mirror of https://github.com/openssl/openssl.git
				
				
				
			Various X509 fixes. Disable broken certificate workarounds
when X509_V_FLAG_X509_STRICT is set. Check for CRLSign in CRL issuer certificates. Reject CRLs with unhandled (any) critical extensions.
This commit is contained in:
		
							parent
							
								
									91180d45f9
								
							
						
					
					
						commit
						bc50157010
					
				
							
								
								
									
										8
									
								
								CHANGES
								
								
								
								
							
							
						
						
									
										8
									
								
								CHANGES
								
								
								
								
							|  | @ -617,6 +617,14 @@ | ||||||
| 
 | 
 | ||||||
|  Changes between 0.9.7c and 0.9.7d  [xx XXX XXXX] |  Changes between 0.9.7c and 0.9.7d  [xx XXX XXXX] | ||||||
| 
 | 
 | ||||||
|  |   *) X509 verify fixes. Disable broken certificate workarounds when  | ||||||
|  |      X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if | ||||||
|  |      keyUsage extension present. Don't accept CRLs with unhandled critical | ||||||
|  |      extensions: since verify currently doesn't process CRL extensions this | ||||||
|  |      rejects a CRL with *any* critical extensions. Add new verify error codes | ||||||
|  |      for these cases. | ||||||
|  |      [Steve Henson] | ||||||
|  | 
 | ||||||
|   *) When creating an OCSP nonce use an OCTET STRING inside the extnValue. |   *) When creating an OCSP nonce use an OCTET STRING inside the extnValue. | ||||||
|      A clarification of RFC2560 will require the use of OCTET STRINGs and  |      A clarification of RFC2560 will require the use of OCTET STRINGs and  | ||||||
|      some implementations cannot handle the current raw format. Since OpenSSL |      some implementations cannot handle the current raw format. Since OpenSSL | ||||||
|  |  | ||||||
|  | @ -147,6 +147,12 @@ const char *X509_verify_cert_error_string(long n) | ||||||
| 	case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: | 	case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: | ||||||
| 		return("unhandled critical extension"); | 		return("unhandled critical extension"); | ||||||
| 
 | 
 | ||||||
|  | 	case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: | ||||||
|  | 		return("key usage does not include CRL signing"); | ||||||
|  | 
 | ||||||
|  | 	case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: | ||||||
|  | 		return("unhandled critical CRL extension"); | ||||||
|  | 
 | ||||||
