]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/pem/pvkfmt.c
PROV: Add type specific MSBLOB and PVK decoding for the MS->key decoders
[thirdparty/openssl.git] / crypto / pem / pvkfmt.c
CommitLineData
0f113f3e 1/*
8020d79b 2 * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved.
a0156a92 3 *
16742672 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
62867571
RS
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
a0156a92
DSH
8 */
9
0f113f3e
MC
10/*
11 * Support for PVK format keys and related structures (such a PUBLICKEYBLOB
a0156a92
DSH
12 * and PRIVATEKEYBLOB).
13 */
14
f41ac0ee 15/*
a158f8cf 16 * RSA and DSA low level APIs are deprecated for public use, but still ok for
f41ac0ee
P
17 * internal use.
18 */
19#include "internal/deprecated.h"
20
a0156a92
DSH
21#include <openssl/pem.h>
22#include <openssl/rand.h>
1e26a8ba 23#include <openssl/bn.h>
a158f8cf
RL
24#include <openssl/dsa.h>
25#include <openssl/rsa.h>
e77c13f8
RL
26#include "internal/cryptlib.h"
27#include "crypto/pem.h"
28#include "crypto/evp.h"
a0156a92 29
0f113f3e
MC
30/*
31 * Utility function: read a DWORD (4 byte unsigned integer) in little endian
a0156a92
DSH
32 * format
33 */
34
35static unsigned int read_ledword(const unsigned char **in)
0f113f3e
MC
36{
37 const unsigned char *p = *in;
38 unsigned int ret;
a158f8cf 39
cbeb0bfa
TM
40 ret = (unsigned int)*p++;
41 ret |= (unsigned int)*p++ << 8;
42 ret |= (unsigned int)*p++ << 16;
43 ret |= (unsigned int)*p++ << 24;
0f113f3e
MC
44 *in = p;
45 return ret;
46}
47
48/*
49 * Read a BIGNUM in little endian format. The docs say that this should take
50 * up bitlen/8 bytes.
a0156a92
DSH
51 */
52
53static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
0f113f3e 54{
85a4807f
DSH
55 *r = BN_lebin2bn(*in, nbyte, NULL);
56 if (*r == NULL)
0f113f3e 57 return 0;
85a4807f
DSH
58 *in += nbyte;
59 return 1;
0f113f3e 60}
a0156a92 61
f4e46b81
RL
62/*
63 * Create an EVP_PKEY from a type specific key.
64 * This takes ownership of |key|, as long as the |evp_type| is acceptable
65 * (EVP_PKEY_RSA or EVP_PKEY_DSA), even if the resulting EVP_PKEY wasn't
66 * created.
67 */
68#define isdss_to_evp_type(isdss) \
69 (isdss == 0 ? EVP_PKEY_RSA : isdss == 1 ? EVP_PKEY_DSA : EVP_PKEY_NONE)
70static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type)
71{
72 EVP_PKEY *pkey = NULL;
73
74 /*
75 * It's assumed that if |key| is NULL, something went wrong elsewhere
76 * and suitable errors are already reported.
77 */
78 if (key == NULL)
79 return NULL;
80
81 if (!ossl_assert(evp_type == EVP_PKEY_RSA || evp_type == EVP_PKEY_DSA)) {
82 ERR_raise(ERR_LIB_PEM, ERR_R_INTERNAL_ERROR);
83 return NULL;
84 }
85
86 if ((pkey = EVP_PKEY_new()) != NULL) {
87 switch (evp_type) {
88 case EVP_PKEY_RSA:
89 if (EVP_PKEY_set1_RSA(pkey, key))
90 break;
91 EVP_PKEY_free(pkey);
92 pkey = NULL;
93 break;
94#ifndef OPENSSL_NO_DSA
95 case EVP_PKEY_DSA:
96 if (EVP_PKEY_set1_DSA(pkey, key))
97 break;
98 EVP_PKEY_free(pkey);
99 pkey = NULL;
100 break;
101#endif
102 }
103 }
104
105 switch (evp_type) {
106 case EVP_PKEY_RSA:
107 RSA_free(key);
108 break;
109#ifndef OPENSSL_NO_DSA
110 case EVP_PKEY_DSA:
111 DSA_free(key);
112 break;
113#endif
114 }
115
116 if (pkey == NULL)
117 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
118 return pkey;
119}
120
a0156a92
DSH
121/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
122
0f113f3e
MC
123# define MS_PUBLICKEYBLOB 0x6
124# define MS_PRIVATEKEYBLOB 0x7
125# define MS_RSA1MAGIC 0x31415352L
126# define MS_RSA2MAGIC 0x32415352L
127# define MS_DSS1MAGIC 0x31535344L
128# define MS_DSS2MAGIC 0x32535344L
a0156a92 129
0f113f3e
MC
130# define MS_KEYALG_RSA_KEYX 0xa400
131# define MS_KEYALG_DSS_SIGN 0x2200
a0156a92 132
0f113f3e
MC
133# define MS_KEYTYPE_KEYX 0x1
134# define MS_KEYTYPE_SIGN 0x2
a0156a92
DSH
135
136/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
0f113f3e 137# define MS_PVKMAGIC 0xb0b5f11eL
a0156a92 138/* Salt length for PVK files */
0f113f3e 139# define PVK_SALTLEN 0x10
5f57abe2
DSH
140/* Maximum length in PVK header */
141# define PVK_MAX_KEYLEN 102400
142/* Maximum salt length */
143# define PVK_MAX_SALTLEN 10240
a0156a92 144
f4e46b81
RL
145/*
146 * Read the MSBLOB header and get relevant data from it.
147 *
148 * |pisdss| and |pispub| have a double role, as they can be used for
149 * discovery as well as to check the the blob meets expectations.
150 * |*pisdss| is the indicator for whether the key is a DSA key or not.
151 * |*pispub| is the indicator for whether the key is public or not.
152 * In both cases, the following input values apply:
153 *
154 * 0 Expected to not be what the variable indicates.
155 * 1 Expected to be what the variable indicates.
156 * -1 No expectations, this function will assign 0 or 1 depending on
157 * header data.
158 */
f55838f3
RL
159int ossl_do_blob_header(const unsigned char **in, unsigned int length,
160 unsigned int *pmagic, unsigned int *pbitlen,
161 int *pisdss, int *pispub)
0f113f3e
MC
162{
163 const unsigned char *p = *in;
a158f8cf 164
0f113f3e
MC
165 if (length < 16)
166 return 0;
167 /* bType */
f4e46b81
RL
168 switch (*p) {
169 case MS_PUBLICKEYBLOB:
0f113f3e 170 if (*pispub == 0) {
9311d0c4 171 ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
0f113f3e
MC
172 return 0;
173 }
174 *pispub = 1;
f4e46b81
RL
175 break;
176
177 case MS_PRIVATEKEYBLOB:
0f113f3e 178 if (*pispub == 1) {
9311d0c4 179 ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
0f113f3e
MC
180 return 0;
181 }
182 *pispub = 0;
f4e46b81
RL
183 break;
184
185 default:
0f113f3e 186 return 0;
a158f8cf 187 }
0f113f3e
MC
188 p++;
189 /* Version */
190 if (*p++ != 0x2) {
9311d0c4 191 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_VERSION_NUMBER);
0f113f3e
MC
192 return 0;
193 }
194 /* Ignore reserved, aiKeyAlg */
195 p += 6;
196 *pmagic = read_ledword(&p);
197 *pbitlen = read_ledword(&p);
0f113f3e 198
f4e46b81
RL
199 /* Consistency check for private vs public */
200 switch (*pmagic) {
0f113f3e 201 case MS_DSS1MAGIC:
0f113f3e
MC
202 case MS_RSA1MAGIC:
203 if (*pispub == 0) {
9311d0c4 204 ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
0f113f3e
MC
205 return 0;
206 }
207 break;
208
209 case MS_DSS2MAGIC:
0f113f3e
MC
210 case MS_RSA2MAGIC:
211 if (*pispub == 1) {
9311d0c4 212 ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
0f113f3e
MC
213 return 0;
214 }
215 break;
216
f4e46b81
RL
217 default:
218 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER);
219 return -1;
220 }
221
222 /* Check that we got the expected type */
223 switch (*pmagic) {
224 case MS_DSS1MAGIC:
225 case MS_DSS2MAGIC:
226 if (*pisdss == 0) {
227 ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_DSS_KEY_BLOB);
228 return 0;
229 }
230 *pisdss = 1;
231 break;
232 case MS_RSA1MAGIC:
233 case MS_RSA2MAGIC:
234 if (*pisdss == 1) {
235 ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_RSA_KEY_BLOB);
236 return 0;
237 }
238 *pisdss = 0;
239 break;
240
0f113f3e 241 default:
9311d0c4 242 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER);
0f113f3e
MC
243 return -1;
244 }
245 *in = p;
246 return 1;
247}
a0156a92 248
f4e46b81 249unsigned int ossl_blob_length(unsigned bitlen, int isdss, int ispub)
0f113f3e 250{
a158f8cf
RL
251 unsigned int nbyte = (bitlen + 7) >> 3;
252 unsigned int hnbyte = (bitlen + 15) >> 4;
253
0f113f3e
MC
254 if (isdss) {
255
256 /*
257 * Expected length: 20 for q + 3 components bitlen each + 24 for seed
258 * structure.
259 */
260 if (ispub)
261 return 44 + 3 * nbyte;
262 /*
263 * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed
264 * structure.
265 */
266 else
267 return 64 + 2 * nbyte;
268 } else {
269 /* Expected length: 4 for 'e' + 'n' */
270 if (ispub)
271 return 4 + nbyte;
272 else
273 /*
274 * Expected length: 4 for 'e' and 7 other components. 2
275 * components are bitlen size, 5 are bitlen/2
276 */
277 return 4 + 2 * nbyte + 5 * hnbyte;
278 }
279
280}
a0156a92 281
f4e46b81
RL
282static void *do_b2i_key(const unsigned char **in, unsigned int length,
283 int *isdss, int *ispub)
0f113f3e
MC
284{
285 const unsigned char *p = *in;
286 unsigned int bitlen, magic;
f4e46b81 287 void *key = NULL;
a158f8cf 288
f4e46b81 289 if (ossl_do_blob_header(&p, length, &magic, &bitlen, isdss, ispub) <= 0) {
9311d0c4 290 ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
0f113f3e
MC
291 return NULL;
292 }
293 length -= 16;
f4e46b81 294 if (length < ossl_blob_length(bitlen, *isdss, *ispub)) {
9311d0c4 295 ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT);
0f113f3e
MC
296 return NULL;
297 }
f4e46b81
RL
298 if (!*isdss)
299 key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub);
a158f8cf
RL
300#ifndef OPENSSL_NO_DSA
301 else
f4e46b81 302 key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub);
a158f8cf
RL
303#endif
304
f4e46b81
RL
305 if (key == NULL) {
306 ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
307 return NULL;
308 }
309
310 return key;
311}
312
313EVP_PKEY *ossl_b2i(const unsigned char **in, unsigned int length, int *ispub)
314{
315 int isdss = -1;
316 void *key = do_b2i_key(in, length, &isdss, ispub);
317
318 return evp_pkey_new0_key(key, isdss_to_evp_type(isdss));
0f113f3e 319}
a0156a92 320
413835f5 321EVP_PKEY *ossl_b2i_bio(BIO *in, int *ispub)
0f113f3e
MC
322{
323 const unsigned char *p;
324 unsigned char hdr_buf[16], *buf = NULL;
325 unsigned int bitlen, magic, length;
326 int isdss;
f4e46b81
RL
327 void *key = NULL;
328 EVP_PKEY *pkey = NULL;
a158f8cf 329
0f113f3e 330 if (BIO_read(in, hdr_buf, 16) != 16) {
9311d0c4 331 ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT);
0f113f3e
MC
332 return NULL;
333 }
334 p = hdr_buf;
413835f5 335 if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, ispub) <= 0)
0f113f3e
MC
336 return NULL;
337
f4e46b81 338 length = ossl_blob_length(bitlen, isdss, *ispub);
66bcba14 339 if (length > BLOB_MAX_LENGTH) {
9311d0c4 340 ERR_raise(ERR_LIB_PEM, PEM_R_HEADER_TOO_LONG);
66bcba14
DSH
341 return NULL;
342 }
0f113f3e 343 buf = OPENSSL_malloc(length);
90945fa3 344 if (buf == NULL) {
9311d0c4 345 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
346 goto err;
347 }
348 p = buf;
349 if (BIO_read(in, buf, length) != (int)length) {
9311d0c4 350 ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT);
0f113f3e
MC
351 goto err;
352 }
353
a158f8cf 354 if (!isdss)
f4e46b81 355 key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub);
a158f8cf
RL
356#ifndef OPENSSL_NO_DSA
357 else
f4e46b81 358 key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub);
a158f8cf
RL
359#endif
360
f4e46b81 361 if (key == NULL) {
a158f8cf 362 ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
f4e46b81
RL
363 goto err;
364 }
0f113f3e 365
f4e46b81 366 pkey = evp_pkey_new0_key(key, isdss_to_evp_type(isdss));
0f113f3e 367 err:
b548a1f1 368 OPENSSL_free(buf);
f4e46b81 369 return pkey;
0f113f3e 370}
a0156a92 371
a158f8cf 372#ifndef OPENSSL_NO_DSA
f4e46b81
RL
373DSA *ossl_b2i_DSA_after_header(const unsigned char **in, unsigned int bitlen,
374 int ispub)
0f113f3e
MC
375{
376 const unsigned char *p = *in;
0f113f3e
MC
377 DSA *dsa = NULL;
378 BN_CTX *ctx = NULL;
1258396d
MC
379 BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL;
380 BIGNUM *pub_key = NULL;
a158f8cf 381 unsigned int nbyte = (bitlen + 7) >> 3;
0f113f3e
MC
382
383 dsa = DSA_new();
f4e46b81 384 if (dsa == NULL)
0f113f3e 385 goto memerr;
1258396d 386 if (!read_lebn(&p, nbyte, &pbn))
0f113f3e 387 goto memerr;
1258396d
MC
388
389 if (!read_lebn(&p, 20, &qbn))
0f113f3e 390 goto memerr;
1258396d
MC
391
392 if (!read_lebn(&p, nbyte, &gbn))
0f113f3e 393 goto memerr;
1258396d 394
0f113f3e 395 if (ispub) {
1258396d 396 if (!read_lebn(&p, nbyte, &pub_key))
0f113f3e
MC
397 goto memerr;
398 } else {
1258396d 399 if (!read_lebn(&p, 20, &priv_key))
0f113f3e 400 goto memerr;
1258396d 401
724339ff
CPG
402 /* Set constant time flag before public key calculation */
403 BN_set_flags(priv_key, BN_FLG_CONSTTIME);
404
0f113f3e 405 /* Calculate public key */
1258396d
MC
406 pub_key = BN_new();
407 if (pub_key == NULL)
0f113f3e 408 goto memerr;
75ebbd9a 409 if ((ctx = BN_CTX_new()) == NULL)
0f113f3e
MC
410 goto memerr;
411
1258396d 412 if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx))
0f113f3e 413 goto memerr;
1258396d 414
0f113f3e 415 BN_CTX_free(ctx);
d288d7fc 416 ctx = NULL;
0f113f3e 417 }
1258396d
MC
418 if (!DSA_set0_pqg(dsa, pbn, qbn, gbn))
419 goto memerr;
420 pbn = qbn = gbn = NULL;
421 if (!DSA_set0_key(dsa, pub_key, priv_key))
422 goto memerr;
d288d7fc 423 pub_key = priv_key = NULL;
0f113f3e 424
0f113f3e 425 *in = p;
f4e46b81 426 return dsa;
0f113f3e
MC
427
428 memerr:
9311d0c4 429 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
d6407083 430 DSA_free(dsa);
1258396d
MC
431 BN_free(pbn);
432 BN_free(qbn);
433 BN_free(gbn);
434 BN_free(pub_key);
435 BN_free(priv_key);
23a1d5e9 436 BN_CTX_free(ctx);
0f113f3e
MC
437 return NULL;
438}
a158f8cf 439#endif
a0156a92 440
f4e46b81
RL
441RSA *ossl_b2i_RSA_after_header(const unsigned char **in, unsigned int bitlen,
442 int ispub)
0f113f3e 443{
9862e9aa 444 const unsigned char *pin = *in;
9862e9aa 445 BIGNUM *e = NULL, *n = NULL, *d = NULL;
204cf940 446 BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
0f113f3e 447 RSA *rsa = NULL;
a158f8cf
RL
448 unsigned int nbyte = (bitlen + 7) >> 3;
449 unsigned int hnbyte = (bitlen + 15) >> 4;
450
0f113f3e 451 rsa = RSA_new();
f4e46b81 452 if (rsa == NULL)
0f113f3e 453 goto memerr;
9862e9aa
RL
454 e = BN_new();
455 if (e == NULL)
0f113f3e 456 goto memerr;
9862e9aa 457 if (!BN_set_word(e, read_ledword(&pin)))
0f113f3e 458 goto memerr;
9862e9aa 459 if (!read_lebn(&pin, nbyte, &n))
0f113f3e
MC
460 goto memerr;
461 if (!ispub) {
9862e9aa 462 if (!read_lebn(&pin, hnbyte, &p))
0f113f3e 463 goto memerr;
9862e9aa 464 if (!read_lebn(&pin, hnbyte, &q))
0f113f3e 465 goto memerr;
9862e9aa 466 if (!read_lebn(&pin, hnbyte, &dmp1))
0f113f3e 467 goto memerr;
9862e9aa 468 if (!read_lebn(&pin, hnbyte, &dmq1))
0f113f3e 469 goto memerr;
9862e9aa 470 if (!read_lebn(&pin, hnbyte, &iqmp))
0f113f3e 471 goto memerr;
9862e9aa 472 if (!read_lebn(&pin, nbyte, &d))
0f113f3e 473 goto memerr;
d288d7fc
BE
474 if (!RSA_set0_factors(rsa, p, q))
475 goto memerr;
476 p = q = NULL;
477 if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp))
478 goto memerr;
479 dmp1 = dmq1 = iqmp = NULL;
0f113f3e 480 }
d288d7fc
BE
481 if (!RSA_set0_key(rsa, n, e, d))
482 goto memerr;
483 n = e = d = NULL;
0f113f3e 484
9862e9aa 485 *in = pin;
f4e46b81 486 return rsa;
0f113f3e 487 memerr:
9311d0c4 488 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
204cf940
MC
489 BN_free(e);
490 BN_free(n);
491 BN_free(p);
492 BN_free(q);
493 BN_free(dmp1);
494 BN_free(dmq1);
495 BN_free(iqmp);
496 BN_free(d);
d6407083 497 RSA_free(rsa);
0f113f3e
MC
498 return NULL;
499}
a0156a92
DSH
500
501EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
0f113f3e 502{
413835f5
RL
503 int ispub = 0;
504
505 return ossl_b2i(in, length, &ispub);
0f113f3e 506}
a0156a92
DSH
507
508EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
0f113f3e 509{
413835f5
RL
510 int ispub = 1;
511
512 return ossl_b2i(in, length, &ispub);
0f113f3e 513}
a0156a92
DSH
514
515EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
0f113f3e 516{
413835f5
RL
517 int ispub = 0;
518
519 return ossl_b2i_bio(in, &ispub);
0f113f3e 520}
a0156a92
DSH
521
522EVP_PKEY *b2i_PublicKey_bio(BIO *in)
0f113f3e 523{
413835f5
RL
524 int ispub = 1;
525
526 return ossl_b2i_bio(in, &ispub);
0f113f3e 527}
a0156a92
DSH
528
529static void write_ledword(unsigned char **out, unsigned int dw)
0f113f3e
MC
530{
531 unsigned char *p = *out;
a158f8cf 532
0f113f3e
MC
533 *p++ = dw & 0xff;
534 *p++ = (dw >> 8) & 0xff;
535 *p++ = (dw >> 16) & 0xff;
536 *p++ = (dw >> 24) & 0xff;
537 *out = p;
538}
a0156a92
DSH
539
540static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
0f113f3e 541{
85a4807f
DSH
542 BN_bn2lebinpad(bn, *out, len);
543 *out += len;
0f113f3e 544}
a0156a92 545
7bc0fdd3
MC
546static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *magic);
547static void write_rsa(unsigned char **out, const RSA *rsa, int ispub);
a158f8cf
RL
548
549#ifndef OPENSSL_NO_DSA
7bc0fdd3
MC
550static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *magic);
551static void write_dsa(unsigned char **out, const DSA *dsa, int ispub);
a158f8cf 552#endif
0f113f3e 553
de0799b0 554static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub)
0f113f3e
MC
555{
556 unsigned char *p;
a158f8cf 557 unsigned int bitlen = 0, magic = 0, keyalg = 0;
e77c13f8 558 int outlen = -1, noinc = 0;
a158f8cf 559
f4e46b81 560 if (EVP_PKEY_is_a(pk, "RSA")) {
3aeb9348 561 bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic);
0f113f3e 562 keyalg = MS_KEYALG_RSA_KEYX;
a158f8cf 563#ifndef OPENSSL_NO_DSA
f4e46b81 564 } else if (EVP_PKEY_is_a(pk, "DSA")) {
a158f8cf
RL
565 bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic);
566 keyalg = MS_KEYALG_DSS_SIGN;
567#endif
568 }
e77c13f8
RL
569 if (bitlen == 0) {
570 goto end;
571 }
f4e46b81
RL
572 outlen = 16
573 + ossl_blob_length(bitlen, keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
0f113f3e 574 if (out == NULL)
e77c13f8 575 goto end;
0f113f3e
MC
576 if (*out)
577 p = *out;
578 else {
cdb10bae 579 if ((p = OPENSSL_malloc(outlen)) == NULL) {
9311d0c4 580 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
e77c13f8
RL
581 outlen = -1;
582 goto end;
cdb10bae 583 }
0f113f3e
MC
584 *out = p;
585 noinc = 1;
586 }
587 if (ispub)
588 *p++ = MS_PUBLICKEYBLOB;
589 else
590 *p++ = MS_PRIVATEKEYBLOB;
591 *p++ = 0x2;
592 *p++ = 0;
593 *p++ = 0;
594 write_ledword(&p, keyalg);
595 write_ledword(&p, magic);
596 write_ledword(&p, bitlen);
a158f8cf 597 if (keyalg == MS_KEYALG_RSA_KEYX)
3aeb9348 598 write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub);
a158f8cf
RL
599#ifndef OPENSSL_NO_DSA
600 else
601 write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub);
602#endif
0f113f3e
MC
603 if (!noinc)
604 *out += outlen;
e77c13f8 605 end:
0f113f3e
MC
606 return outlen;
607}
a0156a92 608
de0799b0 609static int do_i2b_bio(BIO *out, const EVP_PKEY *pk, int ispub)
0f113f3e
MC
610{
611 unsigned char *tmp = NULL;
612 int outlen, wrlen;
a158f8cf 613
0f113f3e
MC
614 outlen = do_i2b(&tmp, pk, ispub);
615 if (outlen < 0)
616 return -1;
617 wrlen = BIO_write(out, tmp, outlen);
618 OPENSSL_free(tmp);
619 if (wrlen == outlen)
620 return outlen;
621 return -1;
622}
a0156a92 623
7bc0fdd3 624static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *pmagic)
0f113f3e
MC
625{
626 int nbyte, hnbyte, bitlen;
2ac6115d 627 const BIGNUM *e;
9862e9aa 628
1e7c159d 629 RSA_get0_key(rsa, NULL, &e, NULL);
9862e9aa 630 if (BN_num_bits(e) > 32)
0f113f3e 631 goto badkey;
9862e9aa
RL
632 bitlen = RSA_bits(rsa);
633 nbyte = RSA_size(rsa);
634 hnbyte = (bitlen + 15) >> 4;
0f113f3e
MC
635 if (ispub) {
636 *pmagic = MS_RSA1MAGIC;
637 return bitlen;
638 } else {
2ac6115d 639 const BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1;
9862e9aa 640
0f113f3e 641 *pmagic = MS_RSA2MAGIC;
9862e9aa 642
0f113f3e
MC
643 /*
644 * For private key each component must fit within nbyte or hnbyte.
645 */
9862e9aa
RL
646 RSA_get0_key(rsa, NULL, NULL, &d);
647 if (BN_num_bytes(d) > nbyte)
0f113f3e 648 goto badkey;
9862e9aa
RL
649 RSA_get0_factors(rsa, &p, &q);
650 RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
651 if ((BN_num_bytes(iqmp) > hnbyte)
652 || (BN_num_bytes(p) > hnbyte)
653 || (BN_num_bytes(q) > hnbyte)
654 || (BN_num_bytes(dmp1) > hnbyte)
655 || (BN_num_bytes(dmq1) > hnbyte))
0f113f3e
MC
656 goto badkey;
657 }
658 return bitlen;
659 badkey:
9311d0c4 660 ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
0f113f3e
MC
661 return 0;
662}
a0156a92 663
7bc0fdd3 664static void write_rsa(unsigned char **out, const RSA *rsa, int ispub)
0f113f3e
MC
665{
666 int nbyte, hnbyte;
2ac6115d 667 const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1;
9862e9aa
RL
668
669 nbyte = RSA_size(rsa);
670 hnbyte = (RSA_bits(rsa) + 15) >> 4;
1e7c159d 671 RSA_get0_key(rsa, &n, &e, &d);
9862e9aa 672 write_lebn(out, e, 4);
159f6e7e 673 write_lebn(out, n, nbyte);
0f113f3e
MC
674 if (ispub)
675 return;
9862e9aa
RL
676 RSA_get0_factors(rsa, &p, &q);
677 RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
678 write_lebn(out, p, hnbyte);
679 write_lebn(out, q, hnbyte);
680 write_lebn(out, dmp1, hnbyte);
681 write_lebn(out, dmq1, hnbyte);
682 write_lebn(out, iqmp, hnbyte);
683 write_lebn(out, d, nbyte);
0f113f3e
MC
684}
685
a158f8cf 686#ifndef OPENSSL_NO_DSA
7bc0fdd3 687static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *pmagic)
a158f8cf
RL
688{
689 int bitlen;
690 const BIGNUM *p = NULL, *q = NULL, *g = NULL;
691 const BIGNUM *pub_key = NULL, *priv_key = NULL;
692
693 DSA_get0_pqg(dsa, &p, &q, &g);
694 DSA_get0_key(dsa, &pub_key, &priv_key);
695 bitlen = BN_num_bits(p);
696 if ((bitlen & 7) || (BN_num_bits(q) != 160)
697 || (BN_num_bits(g) > bitlen))
698 goto badkey;
699 if (ispub) {
700 if (BN_num_bits(pub_key) > bitlen)
701 goto badkey;
702 *pmagic = MS_DSS1MAGIC;
703 } else {
704 if (BN_num_bits(priv_key) > 160)
705 goto badkey;
706 *pmagic = MS_DSS2MAGIC;
707 }
708
709 return bitlen;
710 badkey:
711 ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
712 return 0;
713}
714
7bc0fdd3 715static void write_dsa(unsigned char **out, const DSA *dsa, int ispub)
0f113f3e
MC
716{
717 int nbyte;
2ac6115d
RL
718 const BIGNUM *p = NULL, *q = NULL, *g = NULL;
719 const BIGNUM *pub_key = NULL, *priv_key = NULL;
6e9fa57c
MC
720
721 DSA_get0_pqg(dsa, &p, &q, &g);
722 DSA_get0_key(dsa, &pub_key, &priv_key);
723 nbyte = BN_num_bytes(p);
724 write_lebn(out, p, nbyte);
725 write_lebn(out, q, 20);
726 write_lebn(out, g, nbyte);
0f113f3e 727 if (ispub)
6e9fa57c 728 write_lebn(out, pub_key, nbyte);
0f113f3e 729 else
6e9fa57c 730 write_lebn(out, priv_key, 20);
0f113f3e
MC
731 /* Set "invalid" for seed structure values */
732 memset(*out, 0xff, 24);
733 *out += 24;
734 return;
735}
a158f8cf 736#endif
a0156a92 737
de0799b0 738int i2b_PrivateKey_bio(BIO *out, const EVP_PKEY *pk)
0f113f3e
MC
739{
740 return do_i2b_bio(out, pk, 0);
741}
a0156a92 742
de0799b0 743int i2b_PublicKey_bio(BIO *out, const EVP_PKEY *pk)
0f113f3e
MC
744{
745 return do_i2b_bio(out, pk, 1);
746}
a0156a92 747
f55838f3
RL
748int ossl_do_PVK_header(const unsigned char **in, unsigned int length,
749 int skip_magic,
750 unsigned int *psaltlen, unsigned int *pkeylen)
0f113f3e
MC
751{
752 const unsigned char *p = *in;
753 unsigned int pvk_magic, is_encrypted;
12a765a5 754
0f113f3e
MC
755 if (skip_magic) {
756 if (length < 20) {
9311d0c4 757 ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT);
0f113f3e
MC
758 return 0;
759 }
0f113f3e
MC
760 } else {
761 if (length < 24) {
9311d0c4 762 ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT);
0f113f3e
MC
763 return 0;
764 }
0f113f3e
MC
765 pvk_magic = read_ledword(&p);
766 if (pvk_magic != MS_PVKMAGIC) {
9311d0c4 767 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER);
0f113f3e
MC
768 return 0;
769 }
770 }
771 /* Skip reserved */
772 p += 4;
773 /*
774 * keytype =
775 */ read_ledword(&p);
776 is_encrypted = read_ledword(&p);
777 *psaltlen = read_ledword(&p);
778 *pkeylen = read_ledword(&p);
779
5f57abe2
DSH
780 if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN)
781 return 0;
782
12a765a5 783 if (is_encrypted && *psaltlen == 0) {
9311d0c4 784 ERR_raise(ERR_LIB_PEM, PEM_R_INCONSISTENT_HEADER);
0f113f3e
MC
785 return 0;
786 }
787
788 *in = p;
789 return 1;
790}
791
a158f8cf 792#ifndef OPENSSL_NO_RC4
0f113f3e
MC
793static int derive_pvk_key(unsigned char *key,
794 const unsigned char *salt, unsigned int saltlen,
795 const unsigned char *pass, int passlen)
796{
3cb9fd97 797 EVP_MD_CTX *mctx = EVP_MD_CTX_new();
0f113f3e 798 int rv = 1;
a158f8cf 799
6e59a892
RL
800 if (mctx == NULL
801 || !EVP_DigestInit_ex(mctx, EVP_sha1(), NULL)
802 || !EVP_DigestUpdate(mctx, salt, saltlen)
803 || !EVP_DigestUpdate(mctx, pass, passlen)
804 || !EVP_DigestFinal_ex(mctx, key, NULL))
0f113f3e
MC
805 rv = 0;
806
bfb0641f 807 EVP_MD_CTX_free(mctx);
0f113f3e
MC
808 return rv;
809}
a158f8cf 810#endif
a0156a92 811
f4e46b81 812static void *do_PVK_body_key(const unsigned char **in,
0f113f3e 813 unsigned int saltlen, unsigned int keylen,
f4e46b81
RL
814 pem_password_cb *cb, void *u,
815 int *isdss, int *ispub)
0f113f3e 816{
0f113f3e 817 const unsigned char *p = *in;
a158f8cf 818 unsigned char *enctmp = NULL;
0239283d 819 unsigned char keybuf[20];
f4e46b81 820 void *key = NULL;
25aaa98a 821
846ec07d 822 EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new();
0f113f3e 823 if (saltlen) {
a158f8cf
RL
824#ifndef OPENSSL_NO_RC4
825 unsigned int magic;
0f113f3e 826 char psbuf[PEM_BUFSIZE];
0f113f3e 827 int enctmplen, inlen;
a158f8cf
RL
828 unsigned char *q;
829
0f113f3e
MC
830 if (cb)
831 inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
832 else
833 inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
c82c3462 834 if (inlen < 0) {
9311d0c4 835 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ);
3f6c7691 836 goto err;
0f113f3e
MC
837 }
838 enctmp = OPENSSL_malloc(keylen + 8);
90945fa3 839 if (enctmp == NULL) {
9311d0c4 840 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
3f6c7691 841 goto err;
0f113f3e
MC
842 }
843 if (!derive_pvk_key(keybuf, p, saltlen,
844 (unsigned char *)psbuf, inlen))
3f6c7691 845 goto err;
0f113f3e
MC
846 p += saltlen;
847 /* Copy BLOBHEADER across, decrypt rest */
848 memcpy(enctmp, p, 8);
849 p += 8;
850 if (keylen < 8) {
9311d0c4 851 ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT);
3f6c7691 852 goto err;
0f113f3e
MC
853 }
854 inlen = keylen - 8;
855 q = enctmp + 8;
846ec07d 856 if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
0f113f3e 857 goto err;
846ec07d 858 if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
0f113f3e 859 goto err;
846ec07d 860 if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
0f113f3e
MC
861 goto err;
862 magic = read_ledword((const unsigned char **)&q);
863 if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
864 q = enctmp + 8;
865 memset(keybuf + 5, 0, 11);
846ec07d 866 if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
0f113f3e 867 goto err;
846ec07d 868 if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
0f113f3e 869 goto err;
846ec07d 870 if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
0f113f3e
MC
871 goto err;
872 magic = read_ledword((const unsigned char **)&q);
873 if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
9311d0c4 874 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_DECRYPT);
0f113f3e
MC
875 goto err;
876 }
0239283d 877 }
0f113f3e 878 p = enctmp;
a158f8cf
RL
879#else
880 ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER);
881 goto err;
882#endif
0f113f3e
MC
883 }
884
f4e46b81 885 key = do_b2i_key(&p, keylen, isdss, ispub);
0f113f3e 886 err:
846ec07d 887 EVP_CIPHER_CTX_free(cctx);
0239283d
SL
888 if (enctmp != NULL) {
889 OPENSSL_cleanse(keybuf, sizeof(keybuf));
890 OPENSSL_free(enctmp);
891 }
f4e46b81 892 return key;
0f113f3e 893}
a0156a92 894
f4e46b81
RL
895static void *do_PVK_key_bio(BIO *in, pem_password_cb *cb, void *u,
896 int *isdss, int *ispub)
0f113f3e
MC
897{
898 unsigned char pvk_hdr[24], *buf = NULL;
899 const unsigned char *p;
900 int buflen;
f4e46b81 901 void *key = NULL;
0f113f3e 902 unsigned int saltlen, keylen;
a158f8cf 903
0f113f3e 904 if (BIO_read(in, pvk_hdr, 24) != 24) {
9311d0c4 905 ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT);
0f113f3e
MC
906 return NULL;
907 }
908 p = pvk_hdr;
909
f55838f3 910 if (!ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen))
0f113f3e
MC
911 return 0;
912 buflen = (int)keylen + saltlen;
913 buf = OPENSSL_malloc(buflen);
90945fa3 914 if (buf == NULL) {
9311d0c4 915 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
916 return 0;
917 }
918 p = buf;
919 if (BIO_read(in, buf, buflen) != buflen) {
9311d0c4 920 ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT);
0f113f3e
MC
921 goto err;
922 }
f4e46b81 923 key = do_PVK_body_key(&p, saltlen, keylen, cb, u, isdss, ispub);
0f113f3e
MC
924
925 err:
4b45c6e5 926 OPENSSL_clear_free(buf, buflen);
f4e46b81
RL
927 return key;
928}
929
930#ifndef OPENSSL_NO_DSA
931DSA *b2i_DSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
932{
933 int isdss = 1;
934 int ispub = 0; /* PVK keys are always private */
935
936 return do_PVK_key_bio(in, cb, u, &isdss, &ispub);
937}
938#endif
939
940RSA *b2i_RSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
941{
942 int isdss = 0;
943 int ispub = 0; /* PVK keys are always private */
944
945 return do_PVK_key_bio(in, cb, u, &isdss, &ispub);
946}
947
948EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
949{
950 int isdss = -1;
951 int ispub = -1;
952 void *key = do_PVK_key_bio(in, cb, u, &isdss, &ispub);
953
954 return evp_pkey_new0_key(key, isdss_to_evp_type(isdss));
0f113f3e
MC
955}
956
de0799b0 957static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel,
0f113f3e
MC
958 pem_password_cb *cb, void *u)
959{
960 int outlen = 24, pklen;
a158f8cf 961 unsigned char *p = NULL, *start = NULL;
8e588e28 962 EVP_CIPHER_CTX *cctx = NULL;
a158f8cf
RL
963#ifndef OPENSSL_NO_RC4
964 unsigned char *salt = NULL;
965#endif
966
0f113f3e
MC
967 if (enclevel)
968 outlen += PVK_SALTLEN;
969 pklen = do_i2b(NULL, pk, 0);
970 if (pklen < 0)
971 return -1;
972 outlen += pklen;
8e588e28 973 if (out == NULL)
0f113f3e 974 return outlen;
8e588e28 975 if (*out != NULL) {
0f113f3e 976 p = *out;
8e588e28 977 } else {
febb096c 978 start = p = OPENSSL_malloc(outlen);
90945fa3 979 if (p == NULL) {
9311d0c4 980 ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
981 return -1;
982 }
0f113f3e
MC
983 }
984
8e588e28
MC
985 cctx = EVP_CIPHER_CTX_new();
986 if (cctx == NULL)
098c1e3d 987 goto error;
8e588e28 988
0f113f3e
MC
989 write_ledword(&p, MS_PVKMAGIC);
990 write_ledword(&p, 0);
a158f8cf 991 if (EVP_PKEY_id(pk) == EVP_PKEY_RSA)
0f113f3e 992 write_ledword(&p, MS_KEYTYPE_KEYX);
a158f8cf
RL
993#ifndef OPENSSL_NO_DSA
994 else
995 write_ledword(&p, MS_KEYTYPE_SIGN);
996#endif
0f113f3e
MC
997 write_ledword(&p, enclevel ? 1 : 0);
998 write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
999 write_ledword(&p, pklen);
1000 if (enclevel) {
a158f8cf 1001#ifndef OPENSSL_NO_RC4
0f113f3e
MC
1002 if (RAND_bytes(p, PVK_SALTLEN) <= 0)
1003 goto error;
1004 salt = p;
1005 p += PVK_SALTLEN;
a158f8cf 1006#endif
0f113f3e
MC
1007 }
1008 do_i2b(&p, pk, 0);
8e588e28 1009 if (enclevel != 0) {
a158f8cf 1010#ifndef OPENSSL_NO_RC4
0f113f3e
MC
1011 char psbuf[PEM_BUFSIZE];
1012 unsigned char keybuf[20];
1013 int enctmplen, inlen;
a158f8cf 1014
0f113f3e
MC
1015 if (cb)
1016 inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
1017 else
1018 inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
1019 if (inlen <= 0) {
9311d0c4 1020 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ);
0f113f3e
MC
1021 goto error;
1022 }
1023 if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
1024 (unsigned char *)psbuf, inlen))
1025 goto error;
1026 if (enclevel == 1)
1027 memset(keybuf + 5, 0, 11);
1028 p = salt + PVK_SALTLEN + 8;
846ec07d 1029 if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
0f113f3e
MC
1030 goto error;
1031 OPENSSL_cleanse(keybuf, 20);
dca51418 1032 if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8))
0f113f3e 1033 goto error;
dca51418 1034 if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen))
0f113f3e 1035 goto error;
a158f8cf
RL
1036#else
1037 ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER);
1038 goto error;
1039#endif
0f113f3e 1040 }
8e588e28 1041
846ec07d 1042 EVP_CIPHER_CTX_free(cctx);
8e588e28
MC
1043
1044 if (*out == NULL)
febb096c 1045 *out = start;
8e588e28 1046
0f113f3e
MC
1047 return outlen;
1048
1049 error:
846ec07d 1050 EVP_CIPHER_CTX_free(cctx);
098c1e3d 1051 if (*out == NULL)
febb096c 1052 OPENSSL_free(start);
0f113f3e
MC
1053 return -1;
1054}
a0156a92 1055
de0799b0 1056int i2b_PVK_bio(BIO *out, const EVP_PKEY *pk, int enclevel,
0f113f3e
MC
1057 pem_password_cb *cb, void *u)
1058{
1059 unsigned char *tmp = NULL;
1060 int outlen, wrlen;
a158f8cf 1061
0f113f3e
MC
1062 outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
1063 if (outlen < 0)
1064 return -1;
1065 wrlen = BIO_write(out, tmp, outlen);
1066 OPENSSL_free(tmp);
1067 if (wrlen == outlen) {
0f113f3e
MC
1068 return outlen;
1069 }
9311d0c4 1070 ERR_raise(ERR_LIB_PEM, PEM_R_BIO_WRITE_FAILURE);
0f113f3e
MC
1071 return -1;
1072}