aboutsummaryrefslogtreecommitdiffstats
path: root/src/asn1
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-05-25 22:52:00 +0000
committerlloyd <[email protected]>2012-05-25 22:52:00 +0000
commit12090a7148d9ee73572cc1a7268fc489504a8173 (patch)
tree51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/asn1
parent9594979caf775dc4062850044715b804d1fda60c (diff)
parent65cc04445f8d40497f02a14bd8cb97081790e54b (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.cpp4
-rw-r--r--src/asn1/alg_id.h6
-rw-r--r--src/asn1/asn1_alt.cpp27
-rw-r--r--src/asn1/asn1_att.cpp4
-rw-r--r--src/asn1/asn1_int.cpp8
-rw-r--r--src/asn1/asn1_int.h4
-rw-r--r--src/asn1/asn1_obj.h9
-rw-r--r--src/asn1/asn1_oid.cpp4
-rw-r--r--src/asn1/asn1_str.cpp2
-rw-r--r--src/asn1/asn1_tm.cpp54
-rw-r--r--src/asn1/ber_dec.cpp122
-rw-r--r--src/asn1/ber_dec.h85
-rw-r--r--src/asn1/der_enc.cpp73
-rw-r--r--src/asn1/der_enc.h37
-rw-r--r--src/asn1/x509_dn.cpp74
-rw-r--r--src/asn1/x509_dn.h4
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&);