1*8fb009dcSAndroid Build Coastguard Worker /* ====================================================================
2*8fb009dcSAndroid Build Coastguard Worker * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3*8fb009dcSAndroid Build Coastguard Worker *
4*8fb009dcSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
5*8fb009dcSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
6*8fb009dcSAndroid Build Coastguard Worker * are met:
7*8fb009dcSAndroid Build Coastguard Worker *
8*8fb009dcSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
9*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*8fb009dcSAndroid Build Coastguard Worker *
11*8fb009dcSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
12*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in
13*8fb009dcSAndroid Build Coastguard Worker * the documentation and/or other materials provided with the
14*8fb009dcSAndroid Build Coastguard Worker * distribution.
15*8fb009dcSAndroid Build Coastguard Worker *
16*8fb009dcSAndroid Build Coastguard Worker * 3. All advertising materials mentioning features or use of this
17*8fb009dcSAndroid Build Coastguard Worker * software must display the following acknowledgment:
18*8fb009dcSAndroid Build Coastguard Worker * "This product includes software developed by the OpenSSL Project
19*8fb009dcSAndroid Build Coastguard Worker * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20*8fb009dcSAndroid Build Coastguard Worker *
21*8fb009dcSAndroid Build Coastguard Worker * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22*8fb009dcSAndroid Build Coastguard Worker * endorse or promote products derived from this software without
23*8fb009dcSAndroid Build Coastguard Worker * prior written permission. For written permission, please contact
24*8fb009dcSAndroid Build Coastguard Worker * [email protected].
25*8fb009dcSAndroid Build Coastguard Worker *
26*8fb009dcSAndroid Build Coastguard Worker * 5. Products derived from this software may not be called "OpenSSL"
27*8fb009dcSAndroid Build Coastguard Worker * nor may "OpenSSL" appear in their names without prior written
28*8fb009dcSAndroid Build Coastguard Worker * permission of the OpenSSL Project.
29*8fb009dcSAndroid Build Coastguard Worker *
30*8fb009dcSAndroid Build Coastguard Worker * 6. Redistributions of any form whatsoever must retain the following
31*8fb009dcSAndroid Build Coastguard Worker * acknowledgment:
32*8fb009dcSAndroid Build Coastguard Worker * "This product includes software developed by the OpenSSL Project
33*8fb009dcSAndroid Build Coastguard Worker * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34*8fb009dcSAndroid Build Coastguard Worker *
35*8fb009dcSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36*8fb009dcSAndroid Build Coastguard Worker * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37*8fb009dcSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38*8fb009dcSAndroid Build Coastguard Worker * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39*8fb009dcSAndroid Build Coastguard Worker * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40*8fb009dcSAndroid Build Coastguard Worker * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41*8fb009dcSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42*8fb009dcSAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43*8fb009dcSAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44*8fb009dcSAndroid Build Coastguard Worker * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45*8fb009dcSAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46*8fb009dcSAndroid Build Coastguard Worker * OF THE POSSIBILITY OF SUCH DAMAGE.
47*8fb009dcSAndroid Build Coastguard Worker * ====================================================================
48*8fb009dcSAndroid Build Coastguard Worker *
49*8fb009dcSAndroid Build Coastguard Worker * This product includes cryptographic software written by Eric Young
50*8fb009dcSAndroid Build Coastguard Worker * ([email protected]). This product includes software written by Tim
51*8fb009dcSAndroid Build Coastguard Worker * Hudson ([email protected]). */
52*8fb009dcSAndroid Build Coastguard Worker
53*8fb009dcSAndroid Build Coastguard Worker #include <openssl/evp.h>
54*8fb009dcSAndroid Build Coastguard Worker
55*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bio.h>
56*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bn.h>
57*8fb009dcSAndroid Build Coastguard Worker #include <openssl/dsa.h>
58*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ec.h>
59*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ec_key.h>
60*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
61*8fb009dcSAndroid Build Coastguard Worker #include <openssl/rsa.h>
62*8fb009dcSAndroid Build Coastguard Worker
63*8fb009dcSAndroid Build Coastguard Worker #include "../internal.h"
64*8fb009dcSAndroid Build Coastguard Worker #include "../fipsmodule/rsa/internal.h"
65*8fb009dcSAndroid Build Coastguard Worker
66*8fb009dcSAndroid Build Coastguard Worker
print_hex(BIO * bp,const uint8_t * data,size_t len,int off)67*8fb009dcSAndroid Build Coastguard Worker static int print_hex(BIO *bp, const uint8_t *data, size_t len, int off) {
68*8fb009dcSAndroid Build Coastguard Worker for (size_t i = 0; i < len; i++) {
69*8fb009dcSAndroid Build Coastguard Worker if ((i % 15) == 0) {
70*8fb009dcSAndroid Build Coastguard Worker if (BIO_puts(bp, "\n") <= 0 || //
71*8fb009dcSAndroid Build Coastguard Worker !BIO_indent(bp, off + 4, 128)) {
72*8fb009dcSAndroid Build Coastguard Worker return 0;
73*8fb009dcSAndroid Build Coastguard Worker }
74*8fb009dcSAndroid Build Coastguard Worker }
75*8fb009dcSAndroid Build Coastguard Worker if (BIO_printf(bp, "%02x%s", data[i], (i + 1 == len) ? "" : ":") <= 0) {
76*8fb009dcSAndroid Build Coastguard Worker return 0;
77*8fb009dcSAndroid Build Coastguard Worker }
78*8fb009dcSAndroid Build Coastguard Worker }
79*8fb009dcSAndroid Build Coastguard Worker if (BIO_write(bp, "\n", 1) <= 0) {
80*8fb009dcSAndroid Build Coastguard Worker return 0;
81*8fb009dcSAndroid Build Coastguard Worker }
82*8fb009dcSAndroid Build Coastguard Worker return 1;
83*8fb009dcSAndroid Build Coastguard Worker }
84*8fb009dcSAndroid Build Coastguard Worker
bn_print(BIO * bp,const char * name,const BIGNUM * num,int off)85*8fb009dcSAndroid Build Coastguard Worker static int bn_print(BIO *bp, const char *name, const BIGNUM *num, int off) {
86*8fb009dcSAndroid Build Coastguard Worker if (num == NULL) {
87*8fb009dcSAndroid Build Coastguard Worker return 1;
88*8fb009dcSAndroid Build Coastguard Worker }
89*8fb009dcSAndroid Build Coastguard Worker
90*8fb009dcSAndroid Build Coastguard Worker if (!BIO_indent(bp, off, 128)) {
91*8fb009dcSAndroid Build Coastguard Worker return 0;
92*8fb009dcSAndroid Build Coastguard Worker }
93*8fb009dcSAndroid Build Coastguard Worker if (BN_is_zero(num)) {
94*8fb009dcSAndroid Build Coastguard Worker if (BIO_printf(bp, "%s 0\n", name) <= 0) {
95*8fb009dcSAndroid Build Coastguard Worker return 0;
96*8fb009dcSAndroid Build Coastguard Worker }
97*8fb009dcSAndroid Build Coastguard Worker return 1;
98*8fb009dcSAndroid Build Coastguard Worker }
99*8fb009dcSAndroid Build Coastguard Worker
100*8fb009dcSAndroid Build Coastguard Worker uint64_t u64;
101*8fb009dcSAndroid Build Coastguard Worker if (BN_get_u64(num, &u64)) {
102*8fb009dcSAndroid Build Coastguard Worker const char *neg = BN_is_negative(num) ? "-" : "";
103*8fb009dcSAndroid Build Coastguard Worker return BIO_printf(bp, "%s %s%" PRIu64 " (%s0x%" PRIx64 ")\n", name, neg,
104*8fb009dcSAndroid Build Coastguard Worker u64, neg, u64) > 0;
105*8fb009dcSAndroid Build Coastguard Worker }
106*8fb009dcSAndroid Build Coastguard Worker
107*8fb009dcSAndroid Build Coastguard Worker if (BIO_printf(bp, "%s%s", name,
108*8fb009dcSAndroid Build Coastguard Worker (BN_is_negative(num)) ? " (Negative)" : "") <= 0) {
109*8fb009dcSAndroid Build Coastguard Worker return 0;
110*8fb009dcSAndroid Build Coastguard Worker }
111*8fb009dcSAndroid Build Coastguard Worker
112*8fb009dcSAndroid Build Coastguard Worker // Print |num| in hex, adding a leading zero, as in ASN.1, if the high bit
113*8fb009dcSAndroid Build Coastguard Worker // is set.
114*8fb009dcSAndroid Build Coastguard Worker //
115*8fb009dcSAndroid Build Coastguard Worker // TODO(davidben): Do we need to do this? We already print "(Negative)" above
116*8fb009dcSAndroid Build Coastguard Worker // and negative values are never valid in keys anyway.
117*8fb009dcSAndroid Build Coastguard Worker size_t len = BN_num_bytes(num);
118*8fb009dcSAndroid Build Coastguard Worker uint8_t *buf = OPENSSL_malloc(len + 1);
119*8fb009dcSAndroid Build Coastguard Worker if (buf == NULL) {
120*8fb009dcSAndroid Build Coastguard Worker return 0;
121*8fb009dcSAndroid Build Coastguard Worker }
122*8fb009dcSAndroid Build Coastguard Worker
123*8fb009dcSAndroid Build Coastguard Worker buf[0] = 0;
124*8fb009dcSAndroid Build Coastguard Worker BN_bn2bin(num, buf + 1);
125*8fb009dcSAndroid Build Coastguard Worker int ret;
126*8fb009dcSAndroid Build Coastguard Worker if (len > 0 && (buf[1] & 0x80) != 0) {
127*8fb009dcSAndroid Build Coastguard Worker // Print the whole buffer.
128*8fb009dcSAndroid Build Coastguard Worker ret = print_hex(bp, buf, len + 1, off);
129*8fb009dcSAndroid Build Coastguard Worker } else {
130*8fb009dcSAndroid Build Coastguard Worker // Skip the leading zero.
131*8fb009dcSAndroid Build Coastguard Worker ret = print_hex(bp, buf + 1, len, off);
132*8fb009dcSAndroid Build Coastguard Worker }
133*8fb009dcSAndroid Build Coastguard Worker OPENSSL_free(buf);
134*8fb009dcSAndroid Build Coastguard Worker return ret;
135*8fb009dcSAndroid Build Coastguard Worker }
136*8fb009dcSAndroid Build Coastguard Worker
137*8fb009dcSAndroid Build Coastguard Worker // RSA keys.
138*8fb009dcSAndroid Build Coastguard Worker
do_rsa_print(BIO * out,const RSA * rsa,int off,int include_private)139*8fb009dcSAndroid Build Coastguard Worker static int do_rsa_print(BIO *out, const RSA *rsa, int off,
140*8fb009dcSAndroid Build Coastguard Worker int include_private) {
141*8fb009dcSAndroid Build Coastguard Worker int mod_len = 0;
142*8fb009dcSAndroid Build Coastguard Worker if (rsa->n != NULL) {
143*8fb009dcSAndroid Build Coastguard Worker mod_len = BN_num_bits(rsa->n);
144*8fb009dcSAndroid Build Coastguard Worker }
145*8fb009dcSAndroid Build Coastguard Worker
146*8fb009dcSAndroid Build Coastguard Worker if (!BIO_indent(out, off, 128)) {
147*8fb009dcSAndroid Build Coastguard Worker return 0;
148*8fb009dcSAndroid Build Coastguard Worker }
149*8fb009dcSAndroid Build Coastguard Worker
150*8fb009dcSAndroid Build Coastguard Worker const char *s, *str;
151*8fb009dcSAndroid Build Coastguard Worker if (include_private && rsa->d) {
152*8fb009dcSAndroid Build Coastguard Worker if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
153*8fb009dcSAndroid Build Coastguard Worker return 0;
154*8fb009dcSAndroid Build Coastguard Worker }
155*8fb009dcSAndroid Build Coastguard Worker str = "modulus:";
156*8fb009dcSAndroid Build Coastguard Worker s = "publicExponent:";
157*8fb009dcSAndroid Build Coastguard Worker } else {
158*8fb009dcSAndroid Build Coastguard Worker if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
159*8fb009dcSAndroid Build Coastguard Worker return 0;
160*8fb009dcSAndroid Build Coastguard Worker }
161*8fb009dcSAndroid Build Coastguard Worker str = "Modulus:";
162*8fb009dcSAndroid Build Coastguard Worker s = "Exponent:";
163*8fb009dcSAndroid Build Coastguard Worker }
164*8fb009dcSAndroid Build Coastguard Worker if (!bn_print(out, str, rsa->n, off) ||
165*8fb009dcSAndroid Build Coastguard Worker !bn_print(out, s, rsa->e, off)) {
166*8fb009dcSAndroid Build Coastguard Worker return 0;
167*8fb009dcSAndroid Build Coastguard Worker }
168*8fb009dcSAndroid Build Coastguard Worker
169*8fb009dcSAndroid Build Coastguard Worker if (include_private) {
170*8fb009dcSAndroid Build Coastguard Worker if (!bn_print(out, "privateExponent:", rsa->d, off) ||
171*8fb009dcSAndroid Build Coastguard Worker !bn_print(out, "prime1:", rsa->p, off) ||
172*8fb009dcSAndroid Build Coastguard Worker !bn_print(out, "prime2:", rsa->q, off) ||
173*8fb009dcSAndroid Build Coastguard Worker !bn_print(out, "exponent1:", rsa->dmp1, off) ||
174*8fb009dcSAndroid Build Coastguard Worker !bn_print(out, "exponent2:", rsa->dmq1, off) ||
175*8fb009dcSAndroid Build Coastguard Worker !bn_print(out, "coefficient:", rsa->iqmp, off)) {
176*8fb009dcSAndroid Build Coastguard Worker return 0;
177*8fb009dcSAndroid Build Coastguard Worker }
178*8fb009dcSAndroid Build Coastguard Worker }
179*8fb009dcSAndroid Build Coastguard Worker
180*8fb009dcSAndroid Build Coastguard Worker return 1;
181*8fb009dcSAndroid Build Coastguard Worker }
182*8fb009dcSAndroid Build Coastguard Worker
rsa_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent)183*8fb009dcSAndroid Build Coastguard Worker static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
184*8fb009dcSAndroid Build Coastguard Worker return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 0);
185*8fb009dcSAndroid Build Coastguard Worker }
186*8fb009dcSAndroid Build Coastguard Worker
rsa_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent)187*8fb009dcSAndroid Build Coastguard Worker static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
188*8fb009dcSAndroid Build Coastguard Worker return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 1);
189*8fb009dcSAndroid Build Coastguard Worker }
190*8fb009dcSAndroid Build Coastguard Worker
191*8fb009dcSAndroid Build Coastguard Worker
192*8fb009dcSAndroid Build Coastguard Worker // DSA keys.
193*8fb009dcSAndroid Build Coastguard Worker
do_dsa_print(BIO * bp,const DSA * x,int off,int ptype)194*8fb009dcSAndroid Build Coastguard Worker static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
195*8fb009dcSAndroid Build Coastguard Worker const BIGNUM *priv_key = NULL;
196*8fb009dcSAndroid Build Coastguard Worker if (ptype == 2) {
197*8fb009dcSAndroid Build Coastguard Worker priv_key = DSA_get0_priv_key(x);
198*8fb009dcSAndroid Build Coastguard Worker }
199*8fb009dcSAndroid Build Coastguard Worker
200*8fb009dcSAndroid Build Coastguard Worker const BIGNUM *pub_key = NULL;
201*8fb009dcSAndroid Build Coastguard Worker if (ptype > 0) {
202*8fb009dcSAndroid Build Coastguard Worker pub_key = DSA_get0_pub_key(x);
203*8fb009dcSAndroid Build Coastguard Worker }
204*8fb009dcSAndroid Build Coastguard Worker
205*8fb009dcSAndroid Build Coastguard Worker const char *ktype = "DSA-Parameters";
206*8fb009dcSAndroid Build Coastguard Worker if (ptype == 2) {
207*8fb009dcSAndroid Build Coastguard Worker ktype = "Private-Key";
208*8fb009dcSAndroid Build Coastguard Worker } else if (ptype == 1) {
209*8fb009dcSAndroid Build Coastguard Worker ktype = "Public-Key";
210*8fb009dcSAndroid Build Coastguard Worker }
211*8fb009dcSAndroid Build Coastguard Worker
212*8fb009dcSAndroid Build Coastguard Worker if (!BIO_indent(bp, off, 128) ||
213*8fb009dcSAndroid Build Coastguard Worker BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(DSA_get0_p(x))) <=
214*8fb009dcSAndroid Build Coastguard Worker 0 ||
215*8fb009dcSAndroid Build Coastguard Worker // |priv_key| and |pub_key| may be NULL, in which case |bn_print| will
216*8fb009dcSAndroid Build Coastguard Worker // silently skip them.
217*8fb009dcSAndroid Build Coastguard Worker !bn_print(bp, "priv:", priv_key, off) ||
218*8fb009dcSAndroid Build Coastguard Worker !bn_print(bp, "pub:", pub_key, off) ||
219*8fb009dcSAndroid Build Coastguard Worker !bn_print(bp, "P:", DSA_get0_p(x), off) ||
220*8fb009dcSAndroid Build Coastguard Worker !bn_print(bp, "Q:", DSA_get0_q(x), off) ||
221*8fb009dcSAndroid Build Coastguard Worker !bn_print(bp, "G:", DSA_get0_g(x), off)) {
222*8fb009dcSAndroid Build Coastguard Worker return 0;
223*8fb009dcSAndroid Build Coastguard Worker }
224*8fb009dcSAndroid Build Coastguard Worker
225*8fb009dcSAndroid Build Coastguard Worker return 1;
226*8fb009dcSAndroid Build Coastguard Worker }
227*8fb009dcSAndroid Build Coastguard Worker
dsa_param_print(BIO * bp,const EVP_PKEY * pkey,int indent)228*8fb009dcSAndroid Build Coastguard Worker static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
229*8fb009dcSAndroid Build Coastguard Worker return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 0);
230*8fb009dcSAndroid Build Coastguard Worker }
231*8fb009dcSAndroid Build Coastguard Worker
dsa_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent)232*8fb009dcSAndroid Build Coastguard Worker static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
233*8fb009dcSAndroid Build Coastguard Worker return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 1);
234*8fb009dcSAndroid Build Coastguard Worker }
235*8fb009dcSAndroid Build Coastguard Worker
dsa_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent)236*8fb009dcSAndroid Build Coastguard Worker static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
237*8fb009dcSAndroid Build Coastguard Worker return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 2);
238*8fb009dcSAndroid Build Coastguard Worker }
239*8fb009dcSAndroid Build Coastguard Worker
240*8fb009dcSAndroid Build Coastguard Worker
241*8fb009dcSAndroid Build Coastguard Worker // EC keys.
242*8fb009dcSAndroid Build Coastguard Worker
do_EC_KEY_print(BIO * bp,const EC_KEY * x,int off,int ktype)243*8fb009dcSAndroid Build Coastguard Worker static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
244*8fb009dcSAndroid Build Coastguard Worker const EC_GROUP *group;
245*8fb009dcSAndroid Build Coastguard Worker if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
246*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER);
247*8fb009dcSAndroid Build Coastguard Worker return 0;
248*8fb009dcSAndroid Build Coastguard Worker }
249*8fb009dcSAndroid Build Coastguard Worker
250*8fb009dcSAndroid Build Coastguard Worker const char *ecstr;
251*8fb009dcSAndroid Build Coastguard Worker if (ktype == 2) {
252*8fb009dcSAndroid Build Coastguard Worker ecstr = "Private-Key";
253*8fb009dcSAndroid Build Coastguard Worker } else if (ktype == 1) {
254*8fb009dcSAndroid Build Coastguard Worker ecstr = "Public-Key";
255*8fb009dcSAndroid Build Coastguard Worker } else {
256*8fb009dcSAndroid Build Coastguard Worker ecstr = "ECDSA-Parameters";
257*8fb009dcSAndroid Build Coastguard Worker }
258*8fb009dcSAndroid Build Coastguard Worker
259*8fb009dcSAndroid Build Coastguard Worker if (!BIO_indent(bp, off, 128)) {
260*8fb009dcSAndroid Build Coastguard Worker return 0;
261*8fb009dcSAndroid Build Coastguard Worker }
262*8fb009dcSAndroid Build Coastguard Worker int curve_name = EC_GROUP_get_curve_name(group);
263*8fb009dcSAndroid Build Coastguard Worker if (BIO_printf(bp, "%s: (%s)\n", ecstr,
264*8fb009dcSAndroid Build Coastguard Worker curve_name == NID_undef
265*8fb009dcSAndroid Build Coastguard Worker ? "unknown curve"
266*8fb009dcSAndroid Build Coastguard Worker : EC_curve_nid2nist(curve_name)) <= 0) {
267*8fb009dcSAndroid Build Coastguard Worker return 0;
268*8fb009dcSAndroid Build Coastguard Worker }
269*8fb009dcSAndroid Build Coastguard Worker
270*8fb009dcSAndroid Build Coastguard Worker if (ktype == 2) {
271*8fb009dcSAndroid Build Coastguard Worker const BIGNUM *priv_key = EC_KEY_get0_private_key(x);
272*8fb009dcSAndroid Build Coastguard Worker if (priv_key != NULL && //
273*8fb009dcSAndroid Build Coastguard Worker !bn_print(bp, "priv:", priv_key, off)) {
274*8fb009dcSAndroid Build Coastguard Worker return 0;
275*8fb009dcSAndroid Build Coastguard Worker }
276*8fb009dcSAndroid Build Coastguard Worker }
277*8fb009dcSAndroid Build Coastguard Worker
278*8fb009dcSAndroid Build Coastguard Worker if (ktype > 0 && EC_KEY_get0_public_key(x) != NULL) {
279*8fb009dcSAndroid Build Coastguard Worker uint8_t *pub = NULL;
280*8fb009dcSAndroid Build Coastguard Worker size_t pub_len = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
281*8fb009dcSAndroid Build Coastguard Worker if (pub_len == 0) {
282*8fb009dcSAndroid Build Coastguard Worker return 0;
283*8fb009dcSAndroid Build Coastguard Worker }
284*8fb009dcSAndroid Build Coastguard Worker int ret = BIO_indent(bp, off, 128) && //
285*8fb009dcSAndroid Build Coastguard Worker BIO_puts(bp, "pub:") > 0 && //
286*8fb009dcSAndroid Build Coastguard Worker print_hex(bp, pub, pub_len, off);
287*8fb009dcSAndroid Build Coastguard Worker OPENSSL_free(pub);
288*8fb009dcSAndroid Build Coastguard Worker if (!ret) {
289*8fb009dcSAndroid Build Coastguard Worker return 0;
290*8fb009dcSAndroid Build Coastguard Worker }
291*8fb009dcSAndroid Build Coastguard Worker }
292*8fb009dcSAndroid Build Coastguard Worker
293*8fb009dcSAndroid Build Coastguard Worker return 1;
294*8fb009dcSAndroid Build Coastguard Worker }
295*8fb009dcSAndroid Build Coastguard Worker
eckey_param_print(BIO * bp,const EVP_PKEY * pkey,int indent)296*8fb009dcSAndroid Build Coastguard Worker static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
297*8fb009dcSAndroid Build Coastguard Worker return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 0);
298*8fb009dcSAndroid Build Coastguard Worker }
299*8fb009dcSAndroid Build Coastguard Worker
eckey_pub_print(BIO * bp,const EVP_PKEY * pkey,int indent)300*8fb009dcSAndroid Build Coastguard Worker static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
301*8fb009dcSAndroid Build Coastguard Worker return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 1);
302*8fb009dcSAndroid Build Coastguard Worker }
303*8fb009dcSAndroid Build Coastguard Worker
304*8fb009dcSAndroid Build Coastguard Worker
eckey_priv_print(BIO * bp,const EVP_PKEY * pkey,int indent)305*8fb009dcSAndroid Build Coastguard Worker static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) {
306*8fb009dcSAndroid Build Coastguard Worker return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 2);
307*8fb009dcSAndroid Build Coastguard Worker }
308*8fb009dcSAndroid Build Coastguard Worker
309*8fb009dcSAndroid Build Coastguard Worker
310*8fb009dcSAndroid Build Coastguard Worker typedef struct {
311*8fb009dcSAndroid Build Coastguard Worker int type;
312*8fb009dcSAndroid Build Coastguard Worker int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent);
313*8fb009dcSAndroid Build Coastguard Worker int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent);
314*8fb009dcSAndroid Build Coastguard Worker int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent);
315*8fb009dcSAndroid Build Coastguard Worker } EVP_PKEY_PRINT_METHOD;
316*8fb009dcSAndroid Build Coastguard Worker
317*8fb009dcSAndroid Build Coastguard Worker static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
318*8fb009dcSAndroid Build Coastguard Worker {
319*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY_RSA,
320*8fb009dcSAndroid Build Coastguard Worker rsa_pub_print,
321*8fb009dcSAndroid Build Coastguard Worker rsa_priv_print,
322*8fb009dcSAndroid Build Coastguard Worker NULL /* param_print */,
323*8fb009dcSAndroid Build Coastguard Worker },
324*8fb009dcSAndroid Build Coastguard Worker {
325*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY_DSA,
326*8fb009dcSAndroid Build Coastguard Worker dsa_pub_print,
327*8fb009dcSAndroid Build Coastguard Worker dsa_priv_print,
328*8fb009dcSAndroid Build Coastguard Worker dsa_param_print,
329*8fb009dcSAndroid Build Coastguard Worker },
330*8fb009dcSAndroid Build Coastguard Worker {
331*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY_EC,
332*8fb009dcSAndroid Build Coastguard Worker eckey_pub_print,
333*8fb009dcSAndroid Build Coastguard Worker eckey_priv_print,
334*8fb009dcSAndroid Build Coastguard Worker eckey_param_print,
335*8fb009dcSAndroid Build Coastguard Worker },
336*8fb009dcSAndroid Build Coastguard Worker };
337*8fb009dcSAndroid Build Coastguard Worker
338*8fb009dcSAndroid Build Coastguard Worker static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods);
339*8fb009dcSAndroid Build Coastguard Worker
find_method(int type)340*8fb009dcSAndroid Build Coastguard Worker static EVP_PKEY_PRINT_METHOD *find_method(int type) {
341*8fb009dcSAndroid Build Coastguard Worker for (size_t i = 0; i < kPrintMethodsLen; i++) {
342*8fb009dcSAndroid Build Coastguard Worker if (kPrintMethods[i].type == type) {
343*8fb009dcSAndroid Build Coastguard Worker return &kPrintMethods[i];
344*8fb009dcSAndroid Build Coastguard Worker }
345*8fb009dcSAndroid Build Coastguard Worker }
346*8fb009dcSAndroid Build Coastguard Worker return NULL;
347*8fb009dcSAndroid Build Coastguard Worker }
348*8fb009dcSAndroid Build Coastguard Worker
print_unsupported(BIO * out,const EVP_PKEY * pkey,int indent,const char * kstr)349*8fb009dcSAndroid Build Coastguard Worker static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
350*8fb009dcSAndroid Build Coastguard Worker const char *kstr) {
351*8fb009dcSAndroid Build Coastguard Worker BIO_indent(out, indent, 128);
352*8fb009dcSAndroid Build Coastguard Worker BIO_printf(out, "%s algorithm unsupported\n", kstr);
353*8fb009dcSAndroid Build Coastguard Worker return 1;
354*8fb009dcSAndroid Build Coastguard Worker }
355*8fb009dcSAndroid Build Coastguard Worker
EVP_PKEY_print_public(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)356*8fb009dcSAndroid Build Coastguard Worker int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
357*8fb009dcSAndroid Build Coastguard Worker ASN1_PCTX *pctx) {
358*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
359*8fb009dcSAndroid Build Coastguard Worker if (method != NULL && method->pub_print != NULL) {
360*8fb009dcSAndroid Build Coastguard Worker return method->pub_print(out, pkey, indent);
361*8fb009dcSAndroid Build Coastguard Worker }
362*8fb009dcSAndroid Build Coastguard Worker return print_unsupported(out, pkey, indent, "Public Key");
363*8fb009dcSAndroid Build Coastguard Worker }
364*8fb009dcSAndroid Build Coastguard Worker
EVP_PKEY_print_private(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)365*8fb009dcSAndroid Build Coastguard Worker int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
366*8fb009dcSAndroid Build Coastguard Worker ASN1_PCTX *pctx) {
367*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
368*8fb009dcSAndroid Build Coastguard Worker if (method != NULL && method->priv_print != NULL) {
369*8fb009dcSAndroid Build Coastguard Worker return method->priv_print(out, pkey, indent);
370*8fb009dcSAndroid Build Coastguard Worker }
371*8fb009dcSAndroid Build Coastguard Worker return print_unsupported(out, pkey, indent, "Private Key");
372*8fb009dcSAndroid Build Coastguard Worker }
373*8fb009dcSAndroid Build Coastguard Worker
EVP_PKEY_print_params(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)374*8fb009dcSAndroid Build Coastguard Worker int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
375*8fb009dcSAndroid Build Coastguard Worker ASN1_PCTX *pctx) {
376*8fb009dcSAndroid Build Coastguard Worker EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
377*8fb009dcSAndroid Build Coastguard Worker if (method != NULL && method->param_print != NULL) {
378*8fb009dcSAndroid Build Coastguard Worker return method->param_print(out, pkey, indent);
379*8fb009dcSAndroid Build Coastguard Worker }
380*8fb009dcSAndroid Build Coastguard Worker return print_unsupported(out, pkey, indent, "Parameters");
381*8fb009dcSAndroid Build Coastguard Worker }
382