diff options
author | David Benjamin <davidben@chromium.org> | 2016-01-09 03:53:29 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2016-02-16 22:32:50 +0300 |
commit | 375124b1622e112fbd4584e806030eb7476904c5 (patch) | |
tree | f9ec3d4b640bcf775e357c5db84452cd70620af3 /crypto/pkcs8 | |
parent | fb974e6cb314735e06771887ef8fdcbe837851ee (diff) |
Parse BER for PKCS#12 more accurately.
CBS_asn1_ber_to_der currently uses heuristics because implicitly-tagged
constructed strings in BER are ambiguous with implicitly-tagged sequences. It's
not possible to convert BER to DER without knowing the schema.
Fortunately, implicitly tagged strings don't appear often so instead split the
job up: CBS_asn1_ber_to_der fixes indefinite-length elements and constructed
strings it can see. Implicitly-tagged strings it leaves uncoverted, but they
will only nest one level down (because BER kindly allows one to nest
constructed strings arbitrarily!).
CBS_get_asn1_implicit_string then performs the final concatenation at parse
time. This isn't much more complex and lets us parse BER more accurately and
also reject a number of mis-encoded values (e.g. constructed INTEGERs are not a
thing) we'd previously let through. The downside is the post-conversion parsing
code must be aware of this limitation of CBS_asn1_ber_to_der. Fortunately,
there's only one implicitly-tagged string in our PKCS#12 code.
(In the category of things that really really don't matter, but I had spare
cycles and the old BER converter is weird.)
Change-Id: Iebdd13b08559fa158b308ef83a5bb07bfdf80ae8
Reviewed-on: https://boringssl-review.googlesource.com/7052
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto/pkcs8')
-rw-r--r-- | crypto/pkcs8/pkcs8.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/crypto/pkcs8/pkcs8.c b/crypto/pkcs8/pkcs8.c index ac13faf7..fdce544a 100644 --- a/crypto/pkcs8/pkcs8.c +++ b/crypto/pkcs8/pkcs8.c @@ -737,6 +737,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, struct pkcs12_context *ctx) { CBS content_type, wrapped_contents, contents, content_infos; int nid, ret = 0; + uint8_t *storage = NULL; if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || !CBS_get_asn1(content_info, &wrapped_contents, @@ -767,8 +768,9 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, /* AlgorithmIdentifier, see * https://tools.ietf.org/html/rfc5280#section-4.1.1.2 */ !CBS_get_asn1_element(&eci, &ai, CBS_ASN1_SEQUENCE) || - !CBS_get_asn1(&eci, &encrypted_contents, - CBS_ASN1_CONTEXT_SPECIFIC | 0)) { + !CBS_get_asn1_implicit_string( + &eci, &encrypted_contents, &storage, + CBS_ASN1_CONTEXT_SPECIFIC | 0, CBS_ASN1_OCTETSTRING)) { OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); goto err; } @@ -895,6 +897,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth, } err: + OPENSSL_free(storage); return ret; } |