1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay (at) cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57 #include <openssl/asn1.h> 58 #include <openssl/asn1t.h> 59 #include <openssl/digest.h> 60 #include <openssl/err.h> 61 #include <openssl/mem.h> 62 #include <openssl/obj.h> 63 #include <openssl/stack.h> 64 #include <openssl/thread.h> 65 #include <openssl/x509.h> 66 #include <openssl/x509v3.h> 67 68 #include "../internal.h" 69 70 /* 71 * Method to handle CRL access. In general a CRL could be very large (several 72 * Mb) and can consume large amounts of resources if stored in memory by 73 * multiple processes. This method allows general CRL operations to be 74 * redirected to more efficient callbacks: for example a CRL entry database. 75 */ 76 77 #define X509_CRL_METHOD_DYNAMIC 1 78 79 struct x509_crl_method_st { 80 int flags; 81 int (*crl_init) (X509_CRL *crl); 82 int (*crl_free) (X509_CRL *crl); 83 int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, 84 ASN1_INTEGER *ser, X509_NAME *issuer); 85 int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); 86 }; 87 88 static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b); 89 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); 90 91 ASN1_SEQUENCE(X509_REVOKED) = { 92 ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), 93 ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), 94 ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) 95 } ASN1_SEQUENCE_END(X509_REVOKED) 96 97 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); 98 static int def_crl_lookup(X509_CRL *crl, 99 X509_REVOKED **ret, ASN1_INTEGER *serial, 100 X509_NAME *issuer); 101 102 static const X509_CRL_METHOD int_crl_meth = { 103 0, 104 0, 0, 105 def_crl_lookup, 106 def_crl_verify 107 }; 108 109 static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; 110 111 /* 112 * The X509_CRL_INFO structure needs a bit of customisation. Since we cache 113 * the original encoding the signature wont be affected by reordering of the 114 * revoked field. 115 */ 116 static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, 117 void *exarg) 118 { 119 X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; 120 121 if (!a || !a->revoked) 122 return 1; 123 switch (operation) { 124 /* 125 * Just set cmp function here. We don't sort because that would 126 * affect the output of X509_CRL_print(). 127 */ 128 case ASN1_OP_D2I_POST: 129 (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); 130 break; 131 } 132 return 1; 133 } 134 135 136 ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { 137 ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), 138 ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR), 139 ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), 140 ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), 141 ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), 142 ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), 143 ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) 144 } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) 145 146 /* 147 * Set CRL entry issuer according to CRL certificate issuer extension. Check 148 * for unhandled critical CRL entry extensions. 149 */ 150 151 static int crl_set_issuers(X509_CRL *crl) 152 { 153 154 size_t i, k; 155 int j; 156 GENERAL_NAMES *gens, *gtmp; 157 STACK_OF(X509_REVOKED) *revoked; 158 159 revoked = X509_CRL_get_REVOKED(crl); 160 161 gens = NULL; 162 for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { 163 X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); 164 STACK_OF(X509_EXTENSION) *exts; 165 ASN1_ENUMERATED *reason; 166 X509_EXTENSION *ext; 167 gtmp = X509_REVOKED_get_ext_d2i(rev, 168 NID_certificate_issuer, &j, NULL); 169 if (!gtmp && (j != -1)) { 170 crl->flags |= EXFLAG_INVALID; 171 return 1; 172 } 173 174 if (gtmp) { 175 gens = gtmp; 176 if (!crl->issuers) { 177 crl->issuers = sk_GENERAL_NAMES_new_null(); 178 if (!crl->issuers) 179 return 0; 180 } 181 if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) 182 return 0; 183 } 184 rev->issuer = gens; 185 186 reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); 187 if (!reason && (j != -1)) { 188 crl->flags |= EXFLAG_INVALID; 189 return 1; 190 } 191 192 if (reason) { 193 rev->reason = ASN1_ENUMERATED_get(reason); 194 ASN1_ENUMERATED_free(reason); 195 } else 196 rev->reason = CRL_REASON_NONE; 197 198 /* Check for critical CRL entry extensions */ 199 200 exts = rev->extensions; 201 202 for (k = 0; k < sk_X509_EXTENSION_num(exts); k++) { 203 ext = sk_X509_EXTENSION_value(exts, k); 204 if (ext->critical > 0) { 205 if (OBJ_obj2nid(ext->object) == NID_certificate_issuer) 206 continue; 207 crl->flags |= EXFLAG_CRITICAL; 208 break; 209 } 210 } 211 212 } 213 214 return 1; 215 216 } 217 218 /* 219 * The X509_CRL structure needs a bit of customisation. Cache some extensions 220 * and hash of the whole CRL. 221 */ 222 static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, 223 void *exarg) 224 { 225 X509_CRL *crl = (X509_CRL *)*pval; 226 STACK_OF(X509_EXTENSION) *exts; 227 X509_EXTENSION *ext; 228 size_t idx; 229 230 switch (operation) { 231 case ASN1_OP_NEW_POST: 232 crl->idp = NULL; 233 crl->akid = NULL; 234 crl->flags = 0; 235 crl->idp_flags = 0; 236 crl->idp_reasons = CRLDP_ALL_REASONS; 237 crl->meth = default_crl_method; 238 crl->meth_data = NULL; 239 crl->issuers = NULL; 240 crl->crl_number = NULL; 241 crl->base_crl_number = NULL; 242 break; 243 244 case ASN1_OP_D2I_POST: 245 X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); 246 crl->idp = X509_CRL_get_ext_d2i(crl, 247 NID_issuing_distribution_point, NULL, 248 NULL); 249 if (crl->idp) 250 setup_idp(crl, crl->idp); 251 252 crl->akid = X509_CRL_get_ext_d2i(crl, 253 NID_authority_key_identifier, NULL, 254 NULL); 255 256 crl->crl_number = X509_CRL_get_ext_d2i(crl, 257 NID_crl_number, NULL, NULL); 258 259 crl->base_crl_number = X509_CRL_get_ext_d2i(crl, 260 NID_delta_crl, NULL, 261 NULL); 262 /* Delta CRLs must have CRL number */ 263 if (crl->base_crl_number && !crl->crl_number) 264 crl->flags |= EXFLAG_INVALID; 265 266 /* 267 * See if we have any unhandled critical CRL extensions and indicate 268 * this in a flag. We only currently handle IDP so anything else 269 * critical sets the flag. This code accesses the X509_CRL structure 270 * directly: applications shouldn't do this. 271 */ 272 273 exts = crl->crl->extensions; 274 275 for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { 276 int nid; 277 ext = sk_X509_EXTENSION_value(exts, idx); 278 nid = OBJ_obj2nid(ext->object); 279 if (nid == NID_freshest_crl) 280 crl->flags |= EXFLAG_FRESHEST; 281 if (ext->critical > 0) { 282 /* We handle IDP and deltas */ 283 if ((nid == NID_issuing_distribution_point) 284 || (nid == NID_authority_key_identifier) 285 || (nid == NID_delta_crl)) 286 continue; 287 crl->flags |= EXFLAG_CRITICAL; 288 break; 289 } 290 } 291 292 if (!crl_set_issuers(crl)) 293 return 0; 294 295 if (crl->meth->crl_init) { 296 if (crl->meth->crl_init(crl) == 0) 297 return 0; 298 } 299 break; 300 301 case ASN1_OP_FREE_POST: 302 /* |crl->meth| may be NULL if constructing the object failed before 303 * |ASN1_OP_NEW_POST| was run. */ 304 if (crl->meth && crl->meth->crl_free) { 305 if (!crl->meth->crl_free(crl)) 306 return 0; 307 } 308 if (crl->akid) 309 AUTHORITY_KEYID_free(crl->akid); 310 if (crl->idp) 311 ISSUING_DIST_POINT_free(crl->idp); 312 ASN1_INTEGER_free(crl->crl_number); 313 ASN1_INTEGER_free(crl->base_crl_number); 314 sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); 315 break; 316 } 317 return 1; 318 } 319 320 /* Convert IDP into a more convenient form */ 321 322 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) 323 { 324 int idp_only = 0; 325 /* Set various flags according to IDP */ 326 crl->idp_flags |= IDP_PRESENT; 327 if (idp->onlyuser > 0) { 328 idp_only++; 329 crl->idp_flags |= IDP_ONLYUSER; 330 } 331 if (idp->onlyCA > 0) { 332 idp_only++; 333 crl->idp_flags |= IDP_ONLYCA; 334 } 335 if (idp->onlyattr > 0) { 336 idp_only++; 337 crl->idp_flags |= IDP_ONLYATTR; 338 } 339 340 if (idp_only > 1) 341 crl->idp_flags |= IDP_INVALID; 342 343 if (idp->indirectCRL > 0) 344 crl->idp_flags |= IDP_INDIRECT; 345 346 if (idp->onlysomereasons) { 347 crl->idp_flags |= IDP_REASONS; 348 if (idp->onlysomereasons->length > 0) 349 crl->idp_reasons = idp->onlysomereasons->data[0]; 350 if (idp->onlysomereasons->length > 1) 351 crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); 352 crl->idp_reasons &= CRLDP_ALL_REASONS; 353 } 354 355 DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); 356 } 357 358 ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = { 359 ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), 360 ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), 361 ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) 362 } ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL) 363 364 IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED) 365 366 IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED) 367 368 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO) 369 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL) 370 IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL) 371 372 static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b) 373 { 374 return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber, 375 (ASN1_STRING *)(*b)->serialNumber)); 376 } 377 378 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) 379 { 380 X509_CRL_INFO *inf; 381 inf = crl->crl; 382 if (!inf->revoked) 383 inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); 384 if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { 385 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 386 return 0; 387 } 388 inf->enc.modified = 1; 389 return 1; 390 } 391 392 int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r) 393 { 394 if (crl->meth->crl_verify) 395 return crl->meth->crl_verify(crl, r); 396 return 0; 397 } 398 399 int X509_CRL_get0_by_serial(X509_CRL *crl, 400 X509_REVOKED **ret, ASN1_INTEGER *serial) 401 { 402 if (crl->meth->crl_lookup) 403 return crl->meth->crl_lookup(crl, ret, serial, NULL); 404 return 0; 405 } 406 407 int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) 408 { 409 if (crl->meth->crl_lookup) 410 return crl->meth->crl_lookup(crl, ret, 411 X509_get_serialNumber(x), 412 X509_get_issuer_name(x)); 413 return 0; 414 } 415 416 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) 417 { 418 return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), 419 crl->sig_alg, crl->signature, crl->crl, r)); 420 } 421 422 static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, 423 X509_REVOKED *rev) 424 { 425 size_t i; 426 427 if (!rev->issuer) { 428 if (!nm) 429 return 1; 430 if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) 431 return 1; 432 return 0; 433 } 434 435 if (!nm) 436 nm = X509_CRL_get_issuer(crl); 437 438 for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { 439 GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); 440 if (gen->type != GEN_DIRNAME) 441 continue; 442 if (!X509_NAME_cmp(nm, gen->d.directoryName)) 443 return 1; 444 } 445 return 0; 446 447 } 448 449 static struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT; 450 451 static int def_crl_lookup(X509_CRL *crl, 452 X509_REVOKED **ret, ASN1_INTEGER *serial, 453 X509_NAME *issuer) 454 { 455 X509_REVOKED rtmp, *rev; 456 size_t idx; 457 rtmp.serialNumber = serial; 458 /* 459 * Sort revoked into serial number order if not already sorted. Do this 460 * under a lock to avoid race condition. 461 */ 462 463 CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock); 464 const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked); 465 CRYPTO_STATIC_MUTEX_unlock_read(&g_crl_sort_lock); 466 467 if (!is_sorted) { 468 CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock); 469 if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { 470 sk_X509_REVOKED_sort(crl->crl->revoked); 471 } 472 CRYPTO_STATIC_MUTEX_unlock_write(&g_crl_sort_lock); 473 } 474 475 if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) 476 return 0; 477 /* Need to look for matching name */ 478 for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { 479 rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); 480 if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) 481 return 0; 482 if (crl_revoked_issuer_match(crl, issuer, rev)) { 483 if (ret) 484 *ret = rev; 485 if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) 486 return 2; 487 return 1; 488 } 489 } 490 return 0; 491 } 492 493 void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) 494 { 495 if (meth == NULL) 496 default_crl_method = &int_crl_meth; 497 else 498 default_crl_method = meth; 499 } 500 501 X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), 502 int (*crl_free) (X509_CRL *crl), 503 int (*crl_lookup) (X509_CRL *crl, 504 X509_REVOKED **ret, 505 ASN1_INTEGER *ser, 506 X509_NAME *issuer), 507 int (*crl_verify) (X509_CRL *crl, 508 EVP_PKEY *pk)) 509 { 510 X509_CRL_METHOD *m; 511 m = OPENSSL_malloc(sizeof(X509_CRL_METHOD)); 512 if (!m) 513 return NULL; 514 m->crl_init = crl_init; 515 m->crl_free = crl_free; 516 m->crl_lookup = crl_lookup; 517 m->crl_verify = crl_verify; 518 m->flags = X509_CRL_METHOD_DYNAMIC; 519 return m; 520 } 521 522 void X509_CRL_METHOD_free(X509_CRL_METHOD *m) 523 { 524 if (!(m->flags & X509_CRL_METHOD_DYNAMIC)) 525 return; 526 OPENSSL_free(m); 527 } 528 529 void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) 530 { 531 crl->meth_data = dat; 532 } 533 534 void *X509_CRL_get_meth_data(X509_CRL *crl) 535 { 536 return crl->meth_data; 537 } 538 539 IMPLEMENT_ASN1_SET_OF(X509_REVOKED) 540 541 IMPLEMENT_ASN1_SET_OF(X509_CRL) 542