Home | History | Annotate | Download | only in evp
      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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     51  * Hudson (tjh (at) 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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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