summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/asn1/asn1_item.c143
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
233int 233static int
234ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, 234asn1_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 } 278static int
279asn1_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
342int 328int
329ASN1_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
377int
343ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, 378ASN1_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{