1 /* crypto/asn1/x_crl.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 "cryptlib.h"
  61 #include "asn1_locl.h"
  62 #include <openssl/asn1t.h>
  63 #include <openssl/x509.h>
  64 #include <openssl/x509v3.h>
  65 
  66 static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
  67                                 const X509_REVOKED * const *b);
  68 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
  69 
  70 ASN1_SEQUENCE(X509_REVOKED) = {
  71         ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
  72         ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
  73         ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
  74 } ASN1_SEQUENCE_END(X509_REVOKED)
  75 
  76 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
  77 static int def_crl_lookup(X509_CRL *crl,
  78                 X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
  79 
  80 static X509_CRL_METHOD int_crl_meth =
  81         {
  82         0,
  83         0,0,
  84         def_crl_lookup,
  85         def_crl_verify
  86         };
  87 
  88 static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
  89 
  90 /* The X509_CRL_INFO structure needs a bit of customisation.
  91  * Since we cache the original encoding the signature wont be affected by
  92  * reordering of the revoked field.
  93  */
  94 static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
  95                                                                 void *exarg)
  96 {
  97         X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
  98 
  99         if(!a || !a->revoked) return 1;
 100         switch(operation) {
 101                 /* Just set cmp function here. We don't sort because that
 102                  * would affect the output of X509_CRL_print().
 103                  */
 104                 case ASN1_OP_D2I_POST:
 105                 (void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
 106                 break;
 107         }
 108         return 1;
 109 }
 110 
 111 
 112 ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
 113         ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
 114         ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
 115         ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
 116         ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
 117         ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
 118         ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
 119         ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
 120 } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
 121 
 122 /* Set CRL entry issuer according to CRL certificate issuer extension.
 123  * Check for unhandled critical CRL entry extensions.
 124  */
 125 
 126 static int crl_set_issuers(X509_CRL *crl)
 127         {
 128 
 129         int i, j;
 130         GENERAL_NAMES *gens, *gtmp;
 131         STACK_OF(X509_REVOKED) *revoked;
 132 
 133         revoked = X509_CRL_get_REVOKED(crl);
 134 
 135         gens = NULL;
 136         for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
 137                 {
 138                 X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
 139                 STACK_OF(X509_EXTENSION) *exts;
 140                 ASN1_ENUMERATED *reason;
 141                 X509_EXTENSION *ext;
 142                 gtmp = X509_REVOKED_get_ext_d2i(rev,
 143                                                 NID_certificate_issuer,
 144                                                 &j, NULL);
 145                 if (!gtmp && (j != -1))
 146                         {
 147                         crl->flags |= EXFLAG_INVALID;
 148                         return 1;
 149                         }
 150 
 151                 if (gtmp)
 152                         {
 153                         gens = gtmp;
 154                         if (!crl->issuers)
 155                                 {
 156                                 crl->issuers = sk_GENERAL_NAMES_new_null();
 157                                 if (!crl->issuers)
 158                                         return 0;
 159                                 }
 160                         if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
 161                                 return 0;
 162                         }
 163                 rev->issuer = gens;
 164 
 165                 reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
 166                                                                 &j, NULL);
 167                 if (!reason && (j != -1))
 168                         {
 169                         crl->flags |= EXFLAG_INVALID;
 170                         return 1;
 171                         }
 172 
 173                 if (reason)
 174                         {
 175                         rev->reason = ASN1_ENUMERATED_get(reason);
 176                         ASN1_ENUMERATED_free(reason);
 177                         }
 178                 else
 179                         rev->reason = CRL_REASON_NONE;
 180 
 181                 /* Check for critical CRL entry extensions */
 182 
 183                 exts = rev->extensions;
 184 
 185                 for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
 186                         {
 187                         ext = sk_X509_EXTENSION_value(exts, j);
 188                         if (ext->critical > 0)
 189                                 {
 190                                 if (OBJ_obj2nid(ext->object) ==
 191                                         NID_certificate_issuer)
 192                                         continue;
 193                                 crl->flags |= EXFLAG_CRITICAL;
 194                                 break;
 195                                 }
 196                         }
 197 
 198 
 199                 }
 200 
 201         return 1;
 202 
 203         }
 204 
 205 /* The X509_CRL structure needs a bit of customisation. Cache some extensions
 206  * and hash of the whole CRL.
 207  */
 208 static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 209                                                                 void *exarg)
 210         {
 211         X509_CRL *crl = (X509_CRL *)*pval;
 212         STACK_OF(X509_EXTENSION) *exts;
 213         X509_EXTENSION *ext;
 214         int idx;
 215 
 216         switch(operation)
 217                 {
 218                 case ASN1_OP_NEW_POST:
 219                 crl->idp = NULL;
 220                 crl->akid = NULL;
 221                 crl->flags = 0;
 222                 crl->idp_flags = 0;
 223                 crl->idp_reasons = CRLDP_ALL_REASONS;
 224                 crl->meth = default_crl_method;
 225                 crl->meth_data = NULL;
 226                 crl->issuers = NULL;
 227                 crl->crl_number = NULL;
 228                 crl->base_crl_number = NULL;
 229                 break;
 230 
 231                 case ASN1_OP_D2I_POST:
 232 #ifndef OPENSSL_NO_SHA
 233                 X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
 234 #endif
 235                 crl->idp = X509_CRL_get_ext_d2i(crl,
 236                                 NID_issuing_distribution_point, NULL, NULL);
 237                 if (crl->idp)
 238                         setup_idp(crl, crl->idp);
 239 
 240                 crl->akid = X509_CRL_get_ext_d2i(crl,
 241                                 NID_authority_key_identifier, NULL, NULL);
 242 
 243                 crl->crl_number = X509_CRL_get_ext_d2i(crl,
 244                                 NID_crl_number, NULL, NULL);
 245 
 246                 crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
 247                                 NID_delta_crl, NULL, NULL);
 248                 /* Delta CRLs must have CRL number */
 249                 if (crl->base_crl_number && !crl->crl_number)
 250                         crl->flags |= EXFLAG_INVALID;
 251 
 252                 /* See if we have any unhandled critical CRL extensions and
 253                  * indicate this in a flag. We only currently handle IDP so
 254                  * anything else critical sets the flag.
 255                  *
 256                  * This code accesses the X509_CRL structure directly:
 257                  * applications shouldn't do this.
 258                  */
 259 
 260                 exts = crl->crl->extensions;
 261 
 262                 for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
 263                         {
 264                         int nid;
 265                         ext = sk_X509_EXTENSION_value(exts, idx);
 266                         nid = OBJ_obj2nid(ext->object);
 267                         if (nid == NID_freshest_crl)
 268                                 crl->flags |= EXFLAG_FRESHEST;
 269                         if (ext->critical > 0)
 270                                 {
 271                                 /* We handle IDP and deltas */
 272                                 if ((nid == NID_issuing_distribution_point)
 273                                         || (nid == NID_authority_key_identifier)
 274                                         || (nid == NID_delta_crl))
 275                                         break;;
 276                                 crl->flags |= EXFLAG_CRITICAL;
 277                                 break;
 278                                 }
 279                         }
 280 
 281 
 282                 if (!crl_set_issuers(crl))
 283                         return 0;
 284 
 285                 if (crl->meth->crl_init)
 286                         {
 287                         if (crl->meth->crl_init(crl) == 0)
 288                                 return 0;
 289                         }
 290                 break;
 291 
 292                 case ASN1_OP_FREE_POST:
 293                 if (crl->meth->crl_free)
 294                         {
 295                         if (!crl->meth->crl_free(crl))
 296                                 return 0;
 297                         }
 298                 if (crl->akid)
 299                         AUTHORITY_KEYID_free(crl->akid);
 300                 if (crl->idp)
 301                         ISSUING_DIST_POINT_free(crl->idp);
 302                 ASN1_INTEGER_free(crl->crl_number);
 303                 ASN1_INTEGER_free(crl->base_crl_number);
 304                 sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
 305                 break;
 306                 }
 307         return 1;
 308         }
 309 
 310 /* Convert IDP into a more convenient form */
 311 
 312 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
 313         {
 314         int idp_only = 0;
 315         /* Set various flags according to IDP */
 316         crl->idp_flags |= IDP_PRESENT;
 317         if (idp->onlyuser > 0)
 318                 {
 319                 idp_only++;
 320                 crl->idp_flags |= IDP_ONLYUSER;
 321                 }
 322         if (idp->onlyCA > 0)
 323                 {
 324                 idp_only++;
 325                 crl->idp_flags |= IDP_ONLYCA;
 326                 }
 327         if (idp->onlyattr > 0)
 328                 {
 329                 idp_only++;
 330                 crl->idp_flags |= IDP_ONLYATTR;
 331                 }
 332 
 333         if (idp_only > 1)
 334                 crl->idp_flags |= IDP_INVALID;
 335 
 336         if (idp->indirectCRL > 0)
 337                 crl->idp_flags |= IDP_INDIRECT;
 338 
 339         if (idp->onlysomereasons)
 340                 {
 341                 crl->idp_flags |= IDP_REASONS;
 342                 if (idp->onlysomereasons->length > 0)
 343                         crl->idp_reasons = idp->onlysomereasons->data[0];
 344                 if (idp->onlysomereasons->length > 1)
 345                         crl->idp_reasons |=
 346                                 (idp->onlysomereasons->data[1] << 8);
 347                 crl->idp_reasons &= CRLDP_ALL_REASONS;
 348                 }
 349 
 350         DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
 351         }
 352 
 353 ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
 354         ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
 355         ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
 356         ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
 357 } ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
 358 
 359 IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
 360 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
 361 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
 362 IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
 363 
 364 static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
 365                         const X509_REVOKED * const *b)
 366         {
 367         return(ASN1_STRING_cmp(
 368                 (ASN1_STRING *)(*a)->serialNumber,
 369                 (ASN1_STRING *)(*b)->serialNumber));
 370         }
 371 
 372 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
 373 {
 374         X509_CRL_INFO *inf;
 375         inf = crl->crl;
 376         if(!inf->revoked)
 377                 inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
 378         if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
 379                 ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
 380                 return 0;
 381         }
 382         inf->enc.modified = 1;
 383         return 1;
 384 }
 385 
 386 int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
 387         {
 388         if (crl->meth->crl_verify)
 389                 return crl->meth->crl_verify(crl, r);
 390         return 0;
 391         }
 392 
 393 int X509_CRL_get0_by_serial(X509_CRL *crl,
 394                 X509_REVOKED **ret, ASN1_INTEGER *serial)
 395         {
 396         if (crl->meth->crl_lookup)
 397                 return crl->meth->crl_lookup(crl, ret, serial, NULL);
 398         return 0;
 399         }
 400 
 401 int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
 402         {
 403         if (crl->meth->crl_lookup)
 404                 return crl->meth->crl_lookup(crl, ret,
 405                                                 X509_get_serialNumber(x),
 406                                                 X509_get_issuer_name(x));
 407         return 0;
 408         }
 409 
 410 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
 411         {
 412         return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
 413                 crl->sig_alg, crl->signature,crl->crl,r));
 414         }
 415 
 416 static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
 417                                                 X509_REVOKED *rev)
 418         {
 419         int i;
 420 
 421         if (!rev->issuer)
 422                 {
 423                 if (!nm)
 424                         return 1;
 425                 if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
 426                         return 1;
 427                 return 0;
 428                 }
 429 
 430         if (!nm)
 431                 nm = X509_CRL_get_issuer(crl);
 432 
 433         for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
 434                 {
 435                 GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
 436                 if (gen->type != GEN_DIRNAME)
 437                         continue;
 438                 if (!X509_NAME_cmp(nm, gen->d.directoryName))
 439                         return 1;
 440                 }
 441         return 0;
 442 
 443         }
 444 
 445 static int def_crl_lookup(X509_CRL *crl,
 446                 X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
 447         {
 448         X509_REVOKED rtmp, *rev;
 449         int idx;
 450         rtmp.serialNumber = serial;
 451         /* Sort revoked into serial number order if not already sorted.
 452          * Do this under a lock to avoid race condition.
 453          */
 454         if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
 455                 {
 456                 CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
 457                 sk_X509_REVOKED_sort(crl->crl->revoked);
 458                 CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
 459                 }
 460         idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
 461         if(idx < 0)
 462                 return 0;
 463         /* Need to look for matching name */
 464         for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
 465                 {
 466                 rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
 467                 if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
 468                         return 0;
 469                 if (crl_revoked_issuer_match(crl, issuer, rev))
 470                         {
 471                         if (ret)
 472                                 *ret = rev;
 473                         if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
 474                                 return 2;
 475                         return 1;
 476                         }
 477                 }
 478         return 0;
 479         }
 480 
 481 void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
 482         {
 483         if (meth == NULL)
 484                 default_crl_method = &int_crl_meth;
 485         else
 486                 default_crl_method = meth;
 487         }
 488 
 489 X509_CRL_METHOD *X509_CRL_METHOD_new(
 490         int (*crl_init)(X509_CRL *crl),
 491         int (*crl_free)(X509_CRL *crl),
 492         int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
 493                                 ASN1_INTEGER *ser, X509_NAME *issuer),
 494         int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
 495         {
 496         X509_CRL_METHOD *m;
 497         m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
 498         if (!m)
 499                 return NULL;
 500         m->crl_init = crl_init;
 501         m->crl_free = crl_free;
 502         m->crl_lookup = crl_lookup;
 503         m->crl_verify = crl_verify;
 504         m->flags = X509_CRL_METHOD_DYNAMIC;
 505         return m;
 506         }
 507 
 508 void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
 509         {
 510         if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
 511                 return;
 512         OPENSSL_free(m);
 513         }
 514 
 515 void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
 516         {
 517         crl->meth_data = dat;
 518         }
 519 
 520 void *X509_CRL_get_meth_data(X509_CRL *crl)
 521         {
 522         return crl->meth_data;
 523         }
 524 
 525 IMPLEMENT_STACK_OF(X509_REVOKED)
 526 IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
 527 IMPLEMENT_STACK_OF(X509_CRL)
 528 IMPLEMENT_ASN1_SET_OF(X509_CRL)