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, ©) || 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(©2) - CBS_len(cbs); 263 ret->ber_bytes = BUF_memdup(CBS_data(©2), 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