The attached patch contains:
- an additional method for creating a timestamp directly from a
TS_REQ. The existing method taking a BIO was renamed. In cases where
the reference to TS_REQ is still available, this avoids the
unnecessary DER-encoding and later -decoding.
- added an additional flag to be used (or not) for timestamp
verification, TS_VFY_CHAIN. Omitting this allows to skip the
certificate validation step when he timestamp signature is checked. If
validation of the timestamp is coupled with certificate chain
validation, then external resources (i.e. root and intermediate
certificates) are always needed. When skipping validation, it's
possible to validate a timestamp without any external resources if the
timestamp authority certificate is included (which it must be if
explicitly requested). Certificate validation can then be performed
separately.
Best regards,
Martin Boßlet
? openssl/crypto/aes/aesni-x86.s
? openssl/crypto/modes/ghash-x86.s
Index: openssl/apps/ts.c
===================================================================
RCS file: /v/openssl/cvs/openssl/apps/ts.c,v
retrieving revision 1.10
diff -r1.10 ts.c
862c862
< if (!(response = TS_RESP_create_response(resp_ctx, query_bio)))
---
> if (!(response = TS_RESP_create_response_bio(resp_ctx, query_bio)))
Index: openssl/crypto/ts/.cvsignore
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/ts/.cvsignore,v
retrieving revision 1.2
diff -r1.2 .cvsignore
1a2,3
> .ts_rsp_verify.c.swp
> .ts.h.swp
Index: openssl/crypto/ts/ts.h
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/ts/ts.h,v
retrieving revision 1.6
diff -r1.6 ts.h
607c607,608
< TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
---
> TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, TS_REQ *req);
> TS_RESP *TS_RESP_create_response_bio(TS_RESP_CTX *ctx, BIO *req_bio);
615c616,617
< X509_STORE *store, X509 **signer_out);
---
> X509_STORE *store, X509 **signer_out,
> unsigned flags);
637a640,641
> /* Verify and validate the signer certificate chain */
> #define TS_VFY_CHAIN (1u << 8)
646c650,651
< | TS_VFY_TSA_NAME)
---
> | TS_VFY_TSA_NAME \
> | TS_VFY_CHAIN)
653c658,659
< | TS_VFY_TSA_NAME)
---
> | TS_VFY_TSA_NAME \
> | TS_VFY_CHAIN)
Index: openssl/crypto/ts/ts_rsp_sign.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/ts/ts_rsp_sign.c,v
retrieving revision 1.6
diff -r1.6 ts_rsp_sign.c
82a83,84
> static int int_TS_RESP_create_response(TS_RESP_CTX *ctx, TS_REQ *req);
> static TS_RESP *TS_RESP_finalize(int result, TS_RESP_CTX *ctx);
417,418c419
< /* Main entry method of the response generation. */
< TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
---
> static TS_RESP *TS_RESP_finalize(int result, TS_RESP_CTX *ctx)
420d420
< ASN1_OBJECT *policy;
422,427c422
< int result = 0;
<
< TS_RESP_CTX_init(ctx);
<
< /* Creating the response object. */
< if (!(ctx->response = TS_RESP_new()))
---
> if (!result)
429,430c424,434
< TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
< goto end;
---
> TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
> if (ctx->response != NULL)
> {
> if (TS_RESP_CTX_set_status_info_cond(ctx,
> TS_STATUS_REJECTION, "Error during response "
> "generation.") == 0)
> {
> TS_RESP_free(ctx->response);
> ctx->response = NULL;
> }
> }
431a436,440
> response = ctx->response;
> ctx->response = NULL; /* Ownership will be returned to caller. */
> TS_RESP_CTX_cleanup(ctx);
> return response;
> }
433,434c442,447
< /* Parsing DER request. */
< if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL)))
---
> static int int_TS_RESP_create_response(TS_RESP_CTX *ctx, TS_REQ *req)
> {
> ASN1_OBJECT *policy;
> int result = 0;
>
> if (!(ctx->request = req))
466c479,489
< if (!result)
---
> return result;
> }
>
> /* Main entry method of the response generation. */
> TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, TS_REQ *req)
> {
> int result = 0;
> TS_RESP_CTX_init(ctx);
>
> /* Creating the response object. */
> if (!(ctx->response = TS_RESP_new()))
468,478c491,492
< TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
< if (ctx->response != NULL)
< {
< if (TS_RESP_CTX_set_status_info_cond(ctx,
< TS_STATUS_REJECTION, "Error during response "
< "generation.") == 0)
< {
< TS_RESP_free(ctx->response);
< ctx->response = NULL;
< }
< }
---
> TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
> goto end;
480,483c494,524
< response = ctx->response;
< ctx->response = NULL; /* Ownership will be returned to caller. */
< TS_RESP_CTX_cleanup(ctx);
< return response;
---
> result = int_TS_RESP_create_response(ctx, req);
> end:
> ctx->request = NULL; /* Ownership returned to caller. */
> return TS_RESP_finalize (result, ctx);
> }
>
> TS_RESP *TS_RESP_create_response_bio(TS_RESP_CTX *ctx, BIO *req_bio)
> {
> int result = 0;
> TS_REQ *req;
> TS_RESP_CTX_init(ctx);
>
> /* Creating the response object. */
> if (!(ctx->response = TS_RESP_new()))
> {
> TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
> goto end;
> }
> /* Parsing DER request. */
> if (!(req = d2i_TS_REQ_bio(req_bio, NULL)))
> {
> TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
> "Bad request format or "
> "system error.");
> TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
> goto end;
> }
>
> result = int_TS_RESP_create_response(ctx, req);
> end:
> return TS_RESP_finalize (result, ctx);
Index: openssl/crypto/ts/ts_rsp_verify.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/ts/ts_rsp_verify.c,v
retrieving revision 1.6
diff -r1.6 ts_rsp_verify.c
60a61
> #include "stack/safestack.h"
69c70,71
< static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
---
> static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain,
> int validate_chain);
141c143,144
< X509_STORE *store, X509 **signer_out)
---
> X509_STORE *store, X509 **signer_out,
> unsigned flags)
189,190c192,214
< /* Now verify the certificate. */
< if (!TS_verify_cert(store, certs, signer, &chain)) goto err;
---
> /* Now verify the certificate if requested. */
> if ((flags & TS_VFY_CHAIN)
> && !TS_verify_cert(store, certs, signer, &chain))
> {
> goto err;
> }
> else
> {
> /* simply check if the signer certificate has extended
> key usage timeStamping */
> if (!X509_check_purpose(signer,
> X509_PURPOSE_TIMESTAMP_SIGN,
> 0))
> {
> goto err;
> }
> if (!(chain = sk_X509_new_null()))
> {
> goto err;
> }
> sk_X509_push(chain, signer);
> CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
> }
194c218,219
< if (!TS_check_signing_certs(si, chain)) goto err;
---
> if (!TS_check_signing_certs(si, chain, (flags & TS_VFY_CHAIN)))
> goto err;
262c287,288
< static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
---
> static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain,
> int validate_chain)
278c304
< if (sk_ESS_CERT_ID_num(cert_ids) > 1)
---
> if (validate_chain && sk_ESS_CERT_ID_num(cert_ids) > 1)
421c447
< &signer))
---
> &signer, ctx->flags))