diff options
author | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
commit | 12090a7148d9ee73572cc1a7268fc489504a8173 (patch) | |
tree | 51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/asn1 | |
parent | 9594979caf775dc4062850044715b804d1fda60c (diff) | |
parent | 65cc04445f8d40497f02a14bd8cb97081790e54b (diff) |
propagate from branch 'net.randombit.botan.x509-path-validation' (head 63b5a20eab129ca13287fda33d2d02eec329708f)
to branch 'net.randombit.botan' (head 8b8150f09c55184f028f2929c4e7f7cd0d46d96e)
Diffstat (limited to 'src/asn1')
-rw-r--r-- | src/asn1/alg_id.cpp | 4 | ||||
-rw-r--r-- | src/asn1/alg_id.h | 6 | ||||
-rw-r--r-- | src/asn1/asn1_alt.cpp | 27 | ||||
-rw-r--r-- | src/asn1/asn1_att.cpp | 4 | ||||
-rw-r--r-- | src/asn1/asn1_int.cpp | 8 | ||||
-rw-r--r-- | src/asn1/asn1_int.h | 4 | ||||
-rw-r--r-- | src/asn1/asn1_obj.h | 9 | ||||
-rw-r--r-- | src/asn1/asn1_oid.cpp | 4 | ||||
-rw-r--r-- | src/asn1/asn1_str.cpp | 2 | ||||
-rw-r--r-- | src/asn1/asn1_tm.cpp | 54 | ||||
-rw-r--r-- | src/asn1/ber_dec.cpp | 122 | ||||
-rw-r--r-- | src/asn1/ber_dec.h | 85 | ||||
-rw-r--r-- | src/asn1/der_enc.cpp | 73 | ||||
-rw-r--r-- | src/asn1/der_enc.h | 37 | ||||
-rw-r--r-- | src/asn1/x509_dn.cpp | 74 | ||||
-rw-r--r-- | src/asn1/x509_dn.h | 4 |
16 files changed, 339 insertions, 178 deletions
diff --git a/src/asn1/alg_id.cpp b/src/asn1/alg_id.cpp index 665e42fb3..c4c6b6e24 100644 --- a/src/asn1/alg_id.cpp +++ b/src/asn1/alg_id.cpp @@ -16,7 +16,7 @@ namespace Botan { * Create an AlgorithmIdentifier */ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, - const MemoryRegion<byte>& param) + const std::vector<byte>& param) { oid = alg_id; parameters = param; @@ -26,7 +26,7 @@ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, * Create an AlgorithmIdentifier */ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, - const MemoryRegion<byte>& param) + const std::vector<byte>& param) { oid = OIDS::lookup(alg_id); parameters = param; diff --git a/src/asn1/alg_id.h b/src/asn1/alg_id.h index 417a71b30..1ec6b62d3 100644 --- a/src/asn1/alg_id.h +++ b/src/asn1/alg_id.h @@ -29,11 +29,11 @@ class BOTAN_DLL AlgorithmIdentifier : public ASN1_Object AlgorithmIdentifier(const OID&, Encoding_Option); AlgorithmIdentifier(const std::string&, Encoding_Option); - AlgorithmIdentifier(const OID&, const MemoryRegion<byte>&); - AlgorithmIdentifier(const std::string&, const MemoryRegion<byte>&); + AlgorithmIdentifier(const OID&, const std::vector<byte>&); + AlgorithmIdentifier(const std::string&, const std::vector<byte>&); OID oid; - SecureVector<byte> parameters; + std::vector<byte> parameters; }; /* diff --git a/src/asn1/asn1_alt.cpp b/src/asn1/asn1_alt.cpp index 2d8e3a1d2..1a5c699cd 100644 --- a/src/asn1/asn1_alt.cpp +++ b/src/asn1/asn1_alt.cpp @@ -58,9 +58,8 @@ void AlternativeName::add_attribute(const std::string& type, if(type == "" || str == "") return; - typedef std::multimap<std::string, std::string>::iterator iter; - std::pair<iter, iter> range = alt_info.equal_range(type); - for(iter j = range.first; j != range.second; ++j) + auto range = alt_info.equal_range(type); + for(auto j = range.first; j != range.second; ++j) if(j->second == str) return; @@ -101,13 +100,11 @@ std::multimap<std::string, std::string> AlternativeName::contents() const { std::multimap<std::string, std::string> names; - typedef std::multimap<std::string, std::string>::const_iterator rdn_iter; - for(rdn_iter j = alt_info.begin(); j != alt_info.end(); ++j) - multimap_insert(names, j->first, j->second); + for(auto i = alt_info.begin(); i != alt_info.end(); ++i) + multimap_insert(names, i->first, i->second); - typedef std::multimap<OID, ASN1_String>::const_iterator on_iter; - for(on_iter j = othernames.begin(); j != othernames.end(); ++j) - multimap_insert(names, OIDS::lookup(j->first), j->second.value()); + for(auto i = othernames.begin(); i != othernames.end(); ++i) + multimap_insert(names, OIDS::lookup(i->first), i->second.value()); return names; } @@ -129,19 +126,18 @@ void encode_entries(DER_Encoder& encoder, const std::multimap<std::string, std::string>& attr, const std::string& type, ASN1_Tag tagging) { - typedef std::multimap<std::string, std::string>::const_iterator iter; + auto range = attr.equal_range(type); - std::pair<iter, iter> range = attr.equal_range(type); - for(iter j = range.first; j != range.second; ++j) + for(auto i = range.first; i != range.second; ++i) { if(type == "RFC822" || type == "DNS" || type == "URI") { - ASN1_String asn1_string(j->second, IA5_STRING); + ASN1_String asn1_string(i->second, IA5_STRING); encoder.add_object(tagging, CONTEXT_SPECIFIC, asn1_string.iso_8859()); } else if(type == "IP") { - const u32bit ip = string_to_ipv4(j->second); + const u32bit ip = string_to_ipv4(i->second); byte ip_buf[4] = { 0 }; store_be(ip, ip_buf); encoder.add_object(tagging, CONTEXT_SPECIFIC, ip_buf, 4); @@ -163,8 +159,7 @@ void AlternativeName::encode_into(DER_Encoder& der) const encode_entries(der, alt_info, "URI", ASN1_Tag(6)); encode_entries(der, alt_info, "IP", ASN1_Tag(7)); - std::multimap<OID, ASN1_String>::const_iterator i; - for(i = othernames.begin(); i != othernames.end(); ++i) + for(auto i = othernames.begin(); i != othernames.end(); ++i) { der.start_explicit(0) .encode(i->first) diff --git a/src/asn1/asn1_att.cpp b/src/asn1/asn1_att.cpp index c8d771e25..c0adae643 100644 --- a/src/asn1/asn1_att.cpp +++ b/src/asn1/asn1_att.cpp @@ -15,7 +15,7 @@ namespace Botan { /* * Create an Attribute */ -Attribute::Attribute(const OID& attr_oid, const MemoryRegion<byte>& attr_value) +Attribute::Attribute(const OID& attr_oid, const std::vector<byte>& attr_value) { oid = attr_oid; parameters = attr_value; @@ -25,7 +25,7 @@ Attribute::Attribute(const OID& attr_oid, const MemoryRegion<byte>& attr_value) * Create an Attribute */ Attribute::Attribute(const std::string& attr_oid, - const MemoryRegion<byte>& attr_value) + const std::vector<byte>& attr_value) { oid = OIDS::lookup(attr_oid); parameters = attr_value; diff --git a/src/asn1/asn1_int.cpp b/src/asn1/asn1_int.cpp index 75cb1f90c..ff8eba54e 100644 --- a/src/asn1/asn1_int.cpp +++ b/src/asn1/asn1_int.cpp @@ -20,24 +20,24 @@ BER_Decoding_Error::BER_Decoding_Error(const std::string& str) : Decoding_Error("BER: " + str) {} BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag) : - BER_Decoding_Error(str + ": " + to_string(tag)) {} + BER_Decoding_Error(str + ": " + std::to_string(tag)) {} BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag1, ASN1_Tag tag2) : - BER_Decoding_Error(str + ": " + to_string(tag1) + "/" + to_string(tag2)) {} + BER_Decoding_Error(str + ": " + std::to_string(tag1) + "/" + std::to_string(tag2)) {} namespace ASN1 { /* * Put some arbitrary bytes into a SEQUENCE */ -SecureVector<byte> put_in_sequence(const MemoryRegion<byte>& contents) +std::vector<byte> put_in_sequence(const std::vector<byte>& contents) { return DER_Encoder() .start_cons(SEQUENCE) .raw_bytes(contents) .end_cons() - .get_contents(); + .get_contents_unlocked(); } /* diff --git a/src/asn1/asn1_int.h b/src/asn1/asn1_int.h index 25b3cf100..37edc4e3c 100644 --- a/src/asn1/asn1_int.h +++ b/src/asn1/asn1_int.h @@ -80,7 +80,7 @@ class BOTAN_DLL BER_Object void assert_is_a(ASN1_Tag, ASN1_Tag); ASN1_Tag type_tag, class_tag; - SecureVector<byte> value; + secure_vector<byte> value; }; /* @@ -90,7 +90,7 @@ class DataSource; namespace ASN1 { -SecureVector<byte> put_in_sequence(const MemoryRegion<byte>& val); +std::vector<byte> put_in_sequence(const std::vector<byte>& val); std::string to_string(const BER_Object& obj); /** diff --git a/src/asn1/asn1_obj.h b/src/asn1/asn1_obj.h index 692a6fde6..cee5a18ed 100644 --- a/src/asn1/asn1_obj.h +++ b/src/asn1/asn1_obj.h @@ -15,6 +15,7 @@ #include <botan/alg_id.h> #include <vector> #include <map> +#include <chrono> namespace Botan { @@ -28,11 +29,11 @@ class BOTAN_DLL Attribute : public ASN1_Object void decode_from(class BER_Decoder& from); OID oid; - MemoryVector<byte> parameters; + std::vector<byte> parameters; Attribute() {} - Attribute(const OID&, const MemoryRegion<byte>&); - Attribute(const std::string&, const MemoryRegion<byte>&); + Attribute(const OID&, const std::vector<byte>&); + Attribute(const std::string&, const std::vector<byte>&); }; /** @@ -53,7 +54,7 @@ class BOTAN_DLL X509_Time : public ASN1_Object void set_to(const std::string&); void set_to(const std::string&, ASN1_Tag); - X509_Time(u64bit); + X509_Time(const std::chrono::system_clock::time_point& time); X509_Time(const std::string& = ""); X509_Time(const std::string&, ASN1_Tag); private: diff --git a/src/asn1/asn1_oid.cpp b/src/asn1/asn1_oid.cpp index ae3d48ce2..009b1c2fc 100644 --- a/src/asn1/asn1_oid.cpp +++ b/src/asn1/asn1_oid.cpp @@ -52,7 +52,7 @@ std::string OID::as_string() const std::string oid_str; for(size_t i = 0; i != id.size(); ++i) { - oid_str += to_string(id[i]); + oid_str += std::to_string(id[i]); if(i != id.size() - 1) oid_str += '.'; } @@ -129,7 +129,7 @@ void OID::encode_into(DER_Encoder& der) const if(id.size() < 2) throw Invalid_Argument("OID::encode_into: OID is invalid"); - MemoryVector<byte> encoding; + std::vector<byte> encoding; encoding.push_back(40 * id[0] + id[1]); for(size_t i = 2; i != id.size(); ++i) diff --git a/src/asn1/asn1_str.cpp b/src/asn1/asn1_str.cpp index b28f36d90..44db189f9 100644 --- a/src/asn1/asn1_str.cpp +++ b/src/asn1/asn1_str.cpp @@ -77,7 +77,7 @@ ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : tag(t) tag != UTF8_STRING && tag != BMP_STRING) throw Invalid_Argument("ASN1_String: Unknown string type " + - to_string(tag)); + std::to_string(tag)); } /* diff --git a/src/asn1/asn1_tm.cpp b/src/asn1/asn1_tm.cpp index a059e0528..b8095a41c 100644 --- a/src/asn1/asn1_tm.cpp +++ b/src/asn1/asn1_tm.cpp @@ -10,7 +10,7 @@ #include <botan/ber_dec.h> #include <botan/charset.h> #include <botan/parsing.h> -#include <botan/time.h> +#include <botan/calendar.h> namespace Botan { @@ -23,11 +23,11 @@ X509_Time::X509_Time(const std::string& time_str) } /* -* Create an X509_Time +* Create a X509_Time from a time point */ -X509_Time::X509_Time(u64bit timer) +X509_Time::X509_Time(const std::chrono::system_clock::time_point& time) { - calendar_point cal = calendar_value(timer); + calendar_point cal = calendar_value(time); year = cal.year; month = cal.month; @@ -98,7 +98,7 @@ void X509_Time::set_to(const std::string& time_str) void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag) { if(spec_tag != GENERALIZED_TIME && spec_tag != UTC_TIME) - throw Invalid_Argument("X509_Time: Invalid tag " + to_string(spec_tag)); + throw Invalid_Argument("X509_Time: Invalid tag " + std::to_string(spec_tag)); if(spec_tag == GENERALIZED_TIME && t_spec.size() != 13 && t_spec.size() != 15) throw Invalid_Argument("Invalid GeneralizedTime: " + t_spec); @@ -182,24 +182,30 @@ std::string X509_Time::as_string() const if(time_is_set() == false) throw Invalid_State("X509_Time::as_string: No time set"); - std::string asn1rep; - if(tag == GENERALIZED_TIME) - asn1rep = to_string(year, 4); - else if(tag == UTC_TIME) + u32bit full_year = year; + + if(tag == UTC_TIME) { if(year < 1950 || year >= 2050) throw Encoding_Error("X509_Time: The time " + readable_string() + " cannot be encoded as a UTCTime"); - u32bit asn1year = (year >= 2000) ? (year - 2000) : (year - 1900); - asn1rep = to_string(asn1year, 2); + + full_year = (year >= 2000) ? (year - 2000) : (year - 1900); } - else - throw Invalid_Argument("X509_Time: Invalid tag " + to_string(tag)); - asn1rep += to_string(month, 2) + to_string(day, 2); - asn1rep += to_string(hour, 2) + to_string(minute, 2) + to_string(second, 2); - asn1rep += "Z"; - return asn1rep; + std::string repr = std::to_string(full_year*10000000000 + + month*100000000 + + day*1000000 + + hour*10000 + + minute*100 + + second) + "Z"; + + u32bit desired_size = (tag == UTC_TIME) ? 13 : 15; + + while(repr.size() < desired_size) + repr = "0" + repr; + + return repr; } /* @@ -218,14 +224,12 @@ std::string X509_Time::readable_string() const if(time_is_set() == false) throw Invalid_State("X509_Time::readable_string: No time set"); - std::string readable; - readable += to_string(year, 4) + "/"; - readable += to_string(month ) + "/"; - readable += to_string(day ) + " "; - readable += to_string(hour ) + ":"; - readable += to_string(minute, 2) + ":"; - readable += to_string(second, 2) + " UTC"; - return readable; + std::string output(24, 0); + + std::sprintf(&output[0], "%04d/%02d/%02d %02d:%02d:%02d UTC", + year, month, day, hour, minute, second); + + return output; } /* diff --git a/src/asn1/ber_dec.cpp b/src/asn1/ber_dec.cpp index b31c7b903..dbd59988b 100644 --- a/src/asn1/ber_dec.cpp +++ b/src/asn1/ber_dec.cpp @@ -99,7 +99,7 @@ size_t decode_length(DataSource* ber) */ size_t find_eoc(DataSource* ber) { - SecureVector<byte> buffer(DEFAULT_BUFFERSIZE), data; + secure_vector<byte> buffer(DEFAULT_BUFFERSIZE), data; while(true) { @@ -141,7 +141,11 @@ size_t find_eoc(DataSource* ber) void BER_Object::assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) { if(this->type_tag != type_tag || this->class_tag != class_tag) - throw BER_Decoding_Error("Tag mismatch when decoding"); + throw BER_Decoding_Error("Tag mismatch when decoding got " + + std::to_string(this->type_tag) + "/" + + std::to_string(this->class_tag) + " expected " + + std::to_string(type_tag) + "/" + + std::to_string(class_tag)); } /* @@ -167,7 +171,16 @@ BER_Decoder& BER_Decoder::verify_end() /* * Save all the bytes remaining in the source */ -BER_Decoder& BER_Decoder::raw_bytes(MemoryRegion<byte>& out) +BER_Decoder& BER_Decoder::raw_bytes(secure_vector<byte>& out) + { + out.clear(); + byte buf; + while(source->read_byte(buf)) + out.push_back(buf); + return (*this); + } + +BER_Decoder& BER_Decoder::raw_bytes(std::vector<byte>& out) { out.clear(); byte buf; @@ -208,7 +221,10 @@ BER_Object BER_Decoder::get_next_object() size_t length = decode_length(source); next.value.resize(length); if(source->read(&next.value[0], length) != length) + { + abort(); throw BER_Decoding_Error("Value truncated"); + } if(next.type_tag == EOC && next.class_tag == UNIVERSAL) return get_next_object(); @@ -260,7 +276,7 @@ BER_Decoder::BER_Decoder(DataSource& src) source = &src; owns = false; pushed.type_tag = pushed.class_tag = NO_OBJECT; - parent = 0; + parent = nullptr; } /* @@ -271,18 +287,29 @@ BER_Decoder::BER_Decoder(const byte data[], size_t length) source = new DataSource_Memory(data, length); owns = true; pushed.type_tag = pushed.class_tag = NO_OBJECT; - parent = 0; + parent = nullptr; } /* * BER_Decoder Constructor */ -BER_Decoder::BER_Decoder(const MemoryRegion<byte>& data) +BER_Decoder::BER_Decoder(const secure_vector<byte>& data) { source = new DataSource_Memory(data); owns = true; pushed.type_tag = pushed.class_tag = NO_OBJECT; - parent = 0; + parent = nullptr; + } + +/* +* BER_Decoder Constructor +*/ +BER_Decoder::BER_Decoder(const std::vector<byte>& data) + { + source = new DataSource_Memory(&data[0], data.size()); + owns = true; + pushed.type_tag = pushed.class_tag = NO_OBJECT; + parent = nullptr; } /* @@ -308,7 +335,7 @@ BER_Decoder::~BER_Decoder() { if(owns) delete source; - source = 0; + source = nullptr; } /* @@ -358,7 +385,7 @@ BER_Decoder& BER_Decoder::decode(BigInt& out) BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) { - SecureVector<byte> out_vec; + secure_vector<byte> out_vec; decode(out_vec, OCTET_STRING); out = BigInt::decode(&out_vec[0], out_vec.size()); return (*this); @@ -400,6 +427,29 @@ BER_Decoder& BER_Decoder::decode(size_t& out, } /* +* Decode a small BER encoded INTEGER +*/ +u64bit BER_Decoder::decode_constrained_integer(ASN1_Tag type_tag, + ASN1_Tag class_tag, + size_t T_bytes) + { + if(T_bytes > 8) + throw BER_Decoding_Error("Can't decode small integer over 8 bytes"); + + BigInt integer; + decode(integer, type_tag, class_tag); + + if(integer.bits() > 8*T_bytes) + throw BER_Decoding_Error("Decoded integer value larger than expected"); + + u64bit out = 0; + for(size_t i = 0; i != 8; ++i) + out = (out << 8) | integer.byte_at(7-i); + + return out; + } + +/* * Decode a BER encoded INTEGER */ BER_Decoder& BER_Decoder::decode(BigInt& out, @@ -435,7 +485,15 @@ BER_Decoder& BER_Decoder::decode(BigInt& out, /* * BER decode a BIT STRING or OCTET STRING */ -BER_Decoder& BER_Decoder::decode(MemoryRegion<byte>& out, ASN1_Tag real_type) +BER_Decoder& BER_Decoder::decode(secure_vector<byte>& out, ASN1_Tag real_type) + { + return decode(out, real_type, real_type, UNIVERSAL); + } + +/* +* BER decode a BIT STRING or OCTET STRING +*/ +BER_Decoder& BER_Decoder::decode(std::vector<byte>& out, ASN1_Tag real_type) { return decode(out, real_type, real_type, UNIVERSAL); } @@ -443,7 +501,7 @@ BER_Decoder& BER_Decoder::decode(MemoryRegion<byte>& out, ASN1_Tag real_type) /* * BER decode a BIT STRING or OCTET STRING */ -BER_Decoder& BER_Decoder::decode(MemoryRegion<byte>& buffer, +BER_Decoder& BER_Decoder::decode(secure_vector<byte>& buffer, ASN1_Tag real_type, ASN1_Tag type_tag, ASN1_Tag class_tag) { @@ -466,10 +524,50 @@ BER_Decoder& BER_Decoder::decode(MemoryRegion<byte>& buffer, return (*this); } +BER_Decoder& BER_Decoder::decode(std::vector<byte>& buffer, + ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + if(real_type != OCTET_STRING && real_type != BIT_STRING) + throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); + + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, class_tag); + + if(real_type == OCTET_STRING) + buffer = unlock(obj.value); + else + { + if(obj.value[0] >= 8) + throw BER_Decoding_Error("Bad number of unused bits in BIT STRING"); + + buffer.resize(obj.value.size() - 1); + copy_mem(&buffer[0], &obj.value[1], obj.value.size() - 1); + } + return (*this); + } + /* * Decode an OPTIONAL string type */ -BER_Decoder& BER_Decoder::decode_optional_string(MemoryRegion<byte>& out, +BER_Decoder& BER_Decoder::decode_optional_string(secure_vector<byte>& out, + ASN1_Tag real_type, + u16bit type_no) + { + BER_Object obj = get_next_object(); + + ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no); + + out.clear(); + push_back(obj); + + if(obj.type_tag == type_tag && obj.class_tag == CONTEXT_SPECIFIC) + decode(out, real_type, type_tag, CONTEXT_SPECIFIC); + + return (*this); + } + +BER_Decoder& BER_Decoder::decode_optional_string(std::vector<byte>& out, ASN1_Tag real_type, u16bit type_no) { diff --git a/src/asn1/ber_dec.h b/src/asn1/ber_dec.h index 5f79d3fc1..6b010fcc4 100644 --- a/src/asn1/ber_dec.h +++ b/src/asn1/ber_dec.h @@ -20,33 +20,68 @@ class BOTAN_DLL BER_Decoder { public: BER_Object get_next_object(); - void push_back(const BER_Object&); + void push_back(const BER_Object& obj); bool more_items() const; BER_Decoder& verify_end(); BER_Decoder& discard_remaining(); - BER_Decoder start_cons(ASN1_Tag, ASN1_Tag = UNIVERSAL); + BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL); BER_Decoder& end_cons(); - BER_Decoder& raw_bytes(MemoryRegion<byte>&); + BER_Decoder& raw_bytes(secure_vector<byte>& v); + BER_Decoder& raw_bytes(std::vector<byte>& v); BER_Decoder& decode_null(); - BER_Decoder& decode(bool&); - BER_Decoder& decode(size_t&); - BER_Decoder& decode(class BigInt&); - BER_Decoder& decode(MemoryRegion<byte>&, ASN1_Tag); + BER_Decoder& decode(bool& v); + BER_Decoder& decode(size_t& v); + BER_Decoder& decode(class BigInt& v); + BER_Decoder& decode(std::vector<byte>& v, ASN1_Tag type_tag); + BER_Decoder& decode(secure_vector<byte>& v, ASN1_Tag type_tag); - BER_Decoder& decode(bool&, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(size_t&, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(class BigInt&, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(MemoryRegion<byte>&, ASN1_Tag, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); + BER_Decoder& decode(bool& v, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(class ASN1_Object&); + BER_Decoder& decode(size_t& v, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); - BER_Decoder& decode_octet_string_bigint(class BigInt&); + BER_Decoder& decode(class BigInt& v, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(std::vector<byte>& v, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(secure_vector<byte>& v, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(class ASN1_Object& obj); + + BER_Decoder& decode_octet_string_bigint(class BigInt& b); + + u64bit decode_constrained_integer(ASN1_Tag type_tag, + ASN1_Tag class_tag, + size_t T_bytes); + + template<typename T> BER_Decoder& decode_integer_type(T& out) + { + return decode_integer_type<T>(out, INTEGER, UNIVERSAL); + } + + template<typename T> + BER_Decoder& decode_integer_type(T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC) + { + out = decode_constrained_integer(type_tag, class_tag, sizeof(out)); + return (*this); + } template<typename T> BER_Decoder& decode_optional(T& out, @@ -71,17 +106,27 @@ class BOTAN_DLL BER_Decoder return (*this); } - BER_Decoder& decode_optional_string(MemoryRegion<byte>&, - ASN1_Tag, u16bit); + BER_Decoder& decode_optional_string(std::vector<byte>& out, + ASN1_Tag real_type, + u16bit type_no); + + BER_Decoder& decode_optional_string(secure_vector<byte>& out, + ASN1_Tag real_type, + u16bit type_no); + + BER_Decoder& operator=(const BER_Decoder&) = delete; BER_Decoder(DataSource&); + BER_Decoder(const byte[], size_t); - BER_Decoder(const MemoryRegion<byte>&); + + BER_Decoder(const secure_vector<byte>&); + + BER_Decoder(const std::vector<byte>& vec); + BER_Decoder(const BER_Decoder&); ~BER_Decoder(); private: - BER_Decoder& operator=(const BER_Decoder&) { return (*this); } - BER_Decoder* parent; DataSource* source; BER_Object pushed; diff --git a/src/asn1/der_enc.cpp b/src/asn1/der_enc.cpp index a14b3c5e2..594c32539 100644 --- a/src/asn1/der_enc.cpp +++ b/src/asn1/der_enc.cpp @@ -20,13 +20,13 @@ namespace { /* * DER encode an ASN.1 type tag */ -SecureVector<byte> encode_tag(ASN1_Tag type_tag, ASN1_Tag class_tag) +secure_vector<byte> encode_tag(ASN1_Tag type_tag, ASN1_Tag class_tag) { if((class_tag | 0xE0) != 0xE0) throw Encoding_Error("DER_Encoder: Invalid class tag " + - to_string(class_tag)); + std::to_string(class_tag)); - SecureVector<byte> encoded_tag; + secure_vector<byte> encoded_tag; if(type_tag <= 30) encoded_tag.push_back(static_cast<byte>(type_tag | class_tag)); else @@ -46,9 +46,9 @@ SecureVector<byte> encode_tag(ASN1_Tag type_tag, ASN1_Tag class_tag) /* * DER encode an ASN.1 length field */ -SecureVector<byte> encode_length(size_t length) +secure_vector<byte> encode_length(size_t length) { - SecureVector<byte> encoded_length; + secure_vector<byte> encoded_length; if(length <= 127) encoded_length.push_back(static_cast<byte>(length)); else @@ -68,7 +68,7 @@ SecureVector<byte> encode_length(size_t length) /* * Return the encoded SEQUENCE/SET */ -SecureVector<byte> DER_Encoder::DER_Sequence::get_contents() +secure_vector<byte> DER_Encoder::DER_Sequence::get_contents() { const ASN1_Tag real_class_tag = ASN1_Tag(class_tag | CONSTRUCTED); @@ -80,7 +80,7 @@ SecureVector<byte> DER_Encoder::DER_Sequence::get_contents() set_contents.clear(); } - SecureVector<byte> result; + secure_vector<byte> result; result += encode_tag(type_tag, real_class_tag); result += encode_length(contents.size()); result += contents; @@ -95,7 +95,7 @@ SecureVector<byte> DER_Encoder::DER_Sequence::get_contents() void DER_Encoder::DER_Sequence::add_bytes(const byte data[], size_t length) { if(type_tag == SET) - set_contents.push_back(SecureVector<byte>(data, length)); + set_contents.push_back(secure_vector<byte>(data, data + length)); else contents += std::make_pair(data, length); } @@ -119,12 +119,12 @@ DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) : /* * Return the encoded contents */ -SecureVector<byte> DER_Encoder::get_contents() +secure_vector<byte> DER_Encoder::get_contents() { if(subsequences.size() != 0) throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); - SecureVector<byte> output; + secure_vector<byte> output; std::swap(output, contents); return output; } @@ -147,7 +147,7 @@ DER_Encoder& DER_Encoder::end_cons() if(subsequences.empty()) throw Invalid_State("DER_Encoder::end_cons: No such sequence"); - SecureVector<byte> seq = subsequences[subsequences.size()-1].get_contents(); + secure_vector<byte> seq = subsequences[subsequences.size()-1].get_contents(); subsequences.pop_back(); raw_bytes(seq); return (*this); @@ -177,7 +177,12 @@ DER_Encoder& DER_Encoder::end_explicit() /* * Write raw bytes into the stream */ -DER_Encoder& DER_Encoder::raw_bytes(const MemoryRegion<byte>& val) +DER_Encoder& DER_Encoder::raw_bytes(const secure_vector<byte>& val) + { + return raw_bytes(&val[0], val.size()); + } + +DER_Encoder& DER_Encoder::raw_bytes(const std::vector<byte>& val) { return raw_bytes(&val[0], val.size()); } @@ -200,7 +205,7 @@ DER_Encoder& DER_Encoder::raw_bytes(const byte bytes[], size_t length) */ DER_Encoder& DER_Encoder::encode_null() { - return add_object(NULL_TAG, UNIVERSAL, 0, 0); + return add_object(NULL_TAG, UNIVERSAL, nullptr, 0); } /* @@ -230,7 +235,17 @@ DER_Encoder& DER_Encoder::encode(const BigInt& n) /* * DER encode an OCTET STRING or BIT STRING */ -DER_Encoder& DER_Encoder::encode(const MemoryRegion<byte>& bytes, +DER_Encoder& DER_Encoder::encode(const secure_vector<byte>& bytes, + ASN1_Tag real_type) + { + return encode(&bytes[0], bytes.size(), + real_type, real_type, UNIVERSAL); + } + +/* +* DER encode an OCTET STRING or BIT STRING +*/ +DER_Encoder& DER_Encoder::encode(const std::vector<byte>& bytes, ASN1_Tag real_type) { return encode(&bytes[0], bytes.size(), @@ -275,7 +290,7 @@ DER_Encoder& DER_Encoder::encode(const BigInt& n, return add_object(type_tag, class_tag, 0); bool extra_zero = (n.bits() % 8 == 0); - SecureVector<byte> contents(extra_zero + n.bytes()); + secure_vector<byte> contents(extra_zero + n.bytes()); BigInt::encode(&contents[extra_zero], n); if(n < 0) { @@ -292,7 +307,18 @@ DER_Encoder& DER_Encoder::encode(const BigInt& n, /* * DER encode an OCTET STRING or BIT STRING */ -DER_Encoder& DER_Encoder::encode(const MemoryRegion<byte>& bytes, +DER_Encoder& DER_Encoder::encode(const secure_vector<byte>& bytes, + ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + return encode(&bytes[0], bytes.size(), + real_type, type_tag, class_tag); + } + +/* +* DER encode an OCTET STRING or BIT STRING +*/ +DER_Encoder& DER_Encoder::encode(const std::vector<byte>& bytes, ASN1_Tag real_type, ASN1_Tag type_tag, ASN1_Tag class_tag) { @@ -312,7 +338,7 @@ DER_Encoder& DER_Encoder::encode(const byte bytes[], size_t length, if(real_type == BIT_STRING) { - SecureVector<byte> encoded; + secure_vector<byte> encoded; encoded.push_back(0); encoded += std::make_pair(bytes, length); return add_object(type_tag, class_tag, encoded); @@ -346,7 +372,7 @@ DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj) DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const byte rep[], size_t length) { - SecureVector<byte> buffer; + secure_vector<byte> buffer; buffer += encode_tag(type_tag, class_tag); buffer += encode_length(length); buffer += std::make_pair(rep, length); @@ -358,17 +384,6 @@ DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, * Write the encoding of the byte(s) */ DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const MemoryRegion<byte>& rep_buf) - { - const byte* rep = &rep_buf[0]; - const size_t rep_len = rep_buf.size(); - return add_object(type_tag, class_tag, rep, rep_len); - } - -/* -* Write the encoding of the byte(s) -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const std::string& rep_str) { const byte* rep = reinterpret_cast<const byte*>(rep_str.data()); diff --git a/src/asn1/der_enc.h b/src/asn1/der_enc.h index 183e43b80..adab02247 100644 --- a/src/asn1/der_enc.h +++ b/src/asn1/der_enc.h @@ -22,7 +22,10 @@ class ASN1_Object; class BOTAN_DLL DER_Encoder { public: - SecureVector<byte> get_contents(); + secure_vector<byte> get_contents(); + + std::vector<byte> get_contents_unlocked() + { return unlock(get_contents()); } DER_Encoder& start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL); @@ -32,13 +35,15 @@ class BOTAN_DLL DER_Encoder DER_Encoder& end_explicit(); DER_Encoder& raw_bytes(const byte val[], size_t len); - DER_Encoder& raw_bytes(const MemoryRegion<byte>& val); + DER_Encoder& raw_bytes(const secure_vector<byte>& val); + DER_Encoder& raw_bytes(const std::vector<byte>& val); DER_Encoder& encode_null(); DER_Encoder& encode(bool b); DER_Encoder& encode(size_t s); DER_Encoder& encode(const BigInt& n); - DER_Encoder& encode(const MemoryRegion<byte>& v, ASN1_Tag real_type); + DER_Encoder& encode(const secure_vector<byte>& v, ASN1_Tag real_type); + DER_Encoder& encode(const std::vector<byte>& v, ASN1_Tag real_type); DER_Encoder& encode(const byte val[], size_t len, ASN1_Tag real_type); DER_Encoder& encode(bool b, @@ -53,7 +58,12 @@ class BOTAN_DLL DER_Encoder ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(const MemoryRegion<byte>& v, + DER_Encoder& encode(const std::vector<byte>& v, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(const secure_vector<byte>& v, ASN1_Tag real_type, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); @@ -86,7 +96,16 @@ class BOTAN_DLL DER_Encoder const byte rep[], size_t length); DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const MemoryRegion<byte>& rep); + const std::vector<byte>& rep) + { + return add_object(type_tag, class_tag, &rep[0], rep.size()); + } + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const secure_vector<byte>& rep) + { + return add_object(type_tag, class_tag, &rep[0], rep.size()); + } DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const std::string& str); @@ -99,16 +118,16 @@ class BOTAN_DLL DER_Encoder { public: ASN1_Tag tag_of() const; - SecureVector<byte> get_contents(); + secure_vector<byte> get_contents(); void add_bytes(const byte[], size_t); DER_Sequence(ASN1_Tag, ASN1_Tag); private: ASN1_Tag type_tag, class_tag; - SecureVector<byte> contents; - std::vector< SecureVector<byte> > set_contents; + secure_vector<byte> contents; + std::vector< secure_vector<byte> > set_contents; }; - SecureVector<byte> contents; + secure_vector<byte> contents; std::vector<DER_Sequence> subsequences; }; diff --git a/src/asn1/x509_dn.cpp b/src/asn1/x509_dn.cpp index ceb12cee6..c6bc70553 100644 --- a/src/asn1/x509_dn.cpp +++ b/src/asn1/x509_dn.cpp @@ -27,9 +27,8 @@ X509_DN::X509_DN() */ X509_DN::X509_DN(const std::multimap<OID, std::string>& args) { - std::multimap<OID, std::string>::const_iterator j; - for(j = args.begin(); j != args.end(); ++j) - add_attribute(j->first, j->second); + for(auto i = args.begin(); i != args.end(); ++i) + add_attribute(i->first, i->second); } /* @@ -37,9 +36,8 @@ X509_DN::X509_DN(const std::multimap<OID, std::string>& args) */ X509_DN::X509_DN(const std::multimap<std::string, std::string>& args) { - std::multimap<std::string, std::string>::const_iterator j; - for(j = args.begin(); j != args.end(); ++j) - add_attribute(OIDS::lookup(j->first), j->second); + for(auto i = args.begin(); i != args.end(); ++i) + add_attribute(OIDS::lookup(i->first), i->second); } /* @@ -60,11 +58,9 @@ void X509_DN::add_attribute(const OID& oid, const std::string& str) if(str == "") return; - typedef std::multimap<OID, ASN1_String>::iterator rdn_iter; - - std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid); - for(rdn_iter j = range.first; j != range.second; ++j) - if(j->second.value() == str) + auto range = dn_info.equal_range(oid); + for(auto i = range.first; i != range.second; ++i) + if(i->second.value() == str) return; multimap_insert(dn_info, oid, ASN1_String(str)); @@ -76,11 +72,9 @@ void X509_DN::add_attribute(const OID& oid, const std::string& str) */ std::multimap<OID, std::string> X509_DN::get_attributes() const { - typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter; - std::multimap<OID, std::string> retval; - for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j) - multimap_insert(retval, j->first, j->second.value()); + for(auto i = dn_info.begin(); i != dn_info.end(); ++i) + multimap_insert(retval, i->first, i->second.value()); return retval; } @@ -89,11 +83,9 @@ std::multimap<OID, std::string> X509_DN::get_attributes() const */ std::multimap<std::string, std::string> X509_DN::contents() const { - typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter; - std::multimap<std::string, std::string> retval; - for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j) - multimap_insert(retval, OIDS::lookup(j->first), j->second.value()); + for(auto i = dn_info.begin(); i != dn_info.end(); ++i) + multimap_insert(retval, OIDS::lookup(i->first), i->second.value()); return retval; } @@ -102,21 +94,20 @@ std::multimap<std::string, std::string> X509_DN::contents() const */ std::vector<std::string> X509_DN::get_attribute(const std::string& attr) const { - typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter; - const OID oid = OIDS::lookup(deref_info_field(attr)); - std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid); + + auto range = dn_info.equal_range(oid); std::vector<std::string> values; - for(rdn_iter j = range.first; j != range.second; ++j) - values.push_back(j->second.value()); + for(auto i = range.first; i != range.second; ++i) + values.push_back(i->second.value()); return values; } /* * Return the BER encoded data, if any */ -MemoryVector<byte> X509_DN::get_bits() const +std::vector<byte> X509_DN::get_bits() const { return dn_bits; } @@ -143,15 +134,13 @@ std::string X509_DN::deref_info_field(const std::string& info) */ bool operator==(const X509_DN& dn1, const X509_DN& dn2) { - typedef std::multimap<OID, std::string>::const_iterator rdn_iter; - - std::multimap<OID, std::string> attr1 = dn1.get_attributes(); - std::multimap<OID, std::string> attr2 = dn2.get_attributes(); + auto attr1 = dn1.get_attributes(); + auto attr2 = dn2.get_attributes(); if(attr1.size() != attr2.size()) return false; - rdn_iter p1 = attr1.begin(); - rdn_iter p2 = attr2.begin(); + auto p1 = attr1.begin(); + auto p2 = attr2.begin(); while(true) { @@ -181,18 +170,15 @@ bool operator!=(const X509_DN& dn1, const X509_DN& dn2) */ bool operator<(const X509_DN& dn1, const X509_DN& dn2) { - typedef std::multimap<OID, std::string>::const_iterator rdn_iter; - - std::multimap<OID, std::string> attr1 = dn1.get_attributes(); - std::multimap<OID, std::string> attr2 = dn2.get_attributes(); + auto attr1 = dn1.get_attributes(); + auto attr2 = dn2.get_attributes(); if(attr1.size() < attr2.size()) return true; if(attr1.size() > attr2.size()) return false; - for(rdn_iter p1 = attr1.begin(); p1 != attr1.end(); ++p1) + for(auto p1 = attr1.begin(); p1 != attr1.end(); ++p1) { - std::multimap<OID, std::string>::const_iterator p2; - p2 = attr2.find(p1->first); + auto p2 = attr2.find(p1->first); if(p2 == attr2.end()) return false; if(p1->second > p2->second) return false; if(p1->second < p2->second) return true; @@ -210,8 +196,6 @@ void do_ava(DER_Encoder& encoder, ASN1_Tag string_type, const std::string& oid_str, bool must_exist = false) { - typedef std::multimap<OID, std::string>::const_iterator rdn_iter; - const OID oid = OIDS::lookup(oid_str); const bool exists = (dn_info.find(oid) != dn_info.end()); @@ -219,14 +203,14 @@ void do_ava(DER_Encoder& encoder, throw Encoding_Error("X509_DN: No entry for " + oid_str); if(!exists) return; - std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid); + auto range = dn_info.equal_range(oid); - for(rdn_iter j = range.first; j != range.second; ++j) + for(auto i = range.first; i != range.second; ++i) { encoder.start_cons(SET) .start_cons(SEQUENCE) .encode(oid) - .encode(ASN1_String(j->second, string_type)) + .encode(ASN1_String(i->second, string_type)) .end_cons() .end_cons(); } @@ -239,7 +223,7 @@ void do_ava(DER_Encoder& encoder, */ void X509_DN::encode_into(DER_Encoder& der) const { - std::multimap<OID, std::string> dn_info = get_attributes(); + auto dn_info = get_attributes(); der.start_cons(SEQUENCE); @@ -264,7 +248,7 @@ void X509_DN::encode_into(DER_Encoder& der) const */ void X509_DN::decode_from(BER_Decoder& source) { - MemoryVector<byte> bits; + std::vector<byte> bits; source.start_cons(SEQUENCE) .raw_bytes(bits) diff --git a/src/asn1/x509_dn.h b/src/asn1/x509_dn.h index de44f8c78..f8dc9e782 100644 --- a/src/asn1/x509_dn.h +++ b/src/asn1/x509_dn.h @@ -35,14 +35,14 @@ class BOTAN_DLL X509_DN : public ASN1_Object static std::string deref_info_field(const std::string&); - MemoryVector<byte> get_bits() const; + std::vector<byte> get_bits() const; X509_DN(); X509_DN(const std::multimap<OID, std::string>&); X509_DN(const std::multimap<std::string, std::string>&); private: std::multimap<OID, ASN1_String> dn_info; - MemoryVector<byte> dn_bits; + std::vector<byte> dn_bits; }; bool BOTAN_DLL operator==(const X509_DN&, const X509_DN&); |