Coverage Report

Created: 2025-07-18 07:00

/src/unbound/sldns/keyraw.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * keyraw.c - raw key operations and conversions
3
 *
4
 * (c) NLnet Labs, 2004-2008
5
 *
6
 * See the file LICENSE for the license
7
 */
8
/**
9
 * \file
10
 * Implementation of raw DNSKEY functions (work on wire rdata).
11
 */
12
13
#include "config.h"
14
#include "sldns/keyraw.h"
15
#include "sldns/rrdef.h"
16
17
#ifdef HAVE_SSL
18
#include <openssl/ssl.h>
19
#include <openssl/evp.h>
20
#include <openssl/rand.h>
21
#include <openssl/err.h>
22
#include <openssl/md5.h>
23
#ifdef HAVE_OPENSSL_ENGINE_H
24
#  include <openssl/engine.h>
25
#endif
26
#ifdef HAVE_OPENSSL_BN_H
27
#include <openssl/bn.h>
28
#endif
29
#ifdef HAVE_OPENSSL_PARAM_BUILD_H
30
#  include <openssl/param_build.h>
31
#else
32
#  ifdef HAVE_OPENSSL_RSA_H
33
#  include <openssl/rsa.h>
34
#  endif
35
#  ifdef HAVE_OPENSSL_DSA_H
36
#  include <openssl/dsa.h>
37
#  endif
38
#endif
39
#endif /* HAVE_SSL */
40
41
size_t
42
sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
43
  const size_t len, int alg)
44
0
{
45
  /* for DSA keys */
46
0
  uint8_t t;
47
  
48
  /* for RSA keys */
49
0
  uint16_t exp;
50
0
  uint16_t int16;
51
  
52
0
  switch ((sldns_algorithm)alg) {
53
0
  case LDNS_DSA:
54
0
  case LDNS_DSA_NSEC3:
55
0
    if (len > 0) {
56
0
      t = keydata[0];
57
0
      return (64 + t*8)*8;
58
0
    } else {
59
0
      return 0;
60
0
    }
61
0
    break;
62
0
  case LDNS_RSAMD5:
63
0
  case LDNS_RSASHA1:
64
0
  case LDNS_RSASHA1_NSEC3:
65
0
#ifdef USE_SHA2
66
0
  case LDNS_RSASHA256:
67
0
  case LDNS_RSASHA512:
68
0
#endif
69
0
    if (len > 0) {
70
0
      if (keydata[0] == 0) {
71
        /* big exponent */
72
0
        if (len > 3) {
73
0
          memmove(&int16, keydata + 1, 2);
74
0
          exp = ntohs(int16);
75
0
          return (len - exp - 3)*8;
76
0
        } else {
77
0
          return 0;
78
0
        }
79
0
      } else {
80
0
        exp = keydata[0];
81
0
        return (len-exp-1)*8;
82
0
      }
83
0
    } else {
84
0
      return 0;
85
0
    }
86
0
    break;
87
#ifdef USE_GOST
88
  case LDNS_ECC_GOST:
89
    return 512;
90
#endif
91
0
#ifdef USE_ECDSA
92
0
        case LDNS_ECDSAP256SHA256:
93
0
                return 256;
94
0
        case LDNS_ECDSAP384SHA384:
95
0
                return 384;
96
0
#endif
97
0
#ifdef USE_ED25519
98
0
  case LDNS_ED25519:
99
0
    return 256;
100
0
#endif
101
0
#ifdef USE_ED448
102
0
  case LDNS_ED448:
103
0
    return 456;
104
0
#endif
105
0
  default:
106
0
    return 0;
107
0
  }
108
0
}
109
110
uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize)
111
0
{
112
0
  if(keysize < 4) {
113
0
    return 0;
114
0
  }
115
  /* look at the algorithm field, copied from 2535bis */
116
0
  if (key[3] == LDNS_RSAMD5) {
117
0
    uint16_t ac16 = 0;
118
0
    if (keysize > 4) {
119
0
      memmove(&ac16, key + keysize - 3, 2);
120
0
    }
121
0
    ac16 = ntohs(ac16);
122
0
    return (uint16_t) ac16;
123
0
  } else {
124
0
    size_t i;
125
0
    uint32_t ac32 = 0;
126
0
    for (i = 0; i < keysize; ++i) {
127
0
      ac32 += ((i & 1)) ? key[i] : key[i] << 8;
128
0
    }
129
0
    ac32 += (ac32 >> 16) & 0xFFFF;
130
0
    return (uint16_t) (ac32 & 0xFFFF);
131
0
  }
132
0
}
133
134
#ifdef HAVE_SSL
135
#ifdef USE_GOST
136
/** store GOST engine reference loaded into OpenSSL library */
137
ENGINE* sldns_gost_engine = NULL;
138
139
int
140
sldns_key_EVP_load_gost_id(void)
141
{
142
  static int gost_id = 0;
143
  const EVP_PKEY_ASN1_METHOD* meth;
144
  ENGINE* e;
145
146
  if(gost_id) return gost_id;
147
148
  /* see if configuration loaded gost implementation from other engine*/
149
  meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
150
  if(meth) {
151
    EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
152
    return gost_id;
153
  }
154
155
  /* see if engine can be loaded already */
156
  e = ENGINE_by_id("gost");
157
  if(!e) {
158
    /* load it ourself, in case statically linked */
159
    ENGINE_load_builtin_engines();
160
    ENGINE_load_dynamic();
161
    e = ENGINE_by_id("gost");
162
  }
163
  if(!e) {
164
    /* no gost engine in openssl */
165
    return 0;
166
  }
167
  if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
168
    ENGINE_finish(e);
169
    ENGINE_free(e);
170
    return 0;
171
  }
