提交 bc501570 编写于 作者: D Dr. Stephen Henson

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.
上级 91180d45
...@@ -617,6 +617,14 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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.
*/ */
ctx->error = X509_V_ERR_CERT_REVOKED; if(idx >= 0)
ok = ctx->verify_cb(0, ctx); {
return ok; ctx->error = X509_V_ERR_CERT_REVOKED;
ok = ctx->verify_cb(0, ctx);
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 */ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册