aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/x509
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-01-18 15:21:47 -0500
committerJack Lloyd <[email protected]>2018-01-18 15:21:47 -0500
commit915e840bd0f77d8c2cd526a5d26a88621708f6ca (patch)
treefa93421e12d31f92e55f50f115f3badd29960669 /src/lib/x509
parente7b9733171835e0a91155589318fdd08b1c68113 (diff)
Prepare for making BER_Object members private
Now there are usable accessors that allow the library to avoid using BER_Object members directly.
Diffstat (limited to 'src/lib/x509')
-rw-r--r--src/lib/x509/asn1_alt_name.cpp48
-rw-r--r--src/lib/x509/name_constraint.cpp51
-rw-r--r--src/lib/x509/ocsp.cpp6
-rw-r--r--src/lib/x509/ocsp_types.cpp2
-rw-r--r--src/lib/x509/pkcs10.cpp17
-rw-r--r--src/lib/x509/x509_crl.cpp11
-rw-r--r--src/lib/x509/x509_ext.cpp31
-rw-r--r--src/lib/x509/x509cert.cpp24
-rw-r--r--src/lib/x509/x509cert.h7
9 files changed, 98 insertions, 99 deletions
diff --git a/src/lib/x509/asn1_alt_name.cpp b/src/lib/x509/asn1_alt_name.cpp
index c9f7c780b..4e052ca58 100644
--- a/src/lib/x509/asn1_alt_name.cpp
+++ b/src/lib/x509/asn1_alt_name.cpp
@@ -179,18 +179,15 @@ void AlternativeName::decode_from(BER_Decoder& source)
{
BER_Decoder names = source.start_cons(SEQUENCE);
+ // FIXME this is largely a duplication of GeneralName::decode_from
+
while(names.more_items())
{
BER_Object obj = names.get_next_object();
- if((obj.class_tag != CONTEXT_SPECIFIC) &&
- (obj.class_tag != (CONTEXT_SPECIFIC | CONSTRUCTED)))
- continue;
-
- const ASN1_Tag tag = obj.type_tag;
- if(tag == 0)
+ if(obj.is_a(0, CONTEXT_SPECIFIC))
{
- BER_Decoder othername(obj.value);
+ BER_Decoder othername(obj);
OID oid;
othername.decode(oid);
@@ -199,34 +196,35 @@ void AlternativeName::decode_from(BER_Decoder& source)
BER_Object othername_value_outer = othername.get_next_object();
othername.verify_end();
- if(othername_value_outer.type_tag != ASN1_Tag(0) ||
- othername_value_outer.class_tag !=
- (CONTEXT_SPECIFIC | CONSTRUCTED)
- )
+ if(othername_value_outer.is_a(0, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)) == false)
throw Decoding_Error("Invalid tags on otherName value");
- BER_Decoder othername_value_inner(othername_value_outer.value);
+ BER_Decoder othername_value_inner(othername_value_outer);
BER_Object value = othername_value_inner.get_next_object();
othername_value_inner.verify_end();
- const ASN1_Tag value_type = value.type_tag;
-
- if(ASN1_String::is_string_type(value_type) && value.class_tag == UNIVERSAL)
+ if(ASN1_String::is_string_type(value.type()) && value.get_class() == UNIVERSAL)
{
- add_othername(oid, ASN1::to_string(value), value_type);
+ add_othername(oid, ASN1::to_string(value), value.type());
}
}
}
- else if(tag == 1 || tag == 2 || tag == 6)
+ if(obj.is_a(1, CONTEXT_SPECIFIC))
+ {
+ add_attribute("RFC822", ASN1::to_string(obj));
+ }
+ else if(obj.is_a(2, CONTEXT_SPECIFIC))
+ {
+ add_attribute("DNS", ASN1::to_string(obj));
+ }
+ else if(obj.is_a(6, CONTEXT_SPECIFIC))
{
- if(tag == 1) add_attribute("RFC822", ASN1::to_string(obj));
- if(tag == 2) add_attribute("DNS", ASN1::to_string(obj));
- if(tag == 6) add_attribute("URI", ASN1::to_string(obj));
+ add_attribute("URI", ASN1::to_string(obj));
}
- else if(tag == 4)
+ else if(obj.is_a(4, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)))
{
- BER_Decoder dec(obj.value);
+ BER_Decoder dec(obj);
X509_DN dn;
std::stringstream ss;
@@ -235,11 +233,11 @@ void AlternativeName::decode_from(BER_Decoder& source)
add_attribute("DN", ss.str());
}
- else if(tag == 7)
+ else if(obj.is_a(7, CONTEXT_SPECIFIC))
{
- if(obj.value.size() == 4)
+ if(obj.length() == 4)
{
- const uint32_t ip = load_be<uint32_t>(&obj.value[0], 0);
+ const uint32_t ip = load_be<uint32_t>(obj.bits(), 0);
add_attribute("IP", ipv4_to_string(ip));
}
}
diff --git a/src/lib/x509/name_constraint.cpp b/src/lib/x509/name_constraint.cpp
index 21145824b..888291557 100644
--- a/src/lib/x509/name_constraint.cpp
+++ b/src/lib/x509/name_constraint.cpp
@@ -41,58 +41,49 @@ void GeneralName::encode_into(DER_Encoder&) const
void GeneralName::decode_from(class BER_Decoder& ber)
{
BER_Object obj = ber.get_next_object();
- if((obj.class_tag != CONTEXT_SPECIFIC) &&
- (obj.class_tag != (CONTEXT_SPECIFIC | CONSTRUCTED)))
- throw Decoding_Error("Invalid class tag while decoding GeneralName");
- const ASN1_Tag tag = obj.type_tag;
-
- if(tag == 1 || tag == 2 || tag == 6)
+ if(obj.is_a(1, CONTEXT_SPECIFIC))
{
+ m_type = "RFC822";
m_name = ASN1::to_string(obj);
-
- if(tag == 1)
- {
- m_type = "RFC822";
- }
- else if(tag == 2)
- {
- m_type = "DNS";
- }
- else if(tag == 6)
- {
- m_type = "URI";
- }
}
- else if(tag == 4)
+ else if(obj.is_a(2, CONTEXT_SPECIFIC))
{
+ m_type = "DNS";
+ m_name = ASN1::to_string(obj);
+ }
+ else if(obj.is_a(6, CONTEXT_SPECIFIC))
+ {
+ m_type = "URI";
+ m_name = ASN1::to_string(obj);
+ }
+ else if(obj.is_a(4, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)))
+ {
+ m_type = "DN";
X509_DN dn;
- BER_Decoder dec(obj.value);
+ BER_Decoder dec(obj);
std::stringstream ss;
dn.decode_from(dec);
ss << dn;
m_name = ss.str();
- m_type = "DN";
}
- else if(tag == 7)
+ else if(obj.is_a(7, CONTEXT_SPECIFIC))
{
- if(obj.value.size() == 8)
+ if(obj.length() == 8)
{
- const std::vector<uint8_t> ip(obj.value.begin(), obj.value.begin() + 4);
- const std::vector<uint8_t> net(obj.value.begin() + 4, obj.value.end());
m_type = "IP";
- m_name = ipv4_to_string(load_be<uint32_t>(ip.data(), 0)) + "/" + ipv4_to_string(load_be<uint32_t>(net.data(), 0));
+ m_name = ipv4_to_string(load_be<uint32_t>(obj.bits(), 0)) + "/" +
+ ipv4_to_string(load_be<uint32_t>(obj.bits(), 1));
}
- else if(obj.value.size() == 32)
+ else if(obj.length() == 32)
{
throw Decoding_Error("Unsupported IPv6 name constraint");
}
else
{
- throw Decoding_Error("Invalid IP name constraint size " +
- std::to_string(obj.value.size()));
+ throw Decoding_Error("Invalid IP name constraint size " + std::to_string(obj.length()));
}
}
else
diff --git a/src/lib/x509/ocsp.cpp b/src/lib/x509/ocsp.cpp
index 5a98b7495..10449b019 100644
--- a/src/lib/x509/ocsp.cpp
+++ b/src/lib/x509/ocsp.cpp
@@ -32,18 +32,18 @@ void decode_optional_list(BER_Decoder& ber,
{
BER_Object obj = ber.get_next_object();
- if(obj.type_tag != tag || obj.class_tag != (CONTEXT_SPECIFIC | CONSTRUCTED))
+ if(obj.is_a(tag, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)) == false)
{
ber.push_back(obj);
return;
}
- BER_Decoder list(obj.value);
+ BER_Decoder list(obj);
while(list.more_items())
{
BER_Object certbits = list.get_next_object();
- X509_Certificate cert(unlock(certbits.value));
+ X509_Certificate cert(certbits.bits(), certbits.length());
output.push_back(std::move(cert));
}
}
diff --git a/src/lib/x509/ocsp_types.cpp b/src/lib/x509/ocsp_types.cpp
index 353cb100a..3eda5c05b 100644
--- a/src/lib/x509/ocsp_types.cpp
+++ b/src/lib/x509/ocsp_types.cpp
@@ -97,7 +97,7 @@ void SingleResponse::decode_from(class BER_Decoder& from)
ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED))
.end_cons();
- m_cert_status = cert_status.type_tag;
+ m_cert_status = cert_status.type();
}
}
diff --git a/src/lib/x509/pkcs10.cpp b/src/lib/x509/pkcs10.cpp
index b1543e398..78fea8dc6 100644
--- a/src/lib/x509/pkcs10.cpp
+++ b/src/lib/x509/pkcs10.cpp
@@ -72,20 +72,18 @@ std::unique_ptr<PKCS10_Data> decode_pkcs10(const std::vector<uint8_t>& body)
cert_req_info.decode(data->m_subject_dn);
BER_Object public_key = cert_req_info.get_next_object();
- if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED)
- throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for public key",
- public_key.type_tag, public_key.class_tag);
+ if(public_key.is_a(SEQUENCE, CONSTRUCTED) == false)
+ throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for public key", public_key.tagging());
- data->m_public_key_bits = ASN1::put_in_sequence(unlock(public_key.value));
+ data->m_public_key_bits = ASN1::put_in_sequence(public_key.bits(), public_key.length());
BER_Object attr_bits = cert_req_info.get_next_object();
std::set<std::string> pkcs9_email;
- if(attr_bits.type_tag == 0 &&
- attr_bits.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
+ if(attr_bits.is_a(0, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)))
{
- BER_Decoder attributes(attr_bits.value);
+ BER_Decoder attributes(attr_bits);
while(attributes.more_items())
{
Attribute attr;
@@ -113,9 +111,8 @@ std::unique_ptr<PKCS10_Data> decode_pkcs10(const std::vector<uint8_t>& body)
}
attributes.verify_end();
}
- else if(attr_bits.type_tag != NO_OBJECT)
- throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for attributes",
- attr_bits.type_tag, attr_bits.class_tag);
+ else if(attr_bits.is_set())
+ throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for attributes", attr_bits.tagging());
cert_req_info.verify_end();
diff --git a/src/lib/x509/x509_crl.cpp b/src/lib/x509/x509_crl.cpp
index c6449baf8..da075e009 100644
--- a/src/lib/x509/x509_crl.cpp
+++ b/src/lib/x509/x509_crl.cpp
@@ -141,9 +141,9 @@ std::unique_ptr<CRL_Data> decode_crl_body(const std::vector<uint8_t>& body,
BER_Object next = tbs_crl.get_next_object();
- if(next.type_tag == SEQUENCE && next.class_tag == CONSTRUCTED)
+ if(next.is_a(SEQUENCE, CONSTRUCTED))
{
- BER_Decoder cert_list(next.value);
+ BER_Decoder cert_list(next);
while(cert_list.more_items())
{
@@ -154,15 +154,14 @@ std::unique_ptr<CRL_Data> decode_crl_body(const std::vector<uint8_t>& body,
next = tbs_crl.get_next_object();
}
- if(next.type_tag == 0 &&
- next.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
+ if(next.is_a(0, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)))
{
- BER_Decoder crl_options(next.value);
+ BER_Decoder crl_options(next);
crl_options.decode(data->m_extensions).verify_end();
next = tbs_crl.get_next_object();
}
- if(next.type_tag != NO_OBJECT)
+ if(next.is_set())
throw X509_CRL::X509_CRL_Error("Unknown tag in CRL");
tbs_crl.verify_end();
diff --git a/src/lib/x509/x509_ext.cpp b/src/lib/x509/x509_ext.cpp
index c3b58236a..44c469c48 100644
--- a/src/lib/x509/x509_ext.cpp
+++ b/src/lib/x509/x509_ext.cpp
@@ -350,22 +350,27 @@ void Key_Usage::decode_inner(const std::vector<uint8_t>& in)
BER_Object obj = ber.get_next_object();
- if(obj.type_tag != BIT_STRING || obj.class_tag != UNIVERSAL)
- throw BER_Bad_Tag("Bad tag for usage constraint",
- obj.type_tag, obj.class_tag);
+ obj.assert_is_a(BIT_STRING, UNIVERSAL, "usage constraint");
- if(obj.value.size() != 2 && obj.value.size() != 3)
+ if(obj.length() != 2 && obj.length() != 3)
throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint");
- if(obj.value[0] >= 8)
+ uint16_t usage = 0;
+
+ const uint8_t* bits = obj.bits();
+
+ if(bits[0] >= 8)
throw BER_Decoding_Error("Invalid unused bits in usage constraint");
- obj.value[obj.value.size()-1] &= (0xFF << obj.value[0]);
+ const uint8_t mask = static_cast<uint8_t>(0xFF << bits[0]);
- uint16_t usage = 0;
- for(size_t i = 1; i != obj.value.size(); ++i)
+ if(obj.length() == 2)
+ {
+ usage = make_uint16(bits[1] & mask, 0);
+ }
+ else if(obj.length() == 3)
{
- usage = (obj.value[i] << 8*(sizeof(usage)-i)) | usage;
+ usage = make_uint16(bits[1], bits[2] & mask);
}
m_constraints = Key_Constraints(usage);
@@ -545,7 +550,7 @@ void Name_Constraints::decode_inner(const std::vector<uint8_t>& in)
BER_Object per = ext.get_next_object();
ext.push_back(per);
- if(per.type_tag == 0 && per.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
+ if(per.is_a(0, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)))
{
ext.decode_list(permit,ASN1_Tag(0),ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));
if(permit.empty())
@@ -554,7 +559,7 @@ void Name_Constraints::decode_inner(const std::vector<uint8_t>& in)
BER_Object exc = ext.get_next_object();
ext.push_back(exc);
- if(per.type_tag == 1 && per.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
+ if(per.is_a(1, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)))
{
ext.decode_list(exclude,ASN1_Tag(1),ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));
if(exclude.empty())
@@ -771,7 +776,7 @@ void Authority_Information_Access::decode_inner(const std::vector<uint8_t>& in)
{
BER_Object name = info.get_next_object();
- if(name.type_tag == 6 && name.class_tag == CONTEXT_SPECIFIC)
+ if(name.is_a(6, CONTEXT_SPECIFIC))
{
m_ocsp_responder = ASN1::to_string(name);
}
@@ -781,7 +786,7 @@ void Authority_Information_Access::decode_inner(const std::vector<uint8_t>& in)
{
BER_Object name = info.get_next_object();
- if(name.type_tag == 6 && name.class_tag == CONTEXT_SPECIFIC)
+ if(name.is_a(6, CONTEXT_SPECIFIC))
{
m_ca_issuers.push_back(ASN1::to_string(name));
}
diff --git a/src/lib/x509/x509cert.cpp b/src/lib/x509/x509cert.cpp
index f298006c0..66921ed66 100644
--- a/src/lib/x509/x509cert.cpp
+++ b/src/lib/x509/x509cert.cpp
@@ -85,6 +85,12 @@ X509_Certificate::X509_Certificate(const std::vector<uint8_t>& vec)
load_data(src);
}
+X509_Certificate::X509_Certificate(const uint8_t data[], size_t len)
+ {
+ DataSource_Memory src(data, len);
+ load_data(src);
+ }
+
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
X509_Certificate::X509_Certificate(const std::string& fsname)
{
@@ -128,13 +134,11 @@ std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& o
data->m_issuer_dn_bits = ASN1::put_in_sequence(data->m_issuer_dn.get_bits());
BER_Object public_key = tbs_cert.get_next_object();
- if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED)
- throw BER_Bad_Tag("X509_Certificate: Unexpected tag for public key",
- public_key.type_tag, public_key.class_tag);
+ public_key.assert_is_a(SEQUENCE, CONSTRUCTED, "X.509 certificate public key");
// validate_public_key_params(public_key.value);
AlgorithmIdentifier public_key_alg_id;
- BER_Decoder(public_key.value).decode(public_key_alg_id).discard_remaining();
+ BER_Decoder(public_key).decode(public_key_alg_id).discard_remaining();
std::vector<std::string> public_key_info =
split_on(OIDS::oid2str(public_key_alg_id.get_oid()), '/');
@@ -180,7 +184,7 @@ std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& o
}
}
- data->m_subject_public_key_bits = unlock(public_key.value);
+ data->m_subject_public_key_bits.assign(public_key.bits(), public_key.bits() + public_key.length());
BER_Decoder(data->m_subject_public_key_bits)
.decode(data->m_subject_public_key_algid)
@@ -190,14 +194,12 @@ std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& o
tbs_cert.decode_optional_string(data->m_v2_subject_key_id, BIT_STRING, 2);
BER_Object v3_exts_data = tbs_cert.get_next_object();
- if(v3_exts_data.type_tag == 3 &&
- v3_exts_data.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
+ if(v3_exts_data.is_a(3, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)))
{
- BER_Decoder(v3_exts_data.value).decode(data->m_v3_extensions).verify_end();
+ BER_Decoder(v3_exts_data).decode(data->m_v3_extensions).verify_end();
}
- else if(v3_exts_data.type_tag != NO_OBJECT)
- throw BER_Bad_Tag("Unknown tag in X.509 cert",
- v3_exts_data.type_tag, v3_exts_data.class_tag);
+ else if(v3_exts_data.is_set())
+ throw BER_Bad_Tag("Unknown tag in X.509 cert", v3_exts_data.tagging());
if(tbs_cert.more_items())
throw Decoding_Error("TBSCertificate has extra data after extensions block");
diff --git a/src/lib/x509/x509cert.h b/src/lib/x509/x509cert.h
index a1448637d..79d16d37f 100644
--- a/src/lib/x509/x509cert.h
+++ b/src/lib/x509/x509cert.h
@@ -408,6 +408,13 @@ class BOTAN_PUBLIC_API(2,0) X509_Certificate : public X509_Object
explicit X509_Certificate(const std::vector<uint8_t>& in);
/**
+ * Create a certificate from a buffer
+ * @param data the buffer containing the DER-encoded certificate
+ * @param length length of data in bytes
+ */
+ X509_Certificate(const uint8_t data[], size_t length);
+
+ /**
* Create an uninitialized certificate object. Any attempts to
* access this object will throw an exception.
*/