172
173
  meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
174
  if(!meth) {
175
    /* algo not found */
176
    ENGINE_finish(e);
177
    ENGINE_free(e);
178
    return 0;
179
  }
180
        /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
181
         * on some platforms this frees up the meth and unloads gost stuff */
182
        sldns_gost_engine = e;
183
  
184
  EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
185
  return gost_id;
186
} 
187
188
void sldns_key_EVP_unload_gost(void)
189
{
190
        if(sldns_gost_engine) {
191
                ENGINE_finish(sldns_gost_engine);
192
                ENGINE_free(sldns_gost_engine);
193
                sldns_gost_engine = NULL;
194
        }
195
}
196
#endif /* USE_GOST */
197
198
#ifdef USE_DSA
199
/* Retrieve params as BIGNUM from raw buffer */
200
static int
201
sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
202
  BIGNUM** q, BIGNUM** g, BIGNUM** y)
203
{
204
  uint8_t T;
205
  uint16_t length;
206
  uint16_t offset;
207
208
  if(len == 0)
209
    return 0;
210
  T = (uint8_t)key[0];
211
  length = (64 + T * 8);
212
  offset = 1;
213
214
  if (T > 8) {
215
    return 0;
216
  }
217
  if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
218
    return 0;
219
220
  *q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
221
  offset += SHA_DIGEST_LENGTH;
222
223
  *p = BN_bin2bn(key+offset, (int)length, NULL);
224
  offset += length;
225
226
  *g = BN_bin2bn(key+offset, (int)length, NULL);
227
  offset += length;
228
229
  *y = BN_bin2bn(key+offset, (int)length, NULL);
230
231
  if(!*q || !*p || !*g || !*y) {
232
    BN_free(*q);
233
    BN_free(*p);
234
    BN_free(*g);
235
    BN_free(*y);
236
    return 0;
237
  }
238
  return 1;
239
}
240
241
#ifndef HAVE_OSSL_PARAM_BLD_NEW
242
DSA *
243
sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
244
{
245
  DSA *dsa;
246
  BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
247
  if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
248
    return NULL;
249
  }
