Botan 2.19.0
Crypto and TLS for C&
Public Member Functions | Static Public Member Functions | Protected Member Functions | List of all members
Botan::X509_Object Class Referenceabstract

#include <x509_obj.h>

Inheritance diagram for Botan::X509_Object:
Botan::ASN1_Object Botan::PKCS10_Request Botan::X509_CRL Botan::X509_Certificate

Public Member Functions

virtual std::vector< std::string > alternate_PEM_labels () const
 
std::vector< uint8_t > BER_encode () const
 
bool check_signature (const Public_Key &key) const
 
bool check_signature (const Public_Key *key) const
 
void decode_from (class BER_Decoder &from) override
 
void encode_into (class DER_Encoder &to) const override
 
std::string hash_used_for_signature () const
 
X509_Objectoperator= (const X509_Object &)=default
 
std::string PEM_encode () const
 
virtual std::string PEM_label () const =0
 
const std::vector< uint8_t > & signature () const
 
const AlgorithmIdentifiersignature_algorithm () const
 
const std::vector< uint8_t > & signed_body () const
 
std::vector< uint8_t > tbs_data () const
 
Certificate_Status_Code verify_signature (const Public_Key &key) const
 
 X509_Object (const X509_Object &)=default
 
virtual ~X509_Object ()=default
 

Static Public Member Functions

static std::unique_ptr< PK_Signerchoose_sig_format (AlgorithmIdentifier &sig_algo, const Private_Key &key, RandomNumberGenerator &rng, const std::string &hash_fn, const std::string &padding_algo)
 
static std::vector< uint8_t > make_signed (class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &tbs)
 

Protected Member Functions

void load_data (DataSource &src)
 
 X509_Object ()=default
 

Detailed Description

This class represents abstract X.509 signed objects as in the X.500 SIGNED macro

Definition at line 25 of file x509_obj.h.

Constructor & Destructor Documentation

◆ X509_Object() [1/2]

Botan::X509_Object::X509_Object ( const X509_Object )
default

◆ ~X509_Object()

virtual Botan::X509_Object::~X509_Object ( )
virtualdefault

◆ X509_Object() [2/2]

Botan::X509_Object::X509_Object ( )
protecteddefault

Member Function Documentation

◆ alternate_PEM_labels()

virtual std::vector< std::string > Botan::X509_Object::alternate_PEM_labels ( ) const
inlinevirtual

Definition at line 113 of file x509_obj.h.

114 { return std::vector<std::string>(); }

Referenced by load_data().

◆ BER_encode()

std::vector< uint8_t > Botan::ASN1_Object::BER_encode ( ) const
inherited

Return the encoding of this object. This is a convenience method when just one object needs to be serialized. Use DER_Encoder for complicated encodings.

Definition at line 16 of file asn1_obj.cpp.

17 {
18 std::vector<uint8_t> output;
19 DER_Encoder der(output);
20 this->encode_into(der);
21 return output;
22 }
virtual void encode_into(DER_Encoder &to) const =0

References Botan::ASN1_Object::encode_into().

Referenced by Botan::PSSR::config_for_x509(), Botan::Certificate_Store_In_SQL::find_all_certs(), Botan::Certificate_Store_In_SQL::find_cert(), Botan::X509_Certificate::fingerprint(), Botan::Certificate_Store_In_SQL::insert_cert(), PEM_encode(), and Botan::Certificate_Store_In_SQL::revoke_cert().

◆ check_signature() [1/2]

bool Botan::X509_Object::check_signature ( const Public_Key key) const

Check the signature on this data

Parameters
keythe public key purportedly used to sign this data
Returns
true if the signature is valid, otherwise false

Definition at line 178 of file x509_obj.cpp.

179 {
180 const Certificate_Status_Code code = verify_signature(pub_key);
181 return (code == Certificate_Status_Code::VERIFIED);
182 }
Certificate_Status_Code verify_signature(const Public_Key &key) const
Definition: x509_obj.cpp:184
Certificate_Status_Code
Definition: pkix_enums.h:17

References Botan::VERIFIED, and verify_signature().

Referenced by check_signature().

◆ check_signature() [2/2]

bool Botan::X509_Object::check_signature ( const Public_Key key) const

Check the signature on this data

Parameters
keythe public key purportedly used to sign this data the object will be deleted after use (this should have been a std::unique_ptr<Public_Key>)
Returns
true if the signature is valid, otherwise false

Definition at line 170 of file x509_obj.cpp.

171 {
172 if(!pub_key)
173 throw Invalid_Argument("No key provided for " + PEM_label() + " signature check");
174 std::unique_ptr<const Public_Key> key(pub_key);
175 return check_signature(*key);
176 }
virtual std::string PEM_label() const =0
bool check_signature(const Public_Key &key) const
Definition: x509_obj.cpp:178

