Botan  2.7.0
Crypto and TLS for C++11
emsa_pkcs1.cpp
Go to the documentation of this file.
1 /*
2 * PKCS #1 v1.5 signature padding
3 * (C) 1999-2008 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/emsa_pkcs1.h>
9 #include <botan/hash_id.h>
10 #include <botan/exceptn.h>
11 #include <botan/oids.h>
12 #include <botan/pk_keys.h>
13 #include <botan/internal/padding.h>
14 
15 namespace Botan {
16 
17 namespace {
18 
19 secure_vector<uint8_t> emsa3_encoding(const secure_vector<uint8_t>& msg,
20  size_t output_bits,
21  const uint8_t hash_id[],
22  size_t hash_id_length)
23  {
24  size_t output_length = output_bits / 8;
25  if(output_length < hash_id_length + msg.size() + 10)
26  throw Encoding_Error("emsa3_encoding: Output length is too small");
27 
28  secure_vector<uint8_t> T(output_length);
29  const size_t P_LENGTH = output_length - msg.size() - hash_id_length - 2;
30 
31  T[0] = 0x01;
32  set_mem(&T[1], P_LENGTH, 0xFF);
33  T[P_LENGTH+1] = 0x00;
34 
35  if(hash_id_length > 0)
36  {
37  BOTAN_ASSERT_NONNULL(hash_id);
38  buffer_insert(T, P_LENGTH+2, hash_id, hash_id_length);
39  }
40 
41  buffer_insert(T, output_length-msg.size(), msg.data(), msg.size());
42  return T;
43  }
44 
45 }
46 
47 void EMSA_PKCS1v15::update(const uint8_t input[], size_t length)
48  {
49  m_hash->update(input, length);
50  }
51 
53  {
54  return m_hash->final();
55  }
56 
59  size_t output_bits,
61  {
62  if(msg.size() != m_hash->output_length())
63  throw Encoding_Error("EMSA_PKCS1v15::encoding_of: Bad input length");
64 
65  return emsa3_encoding(msg, output_bits,
66  m_hash_id.data(), m_hash_id.size());
67  }
68 
70  const secure_vector<uint8_t>& raw,
71  size_t key_bits)
72  {
73  if(raw.size() != m_hash->output_length())
74  return false;
75 
76  try
77  {
78  return (coded == emsa3_encoding(raw, key_bits,
79  m_hash_id.data(), m_hash_id.size()));
80  }
81  catch(...)
82  {
83  return false;
84  }
85  }
86 
88  const std::string& cert_hash_name) const
89  {
90  if(cert_hash_name != m_hash->name())
91  throw Invalid_Argument("Hash function from opts and hash_fn argument"
92  " need to be identical");
93  // check that the signature algorithm and the padding scheme fit
94  if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA3"))
95  {
96  throw Invalid_Argument("Encoding scheme with canonical name EMSA3"
97  " not supported for signature algorithm " + key.algo_name());
98  }
99 
100 
101  AlgorithmIdentifier sig_algo;
102  sig_algo.oid = OIDS::lookup( key.algo_name() + "/" + name() );
103  // for RSA PKCSv1.5 parameters "SHALL" be NULL as configured by
104  // RSA_PublicKey::algorithm_identifier()
105  sig_algo.parameters = key.algorithm_identifier().parameters;
106  return sig_algo;
107  }
108 
110  {
111  m_hash_id = pkcs_hash_id(m_hash->name());
112  }
113 
115  {
116  if(!hash_algo.empty())
117  {
118  m_hash_id = pkcs_hash_id(hash_algo);
119  std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_algo));
120  m_hash_name = hash->name();
121  m_hash_output_len = hash->output_length();
122  }
123  else
124  {
125  m_hash_output_len = 0;
126  }
127  }
128 
129 void EMSA_PKCS1v15_Raw::update(const uint8_t input[], size_t length)
130  {
131  m_message += std::make_pair(input, length);
132  }
133 
135  {
137  std::swap(ret, m_message);
138 
139  if(m_hash_output_len > 0 && ret.size() != m_hash_output_len)
140  throw Encoding_Error("EMSA_PKCS1v15_Raw::encoding_of: Bad input length");
141 
142  return ret;
143  }
144 
147  size_t output_bits,
149  {
150  return emsa3_encoding(msg, output_bits, m_hash_id.data(), m_hash_id.size());
151  }
152 
154  const secure_vector<uint8_t>& raw,
155  size_t key_bits)
156  {
157  if(m_hash_output_len > 0 && raw.size() != m_hash_output_len)
158  return false;
159 
160  try
161  {
162  return (coded == emsa3_encoding(raw, key_bits, m_hash_id.data(), m_hash_id.size()));
163  }
164  catch(...)
165  {
166  return false;
167  }
168  }
169 
170 }
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:345
std::vector< uint8_t > parameters
Definition: alg_id.h:46
virtual AlgorithmIdentifier algorithm_identifier() const =0
bool verify(const secure_vector< uint8_t > &, const secure_vector< uint8_t > &, size_t) override
Definition: emsa_pkcs1.cpp:69
void update(const uint8_t[], size_t) override
Definition: emsa_pkcs1.cpp:47
virtual std::string algo_name() const =0
bool verify(const secure_vector< uint8_t > &, const secure_vector< uint8_t > &, size_t) override
Definition: emsa_pkcs1.cpp:153
EMSA_PKCS1v15(HashFunction *hash)
Definition: emsa_pkcs1.cpp:109
bool sig_algo_and_pad_ok(const std::string algo, const std::string padding)
Definition: padding.cpp:37
void set_mem(T *ptr, size_t n, uint8_t val)
Definition: mem_ops.h:123
void update(const uint8_t[], size_t) override
Definition: emsa_pkcs1.cpp:129
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:95
EMSA_PKCS1v15_Raw(const std::string &hash_algo="")
Definition: emsa_pkcs1.cpp:114
secure_vector< uint8_t > raw_data() override
Definition: emsa_pkcs1.cpp:52
secure_vector< uint8_t > raw_data() override
Definition: emsa_pkcs1.cpp:134
Definition: alg_id.cpp:13
AlgorithmIdentifier config_for_x509(const Private_Key &key, const std::string &cert_hash_name) const override
Definition: emsa_pkcs1.cpp:87
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:23
secure_vector< uint8_t > encoding_of(const secure_vector< uint8_t > &, size_t, RandomNumberGenerator &rng) override
Definition: emsa_pkcs1.cpp:146
std::string name() const override
Definition: emsa_pkcs1.h:41
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:103
fe T
Definition: ge.cpp:37
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
std::string lookup(const OID &oid)
Definition: oids.cpp:113
MechanismType hash
secure_vector< uint8_t > encoding_of(const secure_vector< uint8_t > &, size_t, RandomNumberGenerator &rng) override
Definition: emsa_pkcs1.cpp:58
std::vector< uint8_t > pkcs_hash_id(const std::string &name)
Definition: hash_id.cpp:77