250
  /* create the key and set its properties */
251
  if(!(dsa = DSA_new())) {
252
    return NULL;
253
  }
254
#if OPENSSL_VERSION_NUMBER < 0x10100000 || \
255
        (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
256
#ifndef S_SPLINT_S
257
  dsa->p = P;
258
  dsa->q = Q;
259
  dsa->g = G;
260
  dsa->pub_key = Y;
261
#endif /* splint */
262
263
#else /* OPENSSL_VERSION_NUMBER */
264
  if (!DSA_set0_pqg(dsa, P, Q, G)) {
265
    /* QPG not yet attached, need to free */
266
    BN_free(Q);
267
    BN_free(P);
268
    BN_free(G);
269
270
    DSA_free(dsa);
271
    BN_free(Y);
272
    return NULL;
273
  }
274
  if (!DSA_set0_key(dsa, Y, NULL)) {
275
    /* QPG attached, cleaned up by DSA_free() */
276
    DSA_free(dsa);
277
    BN_free(Y);
278
    return NULL;
279
  }
280
#endif
281
282
  return dsa;
283
}
284
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
285
286
EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
287
{
288
#ifdef HAVE_OSSL_PARAM_BLD_NEW
289
  EVP_PKEY* evp_key = NULL;
290
  EVP_PKEY_CTX* ctx;
291
  BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
292
  OSSL_PARAM_BLD* param_bld;
293
  OSSL_PARAM* params = NULL;
294
  if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
295
    return NULL;
296
  }
297
298
  param_bld = OSSL_PARAM_BLD_new();
299
  if(!param_bld) {
300
    BN_free(p);
301
    BN_free(q);
302
    BN_free(g);
303
    BN_free(y);
304
    return NULL;
305
  }
306
  if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
307
     !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
308
     !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
309
     !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
310
    OSSL_PARAM_BLD_free(param_bld);
311
    BN_free(p);
312
    BN_free(q);
313
    BN_free(g);
314
    BN_free(y);
315
    return NULL;
316
  }
317
  params = OSSL_PARAM_BLD_to_param(param_bld);
318
  OSSL_PARAM_BLD_free(param_bld);
319
320
  ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
321
  if(!ctx) {
322
    OSSL_PARAM_free(params);
323
    BN_free(p);
324
    BN_free(q);
325
    BN_free(g);
326
    BN_free(y);
327
    return NULL;
328
  }
329
  if(EVP_PKEY_fromdata_init(ctx) <= 0) {
330
    EVP_PKEY_CTX_free(ctx);
331
    OSSL_PARAM_free(params);
332
    BN_free(p);
333
    BN_free(q);
334
    BN_free(g);
335
    BN_free(y);
336
    return NULL;
337
  }
338
  if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
339
    EVP_PKEY_CTX_free(ctx);
340
    OSSL_PARAM_free(params);
341
    BN_free(p);
342
    BN_free(q);
343
    BN_free(g);
344
    BN_free(y);
345
    return NULL;
346
  }
347
348
  EVP_PKEY_CTX_free(ctx);
349
  OSSL_PARAM_free(params);
350
  BN_free(p);
351
  BN_free(q);
352
  BN_free(g);
353
  BN_free(y);
354
  return evp_key;
355
#else
356
  DSA* dsa;
357
  EVP_PKEY* evp_key = EVP_PKEY_new();
358
  if(!evp_key) {
359
    return NULL;
360
  }
361
  dsa = sldns_key_buf2dsa_raw(key, len);
362
  if(!dsa) {
363
    EVP_PKEY_free(evp_key);
364
    return NULL;
365
  }
366
  if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
367
    DSA_free(dsa);
368
    EVP_PKEY_free(evp_key);
369
    return NULL;
370
  }
371
  return evp_key;
