Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Langley <agl@chromium.org>2014-08-21 21:54:06 +0400
committerAdam Langley <agl@google.com>2014-08-26 01:38:08 +0400
commit9c01e00c2e5bb8087c27203c0adccd9738beb64d (patch)
tree8fb4501a8b05d649506580db138a302713955aa2 /crypto/x509
parentcc8fcf45bbf37cbee85d4b8dac9d9814f6831961 (diff)
Rework support for ASN.1 BER.
Previously, the ASN.1 functions in bytestring were capable of processing indefinite length elements when the _ber functions were used. That works well enough for PKCS#3, but NSS goes a bit crazy with BER encoding and PKCS#12. Rather than complicate the core bytestring functions further, the BER support is removed from them and moved to a separate function that converts from BER to DER (if needed). Change-Id: I2212b28e99bab9fab8c61f80d2012d3e5a3cc2f0 Reviewed-on: https://boringssl-review.googlesource.com/1591 Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto/x509')
-rw-r--r--crypto/x509/pkcs7.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/crypto/x509/pkcs7.c b/crypto/x509/pkcs7.c
index 7744fcce..75c101bd 100644
--- a/crypto/x509/pkcs7.c
+++ b/crypto/x509/pkcs7.c
@@ -19,48 +19,61 @@
#include <openssl/obj.h>
#include <openssl/stack.h>
+#include "../bytestring/internal.h"
+
int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
- CBS content_info, content_type, wrapped_signed_data, signed_data,
- version_bytes, certificates;
- int nid;
+ uint8_t *der_bytes = NULL;
+ size_t der_len;
+ CBS in, content_info, content_type, wrapped_signed_data, signed_data,
+ certificates;
const size_t initial_certs_len = sk_X509_num(out_certs);
+ uint64_t version;
+ int ret = 0;
+
+ /* The input may be in BER format. */
+ if (!CBS_asn1_ber_to_der(cbs, &der_bytes, &der_len)) {
+ return 0;
+ }
+ if (der_bytes != NULL) {
+ CBS_init(&in, der_bytes, der_len);
+ } else {
+ CBS_init(&in, CBS_data(cbs), CBS_len(cbs));
+ }
/* See https://tools.ietf.org/html/rfc2315#section-7 */
- if (!CBS_get_asn1_ber(cbs, &content_info, CBS_ASN1_SEQUENCE) ||
+ if (!CBS_get_asn1(&in, &content_info, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&content_info, &content_type, CBS_ASN1_OBJECT)) {
- return 0;
+ goto err;
}
- nid = OBJ_cbs2nid(&content_type);
- if (nid != NID_pkcs7_signed) {
+ if (OBJ_cbs2nid(&content_type) != NID_pkcs7_signed) {
OPENSSL_PUT_ERROR(X509, PKCS7_get_certificates,
X509_R_NOT_PKCS7_SIGNED_DATA);
- return 0;
+ goto err;
}
/* See https://tools.ietf.org/html/rfc2315#section-9.1 */
- if (!CBS_get_asn1_ber(&content_info, &wrapped_signed_data,
- CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
- !CBS_get_asn1_ber(&wrapped_signed_data, &signed_data,
- CBS_ASN1_SEQUENCE) ||
- !CBS_get_asn1_ber(&signed_data, &version_bytes, CBS_ASN1_INTEGER) ||
- !CBS_get_asn1_ber(&signed_data, NULL /* digests */, CBS_ASN1_SET) ||
- !CBS_get_asn1_ber(&signed_data, NULL /* content */, CBS_ASN1_SEQUENCE)) {
- return 0;
+ if (!CBS_get_asn1(&content_info, &wrapped_signed_data,
+ CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
+ !CBS_get_asn1(&wrapped_signed_data, &signed_data, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&signed_data, &version) ||
+ !CBS_get_asn1(&signed_data, NULL /* digests */, CBS_ASN1_SET) ||
+ !CBS_get_asn1(&signed_data, NULL /* content */, CBS_ASN1_SEQUENCE)) {
+ goto err;
}
- if (CBS_len(&version_bytes) < 1 || CBS_data(&version_bytes)[0] == 0) {
+ if (version < 1) {
OPENSSL_PUT_ERROR(X509, PKCS7_get_certificates,
X509_R_BAD_PKCS7_VERSION);
- return 0;
+ goto err;
}
- if (!CBS_get_asn1_ber(&signed_data, &certificates,
- CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
+ if (!CBS_get_asn1(&signed_data, &certificates,
+ CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
OPENSSL_PUT_ERROR(X509, PKCS7_get_certificates,
X509_R_NO_CERTIFICATES_INCLUDED);
- return 0;
+ goto err;
}
while (CBS_len(&certificates) > 0) {
@@ -86,15 +99,21 @@ int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
sk_X509_push(out_certs, x509);
}
- return 1;
+ ret = 1;
err:
- while (sk_X509_num(out_certs) != initial_certs_len) {
- X509 *x509 = sk_X509_pop(out_certs);
- X509_free(x509);
+ if (der_bytes) {
+ OPENSSL_free(der_bytes);
+ }
+
+ if (!ret) {
+ while (sk_X509_num(out_certs) != initial_certs_len) {
+ X509 *x509 = sk_X509_pop(out_certs);
+ X509_free(x509);
+ }
}
- return 0;
+ return ret;
}
int PKCS7_bundle_certificates(CBB *out, const STACK_OF(X509) *certs) {