1 /*
2 * X.509 SIGNED Object
3 * (C) 1999-2007,2020 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/x509_obj.h>
9 #include <botan/pubkey.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/parsing.h>
13 #include <botan/pem.h>
14 #include <botan/emsa.h>
15 #include <algorithm>
16 
17 namespace Botan {
18 
19 namespace {
20 struct Pss_params
21    {
22    AlgorithmIdentifier hash_algo;
23    AlgorithmIdentifier mask_gen_algo;
24    AlgorithmIdentifier mask_gen_hash;  // redundant: decoded mask_gen_algo.parameters
25    size_t salt_len;
26    size_t trailer_field;
27    };
28 
decode_pss_params(const std::vector<uint8_t> & encoded_pss_params)29 Pss_params decode_pss_params(const std::vector<uint8_t>& encoded_pss_params)
30    {
31    const AlgorithmIdentifier default_hash("SHA-160", AlgorithmIdentifier::USE_NULL_PARAM);
32    const AlgorithmIdentifier default_mgf("MGF1", default_hash.BER_encode());
33 
34    Pss_params pss_parameter;
35    BER_Decoder(encoded_pss_params)
36       .start_cons(SEQUENCE)
37          .decode_optional(pss_parameter.hash_algo, ASN1_Tag(0), PRIVATE, default_hash)
38          .decode_optional(pss_parameter.mask_gen_algo, ASN1_Tag(1), PRIVATE, default_mgf)
39          .decode_optional(pss_parameter.salt_len, ASN1_Tag(2), PRIVATE, size_t(20))
40          .decode_optional(pss_parameter.trailer_field, ASN1_Tag(3), PRIVATE, size_t(1))
41       .end_cons();
42 
43    BER_Decoder(pss_parameter.mask_gen_algo.get_parameters()).decode(pss_parameter.mask_gen_hash);
44 
45    return pss_parameter;
46    }
47 }
48 
49 /*
50 * Read a PEM or BER X.509 object
51 */
load_data(DataSource & in)52 void X509_Object::load_data(DataSource& in)
53    {
54    try {
55       if(ASN1::maybe_BER(in) && !PEM_Code::matches(in))
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    }
90 
91 
encode_into(DER_Encoder & to) const92 void X509_Object::encode_into(DER_Encoder& to) const
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    }
102 
103 /*
104 * Read a BER encoded X.509 object
105 */
decode_from(BER_Decoder & from)106 void X509_Object::decode_from(BER_Decoder& from)
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    }
118 
119 /*
120 * Return a PEM encoded X.509 object
121 */
PEM_encode() const122 std::string X509_Object::PEM_encode() const
123    {
124    return PEM_Code::encode(BER_encode(), PEM_label());
125    }
126 
127 /*
128 * Return the TBS data
129 */
tbs_data() const130 std::vector<uint8_t> X509_Object::tbs_data() const
131    {
132    return ASN1::put_in_sequence(m_tbs_bits);
133    }
134 
135 /*
136 * Return the hash used in generating the signature
137 */
hash_used_for_signature() const138 std::string X509_Object::hash_used_for_signature() const
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    }
166 
167 /*
168 * Check the signature on an object
169 */
check_signature(const Public_Key * pub_key) const170 bool X509_Object::check_signature(const Public_Key* pub_key) const
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    }
177 
check_signature(const Public_Key & pub_key) const178 bool X509_Object::check_signature(const Public_Key& pub_key) const
179    {
180    const Certificate_Status_Code code = verify_signature(pub_key);
181    return (code == Certificate_Status_Code::VERIFIED);
182    }
183 
verify_signature(const Public_Key & pub_key) const184 Certificate_Status_Code X509_Object::verify_signature(const Public_Key& pub_key) const
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())
190       return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
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
199       return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
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          {
208          return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
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          {
221          return Certificate_Status_Code::UNTRUSTED_HASH;
222          }
223 
224       const std::string mgf_algo = pss_parameter.mask_gen_algo.get_oid().to_formatted_string();
225       if(mgf_algo != "MGF1")
226          {
227          return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
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          {
234          return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
235          }
236 
237       if(pss_parameter.trailer_field != 1)
238          {
239          return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
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             {
267             return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
268             }
269          }
270       else
271          {
272          if(!signature_algorithm().parameters_are_null_or_empty())
273             {
274             return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
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)
285          return Certificate_Status_Code::VERIFIED;
286       else
287          return Certificate_Status_Code::SIGNATURE_ERROR;
288       }
289    catch(Algorithm_Not_Found&)
290       {
291       return Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN;
292       }
293    catch(...)
294       {
295       // This shouldn't happen, fallback to generic signature error
296       return Certificate_Status_Code::SIGNATURE_ERROR;
297       }
298    }
299 
300 /*
301 * Apply the X.509 SIGNED macro
302 */
make_signed(PK_Signer * signer,RandomNumberGenerator & rng,const AlgorithmIdentifier & algo,const secure_vector<uint8_t> & tbs_bits)303 std::vector<uint8_t> X509_Object::make_signed(PK_Signer* signer,
304                                             RandomNumberGenerator& rng,
305                                             const AlgorithmIdentifier& algo,
306                                             const secure_vector<uint8_t>& tbs_bits)
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    }
320 
321 namespace {
322 
choose_sig_algo(AlgorithmIdentifier & sig_algo,const Private_Key & key,const std::string & hash_fn,const std::string & user_specified)323 std::string choose_sig_algo(AlgorithmIdentifier& sig_algo,
324                             const Private_Key& key,
325                             const std::string& hash_fn,
326                             const std::string& user_specified)
327    {
328    const std::string algo_name = key.algo_name();
329    std::string padding;
330 
331    // check algo_name and set default
332    if(algo_name == "RSA")
333       {
334       // set to EMSA3 for compatibility reasons, originally it was the only option
335       padding = "EMSA3(" + hash_fn + ")";
336       }
337    else if(algo_name == "DSA" ||
338            algo_name == "ECDSA" ||
339            algo_name == "ECGDSA" ||
340            algo_name == "ECKCDSA" ||
341            algo_name == "GOST-34.10" ||
342            algo_name == "GOST-34.10-2012-256" ||
343            algo_name == "GOST-34.10-2012-512")
344       {
345       padding = "EMSA1(" + hash_fn + ")";
346       }
347    else if(algo_name == "Ed25519")
348       {
349       padding = "Pure";
350       }
351    else if(algo_name == "XMSS")
352       {
353       if(user_specified.empty() == true)
354          {
355          throw Invalid_Argument("XMSS requires padding scheme");
356          }
357       padding = user_specified;
358       sig_algo = AlgorithmIdentifier(OID::from_string("XMSS"), AlgorithmIdentifier::USE_EMPTY_PARAM);
359       return padding;
360       }
361    else
362       {
363       throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name);
364       }
365 
366    if(user_specified.empty() == false)
367       {
368       padding = user_specified;
369       }
370 
371    if(padding != "Pure")
372       {
373       // try to construct an EMSA object from the padding options or default
374       std::unique_ptr<EMSA> emsa;
375       try
376          {
377          emsa.reset(get_emsa(padding));
378          }
379       /*
380       * get_emsa will throw if opts contains {"padding",<valid_padding>} but
381       * <valid_padding> does not specify a hash function.
382       * Omitting it is valid since it needs to be identical to hash_fn.
383       * If it still throws, something happened that we cannot repair here,
384       * e.g. the algorithm/padding combination is not supported.
385       */
386       catch(...)
387          {
388          emsa.reset(get_emsa(padding + "(" + hash_fn + ")"));
389          }
390 
391       if(!emsa)
392          {
393          throw Invalid_Argument("Could not parse padding scheme " + padding);
394          }
395 
396       sig_algo = emsa->config_for_x509(key, hash_fn);
397       return emsa->name();
398       }
399    else
400       {
401       sig_algo = AlgorithmIdentifier(OID::from_string("Ed25519"), AlgorithmIdentifier::USE_EMPTY_PARAM);
402       return "Pure";
403       }
404    }
405 
406 }
407 
408 /*
409 * Choose a signing format for the key
410 */
choose_sig_format(AlgorithmIdentifier & sig_algo,const Private_Key & key,RandomNumberGenerator & rng,const std::string & hash_fn,const std::string & padding_algo)411 std::unique_ptr<PK_Signer> X509_Object::choose_sig_format(AlgorithmIdentifier& sig_algo,
412                                                           const Private_Key& key,
413                                                           RandomNumberGenerator& rng,
414                                                           const std::string& hash_fn,
415                                                           const std::string& padding_algo)
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    }
423 
424 }
425