372
#endif
373
}
374
#endif /* USE_DSA */
375
376
/* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
377
static int
378
sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
379
  BIGNUM** e)
380
0
{
381
0
  uint16_t offset;
382
0
  uint16_t exp;
383
0
  uint16_t int16;
384
385
0
  if (len == 0)
386
0
    return 0;
387
0
  if (key[0] == 0) {
388
0
    if(len < 3)
389
0
      return 0;
390
0
    memmove(&int16, key+1, 2);
391
0
    exp = ntohs(int16);
392
0
    offset = 3;
393
0
  } else {
394
0
    exp = key[0];
395
0
    offset = 1;
396
0
  }
397
398
  /* key length at least one */
399
0
  if(len < (size_t)offset + exp + 1)
400
0
    return 0;
401
402
  /* Exponent */
403
0
  *e = BN_new();
404
0
  if(!*e) return 0;
405
0
  (void) BN_bin2bn(key+offset, (int)exp, *e);
406
0
  offset += exp;
407
408
  /* Modulus */
409
0
  *n = BN_new();
410
0
  if(!*n) {
411
0
    BN_free(*e);
412
0
    return 0;
413
0
  }
414
  /* length of the buffer must match the key length! */
415
0
  (void) BN_bin2bn(key+offset, (int)(len - offset), *n);
416
0
  return 1;
417
0
}
418
419
#ifndef HAVE_OSSL_PARAM_BLD_NEW
420
RSA *
421
sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
422
0
{
423
0
  BIGNUM* modulus = NULL;
424
0
  BIGNUM* exponent = NULL;
425
0
  RSA *rsa;
426
0
  if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
427
0
    return NULL;
428
0
  rsa = RSA_new();
429
0
  if(!rsa) {
430
0
    BN_free(exponent);
431
0
    BN_free(modulus);
432
0
    return NULL;
433
0
  }
434
#if OPENSSL_VERSION_NUMBER < 0x10100000 || \
435
        (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
436
#ifndef S_SPLINT_S
437
  rsa->n = modulus;
438
  rsa->e = exponent;
439
#endif /* splint */
440
441
#else /* OPENSSL_VERSION_NUMBER */
442
0
  if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
443
0
    BN_free(exponent);
444
0
    BN_free(modulus);
445
0
    RSA_free(rsa);
446
0
    return NULL;
447
0
  }
448
0
#endif
449
450
0
  return rsa;
451
0
}
452
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
453
454
EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
455
0
{
456
#ifdef HAVE_OSSL_PARAM_BLD_NEW
457
  EVP_PKEY* evp_key = NULL;
458
  EVP_PKEY_CTX* ctx;
459
  BIGNUM *n=NULL, *e=NULL;
460
  OSSL_PARAM_BLD* param_bld;
461
  OSSL_PARAM* params = NULL;
462
463
  if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) {
464
    return NULL;
465
  }
466
467
  param_bld = OSSL_PARAM_BLD_new();
468
  if(!param_bld) {
469
    BN_free(n);
470
    BN_free(e);
471
    return NULL;
472
  }
473
  if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
474
    OSSL_PARAM_BLD_free(param_bld);
475
    BN_free(n);
476
    BN_free(e);
477
    return NULL;
478
  }
479
  if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
480
    OSSL_PARAM_BLD_free(param_bld);
481
    BN_free(n);
482
    BN_free(e);
483
    return NULL;
484
  }
485
  params = OSSL_PARAM_BLD_to_param(param_bld);
486
  OSSL_PARAM_BLD_free(param_bld);
487
488
  ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
489
  if(!ctx) {
490
    OSSL_PARAM_free(params);
491
    BN_free(n);
492
    BN_free(e);
493
    return NULL;
494
  }
495
  if(EVP_PKEY_fromdata_init(ctx) <= 0) {
496
    EVP_PKEY_CTX_free(ctx);
497
    OSSL_PARAM_free(params);
498
    BN_free(n);
499
    BN_free(e);
500
    return NULL;
501
  }
