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 "../fipsmodule/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 
    155   m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
    156   if (m == NULL) {
    157     OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
    158     goto err;
    159   }
    160 
    161   if (rsa->n != NULL) {
    162     mod_len = BN_num_bits(rsa->n);
    163   }
    164 
    165   if (!BIO_indent(out, off, 128)) {
    166     goto err;
    167   }
    168 
    169   if (include_private && rsa->d) {
    170     if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
    171       goto err;
    172     }
    173     str = "modulus:";
    174     s = "publicExponent:";
    175   } else {
    176     if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
    177       goto err;
    178     }
    179     str = "Modulus:";
    180     s = "Exponent:";
    181   }
    182   if (!bn_print(out, str, rsa->n, m, off) ||
    183       !bn_print(out, s, rsa->e, m, off)) {
    184     goto err;
    185   }
    186 
    187   if (include_private) {
    188     if (!bn_print(out, "privateExponent:", rsa->d, m, off) ||
    189         !bn_print(out, "prime1:", rsa->p, m, off) ||
    190         !bn_print(out, "prime2:", rsa->q, m, off) ||
    191         !bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
    192         !bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
    193         !bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
    194       goto err;
    195     }
    196   }
    197   ret = 1;
    198 
    199 err:
    200   OPENSSL_free(m);
    201   return ret;
    202 }
    203 
    204 static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    205                          ASN1_PCTX *ctx) {
    206   return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
    207 }
    208 
    209 static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    210                           ASN1_PCTX *ctx) {
    211   return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
    212 }
    213 
    214 
    215 // DSA keys.
    216 
    217 static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
    218   uint8_t *m = NULL;
    219   int ret = 0;
    220   size_t buf_len = 0;
    221   const char *ktype = NULL;
    222 
    223   const BIGNUM *priv_key, *pub_key;
    224 
    225   priv_key = NULL;
    226   if (ptype == 2) {
    227     priv_key = x->priv_key;
    228   }
    229 
    230   pub_key = NULL;
    231   if (ptype > 0) {
    232     pub_key = x->pub_key;
    233   }
    234 
    235   ktype = "DSA-Parameters";
    236   if (ptype == 2) {
    237     ktype = "Private-Key";
    238   } else if (ptype == 1) {
    239     ktype = "Public-Key";
    240   }
    241 
    242   update_buflen(x->p, &buf_len);
    243   update_buflen(x->q, &buf_len);
    244   update_buflen(x->g, &buf_len);
    245   update_buflen(priv_key, &buf_len);
    246   update_buflen(pub_key, &buf_len);
    247 
    248   m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
    249   if (m == NULL) {
    250     OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
    251     goto err;
    252   }
    253 
    254   if (priv_key) {
    255     if (!BIO_indent(bp, off, 128) ||
    256         BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
    257       goto err;
    258     }
    259   }
    260 
    261   if (!bn_print(bp, "priv:", priv_key, m, off) ||
    262       !bn_print(bp, "pub: ", pub_key, m, off) ||
    263       !bn_print(bp, "P:   ", x->p, m, off) ||
    264       !bn_print(bp, "Q:   ", x->q, m, off) ||
    265       !bn_print(bp, "G:   ", x->g, m, off)) {
    266     goto err;
    267   }
    268   ret = 1;
    269 
    270 err:
    271   OPENSSL_free(m);
    272   return ret;
    273 }
    274 
    275 static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    276                            ASN1_PCTX *ctx) {
    277   return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
    278 }
    279 
    280 static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    281                          ASN1_PCTX *ctx) {
    282   return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
    283 }
    284 
    285 static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    286                           ASN1_PCTX *ctx) {
    287   return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
    288 }
    289 
    290 
    291 // EC keys.
    292 
    293 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
    294   uint8_t *buffer = NULL;
    295   const char *ecstr;
    296   size_t buf_len = 0, i;
    297   int ret = 0, reason = ERR_R_BIO_LIB;
    298   BIGNUM *order = NULL;
    299   BN_CTX *ctx = NULL;
    300   const EC_GROUP *group;
    301   const EC_POINT *public_key;
    302   const BIGNUM *priv_key;
    303   uint8_t *pub_key_bytes = NULL;
    304   size_t pub_key_bytes_len = 0;
    305 
    306   if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
    307     reason = ERR_R_PASSED_NULL_PARAMETER;
    308     goto err;
    309   }
    310 
    311   ctx = BN_CTX_new();
    312   if (ctx == NULL) {
    313     reason = ERR_R_MALLOC_FAILURE;
    314     goto err;
    315   }
    316 
    317   if (ktype > 0) {
    318     public_key = EC_KEY_get0_public_key(x);
    319     if (public_key != NULL) {
    320       pub_key_bytes_len = EC_POINT_point2oct(
    321           group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
    322       if (pub_key_bytes_len == 0) {
    323         reason = ERR_R_MALLOC_FAILURE;
    324         goto err;
    325       }
    326       pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
    327       if (pub_key_bytes == NULL) {
    328         reason = ERR_R_MALLOC_FAILURE;
    329         goto err;
    330       }
    331       pub_key_bytes_len =
    332           EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
    333                              pub_key_bytes, pub_key_bytes_len, ctx);
    334       if (pub_key_bytes_len == 0) {
    335         reason = ERR_R_MALLOC_FAILURE;
    336         goto err;
    337       }
    338       buf_len = pub_key_bytes_len;
    339     }
    340   }
    341 
    342   if (ktype == 2) {
    343     priv_key = EC_KEY_get0_private_key(x);
    344     if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
    345       buf_len = i;
    346     }
    347   } else {
    348     priv_key = NULL;
    349   }
    350 
    351   if (ktype > 0) {
    352     buf_len += 10;
    353     if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
    354       reason = ERR_R_MALLOC_FAILURE;
    355       goto err;
    356     }
    357   }
    358   if (ktype == 2) {
    359     ecstr = "Private-Key";
    360   } else if (ktype == 1) {
    361     ecstr = "Public-Key";
    362   } else {
    363     ecstr = "ECDSA-Parameters";
    364   }
    365 
    366   if (!BIO_indent(bp, off, 128)) {
    367     goto err;
    368   }
    369   order = BN_new();
    370   if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
    371       BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
    372     goto err;
    373   }
    374 
    375   if ((priv_key != NULL) &&
    376       !bn_print(bp, "priv:", priv_key, buffer, off)) {
    377     goto err;
    378   }
    379   if (pub_key_bytes != NULL) {
    380     BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
    381   }
    382   // TODO(fork): implement
    383   /*
    384   if (!ECPKParameters_print(bp, group, off))
    385     goto err; */
    386   ret = 1;
    387 
    388 err:
    389   if (!ret) {
    390     OPENSSL_PUT_ERROR(EVP, reason);
    391   }
    392   OPENSSL_free(pub_key_bytes);
    393   BN_free(order);
    394   BN_CTX_free(ctx);
    395   OPENSSL_free(buffer);
    396   return ret;
    397 }
    398 
    399 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    400                              ASN1_PCTX *ctx) {
    401   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
    402 }
    403 
    404 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    405                            ASN1_PCTX *ctx) {
    406   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
    407 }
    408 
    409 
    410 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
    411                             ASN1_PCTX *ctx) {
    412   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
    413 }
    414 
    415 
    416 typedef struct {
    417   int type;
    418   int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
    419   int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
    420                     ASN1_PCTX *pctx);
    421   int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
    422                      ASN1_PCTX *pctx);
    423 } EVP_PKEY_PRINT_METHOD;
    424 
    425 static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
    426     {
    427         EVP_PKEY_RSA,
    428         rsa_pub_print,
    429         rsa_priv_print,
    430         NULL /* param_print */,
    431     },
    432     {
    433         EVP_PKEY_DSA,
    434         dsa_pub_print,
    435         dsa_priv_print,
    436         dsa_param_print,
    437     },
    438     {
    439         EVP_PKEY_EC,
    440         eckey_pub_print,
    441         eckey_priv_print,
    442         eckey_param_print,
    443     },
    444 };
    445 
    446 static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods);
    447 
    448 static EVP_PKEY_PRINT_METHOD *find_method(int type) {
    449   for (size_t i = 0; i < kPrintMethodsLen; i++) {
    450     if (kPrintMethods[i].type == type) {
    451       return &kPrintMethods[i];
    452     }
    453   }
    454   return NULL;
    455 }
    456 
    457 static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
    458                              const char *kstr) {
    459   BIO_indent(out, indent, 128);
    460   BIO_printf(out, "%s algorithm unsupported\n", kstr);
    461   return 1;
    462 }
    463 
    464 int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
    465                           ASN1_PCTX *pctx) {
    466   EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
    467   if (method != NULL && method->pub_print != NULL) {
    468     return method->pub_print(out, pkey, indent, pctx);
    469   }
    470   return print_unsupported(out, pkey, indent, "Public Key");
    471 }
    472 
    473 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
    474                            ASN1_PCTX *pctx) {
    475   EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
    476   if (method != NULL && method->priv_print != NULL) {
    477     return method->priv_print(out, pkey, indent, pctx);
    478   }
    479   return print_unsupported(out, pkey, indent, "Private Key");
    480 }
    481 
    482 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
    483                           ASN1_PCTX *pctx) {
    484   EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
    485   if (method != NULL && method->param_print != NULL) {
    486     return method->param_print(out, pkey, indent, pctx);
    487   }
    488   return print_unsupported(out, pkey, indent, "Parameters");
    489 }
    490