1 /* ====================================================================
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 "../internal.h"
64 #include "../rsa/internal.h"
65 
66 
bn_print(BIO * bp,const char * number,const BIGNUM * num,uint8_t * buf,int off)67 static int bn_print(BIO *bp, const char *number, const BIGNUM *num,
68                     uint8_t *buf, int off) {
69   if (num == NULL) {
70     return 1;
71   }
72 
73   if (!BIO_indent(bp, off, 128)) {
74     return 0;
75   }
76   if (BN_is_zero(num)) {
77     if (BIO_printf(bp, "%s 0\n", number) <= 0) {
78       return 0;
79     }
80     return 1;
81   }
82 
83   if (BN_num_bytes(num) <= sizeof(long)) {
84     const char *neg = BN_is_negative(num) ? "-" : "";
85     if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
86                    (unsigned long)num->d[0], neg,
87                    (unsigned long)num->d[0]) <= 0) {
88       return 0;
89     }
90   } else {
91     buf[0] = 0;
92     if (BIO_printf(bp, "%s%s", number,
93                    (BN_is_negative(num)) ? " (Negative)" : "") <= 0) {
94       return 0;
95     }
96     int n = BN_bn2bin(num, &buf[1]);
97 
98     if (buf[1] & 0x80) {
99       n++;
100     } else {
101       buf++;
102     }
103 
104     int i;
105     for (i = 0; i < n; i++) {
106       if ((i % 15) == 0) {
107         if (BIO_puts(bp, "\n") <= 0 ||
108             !BIO_indent(bp, off + 4, 128)) {
109           return 0;
110         }
111       }
112       if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") <= 0) {
113         return 0;
114       }
115     }
116     if (BIO_write(bp, "\n", 1) <= 0) {
117       return 0;
118     }
119   }
120   return 1;
121 }
122 
update_buflen(const BIGNUM * b,size_t * pbuflen)123 static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
124   if (!b) {
125     return;
126   }
127 
128   size_t len = BN_num_bytes(b);
129   if (*pbuflen < len) {
130     *pbuflen = len;
131   }
132 }
133 
134 /* RSA keys. */
135 
do_rsa_print(BIO * out,const RSA * rsa,int off,int include_private)136 static int do_rsa_print(BIO *out, const RSA *rsa, int off,
137                         int include_private) {
138   const char *s, *str;
139   uint8_t *m = NULL;
140   int ret = 0, mod_len = 0;
141   size_t buf_len = 0;
142 
143   update_buflen(rsa->n, &buf_len);
144   update_buflen(rsa->e, &buf_len);
145 
146   if (include_private) {
147     update_buflen(rsa->d, &buf_len);
148     update_buflen(rsa->p, &buf_len);
149     update_buflen(rsa->q, &buf_len);
150     update_buflen(rsa->dmp1, &buf_len);
151     update_buflen(rsa->dmq1, &buf_len);
152     update_buflen(rsa->iqmp, &buf_len);
153 
154     if (rsa->additional_primes != NULL) {
155       for (size_t i = 0;
156            i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
157         const RSA_additional_prime *ap =
158             sk_RSA_additional_prime_value(rsa->additional_primes, i);
159         update_buflen(ap->prime, &buf_len);
160         update_buflen(ap->exp, &buf_len);
161         update_buflen(ap->coeff, &buf_len);
162       }
163     }
164   }
165 
166   m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
167   if (m == NULL) {
168     OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
169     goto err;
170   }
171 
172   if (rsa->n != NULL) {
173     mod_len = BN_num_bits(rsa->n);
174   }
175 
176   if (!BIO_indent(out, off, 128)) {
177     goto err;
178   }
179 
180   if (include_private && rsa->d) {
181     if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
182       goto err;
183     }
184     str = "modulus:";
185     s = "publicExponent:";
186   } else {
187     if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
188       goto err;
189     }
190     str = "Modulus:";
191     s = "Exponent:";
192   }
193   if (!bn_print(out, str, rsa->n, m, off) ||
194       !bn_print(out, s, rsa->e, m, off)) {
195     goto err;
196   }
197 
198   if (include_private) {
199     if (!bn_print(out, "privateExponent:", rsa->d, m, off) ||
200         !bn_print(out, "prime1:", rsa->p, m, off) ||
201         !bn_print(out, "prime2:", rsa->q, m, off) ||
202         !bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
203         !bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
204         !bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
205       goto err;
206     }
207 
208     if (rsa->additional_primes != NULL &&
209         sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
210       if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
211         goto err;
212       }
213       for (size_t i = 0;
214            i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
215         const RSA_additional_prime *ap =
216             sk_RSA_additional_prime_value(rsa->additional_primes, i);
217 
218         if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
219                        (unsigned)(i + 3)) <= 0 ||
220             !bn_print(out, "prime:", ap->prime, m, off) ||
221             !bn_print(out, "exponent:", ap->exp, m, off) ||
222             !bn_print(out, "coeff:", ap->coeff, m, off)) {
223           goto err;
224         }
225       }
226     }
227   }
228   ret = 1;
229 
230 err:
231   OPENSSL_free(m);
232   return ret;
233 }
234 
rsa_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)235 static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
236                          ASN1_PCTX *ctx) {
237   return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
238 }
239 
rsa_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)240 static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
241                           ASN1_PCTX *ctx) {
242   return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
243 }
244 
245 
246 /* DSA keys. */
247 
do_dsa_print(BIO * bp,const DSA * x,int off,int ptype)248 static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
249   uint8_t *m = NULL;
250   int ret = 0;
251   size_t buf_len = 0;
252   const char *ktype = NULL;
253 
254   const BIGNUM *priv_key, *pub_key;
255 
256   priv_key = NULL;
257   if (ptype == 2) {
258     priv_key = x->priv_key;
259   }
260 
261   pub_key = NULL;
262   if (ptype > 0) {
263     pub_key = x->pub_key;
264   }
265 
266   ktype = "DSA-Parameters";
267   if (ptype == 2) {
268     ktype = "Private-Key";
269   } else if (ptype == 1) {
270     ktype = "Public-Key";
271   }
272 
273   update_buflen(x->p, &buf_len);
274   update_buflen(x->q, &buf_len);
275   update_buflen(x->g, &buf_len);
276   update_buflen(priv_key, &buf_len);
277   update_buflen(pub_key, &buf_len);
278 
279   m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
280   if (m == NULL) {
281     OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
282     goto err;
283   }
284 
285   if (priv_key) {
286     if (!BIO_indent(bp, off, 128) ||
287         BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
288       goto err;
289     }
290   }
291 
292   if (!bn_print(bp, "priv:", priv_key, m, off) ||
293       !bn_print(bp, "pub: ", pub_key, m, off) ||
294       !bn_print(bp, "P:   ", x->p, m, off) ||
295       !bn_print(bp, "Q:   ", x->q, m, off) ||
296       !bn_print(bp, "G:   ", x->g, m, off)) {
297     goto err;
298   }
299   ret = 1;
300 
301 err:
302   OPENSSL_free(m);
303   return ret;
304 }
305 
dsa_param_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)306 static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
307                            ASN1_PCTX *ctx) {
308   return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
309 }
310 
dsa_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)311 static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
312                          ASN1_PCTX *ctx) {
313   return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
314 }
315 
dsa_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)316 static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
317                           ASN1_PCTX *ctx) {
318   return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
319 }
320 
321 
322 /* EC keys. */
323 
do_EC_KEY_print(BIO * bp,const EC_KEY * x,int off,int ktype)324 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
325   uint8_t *buffer = NULL;
326   const char *ecstr;
327   size_t buf_len = 0, i;
328   int ret = 0, reason = ERR_R_BIO_LIB;
329   BIGNUM *order = NULL;
330   BN_CTX *ctx = NULL;
331   const EC_GROUP *group;
332   const EC_POINT *public_key;
333   const BIGNUM *priv_key;
334   uint8_t *pub_key_bytes = NULL;
335   size_t pub_key_bytes_len = 0;
336 
337   if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
338     reason = ERR_R_PASSED_NULL_PARAMETER;
339     goto err;
340   }
341 
342   ctx = BN_CTX_new();
343   if (ctx == NULL) {
344     reason = ERR_R_MALLOC_FAILURE;
345     goto err;
346   }
347 
348   if (ktype > 0) {
349     public_key = EC_KEY_get0_public_key(x);
350     if (public_key != NULL) {
351       pub_key_bytes_len = EC_POINT_point2oct(
352           group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
353       if (pub_key_bytes_len == 0) {
354         reason = ERR_R_MALLOC_FAILURE;
355         goto err;
356       }
357       pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
358       if (pub_key_bytes == NULL) {
359         reason = ERR_R_MALLOC_FAILURE;
360         goto err;
361       }
362       pub_key_bytes_len =
363           EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
364                              pub_key_bytes, pub_key_bytes_len, ctx);
365       if (pub_key_bytes_len == 0) {
366         reason = ERR_R_MALLOC_FAILURE;
367         goto err;
368       }
369       buf_len = pub_key_bytes_len;
370     }
371   }
372 
373   if (ktype == 2) {
374     priv_key = EC_KEY_get0_private_key(x);
375     if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
376       buf_len = i;
377     }
378   } else {
379     priv_key = NULL;
380   }
381 
382   if (ktype > 0) {
383     buf_len += 10;
384     if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
385       reason = ERR_R_MALLOC_FAILURE;
386       goto err;
387     }
388   }
389   if (ktype == 2) {
390     ecstr = "Private-Key";
391   } else if (ktype == 1) {
392     ecstr = "Public-Key";
393   } else {
394     ecstr = "ECDSA-Parameters";
395   }
396 
397   if (!BIO_indent(bp, off, 128)) {
398     goto err;
399   }
400   order = BN_new();
401   if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
402       BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
403     goto err;
404   }
405 
406   if ((priv_key != NULL) &&
407       !bn_print(bp, "priv:", priv_key, buffer, off)) {
408     goto err;
409   }
410   if (pub_key_bytes != NULL) {
411     BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
412   }
413   /* TODO(fork): implement */
414   /*
415   if (!ECPKParameters_print(bp, group, off))
416     goto err; */
417   ret = 1;
418 
419 err:
420   if (!ret) {
421     OPENSSL_PUT_ERROR(EVP, reason);
422   }
423   OPENSSL_free(pub_key_bytes);
424   BN_free(order);
425   BN_CTX_free(ctx);
426   OPENSSL_free(buffer);
427   return ret;
428 }
429 
eckey_param_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)430 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
431                              ASN1_PCTX *ctx) {
432   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
433 }
434 
eckey_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)435 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
436                            ASN1_PCTX *ctx) {
437   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
438 }
439 
440 
eckey_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent,ASN1_PCTX * ctx)441 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
442                             ASN1_PCTX *ctx) {
443   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
444 }
445 
446 
447 typedef struct {
448   int type;
449   int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
450   int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
451                     ASN1_PCTX *pctx);
452   int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
453                      ASN1_PCTX *pctx);
454 } EVP_PKEY_PRINT_METHOD;
455 
456 static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
457     {
458         EVP_PKEY_RSA,
459         rsa_pub_print,
460         rsa_priv_print,
461         NULL /* param_print */,
462     },
463     {
464         EVP_PKEY_DSA,
465         dsa_pub_print,
466         dsa_priv_print,
467         dsa_param_print,
468     },
469     {
470         EVP_PKEY_EC,
471         eckey_pub_print,
472         eckey_priv_print,
473         eckey_param_print,
474     },
475 };
476 
477 static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods);
478 
find_method(int type)479 static EVP_PKEY_PRINT_METHOD *find_method(int type) {
480   for (size_t i = 0; i < kPrintMethodsLen; i++) {
481     if (kPrintMethods[i].type == type) {
482       return &kPrintMethods[i];
483     }
484   }
485   return NULL;
486 }
487 
print_unsupported(BIO * out,const EVP_PKEY * pkey,int indent,const char * kstr)488 static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
489                              const char *kstr) {
490   BIO_indent(out, indent, 128);
491   BIO_printf(out, "%s algorithm unsupported\n", kstr);
492   return 1;
493 }
494 
EVP_PKEY_print_public(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)495 int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
496                           ASN1_PCTX *pctx) {
497   EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
498   if (method != NULL && method->pub_print != NULL) {
499     return method->pub_print(out, pkey, indent, pctx);
500   }
501   return print_unsupported(out, pkey, indent, "Public Key");
502 }
503 
EVP_PKEY_print_private(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)504 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
505                            ASN1_PCTX *pctx) {
506   EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
507   if (method != NULL && method->priv_print != NULL) {
508     return method->priv_print(out, pkey, indent, pctx);
509   }
510   return print_unsupported(out, pkey, indent, "Private Key");
511 }
512 
EVP_PKEY_print_params(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)513 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
514                           ASN1_PCTX *pctx) {
515   EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
516   if (method != NULL && method->param_print != NULL) {
517     return method->param_print(out, pkey, indent, pctx);
518   }
519   return print_unsupported(out, pkey, indent, "Parameters");
520 }
521