502
  if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
503
    EVP_PKEY_CTX_free(ctx);
504
    OSSL_PARAM_free(params);
505
    BN_free(n);
506
    BN_free(e);
507
    return NULL;
508
  }
509
510
  EVP_PKEY_CTX_free(ctx);
511
  OSSL_PARAM_free(params);
512
  BN_free(n);
513
  BN_free(e);
514
  return evp_key;
515
#else
516
0
  RSA* rsa;
517
0
  EVP_PKEY *evp_key = EVP_PKEY_new();
518
0
  if(!evp_key) {
519
0
    return NULL;
520
0
  }
521
0
  rsa = sldns_key_buf2rsa_raw(key, len);
522
0
  if(!rsa) {
523
0
    EVP_PKEY_free(evp_key);
524
0
    return NULL;
525
0
  }
526
0
  if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
527
0
    RSA_free(rsa);
528
0
    EVP_PKEY_free(evp_key);
529
0
    return NULL;
530
0
  }
531
0
  return evp_key;
532
0
#endif
533
0
}
534
535
#ifdef USE_GOST
536
EVP_PKEY*
537
sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
538
{
539
  /* prefix header for X509 encoding */
540
  uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
541
    0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 
542
    0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 
543
    0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
544
  unsigned char encoded[37+64];
545
  const unsigned char* pp;
546
  if(keylen != 64) {
547
    /* key wrong size */
548
    return NULL;
549
  }
550
551
  /* create evp_key */
552
  memmove(encoded, asn, 37);
553
  memmove(encoded+37, key, 64);
554
  pp = (unsigned char*)&encoded[0];
555
556
  return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
557
}
558
#endif /* USE_GOST */
559
560
#ifdef USE_ECDSA
561
EVP_PKEY*
562
sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
563
0
{
564
#ifdef HAVE_OSSL_PARAM_BLD_NEW
565
  unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
566
  EVP_PKEY *evp_key = NULL;
567
  EVP_PKEY_CTX* ctx;
568
  OSSL_PARAM_BLD* param_bld;
569
  OSSL_PARAM* params = NULL;
570
  char* group = NULL;
571
572
  /* check length, which uncompressed must be 2 bignums */
573
  if(algo == LDNS_ECDSAP256SHA256) {
574
    if(keylen != 2*256/8) return NULL;
575
    group = "prime256v1";
576
  } else if(algo == LDNS_ECDSAP384SHA384) {
577
    if(keylen != 2*384/8) return NULL;
578
    group = "P-384";
579
  } else {
580
    return NULL;
581
  }
582
  if(keylen+1 > sizeof(buf)) { /* sanity check */
583
    return NULL;
584
  }
585
  /* prepend the 0x04 for uncompressed format */
586
  buf[0] = POINT_CONVERSION_UNCOMPRESSED;
587
  memmove(buf+1, key, keylen);
588
589
  param_bld = OSSL_PARAM_BLD_new();
590
  if(!param_bld) {
591
    return NULL;
592
  }
593
  if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
594
     !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
595
    OSSL_PARAM_BLD_free(param_bld);
596
    return NULL;
597
  }
598
  params = OSSL_PARAM_BLD_to_param(param_bld);
599
  OSSL_PARAM_BLD_free(param_bld);
600
601
  ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
602
  if(!ctx) {
603
    OSSL_PARAM_free(params);
604
    return NULL;
605
  }
606
  if(EVP_PKEY_fromdata_init(ctx) <= 0) {
607
    EVP_PKEY_CTX_free(ctx);
608
    OSSL_PARAM_free(params);
609
    return NULL;
610
  }
611
  if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
612
    EVP_PKEY_CTX_free(ctx);
613
    OSSL_PARAM_free(params);
614
    return NULL;
615
  }
616
  EVP_PKEY_CTX_free(ctx);
617
  OSSL_PARAM_free(params);
