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