diff options
Diffstat (limited to 'src/lib/libcrypto/x509')
-rw-r--r-- | src/lib/libcrypto/x509/by_file.c | 4 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509.h | 11 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_cmp.c | 48 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_r2x.c | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_req.c | 35 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_txt.c | 13 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 131 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.h | 8 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509cset.c | 1 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509name.c | 10 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x_all.c | 1 |
11 files changed, 205 insertions, 63 deletions
diff --git a/src/lib/libcrypto/x509/by_file.c b/src/lib/libcrypto/x509/by_file.c index b4b04183d0..a5e0d4aefa 100644 --- a/src/lib/libcrypto/x509/by_file.c +++ b/src/lib/libcrypto/x509/by_file.c | |||
@@ -150,7 +150,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) | |||
150 | x=PEM_read_bio_X509_AUX(in,NULL,NULL,NULL); | 150 | x=PEM_read_bio_X509_AUX(in,NULL,NULL,NULL); |
151 | if (x == NULL) | 151 | if (x == NULL) |
152 | { | 152 | { |
153 | if ((ERR_GET_REASON(ERR_peek_error()) == | 153 | if ((ERR_GET_REASON(ERR_peek_last_error()) == |
154 | PEM_R_NO_START_LINE) && (count > 0)) | 154 | PEM_R_NO_START_LINE) && (count > 0)) |
155 | { | 155 | { |
156 | ERR_clear_error(); | 156 | ERR_clear_error(); |
@@ -217,7 +217,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) | |||
217 | x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); | 217 | x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); |
218 | if (x == NULL) | 218 | if (x == NULL) |
219 | { | 219 | { |
220 | if ((ERR_GET_REASON(ERR_peek_error()) == | 220 | if ((ERR_GET_REASON(ERR_peek_last_error()) == |
221 | PEM_R_NO_START_LINE) && (count > 0)) | 221 | PEM_R_NO_START_LINE) && (count > 0)) |
222 | { | 222 | { |
223 | ERR_clear_error(); | 223 | ERR_clear_error(); |
diff --git a/src/lib/libcrypto/x509/x509.h b/src/lib/libcrypto/x509/x509.h index 8d0c7e2e17..e8c1a59cf2 100644 --- a/src/lib/libcrypto/x509/x509.h +++ b/src/lib/libcrypto/x509/x509.h | |||
@@ -410,6 +410,7 @@ typedef struct X509_crl_info_st | |||
410 | ASN1_TIME *nextUpdate; | 410 | ASN1_TIME *nextUpdate; |
411 | STACK_OF(X509_REVOKED) *revoked; | 411 | STACK_OF(X509_REVOKED) *revoked; |
412 | STACK_OF(X509_EXTENSION) /* [0] */ *extensions; | 412 | STACK_OF(X509_EXTENSION) /* [0] */ *extensions; |
413 | ASN1_ENCODING enc; | ||
413 | } X509_CRL_INFO; | 414 | } X509_CRL_INFO; |
414 | 415 | ||
415 | struct X509_crl_st | 416 | struct X509_crl_st |
@@ -1037,18 +1038,18 @@ int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, | |||
1037 | int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, | 1038 | int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, |
1038 | unsigned char *bytes, int len, int loc, int set); | 1039 | unsigned char *bytes, int len, int loc, int set); |
1039 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, | 1040 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, |
1040 | char *field, int type, unsigned char *bytes, int len); | 1041 | const char *field, int type, const unsigned char *bytes, int len); |
1041 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, | 1042 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, |
1042 | int type,unsigned char *bytes, int len); | 1043 | int type,unsigned char *bytes, int len); |
1043 | int X509_NAME_add_entry_by_txt(X509_NAME *name, char *field, int type, | 1044 | int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, |
1044 | unsigned char *bytes, int len, int loc, int set); | 1045 | const unsigned char *bytes, int len, int loc, int set); |
1045 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, | 1046 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, |
1046 | ASN1_OBJECT *obj, int type,unsigned char *bytes, | 1047 | ASN1_OBJECT *obj, int type,const unsigned char *bytes, |
1047 | int len); | 1048 | int len); |
1048 | int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, | 1049 | int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, |
1049 | ASN1_OBJECT *obj); | 1050 | ASN1_OBJECT *obj); |
1050 | int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, | 1051 | int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, |
1051 | unsigned char *bytes, int len); | 1052 | const unsigned char *bytes, int len); |
1052 | ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); | 1053 | ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); |
1053 | ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); | 1054 | ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); |
1054 | 1055 | ||
diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c index f460102f49..030d0966fc 100644 --- a/src/lib/libcrypto/x509/x509_cmp.c +++ b/src/lib/libcrypto/x509/x509_cmp.c | |||
@@ -254,33 +254,49 @@ static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b) | |||
254 | return 0; | 254 | return 0; |
255 | } | 255 | } |
256 | 256 | ||
257 | static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b) | ||
258 | { | ||
259 | int j; | ||
260 | j = a->length - b->length; | ||
261 | if (j) | ||
262 | return j; | ||
263 | return memcmp(a->data, b->data, a->length); | ||
264 | } | ||
265 | |||
266 | #define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING) | ||
267 | |||
257 | int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) | 268 | int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) |
258 | { | 269 | { |
259 | int i,j; | 270 | int i,j; |
260 | X509_NAME_ENTRY *na,*nb; | 271 | X509_NAME_ENTRY *na,*nb; |
261 | 272 | ||
262 | if (sk_X509_NAME_ENTRY_num(a->entries) | 273 | unsigned long nabit, nbbit; |
263 | != sk_X509_NAME_ENTRY_num(b->entries)) | 274 | |
264 | return sk_X509_NAME_ENTRY_num(a->entries) | 275 | j = sk_X509_NAME_ENTRY_num(a->entries) |
265 | -sk_X509_NAME_ENTRY_num(b->entries); | 276 | - sk_X509_NAME_ENTRY_num(b->entries); |
277 | if (j) | ||
278 | return j; | ||
266 | for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) | 279 | for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) |
267 | { | 280 | { |
268 | na=sk_X509_NAME_ENTRY_value(a->entries,i); | 281 | na=sk_X509_NAME_ENTRY_value(a->entries,i); |
269 | nb=sk_X509_NAME_ENTRY_value(b->entries,i); | 282 | nb=sk_X509_NAME_ENTRY_value(b->entries,i); |
270 | j=na->value->type-nb->value->type; | 283 | j=na->value->type-nb->value->type; |
271 | if (j) return(j); | 284 | if (j) |
272 | if (na->value->type == V_ASN1_PRINTABLESTRING) | 285 | { |
286 | nabit = ASN1_tag2bit(na->value->type); | ||
287 | nbbit = ASN1_tag2bit(nb->value->type); | ||
288 | if (!(nabit & STR_TYPE_CMP) || | ||
289 | !(nbbit & STR_TYPE_CMP)) | ||
290 | return j; | ||
291 | j = asn1_string_memcmp(na->value, nb->value); | ||
292 | } | ||
293 | else if (na->value->type == V_ASN1_PRINTABLESTRING) | ||
273 | j=nocase_spacenorm_cmp(na->value, nb->value); | 294 | j=nocase_spacenorm_cmp(na->value, nb->value); |
274 | else if (na->value->type == V_ASN1_IA5STRING | 295 | else if (na->value->type == V_ASN1_IA5STRING |
275 | && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress) | 296 | && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress) |
276 | j=nocase_cmp(na->value, nb->value); | 297 | j=nocase_cmp(na->value, nb->value); |
277 | else | 298 | else |
278 | { | 299 | j = asn1_string_memcmp(na->value, nb->value); |
279 | j=na->value->length-nb->value->length; | ||
280 | if (j) return(j); | ||
281 | j=memcmp(na->value->data,nb->value->data, | ||
282 | na->value->length); | ||
283 | } | ||
284 | if (j) return(j); | 300 | if (j) return(j); |
285 | j=na->set-nb->set; | 301 | j=na->set-nb->set; |
286 | if (j) return(j); | 302 | if (j) return(j); |
@@ -306,10 +322,16 @@ unsigned long X509_NAME_hash(X509_NAME *x) | |||
306 | { | 322 | { |
307 | unsigned long ret=0; | 323 | unsigned long ret=0; |
308 | unsigned char md[16]; | 324 | unsigned char md[16]; |
325 | EVP_MD_CTX md_ctx; | ||
309 | 326 | ||
310 | /* Make sure X509_NAME structure contains valid cached encoding */ | 327 | /* Make sure X509_NAME structure contains valid cached encoding */ |
311 | i2d_X509_NAME(x,NULL); | 328 | i2d_X509_NAME(x,NULL); |
312 | EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL); | 329 | EVP_MD_CTX_init(&md_ctx); |
330 | EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); | ||
331 | EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL); | ||
332 | EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length); | ||
333 | EVP_DigestFinal_ex(&md_ctx,md,NULL); | ||
334 | EVP_MD_CTX_cleanup(&md_ctx); | ||
313 | 335 | ||
314 | ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| | 336 | ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| |
315 | ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) | 337 | ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) |
diff --git a/src/lib/libcrypto/x509/x509_r2x.c b/src/lib/libcrypto/x509/x509_r2x.c index db051033d9..fb8a78dabe 100644 --- a/src/lib/libcrypto/x509/x509_r2x.c +++ b/src/lib/libcrypto/x509/x509_r2x.c | |||
@@ -92,8 +92,10 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) | |||
92 | X509_set_subject_name(ret,X509_NAME_dup(xn)); | 92 | X509_set_subject_name(ret,X509_NAME_dup(xn)); |
93 | X509_set_issuer_name(ret,X509_NAME_dup(xn)); | 93 | X509_set_issuer_name(ret,X509_NAME_dup(xn)); |
94 | 94 | ||
95 | X509_gmtime_adj(xi->validity->notBefore,0); | 95 | if (X509_gmtime_adj(xi->validity->notBefore,0) == NULL) |
96 | X509_gmtime_adj(xi->validity->notAfter,(long)60*60*24*days); | 96 | goto err; |
97 | if (X509_gmtime_adj(xi->validity->notAfter,(long)60*60*24*days) == NULL) | ||
98 | goto err; | ||
97 | 99 | ||
98 | X509_set_pubkey(ret,X509_REQ_get_pubkey(r)); | 100 | X509_set_pubkey(ret,X509_REQ_get_pubkey(r)); |
99 | 101 | ||
diff --git a/src/lib/libcrypto/x509/x509_req.c b/src/lib/libcrypto/x509/x509_req.c index 0affa3bf30..59fc6ca548 100644 --- a/src/lib/libcrypto/x509/x509_req.c +++ b/src/lib/libcrypto/x509/x509_req.c | |||
@@ -118,7 +118,7 @@ EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) | |||
118 | * used and there may be more: so the list is configurable. | 118 | * used and there may be more: so the list is configurable. |
119 | */ | 119 | */ |
120 | 120 | ||
121 | static int ext_nid_list[] = { NID_ms_ext_req, NID_ext_req, NID_undef}; | 121 | static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef}; |
122 | 122 | ||
123 | static int *ext_nids = ext_nid_list; | 123 | static int *ext_nids = ext_nid_list; |
124 | 124 | ||
@@ -143,32 +143,33 @@ void X509_REQ_set_extension_nids(int *nids) | |||
143 | } | 143 | } |
144 | 144 | ||
145 | STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) | 145 | STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) |
146 | { | 146 | { |
147 | X509_ATTRIBUTE *attr; | 147 | X509_ATTRIBUTE *attr; |
148 | STACK_OF(X509_ATTRIBUTE) *sk; | ||
149 | ASN1_TYPE *ext = NULL; | 148 | ASN1_TYPE *ext = NULL; |
150 | int i; | 149 | int idx, *pnid; |
151 | unsigned char *p; | 150 | unsigned char *p; |
152 | if ((req == NULL) || (req->req_info == NULL)) | 151 | |
152 | if ((req == NULL) || (req->req_info == NULL) || !ext_nids) | ||
153 | return(NULL); | 153 | return(NULL); |
154 | sk=req->req_info->attributes; | 154 | for (pnid = ext_nids; *pnid != NID_undef; pnid++) |
155 | if (!sk) return NULL; | 155 | { |
156 | for(i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { | 156 | idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); |
157 | attr = sk_X509_ATTRIBUTE_value(sk, i); | 157 | if (idx == -1) |
158 | if(X509_REQ_extension_nid(OBJ_obj2nid(attr->object))) { | 158 | continue; |
159 | if(attr->single) ext = attr->value.single; | 159 | attr = X509_REQ_get_attr(req, idx); |
160 | else if(sk_ASN1_TYPE_num(attr->value.set)) | 160 | if(attr->single) ext = attr->value.single; |
161 | ext = sk_ASN1_TYPE_value(attr->value.set, 0); | 161 | else if(sk_ASN1_TYPE_num(attr->value.set)) |
162 | break; | 162 | ext = sk_ASN1_TYPE_value(attr->value.set, 0); |
163 | break; | ||
163 | } | 164 | } |
164 | } | 165 | if(!ext || (ext->type != V_ASN1_SEQUENCE)) |
165 | if(!ext || (ext->type != V_ASN1_SEQUENCE)) return NULL; | 166 | return NULL; |
166 | p = ext->value.sequence->data; | 167 | p = ext->value.sequence->data; |
167 | return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p, | 168 | return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p, |
168 | ext->value.sequence->length, | 169 | ext->value.sequence->length, |
169 | d2i_X509_EXTENSION, X509_EXTENSION_free, | 170 | d2i_X509_EXTENSION, X509_EXTENSION_free, |
170 | V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | 171 | V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); |
171 | } | 172 | } |
172 | 173 | ||
173 | /* Add a STACK_OF extensions to a certificate request: allow alternative OIDs | 174 | /* Add a STACK_OF extensions to a certificate request: allow alternative OIDs |
174 | * in case we want to create a non standard one. | 175 | * in case we want to create a non standard one. |
diff --git a/src/lib/libcrypto/x509/x509_txt.c b/src/lib/libcrypto/x509/x509_txt.c index e31ebc6741..f19e66a238 100644 --- a/src/lib/libcrypto/x509/x509_txt.c +++ b/src/lib/libcrypto/x509/x509_txt.c | |||
@@ -122,8 +122,14 @@ const char *X509_verify_cert_error_string(long n) | |||
122 | return("certificate revoked"); | 122 | return("certificate revoked"); |
123 | case X509_V_ERR_INVALID_CA: | 123 | case X509_V_ERR_INVALID_CA: |
124 | return ("invalid CA certificate"); | 124 | return ("invalid CA certificate"); |
125 | case X509_V_ERR_INVALID_NON_CA: | ||
126 | return ("invalid non-CA certificate (has CA markings)"); | ||
125 | case X509_V_ERR_PATH_LENGTH_EXCEEDED: | 127 | case X509_V_ERR_PATH_LENGTH_EXCEEDED: |
126 | return ("path length constraint exceeded"); | 128 | return ("path length constraint exceeded"); |
129 | case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: | ||
130 | return("proxy path length constraint exceeded"); | ||
131 | case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: | ||
132 | return("proxy cerificates not allowed, please set the appropriate flag"); | ||
127 | case X509_V_ERR_INVALID_PURPOSE: | 133 | case X509_V_ERR_INVALID_PURPOSE: |
128 | return ("unsupported certificate purpose"); | 134 | return ("unsupported certificate purpose"); |
129 | case X509_V_ERR_CERT_UNTRUSTED: | 135 | case X509_V_ERR_CERT_UNTRUSTED: |
@@ -140,19 +146,16 @@ const char *X509_verify_cert_error_string(long n) | |||
140 | return("authority and issuer serial number mismatch"); | 146 | return("authority and issuer serial number mismatch"); |
141 | case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: | 147 | case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: |
142 | return("key usage does not include certificate signing"); | 148 | return("key usage does not include certificate signing"); |
143 | |||
144 | case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: | 149 | case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: |
145 | return("unable to get CRL issuer certificate"); | 150 | return("unable to get CRL issuer certificate"); |
146 | |||
147 | case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: | 151 | case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: |
148 | return("unhandled critical extension"); | 152 | return("unhandled critical extension"); |
149 | |||
150 | case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: | 153 | case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: |
151 | return("key usage does not include CRL signing"); | 154 | return("key usage does not include CRL signing"); |
152 | 155 | case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: | |
156 | return("key usage does not include digital signature"); | ||
153 | case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: | 157 | case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: |
154 | return("unhandled critical CRL extension"); | 158 | return("unhandled critical CRL extension"); |
155 | |||
156 | default: | 159 | default: |
157 | BIO_snprintf(buf,sizeof buf,"error number %ld",n); | 160 | BIO_snprintf(buf,sizeof buf,"error number %ld",n); |
158 | return(buf); | 161 | return(buf); |
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 2e4d0b823a..e43c861ee7 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -73,7 +73,7 @@ | |||
73 | static int null_callback(int ok,X509_STORE_CTX *e); | 73 | static int null_callback(int ok,X509_STORE_CTX *e); |
74 | static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); | 74 | static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); |
75 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); | 75 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); |
76 | static int check_chain_purpose(X509_STORE_CTX *ctx); | 76 | static int check_chain_extensions(X509_STORE_CTX *ctx); |
77 | static int check_trust(X509_STORE_CTX *ctx); | 77 | static int check_trust(X509_STORE_CTX *ctx); |
78 | static int check_revocation(X509_STORE_CTX *ctx); | 78 | static int check_revocation(X509_STORE_CTX *ctx); |
79 | static int check_cert(X509_STORE_CTX *ctx); | 79 | static int check_cert(X509_STORE_CTX *ctx); |
@@ -281,7 +281,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | /* We have the chain complete: now we need to check its purpose */ | 283 | /* We have the chain complete: now we need to check its purpose */ |
284 | if (ctx->purpose > 0) ok = check_chain_purpose(ctx); | 284 | ok = check_chain_extensions(ctx); |
285 | 285 | ||
286 | if (!ok) goto end; | 286 | if (!ok) goto end; |
287 | 287 | ||
@@ -365,21 +365,39 @@ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | |||
365 | else | 365 | else |
366 | return 0; | 366 | return 0; |
367 | } | 367 | } |
368 | 368 | ||
369 | 369 | ||
370 | /* Check a certificate chains extensions for consistency | 370 | /* Check a certificate chains extensions for consistency |
371 | * with the supplied purpose | 371 | * with the supplied purpose |
372 | */ | 372 | */ |
373 | 373 | ||
374 | static int check_chain_purpose(X509_STORE_CTX *ctx) | 374 | static int check_chain_extensions(X509_STORE_CTX *ctx) |
375 | { | 375 | { |
376 | #ifdef OPENSSL_NO_CHAIN_VERIFY | 376 | #ifdef OPENSSL_NO_CHAIN_VERIFY |
377 | return 1; | 377 | return 1; |
378 | #else | 378 | #else |
379 | int i, ok=0; | 379 | int i, ok=0, must_be_ca; |
380 | X509 *x; | 380 | X509 *x; |
381 | int (*cb)(); | 381 | int (*cb)(); |
382 | int proxy_path_length = 0; | ||
383 | int allow_proxy_certs = !!(ctx->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); | ||
382 | cb=ctx->verify_cb; | 384 | cb=ctx->verify_cb; |
385 | |||
386 | /* must_be_ca can have 1 of 3 values: | ||
387 | -1: we accept both CA and non-CA certificates, to allow direct | ||
388 | use of self-signed certificates (which are marked as CA). | ||
389 | 0: we only accept non-CA certificates. This is currently not | ||
390 | used, but the possibility is present for future extensions. | ||
391 | 1: we only accept CA certificates. This is currently used for | ||
392 | all certificates in the chain except the leaf certificate. | ||
393 | */ | ||
394 | must_be_ca = -1; | ||
395 | |||
396 | /* A hack to keep people who don't want to modify their software | ||
397 | happy */ | ||
398 | if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) | ||
399 | allow_proxy_certs = 1; | ||
400 | |||
383 | /* Check all untrusted certificates */ | 401 | /* Check all untrusted certificates */ |
384 | for (i = 0; i < ctx->last_untrusted; i++) | 402 | for (i = 0; i < ctx->last_untrusted; i++) |
385 | { | 403 | { |
@@ -394,23 +412,73 @@ static int check_chain_purpose(X509_STORE_CTX *ctx) | |||
394 | ok=cb(0,ctx); | 412 | ok=cb(0,ctx); |
395 | if (!ok) goto end; | 413 | if (!ok) goto end; |
396 | } | 414 | } |
397 | ret = X509_check_purpose(x, ctx->purpose, i); | 415 | if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) |
398 | if ((ret == 0) | ||
399 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
400 | && (ret != 1))) | ||
401 | { | 416 | { |
402 | if (i) | 417 | ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; |
418 | ctx->error_depth = i; | ||
419 | ctx->current_cert = x; | ||
420 | ok=cb(0,ctx); | ||
421 | if (!ok) goto end; | ||
422 | } | ||
423 | ret = X509_check_ca(x); | ||
424 | switch(must_be_ca) | ||
425 | { | ||
426 | case -1: | ||
427 | if ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
428 | && (ret != 1) && (ret != 0)) | ||
429 | { | ||
430 | ret = 0; | ||
403 | ctx->error = X509_V_ERR_INVALID_CA; | 431 | ctx->error = X509_V_ERR_INVALID_CA; |
432 | } | ||
404 | else | 433 | else |
405 | ctx->error = X509_V_ERR_INVALID_PURPOSE; | 434 | ret = 1; |
435 | break; | ||
436 | case 0: | ||
437 | if (ret != 0) | ||
438 | { | ||
439 | ret = 0; | ||
440 | ctx->error = X509_V_ERR_INVALID_NON_CA; | ||
441 | } | ||
442 | else | ||
443 | ret = 1; | ||
444 | break; | ||
445 | default: | ||
446 | if ((ret == 0) | ||
447 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
448 | && (ret != 1))) | ||
449 | { | ||
450 | ret = 0; | ||
451 | ctx->error = X509_V_ERR_INVALID_CA; | ||
452 | } | ||
453 | else | ||
454 | ret = 1; | ||
455 | break; | ||
456 | } | ||
457 | if (ret == 0) | ||
458 | { | ||
406 | ctx->error_depth = i; | 459 | ctx->error_depth = i; |
407 | ctx->current_cert = x; | 460 | ctx->current_cert = x; |
408 | ok=cb(0,ctx); | 461 | ok=cb(0,ctx); |
409 | if (!ok) goto end; | 462 | if (!ok) goto end; |
410 | } | 463 | } |
464 | if (ctx->purpose > 0) | ||
465 | { | ||
466 | ret = X509_check_purpose(x, ctx->purpose, | ||
467 | must_be_ca > 0); | ||
468 | if ((ret == 0) | ||
469 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
470 | && (ret != 1))) | ||
471 | { | ||
472 | ctx->error = X509_V_ERR_INVALID_PURPOSE; | ||
473 | ctx->error_depth = i; | ||
474 | ctx->current_cert = x; | ||
475 | ok=cb(0,ctx); | ||
476 | if (!ok) goto end; | ||
477 | } | ||
478 | } | ||
411 | /* Check pathlen */ | 479 | /* Check pathlen */ |
412 | if ((i > 1) && (x->ex_pathlen != -1) | 480 | if ((i > 1) && (x->ex_pathlen != -1) |
413 | && (i > (x->ex_pathlen + 1))) | 481 | && (i > (x->ex_pathlen + proxy_path_length + 1))) |
414 | { | 482 | { |
415 | ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; | 483 | ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; |
416 | ctx->error_depth = i; | 484 | ctx->error_depth = i; |
@@ -418,6 +486,32 @@ static int check_chain_purpose(X509_STORE_CTX *ctx) | |||
418 | ok=cb(0,ctx); | 486 | ok=cb(0,ctx); |
419 | if (!ok) goto end; | 487 | if (!ok) goto end; |
420 | } | 488 | } |
489 | /* If this certificate is a proxy certificate, the next | ||
490 | certificate must be another proxy certificate or a EE | ||
491 | certificate. If not, the next certificate must be a | ||
492 | CA certificate. */ | ||
493 | if (x->ex_flags & EXFLAG_PROXY) | ||
494 | { | ||
495 | PROXY_CERT_INFO_EXTENSION *pci = | ||
496 | X509_get_ext_d2i(x, NID_proxyCertInfo, | ||
497 | NULL, NULL); | ||
498 | if (pci->pcPathLengthConstraint && | ||
499 | ASN1_INTEGER_get(pci->pcPathLengthConstraint) | ||
500 | < i) | ||
501 | { | ||
502 | PROXY_CERT_INFO_EXTENSION_free(pci); | ||
503 | ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; | ||
504 | ctx->error_depth = i; | ||
505 | ctx->current_cert = x; | ||
506 | ok=cb(0,ctx); | ||
507 | if (!ok) goto end; | ||
508 | } | ||
509 | PROXY_CERT_INFO_EXTENSION_free(pci); | ||
510 | proxy_path_length++; | ||
511 | must_be_ca = 0; | ||
512 | } | ||
513 | else | ||
514 | must_be_ca = 1; | ||
421 | } | 515 | } |
422 | ok = 1; | 516 | ok = 1; |
423 | end: | 517 | end: |
@@ -627,6 +721,15 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | |||
627 | X509_EXTENSION *ext; | 721 | X509_EXTENSION *ext; |
628 | /* Look for serial number of certificate in CRL */ | 722 | /* Look for serial number of certificate in CRL */ |
629 | rtmp.serialNumber = X509_get_serialNumber(x); | 723 | rtmp.serialNumber = X509_get_serialNumber(x); |
724 | /* Sort revoked into serial number order if not already sorted. | ||
725 | * Do this under a lock to avoid race condition. | ||
726 | */ | ||
727 | if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) | ||
728 | { | ||
729 | CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); | ||
730 | sk_X509_REVOKED_sort(crl->crl->revoked); | ||
731 | CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); | ||
732 | } | ||
630 | idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); | 733 | idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); |
631 | /* If found assume revoked: want something cleverer than | 734 | /* If found assume revoked: want something cleverer than |
632 | * this to handle entry extensions in V2 CRLs. | 735 | * this to handle entry extensions in V2 CRLs. |
@@ -772,6 +875,7 @@ static int internal_verify(X509_STORE_CTX *ctx) | |||
772 | } | 875 | } |
773 | 876 | ||
774 | /* The last error (if any) is still in the error value */ | 877 | /* The last error (if any) is still in the error value */ |
878 | ctx->current_issuer=xi; | ||
775 | ctx->current_cert=xs; | 879 | ctx->current_cert=xs; |
776 | ok=(*cb)(1,ctx); | 880 | ok=(*cb)(1,ctx); |
777 | if (!ok) goto end; | 881 | if (!ok) goto end; |
@@ -851,7 +955,8 @@ int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) | |||
851 | atm.length=sizeof(buff2); | 955 | atm.length=sizeof(buff2); |
852 | atm.data=(unsigned char *)buff2; | 956 | atm.data=(unsigned char *)buff2; |
853 | 957 | ||
854 | X509_time_adj(&atm,-offset*60, cmp_time); | 958 | if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL) |
959 | return 0; | ||
855 | 960 | ||
856 | if (ctm->type == V_ASN1_UTCTIME) | 961 | if (ctm->type == V_ASN1_UTCTIME) |
857 | { | 962 | { |
diff --git a/src/lib/libcrypto/x509/x509_vfy.h b/src/lib/libcrypto/x509/x509_vfy.h index 198495884c..7fd1f0bc4d 100644 --- a/src/lib/libcrypto/x509/x509_vfy.h +++ b/src/lib/libcrypto/x509/x509_vfy.h | |||
@@ -276,7 +276,7 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ | |||
276 | #define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 | 276 | #define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 |
277 | #define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 | 277 | #define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 |
278 | #define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 | 278 | #define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 |
279 | #define X509_V_ERR_CERT_NOT_YET_VALID 9 | 279 | #define X509_V_ERR_CERT_NOT_YET_VALID 9 |
280 | #define X509_V_ERR_CERT_HAS_EXPIRED 10 | 280 | #define X509_V_ERR_CERT_HAS_EXPIRED 10 |
281 | #define X509_V_ERR_CRL_NOT_YET_VALID 11 | 281 | #define X509_V_ERR_CRL_NOT_YET_VALID 11 |
282 | #define X509_V_ERR_CRL_HAS_EXPIRED 12 | 282 | #define X509_V_ERR_CRL_HAS_EXPIRED 12 |
@@ -306,6 +306,10 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ | |||
306 | #define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 | 306 | #define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 |
307 | #define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 | 307 | #define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 |
308 | #define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 | 308 | #define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 |
309 | #define X509_V_ERR_INVALID_NON_CA 37 | ||
310 | #define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 | ||
311 | #define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 | ||
312 | #define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 | ||
309 | 313 | ||
310 | /* The application is not happy */ | 314 | /* The application is not happy */ |
311 | #define X509_V_ERR_APPLICATION_VERIFICATION 50 | 315 | #define X509_V_ERR_APPLICATION_VERIFICATION 50 |
@@ -324,6 +328,8 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ | |||
324 | #define X509_V_FLAG_IGNORE_CRITICAL 0x10 | 328 | #define X509_V_FLAG_IGNORE_CRITICAL 0x10 |
325 | /* Disable workarounds for broken certificates */ | 329 | /* Disable workarounds for broken certificates */ |
326 | #define X509_V_FLAG_X509_STRICT 0x20 | 330 | #define X509_V_FLAG_X509_STRICT 0x20 |
331 | /* Enable proxy certificate validation */ | ||
332 | #define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 | ||
327 | 333 | ||
328 | int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, | 334 | int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, |
329 | X509_NAME *name); | 335 | X509_NAME *name); |
diff --git a/src/lib/libcrypto/x509/x509cset.c b/src/lib/libcrypto/x509/x509cset.c index 6cac440ea9..9d1646d5c8 100644 --- a/src/lib/libcrypto/x509/x509cset.c +++ b/src/lib/libcrypto/x509/x509cset.c | |||
@@ -129,6 +129,7 @@ int X509_CRL_sort(X509_CRL *c) | |||
129 | r=sk_X509_REVOKED_value(c->crl->revoked,i); | 129 | r=sk_X509_REVOKED_value(c->crl->revoked,i); |
130 | r->sequence=i; | 130 | r->sequence=i; |
131 | } | 131 | } |
132 | c->crl->enc.modified = 1; | ||
132 | return 1; | 133 | return 1; |
133 | } | 134 | } |
134 | 135 | ||
diff --git a/src/lib/libcrypto/x509/x509name.c b/src/lib/libcrypto/x509/x509name.c index 4c20e03ece..068abfe5f0 100644 --- a/src/lib/libcrypto/x509/x509name.c +++ b/src/lib/libcrypto/x509/x509name.c | |||
@@ -195,8 +195,8 @@ int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, | |||
195 | return ret; | 195 | return ret; |
196 | } | 196 | } |
197 | 197 | ||
198 | int X509_NAME_add_entry_by_txt(X509_NAME *name, char *field, int type, | 198 | int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, |
199 | unsigned char *bytes, int len, int loc, int set) | 199 | const unsigned char *bytes, int len, int loc, int set) |
200 | { | 200 | { |
201 | X509_NAME_ENTRY *ne; | 201 | X509_NAME_ENTRY *ne; |
202 | int ret; | 202 | int ret; |
@@ -273,7 +273,7 @@ err: | |||
273 | } | 273 | } |
274 | 274 | ||
275 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, | 275 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, |
276 | char *field, int type, unsigned char *bytes, int len) | 276 | const char *field, int type, const unsigned char *bytes, int len) |
277 | { | 277 | { |
278 | ASN1_OBJECT *obj; | 278 | ASN1_OBJECT *obj; |
279 | X509_NAME_ENTRY *nentry; | 279 | X509_NAME_ENTRY *nentry; |
@@ -309,7 +309,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, | |||
309 | } | 309 | } |
310 | 310 | ||
311 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, | 311 | X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, |
312 | ASN1_OBJECT *obj, int type, unsigned char *bytes, int len) | 312 | ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len) |
313 | { | 313 | { |
314 | X509_NAME_ENTRY *ret; | 314 | X509_NAME_ENTRY *ret; |
315 | 315 | ||
@@ -347,7 +347,7 @@ int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj) | |||
347 | } | 347 | } |
348 | 348 | ||
349 | int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, | 349 | int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, |
350 | unsigned char *bytes, int len) | 350 | const unsigned char *bytes, int len) |
351 | { | 351 | { |
352 | int i; | 352 | int i; |
353 | 353 | ||
diff --git a/src/lib/libcrypto/x509/x_all.c b/src/lib/libcrypto/x509/x_all.c index fb5015cd4d..ac6dea493a 100644 --- a/src/lib/libcrypto/x509/x_all.c +++ b/src/lib/libcrypto/x509/x_all.c | |||
@@ -103,6 +103,7 @@ int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) | |||
103 | 103 | ||
104 | int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) | 104 | int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) |
105 | { | 105 | { |
106 | x->crl->enc.modified = 1; | ||
106 | return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO),x->crl->sig_alg, | 107 | return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO),x->crl->sig_alg, |
107 | x->sig_alg, x->signature, x->crl,pkey,md)); | 108 | x->sig_alg, x->signature, x->crl,pkey,md)); |
108 | } | 109 | } |