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