diff options
author | lloyd <[email protected]> | 2010-03-19 17:59:40 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-03-19 17:59:40 +0000 |
commit | dab16b79c89e54e9551d30dcf54ca89432932dce (patch) | |
tree | fcd4ccce7e442006f8075f8c8a9b298aab5167b3 | |
parent | 8fa0099ce0f2f488ca4c5046c6d019125d1d3b68 (diff) |
Add a couple of new helper functions to BER_Decoder:
decode_and_check takes an expected value; if the decoded value does
not match, a Decoding_Error with a specified string is thrown. Useful
for checking embedded version codes.
decode_octet_string_bigint is for decoding INTEGER values that are
stored as OCTET STRINGs. Totally obnoxious and useless, but common
especially in the ECC standards.
-rw-r--r-- | src/asn1/ber_dec.cpp | 8 | ||||
-rw-r--r-- | src/asn1/ber_dec.h | 25 | ||||
-rw-r--r-- | src/pubkey/ec_dompar/ec_dompar.cpp | 27 | ||||
-rw-r--r-- | src/pubkey/ecc_key/ecc_key.cpp | 14 | ||||
-rw-r--r-- | src/pubkey/if_algo/if_algo.cpp | 7 | ||||
-rw-r--r-- | src/pubkey/pkcs8.cpp | 7 |
6 files changed, 42 insertions, 46 deletions
diff --git a/src/asn1/ber_dec.cpp b/src/asn1/ber_dec.cpp index 66a27dd4e..ea0334202 100644 --- a/src/asn1/ber_dec.cpp +++ b/src/asn1/ber_dec.cpp @@ -355,6 +355,14 @@ BER_Decoder& BER_Decoder::decode(BigInt& out) return decode(out, INTEGER, UNIVERSAL); } +BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) + { + SecureVector<byte> out_vec; + decode(out_vec, OCTET_STRING); + out = BigInt::decode(&out_vec[0], out_vec.size()); + return (*this); + } + /* * Decode a BER encoded BOOLEAN */ diff --git a/src/asn1/ber_dec.h b/src/asn1/ber_dec.h index 2e38af301..3658aeba4 100644 --- a/src/asn1/ber_dec.h +++ b/src/asn1/ber_dec.h @@ -1,6 +1,6 @@ /* * BER Decoder -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -46,11 +46,30 @@ class BOTAN_DLL BER_Decoder BER_Decoder& decode(class ASN1_Object&); + BER_Decoder& decode_octet_string_bigint(class BigInt&); + + template<typename T> + BER_Decoder& decode_optional(T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag, + const T& default_value = T()); + template<typename T> - BER_Decoder& decode_optional(T&, ASN1_Tag, ASN1_Tag, const T& = T()); + BER_Decoder& decode_list(std::vector<T>& out, + bool clear_out = true); template<typename T> - BER_Decoder& decode_list(std::vector<T>&, bool = true); + BER_Decoder& decode_and_check(const T& expected, + const std::string& error_msg) + { + T actual; + decode(actual); + + if(actual != expected) + throw Decoding_Error(error_msg); + + return (*this); + } BER_Decoder& decode_optional_string(MemoryRegion<byte>&, ASN1_Tag, u16bit); diff --git a/src/pubkey/ec_dompar/ec_dompar.cpp b/src/pubkey/ec_dompar/ec_dompar.cpp index 42ae9211e..3512060d1 100644 --- a/src/pubkey/ec_dompar/ec_dompar.cpp +++ b/src/pubkey/ec_dompar/ec_dompar.cpp @@ -54,23 +54,20 @@ EC_Domain_Params::EC_Domain_Params(const MemoryRegion<byte>& ber_data) } else if(obj.type_tag == SEQUENCE) { - BigInt ecpVers1(1); - OID curve_type; - SecureVector<byte> sv_a; - SecureVector<byte> sv_b; - BigInt p; + BigInt p, a, b; SecureVector<byte> sv_base_point; BER_Decoder(ber_data) .start_cons(SEQUENCE) - .decode(ecpVers1) + .decode_and_check<u32bit>(1, "Unknown ECC param version code") .start_cons(SEQUENCE) - .decode(curve_type) + .decode_and_check(OID("1.2.840.10045.1.1"), + "Only prime ECC fields supported") .decode(p) .end_cons() .start_cons(SEQUENCE) - .decode(sv_a, OCTET_STRING) - .decode(sv_b, OCTET_STRING) + .decode_octet_string_bigint(a) + .decode_octet_string_bigint(b) .end_cons() .decode(sv_base_point, OCTET_STRING) .decode(order) @@ -78,17 +75,7 @@ EC_Domain_Params::EC_Domain_Params(const MemoryRegion<byte>& ber_data) .end_cons() .verify_end(); - if(ecpVers1 != 1) - throw Decoding_Error("EC_Domain_Params: Unknown version code"); - - // Only prime curves supported - if(curve_type.as_string() != "1.2.840.10045.1.1") - throw Decoding_Error("Unexpected curve type " + curve_type.as_string()); - - curve = CurveGFp(p, - BigInt::decode(sv_a, sv_a.size()), - BigInt::decode(sv_b, sv_b.size())); - + curve = CurveGFp(p, a, b); base_point = OS2ECP(sv_base_point, curve); base_point.check_invariants(); } diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index a4bd9b635..fdb29b29f 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -125,7 +125,7 @@ MemoryVector<byte> EC_PrivateKey::pkcs8_private_key() const { return DER_Encoder() .start_cons(SEQUENCE) - .encode(BigInt(1)) + .encode(static_cast<u32bit>(1)) .encode(BigInt::encode_1363(private_key, private_key.bytes()), OCTET_STRING) .end_cons() @@ -138,21 +138,13 @@ EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id, domain_params = EC_Domain_Params(alg_id.parameters); domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - u32bit version; - SecureVector<byte> octstr_secret; - BER_Decoder(key_bits) .start_cons(SEQUENCE) - .decode(version) - .decode(octstr_secret, OCTET_STRING) + .decode_and_check<u32bit>(1, "Unknown version code for ECC key") + .decode_octet_string_bigint(private_key) .verify_end() .end_cons(); - if(version != 1) - throw Decoding_Error("Wrong key format version for EC key"); - - private_key = BigInt::decode(octstr_secret, octstr_secret.size()); - public_key = domain().get_base_point() * private_key; try diff --git a/src/pubkey/if_algo/if_algo.cpp b/src/pubkey/if_algo/if_algo.cpp index 759c30c61..82722d489 100644 --- a/src/pubkey/if_algo/if_algo.cpp +++ b/src/pubkey/if_algo/if_algo.cpp @@ -60,11 +60,9 @@ IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng, const AlgorithmIdentifier&, const MemoryRegion<byte>& key_bits) { - u32bit version; - BER_Decoder(key_bits) .start_cons(SEQUENCE) - .decode(version) + .decode_and_check<u32bit>(0, "Unknown PKCS #1 key format version") .decode(n) .decode(e) .decode(d) @@ -75,9 +73,6 @@ IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng, .decode(c) .end_cons(); - if(version != 0) - throw Decoding_Error("Unknown PKCS #1 key format version"); - load_check(rng); } diff --git a/src/pubkey/pkcs8.cpp b/src/pubkey/pkcs8.cpp index 400fdbb48..35ff7f206 100644 --- a/src/pubkey/pkcs8.cpp +++ b/src/pubkey/pkcs8.cpp @@ -105,19 +105,14 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui, key = decryptor.read_all(); } - u32bit version; - BER_Decoder(key) .start_cons(SEQUENCE) - .decode(version) + .decode_and_check<u32bit>(0, "Unknown PKCS #8 version number") .decode(pk_alg_id) .decode(key, OCTET_STRING) .discard_remaining() .end_cons(); - if(version != 0) - throw Decoding_Error("PKCS #8: Unknown version number"); - break; } catch(Decoding_Error) |