References check_signature(), and PEM_label().

◆ choose_sig_format()

std::unique_ptr< PK_Signer > Botan::X509_Object::choose_sig_format ( AlgorithmIdentifier sig_algo,
const Private_Key key,
RandomNumberGenerator rng,
const std::string &  hash_fn,
const std::string &  padding_algo 
)
static

Definition at line 411 of file x509_obj.cpp.

416 {
417 const Signature_Format format = key.default_x509_signature_format();
418
419 const std::string emsa = choose_sig_algo(sig_algo, key, hash_fn, padding_algo);
420
421 return std::unique_ptr<PK_Signer>(new PK_Signer(key, rng, emsa, format));
422 }
Signature_Format
Definition: pk_keys.h:23

References Botan::Public_Key::default_x509_signature_format().

Referenced by Botan::choose_sig_format(), and Botan::PKCS10_Request::create().

◆ decode_from()

void Botan::X509_Object::decode_from ( class BER_Decoder from)
overridevirtual

Decode a BER encoded X509_Object See ASN1_Object::decode_from()

Implements Botan::ASN1_Object.

Definition at line 106 of file x509_obj.cpp.

107 {
108 from.start_cons(SEQUENCE)
109 .start_cons(SEQUENCE)
110 .raw_bytes(m_tbs_bits)
111 .end_cons()
112 .decode(m_sig_algo)
113 .decode(m_sig, BIT_STRING)
114 .end_cons();
115
116 force_decode();
117 }
@ BIT_STRING
Definition: asn1_obj.h:37
@ SEQUENCE
Definition: asn1_obj.h:42

References Botan::BIT_STRING, Botan::BER_Decoder::decode(), Botan::BER_Decoder::end_cons(), Botan::BER_Decoder::raw_bytes(), Botan::SEQUENCE, and Botan::BER_Decoder::start_cons().

Referenced by load_data().

◆ encode_into()

void Botan::X509_Object::encode_into ( class DER_Encoder to) const
overridevirtual

DER encode an X509_Object See ASN1_Object::encode_into()

Implements Botan::ASN1_Object.

Definition at line 92 of file x509_obj.cpp.

93 {
94 to.start_cons(SEQUENCE)
95 .start_cons(SEQUENCE)
96 .raw_bytes(signed_body())
97 .end_cons()
98 .encode(signature_algorithm())
99 .encode(signature(), BIT_STRING)
100 .end_cons();
101 }
const std::vector< uint8_t > & signed_body() const
Definition: x509_obj.h:42
const AlgorithmIdentifier & signature_algorithm() const
Definition: x509_obj.h:47
const std::vector< uint8_t > & signature() const
Definition: x509_obj.h:37

References Botan::BIT_STRING, Botan::DER_Encoder::encode(), Botan::DER_Encoder::end_cons(), Botan::DER_Encoder::raw_bytes(), Botan::SEQUENCE, signature(), signature_algorithm(), signed_body(), and Botan::DER_Encoder::start_cons().

◆ hash_used_for_signature()

std::string Botan::X509_Object::hash_used_for_signature ( ) const
Returns
hash algorithm that was used to generate signature

Definition at line 138 of file x509_obj.cpp.

139 {
140 const OID& oid = m_sig_algo.get_oid();
141 const std::vector<std::string> sig_info = split_on(oid.to_formatted_string(), '/');
142
143 if(sig_info.size() == 1 && sig_info[0] == "Ed25519")
144 return "SHA-512";
145 else if(sig_info.size() != 2)
146 throw Internal_Error("Invalid name format found for " + oid.to_string());
147
148 if(sig_info[1] == "EMSA4")
149 {
150 const OID hash_oid = decode_pss_params(signature_algorithm().get_parameters()).hash_algo.get_oid();
151 return hash_oid.to_formatted_string();
152 }
153 else
154 {
155 const std::vector<std::string> pad_and_hash =
156 parse_algorithm_name(sig_info[1]);
157
158 if(pad_and_hash.size() != 2)
159 {
160 throw Internal_Error("Invalid name format " + sig_info[1]);
161 }
162
163 return pad_and_hash[1];
164 }
165 }
const OID & get_oid() const
Definition: asn1_obj.h:445
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:148
std::vector< std::string > parse_algorithm_name(const std::string &namex)
Definition: parsing.cpp:95

References Botan::AlgorithmIdentifier::get_oid(), Botan::parse_algorithm_name(), signature_algorithm(), Botan::split_on(), Botan::OID::to_formatted_string(), and Botan::OID::to_string().

◆ load_data()

void Botan::X509_Object::load_data ( DataSource src)
protected

Decodes from src as either DER or PEM data, then calls force_decode()

Definition at line 52 of file x509_obj.cpp.

