diff options
author | Jack Lloyd <[email protected]> | 2018-01-18 15:21:47 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-01-18 15:21:47 -0500 |
commit | 915e840bd0f77d8c2cd526a5d26a88621708f6ca (patch) | |
tree | fa93421e12d31f92e55f50f115f3badd29960669 /src/lib/x509 | |
parent | e7b9733171835e0a91155589318fdd08b1c68113 (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.cpp | 48 | ||||
-rw-r--r-- | src/lib/x509/name_constraint.cpp | 51 | ||||
-rw-r--r-- | src/lib/x509/ocsp.cpp | 6 | ||||
-rw-r--r-- | src/lib/x509/ocsp_types.cpp | 2 | ||||
-rw-r--r-- | src/lib/x509/pkcs10.cpp | 17 | ||||
-rw-r--r-- | src/lib/x509/x509_crl.cpp | 11 | ||||
-rw-r--r-- | src/lib/x509/x509_ext.cpp | 31 | ||||
-rw-r--r-- | src/lib/x509/x509cert.cpp | 24 | ||||
-rw-r--r-- | src/lib/x509/x509cert.h | 7 |
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. */ |