Branch data Line data Source code
1 : : /* crypto/x509/x509_cmp.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : :
59 : : #include <stdio.h>
60 : : #include <ctype.h>
61 : : #include "cryptlib.h"
62 : : #include <openssl/asn1.h>
63 : : #include <openssl/objects.h>
64 : : #include <openssl/x509.h>
65 : : #include <openssl/x509v3.h>
66 : :
67 : 107 : int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
68 : : {
69 : : int i;
70 : : X509_CINF *ai,*bi;
71 : :
72 : 107 : ai=a->cert_info;
73 : 107 : bi=b->cert_info;
74 : 107 : i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
75 [ + + ]: 107 : if (i) return(i);
76 : 57 : return(X509_NAME_cmp(ai->issuer,bi->issuer));
77 : : }
78 : :
79 : : #ifndef OPENSSL_NO_MD5
80 : 0 : unsigned long X509_issuer_and_serial_hash(X509 *a)
81 : : {
82 : 0 : unsigned long ret=0;
83 : : EVP_MD_CTX ctx;
84 : : unsigned char md[16];
85 : : char *f;
86 : :
87 : 0 : EVP_MD_CTX_init(&ctx);
88 : 0 : f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
89 [ # # ]: 0 : if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
90 : : goto err;
91 [ # # ]: 0 : if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
92 : : goto err;
93 : 0 : OPENSSL_free(f);
94 [ # # ]: 0 : if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
95 : 0 : (unsigned long)a->cert_info->serialNumber->length))
96 : : goto err;
97 [ # # ]: 0 : if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
98 : : goto err;
99 : 0 : ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
100 : 0 : ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
101 : : )&0xffffffffL;
102 : : err:
103 : 0 : EVP_MD_CTX_cleanup(&ctx);
104 : 0 : return(ret);
105 : : }
106 : : #endif
107 : :
108 : 0 : int X509_issuer_name_cmp(const X509 *a, const X509 *b)
109 : : {
110 : 0 : return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
111 : : }
112 : :
113 : 3735 : int X509_subject_name_cmp(const X509 *a, const X509 *b)
114 : : {
115 : 3735 : return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
116 : : }
117 : :
118 : 0 : int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
119 : : {
120 : 0 : return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
121 : : }
122 : :
123 : : #ifndef OPENSSL_NO_SHA
124 : 0 : int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
125 : : {
126 : 0 : return memcmp(a->sha1_hash, b->sha1_hash, 20);
127 : : }
128 : : #endif
129 : :
130 : 11264 : X509_NAME *X509_get_issuer_name(X509 *a)
131 : : {
132 : 11264 : return(a->cert_info->issuer);
133 : : }
134 : :
135 : 0 : unsigned long X509_issuer_name_hash(X509 *x)
136 : : {
137 : 0 : return(X509_NAME_hash(x->cert_info->issuer));
138 : : }
139 : :
140 : : #ifndef OPENSSL_NO_MD5
141 : 0 : unsigned long X509_issuer_name_hash_old(X509 *x)
142 : : {
143 : 0 : return(X509_NAME_hash_old(x->cert_info->issuer));
144 : : }
145 : : #endif
146 : :
147 : 56863 : X509_NAME *X509_get_subject_name(X509 *a)
148 : : {
149 : 56863 : return(a->cert_info->subject);
150 : : }
151 : :
152 : 2565 : ASN1_INTEGER *X509_get_serialNumber(X509 *a)
153 : : {
154 : 2565 : return(a->cert_info->serialNumber);
155 : : }
156 : :
157 : 4 : unsigned long X509_subject_name_hash(X509 *x)
158 : : {
159 : 4 : return(X509_NAME_hash(x->cert_info->subject));
160 : : }
161 : :
162 : : #ifndef OPENSSL_NO_MD5
163 : 0 : unsigned long X509_subject_name_hash_old(X509 *x)
164 : : {
165 : 0 : return(X509_NAME_hash_old(x->cert_info->subject));
166 : : }
167 : : #endif
168 : :
169 : : #ifndef OPENSSL_NO_SHA
170 : : /* Compare two certificates: they must be identical for
171 : : * this to work. NB: Although "cmp" operations are generally
172 : : * prototyped to take "const" arguments (eg. for use in
173 : : * STACKs), the way X509 handling is - these operations may
174 : : * involve ensuring the hashes are up-to-date and ensuring
175 : : * certain cert information is cached. So this is the point
176 : : * where the "depth-first" constification tree has to halt
177 : : * with an evil cast.
178 : : */
179 : 3038 : int X509_cmp(const X509 *a, const X509 *b)
180 : : {
181 : : int rv;
182 : : /* ensure hash is valid */
183 : 3038 : X509_check_purpose((X509 *)a, -1, 0);
184 : 3038 : X509_check_purpose((X509 *)b, -1, 0);
185 : :
186 : 3038 : rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
187 [ + + ]: 3038 : if (rv)
188 : : return rv;
189 : : /* Check for match against stored encoding too */
190 [ + - ][ + - ]: 12 : if (!a->cert_info->enc.modified && !b->cert_info->enc.modified)
191 : : {
192 : 12 : rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
193 [ + - ]: 12 : if (rv)
194 : : return rv;
195 : 12 : return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
196 : : a->cert_info->enc.len);
197 : : }
198 : : return rv;
199 : : }
200 : : #endif
201 : :
202 : :
203 : 12099 : int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
204 : : {
205 : : int ret;
206 : :
207 : : /* Ensure canonical encoding is present and up to date */
208 : :
209 [ + - ][ - + ]: 12099 : if (!a->canon_enc || a->modified)
210 : : {
211 : 0 : ret = i2d_X509_NAME((X509_NAME *)a, NULL);
212 [ # # ]: 0 : if (ret < 0)
213 : : return -2;
214 : : }
215 : :
216 [ + - ][ - + ]: 12099 : if (!b->canon_enc || b->modified)
217 : : {
218 : 0 : ret = i2d_X509_NAME((X509_NAME *)b, NULL);
219 [ # # ]: 0 : if (ret < 0)
220 : : return -2;
221 : : }
222 : :
223 : 12099 : ret = a->canon_enclen - b->canon_enclen;
224 : :
225 [ + + ]: 12099 : if (ret)
226 : : return ret;
227 : :
228 : 6129 : return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
229 : :
230 : : }
231 : :
232 : 21 : unsigned long X509_NAME_hash(X509_NAME *x)
233 : : {
234 : 21 : unsigned long ret=0;
235 : : unsigned char md[SHA_DIGEST_LENGTH];
236 : :
237 : : /* Make sure X509_NAME structure contains valid cached encoding */
238 : 21 : i2d_X509_NAME(x,NULL);
239 [ + - ]: 21 : if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
240 : : NULL))
241 : : return 0;
242 : :
243 : 63 : ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
244 : 42 : ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
245 : : )&0xffffffffL;
246 : 21 : return(ret);
247 : : }
248 : :
249 : :
250 : : #ifndef OPENSSL_NO_MD5
251 : : /* I now DER encode the name and hash it. Since I cache the DER encoding,
252 : : * this is reasonably efficient. */
253 : :
254 : 0 : unsigned long X509_NAME_hash_old(X509_NAME *x)
255 : : {
256 : : EVP_MD_CTX md_ctx;
257 : 0 : unsigned long ret=0;
258 : : unsigned char md[16];
259 : :
260 : : /* Make sure X509_NAME structure contains valid cached encoding */
261 : 0 : i2d_X509_NAME(x,NULL);
262 : 0 : EVP_MD_CTX_init(&md_ctx);
263 : 0 : EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
264 [ # # ]: 0 : if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
265 [ # # ]: 0 : && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
266 [ # # ]: 0 : && EVP_DigestFinal_ex(&md_ctx,md,NULL))
267 : 0 : ret=(((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
268 : 0 : ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
269 : : )&0xffffffffL;
270 : 0 : EVP_MD_CTX_cleanup(&md_ctx);
271 : :
272 : 0 : return(ret);
273 : : }
274 : : #endif
275 : :
276 : : /* Search a stack of X509 for a match */
277 : 57 : X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
278 : : ASN1_INTEGER *serial)
279 : : {
280 : : int i;
281 : : X509_CINF cinf;
282 : 57 : X509 x,*x509=NULL;
283 : :
284 [ + - ]: 57 : if(!sk) return NULL;
285 : :
286 : 57 : x.cert_info= &cinf;
287 : 57 : cinf.serialNumber=serial;
288 : 57 : cinf.issuer=name;
289 : :
290 [ + - ]: 107 : for (i=0; i<sk_X509_num(sk); i++)
291 : : {
292 : 107 : x509=sk_X509_value(sk,i);
293 [ + + ]: 107 : if (X509_issuer_and_serial_cmp(x509,&x) == 0)
294 : : return(x509);
295 : : }
296 : : return(NULL);
297 : : }
298 : :
299 : 20 : X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
300 : : {
301 : : X509 *x509;
302 : : int i;
303 : :
304 [ + + ]: 38 : for (i=0; i<sk_X509_num(sk); i++)
305 : : {
306 : 27 : x509=sk_X509_value(sk,i);
307 [ + + ]: 27 : if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
308 : : return(x509);
309 : : }
310 : : return(NULL);
311 : : }
312 : :
313 : 14609 : EVP_PKEY *X509_get_pubkey(X509 *x)
314 : : {
315 [ + - ][ + - ]: 14609 : if ((x == NULL) || (x->cert_info == NULL))
316 : : return(NULL);
317 : 14609 : return(X509_PUBKEY_get(x->cert_info->key));
318 : : }
319 : :
320 : 76 : ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
321 : : {
322 [ + - ]: 76 : if(!x) return NULL;
323 : 76 : return x->cert_info->key->public_key;
324 : : }
325 : :
326 : :
327 : 1130 : int X509_check_private_key(X509 *x, EVP_PKEY *k)
328 : : {
329 : : EVP_PKEY *xk;
330 : : int ret;
331 : :
332 : 1130 : xk=X509_get_pubkey(x);
333 : :
334 [ + - ]: 1130 : if (xk)
335 : 1130 : ret = EVP_PKEY_cmp(xk, k);
336 : : else
337 : : ret = -2;
338 : :
339 [ - - - + ]: 1130 : switch (ret)
340 : : {
341 : : case 1:
342 : : break;
343 : : case 0:
344 : 0 : X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
345 : 0 : break;
346 : : case -1:
347 : 0 : X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
348 : 0 : break;
349 : : case -2:
350 : 0 : X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
351 : : }
352 [ + - ]: 1130 : if (xk)
353 : 1130 : EVP_PKEY_free(xk);
354 [ - + ]: 1130 : if (ret > 0)
355 : : return 1;
356 : 0 : return 0;
357 : : }
358 : :
359 : : /* Check a suite B algorithm is permitted: pass in a public key and
360 : : * the NID of its signature (or 0 if no signature). The pflags is
361 : : * a pointer to a flags field which must contain the suite B verification
362 : : * flags.
363 : : */
364 : :
365 : : #ifndef OPENSSL_NO_EC
366 : :
367 : 0 : static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
368 : : {
369 : 0 : const EC_GROUP *grp = NULL;
370 : : int curve_nid;
371 [ # # ][ # # ]: 0 : if (pkey && pkey->type == EVP_PKEY_EC)
372 : 0 : grp = EC_KEY_get0_group(pkey->pkey.ec);
373 [ # # ]: 0 : if (!grp)
374 : : return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
375 : 0 : curve_nid = EC_GROUP_get_curve_name(grp);
376 : : /* Check curve is consistent with LOS */
377 [ # # ]: 0 : if (curve_nid == NID_secp384r1) /* P-384 */
378 : : {
379 : : /* Check signature algorithm is consistent with
380 : : * curve.
381 : : */
382 [ # # ]: 0 : if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
383 : : return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
384 [ # # ]: 0 : if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
385 : : return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
386 : : /* If we encounter P-384 we cannot use P-256 later */
387 : 0 : *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
388 : : }
389 [ # # ]: 0 : else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */
390 : : {
391 [ # # ]: 0 : if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
392 : : return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
393 [ # # ]: 0 : if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
394 : : return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
395 : : }
396 : : else
397 : : return X509_V_ERR_SUITE_B_INVALID_CURVE;
398 : :
399 : : return X509_V_OK;
400 : : }
401 : :
402 : 436 : int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
403 : : unsigned long flags)
404 : : {
405 : : int rv, i, sign_nid;
406 : 436 : EVP_PKEY *pk = NULL;
407 : : unsigned long tflags;
408 [ - + ]: 436 : if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
409 : : return X509_V_OK;
410 : 0 : tflags = flags;
411 : : /* If no EE certificate passed in must be first in chain */
412 [ # # ]: 0 : if (x == NULL)
413 : : {
414 : 0 : x = sk_X509_value(chain, 0);
415 : 0 : i = 1;
416 : : }
417 : : else
418 : : i = 0;
419 : :
420 [ # # ]: 0 : if (X509_get_version(x) != 2)
421 : : {
422 : : rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
423 : : /* Correct error depth */
424 : : i = 0;
425 : : goto end;
426 : : }
427 : :
428 : 0 : pk = X509_get_pubkey(x);
429 : : /* Check EE key only */
430 : 0 : rv = check_suite_b(pk, -1, &tflags);
431 [ # # ]: 0 : if (rv != X509_V_OK)
432 : : {
433 : : /* Correct error depth */
434 : : i = 0;
435 : : goto end;
436 : : }
437 [ # # ]: 0 : for(; i < sk_X509_num(chain); i++)
438 : : {
439 : 0 : sign_nid = X509_get_signature_nid(x);
440 : 0 : x = sk_X509_value(chain, i);
441 [ # # ]: 0 : if (X509_get_version(x) != 2)
442 : : {
443 : : rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
444 : : goto end;
445 : : }
446 : 0 : EVP_PKEY_free(pk);
447 : 0 : pk = X509_get_pubkey(x);
448 : 0 : rv = check_suite_b(pk, sign_nid, &tflags);
449 [ # # ]: 0 : if (rv != X509_V_OK)
450 : : goto end;
451 : : }
452 : :
453 : : /* Final check: root CA signature */
454 : 0 : rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
455 : : end:
456 [ # # ]: 0 : if (pk)
457 : 0 : EVP_PKEY_free(pk);
458 [ # # ]: 0 : if (rv != X509_V_OK)
459 : : {
460 : : /* Invalid signature or LOS errors are for previous cert */
461 [ # # ]: 0 : if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
462 [ # # ]: 0 : || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
463 : 0 : i--;
464 : : /* If we have LOS error and flags changed then we are signing
465 : : * P-384 with P-256. Use more meaninggul error.
466 : : */
467 [ # # ][ # # ]: 0 : if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
468 : 0 : rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
469 [ # # ]: 0 : if (perror_depth)
470 : 0 : *perror_depth = i;
471 : : }
472 : 0 : return rv;
473 : : }
474 : :
475 : 0 : int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
476 : : {
477 : : int sign_nid;
478 [ # # ]: 0 : if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
479 : : return X509_V_OK;
480 : 0 : sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
481 : 0 : return check_suite_b(pk, sign_nid, &flags);
482 : : }
483 : :
484 : : #else
485 : : int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
486 : : unsigned long flags)
487 : : {
488 : : return 0;
489 : : }
490 : :
491 : : int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
492 : : {
493 : : return 0;
494 : : }
495 : :
496 : : #endif
497 : : /* Not strictly speaking an "up_ref" as a STACK doesn't have a reference
498 : : * count but it has the same effect by duping the STACK and upping the ref
499 : : * of each X509 structure.
500 : : */
501 : 36 : STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
502 : : {
503 : : STACK_OF(X509) *ret;
504 : : int i;
505 : 36 : ret = sk_X509_dup(chain);
506 [ + + ]: 93 : for (i = 0; i < sk_X509_num(ret); i++)
507 : : {
508 : 57 : X509 *x = sk_X509_value(ret, i);
509 : 57 : CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
510 : : }
511 : 36 : return ret;
512 : : }
|