53 {
54 try {
56 {
57 BER_Decoder dec(in);
58 decode_from(dec);
59 }
60 else
61 {
62 std::string got_label;
63 DataSource_Memory ber(PEM_Code::decode(in, got_label));
64
65 if(got_label != PEM_label())
66 {
67 bool is_alternate = false;
68 for(std::string alt_label : alternate_PEM_labels())
69 {
70 if(got_label == alt_label)
71 {
72 is_alternate = true;
73 break;
74 }
75 }
76
77 if(!is_alternate)
78 throw Decoding_Error("Unexpected PEM label for " + PEM_label() + " of " + got_label);
79 }
80
81 BER_Decoder dec(ber);
82 decode_from(dec);
83 }
84 }
85 catch(Decoding_Error& e)
86 {
87 throw Decoding_Error(PEM_label() + " decoding", e);
88 }
89 }
void decode_from(class BER_Decoder &from) override
Definition: x509_obj.cpp:106
virtual std::vector< std::string > alternate_PEM_labels() const
Definition: x509_obj.h:113
bool maybe_BER(DataSource &source)
Definition: asn1_obj.cpp:222
bool matches(DataSource &source, const std::string &extra, size_t search_range)
Definition: pem.cpp:142
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68

References alternate_PEM_labels(), Botan::PEM_Code::decode(), decode_from(), Botan::PEM_Code::matches(), Botan::ASN1::maybe_BER(), and PEM_label().

Referenced by Botan::PKCS10_Request::PKCS10_Request(), Botan::X509_Certificate::X509_Certificate(), and Botan::X509_CRL::X509_CRL().

◆ make_signed()

std::vector< uint8_t > Botan::X509_Object::make_signed ( class PK_Signer signer,
RandomNumberGenerator rng,
const AlgorithmIdentifier alg_id,
const secure_vector< uint8_t > &  tbs 
)
static

Create a signed X509 object.

Parameters
signerthe signer used to sign the object
rngthe random number generator to use
alg_idthe algorithm identifier of the signature scheme
tbsthe tbs bits to be signed
Returns
signed X509 object

Definition at line 303 of file x509_obj.cpp.

307 {
308 const std::vector<uint8_t> signature = signer->sign_message(tbs_bits, rng);
309
310 std::vector<uint8_t> output;
311 DER_Encoder(output)
312 .start_cons(SEQUENCE)
313 .raw_bytes(tbs_bits)
314 .encode(algo)
315 .encode(signature, BIT_STRING)
316 .end_cons();
317
318 return output;
319 }

References Botan::BIT_STRING, Botan::DER_Encoder::encode(), Botan::DER_Encoder::end_cons(), Botan::DER_Encoder::raw_bytes(), Botan::SEQUENCE, Botan::PK_Signer::sign_message(), signature(), and Botan::DER_Encoder::start_cons().

Referenced by Botan::PKCS10_Request::create(), and Botan::X509_CA::make_cert().

◆ operator=()

X509_Object & Botan::X509_Object::operator= ( const X509_Object )
default

◆ PEM_encode()

std::string Botan::X509_Object::PEM_encode ( ) const
Returns
PEM encoding of this

Definition at line 122 of file x509_obj.cpp.

123 {
125 }
std::vector< uint8_t > BER_encode() const
Definition: asn1_obj.cpp:16
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43

References Botan::ASN1_Object::BER_encode(), Botan::PEM_Code::encode(), and PEM_label().

◆ PEM_label()

virtual std::string Botan::X509_Object::PEM_label ( ) const
pure virtual

◆ signature()

const std::vector< uint8_t > & Botan::X509_Object::signature ( ) const
inline
Returns
signature on tbs_data()

Definition at line 37 of file x509_obj.h.

37{ return m_sig; }

Referenced by encode_into(), make_signed(), Botan::X509_Certificate::operator<(), Botan::X509_Certificate::operator==(), and verify_signature().

◆ signature_algorithm()

const AlgorithmIdentifier & Botan::X509_Object::signature_algorithm ( ) const
inline
Returns
signature algorithm that was used to generate signature

Definition at line 47 of file x509_obj.h.

47{ return m_sig_algo; }

Referenced by encode_into(), hash_used_for_signature(), Botan::X509_Certificate::operator==(), Botan::X509_Certificate::to_string(), verify_signature(), and Botan::X509_CA::X509_CA().

◆ signed_body()

const std::vector< uint8_t > & Botan::X509_Object::signed_body ( ) const
inline
Returns
signed body

Definition at line 42 of file x509_obj.h.

42{ return m_tbs_bits; }

Referenced by encode_into(), Botan::X509_Certificate::operator<(), and Botan::X509_Certificate::operator==().

◆ tbs_data()

std::vector< uint8_t > Botan::X509_Object::tbs_data ( ) const

The underlying data that is to be or was signed

Returns
data that is or was signed

Definition at line 130 of file x509_obj.cpp.

