I updated the patch (now in unified form) to keep backwards compatibility.

Best regards,
Martin

2010/12/29 Stephen Henson via RT <[email protected]>:
>> [[email protected] - Mon Dec 27 14:59:59 2010]:
>>
>> 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.
>
> We are very reluctant to rename/delete functions as this will break some
> applications. It is only ever done on major releases (meaning they can't
> be backported to 1.0.x) and then usually for functions that are only
> intended to be used internally. So really we need new functions names
> keeping the existing ones: it's unfortunate that the BIO related
> functions don't follow the convention of having "bio" in their name but
> we're stuck with it now.
>
> Also please use unified diff format for patches.
>
> Steve.
> --
> Dr Stephen N. Henson. OpenSSL project core developer.
> Commercial tech support now available see: http://www.openssl.org
>
>

Index: crypto/ts/ts.h
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/ts/ts.h,v
retrieving revision 1.6
diff -u -r1.6 ts.h
--- crypto/ts/ts.h	12 Nov 2008 03:58:06 -0000	1.6
+++ crypto/ts/ts.h	29 Dec 2010 17:33:07 -0000
@@ -604,6 +604,7 @@
  * In case of errors it sets the status info properly.
  * Returns NULL only in case of memory allocation/fatal error.
  */
+TS_RESP *TS_RESP_create_response_req(TS_RESP_CTX *ctx, TS_REQ *req);
 TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
 
 /*
@@ -611,8 +612,11 @@
  * they are defined in ts/ts_resp_verify.c.
  */
 
-int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
-			     X509_STORE *store, X509 **signer_out);
+int TS_RESP_verify_signature_flags(PKCS7 *token, STACK_OF(X509) *certs,
+                                   X509_STORE *store, X509 **signer_out,
+                                   unsigned flags);
+#define TS_RESP_verify_signature(p7, certs, store, s_out) \
+                TS_RESP_verify_signature_flags(p7, certs, store, s_out, 0)
 
 /* Context structure for the generic verify method. */
 
@@ -635,6 +639,8 @@
 #define	TS_VFY_SIGNER		(1u << 6)
 /* Verify if the TSA name field equals to the user provided name. */
 #define	TS_VFY_TSA_NAME		(1u << 7)
+/* Verify and validate the signer certificate chain */
+#define TS_VFY_CHAIN            (1u << 8)
 
 /* You can use the following convenience constants. */
 #define	TS_VFY_ALL_IMPRINT	(TS_VFY_SIGNATURE	\
@@ -643,14 +649,16 @@
 				 | TS_VFY_IMPRINT	\
 				 | TS_VFY_NONCE		\
 				 | TS_VFY_SIGNER	\
-				 | TS_VFY_TSA_NAME)
+				 | TS_VFY_TSA_NAME	\
+				 | TS_VFY_CHAIN)
 #define	TS_VFY_ALL_DATA		(TS_VFY_SIGNATURE	\
 				 | TS_VFY_VERSION	\
 				 | TS_VFY_POLICY	\
 				 | TS_VFY_DATA		\
 				 | TS_VFY_NONCE		\
 				 | TS_VFY_SIGNER	\
-				 | TS_VFY_TSA_NAME)
+				 | TS_VFY_TSA_NAME	\
+				 | TS_VFY_CHAIN)
 
 typedef struct TS_verify_ctx
 	{
Index: crypto/ts/ts_rsp_sign.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/ts/ts_rsp_sign.c,v
retrieving revision 1.6
diff -u -r1.6 ts_rsp_sign.c
--- crypto/ts/ts_rsp_sign.c	19 Mar 2006 21:09:48 -0000	1.6
+++ crypto/ts/ts_rsp_sign.c	29 Dec 2010 17:33:08 -0000
@@ -80,6 +80,8 @@
 					    ASN1_OBJECT *policy);
 static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
 static int TS_RESP_sign(TS_RESP_CTX *ctx);
+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);
 
 static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
 						   STACK_OF(X509) *certs);
@@ -414,24 +416,35 @@
        return 1;
        }
 
-/* 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)
 	{
-	ASN1_OBJECT *policy;
 	TS_RESP *response;
-	int result = 0;
-
-	TS_RESP_CTX_init(ctx);
-
-	/* Creating the response object. */
-	if (!(ctx->response = TS_RESP_new())) 
+	if (!result)
 		{
-		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;
+				}
+			}
 		}
+	response = ctx->response;
+	ctx->response = NULL;	/* Ownership will be returned to caller. */
+	TS_RESP_CTX_cleanup(ctx);
+	return response;
+	}
 
-	/* 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))
 		{
 		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
 					    "Bad request format or "
@@ -463,24 +476,52 @@
 	/* Everything was successful. */
 	result = 1;
  end:
-	if (!result)
+	return result;
+	}
+
+/* Main entry method of the response generation. */
+TS_RESP *TS_RESP_create_response_req(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()))
 		{
-		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;
 		}
-	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(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);
 	}
 
 /* Initializes the variable part of the context. */
Index: crypto/ts/ts_rsp_verify.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/ts/ts_rsp_verify.c,v
retrieving revision 1.6
diff -u -r1.6 ts_rsp_verify.c
--- crypto/ts/ts_rsp_verify.c	23 Sep 2009 23:43:48 -0000	1.6
+++ crypto/ts/ts_rsp_verify.c	29 Dec 2010 17:33:08 -0000
@@ -66,7 +66,8 @@
 
 static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
 			  X509 *signer, STACK_OF(X509) **chain);
-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);
 static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
 static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
 static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
@@ -137,8 +138,9 @@
  *	- Verify the signature value.
  *	- Returns the signer certificate in 'signer', if 'signer' is not NULL.
  */
-int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
-			     X509_STORE *store, X509 **signer_out)
+int TS_RESP_verify_signature_flags(PKCS7 *token, STACK_OF(X509) *certs,
+			     X509_STORE *store, X509 **signer_out,
+			     unsigned flags)
 	{
 	STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
 	PKCS7_SIGNER_INFO *si;
@@ -186,12 +188,34 @@
 	if (!signers || sk_X509_num(signers) != 1) goto err;
 	signer = sk_X509_value(signers, 0);
 
-	/* 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);
+	}
 
 	/* Check if the signer certificate is consistent with the
 	   ESS extension. */
-	if (!TS_check_signing_certs(si, chain)) goto err;
+	if (!TS_check_signing_certs(si, chain, (flags & TS_VFY_CHAIN))) 
+		goto err;
 
 	/* Creating the message digest. */
 	p7bio = PKCS7_dataInit(token, NULL);
@@ -259,7 +283,8 @@
 	return ret;
 	}
 
-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)
 	{
 	ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
 	STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
@@ -275,7 +300,7 @@
 	
 	/* Check the other certificates of the chain if there are more
 	   than one certificate ids in cert_ids. */
-	if (sk_ESS_CERT_ID_num(cert_ids) > 1)
+	if (validate_chain && sk_ESS_CERT_ID_num(cert_ids) > 1)
 		{
 		/* All the certificates of the chain must be in cert_ids. */
 		for (i = 1; i < sk_X509_num(chain); ++i)
@@ -417,8 +442,8 @@
 
 	/* Verify the signature. */
 	if ((ctx->flags & TS_VFY_SIGNATURE)
-	    && !TS_RESP_verify_signature(token, ctx->certs, ctx->store,
-					 &signer))
+	    && !TS_RESP_verify_signature_flags(token, ctx->certs, ctx->store,
+					       &signer, ctx->flags))
 		goto err;
 	
 	/* Check version number of response. */

Reply via email to