diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/asn1/asn1_item.c | 143 |
1 files changed, 89 insertions, 54 deletions
diff --git a/src/lib/libcrypto/asn1/asn1_item.c b/src/lib/libcrypto/asn1/asn1_item.c index 4458ceb866..87f426c6f8 100644 --- a/src/lib/libcrypto/asn1/asn1_item.c +++ b/src/lib/libcrypto/asn1/asn1_item.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: asn1_item.c,v 1.16 2023/07/07 19:37:52 beck Exp $ */ | 1 | /* $OpenBSD: asn1_item.c,v 1.17 2023/07/13 20:59:10 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -230,73 +230,59 @@ ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, | |||
230 | return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); | 230 | return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); |
231 | } | 231 | } |
232 | 232 | ||
233 | int | 233 | static int |
234 | ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, | 234 | asn1_item_set_algorithm_identifiers(EVP_MD_CTX *ctx, X509_ALGOR *algor1, |
235 | ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) | 235 | X509_ALGOR *algor2) |
236 | { | 236 | { |
237 | const EVP_MD *type; | ||
238 | EVP_PKEY *pkey; | 237 | EVP_PKEY *pkey; |
239 | unsigned char *in = NULL, *out = NULL; | 238 | ASN1_OBJECT *aobj; |
240 | size_t out_len = 0; | 239 | const EVP_MD *md; |
241 | int in_len = 0; | 240 | int sign_id, sign_param; |
242 | int signid, paramtype; | ||
243 | int rv = 2; | ||
244 | int ret = 0; | ||
245 | 241 | ||
246 | if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx)) == NULL) { | 242 | if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx)) == NULL) { |
247 | ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); | 243 | ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); |
248 | return 0; | 244 | return 0; |
249 | } | 245 | } |
250 | 246 | ||
251 | if (pkey->ameth == NULL) { | 247 | if ((md = EVP_MD_CTX_md(ctx)) == NULL) { |
252 | ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); | 248 | ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); |
253 | return 0; | 249 | return 0; |
254 | } | 250 | } |
255 | 251 | ||
256 | if (pkey->ameth->item_sign != NULL) { | 252 | if (!OBJ_find_sigid_by_algs(&sign_id, EVP_MD_nid(md), |
257 | rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, | 253 | pkey->ameth->pkey_id)) { |
258 | signature); | 254 | ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); |
259 | if (rv == 1) { | 255 | return 0; |
260 | out_len = signature->length; | 256 | } |
261 | goto done; | 257 | if ((aobj = OBJ_nid2obj(sign_id)) == NULL) { |
262 | } | 258 | ASN1error(ASN1_R_UNKNOWN_OBJECT_TYPE); |
263 | /* Return value meanings: | 259 | return 0; |
264 | * <=0: error. | ||
265 | * 1: method does everything. | ||
266 | * 2: carry on as normal. | ||
267 | * 3: ASN1 method sets algorithm identifiers: just sign. | ||
268 | */ | ||
269 | if (rv <= 0) { | ||
270 | ASN1error(ERR_R_EVP_LIB); | ||
271 | goto err; | ||
272 | } | ||
273 | } | 260 | } |
274 | 261 | ||
275 | if (rv == 2) { | 262 | sign_param = V_ASN1_UNDEF; |
276 | if ((type = EVP_MD_CTX_md(ctx)) == NULL) { | 263 | if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) |
277 | ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); | 264 | sign_param = V_ASN1_NULL; |
278 | return 0; | ||
279 | } | ||
280 | 265 | ||
281 | if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), | 266 | if (algor1 != NULL) { |
282 | pkey->ameth->pkey_id)) { | 267 | if (!X509_ALGOR_set0(algor1, aobj, sign_param, NULL)) |
283 | ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); | ||
284 | return 0; | 268 | return 0; |
285 | } | 269 | } |
286 | 270 | if (algor2 != NULL) { | |
287 | if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) | 271 | if (!X509_ALGOR_set0(algor2, aobj, sign_param, NULL)) |
288 | paramtype = V_ASN1_NULL; | 272 | return 0; |
289 | else | 273 | } |
290 | paramtype = V_ASN1_UNDEF; | ||
291 | 274 | ||
292 | if (algor1) | 275 | return 1; |
293 | X509_ALGOR_set0(algor1, | 276 | } |
294 | OBJ_nid2obj(signid), paramtype, NULL); | ||
295 | if (algor2) | ||
296 | X509_ALGOR_set0(algor2, | ||
297 | OBJ_nid2obj(signid), paramtype, NULL); | ||
298 | 277 | ||
299 | } | 278 | static int |
279 | asn1_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, | ||
280 | ASN1_BIT_STRING *signature) | ||
281 | { | ||
282 | unsigned char *in = NULL, *out = NULL; | ||
283 | size_t out_len = 0; | ||
284 | int in_len = 0; | ||
285 | int ret = 0; | ||
300 | 286 | ||
301 | if ((in_len = ASN1_item_i2d(asn, &in, it)) <= 0) { | 287 | if ((in_len = ASN1_item_i2d(asn, &in, it)) <= 0) { |
302 | in_len = 0; | 288 | in_len = 0; |
@@ -325,14 +311,14 @@ ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, | |||
325 | out = NULL; | 311 | out = NULL; |
326 | 312 | ||
327 | if (!asn1_abs_set_unused_bits(signature, 0)) { | 313 | if (!asn1_abs_set_unused_bits(signature, 0)) { |
314 | ASN1_STRING_set0(signature, NULL, 0); | ||
328 | ASN1error(ERR_R_ASN1_LIB); | 315 | ASN1error(ERR_R_ASN1_LIB); |
329 | goto err; | 316 | goto err; |
330 | } | 317 | } |
331 | 318 | ||
332 | done: | 319 | ret = 1; |
333 | ret = out_len; | 320 | |
334 | err: | 321 | err: |
335 | EVP_MD_CTX_cleanup(ctx); | ||
336 | freezero(in, in_len); | 322 | freezero(in, in_len); |
337 | freezero(out, out_len); | 323 | freezero(out, out_len); |
338 | 324 | ||
@@ -340,6 +326,55 @@ ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, | |||
340 | } | 326 | } |
341 | 327 | ||
342 | int | 328 | int |
329 | ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, | ||
330 | ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) | ||
331 | { | ||
332 | EVP_PKEY *pkey; | ||
333 | int rv; | ||
334 | int ret = 0; | ||
335 | |||
336 | if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx)) == NULL) { | ||
337 | ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); | ||
338 | goto err; | ||
339 | } | ||
340 | if (pkey->ameth == NULL) { | ||
341 | ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); | ||
342 | goto err; | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * API insanity ahead. If the item_sign() method is absent or if it | ||
347 | * returns 2, this means: do all the work here. If it returns 3, only | ||
348 | * sign. If it returns 1, then there's nothing to do but to return | ||
349 | * the signature's length. Everything else is an error. | ||
350 | */ | ||
351 | |||
352 | rv = 2; | ||
353 | if (pkey->ameth->item_sign != NULL) | ||
354 | rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, | ||
355 | signature); | ||
356 | if (rv <= 0 || rv > 3) | ||
357 | goto err; | ||
358 | if (rv == 1) | ||
359 | goto done; | ||
360 | if (rv == 2) { | ||
361 | if (!asn1_item_set_algorithm_identifiers(ctx, algor1, algor2)) | ||
362 | goto err; | ||
363 | } | ||
364 | |||
365 | if (!asn1_item_sign(ctx, it, asn, signature)) | ||
366 | goto err; | ||
367 | |||
368 | done: | ||
369 | ret = signature->length; | ||
370 | |||
371 | err: | ||
372 | EVP_MD_CTX_cleanup(ctx); | ||
373 | |||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | int | ||
343 | ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, | 378 | ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, |
344 | ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) | 379 | ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) |
345 | { | 380 | { |