Ensure that we consume all the data when decoding an SPKI
[openssl.git] / crypto / x509 / x_pubkey.c
1 /*
2  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /*
11  * DSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <stdio.h>
17 #include "internal/cryptlib.h"
18 #include <openssl/asn1t.h>
19 #include <openssl/x509.h>
20 #include "crypto/asn1.h"
21 #include "crypto/evp.h"
22 #include "crypto/x509.h"
23 #include <openssl/rsa.h>
24 #include <openssl/dsa.h>
25 #include <openssl/decoder.h>
26 #include <openssl/encoder.h>
27 #include "internal/provider.h"
28 #include "internal/sizes.h"
29
30 struct X509_pubkey_st {
31     X509_ALGOR *algor;
32     ASN1_BIT_STRING *public_key;
33
34     EVP_PKEY *pkey;
35
36     /* extra data for the callback, used by d2i_PUBKEY_ex */
37     OSSL_LIB_CTX *libctx;
38     char *propq;
39
40     /* Flag to force legacy keys */
41     unsigned int flag_force_legacy : 1;
42 };
43
44 static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key);
45
46 static int x509_pubkey_set0_libctx(X509_PUBKEY *x, OSSL_LIB_CTX *libctx,
47                                    const char *propq)
48 {
49     if (x != NULL) {
50         x->libctx = libctx;
51         OPENSSL_free(x->propq);
52         x->propq = NULL;
53         if (propq != NULL) {
54             x->propq = OPENSSL_strdup(propq);
55             if (x->propq == NULL)
56                 return 0;
57         }
58     }
59     return 1;
60 }
61
62 ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = {
63         ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
64         ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
65 } static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL)
66
67 static void x509_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
68 {
69     X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
70
71     X509_ALGOR_free(pubkey->algor);
72     ASN1_BIT_STRING_free(pubkey->public_key);
73     EVP_PKEY_free(pubkey->pkey);
74     OPENSSL_free(pubkey->propq);
75     OPENSSL_free(pubkey);
76     *pval = NULL;
77 }
78
79 static int x509_pubkey_ex_populate(ASN1_VALUE **pval, const ASN1_ITEM *it)
80 {
81     X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
82
83     return (pubkey->algor != NULL
84             || (pubkey->algor = X509_ALGOR_new()) != NULL)
85         && (pubkey->public_key != NULL
86             || (pubkey->public_key = ASN1_BIT_STRING_new()) != NULL);
87 }
88
89
90 static int x509_pubkey_ex_new_ex(ASN1_VALUE **pval, const ASN1_ITEM *it,
91                                  OSSL_LIB_CTX *libctx, const char *propq)
92 {
93     X509_PUBKEY *ret;
94
95     if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL
96         || !x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL)
97         || !x509_pubkey_set0_libctx(ret, libctx, propq)) {
98         x509_pubkey_ex_free((ASN1_VALUE **)&ret, NULL);
99         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
100     } else {
101         *pval = (ASN1_VALUE *)ret;
102     }
103
104     return ret != NULL;
105 }
106
107 static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval,
108                                  const unsigned char **in, long len,
109                                  const ASN1_ITEM *it, int tag, int aclass,
110                                  char opt, ASN1_TLC *ctx, OSSL_LIB_CTX *libctx,
111                                  const char *propq)
112 {
113     const unsigned char *in_saved = *in;
114     size_t publen;
115     X509_PUBKEY *pubkey;
116     int ret;
117     OSSL_DECODER_CTX *dctx = NULL;
118     unsigned char *tmpbuf = NULL;
119
120     if (*pval == NULL && !x509_pubkey_ex_new_ex(pval, it, libctx, propq))
121         return 0;
122     if (!x509_pubkey_ex_populate(pval, NULL)) {
123         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
124         return 0;
125     }
126
127     /* This ensures that |*in| advances properly no matter what */
128     if ((ret = ASN1_item_ex_d2i(pval, in, len,
129                                 ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL),
130                                 tag, aclass, opt, ctx)) <= 0)
131         return ret;
132
133     publen = *in - in_saved;
134     if (!ossl_assert(publen > 0)) {
135         ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR);
136         return 0;
137     }
138
139     pubkey = (X509_PUBKEY *)*pval;
140     EVP_PKEY_free(pubkey->pkey);
141     pubkey->pkey = NULL;
142
143     /*
144      * Opportunistically decode the key but remove any non fatal errors
145      * from the queue. Subsequent explicit attempts to decode/use the key
146      * will return an appropriate error.
147      */
148     ERR_set_mark();
149
150     /*
151      * Try to decode with legacy method first.  This ensures that engines
152      * aren't overriden by providers.
153      */
154     if ((ret = x509_pubkey_decode(&pubkey->pkey, pubkey)) == -1) {
155         /* -1 indicates a fatal error, like malloc failure */
156         ERR_clear_last_mark();
157         goto end;
158     }
159
160     /* Try to decode it into an EVP_PKEY with OSSL_DECODER */
161     if (ret <= 0 && !pubkey->flag_force_legacy) {
162         const unsigned char *p;
163         char txtoidname[OSSL_MAX_NAME_SIZE];
164         size_t slen = publen;
165
166         /*
167         * The decoders don't know how to handle anything other than Universal
168         * class so we modify the data accordingly.
169         */
170         if (aclass != V_ASN1_UNIVERSAL) {
171             tmpbuf = OPENSSL_memdup(in_saved, publen);
172             if (tmpbuf == NULL) {
173                 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
174                 return 0;
175             }
176             in_saved = tmpbuf;
177             *tmpbuf = V_ASN1_CONSTRUCTED | V_ASN1_SEQUENCE;
178         }
179         p = in_saved;
180
181         if (OBJ_obj2txt(txtoidname, sizeof(txtoidname),
182                         pubkey->algor->algorithm, 0) <= 0) {
183             ERR_clear_last_mark();
184             goto end;
185         }
186         if ((dctx =
187              OSSL_DECODER_CTX_new_for_pkey(&pubkey->pkey,
188                                            "DER", "SubjectPublicKeyInfo",
189                                            txtoidname, EVP_PKEY_PUBLIC_KEY,
190                                            pubkey->libctx,
191                                            pubkey->propq)) != NULL)
192             /*
193              * As said higher up, we're being opportunistic.  In other words,
194              * we don't care if we fail.
195              */
196             if (OSSL_DECODER_from_data(dctx, &p, &slen)) {
197                 if (slen != 0) {
198                     /*
199                      * If we successfully decoded then we *must* consume all the
200                      * bytes.
201                      */
202                     ERR_clear_last_mark();
203                     ERR_raise(ERR_LIB_ASN1, EVP_R_DECODE_ERROR);
204                     goto end;
205                 }
206             }
207     }
208
209     ERR_pop_to_mark();
210     ret = 1;
211  end:
212     OSSL_DECODER_CTX_free(dctx);
213     OPENSSL_free(tmpbuf);
214     return ret;
215 }
216
217 static int x509_pubkey_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
218                               const ASN1_ITEM *it, int tag, int aclass)
219 {
220     return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL),
221                             tag, aclass);
222 }
223
224 static int x509_pubkey_ex_print(BIO *out, const ASN1_VALUE **pval, int indent,
225                                 const char *fname, const ASN1_PCTX *pctx)
226 {
227     return ASN1_item_print(out, *pval, indent,
228                            ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), pctx);
229 }
230
231 static const ASN1_EXTERN_FUNCS x509_pubkey_ff = {
232     NULL,
233     NULL,
234     x509_pubkey_ex_free,
235     0,                          /* Default clear behaviour is OK */
236     NULL,
237     x509_pubkey_ex_i2d,
238     x509_pubkey_ex_print,
239     x509_pubkey_ex_new_ex,
240     x509_pubkey_ex_d2i_ex,
241 };
242
243 IMPLEMENT_EXTERN_ASN1(X509_PUBKEY, V_ASN1_SEQUENCE, x509_pubkey_ff)
244 IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
245
246 X509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq)
247 {
248     X509_PUBKEY *pubkey = NULL;
249
250     pubkey = (X509_PUBKEY *)ASN1_item_new_ex(X509_PUBKEY_it(), libctx, propq);
251     if (!x509_pubkey_set0_libctx(pubkey, libctx, propq)) {
252         X509_PUBKEY_free(pubkey);
253         pubkey = NULL;
254     }
255     return pubkey;
256 }
257
258 /*
259  * X509_PUBKEY_dup() must be implemented manually, because there is no
260  * support for it in ASN1_EXTERN_FUNCS.
261  */
262 X509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a)
263 {
264     X509_PUBKEY *pubkey = OPENSSL_zalloc(sizeof(*pubkey));
265
266     if (pubkey == NULL
267             || !x509_pubkey_set0_libctx(pubkey, a->libctx, a->propq)
268             || (pubkey->algor = X509_ALGOR_dup(a->algor)) == NULL
269             || (pubkey->public_key = ASN1_BIT_STRING_new()) == NULL
270             || !ASN1_BIT_STRING_set(pubkey->public_key,
271                                     a->public_key->data, a->public_key->length)
272             || (a->pkey != NULL && !EVP_PKEY_up_ref(a->pkey))) {
273         x509_pubkey_ex_free((ASN1_VALUE **)&pubkey,
274                             ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL));
275         ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
276         return NULL;
277     }
278     pubkey->pkey = a->pkey;
279     return pubkey;
280 }
281
282 int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
283 {
284     X509_PUBKEY *pk = NULL;
285
286     if (x == NULL || pkey == NULL) {
287         ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
288         return 0;
289     }
290
291     if (pkey->ameth != NULL) {
292         if ((pk = X509_PUBKEY_new()) == NULL) {
293             ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
294             goto error;
295         }
296         if (pkey->ameth->pub_encode != NULL) {
297             if (!pkey->ameth->pub_encode(pk, pkey)) {
298                 ERR_raise(ERR_LIB_X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
299                 goto error;
300             }
301         } else {
302             ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED);
303             goto error;
304         }
305     } else if (evp_pkey_is_provided(pkey)) {
306         unsigned char *der = NULL;
307         size_t derlen = 0;
308         OSSL_ENCODER_CTX *ectx =
309             OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_PUBLIC_KEY,
310                                           "DER", "SubjectPublicKeyInfo",
311                                           NULL);
312
313         if (OSSL_ENCODER_to_data(ectx, &der, &derlen)) {
314             const unsigned char *pder = der;
315
316             pk = d2i_X509_PUBKEY(NULL, &pder, (long)derlen);
317         }
318
319         OSSL_ENCODER_CTX_free(ectx);
320         OPENSSL_free(der);
321     }
322
323     if (pk == NULL) {
324         ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM);
325         goto error;
326     }
327
328     X509_PUBKEY_free(*x);
329     if (!EVP_PKEY_up_ref(pkey)) {
330         ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
331         goto error;
332     }
333     *x = pk;
334
335     /*
336      * pk->pkey is NULL when using the legacy routine, but is non-NULL when
337      * going through the encoder, and for all intents and purposes, it's
338      * a perfect copy of the public key portions of |pkey|, just not the same
339      * instance.  If that's all there was to pkey then we could simply return
340      * early, right here. However, some application might very well depend on
341      * the passed |pkey| being used and none other, so we spend a few more
342      * cycles throwing away the newly created |pk->pkey| and replace it with
343      * |pkey|.
344      */
345     if (pk->pkey != NULL)
346         EVP_PKEY_free(pk->pkey);
347
348     pk->pkey = pkey;
349     return 1;
350
351  error:
352     X509_PUBKEY_free(pk);
353     return 0;
354 }
355
356 /*
357  * Attempt to decode a public key.
358  * Returns 1 on success, 0 for a decode failure and -1 for a fatal
359  * error e.g. malloc failure.
360  *
361  * This function is #legacy.
362  */
363 static int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key)
364 {
365     EVP_PKEY *pkey = EVP_PKEY_new();
366
367     if (pkey == NULL) {
368         ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
369         return -1;
370     }
371
372     if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
373         ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM);
374         goto error;
375     }
376
377     if (pkey->ameth->pub_decode) {
378         /*
379          * Treat any failure of pub_decode as a decode error. In
380          * future we could have different return codes for decode
381          * errors and fatal errors such as malloc failure.
382          */
383         if (!pkey->ameth->pub_decode(pkey, key))
384             goto error;
385     } else {
386         ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED);
387         goto error;
388     }
389
390     *ppkey = pkey;
391     return 1;
392
393  error:
394     EVP_PKEY_free(pkey);
395     return 0;
396 }
397
398 EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key)
399 {
400     EVP_PKEY *ret = NULL;
401
402     if (key == NULL || key->public_key == NULL)
403         return NULL;
404
405     if (key->pkey != NULL)
406         return key->pkey;
407
408     /*
409      * When the key ASN.1 is initially parsed an attempt is made to
410      * decode the public key and cache the EVP_PKEY structure. If this
411      * operation fails the cached value will be NULL. Parsing continues
412      * to allow parsing of unknown key types or unsupported forms.
413      * We repeat the decode operation so the appropriate errors are left
414      * in the queue.
415      */
416     x509_pubkey_decode(&ret, key);
417     /* If decode doesn't fail something bad happened */
418     if (ret != NULL) {
419         ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
420         EVP_PKEY_free(ret);
421     }
422
423     return NULL;
424 }
425
426 EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key)
427 {
428     EVP_PKEY *ret = X509_PUBKEY_get0(key);
429
430     if (ret != NULL && !EVP_PKEY_up_ref(ret)) {
431         ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
432         ret = NULL;
433     }
434     return ret;
435 }
436
437 /*
438  * Now three pseudo ASN1 routines that take an EVP_PKEY structure and encode
439  * or decode as X509_PUBKEY
440  */
441 static EVP_PKEY *d2i_PUBKEY_int(EVP_PKEY **a,
442                                 const unsigned char **pp, long length,
443                                 OSSL_LIB_CTX *libctx, const char *propq,
444                                 unsigned int force_legacy,
445                                 X509_PUBKEY *
446                                 (*d2i_x509_pubkey)(X509_PUBKEY **a,
447                                                    const unsigned char **in,
448                                                    long len))
449 {
450     X509_PUBKEY *xpk, *xpk2 = NULL, **pxpk = NULL;
451     EVP_PKEY *pktmp = NULL;
452     const unsigned char *q;
453
454     q = *pp;
455
456     /*
457      * If libctx or propq are non-NULL, we take advantage of the reuse
458      * feature.  It's not generally recommended, but is safe enough for
459      * newly created structures.
460      */
461     if (libctx != NULL || propq != NULL || force_legacy) {
462         xpk2 = OPENSSL_zalloc(sizeof(*xpk2));
463         if (xpk2 == NULL) {
464             ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
465             return NULL;
466         }
467         if (!x509_pubkey_set0_libctx(xpk2, libctx, propq))
468             goto end;
469         xpk2->flag_force_legacy = !!force_legacy;
470         pxpk = &xpk2;
471     }
472     xpk = d2i_x509_pubkey(pxpk, &q, length);
473     if (xpk == NULL)
474         goto end;
475     pktmp = X509_PUBKEY_get(xpk);
476     X509_PUBKEY_free(xpk);
477     xpk2 = NULL;                 /* We know that xpk == xpk2 */
478     if (pktmp == NULL)
479         goto end;
480     *pp = q;
481     if (a != NULL) {
482         EVP_PKEY_free(*a);
483         *a = pktmp;
484     }
485  end:
486     X509_PUBKEY_free(xpk2);
487     return pktmp;
488 }
489
490 /* For the algorithm specific d2i functions further down */
491 static EVP_PKEY *d2i_PUBKEY_legacy(EVP_PKEY **a,
492                                    const unsigned char **pp, long length)
493 {
494     return d2i_PUBKEY_int(a, pp, length, NULL, NULL, 1, d2i_X509_PUBKEY);
495 }
496
497 EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length,
498                         OSSL_LIB_CTX *libctx, const char *propq)
499 {
500     return d2i_PUBKEY_int(a, pp, length, libctx, propq, 0, d2i_X509_PUBKEY);
501 }
502
503 EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
504 {
505     return d2i_PUBKEY_ex(a, pp, length, NULL, NULL);
506 }
507
508 int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
509 {
510     int ret = -1;
511
512     if (a == NULL)
513         return 0;
514     if (a->ameth != NULL) {
515         X509_PUBKEY *xpk = NULL;
516
517         if ((xpk = X509_PUBKEY_new()) == NULL)
518             return -1;
519
520         /* pub_encode() only encode parameters, not the key itself */
521         if (a->ameth->pub_encode != NULL && a->ameth->pub_encode(xpk, a)) {
522             xpk->pkey = (EVP_PKEY *)a;
523             ret = i2d_X509_PUBKEY(xpk, pp);
524             xpk->pkey = NULL;
525         }
526         X509_PUBKEY_free(xpk);
527     } else if (a->keymgmt != NULL) {
528         OSSL_ENCODER_CTX *ctx =
529             OSSL_ENCODER_CTX_new_for_pkey(a, EVP_PKEY_PUBLIC_KEY,
530                                           "DER", "SubjectPublicKeyInfo",
531                                           NULL);
532         BIO *out = BIO_new(BIO_s_mem());
533         BUF_MEM *buf = NULL;
534
535         if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0
536             && out != NULL
537             && OSSL_ENCODER_to_bio(ctx, out)
538             && BIO_get_mem_ptr(out, &buf) > 0) {
539             ret = buf->length;
540
541             if (pp != NULL) {
542                 if (*pp == NULL) {
543                     *pp = (unsigned char *)buf->data;
544                     buf->length = 0;
545                     buf->data = NULL;
546                 } else {
547                     memcpy(*pp, buf->data, ret);
548                     *pp += ret;
549                 }
550             }
551         }
552         BIO_free(out);
553         OSSL_ENCODER_CTX_free(ctx);
554     }
555
556     return ret;
557 }
558
559 /*
560  * The following are equivalents but which return RSA and DSA keys
561  */
562 RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
563 {
564     EVP_PKEY *pkey;
565     RSA *key = NULL;
566     const unsigned char *q;
567
568     q = *pp;
569     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
570     if (pkey == NULL)
571         return NULL;
572     key = EVP_PKEY_get1_RSA(pkey);
573     EVP_PKEY_free(pkey);
574     if (key == NULL)
575         return NULL;
576     *pp = q;
577     if (a != NULL) {
578         RSA_free(*a);
579         *a = key;
580     }
581     return key;
582 }
583
584 int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
585 {
586     EVP_PKEY *pktmp;
587     int ret;
588     if (!a)
589         return 0;
590     pktmp = EVP_PKEY_new();
591     if (pktmp == NULL) {
592         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
593         return -1;
594     }
595     (void)EVP_PKEY_assign_RSA(pktmp, (RSA *)a);
596     ret = i2d_PUBKEY(pktmp, pp);
597     pktmp->pkey.ptr = NULL;
598     EVP_PKEY_free(pktmp);
599     return ret;
600 }
601
602 #ifndef OPENSSL_NO_DH
603 DH *ossl_d2i_DH_PUBKEY(DH **a, const unsigned char **pp, long length)
604 {
605     EVP_PKEY *pkey;
606     DH *key = NULL;
607     const unsigned char *q;
608
609     q = *pp;
610     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
611     if (pkey == NULL)
612         return NULL;
613     if (EVP_PKEY_get_id(pkey) == EVP_PKEY_DH)
614         key = EVP_PKEY_get1_DH(pkey);
615     EVP_PKEY_free(pkey);
616     if (key == NULL)
617         return NULL;
618     *pp = q;
619     if (a != NULL) {
620         DH_free(*a);
621         *a = key;
622     }
623     return key;
624 }
625
626 int ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp)
627 {
628     EVP_PKEY *pktmp;
629     int ret;
630     if (!a)
631         return 0;
632     pktmp = EVP_PKEY_new();
633     if (pktmp == NULL) {
634         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
635         return -1;
636     }
637     (void)EVP_PKEY_assign_DH(pktmp, (DH *)a);
638     ret = i2d_PUBKEY(pktmp, pp);
639     pktmp->pkey.ptr = NULL;
640     EVP_PKEY_free(pktmp);
641     return ret;
642 }
643
644 DH *ossl_d2i_DHx_PUBKEY(DH **a, const unsigned char **pp, long length)
645 {
646     EVP_PKEY *pkey;
647     DH *key = NULL;
648     const unsigned char *q;
649
650     q = *pp;
651     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
652     if (pkey == NULL)
653         return NULL;
654     if (EVP_PKEY_get_id(pkey) == EVP_PKEY_DHX)
655         key = EVP_PKEY_get1_DH(pkey);
656     EVP_PKEY_free(pkey);
657     if (key == NULL)
658         return NULL;
659     *pp = q;
660     if (a != NULL) {
661         DH_free(*a);
662         *a = key;
663     }
664     return key;
665 }
666
667 int ossl_i2d_DHx_PUBKEY(const DH *a, unsigned char **pp)
668 {
669     EVP_PKEY *pktmp;
670     int ret;
671     if (!a)
672         return 0;
673     pktmp = EVP_PKEY_new();
674     if (pktmp == NULL) {
675         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
676         return -1;
677     }
678     (void)EVP_PKEY_assign(pktmp, EVP_PKEY_DHX, (DH *)a);
679     ret = i2d_PUBKEY(pktmp, pp);
680     pktmp->pkey.ptr = NULL;
681     EVP_PKEY_free(pktmp);
682     return ret;
683 }
684 #endif
685
686 #ifndef OPENSSL_NO_DSA
687 DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
688 {
689     EVP_PKEY *pkey;
690     DSA *key = NULL;
691     const unsigned char *q;
692
693     q = *pp;
694     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
695     if (pkey == NULL)
696         return NULL;
697     key = EVP_PKEY_get1_DSA(pkey);
698     EVP_PKEY_free(pkey);
699     if (key == NULL)
700         return NULL;
701     *pp = q;
702     if (a != NULL) {
703         DSA_free(*a);
704         *a = key;
705     }
706     return key;
707 }
708
709 int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
710 {
711     EVP_PKEY *pktmp;
712     int ret;
713     if (!a)
714         return 0;
715     pktmp = EVP_PKEY_new();
716     if (pktmp == NULL) {
717         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
718         return -1;
719     }
720     (void)EVP_PKEY_assign_DSA(pktmp, (DSA *)a);
721     ret = i2d_PUBKEY(pktmp, pp);
722     pktmp->pkey.ptr = NULL;
723     EVP_PKEY_free(pktmp);
724     return ret;
725 }
726 #endif
727
728 #ifndef OPENSSL_NO_EC
729 EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
730 {
731     EVP_PKEY *pkey;
732     EC_KEY *key = NULL;
733     const unsigned char *q;
734     int type;
735
736     q = *pp;
737     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
738     if (pkey == NULL)
739         return NULL;
740     type = EVP_PKEY_get_id(pkey);
741     if (type == EVP_PKEY_EC || type == EVP_PKEY_SM2)
742         key = EVP_PKEY_get1_EC_KEY(pkey);
743     EVP_PKEY_free(pkey);
744     if (key == NULL)
745         return NULL;
746     *pp = q;
747     if (a != NULL) {
748         EC_KEY_free(*a);
749         *a = key;
750     }
751     return key;
752 }
753
754 int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
755 {
756     EVP_PKEY *pktmp;
757     int ret;
758
759     if (a == NULL)
760         return 0;
761     if ((pktmp = EVP_PKEY_new()) == NULL) {
762         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
763         return -1;
764     }
765     (void)EVP_PKEY_assign_EC_KEY(pktmp, (EC_KEY *)a);
766     ret = i2d_PUBKEY(pktmp, pp);
767     pktmp->pkey.ptr = NULL;
768     EVP_PKEY_free(pktmp);
769     return ret;
770 }
771
772 ECX_KEY *ossl_d2i_ED25519_PUBKEY(ECX_KEY **a,
773                                  const unsigned char **pp, long length)
774 {
775     EVP_PKEY *pkey;
776     ECX_KEY *key = NULL;
777     const unsigned char *q;
778
779     q = *pp;
780     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
781     if (pkey == NULL)
782         return NULL;
783     key = ossl_evp_pkey_get1_ED25519(pkey);
784     EVP_PKEY_free(pkey);
785     if (key == NULL)
786         return NULL;
787     *pp = q;
788     if (a != NULL) {
789         ossl_ecx_key_free(*a);
790         *a = key;
791     }
792     return key;
793 }
794
795 int ossl_i2d_ED25519_PUBKEY(const ECX_KEY *a, unsigned char **pp)
796 {
797     EVP_PKEY *pktmp;
798     int ret;
799
800     if (a == NULL)
801         return 0;
802     if ((pktmp = EVP_PKEY_new()) == NULL) {
803         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
804         return -1;
805     }
806     (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED25519, (ECX_KEY *)a);
807     ret = i2d_PUBKEY(pktmp, pp);
808     pktmp->pkey.ptr = NULL;
809     EVP_PKEY_free(pktmp);
810     return ret;
811 }
812
813 ECX_KEY *ossl_d2i_ED448_PUBKEY(ECX_KEY **a,
814                                const unsigned char **pp, long length)
815 {
816     EVP_PKEY *pkey;
817     ECX_KEY *key = NULL;
818     const unsigned char *q;
819
820     q = *pp;
821     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
822     if (pkey == NULL)
823         return NULL;
824     if (EVP_PKEY_get_id(pkey) == EVP_PKEY_ED448)
825         key = ossl_evp_pkey_get1_ED448(pkey);
826     EVP_PKEY_free(pkey);
827     if (key == NULL)
828         return NULL;
829     *pp = q;
830     if (a != NULL) {
831         ossl_ecx_key_free(*a);
832         *a = key;
833     }
834     return key;
835 }
836
837 int ossl_i2d_ED448_PUBKEY(const ECX_KEY *a, unsigned char **pp)
838 {
839     EVP_PKEY *pktmp;
840     int ret;
841
842     if (a == NULL)
843         return 0;
844     if ((pktmp = EVP_PKEY_new()) == NULL) {
845         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
846         return -1;
847     }
848     (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED448, (ECX_KEY *)a);
849     ret = i2d_PUBKEY(pktmp, pp);
850     pktmp->pkey.ptr = NULL;
851     EVP_PKEY_free(pktmp);
852     return ret;
853 }
854
855 ECX_KEY *ossl_d2i_X25519_PUBKEY(ECX_KEY **a,
856                                 const unsigned char **pp, long length)
857 {
858     EVP_PKEY *pkey;
859     ECX_KEY *key = NULL;
860     const unsigned char *q;
861
862     q = *pp;
863     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
864     if (pkey == NULL)
865         return NULL;
866     if (EVP_PKEY_get_id(pkey) == EVP_PKEY_X25519)
867         key = ossl_evp_pkey_get1_X25519(pkey);
868     EVP_PKEY_free(pkey);
869     if (key == NULL)
870         return NULL;
871     *pp = q;
872     if (a != NULL) {
873         ossl_ecx_key_free(*a);
874         *a = key;
875     }
876     return key;
877 }
878
879 int ossl_i2d_X25519_PUBKEY(const ECX_KEY *a, unsigned char **pp)
880 {
881     EVP_PKEY *pktmp;
882     int ret;
883
884     if (a == NULL)
885         return 0;
886     if ((pktmp = EVP_PKEY_new()) == NULL) {
887         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
888         return -1;
889     }
890     (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X25519, (ECX_KEY *)a);
891     ret = i2d_PUBKEY(pktmp, pp);
892     pktmp->pkey.ptr = NULL;
893     EVP_PKEY_free(pktmp);
894     return ret;
895 }
896
897 ECX_KEY *ossl_d2i_X448_PUBKEY(ECX_KEY **a,
898                               const unsigned char **pp, long length)
899 {
900     EVP_PKEY *pkey;
901     ECX_KEY *key = NULL;
902     const unsigned char *q;
903
904     q = *pp;
905     pkey = d2i_PUBKEY_legacy(NULL, &q, length);
906     if (pkey == NULL)
907         return NULL;
908     if (EVP_PKEY_get_id(pkey) == EVP_PKEY_X448)
909         key = ossl_evp_pkey_get1_X448(pkey);
910     EVP_PKEY_free(pkey);
911     if (key == NULL)
912         return NULL;
913     *pp = q;
914     if (a != NULL) {
915         ossl_ecx_key_free(*a);
916         *a = key;
917     }
918     return key;
919 }
920
921 int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp)
922 {
923     EVP_PKEY *pktmp;
924     int ret;
925
926     if (a == NULL)
927         return 0;
928     if ((pktmp = EVP_PKEY_new()) == NULL) {
929         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
930         return -1;
931     }
932     (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X448, (ECX_KEY *)a);
933     ret = i2d_PUBKEY(pktmp, pp);
934     pktmp->pkey.ptr = NULL;
935     EVP_PKEY_free(pktmp);
936     return ret;
937 }
938
939 #endif
940
941 int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
942                            int ptype, void *pval,
943                            unsigned char *penc, int penclen)
944 {
945     if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
946         return 0;
947     if (penc) {
948         OPENSSL_free(pub->public_key->data);
949         pub->public_key->data = penc;
950         pub->public_key->length = penclen;
951         /* Set number of unused bits to zero */
952         pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
953         pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
954     }
955     return 1;
956 }
957
958 int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
959                            const unsigned char **pk, int *ppklen,
960                            X509_ALGOR **pa, const X509_PUBKEY *pub)
961 {
962     if (ppkalg)
963         *ppkalg = pub->algor->algorithm;
964     if (pk) {
965         *pk = pub->public_key->data;
966         *ppklen = pub->public_key->length;
967     }
968     if (pa)
969         *pa = pub->algor;
970     return 1;
971 }
972
973 ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
974 {
975     if (x == NULL)
976         return NULL;
977     return x->cert_info.key->public_key;
978 }
979
980 /* Returns 1 for equal, 0, for non-equal, < 0 on error */
981 int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b)
982 {
983     X509_ALGOR *algA, *algB;
984     EVP_PKEY *pA, *pB;
985
986     if (a == b)
987         return 1;
988     if (a == NULL || b == NULL)
989         return 0;
990     if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a) || algA == NULL
991         || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b) || algB == NULL)
992         return -2;
993     if (X509_ALGOR_cmp(algA, algB) != 0)
994         return 0;
995     if ((pA = X509_PUBKEY_get0(a)) == NULL
996         || (pB = X509_PUBKEY_get0(b)) == NULL)
997         return -2;
998     return EVP_PKEY_eq(pA, pB);
999 }
1000
1001 int ossl_x509_PUBKEY_get0_libctx(OSSL_LIB_CTX **plibctx, const char **ppropq,
1002                                  const X509_PUBKEY *key)
1003 {
1004     if (plibctx)
1005         *plibctx = key->libctx;
1006     if (ppropq)
1007         *ppropq = key->propq;
1008     return 1;
1009 }