/src/botan/src/lib/pk_pad/emsa.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * (C) 2015 Jack Lloyd |
3 | | * |
4 | | * Botan is released under the Simplified BSD License (see license.txt) |
5 | | */ |
6 | | |
7 | | #include <botan/internal/emsa.h> |
8 | | #include <botan/hash.h> |
9 | | #include <botan/internal/scan_name.h> |
10 | | #include <botan/exceptn.h> |
11 | | |
12 | | #if defined(BOTAN_HAS_EMSA1) |
13 | | #include <botan/internal/emsa1.h> |
14 | | #endif |
15 | | |
16 | | #if defined(BOTAN_HAS_EMSA_X931) |
17 | | #include <botan/internal/emsa_x931.h> |
18 | | #endif |
19 | | |
20 | | #if defined(BOTAN_HAS_EMSA_PKCS1) |
21 | | #include <botan/internal/emsa_pkcs1.h> |
22 | | #endif |
23 | | |
24 | | #if defined(BOTAN_HAS_EMSA_PSSR) |
25 | | #include <botan/internal/pssr.h> |
26 | | #endif |
27 | | |
28 | | #if defined(BOTAN_HAS_EMSA_RAW) |
29 | | #include <botan/internal/emsa_raw.h> |
30 | | #endif |
31 | | |
32 | | #if defined(BOTAN_HAS_ISO_9796) |
33 | | #include <botan/internal/iso9796.h> |
34 | | #endif |
35 | | |
36 | | namespace Botan { |
37 | | |
38 | | AlgorithmIdentifier EMSA::config_for_x509(const Private_Key& /*unused*/, |
39 | | const std::string& /*unused*/) const |
40 | 0 | { |
41 | 0 | throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects"); |
42 | 0 | } |
43 | | |
44 | | std::unique_ptr<EMSA> EMSA::create(const std::string& algo_spec) |
45 | 6.79k | { |
46 | 6.79k | SCAN_Name req(algo_spec); |
47 | | |
48 | 6.79k | #if defined(BOTAN_HAS_EMSA1) |
49 | 6.79k | if(req.algo_name() == "EMSA1" && req.arg_count() == 1) |
50 | 556 | { |
51 | 556 | if(auto hash = HashFunction::create(req.arg(0))) |
52 | 556 | return std::make_unique<EMSA1>(std::move(hash)); |
53 | 556 | } |
54 | 6.23k | #endif |
55 | | |
56 | 6.23k | #if defined(BOTAN_HAS_EMSA_PKCS1) |
57 | 6.23k | if(req.algo_name() == "EMSA_PKCS1" || |
58 | 6.23k | req.algo_name() == "PKCS1v15" || |
59 | 6.23k | req.algo_name() == "EMSA-PKCS1-v1_5" || |
60 | 6.23k | req.algo_name() == "EMSA3") |
61 | 6.18k | { |
62 | 6.18k | if(req.arg_count() == 2 && req.arg(0) == "Raw") |
63 | 0 | { |
64 | 0 | return std::make_unique<EMSA_PKCS1v15_Raw>(req.arg(1)); |
65 | 0 | } |
66 | 6.18k | else if(req.arg_count() == 1) |
67 | 6.18k | { |
68 | 6.18k | if(req.arg(0) == "Raw") |
69 | 0 | { |
70 | 0 | return std::make_unique<EMSA_PKCS1v15_Raw>(); |
71 | 0 | } |
72 | 6.18k | else |
73 | 6.18k | { |
74 | 6.18k | if(auto hash = HashFunction::create(req.arg(0))) |
75 | 6.18k | { |
76 | 6.18k | return std::make_unique<EMSA_PKCS1v15>(std::move(hash)); |
77 | 6.18k | } |
78 | 6.18k | } |
79 | 6.18k | } |
80 | 6.18k | } |
81 | 57 | #endif |
82 | | |
83 | 57 | #if defined(BOTAN_HAS_EMSA_PSSR) |
84 | 57 | if(req.algo_name() == "PSS_Raw" || |
85 | 57 | req.algo_name() == "PSSR_Raw") |
86 | 0 | { |
87 | 0 | if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") |
88 | 0 | { |
89 | 0 | if(auto hash = HashFunction::create(req.arg(0))) |
90 | 0 | { |
91 | 0 | if(req.arg_count() == 3) |
92 | 0 | { |
93 | 0 | const size_t salt_size = req.arg_as_integer(2, 0); |
94 | 0 | return std::make_unique<PSSR_Raw>(std::move(hash), salt_size); |
95 | 0 | } |
96 | 0 | else |
97 | 0 | { |
98 | 0 | return std::make_unique<PSSR_Raw>(std::move(hash)); |
99 | 0 | } |
100 | 0 | } |
101 | 0 | } |
102 | 0 | } |
103 | | |
104 | 57 | if(req.algo_name() == "PSS" || |
105 | 57 | req.algo_name() == "PSSR" || |
106 | 57 | req.algo_name() == "EMSA-PSS" || |
107 | 57 | req.algo_name() == "PSS-MGF1" || |
108 | 57 | req.algo_name() == "EMSA4") |
109 | 56 | { |
110 | 56 | if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") |
111 | 56 | { |
112 | 56 | if(auto hash = HashFunction::create(req.arg(0))) |
113 | 56 | { |
114 | 56 | if(req.arg_count() == 3) |
115 | 56 | { |
116 | 56 | const size_t salt_size = req.arg_as_integer(2, 0); |
117 | 56 | return std::make_unique<PSSR>(std::move(hash), salt_size); |
118 | 56 | } |
119 | 0 | else |
120 | 0 | { |
121 | 0 | return std::make_unique<PSSR>(std::move(hash)); |
122 | 0 | } |
123 | 56 | } |
124 | 56 | } |
125 | 56 | } |
126 | 1 | #endif |
127 | | |
128 | 1 | #if defined(BOTAN_HAS_ISO_9796) |
129 | 1 | if(req.algo_name() == "ISO_9796_DS2") |
130 | 0 | { |
131 | 0 | if(req.arg_count_between(1, 3)) |
132 | 0 | { |
133 | 0 | if(auto hash = HashFunction::create(req.arg(0))) |
134 | 0 | { |
135 | 0 | const size_t salt_size = req.arg_as_integer(2, hash->output_length()); |
136 | 0 | const bool implicit = req.arg(1, "exp") == "imp"; |
137 | 0 | return std::make_unique<ISO_9796_DS2>(std::move(hash), implicit, salt_size); |
138 | 0 | } |
139 | 0 | } |
140 | 0 | } |
141 | | //ISO-9796-2 DS 3 is deterministic and DS2 without a salt |
142 | 1 | if(req.algo_name() == "ISO_9796_DS3") |
143 | 0 | { |
144 | 0 | if(req.arg_count_between(1, 2)) |
145 | 0 | { |
146 | 0 | if(auto hash = HashFunction::create(req.arg(0))) |
147 | 0 | { |
148 | 0 | const bool implicit = req.arg(1, "exp") == "imp"; |
149 | 0 | return std::make_unique<ISO_9796_DS3>(std::move(hash), implicit); |
150 | 0 | } |
151 | 0 | } |
152 | 0 | } |
153 | 1 | #endif |
154 | | |
155 | 1 | #if defined(BOTAN_HAS_EMSA_X931) |
156 | 1 | if(req.algo_name() == "EMSA_X931" || |
157 | 1 | req.algo_name() == "EMSA2" || |
158 | 1 | req.algo_name() == "X9.31") |
159 | 0 | { |
160 | 0 | if(req.arg_count() == 1) |
161 | 0 | { |
162 | 0 | if(auto hash = HashFunction::create(req.arg(0))) |
163 | 0 | { |
164 | 0 | return std::make_unique<EMSA_X931>(std::move(hash)); |
165 | 0 | } |
166 | 0 | } |
167 | 0 | } |
168 | 1 | #endif |
169 | | |
170 | 1 | #if defined(BOTAN_HAS_EMSA_RAW) |
171 | 1 | if(req.algo_name() == "Raw") |
172 | 0 | { |
173 | 0 | if(req.arg_count() == 0) |
174 | 0 | { |
175 | 0 | return std::make_unique<EMSA_Raw>(); |
176 | 0 | } |
177 | 0 | else |
178 | 0 | { |
179 | 0 | auto hash = HashFunction::create(req.arg(0)); |
180 | 0 | if(hash) |
181 | 0 | return std::make_unique<EMSA_Raw>(hash->output_length()); |
182 | 0 | } |
183 | 0 | } |
184 | 1 | #endif |
185 | | |
186 | 1 | return nullptr; |
187 | 1 | } |
188 | | |
189 | | std::unique_ptr<EMSA> EMSA::create_or_throw(const std::string& algo_spec) |
190 | 6.79k | { |
191 | 6.79k | auto emsa = EMSA::create(algo_spec); |
192 | 6.79k | if(emsa) |
193 | 6.79k | return emsa; |
194 | 1 | throw Algorithm_Not_Found(algo_spec); |
195 | 6.79k | } |
196 | | |
197 | | std::string hash_for_emsa(const std::string& algo_spec) |
198 | 6.79k | { |
199 | 6.79k | SCAN_Name emsa_name(algo_spec); |
200 | | |
201 | 6.79k | if(emsa_name.arg_count() > 0) |
202 | 6.79k | { |
203 | 6.79k | return emsa_name.arg(0); |
204 | 6.79k | } |
205 | | |
206 | | // If we don't understand what this is return a safe default |
207 | 0 | #if defined(BOTAN_HAS_SHA2_64) |
208 | 0 | return "SHA-512"; |
209 | | #else |
210 | | return "SHA-256"; |
211 | | #endif |
212 | 6.79k | } |
213 | | |
214 | | } |