Home | History | Annotate | Download | only in pkcs7
      1 /* Copyright (c) 2017, Google Inc.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 #include <openssl/pkcs7.h>
     16 
     17 #include <assert.h>
     18 #include <limits.h>
     19 
     20 #include <openssl/bytestring.h>
     21 #include <openssl/err.h>
     22 #include <openssl/mem.h>
     23 #include <openssl/pem.h>
     24 #include <openssl/pool.h>
     25 #include <openssl/stack.h>
     26 #include <openssl/x509.h>
     27 
     28 #include "internal.h"
     29 #include "../internal.h"
     30 
     31 
     32 int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
     33   int ret = 0;
     34   const size_t initial_certs_len = sk_X509_num(out_certs);
     35   STACK_OF(CRYPTO_BUFFER) *raw = sk_CRYPTO_BUFFER_new_null();
     36   if (raw == NULL ||
     37       !PKCS7_get_raw_certificates(raw, cbs, NULL)) {
     38     goto err;
     39   }
     40 
     41   for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(raw); i++) {
     42     CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_value(raw, i);
     43     X509 *x509 = X509_parse_from_buffer(buf);
     44     if (x509 == NULL ||
     45         !sk_X509_push(out_certs, x509)) {
     46       X509_free(x509);
     47       goto err;
     48     }
     49   }
     50 
     51   ret = 1;
     52 
     53 err:
     54   sk_CRYPTO_BUFFER_pop_free(raw, CRYPTO_BUFFER_free);
     55   if (!ret) {
     56     while (sk_X509_num(out_certs) != initial_certs_len) {
     57       X509 *x509 = sk_X509_pop(out_certs);
     58       X509_free(x509);
     59     }
     60   }
     61 
     62   return ret;
     63 }
     64 
     65 int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) {
     66   CBS signed_data, crls;
     67   uint8_t *der_bytes = NULL;
     68   int ret = 0, has_crls;
     69   const size_t initial_crls_len = sk_X509_CRL_num(out_crls);
     70 
     71   // See https://tools.ietf.org/html/rfc2315#section-9.1
     72   if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs) ||
     73       // Even if only CRLs are included, there may be an empty certificates
     74       // block. OpenSSL does this, for example.
     75       !CBS_get_optional_asn1(
     76           &signed_data, NULL, NULL,
     77           CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
     78       !CBS_get_optional_asn1(
     79           &signed_data, &crls, &has_crls,
     80           CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) {
     81     goto err;
     82   }
     83 
     84   if (!has_crls) {
     85     CBS_init(&crls, NULL, 0);
     86   }
     87 
     88   while (CBS_len(&crls) > 0) {
     89     CBS crl_data;
     90     X509_CRL *crl;
     91     const uint8_t *inp;
     92 
     93     if (!CBS_get_asn1_element(&crls, &crl_data, CBS_ASN1_SEQUENCE)) {
     94       goto err;
     95     }
     96 
     97     if (CBS_len(&crl_data) > LONG_MAX) {
     98       goto err;
     99     }
    100     inp = CBS_data(&crl_data);
    101     crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data));
    102     if (!crl) {
    103       goto err;
    104     }
    105 
    106     assert(inp == CBS_data(&crl_data) + CBS_len(&crl_data));
    107 
    108     if (sk_X509_CRL_push(out_crls, crl) == 0) {
    109       X509_CRL_free(crl);
    110       goto err;
    111     }
    112   }
    113 
    114   ret = 1;
    115 
    116 err:
    117   OPENSSL_free(der_bytes);
    118 
    119   if (!ret) {
    120     while (sk_X509_CRL_num(out_crls) != initial_crls_len) {
    121       X509_CRL_free(sk_X509_CRL_pop(out_crls));
    122     }
    123   }
    124 
    125   return ret;
    126 }
    127 
    128 int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, BIO *pem_bio) {
    129   uint8_t *data;
    130   long len;
    131   int ret;
    132 
    133   // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM
    134   // internally will actually allow several other values too, including
    135   // "CERTIFICATE".
    136   if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */,
    137                           PEM_STRING_PKCS7, pem_bio,
    138                           NULL /* password callback */,
    139                           NULL /* password callback argument */)) {
    140     return 0;
    141   }
    142 
    143   CBS cbs;
    144   CBS_init(&cbs, data, len);
    145   ret = PKCS7_get_certificates(out_certs, &cbs);
    146   OPENSSL_free(data);
    147   return ret;
    148 }
    149 
    150 int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, BIO *pem_bio) {
    151   uint8_t *data;
    152   long len;
    153   int ret;
    154 
    155   // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM
    156   // internally will actually allow several other values too, including
    157   // "CERTIFICATE".
    158   if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */,
    159                           PEM_STRING_PKCS7, pem_bio,
    160                           NULL /* password callback */,
    161                           NULL /* password callback argument */)) {
    162     return 0;
    163   }
    164 
    165   CBS cbs;
    166   CBS_init(&cbs, data, len);
    167   ret = PKCS7_get_CRLs(out_crls, &cbs);
    168   OPENSSL_free(data);
    169   return ret;
    170 }
    171 
    172 static int pkcs7_bundle_certificates_cb(CBB *out, const void *arg) {
    173   const STACK_OF(X509) *certs = arg;
    174   size_t i;
    175   CBB certificates;
    176 
    177   // See https://tools.ietf.org/html/rfc2315#section-9.1
    178   if (!CBB_add_asn1(out, &certificates,
    179                     CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
    180     return 0;
    181   }
    182 
    183   for (i = 0; i < sk_X509_num(certs); i++) {
    184     X509 *x509 = sk_X509_value(certs, i);
    185     uint8_t *buf;
    186     int len = i2d_X509(x509, NULL);
    187 
    188     if (len < 0 ||
    189         !CBB_add_space(&certificates, &buf, len) ||
    190         i2d_X509(x509, &buf) < 0) {
    191       return 0;
    192     }
    193   }
    194 
    195   return CBB_flush(out);
    196 }
    197 
    198 int PKCS7_bundle_certificates(CBB *out, const STACK_OF(X509) *certs) {
    199   return pkcs7_bundle(out, pkcs7_bundle_certificates_cb, certs);
    200 }
    201 
    202 static int pkcs7_bundle_crls_cb(CBB *out, const void *arg) {
    203   const STACK_OF(X509_CRL) *crls = arg;
    204   size_t i;
    205   CBB crl_data;
    206 
    207   // See https://tools.ietf.org/html/rfc2315#section-9.1
    208   if (!CBB_add_asn1(out, &crl_data,
    209                     CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) {
    210     return 0;
    211   }
    212 
    213   for (i = 0; i < sk_X509_CRL_num(crls); i++) {
    214     X509_CRL *crl = sk_X509_CRL_value(crls, i);
    215     uint8_t *buf;
    216     int len = i2d_X509_CRL(crl, NULL);
    217 
    218     if (len < 0 ||
    219         !CBB_add_space(&crl_data, &buf, len) ||
    220         i2d_X509_CRL(crl, &buf) < 0) {
    221       return 0;
    222     }
    223   }
    224 
    225   return CBB_flush(out);
    226 }
    227 
    228 int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls) {
    229   return pkcs7_bundle(out, pkcs7_bundle_crls_cb, crls);
    230 }
    231 
    232 static PKCS7 *pkcs7_new(CBS *cbs) {
    233   PKCS7 *ret = OPENSSL_malloc(sizeof(PKCS7));
    234   if (ret == NULL) {
    235     return NULL;
    236   }
    237   OPENSSL_memset(ret, 0, sizeof(PKCS7));
    238   ret->type = (ASN1_OBJECT *)OBJ_nid2obj(NID_pkcs7_signed);
    239   ret->d.sign = OPENSSL_malloc(sizeof(PKCS7_SIGNED));
    240   if (ret->d.sign == NULL) {
    241     goto err;
    242   }
    243   ret->d.sign->cert = sk_X509_new_null();
    244   ret->d.sign->crl = sk_X509_CRL_new_null();
    245   CBS copy = *cbs, copy2 = *cbs;
    246   if (ret->d.sign->cert == NULL || ret->d.sign->crl == NULL ||
    247       !PKCS7_get_certificates(ret->d.sign->cert, &copy) ||
    248       !PKCS7_get_CRLs(ret->d.sign->crl, cbs)) {
    249     goto err;
    250   }
    251 
    252   if (sk_X509_num(ret->d.sign->cert) == 0) {
    253     sk_X509_free(ret->d.sign->cert);
    254     ret->d.sign->cert = NULL;
    255   }
    256 
    257   if (sk_X509_CRL_num(ret->d.sign->crl) == 0) {
    258     sk_X509_CRL_free(ret->d.sign->crl);
    259     ret->d.sign->crl = NULL;
    260   }
    261 
    262   ret->ber_len = CBS_len(&copy2) - CBS_len(cbs);
    263   ret->ber_bytes = BUF_memdup(CBS_data(&copy2), ret->ber_len);
    264   if (ret->ber_bytes == NULL) {
    265     goto err;
    266   }
    267 
    268   return ret;
    269 
    270 err:
    271   PKCS7_free(ret);
    272   return NULL;
    273 }
    274 
    275 PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp,
    276                  size_t len) {
    277   CBS cbs;
    278   CBS_init(&cbs, *inp, len);
    279   PKCS7 *ret = pkcs7_new(&cbs);
    280   if (ret == NULL) {
    281     return NULL;
    282   }
    283   *inp = CBS_data(&cbs);
    284   if (out != NULL) {
    285     PKCS7_free(*out);
    286     *out = ret;
    287   }
    288   return ret;
    289 }
    290 
    291 PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out) {
    292   // Use a generous bound, to allow for PKCS#7 files containing large root sets.
    293   static const size_t kMaxSize = 4 * 1024 * 1024;
    294   uint8_t *data;
    295   size_t len;
    296   if (!BIO_read_asn1(bio, &data, &len, kMaxSize)) {
    297     return NULL;
    298   }
    299 
    300   CBS cbs;
    301   CBS_init(&cbs, data, len);
    302   PKCS7 *ret = pkcs7_new(&cbs);
    303   OPENSSL_free(data);
    304   if (out != NULL && ret != NULL) {
    305     PKCS7_free(*out);
    306     *out = ret;
    307   }
    308   return ret;
    309 }
    310 
    311 int i2d_PKCS7(const PKCS7 *p7, uint8_t **out) {
    312   if (p7->ber_len > INT_MAX) {
    313     OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
    314     return -1;
    315   }
    316 
    317   if (out == NULL) {
    318     return (int)p7->ber_len;
    319   }
    320 
    321   if (*out == NULL) {
    322     *out = OPENSSL_malloc(p7->ber_len);
    323     if (*out == NULL) {
    324       OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
    325       return -1;
    326     }
    327     OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len);
    328   } else {
    329     OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len);
    330     *out += p7->ber_len;
    331   }
    332   return (int)p7->ber_len;
    333 }
    334 
    335 int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) {
    336   return BIO_write_all(bio, p7->ber_bytes, p7->ber_len);
    337 }
    338 
    339 void PKCS7_free(PKCS7 *p7) {
    340   if (p7 == NULL) {
    341     return;
    342   }
    343 
    344   OPENSSL_free(p7->ber_bytes);
    345   ASN1_OBJECT_free(p7->type);
    346   // We only supported signed data.
    347   if (p7->d.sign != NULL) {
    348     sk_X509_pop_free(p7->d.sign->cert, X509_free);
    349     sk_X509_CRL_pop_free(p7->d.sign->crl, X509_CRL_free);
    350     OPENSSL_free(p7->d.sign);
    351   }
    352   OPENSSL_free(p7);
    353 }
    354 
    355 // We only support signed data, so these getters are no-ops.
    356 int PKCS7_type_is_data(const PKCS7 *p7) { return 0; }
    357 int PKCS7_type_is_digest(const PKCS7 *p7) { return 0; }
    358 int PKCS7_type_is_encrypted(const PKCS7 *p7) { return 0; }
    359 int PKCS7_type_is_enveloped(const PKCS7 *p7) { return 0; }
    360 int PKCS7_type_is_signed(const PKCS7 *p7) { return 1; }
    361 int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7) { return 0; }
    362 
    363 PKCS7 *PKCS7_sign(X509 *sign_cert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
    364                   BIO *data, int flags) {
    365   if (sign_cert != NULL || pkey != NULL || flags != PKCS7_DETACHED) {
    366     OPENSSL_PUT_ERROR(PKCS7, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    367     return NULL;
    368   }
    369 
    370   uint8_t *der;
    371   size_t len;
    372   CBB cbb;
    373   if (!CBB_init(&cbb, 2048) ||
    374       !PKCS7_bundle_certificates(&cbb, certs) ||
    375       !CBB_finish(&cbb, &der, &len)) {
    376     CBB_cleanup(&cbb);
    377     return NULL;
    378   }
    379 
    380   CBS cbs;
    381   CBS_init(&cbs, der, len);
    382   PKCS7 *ret = pkcs7_new(&cbs);
    383   OPENSSL_free(der);
    384   return ret;
    385 }
    386