components/openssl/openssl-1.0.1/patches/33_cert_chain.patch
changeset 1444 45cb7c6c7aa2
child 1641 2fc479afcf70
equal deleted inserted replaced
1443:7dbaf9c81b75 1444:45cb7c6c7aa2
       
     1 This patch comes from OpenSSL upstream code, and the change has been commited to OpenSSL 1.0.2.
       
     2   http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=fbd2164044f92383955a801ad1b2857d71e83f27
       
     3   http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=51e7a4378a78bb0870a2cdc5c524c230c929ebcb
       
     4   http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=2dabd822366df7b2608b55d5ca5f31d5d484cbaf
       
     5 
       
     6 Index: openssl/crypto/x509/x509_trs.c
       
     7 ============================================================================
       
     8 $ diff -ru crypto/x509/x509_trs.c crypto/x509/x509_trs.c 
       
     9 --- openssl/crypto/x509/x509_trs.c.orig	4 Dec 2012 17:26:04 -0000	1.133.2.11.2.6.2.3
       
    10 +++ openssl/crypto/x509/x509_trs.c	14 Dec 2012 14:30:45 -0000	1.133.2.11.2.6.2.4
       
    11 @@ -114,6 +114,15 @@ int X509_check_trust(X509 *x, int id, int flags)
       
    12  	X509_TRUST *pt;
       
    13  	int idx;
       
    14  	if(id == -1) return 1;
       
    15 +	/* We get this as a default value */
       
    16 +	if (id == 0)
       
    17 +		{
       
    18 +		int rv;
       
    19 +		rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
       
    20 +		if (rv != X509_TRUST_UNTRUSTED)
       
    21 +			return rv;
       
    22 +		return trust_compat(NULL, x, 0);
       
    23 +		}
       
    24  	idx = X509_TRUST_get_by_id(id);
       
    25  	if(idx == -1) return default_trust(id, x, flags);
       
    26  	pt = X509_TRUST_get0(idx);
       
    27 Index: openssl/crypto/x509/x509_vfy.c
       
    28 ============================================================================
       
    29 $ cvs diff -u -r1.105.2.9.2.4.2.3 -r1.105.2.9.2.4.2.4 x509_vfy.c
       
    30 --- openssl/crypto/x509/x509_vfy.c	14 Dec 2012 12:53:48 -0000	1.105.2.9.2.4.2.3
       
    31 +++ openssl/crypto/x509/x509_vfy.c	14 Dec 2012 14:30:46 -0000	1.105.2.9.2.4.2.4
       
    32 @@ -150,6 +150,33 @@
       
    33  	}
       
    34  #endif
       
    35  
       
    36 +/* Given a certificate try and find an exact match in the store */
       
    37 +
       
    38 +static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
       
    39 +	{
       
    40 +	STACK_OF(X509) *certs;
       
    41 +	X509 *xtmp = NULL;
       
    42 +	int i;
       
    43 +	/* Lookup all certs with matching subject name */
       
    44 +	certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
       
    45 +	if (certs == NULL)
       
    46 +		return NULL;
       
    47 +	/* Look for exact match */
       
    48 +	for (i = 0; i < sk_X509_num(certs); i++)
       
    49 +		{
       
    50 +		xtmp = sk_X509_value(certs, i);
       
    51 +		if (!X509_cmp(xtmp, x))
       
    52 +			break;
       
    53 +		}
       
    54 +	if (i < sk_X509_num(certs))
       
    55 +		CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
       
    56 +	else
       
    57 +		xtmp = NULL;
       
    58 +	sk_X509_pop_free(certs, X509_free);
       
    59 +	return xtmp;
       
    60 +	}
       
    61 +
       
    62 +
       
    63  int X509_verify_cert(X509_STORE_CTX *ctx)
       
    64  	{
       
    65  	X509 *x,*xtmp,*chain_ss=NULL;
       
    66 @@ -307,8 +307,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
       
    67  
       
    68  	/* we now have our chain, lets check it... */
       
    69  
       
    70 -	/* Is last certificate looked up self signed? */
       
    71 -	if (!ctx->check_issued(ctx,x,x))
       
    72 +	i = check_trust(ctx);
       
    73 +
       
    74 +	/* If explicitly rejected error */
       
    75 +	if (i == X509_TRUST_REJECTED)
       
    76 +		goto end;
       
    77 +	/* If not explicitly trusted then indicate error */
       
    78 +	if (i != X509_TRUST_TRUSTED)
       
    79  		{
       
    80  		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
       
    81  			{
       
    82 @@ -346,12 +351,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
       
    83  	
       
    84  	if (!ok) goto end;
       
    85  
       
    86 -	/* The chain extensions are OK: check trust */
       
    87 -
       
    88 -	if (param->trust > 0) ok = check_trust(ctx);
       
    89 -
       
    90 -	if (!ok) goto end;
       
    91 -
       
    92  	/* We may as well copy down any DSA parameters that are required */
       
    93  	X509_get_pubkey_parameters(NULL,ctx->chain);
       
    94  
       
    95 @@ -642,28 +641,54 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
       
    96  
       
    97  static int check_trust(X509_STORE_CTX *ctx)
       
    98  {
       
    99 -#ifdef OPENSSL_NO_CHAIN_VERIFY
       
   100 -	return 1;
       
   101 -#else
       
   102  	int i, ok;
       
   103 -	X509 *x;
       
   104 +	X509 *x = NULL;
       
   105  	int (*cb)(int xok,X509_STORE_CTX *xctx);
       
   106  	cb=ctx->verify_cb;
       
   107 -/* For now just check the last certificate in the chain */
       
   108 -	i = sk_X509_num(ctx->chain) - 1;
       
   109 -	x = sk_X509_value(ctx->chain, i);
       
   110 -	ok = X509_check_trust(x, ctx->param->trust, 0);
       
   111 -	if (ok == X509_TRUST_TRUSTED)
       
   112 -		return 1;
       
   113 -	ctx->error_depth = i;
       
   114 -	ctx->current_cert = x;
       
   115 -	if (ok == X509_TRUST_REJECTED)
       
   116 -		ctx->error = X509_V_ERR_CERT_REJECTED;
       
   117 -	else
       
   118 -		ctx->error = X509_V_ERR_CERT_UNTRUSTED;
       
   119 -	ok = cb(0, ctx);
       
   120 -	return ok;
       
   121 -#endif
       
   122 +	/* Check all trusted certificates in chain */
       
   123 +	for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++)
       
   124 +		{
       
   125 +		x = sk_X509_value(ctx->chain, i);
       
   126 +		ok = X509_check_trust(x, ctx->param->trust, 0);
       
   127 +		/* If explicitly trusted return trusted */
       
   128 +		if (ok == X509_TRUST_TRUSTED)
       
   129 +			return X509_TRUST_TRUSTED;
       
   130 +		/* If explicitly rejected notify callback and reject if
       
   131 +		 * not overridden.
       
   132 +		 */
       
   133 +		if (ok == X509_TRUST_REJECTED)
       
   134 +			{
       
   135 +			ctx->error_depth = i;
       
   136 +			ctx->current_cert = x;
       
   137 +			ctx->error = X509_V_ERR_CERT_REJECTED;
       
   138 +			ok = cb(0, ctx);
       
   139 +			if (!ok)
       
   140 +				return X509_TRUST_REJECTED;
       
   141 +			}
       
   142 +		}
       
   143 +	/* If we accept partial chains and have at least one trusted
       
   144 +	 * certificate return success.
       
   145 +	 */
       
   146 +	if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
       
   147 +		{
       
   148 +		X509 *mx;
       
   149 +		if (ctx->last_untrusted < sk_X509_num(ctx->chain))
       
   150 +			return X509_TRUST_TRUSTED;
       
   151 +		x = sk_X509_value(ctx->chain, 0);
       
   152 +		mx = lookup_cert_match(ctx, x);
       
   153 +		if (mx)
       
   154 +			{
       
   155 +			(void)sk_X509_set(ctx->chain, 0, mx);
       
   156 +			X509_free(x);
       
   157 +			ctx->last_untrusted = 0;
       
   158 +			return X509_TRUST_TRUSTED;
       
   159 +			}
       
   160 +		}
       
   161 +
       
   162 +	/* If no trusted certs in chain at all return untrusted and
       
   163 +	 * allow standard (no issuer cert) etc errors to be indicated.
       
   164 +	 */
       
   165 +	return X509_TRUST_UNTRUSTED;
       
   166  }
       
   167  
       
   168  static int check_revocation(X509_STORE_CTX *ctx)
       
   169 @@ -1591,6 +1630,8 @@ static int internal_verify(X509_STORE_CTX *ctx)
       
   170  		xs=xi;
       
   171  	else
       
   172  		{
       
   173 +		if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN && n == 0)
       
   174 +			return check_cert_time(ctx, xi);
       
   175  		if (n <= 0)
       
   176  			{
       
   177  			ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
       
   178 Index: openssl/crypto/x509/x509_vfy.h
       
   179 ============================================================================
       
   180 $ cvs diff -u -r1.67.2.3.4.1 -r1.67.2.3.4.2 x509_vfy.h
       
   181 --- openssl/crypto/x509/x509_vfy.h	26 Sep 2012 13:50:42 -0000	1.67.2.3.4.1
       
   182 +++ openssl/crypto/x509/x509_vfy.h	14 Dec 2012 14:30:46 -0000	1.67.2.3.4.2
       
   183 @@ -390,6 +390,8 @@
       
   184  /* Check selfsigned CA signature */
       
   185  #define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
       
   186  
       
   187 +/* Allow partial chains if at least one certificate is in trusted store */
       
   188 +#define X509_V_FLAG_PARTIAL_CHAIN		0x80000
       
   189  
       
   190  #define X509_VP_FLAG_DEFAULT			0x1
       
   191  #define X509_VP_FLAG_OVERWRITE			0x2
       
   192 Index: openssl/apps/apps.c
       
   193 ============================================================================
       
   194 $ cvs diff -u -r1.133.2.11.2.6.2.3 -r1.133.2.11.2.6.2.4 apps.c
       
   195 --- openssl/apps/apps.c	4 Dec 2012 17:26:04 -0000	1.133.2.11.2.6.2.3
       
   196 +++ openssl/apps/apps.c	14 Dec 2012 14:30:45 -0000	1.133.2.11.2.6.2.4
       
   197 @@ -2361,6 +2361,8 @@
       
   198  		flags |= X509_V_FLAG_NOTIFY_POLICY;
       
   199  	else if (!strcmp(arg, "-check_ss_sig"))
       
   200  		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
       
   201 +	else if (!strcmp(arg, "-partial_chain"))
       
   202 +		flags |= X509_V_FLAG_PARTIAL_CHAIN;
       
   203  	else
       
   204  		return 0;
       
   205