1/*
2 * Copyright 1995-2018 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#include <stdio.h>
11#include "internal/cryptlib.h"
12#include <openssl/asn1t.h>
13#include <openssl/x509.h>
14#include "crypto/asn1.h"
15#include "crypto/evp.h"
16#include "crypto/x509.h"
17#include <openssl/rsa.h>
18#include <openssl/dsa.h>
19
20struct X509_pubkey_st {
21 X509_ALGOR *algor;
22 ASN1_BIT_STRING *public_key;
23 EVP_PKEY *pkey;
24};
25
26static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key);
27
28/* Minor tweak to operation: free up EVP_PKEY */
29static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
30 void *exarg)
31{
32 if (operation == ASN1_OP_FREE_POST) {
33 X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
34 EVP_PKEY_free(pubkey->pkey);
35 } else if (operation == ASN1_OP_D2I_POST) {
36 /* Attempt to decode public key and cache in pubkey structure. */
37 X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
38 EVP_PKEY_free(pubkey->pkey);
39 pubkey->pkey = NULL;
40 /*
41 * Opportunistically decode the key but remove any non fatal errors
42 * from the queue. Subsequent explicit attempts to decode/use the key
43 * will return an appropriate error.
44 */
45 ERR_set_mark();
46 if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1)
47 return 0;
48 ERR_pop_to_mark();
49 }
50 return 1;
51}
52
53ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
54 ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
55 ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
56} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
57
58IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
59IMPLEMENT_ASN1_DUP_FUNCTION(X509_PUBKEY)
60
61/* TODO should better be called X509_PUBKEY_set1 */
62int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
63{
64 X509_PUBKEY *pk = NULL;
65
66 if (x == NULL)
67 return 0;
68
69 if ((pk = X509_PUBKEY_new()) == NULL)
70 goto error;
71
72 if (pkey != NULL && pkey->ameth) {
73 if (pkey->ameth->pub_encode) {
74 if (!pkey->ameth->pub_encode(pk, pkey)) {
75 X509err(X509_F_X509_PUBKEY_SET,
76 X509_R_PUBLIC_KEY_ENCODE_ERROR);
77 goto error;
78 }
79 } else {
80 X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
81 goto error;
82 }
83 } else {
84 X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
85 goto error;
86 }
87
88 X509_PUBKEY_free(*x);
89 *x = pk;
90 pk->pkey = pkey;
91 return EVP_PKEY_up_ref(pkey);
92
93 error:
94 X509_PUBKEY_free(pk);
95 return 0;
96}
97
98/*
99 * Attempt to decode a public key.
100 * Returns 1 on success, 0 for a decode failure and -1 for a fatal
101 * error e.g. malloc failure.
102 */
103
104
105static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key)
106{
107 EVP_PKEY *pkey = EVP_PKEY_new();
108
109 if (pkey == NULL) {
110 X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
111 return -1;
112 }
113
114 if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
115 X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM);
116 goto error;
117 }
118
119 if (pkey->ameth->pub_decode) {
120 /*
121 * Treat any failure of pub_decode as a decode error. In
122 * future we could have different return codes for decode
123 * errors and fatal errors such as malloc failure.
124 */
125 if (!pkey->ameth->pub_decode(pkey, key)) {
126 X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR);
127 goto error;
128 }
129 } else {
130 X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED);
131 goto error;
132 }
133
134 *ppkey = pkey;
135 return 1;
136
137 error:
138 EVP_PKEY_free(pkey);
139 return 0;
140}
141
142EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key)
143{
144 EVP_PKEY *ret = NULL;
145
146 if (key == NULL || key->public_key == NULL)
147 return NULL;
148
149 if (key->pkey != NULL)
150 return key->pkey;
151
152 /*
153 * When the key ASN.1 is initially parsed an attempt is made to
154 * decode the public key and cache the EVP_PKEY structure. If this
155 * operation fails the cached value will be NULL. Parsing continues
156 * to allow parsing of unknown key types or unsupported forms.
157 * We repeat the decode operation so the appropriate errors are left
158 * in the queue.
159 */
160 x509_pubkey_decode(&ret, key);
161 /* If decode doesn't fail something bad happened */
162 if (ret != NULL) {
163 X509err(X509_F_X509_PUBKEY_GET0, ERR_R_INTERNAL_ERROR);
164 EVP_PKEY_free(ret);
165 }
166
167 return NULL;
168}
169
170EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
171{
172 EVP_PKEY *ret = X509_PUBKEY_get0(key);
173 if (ret != NULL)
174 EVP_PKEY_up_ref(ret);
175 return ret;
176}
177
178/*
179 * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
180 * decode as X509_PUBKEY
181 */
182
183EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
184{
185 X509_PUBKEY *xpk;
186 EVP_PKEY *pktmp;
187 const unsigned char *q;
188
189 q = *pp;
190 xpk = d2i_X509_PUBKEY(NULL, &q, length);
191 if (xpk == NULL)
192 return NULL;
193 pktmp = X509_PUBKEY_get(xpk);
194 X509_PUBKEY_free(xpk);
195 if (pktmp == NULL)
196 return NULL;
197 *pp = q;
198 if (a != NULL) {
199 EVP_PKEY_free(*a);
200 *a = pktmp;
201 }
202 return pktmp;
203}
204
205int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
206{
207 X509_PUBKEY *xpk = NULL;
208 int ret = -1;
209
210 if (a == NULL)
211 return 0;
212 if ((xpk = X509_PUBKEY_new()) == NULL)
213 return -1;
214 if (a->ameth != NULL && a->ameth->pub_encode != NULL
215 && !a->ameth->pub_encode(xpk, a))
216 goto error;
217 xpk->pkey = (EVP_PKEY *)a;
218 ret = i2d_X509_PUBKEY(xpk, pp);
219 xpk->pkey = NULL;
220 error:
221 X509_PUBKEY_free(xpk);
222 return ret;
223}
224
225/*
226 * The following are equivalents but which return RSA and DSA keys
227 */
228#ifndef OPENSSL_NO_RSA
229RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
230{
231 EVP_PKEY *pkey;
232 RSA *key;
233 const unsigned char *q;
234
235 q = *pp;
236 pkey = d2i_PUBKEY(NULL, &q, length);
237 if (pkey == NULL)
238 return NULL;
239 key = EVP_PKEY_get1_RSA(pkey);
240 EVP_PKEY_free(pkey);
241 if (key == NULL)
242 return NULL;
243 *pp = q;
244 if (a != NULL) {
245 RSA_free(*a);
246 *a = key;
247 }
248 return key;
249}
250
251int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
252{
253 EVP_PKEY *pktmp;
254 int ret;
255 if (!a)
256 return 0;
257 pktmp = EVP_PKEY_new();
258 if (pktmp == NULL) {
259 ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
260 return -1;
261 }
262 (void)EVP_PKEY_assign_RSA(pktmp, (RSA *)a);
263 ret = i2d_PUBKEY(pktmp, pp);
264 pktmp->pkey.ptr = NULL;
265 EVP_PKEY_free(pktmp);
266 return ret;
267}
268#endif
269
270#ifndef OPENSSL_NO_DSA
271DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
272{
273 EVP_PKEY *pkey;
274 DSA *key;
275 const unsigned char *q;
276
277 q = *pp;
278 pkey = d2i_PUBKEY(NULL, &q, length);
279 if (pkey == NULL)
280 return NULL;
281 key = EVP_PKEY_get1_DSA(pkey);
282 EVP_PKEY_free(pkey);
283 if (key == NULL)
284 return NULL;
285 *pp = q;
286 if (a != NULL) {
287 DSA_free(*a);
288 *a = key;
289 }
290 return key;
291}
292
293int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
294{
295 EVP_PKEY *pktmp;
296 int ret;
297 if (!a)
298 return 0;
299 pktmp = EVP_PKEY_new();
300 if (pktmp == NULL) {
301 ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
302 return -1;
303 }
304 (void)EVP_PKEY_assign_DSA(pktmp, (DSA *)a);
305 ret = i2d_PUBKEY(pktmp, pp);
306 pktmp->pkey.ptr = NULL;
307 EVP_PKEY_free(pktmp);
308 return ret;
309}
310#endif
311
312#ifndef OPENSSL_NO_EC
313EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
314{
315 EVP_PKEY *pkey;
316 EC_KEY *key;
317 const unsigned char *q;
318
319 q = *pp;
320 pkey = d2i_PUBKEY(NULL, &q, length);
321 if (pkey == NULL)
322 return NULL;
323 key = EVP_PKEY_get1_EC_KEY(pkey);
324 EVP_PKEY_free(pkey);
325 if (key == NULL)
326 return NULL;
327 *pp = q;
328 if (a != NULL) {
329 EC_KEY_free(*a);
330 *a = key;
331 }
332 return key;
333}
334
335int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
336{
337 EVP_PKEY *pktmp;
338 int ret;
339
340 if (a == NULL)
341 return 0;
342 if ((pktmp = EVP_PKEY_new()) == NULL) {
343 ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
344 return -1;
345 }
346 (void)EVP_PKEY_assign_EC_KEY(pktmp, (EC_KEY *)a);
347 ret = i2d_PUBKEY(pktmp, pp);
348 pktmp->pkey.ptr = NULL;
349 EVP_PKEY_free(pktmp);
350 return ret;
351}
352#endif
353
354int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
355 int ptype, void *pval,
356 unsigned char *penc, int penclen)
357{
358 if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
359 return 0;
360 if (penc) {
361 OPENSSL_free(pub->public_key->data);
362 pub->public_key->data = penc;
363 pub->public_key->length = penclen;
364 /* Set number of unused bits to zero */
365 pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
366 pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
367 }
368 return 1;
369}
370
371int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
372 const unsigned char **pk, int *ppklen,
373 X509_ALGOR **pa, X509_PUBKEY *pub)
374{
375 if (ppkalg)
376 *ppkalg = pub->algor->algorithm;
377 if (pk) {
378 *pk = pub->public_key->data;
379 *ppklen = pub->public_key->length;
380 }
381 if (pa)
382 *pa = pub->algor;
383 return 1;
384}
385
386ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
387{
388 if (x == NULL)
389 return NULL;
390 return x->cert_info.key->public_key;
391}
392