131 {
132 return ASN1::put_in_sequence(m_tbs_bits);
133 }
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:195

References Botan::ASN1::put_in_sequence().

Referenced by verify_signature().

◆ verify_signature()

Certificate_Status_Code Botan::X509_Object::verify_signature ( const Public_Key key) const

Check the signature on this data

Parameters
keythe public key purportedly used to sign this data
Returns
status of the signature - OK if verified or otherwise an indicator of the problem preventing verification.

Definition at line 184 of file x509_obj.cpp.

185 {
186 const std::vector<std::string> sig_info =
187 split_on(m_sig_algo.get_oid().to_formatted_string(), '/');
188
189 if(sig_info.size() < 1 || sig_info.size() > 2 || sig_info[0] != pub_key.algo_name())
191
192 const std::string pub_key_algo = sig_info[0];
193 std::string padding;
194 if(sig_info.size() == 2)
195 padding = sig_info[1];
196 else if(pub_key_algo == "Ed25519" || pub_key_algo == "XMSS")
197 padding = "Pure";
198 else
200
201 const Signature_Format format = pub_key.default_x509_signature_format();
202
203 if(padding == "EMSA4")
204 {
205 // "MUST contain RSASSA-PSS-params"
206 if(signature_algorithm().get_parameters().empty())
207 {
209 }
210
211 Pss_params pss_parameter = decode_pss_params(signature_algorithm().get_parameters());
212
213 // hash_algo must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512
214 const std::string hash_algo = pss_parameter.hash_algo.get_oid().to_formatted_string();
215 if(hash_algo != "SHA-160" &&
216 hash_algo != "SHA-224" &&
217 hash_algo != "SHA-256" &&
218 hash_algo != "SHA-384" &&
219 hash_algo != "SHA-512")
220 {
222 }
223
224 const std::string mgf_algo = pss_parameter.mask_gen_algo.get_oid().to_formatted_string();
225 if(mgf_algo != "MGF1")
226 {
228 }
229
230 // For MGF1, it is strongly RECOMMENDED that the underlying hash function be the same as the one identified by hashAlgorithm
231 // Must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512
232 if(pss_parameter.mask_gen_hash.get_oid() != pss_parameter.hash_algo.get_oid())
233 {
235 }
236
237 if(pss_parameter.trailer_field != 1)
238 {
240 }
241
242 padding += "(" + hash_algo + "," + mgf_algo + "," + std::to_string(pss_parameter.salt_len) + ")";
243 }
244 else
245 {
246 /*
247 * For all other signature types the signature parameters should
248 * be either NULL or empty. In theory there is some distinction between
249 * these but in practice they seem to be used somewhat interchangeably.
250 *
251 * The various RFCs all have prescriptions of what is allowed:
252 * RSA - NULL (RFC 3279)
253 * DSA - empty (RFC 3279)
254 * ECDSA - empty (RFC 3279)
255 * GOST - empty (RFC 4491)
256 * Ed25519 - empty (RFC 8410)
257 * XMSS - empty (draft-vangeest-x509-hash-sigs)
258 *
259 * But in practice we find RSA with empty and ECDSA will NULL all
260 * over the place so it's not really possible to enforce. For Ed25519
261 * and XMSS because they are new we attempt to enforce.
262 */
263 if(pub_key_algo == "Ed25519" || pub_key_algo == "XMSS")
264 {
265 if(!signature_algorithm().parameters_are_empty())
266 {
268 }
269 }
270 else
271 {
272 if(!signature_algorithm().parameters_are_null_or_empty())
273 {
275 }
276 }
277 }
278
279 try
280 {
281 PK_Verifier verifier(pub_key, padding, format);
282 const bool valid = verifier.verify_message(tbs_data(), signature());
283
284 if(valid)
286 else
288 }
289 catch(Algorithm_Not_Found&)
290 {
292 }
293 catch(...)
294 {
295 // This shouldn't happen, fallback to generic signature error
297 }
298 }
std::string to_formatted_string() const
Definition: asn1_oid.cpp:111
std::vector< uint8_t > tbs_data() const
Definition: x509_obj.cpp:130
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:22

References Botan::Public_Key::algo_name(), Botan::Public_Key::default_x509_signature_format(), Botan::AlgorithmIdentifier::get_oid(), hash_algo, signature(), Botan::SIGNATURE_ALGO_BAD_PARAMS, Botan::SIGNATURE_ALGO_UNKNOWN, signature_algorithm(), Botan::SIGNATURE_ERROR, Botan::split_on(), tbs_data(), Botan::OID::to_formatted_string(), Botan::ASN1::to_string(), Botan::UNTRUSTED_HASH, Botan::VERIFIED, and Botan::PK_Verifier::verify_message().

Referenced by check_signature().


The documentation for this class was generated from the following files: