Botan 3.13.0
Crypto and TLS for C&
Botan::ASN1 Namespace Reference

Functions

std::vector< uint8_t > der_sequence_header (size_t contents_len)
std::vector< uint8_t > integer_contents (const BigInt &n)
BigInt integer_from_contents (std::span< const uint8_t > contents)
bool is_der_sequence_header (std::span< const uint8_t > bytes)
bool is_single_der_object (std::span< const uint8_t > bytes, ASN1_Type expected_type, ASN1_Class expected_class)
bool maybe_BER (DataSource &source)
std::vector< uint8_t > put_in_sequence (const std::vector< uint8_t > &contents)
std::vector< uint8_t > put_in_sequence (const uint8_t bits[], size_t len)
std::string to_string (const BER_Object &obj)

Function Documentation

◆ der_sequence_header()

std::vector< uint8_t > Botan::ASN1::der_sequence_header ( size_t contents_len)

Return the DER tag and length header of a SEQUENCE with the given contents length

Parameters
contents_lenthe length in bytes of the SEQUENCE contents

Definition at line 71 of file der_enc.cpp.

71 {
72 std::vector<uint8_t> header;
73 header.reserve(2 + sizeof(contents_len));
75 encode_length(header, contents_len);
76 return header;
77}

References Botan::Constructed, and Botan::Sequence.

Referenced by put_in_sequence(), Botan::OCSP::Response::verify_signature(), and Botan::X509_Object::verify_signature().

◆ integer_contents()

std::vector< uint8_t > Botan::ASN1::integer_contents ( const BigInt & n)

Return the contents octets of the DER encoding of the INTEGER n: big-endian two's complement, minimal length. Zero encodes as a single 0x00 octet.

Definition at line 356 of file der_enc.cpp.

356 {
357 if(n == 0) {
358 return {0x00};
359 }
360
361 // Serialize magnitude with one extra leading byte
362 auto contents = n.serialize(n.bytes() + 1);
363
364 if(n.signum() < 0) {
365 // Two's complement: bitwise NOT then increment
366 for(auto& byte : contents) {
367 byte = ~byte;
368 }
369 for(size_t i = contents.size(); i > 0; --i) {
370 if(++contents[i - 1] != 0) {
371 break;
372 }
373 }
374 }
375
376 /*
377 * DER requires the leading byte be emitted only if it required
378 */
379 BOTAN_ASSERT_NOMSG(contents.size() >= 2);
380 const bool leading_byte_redundant =
381 (contents[0] == 0x00 && (contents[1] & 0x80) == 0) || (contents[0] == 0xFF && (contents[1] & 0x80) != 0);
382
383 if(leading_byte_redundant) {
384 contents.erase(contents.begin());
385 }
386 return contents;
387}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
int signum() const
Definition bigint.h:493
size_t bytes() const
Definition bigint.cpp:294
T serialize(size_t len) const
Definition bigint.h:790

References BOTAN_ASSERT_NOMSG, Botan::BigInt::bytes(), Botan::BigInt::serialize(), and Botan::BigInt::signum().

Referenced by Botan::DER_Encoder::encode().

◆ integer_from_contents()

BigInt Botan::ASN1::integer_from_contents ( std::span< const uint8_t > contents)

Decode the contents octets of a BER INTEGER (big-endian two's complement). Redundant leading octets are accepted; an empty input is rejected.

Definition at line 801 of file ber_dec.cpp.

801 {
802 if(contents.empty()) {
803 throw BER_Decoding_Error("INTEGER encoding has no content octets");
804 }
805
806 BigInt out;
807
808 const bool negative = (contents[0] & 0x80) == 0x80;
809
810 if(negative) {
811 secure_vector<uint8_t> vec(contents.begin(), contents.end());
812 for(size_t i = vec.size(); i > 0; --i) {
813 const bool gt0 = (vec[i - 1] > 0);
814 vec[i - 1] -= 1;
815 if(gt0) {
816 break;
817 }
818 }
819 for(auto& byte : vec) {
820 byte = ~byte;
821 }
822 out._assign_from_bytes(vec);
824 } else {
825 out._assign_from_bytes(contents);
826 }
827
828 return out;
829}
void _assign_from_bytes(std::span< const uint8_t > bytes)
Definition bigint.h:1044
void set_sign(Sign sign)
Definition bigint.h:663
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128

References Botan::BigInt::_assign_from_bytes(), Botan::BigInt::Negative, and Botan::BigInt::set_sign().

Referenced by Botan::BER_Decoder::decode(), and Botan::X509_Serial_Number::to_bigint().

◆ is_der_sequence_header()

bool Botan::ASN1::is_der_sequence_header ( std::span< const uint8_t > bytes)

Return true if the bytes are exactly one DER-encoded SEQUENCE, that is a SEQUENCE whose tag plus length header plus contents span the entire buffer with no trailing data. The contents themselves are not otherwise validated.

Definition at line 1128 of file ber_dec.cpp.

1128 {
1130}
bool is_single_der_object(std::span< const uint8_t > bytes, ASN1_Type expected_type, ASN1_Class expected_class)
Definition ber_dec.cpp:1100

References Botan::Constructed, is_single_der_object(), Botan::Sequence, and Botan::Universal.

Referenced by Botan::AlgorithmIdentifier::decode_from().

◆ is_single_der_object()

bool Botan::ASN1::is_single_der_object ( std::span< const uint8_t > bytes,
ASN1_Type expected_type,
ASN1_Class expected_class )

Definition at line 1100 of file ber_dec.cpp.

1100 {
1101 if(bytes.empty()) {
1102 return false;
1103 }
1104
1105 try {
1106 DataSource_Span src(bytes);
1107
1108 ASN1_Type type_tag = ASN1_Type::NoObject;
1109 ASN1_Class class_tag = ASN1_Class::NoObject;
1110 const size_t tag_bytes = decode_tag(&src, type_tag, class_tag);
1111
1112 if(type_tag != expected_type || class_tag != expected_class) {
1113 return false;
1114 }
1115
1116 const auto dl = decode_length(&src, /*allow_indef=*/0, /*der_mode=*/true, is_constructed(expected_class));
1117
1118 const size_t header_bytes = tag_bytes + dl.field_length();
1119 if(header_bytes > bytes.size()) {
1120 return false;
1121 }
1122 return dl.content_length() == bytes.size() - header_bytes;
1123 } catch(Decoding_Error&) {
1124 return false;
1125 }
1126}
ASN1_Class
Definition asn1_obj.h:32
ASN1_Type
Definition asn1_obj.h:47

References Botan::NoObject.

Referenced by Botan::AlgorithmIdentifier::decode_from(), and is_der_sequence_header().

◆ maybe_BER()

bool Botan::ASN1::maybe_BER ( DataSource & src)

Heuristics tests; is this object possibly BER?

Parameters
srca data source that will be peeked at but not modified

Definition at line 231 of file asn1_obj.cpp.

231 {
232 uint8_t first_u8 = 0;
233 if(source.peek_byte(first_u8) == 0) {
234 BOTAN_ASSERT_EQUAL(source.read_byte(first_u8), 0, "Expected EOF");
235 throw Stream_IO_Error("ASN1::maybe_BER: Source was empty");
236 }
237
238 const auto cons_seq = static_cast<uint8_t>(ASN1_Class::Constructed) | static_cast<uint8_t>(ASN1_Type::Sequence);
239 return first_u8 == cons_seq;
240}
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition assert.h:88

References BOTAN_ASSERT_EQUAL, Botan::Constructed, Botan::DataSource::peek_byte(), Botan::DataSource::read_byte(), and Botan::Sequence.

Referenced by Botan::X509_Object::load_data(), and Botan::X509::load_key().

◆ put_in_sequence() [1/2]

std::vector< uint8_t > Botan::ASN1::put_in_sequence ( const std::vector< uint8_t > & val)

Return the contents wrapped in a DER SEQUENCE

Parameters
valthe contents of the SEQUENCE

Definition at line 208 of file asn1_obj.cpp.

208 {
209 return ASN1::put_in_sequence(contents.data(), contents.size());
210}
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition asn1_obj.cpp:208

References put_in_sequence().

Referenced by Botan::GeneralName::binary_name(), botan_x509_crl_view_binary_values(), put_in_sequence(), and Botan::X509_Object::tbs_data().

◆ put_in_sequence() [2/2]

std::vector< uint8_t > Botan::ASN1::put_in_sequence ( const uint8_t bits[],
size_t len )

Return the contents wrapped in a DER SEQUENCE

Parameters
bitsthe contents of the SEQUENCE
lenthe length of bits in bytes

Definition at line 212 of file asn1_obj.cpp.

212 {
213 std::vector<uint8_t> output = der_sequence_header(len);
214 output.reserve(output.size() + len);
215 if(len > 0) {
216 output.insert(output.end(), bits, bits + len);
217 }
218 return output;
219}
std::vector< uint8_t > der_sequence_header(size_t contents_len)
Definition der_enc.cpp:71

References der_sequence_header().

◆ to_string()

std::string Botan::ASN1::to_string ( const BER_Object & obj)

Return the contents of a BER object interpreted as a string

Parameters
objthe object whose contents are converted

Definition at line 224 of file asn1_obj.cpp.

224 {
225 return bytes_to_string(obj.data());
226}
std::span< const uint8_t > data() const
Definition asn1_obj.h:308
std::string bytes_to_string(std::span< const uint8_t > bytes)
Definition mem_utils.h:76

References Botan::bytes_to_string(), and Botan::BER_Object::data().

Referenced by Botan::AlternativeName::decode_from(), Botan::ASN1_String::decode_from(), Botan::ASN1_Time::decode_from(), and Botan::GeneralName::decode_from().