blob: 56521ec56bda3bb404c967aadc1950edf4cc5643 [file] [log] [blame]
David Benjamin4969cc92016-04-22 15:02:23 -04001/* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com). */
52
53#include <openssl/evp.h>
54
55#include <openssl/bio.h>
56#include <openssl/bn.h>
57#include <openssl/dsa.h>
58#include <openssl/ec.h>
59#include <openssl/ec_key.h>
60#include <openssl/mem.h>
61#include <openssl/rsa.h>
62
63#include "../rsa/internal.h"
64
65
66static int bn_print(BIO *bp, const char *number, const BIGNUM *num,
67 uint8_t *buf, int off) {
68 if (num == NULL) {
69 return 1;
70 }
71
72 if (!BIO_indent(bp, off, 128)) {
73 return 0;
74 }
75 if (BN_is_zero(num)) {
76 if (BIO_printf(bp, "%s 0\n", number) <= 0) {
77 return 0;
78 }
79 return 1;
80 }
81
82 if (BN_num_bytes(num) <= sizeof(long)) {
83 const char *neg = BN_is_negative(num) ? "-" : "";
84 if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
85 (unsigned long)num->d[0], neg,
86 (unsigned long)num->d[0]) <= 0) {
87 return 0;
88 }
89 } else {
90 buf[0] = 0;
91 if (BIO_printf(bp, "%s%s", number,
92 (BN_is_negative(num)) ? " (Negative)" : "") <= 0) {
93 return 0;
94 }
95 int n = BN_bn2bin(num, &buf[1]);
96
97 if (buf[1] & 0x80) {
98 n++;
99 } else {
100 buf++;
101 }
102
103 int i;
104 for (i = 0; i < n; i++) {
105 if ((i % 15) == 0) {
106 if (BIO_puts(bp, "\n") <= 0 ||
107 !BIO_indent(bp, off + 4, 128)) {
108 return 0;
109 }
110 }
111 if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") <= 0) {
112 return 0;
113 }
114 }
115 if (BIO_write(bp, "\n", 1) <= 0) {
116 return 0;
117 }
118 }
119 return 1;
120}
121
122static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
123 size_t i;
124
125 if (!b) {
126 return;
127 }
128
129 i = BN_num_bytes(b);
130 if (*pbuflen < i) {
131 *pbuflen = i;
132 }
133}
134
135/* RSA keys. */
136
137static int do_rsa_print(BIO *out, const RSA *rsa, int off,
138 int include_private) {
139 const char *s, *str;
140 uint8_t *m = NULL;
141 int ret = 0, mod_len = 0;
142 size_t buf_len = 0;
143
144 update_buflen(rsa->n, &buf_len);
145 update_buflen(rsa->e, &buf_len);
146
147 if (include_private) {
148 update_buflen(rsa->d, &buf_len);
149 update_buflen(rsa->p, &buf_len);
150 update_buflen(rsa->q, &buf_len);
151 update_buflen(rsa->dmp1, &buf_len);
152 update_buflen(rsa->dmq1, &buf_len);
153 update_buflen(rsa->iqmp, &buf_len);
154
155 if (rsa->additional_primes != NULL) {
156 size_t i;
157
158 for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
159 i++) {
160 const RSA_additional_prime *ap =
161 sk_RSA_additional_prime_value(rsa->additional_primes, i);
162 update_buflen(ap->prime, &buf_len);
163 update_buflen(ap->exp, &buf_len);
164 update_buflen(ap->coeff, &buf_len);
165 }
166 }
167 }
168
169 m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
170 if (m == NULL) {
171 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
172 goto err;
173 }
174
175 if (rsa->n != NULL) {
176 mod_len = BN_num_bits(rsa->n);
177 }
178
179 if (!BIO_indent(out, off, 128)) {
180 goto err;
181 }
182
183 if (include_private && rsa->d) {
184 if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
185 goto err;
186 }
187 str = "modulus:";
188 s = "publicExponent:";
189 } else {
190 if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
191 goto err;
192 }
193 str = "Modulus:";
194 s = "Exponent:";
195 }
196 if (!bn_print(out, str, rsa->n, m, off) ||
197 !bn_print(out, s, rsa->e, m, off)) {
198 goto err;
199 }
200
201 if (include_private) {
202 if (!bn_print(out, "privateExponent:", rsa->d, m, off) ||
203 !bn_print(out, "prime1:", rsa->p, m, off) ||
204 !bn_print(out, "prime2:", rsa->q, m, off) ||
205 !bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
206 !bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
207 !bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
208 goto err;
209 }
210
211 if (rsa->additional_primes != NULL &&
212 sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
213 size_t i;
214
215 if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
216 goto err;
217 }
218 for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
219 i++) {
220 const RSA_additional_prime *ap =
221 sk_RSA_additional_prime_value(rsa->additional_primes, i);
222
223 if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
224 (unsigned)(i + 3)) <= 0 ||
225 !bn_print(out, "prime:", ap->prime, m, off) ||
226 !bn_print(out, "exponent:", ap->exp, m, off) ||
227 !bn_print(out, "coeff:", ap->coeff, m, off)) {
228 goto err;
229 }
230 }
231 }
232 }
233 ret = 1;
234
235err:
236 OPENSSL_free(m);
237 return ret;
238}
239
240static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
241 ASN1_PCTX *ctx) {
242 return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
243}
244
245static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
246 ASN1_PCTX *ctx) {
247 return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
248}
249
250
251/* DSA keys. */
252
253static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
254 uint8_t *m = NULL;
255 int ret = 0;
256 size_t buf_len = 0;
257 const char *ktype = NULL;
258
259 const BIGNUM *priv_key, *pub_key;
260
261 priv_key = NULL;
262 if (ptype == 2) {
263 priv_key = x->priv_key;
264 }
265
266 pub_key = NULL;
267 if (ptype > 0) {
268 pub_key = x->pub_key;
269 }
270
271 ktype = "DSA-Parameters";
272 if (ptype == 2) {
273 ktype = "Private-Key";
274 } else if (ptype == 1) {
275 ktype = "Public-Key";
276 }
277
278 update_buflen(x->p, &buf_len);
279 update_buflen(x->q, &buf_len);
280 update_buflen(x->g, &buf_len);
281 update_buflen(priv_key, &buf_len);
282 update_buflen(pub_key, &buf_len);
283
284 m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
285 if (m == NULL) {
286 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
287 goto err;
288 }
289
290 if (priv_key) {
291 if (!BIO_indent(bp, off, 128) ||
292 BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
293 goto err;
294 }
295 }
296
297 if (!bn_print(bp, "priv:", priv_key, m, off) ||
298 !bn_print(bp, "pub: ", pub_key, m, off) ||
299 !bn_print(bp, "P: ", x->p, m, off) ||
300 !bn_print(bp, "Q: ", x->q, m, off) ||
301 !bn_print(bp, "G: ", x->g, m, off)) {
302 goto err;
303 }
304 ret = 1;
305
306err:
307 OPENSSL_free(m);
308 return ret;
309}
310
311static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
312 ASN1_PCTX *ctx) {
313 return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
314}
315
316static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
317 ASN1_PCTX *ctx) {
318 return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
319}
320
321static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
322 ASN1_PCTX *ctx) {
323 return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
324}
325
326
327/* EC keys. */
328
329static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
330 uint8_t *buffer = NULL;
331 const char *ecstr;
332 size_t buf_len = 0, i;
333 int ret = 0, reason = ERR_R_BIO_LIB;
334 BIGNUM *order = NULL;
335 BN_CTX *ctx = NULL;
336 const EC_GROUP *group;
337 const EC_POINT *public_key;
338 const BIGNUM *priv_key;
339 uint8_t *pub_key_bytes = NULL;
340 size_t pub_key_bytes_len = 0;
341
342 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
343 reason = ERR_R_PASSED_NULL_PARAMETER;
344 goto err;
345 }
346
347 ctx = BN_CTX_new();
348 if (ctx == NULL) {
349 reason = ERR_R_MALLOC_FAILURE;
350 goto err;
351 }
352
353 if (ktype > 0) {
354 public_key = EC_KEY_get0_public_key(x);
355 if (public_key != NULL) {
356 pub_key_bytes_len = EC_POINT_point2oct(
357 group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
358 if (pub_key_bytes_len == 0) {
359 reason = ERR_R_MALLOC_FAILURE;
360 goto err;
361 }
362 pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
363 if (pub_key_bytes == NULL) {
364 reason = ERR_R_MALLOC_FAILURE;
365 goto err;
366 }
367 pub_key_bytes_len =
368 EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
369 pub_key_bytes, pub_key_bytes_len, ctx);
370 if (pub_key_bytes_len == 0) {
371 reason = ERR_R_MALLOC_FAILURE;
372 goto err;
373 }
374 buf_len = pub_key_bytes_len;
375 }
376 }
377
378 if (ktype == 2) {
379 priv_key = EC_KEY_get0_private_key(x);
380 if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
381 buf_len = i;
382 }
383 } else {
384 priv_key = NULL;
385 }
386
387 if (ktype > 0) {
388 buf_len += 10;
389 if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
390 reason = ERR_R_MALLOC_FAILURE;
391 goto err;
392 }
393 }
394 if (ktype == 2) {
395 ecstr = "Private-Key";
396 } else if (ktype == 1) {
397 ecstr = "Public-Key";
398 } else {
399 ecstr = "ECDSA-Parameters";
400 }
401
402 if (!BIO_indent(bp, off, 128)) {
403 goto err;
404 }
405 order = BN_new();
406 if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
407 BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
408 goto err;
409 }
410
411 if ((priv_key != NULL) &&
412 !bn_print(bp, "priv:", priv_key, buffer, off)) {
413 goto err;
414 }
415 if (pub_key_bytes != NULL) {
416 BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
417 }
418 /* TODO(fork): implement */
419 /*
420 if (!ECPKParameters_print(bp, group, off))
421 goto err; */
422 ret = 1;
423
424err:
425 if (!ret) {
426 OPENSSL_PUT_ERROR(EVP, reason);
427 }
428 OPENSSL_free(pub_key_bytes);
429 BN_free(order);
430 BN_CTX_free(ctx);
431 OPENSSL_free(buffer);
432 return ret;
433}
434
435static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
436 ASN1_PCTX *ctx) {
437 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
438}
439
440static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
441 ASN1_PCTX *ctx) {
442 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
443}
444
445
446static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
447 ASN1_PCTX *ctx) {
448 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
449}
450
451
452typedef struct {
453 int type;
454 int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
455 int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
456 ASN1_PCTX *pctx);
457 int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
458 ASN1_PCTX *pctx);
459} EVP_PKEY_PRINT_METHOD;
460
461static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
462 {
463 EVP_PKEY_RSA,
464 rsa_pub_print,
465 rsa_priv_print,
466 NULL /* param_print */,
467 },
468 {
469 EVP_PKEY_DSA,
470 dsa_pub_print,
471 dsa_priv_print,
472 dsa_param_print,
473 },
474 {
475 EVP_PKEY_EC,
476 eckey_pub_print,
477 eckey_priv_print,
478 eckey_param_print,
479 },
480};
481
482static size_t kPrintMethodsLen =
483 sizeof(kPrintMethods) / sizeof(kPrintMethods[0]);
484
485static EVP_PKEY_PRINT_METHOD *find_method(int type) {
486 size_t i;
487 for (i = 0; i < kPrintMethodsLen; i++) {
488 if (kPrintMethods[i].type == type) {
489 return &kPrintMethods[i];
490 }
491 }
492 return NULL;
493}
494
495static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
496 const char *kstr) {
497 BIO_indent(out, indent, 128);
498 BIO_printf(out, "%s algorithm unsupported\n", kstr);
499 return 1;
500}
501
502int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
503 ASN1_PCTX *pctx) {
504 EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
505 if (method != NULL && method->pub_print != NULL) {
506 return method->pub_print(out, pkey, indent, pctx);
507 }
508 return print_unsupported(out, pkey, indent, "Public Key");
509}
510
511int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
512 ASN1_PCTX *pctx) {
513 EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
514 if (method != NULL && method->priv_print != NULL) {
515 return method->priv_print(out, pkey, indent, pctx);
516 }
517 return print_unsupported(out, pkey, indent, "Private Key");
518}
519
520int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
521 ASN1_PCTX *pctx) {
522 EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
523 if (method != NULL && method->param_print != NULL) {
524 return method->param_print(out, pkey, indent, pctx);
525 }
526 return print_unsupported(out, pkey, indent, "Parameters");
527}