| 	default: | 	default: | ||||||
| 		BIO_snprintf(buf,sizeof buf,"error number %ld",n); | 		BIO_snprintf(buf,sizeof buf,"error number %ld",n); | ||||||
| 		return(buf); | 		return(buf); | ||||||
|  |  | ||||||
|  | @ -383,6 +383,7 @@ static int check_chain_purpose(X509_STORE_CTX *ctx) | ||||||
| 	/* Check all untrusted certificates */ | 	/* Check all untrusted certificates */ | ||||||
| 	for (i = 0; i < ctx->last_untrusted; i++) | 	for (i = 0; i < ctx->last_untrusted; i++) | ||||||
| 		{ | 		{ | ||||||
|  | 		int ret; | ||||||
| 		x = sk_X509_value(ctx->chain, i); | 		x = sk_X509_value(ctx->chain, i); | ||||||
| 		if (!(ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) | 		if (!(ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) | ||||||
| 			&& (x->ex_flags & EXFLAG_CRITICAL)) | 			&& (x->ex_flags & EXFLAG_CRITICAL)) | ||||||
|  | @ -393,7 +394,10 @@ static int check_chain_purpose(X509_STORE_CTX *ctx) | ||||||
| 			ok=cb(0,ctx); | 			ok=cb(0,ctx); | ||||||
| 			if (!ok) goto end; | 			if (!ok) goto end; | ||||||
| 			} | 			} | ||||||
| 		if (!X509_check_purpose(x, ctx->purpose, i)) | 		ret = X509_check_purpose(x, ctx->purpose, i); | ||||||
|  | 		if ((ret == 0) | ||||||
|  | 			 || ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||||||
|  | 				&& (ret != 1))) | ||||||
| 			{ | 			{ | ||||||
| 			if (i) | 			if (i) | ||||||
| 				ctx->error = X509_V_ERR_INVALID_CA; | 				ctx->error = X509_V_ERR_INVALID_CA; | ||||||
|  | @ -537,6 +541,14 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) | ||||||
| 
 | 
 | ||||||
| 	if(issuer) | 	if(issuer) | ||||||
| 		{ | 		{ | ||||||
|  | 		/* Check for cRLSign bit if keyUsage present */ | ||||||
|  | 		if ((issuer->ex_flags & EXFLAG_KUSAGE) && | ||||||
|  | 			!(issuer->ex_kusage & KU_CRL_SIGN)) | ||||||
|  | 			{ | ||||||
|  | 			ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; | ||||||
|  | 			ok = ctx->verify_cb(0, ctx); | ||||||
|  | 			if(!ok) goto err; | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 		/* Attempt to get issuer certificate public key */ | 		/* Attempt to get issuer certificate public key */ | ||||||
| 		ikey = X509_get_pubkey(issuer); | 		ikey = X509_get_pubkey(issuer); | ||||||
|  | @ -611,17 +623,46 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | ||||||
| 	{ | 	{ | ||||||
| 	int idx, ok; | 	int idx, ok; | ||||||
| 	X509_REVOKED rtmp; | 	X509_REVOKED rtmp; | ||||||
|  | 	STACK_OF(X509_EXTENSION) *exts; | ||||||
|  | 	X509_EXTENSION *ext; | ||||||
| 	/* Look for serial number of certificate in CRL */ | 	/* Look for serial number of certificate in CRL */ | ||||||
| 	rtmp.serialNumber = X509_get_serialNumber(x); | 	rtmp.serialNumber = X509_get_serialNumber(x); | ||||||
| 	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); | 	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); | ||||||
| 	/* Not found: OK */ | 	/* If found assume revoked: want something cleverer than
 | ||||||
| 	if(idx == -1) return 1; |  | ||||||
| 	/* Otherwise revoked: want something cleverer than
 |  | ||||||
| 	 * this to handle entry extensions in V2 CRLs. | 	 * this to handle entry extensions in V2 CRLs. | ||||||
| 	 */ | 	 */ | ||||||
|  | 	if(idx >= 0) | ||||||
|  | 		{ | ||||||
| 		ctx->error = X509_V_ERR_CERT_REVOKED; | 		ctx->error = X509_V_ERR_CERT_REVOKED; | ||||||
| 		ok = ctx->verify_cb(0, ctx); | 		ok = ctx->verify_cb(0, ctx); | ||||||
| 	return ok; | 		if (!ok) return 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	if (ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	/* See if we have any critical CRL extensions: since we
 | ||||||
|  | 	 * currently don't handle any CRL extensions the CRL must be | ||||||
|  | 	 * rejected.  | ||||||
|  | 	 * This code accesses the X509_CRL structure directly: applications | ||||||
|  | 	 * shouldn't do this. | ||||||
|  | 	 */ | ||||||
|  | 
 | ||||||
|  | 	exts = crl->crl->extensions; | ||||||
|  | 
 | ||||||
|  | 	for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) | ||||||
|  | 		{ | ||||||
|  | 		ext = sk_X509_EXTENSION_value(exts, idx); | ||||||
|  | 		if (ext->critical > 0) | ||||||
|  | 			{ | ||||||
|  | 			ctx->error = | ||||||
|  | 				X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; | ||||||
|  | 			ok = ctx->verify_cb(0, ctx); | ||||||
|  | 			if(!ok) return 0; | ||||||
|  | 			break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	return 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| static int internal_verify(X509_STORE_CTX *ctx) | static int internal_verify(X509_STORE_CTX *ctx) | ||||||
|  |  | ||||||
|  | @ -305,17 +305,26 @@ struct x509_store_ctx_st      /* X509_STORE_CTX */ | ||||||
| 
 | 
 | ||||||
| #define		X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER		33 | #define		X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER		33 | ||||||
| #define		X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION		34 | #define		X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION		34 | ||||||
|  | #define		X509_V_ERR_KEYUSAGE_NO_CRL_SIGN			35 | ||||||
|  | #define		X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION	36 | ||||||
| 
 | 
 | ||||||
| /* The application is not happy */ | /* The application is not happy */ | ||||||
| #define		X509_V_ERR_APPLICATION_VERIFICATION		50 | #define		X509_V_ERR_APPLICATION_VERIFICATION		50 | ||||||
| 
 | 
 | ||||||
| /* Certificate verify flags */ | /* Certificate verify flags */ | ||||||
| 
 | 
 | ||||||
| #define	X509_V_FLAG_CB_ISSUER_CHECK		0x1	/* Send issuer+subject checks to verify_cb */ | /* Send issuer+subject checks to verify_cb */ | ||||||
| #define	X509_V_FLAG_USE_CHECK_TIME		0x2	/* Use check time instead of current time */ | #define	X509_V_FLAG_CB_ISSUER_CHECK		0x1 | ||||||
| #define	X509_V_FLAG_CRL_CHECK			0x4	/* Lookup CRLs */ | /* Use check time instead of current time */ | ||||||
| #define	X509_V_FLAG_CRL_CHECK_ALL		0x8	/* Lookup CRLs for whole chain */ | #define	X509_V_FLAG_USE_CHECK_TIME		0x2 | ||||||
| #define	X509_V_FLAG_IGNORE_CRITICAL		0x10	/* Ignore unhandled critical extensions */ | /* Lookup CRLs */ | ||||||
|  | #define	X509_V_FLAG_CRL_CHECK			0x4 | ||||||
|  | /* Lookup CRLs for whole chain */ | ||||||
|  | #define	X509_V_FLAG_CRL_CHECK_ALL		0x8 | ||||||
|  | /* Ignore unhandled critical extensions */ | ||||||
|  | #define	X509_V_FLAG_IGNORE_CRITICAL		0x10 | ||||||
|  | /* Disable workarounds for broken certificates */ | ||||||
|  | #define	X509_V_FLAG_X509_STRICT			0x20 | ||||||
| 
 | 
 | ||||||
| int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, | int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, | ||||||
| 	     X509_NAME *name); | 	     X509_NAME *name); | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
|  * project 2001. |  * project 2001. | ||||||
|  */ |  */ | ||||||
| /* ====================================================================
 | /* ====================================================================
 | ||||||
|  * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved. |  * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved. | ||||||
|  * |  * | ||||||
|  * Redistribution and use in source and binary forms, with or without |  * Redistribution and use in source and binary forms, with or without | ||||||
|  * modification, are permitted provided that the following conditions |  * modification, are permitted provided that the following conditions | ||||||
|  | @ -415,6 +415,7 @@ static void x509v3_cache_extensions(X509 *x) | ||||||
|  * 1 is a CA |  * 1 is a CA | ||||||
|  * 2 basicConstraints absent so "maybe" a CA |  * 2 basicConstraints absent so "maybe" a CA | ||||||
|  * 3 basicConstraints absent but self signed V1. |  * 3 basicConstraints absent but self signed V1. | ||||||
|  |  * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) | #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) | ||||||
|  | @ -436,7 +437,7 @@ static int ca_check(const X509 *x) | ||||||
| 	} else { | 	} else { | ||||||
| 		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3; | 		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3; | ||||||
| 		/* If key usage present it must have certSign so tolerate it */ | 		/* If key usage present it must have certSign so tolerate it */ | ||||||
| 		else if (x->ex_flags & EXFLAG_KUSAGE) return 3; | 		else if (x->ex_flags & EXFLAG_KUSAGE) return 4; | ||||||
| 		else return 2; | 		else return 2; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue