8 #include <botan/x509_ext.h>
9 #include <botan/sha160.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/oids.h>
13 #include <botan/internal/bit_ops.h>
22 Certificate_Extension* Extensions::get_extension(
const OID&
oid)
24 #define X509_EXTENSION(NAME, TYPE) \
25 if(OIDS::name_of(oid, NAME)) \
26 return new Cert_Extension::TYPE();
33 X509_EXTENSION(
"X509v3.IssuerAlternativeName", Issuer_Alternative_Name);
34 X509_EXTENSION(
"X509v3.SubjectAlternativeName", Subject_Alternative_Name);
36 X509_EXTENSION(
"X509v3.CertificatePolicies", Certificate_Policies);
55 for(
size_t i = 0; i != extensions.size(); ++i)
56 delete extensions[i].first;
59 for(
size_t i = 0; i != other.extensions.size(); ++i)
61 std::make_pair(other.extensions[i].first->copy(),
62 other.extensions[i].second));
64 should_throw = other.should_throw;
79 extensions.push_back(std::make_pair(extn, critical));
87 for(
size_t i = 0; i != extensions.size(); ++i)
90 const bool is_critical = extensions[i].second;
98 .encode_optional(is_critical,
false)
110 for(
size_t i = 0; i != extensions.size(); ++i)
111 delete extensions[i].first;
133 if(!critical || !should_throw)
136 throw Decoding_Error(
"Encountered unknown X.509 extension marked "
137 "as critical; OID = " + oid.
as_string());
142 extensions.push_back(std::make_pair(ext, critical));
153 for(
size_t i = 0; i != extensions.size(); ++i)
154 extensions[i].first->contents_to(subject_info, issuer_info);
162 for(
size_t i = 0; i != extensions.size(); ++i)
163 delete extensions[i].first;
166 namespace Cert_Extension {
174 throw Invalid_State(
"Basic_Constraints::get_path_limit: Not a CA");
188 .encode_optional(path_limit, NO_CERT_PATH_LIMIT)
213 void Basic_Constraints::contents_to(Data_Store& subject, Data_Store&)
const
215 subject.add(
"X509v3.BasicConstraints.is_ca", (is_ca ? 1 : 0));
216 subject.add(
"X509v3.BasicConstraints.path_constraint", path_limit);
222 MemoryVector<byte> Key_Usage::encode_inner()
const
225 throw Encoding_Error(
"Cannot encode zero usage constraints");
227 const size_t unused_bits =
low_bit(constraints) - 1;
229 MemoryVector<byte> der;
231 der.push_back(2 + ((unused_bits < 8) ? 1 : 0));
232 der.push_back(unused_bits % 8);
233 der.push_back((constraints >> 8) & 0xFF);
234 if(constraints & 0xFF)
235 der.push_back(constraints & 0xFF);
243 void Key_Usage::decode_inner(
const MemoryRegion<byte>& in)
247 BER_Object obj = ber.get_next_object();
250 throw BER_Bad_Tag(
"Bad tag for usage constraint",
251 obj.type_tag, obj.class_tag);
253 if(obj.value.size() != 2 && obj.value.size() != 3)
254 throw BER_Decoding_Error(
"Bad size for BITSTRING in usage constraint");
256 if(obj.value[0] >= 8)
257 throw BER_Decoding_Error(
"Invalid unused bits in usage constraint");
259 obj.value[obj.value.size()-1] &= (0xFF << obj.value[0]);
262 for(
size_t i = 1; i != obj.value.size(); ++i)
263 usage = (obj.value[i] << 8) | usage;
271 void Key_Usage::contents_to(Data_Store& subject, Data_Store&)
const
273 subject.add(
"X509v3.KeyUsage", constraints);
279 MemoryVector<byte> Subject_Key_ID::encode_inner()
const
281 return DER_Encoder().encode(key_id,
OCTET_STRING).get_contents();
287 void Subject_Key_ID::decode_inner(
const MemoryRegion<byte>& in)
289 BER_Decoder(in).decode(key_id,
OCTET_STRING).verify_end();
295 void Subject_Key_ID::contents_to(Data_Store& subject, Data_Store&)
const
297 subject.add(
"X509v3.SubjectKeyIdentifier", key_id);
306 key_id = hash.
process(pub_key);
334 void Authority_Key_ID::contents_to(Data_Store&, Data_Store& issuer)
const
337 issuer.add(
"X509v3.AuthorityKeyIdentifier", key_id);
343 MemoryVector<byte> Alternative_Name::encode_inner()
const
345 return DER_Encoder().encode(alt_name).get_contents();
351 void Alternative_Name::decode_inner(
const MemoryRegion<byte>& in)
353 BER_Decoder(in).
decode(alt_name);
359 void Alternative_Name::contents_to(Data_Store& subject_info,
360 Data_Store& issuer_info)
const
362 std::multimap<std::string, std::string> contents =
365 if(oid_name_str ==
"X509v3.SubjectAlternativeName")
366 subject_info.add(contents);
367 else if(oid_name_str ==
"X509v3.IssuerAlternativeName")
368 issuer_info.add(contents);
370 throw Internal_Error(
"In Alternative_Name, unknown type " +
378 const std::string& oid_name_str,
379 const std::string& config_name_str)
381 this->alt_name = alt_name;
382 this->oid_name_str = oid_name_str;
383 this->config_name_str = config_name_str;
393 "subject_alternative_name")
402 "issuer_alternative_name")
432 void Extended_Key_Usage::contents_to(Data_Store& subject, Data_Store&)
const
434 for(
size_t i = 0; i != oids.size(); ++i)
435 subject.add(
"X509v3.ExtendedKeyUsage", oids[i].as_string());
443 class Policy_Information :
public ASN1_Object
448 Policy_Information() {}
449 Policy_Information(
const OID& oid) : oid(oid) {}
451 void encode_into(DER_Encoder& codec)
const
458 void decode_from(BER_Decoder& codec)
472 MemoryVector<byte> Certificate_Policies::encode_inner()
const
474 std::vector<Policy_Information> policies;
476 for(
size_t i = 0; i != oids.size(); ++i)
477 policies.push_back(oids[i]);
481 .encode_list(policies)
489 void Certificate_Policies::decode_inner(
const MemoryRegion<byte>& in)
491 std::vector<Policy_Information> policies;
495 .decode_list(policies)
499 for(
size_t i = 0; i != policies.size(); ++i)
500 oids.push_back(policies[i].oid);
506 void Certificate_Policies::contents_to(Data_Store& info, Data_Store&)
const
508 for(
size_t i = 0; i != oids.size(); ++i)
509 info.add(
"X509v3.ExtendedKeyUsage", oids[i].as_string());
551 void CRL_Number::contents_to(Data_Store& info, Data_Store&)
const
553 info.add(
"X509v3.CRLNumber", crl_number);
559 MemoryVector<byte> CRL_ReasonCode::encode_inner()
const
569 void CRL_ReasonCode::decode_inner(
const MemoryRegion<byte>& in)
571 size_t reason_code = 0;
573 reason =
static_cast<CRL_Code>(reason_code);
579 void CRL_ReasonCode::contents_to(Data_Store& info, Data_Store&)
const
581 info.add(
"X509v3.CRLReasonCode", reason);
DER_Encoder & encode_list(const std::vector< T > &values)
virtual std::string oid_name() const =0
SecureVector< byte > get_contents()
Issuer_Alternative_Name(const AlternativeName &=AlternativeName())
virtual MemoryVector< byte > encode_inner() const =0
Alternative_Name(const AlternativeName &, const std::string &, const std::string &)
size_t get_path_limit() const
BER_Decoder & decode_optional_string(MemoryRegion< byte > &, ASN1_Tag, u16bit)
BER_Decoder & decode(bool &)
Extensions(const Extensions &)
CRL_Number * copy() const
std::multimap< std::string, std::string > contents() const
void contents_to(Data_Store &, Data_Store &) const
BER_Decoder start_cons(ASN1_Tag, ASN1_Tag=UNIVERSAL)
void add(Certificate_Extension *extn, bool critical=false)
BER_Decoder & decode_list(std::vector< T > &out, bool clear_out=true)
void decode_from(class BER_Decoder &)
DER_Encoder & encode(bool b)
BER_Decoder & decode_optional(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag, const T &default_value=T())
std::string lookup(const OID &oid)
virtual bool should_encode() const
SecureVector< byte > process(const byte in[], size_t length)
Subject_Alternative_Name(const AlternativeName &=AlternativeName())
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
AlternativeName get_alt_name() const
Extensions & operator=(const Extensions &)
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
BER_Decoder & verify_end()
std::string as_string() const
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
void encode_into(class DER_Encoder &) const
virtual void decode_inner(const MemoryRegion< byte > &)=0
size_t get_crl_number() const
#define X509_EXTENSION(NAME, TYPE)