1 /* crypto/cms/cms_lib.c */
   2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
   3  * project.
   4  */
   5 /* ====================================================================
   6  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions
  10  * are met:
  11  *
  12  * 1. Redistributions of source code must retain the above copyright
  13  *    notice, this list of conditions and the following disclaimer.
  14  *
  15  * 2. Redistributions in binary form must reproduce the above copyright
  16  *    notice, this list of conditions and the following disclaimer in
  17  *    the documentation and/or other materials provided with the
  18  *    distribution.
  19  *
  20  * 3. All advertising materials mentioning features or use of this
  21  *    software must display the following acknowledgment:
  22  *    "This product includes software developed by the OpenSSL Project
  23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24  *
  25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26  *    endorse or promote products derived from this software without
  27  *    prior written permission. For written permission, please contact
  28  *    licensing@OpenSSL.org.
  29  *
  30  * 5. Products derived from this software may not be called "OpenSSL"
  31  *    nor may "OpenSSL" appear in their names without prior written
  32  *    permission of the OpenSSL Project.
  33  *
  34  * 6. Redistributions of any form whatsoever must retain the following
  35  *    acknowledgment:
  36  *    "This product includes software developed by the OpenSSL Project
  37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38  *
  39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50  * OF THE POSSIBILITY OF SUCH DAMAGE.
  51  * ====================================================================
  52  */
  53 
  54 #include <openssl/asn1t.h>
  55 #include <openssl/x509.h>
  56 #include <openssl/err.h>
  57 #include <openssl/pem.h>
  58 #include <openssl/bio.h>
  59 #include <openssl/asn1.h>
  60 #include "cms.h"
  61 #include "cms_lcl.h"
  62 
  63 IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
  64 IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
  65 
  66 DECLARE_ASN1_ITEM(CMS_CertificateChoices)
  67 DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
  68 DECLARE_STACK_OF(CMS_CertificateChoices)
  69 DECLARE_STACK_OF(CMS_RevocationInfoChoice)
  70 
  71 const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
  72         {
  73         return cms->contentType;
  74         }
  75 
  76 CMS_ContentInfo *cms_Data_create(void)
  77         {
  78         CMS_ContentInfo *cms;
  79         cms = CMS_ContentInfo_new();
  80         if (cms)
  81                 {
  82                 cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
  83                 /* Never detached */
  84                 CMS_set_detached(cms, 0);
  85                 }
  86         return cms;
  87         }
  88 
  89 BIO *cms_content_bio(CMS_ContentInfo *cms)
  90         {
  91         ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
  92         if (!pos)
  93                 return NULL;
  94         /* If content detached data goes nowhere: create NULL BIO */
  95         if (!*pos)
  96                 return BIO_new(BIO_s_null());
  97         /* If content not detached and created return memory BIO
  98          */
  99         if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
 100                 return BIO_new(BIO_s_mem());
 101         /* Else content was read in: return read only BIO for it */
 102         return BIO_new_mem_buf((*pos)->data, (*pos)->length);
 103         }
 104 
 105 BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
 106         {
 107         BIO *cmsbio, *cont;
 108         if (icont)
 109                 cont = icont;
 110         else
 111                 cont = cms_content_bio(cms);
 112         if (!cont)
 113                 {
 114                 CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
 115                 return NULL;
 116                 }
 117         switch (OBJ_obj2nid(cms->contentType))
 118                 {
 119 
 120                 case NID_pkcs7_data:
 121                 return cont;
 122 
 123                 case NID_pkcs7_signed:
 124                 cmsbio = cms_SignedData_init_bio(cms);
 125                 break;
 126 
 127                 case NID_pkcs7_digest:
 128                 cmsbio = cms_DigestedData_init_bio(cms);
 129                 break;
 130 #ifdef ZLIB
 131                 case NID_id_smime_ct_compressedData:
 132                 cmsbio = cms_CompressedData_init_bio(cms);
 133                 break;
 134 #endif
 135 
 136                 case NID_pkcs7_encrypted:
 137                 cmsbio = cms_EncryptedData_init_bio(cms);
 138                 break;
 139 
 140                 case NID_pkcs7_enveloped:
 141                 cmsbio = cms_EnvelopedData_init_bio(cms);
 142                 break;
 143 
 144                 default:
 145                 CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
 146                 return NULL;
 147                 }
 148 
 149         if (cmsbio)
 150                 return BIO_push(cmsbio, cont);
 151 
 152         if (!icont)
 153                 BIO_free(cont);
 154         return NULL;
 155 
 156         }
 157 
 158 int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
 159         {
 160         ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
 161         if (!pos)
 162                 return 0;
 163         /* If ebmedded content find memory BIO and set content */
 164         if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
 165                 {
 166                 BIO *mbio;
 167                 unsigned char *cont;
 168                 long contlen;
 169                 mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
 170                 if (!mbio)
 171                         {
 172                         CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
 173                         return 0;
 174                         }
 175                 contlen = BIO_get_mem_data(mbio, &cont);
 176                 /* Set bio as read only so its content can't be clobbered */
 177                 BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
 178                 BIO_set_mem_eof_return(mbio, 0);
 179                 ASN1_STRING_set0(*pos, cont, contlen);
 180                 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
 181                 }
 182 
 183         switch (OBJ_obj2nid(cms->contentType))
 184                 {
 185 
 186                 case NID_pkcs7_data:
 187                 case NID_pkcs7_enveloped:
 188                 case NID_pkcs7_encrypted:
 189                 case NID_id_smime_ct_compressedData:
 190                 /* Nothing to do */
 191                 return 1;
 192 
 193                 case NID_pkcs7_signed:
 194                 return cms_SignedData_final(cms, cmsbio);
 195 
 196                 case NID_pkcs7_digest:
 197                 return cms_DigestedData_do_final(cms, cmsbio, 0);
 198 
 199                 default:
 200                 CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
 201                 return 0;
 202                 }
 203         }
 204 
 205 /* Return an OCTET STRING pointer to content. This allows it to
 206  * be accessed or set later.
 207  */
 208 
 209 ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
 210         {
 211         switch (OBJ_obj2nid(cms->contentType))
 212                 {
 213 
 214                 case NID_pkcs7_data:
 215                 return &cms->d.data;
 216 
 217                 case NID_pkcs7_signed:
 218                 return &cms->d.signedData->encapContentInfo->eContent;
 219 
 220                 case NID_pkcs7_enveloped:
 221                 return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
 222 
 223                 case NID_pkcs7_digest:
 224                 return &cms->d.digestedData->encapContentInfo->eContent;
 225 
 226                 case NID_pkcs7_encrypted:
 227                 return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
 228 
 229                 case NID_id_smime_ct_authData:
 230                 return &cms->d.authenticatedData->encapContentInfo->eContent;
 231 
 232                 case NID_id_smime_ct_compressedData:
 233                 return &cms->d.compressedData->encapContentInfo->eContent;
 234 
 235                 default:
 236                 if (cms->d.other->type == V_ASN1_OCTET_STRING)
 237                         return &cms->d.other->value.octet_string;
 238                 CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
 239                 return NULL;
 240 
 241                 }
 242         }
 243 
 244 /* Return an ASN1_OBJECT pointer to content type. This allows it to
 245  * be accessed or set later.
 246  */
 247 
 248 static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
 249         {
 250         switch (OBJ_obj2nid(cms->contentType))
 251                 {
 252 
 253                 case NID_pkcs7_signed:
 254                 return &cms->d.signedData->encapContentInfo->eContentType;
 255 
 256                 case NID_pkcs7_enveloped:
 257                 return &cms->d.envelopedData->encryptedContentInfo->contentType;
 258 
 259                 case NID_pkcs7_digest:
 260                 return &cms->d.digestedData->encapContentInfo->eContentType;
 261 
 262                 case NID_pkcs7_encrypted:
 263                 return &cms->d.encryptedData->encryptedContentInfo->contentType;
 264 
 265                 case NID_id_smime_ct_authData:
 266                 return &cms->d.authenticatedData->encapContentInfo->eContentType;
 267 
 268                 case NID_id_smime_ct_compressedData:
 269                 return &cms->d.compressedData->encapContentInfo->eContentType;
 270 
 271                 default:
 272                 CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
 273                                         CMS_R_UNSUPPORTED_CONTENT_TYPE);
 274                 return NULL;
 275 
 276                 }
 277         }
 278 
 279 const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
 280         {
 281         ASN1_OBJECT **petype;
 282         petype = cms_get0_econtent_type(cms);
 283         if (petype)
 284                 return *petype;
 285         return NULL;
 286         }
 287 
 288 int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
 289         {
 290         ASN1_OBJECT **petype, *etype;
 291         petype = cms_get0_econtent_type(cms);
 292         if (!petype)
 293                 return 0;
 294         if (!oid)
 295                 return 1;
 296         etype = OBJ_dup(oid);
 297         if (!etype)
 298                 return 0;
 299         ASN1_OBJECT_free(*petype);
 300         *petype = etype;
 301         return 1;
 302         }
 303 
 304 int CMS_is_detached(CMS_ContentInfo *cms)
 305         {
 306         ASN1_OCTET_STRING **pos;
 307         pos = CMS_get0_content(cms);
 308         if (!pos)
 309                 return -1;
 310         if (*pos)
 311                 return 0;
 312         return 1;
 313         }
 314 
 315 int CMS_set_detached(CMS_ContentInfo *cms, int detached)
 316         {
 317         ASN1_OCTET_STRING **pos;
 318         pos = CMS_get0_content(cms);
 319         if (!pos)
 320                 return 0;
 321         if (detached)
 322                 {
 323                 if (*pos)
 324                         {
 325                         ASN1_OCTET_STRING_free(*pos);
 326                         *pos = NULL;
 327                         }
 328                 return 1;
 329                 }
 330         if (!*pos)
 331                 *pos = ASN1_OCTET_STRING_new();
 332         if (*pos)
 333                 {
 334                 /* NB: special flag to show content is created and not
 335                  * read in.
 336                  */
 337                 (*pos)->flags |= ASN1_STRING_FLAG_CONT;
 338                 return 1;
 339                 }
 340         CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
 341         return 0;
 342         }
 343 
 344 /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
 345 
 346 void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
 347         {
 348         int param_type;
 349 
 350         if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
 351                 param_type = V_ASN1_UNDEF;
 352         else
 353                 param_type = V_ASN1_NULL;
 354 
 355         X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
 356 
 357         }
 358 
 359 /* Create a digest BIO from an X509_ALGOR structure */
 360 
 361 BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
 362         {
 363         BIO *mdbio = NULL;
 364         ASN1_OBJECT *digestoid;
 365         const EVP_MD *digest;
 366         X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
 367         digest = EVP_get_digestbyobj(digestoid);
 368         if (!digest)
 369                 {
 370                 CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
 371                                 CMS_R_UNKNOWN_DIGEST_ALGORIHM);
 372                 goto err;
 373                 }
 374         mdbio = BIO_new(BIO_f_md());
 375         if (!mdbio || !BIO_set_md(mdbio, digest))
 376                 {
 377                 CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
 378                                 CMS_R_MD_BIO_INIT_ERROR);
 379                 goto err;
 380                 }
 381         return mdbio;
 382         err:
 383         if (mdbio)
 384                 BIO_free(mdbio);
 385         return NULL;
 386         }
 387 
 388 /* Locate a message digest content from a BIO chain based on SignerInfo */
 389 
 390 int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
 391                                         X509_ALGOR *mdalg)
 392         {
 393         int nid;
 394         ASN1_OBJECT *mdoid;
 395         X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
 396         nid = OBJ_obj2nid(mdoid);
 397         /* Look for digest type to match signature */
 398         for (;;)
 399                 {
 400                 EVP_MD_CTX *mtmp;
 401                 chain = BIO_find_type(chain, BIO_TYPE_MD);
 402                 if (chain == NULL)
 403                         {
 404                         CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
 405                                                 CMS_R_NO_MATCHING_DIGEST);
 406                         return 0;
 407                         }
 408                 BIO_get_md_ctx(chain, &mtmp);
 409                 if (EVP_MD_CTX_type(mtmp) == nid
 410                 /* Workaround for broken implementations that use signature
 411                  * algorithm  OID instead of digest.
 412                  */
 413                         || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
 414                         return EVP_MD_CTX_copy_ex(mctx, mtmp);
 415                 chain = BIO_next(chain);
 416                 }
 417         }
 418 
 419 static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
 420         {
 421         switch (OBJ_obj2nid(cms->contentType))
 422                 {
 423 
 424                 case NID_pkcs7_signed:
 425                 return &cms->d.signedData->certificates;
 426 
 427                 case NID_pkcs7_enveloped:
 428                 return &cms->d.envelopedData->originatorInfo->certificates;
 429 
 430                 default:
 431                 CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
 432                                         CMS_R_UNSUPPORTED_CONTENT_TYPE);
 433                 return NULL;
 434 
 435                 }
 436         }
 437 
 438 CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
 439         {
 440         STACK_OF(CMS_CertificateChoices) **pcerts;
 441         CMS_CertificateChoices *cch;
 442         pcerts = cms_get0_certificate_choices(cms);
 443         if (!pcerts)
 444                 return NULL;
 445         if (!*pcerts)
 446                 *pcerts = sk_CMS_CertificateChoices_new_null();
 447         if (!*pcerts)
 448                 return NULL;
 449         cch = M_ASN1_new_of(CMS_CertificateChoices);
 450         if (!cch)
 451                 return NULL;
 452         if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
 453                 {
 454                 M_ASN1_free_of(cch, CMS_CertificateChoices);
 455                 return NULL;
 456                 }
 457         return cch;
 458         }
 459 
 460 int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
 461         {
 462         CMS_CertificateChoices *cch;
 463         STACK_OF(CMS_CertificateChoices) **pcerts;
 464         int i;
 465         pcerts = cms_get0_certificate_choices(cms);
 466         if (!pcerts)
 467                 return 0;
 468         for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
 469                 {
 470                 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
 471                 if (cch->type == CMS_CERTCHOICE_CERT)
 472                         {
 473                         if (!X509_cmp(cch->d.certificate, cert))
 474                                 {
 475                                 CMSerr(CMS_F_CMS_ADD0_CERT,
 476                                         CMS_R_CERTIFICATE_ALREADY_PRESENT);
 477                                 return 0;
 478                                 }
 479                         }
 480                 }
 481         cch = CMS_add0_CertificateChoices(cms);
 482         if (!cch)
 483                 return 0;
 484         cch->type = CMS_CERTCHOICE_CERT;
 485         cch->d.certificate = cert;
 486         return 1;
 487         }
 488 
 489 int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
 490         {
 491         int r;
 492         r = CMS_add0_cert(cms, cert);
 493         if (r > 0)
 494                 CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
 495         return r;
 496         }
 497 
 498 static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
 499         {
 500         switch (OBJ_obj2nid(cms->contentType))
 501                 {
 502 
 503                 case NID_pkcs7_signed:
 504                 return &cms->d.signedData->crls;
 505 
 506                 case NID_pkcs7_enveloped:
 507                 return &cms->d.envelopedData->originatorInfo->crls;
 508 
 509                 default:
 510                 CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
 511                                         CMS_R_UNSUPPORTED_CONTENT_TYPE);
 512                 return NULL;
 513 
 514                 }
 515         }
 516 
 517 CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
 518         {
 519         STACK_OF(CMS_RevocationInfoChoice) **pcrls;
 520         CMS_RevocationInfoChoice *rch;
 521         pcrls = cms_get0_revocation_choices(cms);
 522         if (!pcrls)
 523                 return NULL;
 524         if (!*pcrls)
 525                 *pcrls = sk_CMS_RevocationInfoChoice_new_null();
 526         if (!*pcrls)
 527                 return NULL;
 528         rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
 529         if (!rch)
 530                 return NULL;
 531         if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
 532                 {
 533                 M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
 534                 return NULL;
 535                 }
 536         return rch;
 537         }
 538 
 539 int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
 540         {
 541         CMS_RevocationInfoChoice *rch;
 542         rch = CMS_add0_RevocationInfoChoice(cms);
 543         if (!rch)
 544                 return 0;
 545         rch->type = CMS_REVCHOICE_CRL;
 546         rch->d.crl = crl;
 547         return 1;
 548         }
 549 
 550 int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
 551         {
 552         int r;
 553         r = CMS_add0_crl(cms, crl);
 554         if (r > 0)
 555                 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
 556         return r;
 557         }
 558 
 559 STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
 560         {
 561         STACK_OF(X509) *certs = NULL;
 562         CMS_CertificateChoices *cch;
 563         STACK_OF(CMS_CertificateChoices) **pcerts;
 564         int i;
 565         pcerts = cms_get0_certificate_choices(cms);
 566         if (!pcerts)
 567                 return NULL;
 568         for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
 569                 {
 570                 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
 571                 if (cch->type == 0)
 572                         {
 573                         if (!certs)
 574                                 {
 575                                 certs = sk_X509_new_null();
 576                                 if (!certs)
 577                                         return NULL;
 578                                 }
 579                         if (!sk_X509_push(certs, cch->d.certificate))
 580                                 {
 581                                 sk_X509_pop_free(certs, X509_free);
 582                                 return NULL;
 583                                 }
 584                         CRYPTO_add(&cch->d.certificate->references,
 585                                                 1, CRYPTO_LOCK_X509);
 586                         }
 587                 }
 588         return certs;
 589 
 590         }
 591 
 592 STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
 593         {
 594         STACK_OF(X509_CRL) *crls = NULL;
 595         STACK_OF(CMS_RevocationInfoChoice) **pcrls;
 596         CMS_RevocationInfoChoice *rch;
 597         int i;
 598         pcrls = cms_get0_revocation_choices(cms);
 599         if (!pcrls)
 600                 return NULL;
 601         for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
 602                 {
 603                 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
 604                 if (rch->type == 0)
 605                         {
 606                         if (!crls)
 607                                 {
 608                                 crls = sk_X509_CRL_new_null();
 609                                 if (!crls)
 610                                         return NULL;
 611                                 }
 612                         if (!sk_X509_CRL_push(crls, rch->d.crl))
 613                                 {
 614                                 sk_X509_CRL_pop_free(crls, X509_CRL_free);
 615                                 return NULL;
 616                                 }
 617                         CRYPTO_add(&rch->d.crl->references,
 618                                                 1, CRYPTO_LOCK_X509_CRL);
 619                         }
 620                 }
 621         return crls;
 622         }