/src/xmlsec/src/openssl/digests.c
Line | Count | Source |
1 | | /** |
2 | | * XML Security Library (http://www.aleksey.com/xmlsec). |
3 | | * |
4 | | * This is free software; see the Copyright file in the source distribution for precise wording. |
5 | | * |
6 | | * Copyright (C) 2002-2026 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. |
7 | | */ |
8 | | /** |
9 | | * @addtogroup xmlsec_openssl_crypto |
10 | | * @brief Digests transforms implementation for OpenSSL. |
11 | | */ |
12 | | #include "globals.h" |
13 | | |
14 | | #include <string.h> |
15 | | |
16 | | #include <openssl/evp.h> |
17 | | |
18 | | #include <xmlsec/xmlsec.h> |
19 | | #include <xmlsec/buffer.h> |
20 | | #include <xmlsec/keys.h> |
21 | | #include <xmlsec/transforms.h> |
22 | | #include <xmlsec/errors.h> |
23 | | |
24 | | #include <xmlsec/openssl/crypto.h> |
25 | | #include <xmlsec/openssl/evp.h> |
26 | | #include "openssl_compat.h" |
27 | | |
28 | | #ifdef XMLSEC_OPENSSL_API_300 |
29 | | #include <openssl/core_names.h> |
30 | | #endif /* XMLSEC_OPENSSL_API_300 */ |
31 | | |
32 | | #include "../cast_helpers.h" |
33 | | |
34 | | /****************************************************************************** |
35 | | * |
36 | | * Internal OpenSSL EVP Digest CTX |
37 | | * |
38 | | *****************************************************************************/ |
39 | | typedef struct _xmlSecOpenSSLEvpDigestCtx xmlSecOpenSSLEvpDigestCtx, *xmlSecOpenSSLEvpDigestCtxPtr; |
40 | | struct _xmlSecOpenSSLEvpDigestCtx { |
41 | | EVP_MD* digest; |
42 | | int digestNeedsToBeFreed; |
43 | | EVP_MD_CTX* digestCtx; |
44 | | xmlSecByte dgst[EVP_MAX_MD_SIZE]; |
45 | | xmlSecSize dgstSize; /* dgst size in bytes */ |
46 | | }; |
47 | | |
48 | | /****************************************************************************** |
49 | | * |
50 | | * EVP Digest transforms |
51 | | * |
52 | | *****************************************************************************/ |
53 | 585k | XMLSEC_TRANSFORM_DECLARE(OpenSSLEvpDigest, xmlSecOpenSSLEvpDigestCtx) |
54 | 585k | #define xmlSecOpenSSLEvpDigestSize XMLSEC_TRANSFORM_SIZE(OpenSSLEvpDigest) |
55 | 585k | |
56 | 585k | static int xmlSecOpenSSLEvpDigestInitialize (xmlSecTransformPtr transform); |
57 | 585k | static void xmlSecOpenSSLEvpDigestFinalize (xmlSecTransformPtr transform); |
58 | 585k | static int xmlSecOpenSSLEvpDigestVerify (xmlSecTransformPtr transform, |
59 | 585k | const xmlSecByte* data, |
60 | 585k | xmlSecSize dataSize, |
61 | 585k | xmlSecTransformCtxPtr transformCtx); |
62 | 585k | static int xmlSecOpenSSLEvpDigestExecute (xmlSecTransformPtr transform, |
63 | 585k | int last, |
64 | 585k | xmlSecTransformCtxPtr transformCtx); |
65 | 585k | static int xmlSecOpenSSLEvpDigestCheckId (xmlSecTransformPtr transform); |
66 | 585k | |
67 | 585k | static int |
68 | 585k | xmlSecOpenSSLEvpDigestCheckId(xmlSecTransformPtr transform) { |
69 | | |
70 | 195k | #ifndef XMLSEC_NO_MD5 |
71 | 195k | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformMd5Id)) { |
72 | 0 | return(1); |
73 | 0 | } else |
74 | 195k | #endif /* XMLSEC_NO_MD5 */ |
75 | | |
76 | 195k | #ifndef XMLSEC_NO_RIPEMD160 |
77 | 195k | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRipemd160Id)) { |
78 | 0 | return(1); |
79 | 0 | } else |
80 | 195k | #endif /* XMLSEC_NO_RIPEMD160 */ |
81 | | |
82 | 195k | #ifndef XMLSEC_NO_SHA1 |
83 | 195k | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha1Id)) { |
84 | 195k | return(1); |
85 | 195k | } else |
86 | 50 | #endif /* XMLSEC_NO_SHA1 */ |
87 | | |
88 | 50 | #ifndef XMLSEC_NO_SHA224 |
89 | 50 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha224Id)) { |
90 | 7 | return(1); |
91 | 7 | } else |
92 | 43 | #endif /* XMLSEC_NO_SHA224 */ |
93 | | |
94 | 43 | #ifndef XMLSEC_NO_SHA256 |
95 | 43 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha256Id)) { |
96 | 26 | return(1); |
97 | 26 | } else |
98 | 17 | #endif /* XMLSEC_NO_SHA256 */ |
99 | | |
100 | 17 | #ifndef XMLSEC_NO_SHA384 |
101 | 17 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha384Id)) { |
102 | 0 | return(1); |
103 | 0 | } else |
104 | 17 | #endif /* XMLSEC_NO_SHA384 */ |
105 | | |
106 | 17 | #ifndef XMLSEC_NO_SHA512 |
107 | 17 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha512Id)) { |
108 | 15 | return(1); |
109 | 15 | } else |
110 | 2 | #endif /* XMLSEC_NO_SHA512 */ |
111 | | |
112 | 2 | #ifndef XMLSEC_NO_SHA3 |
113 | 2 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_224Id)) { |
114 | 2 | return(1); |
115 | 2 | } else |
116 | 0 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_256Id)) { |
117 | 0 | return(1); |
118 | 0 | } else |
119 | 0 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_384Id)) { |
120 | 0 | return(1); |
121 | 0 | } else |
122 | 0 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_512Id)) { |
123 | 0 | return(1); |
124 | 0 | } else |
125 | 0 | #endif /* XMLSEC_NO_SHA3 */ |
126 | | |
127 | | #ifndef XMLSEC_NO_GOST |
128 | | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformGostR3411_94Id)) { |
129 | | return(1); |
130 | | } else |
131 | | #endif /* XMLSEC_NO_GOST */ |
132 | | |
133 | | #ifndef XMLSEC_NO_GOST2012 |
134 | | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformGostR3411_2012_256Id)) { |
135 | | return(1); |
136 | | } else |
137 | | |
138 | | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformGostR3411_2012_512Id)) { |
139 | | return(1); |
140 | | } else |
141 | | #endif /* XMLSEC_NO_GOST2012 */ |
142 | | |
143 | 0 | { |
144 | 0 | return(0); |
145 | 0 | } |
146 | 195k | } |
147 | | |
148 | | /* small helper macro to reduce clutter in the code */ |
149 | | #ifndef XMLSEC_OPENSSL_API_300 |
150 | | #define XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, digestVal, digestName) \ |
151 | | (ctx)->digest = (EVP_MD*)(digestVal) |
152 | | |
153 | | #else /* XMLSEC_OPENSSL_API_300 */ |
154 | | |
155 | | static int |
156 | 9.98k | xmlSecOpenSSLEvpDigestSetDigestByName(xmlSecOpenSSLEvpDigestCtxPtr ctx, const char * digestName) { |
157 | 9.98k | xmlSecAssert2(ctx != NULL, -1); |
158 | 9.98k | xmlSecAssert2(ctx->digest == NULL, -1); |
159 | 9.98k | xmlSecAssert2(digestName != NULL, -1); |
160 | | |
161 | 9.98k | ctx->digest = EVP_MD_fetch(xmlSecOpenSSLGetLibCtx(), digestName, NULL); |
162 | 9.98k | if(ctx->digest == NULL) { |
163 | 0 | xmlSecOpenSSLError2("EVP_MD_fetch", NULL, "digestName=%s", xmlSecErrorsSafeString(digestName)); |
164 | 0 | return(-1); |
165 | 0 | } |
166 | 9.98k | ctx->digestNeedsToBeFreed = 1; |
167 | 9.98k | return(0); |
168 | 9.98k | } |
169 | | |
170 | | #define XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, digestVal, digestName) \ |
171 | 9.98k | if (xmlSecOpenSSLEvpDigestSetDigestByName((ctx), (digestName)) < 0) { \ |
172 | 0 | xmlSecInternalError2("xmlSecOpenSSLEvpDigestSetDigestByName", \ |
173 | 0 | xmlSecTransformGetName(transform), \ |
174 | 0 | "digestName=%s", xmlSecErrorsSafeString(digestName)); \ |
175 | 0 | xmlSecOpenSSLEvpDigestFinalize(transform); \ |
176 | 0 | return(-1); \ |
177 | 0 | } |
178 | | |
179 | | |
180 | | #endif /* XMLSEC_OPENSSL_API_300 */ |
181 | | |
182 | | #if !defined(XMLSEC_NO_GOST) || !defined(XMLSEC_NO_GOST2012) |
183 | | |
184 | | /* Not all algorithms have been converted to the new provider design (e.g. GOST) */ |
185 | | /* TODO: EVP_get_digestbyname() is deprecated in OpenSSL 3.0. Replace with EVP_MD_fetch() |
186 | | * once GOST algorithms become available as OpenSSL providers. */ |
187 | | static int |
188 | | xmlSecOpenSSLEvpDigestSetGostDigestByName(xmlSecOpenSSLEvpDigestCtxPtr ctx, const char * digestName) { |
189 | | xmlSecAssert2(ctx != NULL, -1); |
190 | | xmlSecAssert2(ctx->digest == NULL, -1); |
191 | | xmlSecAssert2(digestName != NULL, -1); |
192 | | |
193 | | ctx->digest = (EVP_MD*)EVP_get_digestbyname(digestName); |
194 | | if(ctx->digest == NULL) { |
195 | | xmlSecOpenSSLError2("EVP_get_digestbyname", NULL, "digestName=%s", xmlSecErrorsSafeString(digestName)); |
196 | | return(-1); |
197 | | } |
198 | | return(0); |
199 | | } |
200 | | |
201 | | #define XMLSEC_OPENSSL_EVP_DIGEST_SETUP_GOST(transform, ctx, digestName) \ |
202 | | if (xmlSecOpenSSLEvpDigestSetGostDigestByName((ctx), (digestName)) < 0) { \ |
203 | | xmlSecInternalError2("xmlSecOpenSSLEvpDigestSetGostDigestByName", \ |
204 | | xmlSecTransformGetName(transform), \ |
205 | | "digestName=%s", xmlSecErrorsSafeString(digestName)); \ |
206 | | xmlSecOpenSSLEvpDigestFinalize(transform); \ |
207 | | return(-1); \ |
208 | | } |
209 | | #endif /* !defined(XMLSEC_NO_GOST) || !defined(XMLSEC_NO_GOST2012) */ |
210 | | |
211 | | |
212 | | static int |
213 | 9.98k | xmlSecOpenSSLEvpDigestInitialize(xmlSecTransformPtr transform) { |
214 | 9.98k | xmlSecOpenSSLEvpDigestCtxPtr ctx; |
215 | | |
216 | 9.98k | xmlSecAssert2(xmlSecOpenSSLEvpDigestCheckId(transform), -1); |
217 | 9.98k | xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpDigestSize), -1); |
218 | | |
219 | 9.98k | ctx = xmlSecOpenSSLEvpDigestGetCtx(transform); |
220 | 9.98k | xmlSecAssert2(ctx != NULL, -1); |
221 | | |
222 | | /* initialize context */ |
223 | 9.98k | memset(ctx, 0, sizeof(xmlSecOpenSSLEvpDigestCtx)); |
224 | | |
225 | 9.98k | #ifndef XMLSEC_NO_MD5 |
226 | 9.98k | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformMd5Id)) { |
227 | 0 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_md5(), OSSL_DIGEST_NAME_MD5); |
228 | 0 | } else |
229 | 9.98k | #endif /* XMLSEC_NO_MD5 */ |
230 | | |
231 | 9.98k | #ifndef XMLSEC_NO_RIPEMD160 |
232 | 9.98k | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRipemd160Id)) { |
233 | 0 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_ripemd160(), OSSL_DIGEST_NAME_RIPEMD160); |
234 | 0 | } else |
235 | 9.98k | #endif /* XMLSEC_NO_RIPEMD160 */ |
236 | | |
237 | 9.98k | #ifndef XMLSEC_NO_SHA1 |
238 | 9.98k | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha1Id)) { |
239 | 9.96k | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha1(), OSSL_DIGEST_NAME_SHA1); |
240 | 9.96k | } else |
241 | 16 | #endif /* XMLSEC_NO_SHA1 */ |
242 | | |
243 | 16 | #ifndef XMLSEC_NO_SHA224 |
244 | 16 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha224Id)) { |
245 | 2 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha224(), OSSL_DIGEST_NAME_SHA2_224); |
246 | 2 | } else |
247 | 14 | #endif /* XMLSEC_NO_SHA224 */ |
248 | | |
249 | 14 | #ifndef XMLSEC_NO_SHA256 |
250 | 14 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha256Id)) { |
251 | 10 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha256(), OSSL_DIGEST_NAME_SHA2_256); |
252 | 10 | } else |
253 | 4 | #endif /* XMLSEC_NO_SHA256 */ |
254 | | |
255 | 4 | #ifndef XMLSEC_NO_SHA384 |
256 | 4 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha384Id)) { |
257 | 0 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha384(), OSSL_DIGEST_NAME_SHA2_384); |
258 | 0 | } else |
259 | 4 | #endif /* XMLSEC_NO_SHA384 */ |
260 | | |
261 | 4 | #ifndef XMLSEC_NO_SHA512 |
262 | 4 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha512Id)) { |
263 | 3 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha512(), OSSL_DIGEST_NAME_SHA2_512); |
264 | 3 | } else |
265 | 1 | #endif /* XMLSEC_NO_SHA512 */ |
266 | | |
267 | 1 | #ifndef XMLSEC_NO_SHA3 |
268 | 1 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_224Id)) { |
269 | 1 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha3_224(), OSSL_DIGEST_NAME_SHA3_224); |
270 | 1 | } else |
271 | 0 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_256Id)) { |
272 | 0 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha3_256(), OSSL_DIGEST_NAME_SHA3_256); |
273 | 0 | } else |
274 | 0 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_384Id)) { |
275 | 0 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha3_384(), OSSL_DIGEST_NAME_SHA3_384); |
276 | 0 | } else |
277 | 0 | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformSha3_512Id)) { |
278 | 0 | XMLSEC_OPENSSL_EVP_DIGEST_SETUP(transform, ctx, EVP_sha3_512(), OSSL_DIGEST_NAME_SHA3_512); |
279 | 0 | } else |
280 | 0 | #endif /* XMLSEC_NO_SHA3 */ |
281 | | |
282 | | #ifndef XMLSEC_NO_GOST |
283 | | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformGostR3411_94Id)) { |
284 | | XMLSEC_OPENSSL_EVP_DIGEST_SETUP_GOST(transform, ctx, XMLSEC_OPENSSL_DIGEST_NAME_GOST94); |
285 | | } else |
286 | | #endif /* XMLSEC_NO_GOST */ |
287 | | |
288 | | #ifndef XMLSEC_NO_GOST2012 |
289 | | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformGostR3411_2012_256Id)) { |
290 | | XMLSEC_OPENSSL_EVP_DIGEST_SETUP_GOST(transform, ctx, XMLSEC_OPENSSL_DIGEST_NAME_GOST12_256); |
291 | | } else |
292 | | |
293 | | if(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformGostR3411_2012_512Id)) { |
294 | | XMLSEC_OPENSSL_EVP_DIGEST_SETUP_GOST(transform, ctx, XMLSEC_OPENSSL_DIGEST_NAME_GOST12_512); |
295 | | } else |
296 | | #endif /* XMLSEC_NO_GOST2012 */ |
297 | 0 | { |
298 | 0 | xmlSecInvalidTransformError(transform); |
299 | 0 | xmlSecOpenSSLEvpDigestFinalize(transform); |
300 | 0 | return(-1); |
301 | 0 | } |
302 | 9.98k | xmlSecAssert2(ctx->digest != NULL, -1); |
303 | | |
304 | | /* create digest CTX */ |
305 | 9.98k | ctx->digestCtx = EVP_MD_CTX_new(); |
306 | 9.98k | if(ctx->digestCtx == NULL) { |
307 | 0 | xmlSecOpenSSLError("EVP_MD_CTX_new", xmlSecTransformGetName(transform)); |
308 | 0 | xmlSecOpenSSLEvpDigestFinalize(transform); |
309 | 0 | return(-1); |
310 | 0 | } |
311 | | |
312 | | /* done */ |
313 | 9.98k | return(0); |
314 | 9.98k | } |
315 | | |
316 | | static void |
317 | 9.98k | xmlSecOpenSSLEvpDigestFinalize(xmlSecTransformPtr transform) { |
318 | 9.98k | xmlSecOpenSSLEvpDigestCtxPtr ctx; |
319 | | |
320 | 9.98k | xmlSecAssert(xmlSecOpenSSLEvpDigestCheckId(transform)); |
321 | 9.98k | xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpDigestSize)); |
322 | | |
323 | 9.98k | ctx = xmlSecOpenSSLEvpDigestGetCtx(transform); |
324 | 9.98k | xmlSecAssert(ctx != NULL); |
325 | | |
326 | 9.98k | if(ctx->digestCtx != NULL) { |
327 | 9.98k | EVP_MD_CTX_free(ctx->digestCtx); |
328 | 9.98k | } |
329 | | |
330 | 9.98k | #ifdef XMLSEC_OPENSSL_API_300 |
331 | 9.98k | if((ctx->digest != NULL) && (ctx->digestNeedsToBeFreed != 0)) { |
332 | 9.98k | EVP_MD_free(ctx->digest); |
333 | 9.98k | } |
334 | 9.98k | #endif /* XMLSEC_OPENSSL_API_300 */ |
335 | | |
336 | 9.98k | OPENSSL_cleanse(ctx, sizeof(xmlSecOpenSSLEvpDigestCtx)); |
337 | 9.98k | } |
338 | | |
339 | | static int |
340 | | xmlSecOpenSSLEvpDigestVerify(xmlSecTransformPtr transform, |
341 | | const xmlSecByte* data, xmlSecSize dataSize, |
342 | 4.76k | xmlSecTransformCtxPtr transformCtx) { |
343 | 4.76k | xmlSecOpenSSLEvpDigestCtxPtr ctx; |
344 | 4.76k | int ret; |
345 | | |
346 | 4.76k | xmlSecAssert2(xmlSecOpenSSLEvpDigestCheckId(transform), -1); |
347 | 4.76k | xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpDigestSize), -1); |
348 | 4.76k | xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1); |
349 | 4.76k | xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1); |
350 | 4.76k | xmlSecAssert2(data != NULL, -1); |
351 | 4.76k | xmlSecAssert2(transformCtx != NULL, -1); |
352 | | |
353 | 4.76k | ctx = xmlSecOpenSSLEvpDigestGetCtx(transform); |
354 | 4.76k | xmlSecAssert2(ctx != NULL, -1); |
355 | 4.76k | xmlSecAssert2(ctx->dgstSize > 0, -1); |
356 | | |
357 | 4.76k | if(dataSize != ctx->dgstSize) { |
358 | 132 | xmlSecInvalidSizeError("Digest", dataSize, ctx->dgstSize, |
359 | 132 | xmlSecTransformGetName(transform)); |
360 | 132 | transform->status = xmlSecTransformStatusFail; |
361 | 132 | return(0); |
362 | 132 | } |
363 | | |
364 | 4.63k | ret = xmlSecMemEqual(ctx->dgst, data, ctx->dgstSize); |
365 | 4.63k | if(ret < 0) { |
366 | 0 | xmlSecInternalError("xmlSecMemEqual", xmlSecTransformGetName(transform)); |
367 | 0 | return(-1); |
368 | 0 | } |
369 | 4.63k | if(ret == 0) { |
370 | 4.50k | xmlSecInvalidDataError("data and digest do not match", |
371 | 4.50k | xmlSecTransformGetName(transform)); |
372 | 4.50k | transform->status = xmlSecTransformStatusFail; |
373 | 4.50k | return(0); |
374 | 4.50k | } |
375 | | |
376 | 134 | transform->status = xmlSecTransformStatusOk; |
377 | 134 | return(0); |
378 | 4.63k | } |
379 | | |
380 | | static int |
381 | 170k | xmlSecOpenSSLEvpDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { |
382 | 170k | xmlSecOpenSSLEvpDigestCtxPtr ctx; |
383 | 170k | xmlSecBufferPtr in, out; |
384 | 170k | int ret; |
385 | | |
386 | 170k | xmlSecAssert2(xmlSecOpenSSLEvpDigestCheckId(transform), -1); |
387 | 170k | xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); |
388 | 170k | xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpDigestSize), -1); |
389 | 170k | xmlSecAssert2(transformCtx != NULL, -1); |
390 | | |
391 | 170k | in = &(transform->inBuf); |
392 | 170k | xmlSecAssert2(in != NULL, -1); |
393 | | |
394 | 170k | out = &(transform->outBuf); |
395 | 170k | xmlSecAssert2(out != NULL, -1); |
396 | | |
397 | 170k | ctx = xmlSecOpenSSLEvpDigestGetCtx(transform); |
398 | 170k | xmlSecAssert2(ctx != NULL, -1); |
399 | 170k | xmlSecAssert2(ctx->digest != NULL, -1); |
400 | 170k | xmlSecAssert2(ctx->digestCtx != NULL, -1); |
401 | | |
402 | 170k | if(transform->status == xmlSecTransformStatusNone) { |
403 | 6.46k | ret = EVP_DigestInit(ctx->digestCtx, ctx->digest); |
404 | 6.46k | if(ret != 1) { |
405 | 0 | xmlSecOpenSSLError("EVP_DigestInit", |
406 | 0 | xmlSecTransformGetName(transform)); |
407 | 0 | return(-1); |
408 | 0 | } |
409 | 6.46k | transform->status = xmlSecTransformStatusWorking; |
410 | 6.46k | } |
411 | | |
412 | 170k | if(transform->status == xmlSecTransformStatusWorking) { |
413 | 170k | xmlSecSize inSize; |
414 | | |
415 | 170k | inSize = xmlSecBufferGetSize(in); |
416 | 170k | if(inSize > 0) { |
417 | 156k | ret = EVP_DigestUpdate(ctx->digestCtx, xmlSecBufferGetData(in), inSize); |
418 | 156k | if(ret != 1) { |
419 | 0 | xmlSecOpenSSLError2("EVP_DigestUpdate", |
420 | 0 | xmlSecTransformGetName(transform), |
421 | 0 | "size=" XMLSEC_SIZE_FMT, inSize); |
422 | 0 | return(-1); |
423 | 0 | } |
424 | | |
425 | 156k | ret = xmlSecBufferRemoveHead(in, inSize); |
426 | 156k | if(ret < 0) { |
427 | 0 | xmlSecInternalError2("xmlSecBufferRemoveHead", |
428 | 0 | xmlSecTransformGetName(transform), |
429 | 0 | "size=" XMLSEC_SIZE_FMT, inSize); |
430 | 0 | return(-1); |
431 | 0 | } |
432 | 156k | } |
433 | 170k | if(last) { |
434 | 6.46k | xmlSecOpenSSLSizeT mdSize; |
435 | 6.46k | xmlSecSize size; |
436 | 6.46k | unsigned int dgstSize; |
437 | | |
438 | 6.46k | mdSize = EVP_MD_size(ctx->digest); |
439 | 6.46k | if (mdSize <= 0) { |
440 | 0 | xmlSecOpenSSLError("EVP_MD_size", xmlSecTransformGetName(transform)); |
441 | 0 | return(-1); |
442 | 0 | } |
443 | 6.46k | XMLSEC_OPENSSL_SAFE_CAST_SIZE_T_TO_SIZE(mdSize, size, return(-1), xmlSecTransformGetName(transform)); |
444 | 6.46k | xmlSecAssert2(size <= sizeof(ctx->dgst), -1); |
445 | | |
446 | 6.46k | ret = EVP_DigestFinal(ctx->digestCtx, ctx->dgst, &dgstSize); |
447 | 6.46k | if(ret != 1) { |
448 | 0 | xmlSecOpenSSLError("EVP_DigestFinal", |
449 | 0 | xmlSecTransformGetName(transform)); |
450 | 0 | return(-1); |
451 | 0 | } |
452 | 6.46k | xmlSecAssert2(dgstSize > 0, -1); |
453 | 6.46k | xmlSecAssert2((xmlSecOpenSSLSizeT)dgstSize == mdSize, -1); /* cross-check: digest final agrees with EVP_MD_size */ |
454 | 6.46k | ctx->dgstSize = dgstSize; |
455 | | |
456 | | /* copy result to output */ |
457 | 6.46k | if(transform->operation == xmlSecTransformOperationSign) { |
458 | 0 | ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize); |
459 | 0 | if(ret < 0) { |
460 | 0 | xmlSecInternalError2("xmlSecBufferAppend", |
461 | 0 | xmlSecTransformGetName(transform), |
462 | 0 | "size=" XMLSEC_SIZE_FMT, ctx->dgstSize); |
463 | 0 | return(-1); |
464 | 0 | } |
465 | 0 | } |
466 | 6.46k | transform->status = xmlSecTransformStatusFinished; |
467 | 6.46k | } |
468 | 170k | } else if(transform->status == xmlSecTransformStatusFinished) { |
469 | | /* the only way we can get here is if there is no input */ |
470 | 0 | xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1); |
471 | 0 | } else { |
472 | 0 | xmlSecInvalidTransformStatusError(transform); |
473 | 0 | return(-1); |
474 | 0 | } |
475 | | |
476 | 170k | return(0); |
477 | 170k | } |
478 | | |
479 | | |
480 | | /* Helper macros to define the digest transform klass */ |
481 | | #define XMLSEC_OPENSSL_EVP_DIGEST_KLASS_EX(name, readNode) \ |
482 | | static xmlSecTransformKlass xmlSecOpenSSL ## name ## Klass = { \ |
483 | | sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ \ |
484 | | xmlSecOpenSSLEvpDigestSize, /* xmlSecSize objSize */ \ |
485 | | xmlSecName ## name, /* const xmlChar* name; */ \ |
486 | | xmlSecHref ## name, /* const xmlChar* href; */ \ |
487 | | xmlSecTransformUsageDigestMethod, /* xmlSecTransformUsage usage; */ \ |
488 | | xmlSecOpenSSLEvpDigestInitialize, /* xmlSecTransformInitializeMethod initialize; */ \ |
489 | | xmlSecOpenSSLEvpDigestFinalize, /* xmlSecTransformFinalizeMethod finalize; */ \ |
490 | | readNode, /* xmlSecTransformNodeReadMethod readNode; */ \ |
491 | | NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ \ |
492 | | NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ \ |
493 | | NULL, /* xmlSecTransformSetKeyMethod setKey; */ \ |
494 | | xmlSecOpenSSLEvpDigestVerify, /* xmlSecTransformVerifyMethod verify; */ \ |
495 | | xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ \ |
496 | | xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ \ |
497 | | xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ \ |
498 | | NULL, /* xmlSecTransformPushXmlMethod pushXml; */ \ |
499 | | NULL, /* xmlSecTransformPopXmlMethod popXml; */ \ |
500 | | xmlSecOpenSSLEvpDigestExecute, /* xmlSecTransformExecuteMethod execute; */ \ |
501 | | NULL, /* void* reserved0; */ \ |
502 | | NULL, /* void* reserved1; */ \ |
503 | | }; |
504 | | |
505 | | #define XMLSEC_OPENSSL_EVP_DIGEST_KLASS(name) \ |
506 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS_EX(name, NULL) |
507 | | |
508 | | |
509 | | #ifndef XMLSEC_NO_MD5 |
510 | | /****************************************************************************** |
511 | | * |
512 | | * MD5 |
513 | | * |
514 | | *****************************************************************************/ |
515 | | /* MD5 digest transform: xmlSecOpenSSLMd5Klass */ |
516 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Md5) |
517 | | |
518 | | /** |
519 | | * @brief MD5 digest transform klass. |
520 | | * @return pointer to MD5 digest transform klass. |
521 | | */ |
522 | | xmlSecTransformId |
523 | 205k | xmlSecOpenSSLTransformMd5GetKlass(void) { |
524 | 205k | return(&xmlSecOpenSSLMd5Klass); |
525 | 205k | } |
526 | | #endif /* XMLSEC_NO_MD5 */ |
527 | | |
528 | | #ifndef XMLSEC_NO_RIPEMD160 |
529 | | /****************************************************************************** |
530 | | * |
531 | | * RIPEMD160 |
532 | | * |
533 | | *****************************************************************************/ |
534 | | /* RIPEMD-160 digest transform: xmlSecOpenSSLRipemd160Klass */ |
535 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Ripemd160) |
536 | | |
537 | | /** |
538 | | * @brief RIPEMD-160 digest transform klass. |
539 | | * @return pointer to RIPEMD-160 digest transform klass. |
540 | | */ |
541 | | xmlSecTransformId |
542 | 205k | xmlSecOpenSSLTransformRipemd160GetKlass(void) { |
543 | 205k | return(&xmlSecOpenSSLRipemd160Klass); |
544 | 205k | } |
545 | | #endif /* XMLSEC_NO_RIPEMD160 */ |
546 | | |
547 | | |
548 | | #ifndef XMLSEC_NO_SHA1 |
549 | | /****************************************************************************** |
550 | | * |
551 | | * SHA1 |
552 | | * |
553 | | *****************************************************************************/ |
554 | | /* SHA-1 digest transform: xmlSecOpenSSLSha1Klass */ |
555 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha1) |
556 | | |
557 | | /** |
558 | | * @brief SHA-1 digest transform klass. |
559 | | * @return pointer to SHA-1 digest transform klass. |
560 | | */ |
561 | | xmlSecTransformId |
562 | 205k | xmlSecOpenSSLTransformSha1GetKlass(void) { |
563 | 205k | return(&xmlSecOpenSSLSha1Klass); |
564 | 205k | } |
565 | | #endif /* XMLSEC_NO_SHA1 */ |
566 | | |
567 | | #ifndef XMLSEC_NO_SHA224 |
568 | | /****************************************************************************** |
569 | | * |
570 | | * SHA2-224 |
571 | | * |
572 | | *****************************************************************************/ |
573 | | /* SHA2-224 digest transform: xmlSecOpenSSLSha224Klass */ |
574 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha224) |
575 | | |
576 | | /** |
577 | | * @brief SHA2-224 digest transform klass. |
578 | | * @return pointer to SHA2-224 digest transform klass. |
579 | | */ |
580 | | xmlSecTransformId |
581 | 70 | xmlSecOpenSSLTransformSha224GetKlass(void) { |
582 | 70 | return(&xmlSecOpenSSLSha224Klass); |
583 | 70 | } |
584 | | #endif /* XMLSEC_NO_SHA224 */ |
585 | | |
586 | | #ifndef XMLSEC_NO_SHA256 |
587 | | /****************************************************************************** |
588 | | * |
589 | | * SHA2-256 |
590 | | * |
591 | | *****************************************************************************/ |
592 | | /* SHA2-256 digest transform: xmlSecOpenSSLSha256Klass */ |
593 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha256) |
594 | | |
595 | | /** |
596 | | * @brief SHA2-256 digest transform klass. |
597 | | * @return pointer to SHA2-256 digest transform klass. |
598 | | */ |
599 | | xmlSecTransformId |
600 | 61 | xmlSecOpenSSLTransformSha256GetKlass(void) { |
601 | 61 | return(&xmlSecOpenSSLSha256Klass); |
602 | 61 | } |
603 | | #endif /* XMLSEC_NO_SHA256 */ |
604 | | |
605 | | #ifndef XMLSEC_NO_SHA384 |
606 | | /****************************************************************************** |
607 | | * |
608 | | * SHA2-384 |
609 | | * |
610 | | *****************************************************************************/ |
611 | | /* SHA2-384 digest transform: xmlSecOpenSSLSha384Klass */ |
612 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha384) |
613 | | |
614 | | /** |
615 | | * @brief SHA2-384 digest transform klass. |
616 | | * @return pointer to SHA2-384 digest transform klass. |
617 | | */ |
618 | | xmlSecTransformId |
619 | 25 | xmlSecOpenSSLTransformSha384GetKlass(void) { |
620 | 25 | return(&xmlSecOpenSSLSha384Klass); |
621 | 25 | } |
622 | | #endif /* XMLSEC_NO_SHA384 */ |
623 | | |
624 | | #ifndef XMLSEC_NO_SHA512 |
625 | | /****************************************************************************** |
626 | | * |
627 | | * SHA2-512 |
628 | | * |
629 | | *****************************************************************************/ |
630 | | /* SHA2-512 digest transform: xmlSecOpenSSLSha512Klass */ |
631 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha512) |
632 | | |
633 | | /** |
634 | | * @brief SHA2-512 digest transform klass. |
635 | | * @return pointer to SHA2-512 digest transform klass. |
636 | | */ |
637 | | xmlSecTransformId |
638 | 25 | xmlSecOpenSSLTransformSha512GetKlass(void) { |
639 | 25 | return(&xmlSecOpenSSLSha512Klass); |
640 | 25 | } |
641 | | #endif /* XMLSEC_NO_SHA512 */ |
642 | | |
643 | | |
644 | | #ifndef XMLSEC_NO_SHA3 |
645 | | /****************************************************************************** |
646 | | * |
647 | | * SHA3-224 |
648 | | * |
649 | | *****************************************************************************/ |
650 | | /* SHA3-224 digest transform: xmlSecOpenSSLSha3_224Klass */ |
651 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha3_224) |
652 | | |
653 | | /** |
654 | | * @brief SHA3-224 digest transform klass. |
655 | | * @return pointer to SHA3-224 digest transform klass. |
656 | | */ |
657 | | xmlSecTransformId |
658 | 7 | xmlSecOpenSSLTransformSha3_224GetKlass(void) { |
659 | 7 | return(&xmlSecOpenSSLSha3_224Klass); |
660 | 7 | } |
661 | | |
662 | | /****************************************************************************** |
663 | | * |
664 | | * SHA3-256 |
665 | | * |
666 | | *****************************************************************************/ |
667 | | /* SHA3-256 digest transform: xmlSecOpenSSLSha3_256Klass */ |
668 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha3_256) |
669 | | |
670 | | /** |
671 | | * @brief SHA3-256 digest transform klass. |
672 | | * @return pointer to SHA3-256 digest transform klass. |
673 | | */ |
674 | | xmlSecTransformId |
675 | 4 | xmlSecOpenSSLTransformSha3_256GetKlass(void) { |
676 | 4 | return(&xmlSecOpenSSLSha3_256Klass); |
677 | 4 | } |
678 | | |
679 | | /****************************************************************************** |
680 | | * |
681 | | * SHA3-384 |
682 | | * |
683 | | *****************************************************************************/ |
684 | | /* SHA3-384 digest transform: xmlSecOpenSSLSha3_384Klass */ |
685 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha3_384) |
686 | | |
687 | | /** |
688 | | * @brief SHA3-384 digest transform klass. |
689 | | * @return pointer to SHA3-384 digest transform klass. |
690 | | */ |
691 | | xmlSecTransformId |
692 | 4 | xmlSecOpenSSLTransformSha3_384GetKlass(void) { |
693 | 4 | return(&xmlSecOpenSSLSha3_384Klass); |
694 | 4 | } |
695 | | |
696 | | /****************************************************************************** |
697 | | * |
698 | | * SHA3-512 |
699 | | * |
700 | | *****************************************************************************/ |
701 | | /* SHA3-512 digest transform: xmlSecOpenSSLSha3_512Klass */ |
702 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(Sha3_512) |
703 | | |
704 | | /** |
705 | | * @brief SHA3-512 digest transform klass. |
706 | | * @return pointer to SHA3-512 digest transform klass. |
707 | | */ |
708 | | xmlSecTransformId |
709 | 4 | xmlSecOpenSSLTransformSha3_512GetKlass(void) { |
710 | 4 | return(&xmlSecOpenSSLSha3_512Klass); |
711 | 4 | } |
712 | | #endif /* XMLSEC_NO_SHA3 */ |
713 | | |
714 | | #ifndef XMLSEC_NO_GOST |
715 | | /****************************************************************************** |
716 | | * |
717 | | * GOSTR3411_94 |
718 | | * |
719 | | *****************************************************************************/ |
720 | | /* GOSTR3411-94 digest transform: xmlSecOpenSSLGostR3411_94Klass */ |
721 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(GostR3411_94) |
722 | | |
723 | | /** |
724 | | * @brief GOSTR3411_94 digest transform klass. |
725 | | * @return pointer to GOSTR3411_94 digest transform klass. |
726 | | */ |
727 | | xmlSecTransformId |
728 | | xmlSecOpenSSLTransformGostR3411_94GetKlass(void) { |
729 | | return(&xmlSecOpenSSLGostR3411_94Klass); |
730 | | } |
731 | | #endif /* XMLSEC_NO_GOST */ |
732 | | |
733 | | #ifndef XMLSEC_NO_GOST2012 |
734 | | |
735 | | /****************************************************************************** |
736 | | * |
737 | | * GOST R 34.11-2012 256 bit |
738 | | * |
739 | | *****************************************************************************/ |
740 | | /* GOST R 34.11-2012 256 bit digest transform: xmlSecOpenSSLGostR3411_2012_256Klass */ |
741 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(GostR3411_2012_256) |
742 | | |
743 | | /** |
744 | | * @brief GOST R 34.11-2012 256 bit digest transform klass. |
745 | | * @return pointer to GOST R 34.11-2012 256 bit digest transform klass. |
746 | | */ |
747 | | xmlSecTransformId |
748 | | xmlSecOpenSSLTransformGostR3411_2012_256GetKlass(void) { |
749 | | return(&xmlSecOpenSSLGostR3411_2012_256Klass); |
750 | | } |
751 | | |
752 | | /****************************************************************************** |
753 | | * |
754 | | * GOST R 34.11-2012 512 bit |
755 | | * |
756 | | *****************************************************************************/ |
757 | | /* GOST R 34.11-2012 512 bit digest transform: xmlSecOpenSSLGostR3411_2012_512Klass */ |
758 | | XMLSEC_OPENSSL_EVP_DIGEST_KLASS(GostR3411_2012_512) |
759 | | |
760 | | /** |
761 | | * @brief GOST R 34.11-2012 512 bit digest transform klass. |
762 | | * @return pointer to GOST R 34.11-2012 512 bit digest transform klass. |
763 | | */ |
764 | | xmlSecTransformId |
765 | | xmlSecOpenSSLTransformGostR3411_2012_512GetKlass(void) { |
766 | | return(&xmlSecOpenSSLGostR3411_2012_512Klass); |
767 | | } |
768 | | |
769 | | #endif /* XMLSEC_NO_GOST2012 */ |