618
  return evp_key;
619
#else
620
0
  unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
621
0
        const unsigned char* pp = buf;
622
0
        EVP_PKEY *evp_key;
623
0
        EC_KEY *ec;
624
  /* check length, which uncompressed must be 2 bignums */
625
0
        if(algo == LDNS_ECDSAP256SHA256) {
626
0
    if(keylen != 2*256/8) return NULL;
627
0
                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
628
0
        } else if(algo == LDNS_ECDSAP384SHA384) {
629
0
    if(keylen != 2*384/8) return NULL;
630
0
                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
631
0
        } else    ec = NULL;
632
0
        if(!ec) return NULL;
633
0
  if(keylen+1 > sizeof(buf)) { /* sanity check */
634
0
                EC_KEY_free(ec);
635
0
    return NULL;
636
0
  }
637
  /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
638
   * of openssl) for uncompressed data */
639
0
  buf[0] = POINT_CONVERSION_UNCOMPRESSED;
640
0
  memmove(buf+1, key, keylen);
641
0
        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
642
0
                EC_KEY_free(ec);
643
0
                return NULL;
644
0
        }
645
0
        evp_key = EVP_PKEY_new();
646
0
        if(!evp_key) {
647
0
                EC_KEY_free(ec);
648
0
                return NULL;
649
0
        }
650
0
        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
651
0
    EVP_PKEY_free(evp_key);
652
0
    EC_KEY_free(ec);
653
0
    return NULL;
654
0
  }
655
0
        return evp_key;
656
0
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
657
0
}
658
#endif /* USE_ECDSA */
659
660
#ifdef USE_ED25519
661
EVP_PKEY*
662
sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
663
0
{
664
  /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
665
0
  uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
666
0
    0x70, 0x03, 0x21, 0x00};
667
0
  int pre_len = 12;
668
0
  uint8_t buf[256];
669
0
  EVP_PKEY *evp_key;
670
  /* pp gets modified by d2i() */
671
0
  const unsigned char* pp = (unsigned char*)buf;
672
0
  if(keylen != 32 || keylen + pre_len > sizeof(buf))
673
0
    return NULL; /* wrong length */
674
0
  memmove(buf, pre, pre_len);
675
0
  memmove(buf+pre_len, key, keylen);
676
0
  evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
677
0
  return evp_key;
678
0
}
679
#endif /* USE_ED25519 */
680
681
#ifdef USE_ED448
682
EVP_PKEY*
683
sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
684
0
{
685
  /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
686
0
  uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
687
0
    0x71, 0x03, 0x3a, 0x00};
688
0
        int pre_len = 12;
689
0
  uint8_t buf[256];
690
0
        EVP_PKEY *evp_key;
691
  /* pp gets modified by d2i() */
692
0
        const unsigned char* pp = (unsigned char*)buf;
693
0
  if(keylen != 57 || keylen + pre_len > sizeof(buf))
694
0
    return NULL; /* wrong length */
695
0
  memmove(buf, pre, pre_len);
696
0
  memmove(buf+pre_len, key, keylen);
697
0
  evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
698
0
        return evp_key;
699
0
}
700
#endif /* USE_ED448 */
701
702
int
703
sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
704
  const EVP_MD* md)
705
0
{
706
0
  EVP_MD_CTX* ctx;
707
0
  ctx = EVP_MD_CTX_create();
708
0
  if(!ctx)
709
0
    return 0;
710
0
  if(!EVP_DigestInit_ex(ctx, md, NULL) ||
711
0
    !EVP_DigestUpdate(ctx, data, len) ||
712
0
    !EVP_DigestFinal_ex(ctx, dest, NULL)) {
713
0
    EVP_MD_CTX_destroy(ctx);
714
0
    return 0;
715
0
  }
716
0
  EVP_MD_CTX_destroy(ctx);
717
0
  return 1;
718
0
}
719
#endif /* HAVE_SSL */