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