155714Skris/* crypto/asn1/t_pkey.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296465Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296465Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296465Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296465Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296465Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 58160814Ssimon/* ==================================================================== 59160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60296465Sdelphij * Binary polynomial ECC support in OpenSSL originally developed by 61160814Ssimon * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 62160814Ssimon */ 6355714Skris 6455714Skris#include <stdio.h> 6555714Skris#include "cryptlib.h" 66160814Ssimon#include <openssl/objects.h> 6755714Skris#include <openssl/buffer.h> 6855714Skris#include <openssl/bn.h> 69109998Smarkm#ifndef OPENSSL_NO_RSA 70296465Sdelphij# include <openssl/rsa.h> 7155714Skris#endif 72109998Smarkm#ifndef OPENSSL_NO_DH 73296465Sdelphij# include <openssl/dh.h> 7455714Skris#endif 75109998Smarkm#ifndef OPENSSL_NO_DSA 76296465Sdelphij# include <openssl/dsa.h> 7755714Skris#endif 78160814Ssimon#ifndef OPENSSL_NO_EC 79296465Sdelphij# include <openssl/ec.h> 80160814Ssimon#endif 8155714Skris 82296465Sdelphijstatic int print(BIO *fp, const char *str, const BIGNUM *num, 83296465Sdelphij unsigned char *buf, int off); 84160814Ssimon#ifndef OPENSSL_NO_EC 85160814Ssimonstatic int print_bin(BIO *fp, const char *str, const unsigned char *num, 86296465Sdelphij size_t len, int off); 87160814Ssimon#endif 88109998Smarkm#ifndef OPENSSL_NO_RSA 89296465Sdelphij# ifndef OPENSSL_NO_FP_API 90109998Smarkmint RSA_print_fp(FILE *fp, const RSA *x, int off) 91296465Sdelphij{ 92296465Sdelphij BIO *b; 93296465Sdelphij int ret; 9455714Skris 95296465Sdelphij if ((b = BIO_new(BIO_s_file())) == NULL) { 96296465Sdelphij RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB); 97296465Sdelphij return (0); 98296465Sdelphij } 99296465Sdelphij BIO_set_fp(b, fp, BIO_NOCLOSE); 100296465Sdelphij ret = RSA_print(b, x, off); 101296465Sdelphij BIO_free(b); 102296465Sdelphij return (ret); 103296465Sdelphij} 104296465Sdelphij# endif 10555714Skris 106109998Smarkmint RSA_print(BIO *bp, const RSA *x, int off) 107296465Sdelphij{ 108296465Sdelphij char str[128]; 109296465Sdelphij const char *s; 110296465Sdelphij unsigned char *m = NULL; 111296465Sdelphij int ret = 0, mod_len = 0; 112296465Sdelphij size_t buf_len = 0, i; 11355714Skris 114296465Sdelphij if (x->n) 115296465Sdelphij buf_len = (size_t)BN_num_bytes(x->n); 116296465Sdelphij if (x->e) 117296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->e))) 118296465Sdelphij buf_len = i; 119296465Sdelphij if (x->d) 120296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->d))) 121296465Sdelphij buf_len = i; 122296465Sdelphij if (x->p) 123296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->p))) 124296465Sdelphij buf_len = i; 125296465Sdelphij if (x->q) 126296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->q))) 127296465Sdelphij buf_len = i; 128296465Sdelphij if (x->dmp1) 129296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1))) 130296465Sdelphij buf_len = i; 131296465Sdelphij if (x->dmq1) 132296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1))) 133296465Sdelphij buf_len = i; 134296465Sdelphij if (x->iqmp) 135296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp))) 136296465Sdelphij buf_len = i; 137100936Snectar 138296465Sdelphij m = (unsigned char *)OPENSSL_malloc(buf_len + 10); 139296465Sdelphij if (m == NULL) { 140296465Sdelphij RSAerr(RSA_F_RSA_PRINT, ERR_R_MALLOC_FAILURE); 141296465Sdelphij goto err; 142296465Sdelphij } 14355714Skris 144296465Sdelphij if (x->n != NULL) 145296465Sdelphij mod_len = BN_num_bits(x->n); 146160814Ssimon 147296465Sdelphij if (x->d != NULL) { 148296465Sdelphij if (!BIO_indent(bp, off, 128)) 149296465Sdelphij goto err; 150296465Sdelphij if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) 151296465Sdelphij <= 0) 152296465Sdelphij goto err; 153296465Sdelphij } 15455714Skris 155296465Sdelphij if (x->d == NULL) 156296465Sdelphij BIO_snprintf(str, sizeof str, "Modulus (%d bit):", mod_len); 157296465Sdelphij else 158296465Sdelphij BUF_strlcpy(str, "modulus:", sizeof str); 159296465Sdelphij if (!print(bp, str, x->n, m, off)) 160296465Sdelphij goto err; 161296465Sdelphij s = (x->d == NULL) ? "Exponent:" : "publicExponent:"; 162296465Sdelphij if ((x->e != NULL) && !print(bp, s, x->e, m, off)) 163296465Sdelphij goto err; 164296465Sdelphij if ((x->d != NULL) && !print(bp, "privateExponent:", x->d, m, off)) 165296465Sdelphij goto err; 166296465Sdelphij if ((x->p != NULL) && !print(bp, "prime1:", x->p, m, off)) 167296465Sdelphij goto err; 168296465Sdelphij if ((x->q != NULL) && !print(bp, "prime2:", x->q, m, off)) 169296465Sdelphij goto err; 170296465Sdelphij if ((x->dmp1 != NULL) && !print(bp, "exponent1:", x->dmp1, m, off)) 171296465Sdelphij goto err; 172296465Sdelphij if ((x->dmq1 != NULL) && !print(bp, "exponent2:", x->dmq1, m, off)) 173296465Sdelphij goto err; 174296465Sdelphij if ((x->iqmp != NULL) && !print(bp, "coefficient:", x->iqmp, m, off)) 175296465Sdelphij goto err; 176296465Sdelphij ret = 1; 177296465Sdelphij err: 178296465Sdelphij if (m != NULL) 179296465Sdelphij OPENSSL_free(m); 180296465Sdelphij return (ret); 181296465Sdelphij} 182296465Sdelphij#endif /* OPENSSL_NO_RSA */ 18355714Skris 184109998Smarkm#ifndef OPENSSL_NO_DSA 185296465Sdelphij# ifndef OPENSSL_NO_FP_API 186109998Smarkmint DSA_print_fp(FILE *fp, const DSA *x, int off) 187296465Sdelphij{ 188296465Sdelphij BIO *b; 189296465Sdelphij int ret; 19055714Skris 191296465Sdelphij if ((b = BIO_new(BIO_s_file())) == NULL) { 192296465Sdelphij DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB); 193296465Sdelphij return (0); 194296465Sdelphij } 195296465Sdelphij BIO_set_fp(b, fp, BIO_NOCLOSE); 196296465Sdelphij ret = DSA_print(b, x, off); 197296465Sdelphij BIO_free(b); 198296465Sdelphij return (ret); 199296465Sdelphij} 200296465Sdelphij# endif 20155714Skris 202109998Smarkmint DSA_print(BIO *bp, const DSA *x, int off) 203296465Sdelphij{ 204296465Sdelphij unsigned char *m = NULL; 205296465Sdelphij int ret = 0; 206296465Sdelphij size_t buf_len = 0, i; 20755714Skris 208296465Sdelphij if (x->p) 209296465Sdelphij buf_len = (size_t)BN_num_bytes(x->p); 210296465Sdelphij if (x->q) 211296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->q))) 212296465Sdelphij buf_len = i; 213296465Sdelphij if (x->g) 214296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->g))) 215296465Sdelphij buf_len = i; 216296465Sdelphij if (x->priv_key) 217296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key))) 218296465Sdelphij buf_len = i; 219296465Sdelphij if (x->pub_key) 220296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key))) 221296465Sdelphij buf_len = i; 222100936Snectar 223296465Sdelphij m = (unsigned char *)OPENSSL_malloc(buf_len + 10); 224296465Sdelphij if (m == NULL) { 225296465Sdelphij DSAerr(DSA_F_DSA_PRINT, ERR_R_MALLOC_FAILURE); 226296465Sdelphij goto err; 227296465Sdelphij } 22855714Skris 229296465Sdelphij if (x->priv_key != NULL) { 230296465Sdelphij if (!BIO_indent(bp, off, 128)) 231296465Sdelphij goto err; 232296465Sdelphij if (BIO_printf(bp, "Private-Key: (%d bit)\n", BN_num_bits(x->p)) 233296465Sdelphij <= 0) 234296465Sdelphij goto err; 235296465Sdelphij } 23655714Skris 237296465Sdelphij if ((x->priv_key != NULL) && !print(bp, "priv:", x->priv_key, m, off)) 238296465Sdelphij goto err; 239296465Sdelphij if ((x->pub_key != NULL) && !print(bp, "pub: ", x->pub_key, m, off)) 240296465Sdelphij goto err; 241296465Sdelphij if ((x->p != NULL) && !print(bp, "P: ", x->p, m, off)) 242296465Sdelphij goto err; 243296465Sdelphij if ((x->q != NULL) && !print(bp, "Q: ", x->q, m, off)) 244296465Sdelphij goto err; 245296465Sdelphij if ((x->g != NULL) && !print(bp, "G: ", x->g, m, off)) 246296465Sdelphij goto err; 247296465Sdelphij ret = 1; 248296465Sdelphij err: 249296465Sdelphij if (m != NULL) 250296465Sdelphij OPENSSL_free(m); 251296465Sdelphij return (ret); 252296465Sdelphij} 253296465Sdelphij#endif /* !OPENSSL_NO_DSA */ 25455714Skris 255160814Ssimon#ifndef OPENSSL_NO_EC 256296465Sdelphij# ifndef OPENSSL_NO_FP_API 257160814Ssimonint ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) 258296465Sdelphij{ 259296465Sdelphij BIO *b; 260296465Sdelphij int ret; 261160814Ssimon 262296465Sdelphij if ((b = BIO_new(BIO_s_file())) == NULL) { 263296465Sdelphij ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB); 264296465Sdelphij return (0); 265296465Sdelphij } 266296465Sdelphij BIO_set_fp(b, fp, BIO_NOCLOSE); 267296465Sdelphij ret = ECPKParameters_print(b, x, off); 268296465Sdelphij BIO_free(b); 269296465Sdelphij return (ret); 270296465Sdelphij} 271160814Ssimon 272160814Ssimonint EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) 273296465Sdelphij{ 274296465Sdelphij BIO *b; 275296465Sdelphij int ret; 276160814Ssimon 277296465Sdelphij if ((b = BIO_new(BIO_s_file())) == NULL) { 278296465Sdelphij ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); 279296465Sdelphij return (0); 280296465Sdelphij } 281296465Sdelphij BIO_set_fp(b, fp, BIO_NOCLOSE); 282296465Sdelphij ret = EC_KEY_print(b, x, off); 283296465Sdelphij BIO_free(b); 284296465Sdelphij return (ret); 285296465Sdelphij} 286296465Sdelphij# endif 287296465Sdelphij 288160814Ssimonint ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) 289296465Sdelphij{ 290296465Sdelphij unsigned char *buffer = NULL; 291296465Sdelphij size_t buf_len = 0, i; 292296465Sdelphij int ret = 0, reason = ERR_R_BIO_LIB; 293296465Sdelphij BN_CTX *ctx = NULL; 294296465Sdelphij const EC_POINT *point = NULL; 295296465Sdelphij BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, 296296465Sdelphij *order = NULL, *cofactor = NULL; 297296465Sdelphij const unsigned char *seed; 298296465Sdelphij size_t seed_len = 0; 299160814Ssimon 300296465Sdelphij static const char *gen_compressed = "Generator (compressed):"; 301296465Sdelphij static const char *gen_uncompressed = "Generator (uncompressed):"; 302296465Sdelphij static const char *gen_hybrid = "Generator (hybrid):"; 303160814Ssimon 304296465Sdelphij if (!x) { 305296465Sdelphij reason = ERR_R_PASSED_NULL_PARAMETER; 306296465Sdelphij goto err; 307296465Sdelphij } 308160814Ssimon 309296465Sdelphij if (EC_GROUP_get_asn1_flag(x)) { 310296465Sdelphij /* the curve parameter are given by an asn1 OID */ 311296465Sdelphij int nid; 312160814Ssimon 313296465Sdelphij if (!BIO_indent(bp, off, 128)) 314296465Sdelphij goto err; 315160814Ssimon 316296465Sdelphij nid = EC_GROUP_get_curve_name(x); 317296465Sdelphij if (nid == 0) 318296465Sdelphij goto err; 319160814Ssimon 320296465Sdelphij if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) 321296465Sdelphij goto err; 322296465Sdelphij if (BIO_printf(bp, "\n") <= 0) 323296465Sdelphij goto err; 324296465Sdelphij } else { 325296465Sdelphij /* explicit parameters */ 326296465Sdelphij int is_char_two = 0; 327296465Sdelphij point_conversion_form_t form; 328296465Sdelphij int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); 329160814Ssimon 330296465Sdelphij if (tmp_nid == NID_X9_62_characteristic_two_field) 331296465Sdelphij is_char_two = 1; 332160814Ssimon 333296465Sdelphij if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || 334296465Sdelphij (b = BN_new()) == NULL || (order = BN_new()) == NULL || 335296465Sdelphij (cofactor = BN_new()) == NULL) { 336296465Sdelphij reason = ERR_R_MALLOC_FAILURE; 337296465Sdelphij goto err; 338296465Sdelphij } 339160814Ssimon 340296465Sdelphij if (is_char_two) { 341296465Sdelphij if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) { 342296465Sdelphij reason = ERR_R_EC_LIB; 343296465Sdelphij goto err; 344296465Sdelphij } 345296465Sdelphij } else { /* prime field */ 346160814Ssimon 347296465Sdelphij if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) { 348296465Sdelphij reason = ERR_R_EC_LIB; 349296465Sdelphij goto err; 350296465Sdelphij } 351296465Sdelphij } 352160814Ssimon 353296465Sdelphij if ((point = EC_GROUP_get0_generator(x)) == NULL) { 354296465Sdelphij reason = ERR_R_EC_LIB; 355296465Sdelphij goto err; 356296465Sdelphij } 357296465Sdelphij if (!EC_GROUP_get_order(x, order, NULL) || 358296465Sdelphij !EC_GROUP_get_cofactor(x, cofactor, NULL)) { 359296465Sdelphij reason = ERR_R_EC_LIB; 360296465Sdelphij goto err; 361296465Sdelphij } 362160814Ssimon 363296465Sdelphij form = EC_GROUP_get_point_conversion_form(x); 364160814Ssimon 365296465Sdelphij if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { 366296465Sdelphij reason = ERR_R_EC_LIB; 367296465Sdelphij goto err; 368296465Sdelphij } 369160814Ssimon 370296465Sdelphij buf_len = (size_t)BN_num_bytes(p); 371296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(a))) 372296465Sdelphij buf_len = i; 373296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(b))) 374296465Sdelphij buf_len = i; 375296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(gen))) 376296465Sdelphij buf_len = i; 377296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(order))) 378296465Sdelphij buf_len = i; 379296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 380296465Sdelphij buf_len = i; 381160814Ssimon 382296465Sdelphij if ((seed = EC_GROUP_get0_seed(x)) != NULL) 383296465Sdelphij seed_len = EC_GROUP_get_seed_len(x); 384160814Ssimon 385296465Sdelphij buf_len += 10; 386296465Sdelphij if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { 387296465Sdelphij reason = ERR_R_MALLOC_FAILURE; 388296465Sdelphij goto err; 389296465Sdelphij } 390160814Ssimon 391296465Sdelphij if (!BIO_indent(bp, off, 128)) 392296465Sdelphij goto err; 393160814Ssimon 394296465Sdelphij /* print the 'short name' of the field type */ 395296465Sdelphij if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) 396296465Sdelphij <= 0) 397296465Sdelphij goto err; 398160814Ssimon 399296465Sdelphij if (is_char_two) { 400296465Sdelphij /* print the 'short name' of the base type OID */ 401296465Sdelphij int basis_type = EC_GROUP_get_basis_type(x); 402296465Sdelphij if (basis_type == 0) 403296465Sdelphij goto err; 404296465Sdelphij 405296465Sdelphij if (!BIO_indent(bp, off, 128)) 406296465Sdelphij goto err; 407296465Sdelphij 408296465Sdelphij if (BIO_printf(bp, "Basis Type: %s\n", 409296465Sdelphij OBJ_nid2sn(basis_type)) <= 0) 410296465Sdelphij goto err; 411296465Sdelphij 412296465Sdelphij /* print the polynomial */ 413296465Sdelphij if ((p != NULL) && !print(bp, "Polynomial:", p, buffer, off)) 414296465Sdelphij goto err; 415296465Sdelphij } else { 416296465Sdelphij if ((p != NULL) && !print(bp, "Prime:", p, buffer, off)) 417296465Sdelphij goto err; 418296465Sdelphij } 419296465Sdelphij if ((a != NULL) && !print(bp, "A: ", a, buffer, off)) 420296465Sdelphij goto err; 421296465Sdelphij if ((b != NULL) && !print(bp, "B: ", b, buffer, off)) 422296465Sdelphij goto err; 423296465Sdelphij if (form == POINT_CONVERSION_COMPRESSED) { 424296465Sdelphij if ((gen != NULL) && !print(bp, gen_compressed, gen, buffer, off)) 425296465Sdelphij goto err; 426296465Sdelphij } else if (form == POINT_CONVERSION_UNCOMPRESSED) { 427296465Sdelphij if ((gen != NULL) && !print(bp, gen_uncompressed, gen, 428296465Sdelphij buffer, off)) 429296465Sdelphij goto err; 430296465Sdelphij } else { /* form == POINT_CONVERSION_HYBRID */ 431296465Sdelphij 432296465Sdelphij if ((gen != NULL) && !print(bp, gen_hybrid, gen, buffer, off)) 433296465Sdelphij goto err; 434296465Sdelphij } 435296465Sdelphij if ((order != NULL) && !print(bp, "Order: ", order, buffer, off)) 436296465Sdelphij goto err; 437296465Sdelphij if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor, 438296465Sdelphij buffer, off)) 439296465Sdelphij goto err; 440296465Sdelphij if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) 441296465Sdelphij goto err; 442296465Sdelphij } 443296465Sdelphij ret = 1; 444296465Sdelphij err: 445296465Sdelphij if (!ret) 446296465Sdelphij ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); 447296465Sdelphij if (p) 448296465Sdelphij BN_free(p); 449296465Sdelphij if (a) 450296465Sdelphij BN_free(a); 451296465Sdelphij if (b) 452296465Sdelphij BN_free(b); 453296465Sdelphij if (gen) 454296465Sdelphij BN_free(gen); 455296465Sdelphij if (order) 456296465Sdelphij BN_free(order); 457296465Sdelphij if (cofactor) 458296465Sdelphij BN_free(cofactor); 459296465Sdelphij if (ctx) 460296465Sdelphij BN_CTX_free(ctx); 461296465Sdelphij if (buffer != NULL) 462296465Sdelphij OPENSSL_free(buffer); 463296465Sdelphij return (ret); 464296465Sdelphij} 465296465Sdelphij 466160814Ssimonint EC_KEY_print(BIO *bp, const EC_KEY *x, int off) 467296465Sdelphij{ 468296465Sdelphij unsigned char *buffer = NULL; 469296465Sdelphij size_t buf_len = 0, i; 470296465Sdelphij int ret = 0, reason = ERR_R_BIO_LIB; 471296465Sdelphij BIGNUM *pub_key = NULL, *order = NULL; 472296465Sdelphij BN_CTX *ctx = NULL; 473296465Sdelphij const EC_GROUP *group; 474296465Sdelphij const EC_POINT *public_key; 475296465Sdelphij const BIGNUM *priv_key; 476160814Ssimon 477296465Sdelphij if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 478296465Sdelphij reason = ERR_R_PASSED_NULL_PARAMETER; 479296465Sdelphij goto err; 480296465Sdelphij } 481160814Ssimon 482296465Sdelphij public_key = EC_KEY_get0_public_key(x); 483296465Sdelphij if ((pub_key = EC_POINT_point2bn(group, public_key, 484296465Sdelphij EC_KEY_get_conv_form(x), NULL, 485296465Sdelphij ctx)) == NULL) { 486296465Sdelphij reason = ERR_R_EC_LIB; 487296465Sdelphij goto err; 488296465Sdelphij } 489160814Ssimon 490296465Sdelphij buf_len = (size_t)BN_num_bytes(pub_key); 491296465Sdelphij priv_key = EC_KEY_get0_private_key(x); 492296465Sdelphij if (priv_key != NULL) { 493296465Sdelphij if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len) 494296465Sdelphij buf_len = i; 495296465Sdelphij } 496160814Ssimon 497296465Sdelphij buf_len += 10; 498296465Sdelphij if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { 499296465Sdelphij reason = ERR_R_MALLOC_FAILURE; 500296465Sdelphij goto err; 501296465Sdelphij } 502160814Ssimon 503296465Sdelphij if (priv_key != NULL) { 504296465Sdelphij if (!BIO_indent(bp, off, 128)) 505296465Sdelphij goto err; 506296465Sdelphij if ((order = BN_new()) == NULL) 507296465Sdelphij goto err; 508296465Sdelphij if (!EC_GROUP_get_order(group, order, NULL)) 509296465Sdelphij goto err; 510296465Sdelphij if (BIO_printf(bp, "Private-Key: (%d bit)\n", 511296465Sdelphij BN_num_bits(order)) <= 0) 512296465Sdelphij goto err; 513296465Sdelphij } 51455714Skris 515296465Sdelphij if ((priv_key != NULL) && !print(bp, "priv:", priv_key, buffer, off)) 516296465Sdelphij goto err; 517296465Sdelphij if ((pub_key != NULL) && !print(bp, "pub: ", pub_key, buffer, off)) 518296465Sdelphij goto err; 519296465Sdelphij if (!ECPKParameters_print(bp, group, off)) 520296465Sdelphij goto err; 521296465Sdelphij ret = 1; 522296465Sdelphij err: 523296465Sdelphij if (!ret) 524296465Sdelphij ECerr(EC_F_EC_KEY_PRINT, reason); 525296465Sdelphij if (pub_key) 526296465Sdelphij BN_free(pub_key); 527296465Sdelphij if (order) 528296465Sdelphij BN_free(order); 529296465Sdelphij if (ctx) 530296465Sdelphij BN_CTX_free(ctx); 531296465Sdelphij if (buffer != NULL) 532296465Sdelphij OPENSSL_free(buffer); 533296465Sdelphij return (ret); 534296465Sdelphij} 535296465Sdelphij#endif /* OPENSSL_NO_EC */ 53655714Skris 537296465Sdelphijstatic int print(BIO *bp, const char *number, const BIGNUM *num, 538296465Sdelphij unsigned char *buf, int off) 539296465Sdelphij{ 540296465Sdelphij int n, i; 541296465Sdelphij const char *neg; 54255714Skris 543296465Sdelphij if (num == NULL) 544296465Sdelphij return (1); 545296465Sdelphij neg = (BN_is_negative(num)) ? "-" : ""; 546296465Sdelphij if (!BIO_indent(bp, off, 128)) 547296465Sdelphij return 0; 548296465Sdelphij if (BN_is_zero(num)) { 549296465Sdelphij if (BIO_printf(bp, "%s 0\n", number) <= 0) 550296465Sdelphij return 0; 551296465Sdelphij return 1; 552296465Sdelphij } 55355714Skris 554296465Sdelphij if (BN_num_bytes(num) <= BN_BYTES) { 555296465Sdelphij if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg, 556296465Sdelphij (unsigned long)num->d[0], neg, 557296465Sdelphij (unsigned long)num->d[0]) 558296465Sdelphij <= 0) 559296465Sdelphij return (0); 560296465Sdelphij } else { 561296465Sdelphij buf[0] = 0; 562296465Sdelphij if (BIO_printf(bp, "%s%s", number, 563296465Sdelphij (neg[0] == '-') ? " (Negative)" : "") <= 0) 564296465Sdelphij return (0); 565296465Sdelphij n = BN_bn2bin(num, &buf[1]); 566296465Sdelphij 567296465Sdelphij if (buf[1] & 0x80) 568296465Sdelphij n++; 569296465Sdelphij else 570296465Sdelphij buf++; 571296465Sdelphij 572296465Sdelphij for (i = 0; i < n; i++) { 573296465Sdelphij if ((i % 15) == 0) { 574296465Sdelphij if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128)) 575296465Sdelphij return 0; 576296465Sdelphij } 577296465Sdelphij if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") 578296465Sdelphij <= 0) 579296465Sdelphij return (0); 580296465Sdelphij } 581296465Sdelphij if (BIO_write(bp, "\n", 1) <= 0) 582296465Sdelphij return (0); 583296465Sdelphij } 584296465Sdelphij return (1); 585296465Sdelphij} 586296465Sdelphij 587160814Ssimon#ifndef OPENSSL_NO_EC 588160814Ssimonstatic int print_bin(BIO *fp, const char *name, const unsigned char *buf, 589296465Sdelphij size_t len, int off) 590296465Sdelphij{ 591296465Sdelphij size_t i; 592296465Sdelphij char str[128]; 593160814Ssimon 594296465Sdelphij if (buf == NULL) 595296465Sdelphij return 1; 596296465Sdelphij if (off) { 597296465Sdelphij if (off > 128) 598296465Sdelphij off = 128; 599296465Sdelphij memset(str, ' ', off); 600296465Sdelphij if (BIO_write(fp, str, off) <= 0) 601296465Sdelphij return 0; 602296465Sdelphij } 603160814Ssimon 604296465Sdelphij if (BIO_printf(fp, "%s", name) <= 0) 605296465Sdelphij return 0; 606160814Ssimon 607296465Sdelphij for (i = 0; i < len; i++) { 608296465Sdelphij if ((i % 15) == 0) { 609296465Sdelphij str[0] = '\n'; 610296465Sdelphij memset(&(str[1]), ' ', off + 4); 611296465Sdelphij if (BIO_write(fp, str, off + 1 + 4) <= 0) 612296465Sdelphij return 0; 613296465Sdelphij } 614296465Sdelphij if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= 615296465Sdelphij 0) 616296465Sdelphij return 0; 617296465Sdelphij } 618296465Sdelphij if (BIO_write(fp, "\n", 1) <= 0) 619296465Sdelphij return 0; 620160814Ssimon 621296465Sdelphij return 1; 622296465Sdelphij} 623160814Ssimon#endif 624160814Ssimon 625109998Smarkm#ifndef OPENSSL_NO_DH 626296465Sdelphij# ifndef OPENSSL_NO_FP_API 627109998Smarkmint DHparams_print_fp(FILE *fp, const DH *x) 628296465Sdelphij{ 629296465Sdelphij BIO *b; 630296465Sdelphij int ret; 63155714Skris 632296465Sdelphij if ((b = BIO_new(BIO_s_file())) == NULL) { 633296465Sdelphij DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB); 634296465Sdelphij return (0); 635296465Sdelphij } 636296465Sdelphij BIO_set_fp(b, fp, BIO_NOCLOSE); 637296465Sdelphij ret = DHparams_print(b, x); 638296465Sdelphij BIO_free(b); 639296465Sdelphij return (ret); 640296465Sdelphij} 641296465Sdelphij# endif 64255714Skris 643109998Smarkmint DHparams_print(BIO *bp, const DH *x) 644296465Sdelphij{ 645296465Sdelphij unsigned char *m = NULL; 646296465Sdelphij int reason = ERR_R_BUF_LIB, ret = 0; 647296465Sdelphij size_t buf_len = 0, i; 64855714Skris 649296465Sdelphij if (x->p) 650296465Sdelphij buf_len = (size_t)BN_num_bytes(x->p); 651296465Sdelphij else { 652296465Sdelphij reason = ERR_R_PASSED_NULL_PARAMETER; 653296465Sdelphij goto err; 654296465Sdelphij } 655296465Sdelphij if (x->g) 656296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->g))) 657296465Sdelphij buf_len = i; 658296465Sdelphij m = (unsigned char *)OPENSSL_malloc(buf_len + 10); 659296465Sdelphij if (m == NULL) { 660296465Sdelphij reason = ERR_R_MALLOC_FAILURE; 661296465Sdelphij goto err; 662296465Sdelphij } 66355714Skris 664296465Sdelphij if (BIO_printf(bp, "Diffie-Hellman-Parameters: (%d bit)\n", 665296465Sdelphij BN_num_bits(x->p)) <= 0) 666296465Sdelphij goto err; 667296465Sdelphij if (!print(bp, "prime:", x->p, m, 4)) 668296465Sdelphij goto err; 669296465Sdelphij if (!print(bp, "generator:", x->g, m, 4)) 670296465Sdelphij goto err; 671296465Sdelphij if (x->length != 0) { 672296465Sdelphij if (BIO_printf(bp, " recommended-private-length: %d bits\n", 673296465Sdelphij (int)x->length) <= 0) 674296465Sdelphij goto err; 675296465Sdelphij } 676296465Sdelphij ret = 1; 677296465Sdelphij if (0) { 678296465Sdelphij err: 679296465Sdelphij DHerr(DH_F_DHPARAMS_PRINT, reason); 680296465Sdelphij } 681296465Sdelphij if (m != NULL) 682296465Sdelphij OPENSSL_free(m); 683296465Sdelphij return (ret); 684296465Sdelphij} 68555714Skris#endif 68655714Skris 687109998Smarkm#ifndef OPENSSL_NO_DSA 688296465Sdelphij# ifndef OPENSSL_NO_FP_API 689109998Smarkmint DSAparams_print_fp(FILE *fp, const DSA *x) 690296465Sdelphij{ 691296465Sdelphij BIO *b; 692296465Sdelphij int ret; 69355714Skris 694296465Sdelphij if ((b = BIO_new(BIO_s_file())) == NULL) { 695296465Sdelphij DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB); 696296465Sdelphij return (0); 697296465Sdelphij } 698296465Sdelphij BIO_set_fp(b, fp, BIO_NOCLOSE); 699296465Sdelphij ret = DSAparams_print(b, x); 700296465Sdelphij BIO_free(b); 701296465Sdelphij return (ret); 702296465Sdelphij} 703296465Sdelphij# endif 70455714Skris 705109998Smarkmint DSAparams_print(BIO *bp, const DSA *x) 706296465Sdelphij{ 707296465Sdelphij unsigned char *m = NULL; 708296465Sdelphij int ret = 0; 709296465Sdelphij size_t buf_len = 0, i; 71055714Skris 711296465Sdelphij if (x->p) 712296465Sdelphij buf_len = (size_t)BN_num_bytes(x->p); 713296465Sdelphij else { 714296465Sdelphij DSAerr(DSA_F_DSAPARAMS_PRINT, DSA_R_MISSING_PARAMETERS); 715296465Sdelphij goto err; 716296465Sdelphij } 717296465Sdelphij if (x->q) 718296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->q))) 719296465Sdelphij buf_len = i; 720296465Sdelphij if (x->g) 721296465Sdelphij if (buf_len < (i = (size_t)BN_num_bytes(x->g))) 722296465Sdelphij buf_len = i; 723296465Sdelphij m = (unsigned char *)OPENSSL_malloc(buf_len + 10); 724296465Sdelphij if (m == NULL) { 725296465Sdelphij DSAerr(DSA_F_DSAPARAMS_PRINT, ERR_R_MALLOC_FAILURE); 726296465Sdelphij goto err; 727296465Sdelphij } 72855714Skris 729296465Sdelphij if (BIO_printf(bp, "DSA-Parameters: (%d bit)\n", BN_num_bits(x->p)) <= 0) 730296465Sdelphij goto err; 731296465Sdelphij if (!print(bp, "p:", x->p, m, 4)) 732296465Sdelphij goto err; 733296465Sdelphij if ((x->q != NULL) && !print(bp, "q:", x->q, m, 4)) 734296465Sdelphij goto err; 735296465Sdelphij if ((x->g != NULL) && !print(bp, "g:", x->g, m, 4)) 736296465Sdelphij goto err; 737296465Sdelphij ret = 1; 738296465Sdelphij err: 739296465Sdelphij if (m != NULL) 740296465Sdelphij OPENSSL_free(m); 741296465Sdelphij return (ret); 742296465Sdelphij} 74355714Skris 744296465Sdelphij#endif /* !OPENSSL_NO_DSA */ 74555714Skris 746160814Ssimon#ifndef OPENSSL_NO_EC 747296465Sdelphij# ifndef OPENSSL_NO_FP_API 748160814Ssimonint ECParameters_print_fp(FILE *fp, const EC_KEY *x) 749296465Sdelphij{ 750296465Sdelphij BIO *b; 751296465Sdelphij int ret; 752160814Ssimon 753296465Sdelphij if ((b = BIO_new(BIO_s_file())) == NULL) { 754296465Sdelphij ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); 755296465Sdelphij return (0); 756296465Sdelphij } 757296465Sdelphij BIO_set_fp(b, fp, BIO_NOCLOSE); 758296465Sdelphij ret = ECParameters_print(b, x); 759296465Sdelphij BIO_free(b); 760296465Sdelphij return (ret); 761296465Sdelphij} 762296465Sdelphij# endif 763296465Sdelphij 764160814Ssimonint ECParameters_print(BIO *bp, const EC_KEY *x) 765296465Sdelphij{ 766296465Sdelphij int reason = ERR_R_EC_LIB, ret = 0; 767296465Sdelphij BIGNUM *order = NULL; 768296465Sdelphij const EC_GROUP *group; 769160814Ssimon 770296465Sdelphij if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 771296465Sdelphij reason = ERR_R_PASSED_NULL_PARAMETER;; 772296465Sdelphij goto err; 773296465Sdelphij } 774160814Ssimon 775296465Sdelphij if ((order = BN_new()) == NULL) { 776296465Sdelphij reason = ERR_R_MALLOC_FAILURE; 777296465Sdelphij goto err; 778296465Sdelphij } 779296465Sdelphij 780296465Sdelphij if (!EC_GROUP_get_order(group, order, NULL)) { 781296465Sdelphij reason = ERR_R_EC_LIB; 782296465Sdelphij goto err; 783296465Sdelphij } 784296465Sdelphij 785296465Sdelphij if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n", 786296465Sdelphij BN_num_bits(order)) <= 0) 787296465Sdelphij goto err; 788296465Sdelphij if (!ECPKParameters_print(bp, group, 4)) 789296465Sdelphij goto err; 790296465Sdelphij ret = 1; 791296465Sdelphij err: 792296465Sdelphij if (order) 793296465Sdelphij BN_free(order); 794296465Sdelphij ECerr(EC_F_ECPARAMETERS_PRINT, reason); 795296465Sdelphij return (ret); 796296465Sdelphij} 797296465Sdelphij 798160814Ssimon#endif 799