Coverage Report

Created: 2018-08-29 13:53

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