xref: /onnv-gate/usr/src/common/openssl/apps/ec.c (revision 2139:6243c3338933)
1*2139Sjp161948 /* apps/ec.c */
2*2139Sjp161948 /*
3*2139Sjp161948  * Written by Nils Larsch for the OpenSSL project.
4*2139Sjp161948  */
5*2139Sjp161948 /* ====================================================================
6*2139Sjp161948  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
7*2139Sjp161948  *
8*2139Sjp161948  * Redistribution and use in source and binary forms, with or without
9*2139Sjp161948  * modification, are permitted provided that the following conditions
10*2139Sjp161948  * are met:
11*2139Sjp161948  *
12*2139Sjp161948  * 1. Redistributions of source code must retain the above copyright
13*2139Sjp161948  *    notice, this list of conditions and the following disclaimer.
14*2139Sjp161948  *
15*2139Sjp161948  * 2. Redistributions in binary form must reproduce the above copyright
16*2139Sjp161948  *    notice, this list of conditions and the following disclaimer in
17*2139Sjp161948  *    the documentation and/or other materials provided with the
18*2139Sjp161948  *    distribution.
19*2139Sjp161948  *
20*2139Sjp161948  * 3. All advertising materials mentioning features or use of this
21*2139Sjp161948  *    software must display the following acknowledgment:
22*2139Sjp161948  *    "This product includes software developed by the OpenSSL Project
23*2139Sjp161948  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24*2139Sjp161948  *
25*2139Sjp161948  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26*2139Sjp161948  *    endorse or promote products derived from this software without
27*2139Sjp161948  *    prior written permission. For written permission, please contact
28*2139Sjp161948  *    openssl-core@openssl.org.
29*2139Sjp161948  *
30*2139Sjp161948  * 5. Products derived from this software may not be called "OpenSSL"
31*2139Sjp161948  *    nor may "OpenSSL" appear in their names without prior written
32*2139Sjp161948  *    permission of the OpenSSL Project.
33*2139Sjp161948  *
34*2139Sjp161948  * 6. Redistributions of any form whatsoever must retain the following
35*2139Sjp161948  *    acknowledgment:
36*2139Sjp161948  *    "This product includes software developed by the OpenSSL Project
37*2139Sjp161948  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38*2139Sjp161948  *
39*2139Sjp161948  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40*2139Sjp161948  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41*2139Sjp161948  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42*2139Sjp161948  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43*2139Sjp161948  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44*2139Sjp161948  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45*2139Sjp161948  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46*2139Sjp161948  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*2139Sjp161948  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48*2139Sjp161948  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49*2139Sjp161948  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50*2139Sjp161948  * OF THE POSSIBILITY OF SUCH DAMAGE.
51*2139Sjp161948  * ====================================================================
52*2139Sjp161948  *
53*2139Sjp161948  * This product includes cryptographic software written by Eric Young
54*2139Sjp161948  * (eay@cryptsoft.com).  This product includes software written by Tim
55*2139Sjp161948  * Hudson (tjh@cryptsoft.com).
56*2139Sjp161948  *
57*2139Sjp161948  */
58*2139Sjp161948 
59*2139Sjp161948 #include <openssl/opensslconf.h>
60*2139Sjp161948 #ifndef OPENSSL_NO_EC
61*2139Sjp161948 #include <stdio.h>
62*2139Sjp161948 #include <stdlib.h>
63*2139Sjp161948 #include <string.h>
64*2139Sjp161948 #include "apps.h"
65*2139Sjp161948 #include <openssl/bio.h>
66*2139Sjp161948 #include <openssl/err.h>
67*2139Sjp161948 #include <openssl/evp.h>
68*2139Sjp161948 #include <openssl/pem.h>
69*2139Sjp161948 
70*2139Sjp161948 #undef PROG
71*2139Sjp161948 #define PROG	ec_main
72*2139Sjp161948 
73*2139Sjp161948 /* -inform arg    - input format - default PEM (one of DER, NET or PEM)
74*2139Sjp161948  * -outform arg   - output format - default PEM
75*2139Sjp161948  * -in arg        - input file - default stdin
76*2139Sjp161948  * -out arg       - output file - default stdout
77*2139Sjp161948  * -des           - encrypt output if PEM format with DES in cbc mode
78*2139Sjp161948  * -text          - print a text version
79*2139Sjp161948  * -param_out     - print the elliptic curve parameters
80*2139Sjp161948  * -conv_form arg - specifies the point encoding form
81*2139Sjp161948  * -param_enc arg - specifies the parameter encoding
82*2139Sjp161948  */
83*2139Sjp161948 
84*2139Sjp161948 int MAIN(int, char **);
85*2139Sjp161948 
MAIN(int argc,char ** argv)86*2139Sjp161948 int MAIN(int argc, char **argv)
87*2139Sjp161948 {
88*2139Sjp161948 #ifndef OPENSSL_NO_ENGINE
89*2139Sjp161948 	ENGINE 	*e = NULL;
90*2139Sjp161948 #endif
91*2139Sjp161948 	int 	ret = 1;
92*2139Sjp161948 	EC_KEY 	*eckey = NULL;
93*2139Sjp161948 	const EC_GROUP *group;
94*2139Sjp161948 	int 	i, badops = 0;
95*2139Sjp161948 	const EVP_CIPHER *enc = NULL;
96*2139Sjp161948 	BIO 	*in = NULL, *out = NULL;
97*2139Sjp161948 	int 	informat, outformat, text=0, noout=0;
98*2139Sjp161948 	int  	pubin = 0, pubout = 0, param_out = 0;
99*2139Sjp161948 	char 	*infile, *outfile, *prog, *engine;
100*2139Sjp161948 	char 	*passargin = NULL, *passargout = NULL;
101*2139Sjp161948 	char 	*passin = NULL, *passout = NULL;
102*2139Sjp161948 	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
103*2139Sjp161948 	int	new_form = 0;
104*2139Sjp161948 	int	asn1_flag = OPENSSL_EC_NAMED_CURVE;
105*2139Sjp161948 	int 	new_asn1_flag = 0;
106*2139Sjp161948 
107*2139Sjp161948 	apps_startup();
108*2139Sjp161948 
109*2139Sjp161948 	if (bio_err == NULL)
110*2139Sjp161948 		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
111*2139Sjp161948 			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
112*2139Sjp161948 
113*2139Sjp161948 	if (!load_config(bio_err, NULL))
114*2139Sjp161948 		goto end;
115*2139Sjp161948 
116*2139Sjp161948 	engine = NULL;
117*2139Sjp161948 	infile = NULL;
118*2139Sjp161948 	outfile = NULL;
119*2139Sjp161948 	informat = FORMAT_PEM;
120*2139Sjp161948 	outformat = FORMAT_PEM;
121*2139Sjp161948 
122*2139Sjp161948 	prog = argv[0];
123*2139Sjp161948 	argc--;
124*2139Sjp161948 	argv++;
125*2139Sjp161948 	while (argc >= 1)
126*2139Sjp161948 		{
127*2139Sjp161948 		if (strcmp(*argv,"-inform") == 0)
128*2139Sjp161948 			{
129*2139Sjp161948 			if (--argc < 1) goto bad;
130*2139Sjp161948 			informat=str2fmt(*(++argv));
131*2139Sjp161948 			}
132*2139Sjp161948 		else if (strcmp(*argv,"-outform") == 0)
133*2139Sjp161948 			{
134*2139Sjp161948 			if (--argc < 1) goto bad;
135*2139Sjp161948 			outformat=str2fmt(*(++argv));
136*2139Sjp161948 			}
137*2139Sjp161948 		else if (strcmp(*argv,"-in") == 0)
138*2139Sjp161948 			{
139*2139Sjp161948 			if (--argc < 1) goto bad;
140*2139Sjp161948 			infile= *(++argv);
141*2139Sjp161948 			}
142*2139Sjp161948 		else if (strcmp(*argv,"-out") == 0)
143*2139Sjp161948 			{
144*2139Sjp161948 			if (--argc < 1) goto bad;
145*2139Sjp161948 			outfile= *(++argv);
146*2139Sjp161948 			}
147*2139Sjp161948 		else if (strcmp(*argv,"-passin") == 0)
148*2139Sjp161948 			{
149*2139Sjp161948 			if (--argc < 1) goto bad;
150*2139Sjp161948 			passargin= *(++argv);
151*2139Sjp161948 			}
152*2139Sjp161948 		else if (strcmp(*argv,"-passout") == 0)
153*2139Sjp161948 			{
154*2139Sjp161948 			if (--argc < 1) goto bad;
155*2139Sjp161948 			passargout= *(++argv);
156*2139Sjp161948 			}
157*2139Sjp161948 		else if (strcmp(*argv, "-engine") == 0)
158*2139Sjp161948 			{
159*2139Sjp161948 			if (--argc < 1) goto bad;
160*2139Sjp161948 			engine= *(++argv);
161*2139Sjp161948 			}
162*2139Sjp161948 		else if (strcmp(*argv, "-noout") == 0)
163*2139Sjp161948 			noout = 1;
164*2139Sjp161948 		else if (strcmp(*argv, "-text") == 0)
165*2139Sjp161948 			text = 1;
166*2139Sjp161948 		else if (strcmp(*argv, "-conv_form") == 0)
167*2139Sjp161948 			{
168*2139Sjp161948 			if (--argc < 1)
169*2139Sjp161948 				goto bad;
170*2139Sjp161948 			++argv;
171*2139Sjp161948 			new_form = 1;
172*2139Sjp161948 			if (strcmp(*argv, "compressed") == 0)
173*2139Sjp161948 				form = POINT_CONVERSION_COMPRESSED;
174*2139Sjp161948 			else if (strcmp(*argv, "uncompressed") == 0)
175*2139Sjp161948 				form = POINT_CONVERSION_UNCOMPRESSED;
176*2139Sjp161948 			else if (strcmp(*argv, "hybrid") == 0)
177*2139Sjp161948 				form = POINT_CONVERSION_HYBRID;
178*2139Sjp161948 			else
179*2139Sjp161948 				goto bad;
180*2139Sjp161948 			}
181*2139Sjp161948 		else if (strcmp(*argv, "-param_enc") == 0)
182*2139Sjp161948 			{
183*2139Sjp161948 			if (--argc < 1)
184*2139Sjp161948 				goto bad;
185*2139Sjp161948 			++argv;
186*2139Sjp161948 			new_asn1_flag = 1;
187*2139Sjp161948 			if (strcmp(*argv, "named_curve") == 0)
188*2139Sjp161948 				asn1_flag = OPENSSL_EC_NAMED_CURVE;
189*2139Sjp161948 			else if (strcmp(*argv, "explicit") == 0)
190*2139Sjp161948 				asn1_flag = 0;
191*2139Sjp161948 			else
192*2139Sjp161948 				goto bad;
193*2139Sjp161948 			}
194*2139Sjp161948 		else if (strcmp(*argv, "-param_out") == 0)
195*2139Sjp161948 			param_out = 1;
196*2139Sjp161948 		else if (strcmp(*argv, "-pubin") == 0)
197*2139Sjp161948 			pubin=1;
198*2139Sjp161948 		else if (strcmp(*argv, "-pubout") == 0)
199*2139Sjp161948 			pubout=1;
200*2139Sjp161948 		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
201*2139Sjp161948 			{
202*2139Sjp161948 			BIO_printf(bio_err, "unknown option %s\n", *argv);
203*2139Sjp161948 			badops=1;
204*2139Sjp161948 			break;
205*2139Sjp161948 			}
206*2139Sjp161948 		argc--;
207*2139Sjp161948 		argv++;
208*2139Sjp161948 		}
209*2139Sjp161948 
210*2139Sjp161948 	if (badops)
211*2139Sjp161948 		{
212*2139Sjp161948 bad:
213*2139Sjp161948 		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
214*2139Sjp161948 		BIO_printf(bio_err, "where options are\n");
215*2139Sjp161948 		BIO_printf(bio_err, " -inform arg     input format - "
216*2139Sjp161948 				"DER or PEM\n");
217*2139Sjp161948 		BIO_printf(bio_err, " -outform arg    output format - "
218*2139Sjp161948 				"DER or PEM\n");
219*2139Sjp161948 		BIO_printf(bio_err, " -in arg         input file\n");
220*2139Sjp161948 		BIO_printf(bio_err, " -passin arg     input file pass "
221*2139Sjp161948 				"phrase source\n");
222*2139Sjp161948 		BIO_printf(bio_err, " -out arg        output file\n");
223*2139Sjp161948 		BIO_printf(bio_err, " -passout arg    output file pass "
224*2139Sjp161948 				"phrase source\n");
225*2139Sjp161948 		BIO_printf(bio_err, " -engine e       use engine e, "
226*2139Sjp161948 				"possibly a hardware device.\n");
227*2139Sjp161948 		BIO_printf(bio_err, " -des            encrypt PEM output, "
228*2139Sjp161948 				"instead of 'des' every other \n"
229*2139Sjp161948 				"                 cipher "
230*2139Sjp161948 				"supported by OpenSSL can be used\n");
231*2139Sjp161948 		BIO_printf(bio_err, " -text           print the key\n");
232*2139Sjp161948 		BIO_printf(bio_err, " -noout          don't print key out\n");
233*2139Sjp161948 		BIO_printf(bio_err, " -param_out      print the elliptic "
234*2139Sjp161948 				"curve parameters\n");
235*2139Sjp161948 		BIO_printf(bio_err, " -conv_form arg  specifies the "
236*2139Sjp161948 				"point conversion form \n");
237*2139Sjp161948 		BIO_printf(bio_err, "                 possible values:"
238*2139Sjp161948 				" compressed\n");
239*2139Sjp161948 		BIO_printf(bio_err, "                                 "
240*2139Sjp161948 				" uncompressed (default)\n");
241*2139Sjp161948 		BIO_printf(bio_err, "                                  "
242*2139Sjp161948 				" hybrid\n");
243*2139Sjp161948 		BIO_printf(bio_err, " -param_enc arg  specifies the way"
244*2139Sjp161948 				" the ec parameters are encoded\n");
245*2139Sjp161948 		BIO_printf(bio_err, "                 in the asn1 der "
246*2139Sjp161948 				"encoding\n");
247*2139Sjp161948 		BIO_printf(bio_err, "                 possilbe values:"
248*2139Sjp161948 				" named_curve (default)\n");
249*2139Sjp161948 		BIO_printf(bio_err,"                                  "
250*2139Sjp161948 				"explicit\n");
251*2139Sjp161948 		goto end;
252*2139Sjp161948 		}
253*2139Sjp161948 
254*2139Sjp161948 	ERR_load_crypto_strings();
255*2139Sjp161948 
256*2139Sjp161948 #ifndef OPENSSL_NO_ENGINE
257*2139Sjp161948         e = setup_engine(bio_err, engine, 0);
258*2139Sjp161948 #endif
259*2139Sjp161948 
260*2139Sjp161948 	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
261*2139Sjp161948 		{
262*2139Sjp161948 		BIO_printf(bio_err, "Error getting passwords\n");
263*2139Sjp161948 		goto end;
264*2139Sjp161948 		}
265*2139Sjp161948 
266*2139Sjp161948 	in = BIO_new(BIO_s_file());
267*2139Sjp161948 	out = BIO_new(BIO_s_file());
268*2139Sjp161948 	if ((in == NULL) || (out == NULL))
269*2139Sjp161948 		{
270*2139Sjp161948 		ERR_print_errors(bio_err);
271*2139Sjp161948 		goto end;
272*2139Sjp161948 		}
273*2139Sjp161948 
274*2139Sjp161948 	if (infile == NULL)
275*2139Sjp161948 		BIO_set_fp(in, stdin, BIO_NOCLOSE);
276*2139Sjp161948 	else
277*2139Sjp161948 		{
278*2139Sjp161948 		if (BIO_read_filename(in, infile) <= 0)
279*2139Sjp161948 			{
280*2139Sjp161948 			perror(infile);
281*2139Sjp161948 			goto end;
282*2139Sjp161948 			}
283*2139Sjp161948 		}
284*2139Sjp161948 
285*2139Sjp161948 	BIO_printf(bio_err, "read EC key\n");
286*2139Sjp161948 	if (informat == FORMAT_ASN1)
287*2139Sjp161948 		{
288*2139Sjp161948 		if (pubin)
289*2139Sjp161948 			eckey = d2i_EC_PUBKEY_bio(in, NULL);
290*2139Sjp161948 		else
291*2139Sjp161948 			eckey = d2i_ECPrivateKey_bio(in, NULL);
292*2139Sjp161948 		}
293*2139Sjp161948 	else if (informat == FORMAT_PEM)
294*2139Sjp161948 		{
295*2139Sjp161948 		if (pubin)
296*2139Sjp161948 			eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL,
297*2139Sjp161948 				NULL);
298*2139Sjp161948 		else
299*2139Sjp161948 			eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
300*2139Sjp161948 				passin);
301*2139Sjp161948 		}
302*2139Sjp161948 	else
303*2139Sjp161948 		{
304*2139Sjp161948 		BIO_printf(bio_err, "bad input format specified for key\n");
305*2139Sjp161948 		goto end;
306*2139Sjp161948 		}
307*2139Sjp161948 	if (eckey == NULL)
308*2139Sjp161948 		{
309*2139Sjp161948 		BIO_printf(bio_err,"unable to load Key\n");
310*2139Sjp161948 		ERR_print_errors(bio_err);
311*2139Sjp161948 		goto end;
312*2139Sjp161948 		}
313*2139Sjp161948 
314*2139Sjp161948 	if (outfile == NULL)
315*2139Sjp161948 		{
316*2139Sjp161948 		BIO_set_fp(out, stdout, BIO_NOCLOSE);
317*2139Sjp161948 #ifdef OPENSSL_SYS_VMS
318*2139Sjp161948 			{
319*2139Sjp161948 			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
320*2139Sjp161948 			out = BIO_push(tmpbio, out);
321*2139Sjp161948 			}
322*2139Sjp161948 #endif
323*2139Sjp161948 		}
324*2139Sjp161948 	else
325*2139Sjp161948 		{
326*2139Sjp161948 		if (BIO_write_filename(out, outfile) <= 0)
327*2139Sjp161948 			{
328*2139Sjp161948 			perror(outfile);
329*2139Sjp161948 			goto end;
330*2139Sjp161948 			}
331*2139Sjp161948 		}
332*2139Sjp161948 
333*2139Sjp161948 	group = EC_KEY_get0_group(eckey);
334*2139Sjp161948 
335*2139Sjp161948 	if (new_form)
336*2139Sjp161948 		EC_KEY_set_conv_form(eckey, form);
337*2139Sjp161948 
338*2139Sjp161948 	if (new_asn1_flag)
339*2139Sjp161948 		EC_KEY_set_asn1_flag(eckey, asn1_flag);
340*2139Sjp161948 
341*2139Sjp161948 	if (text)
342*2139Sjp161948 		if (!EC_KEY_print(out, eckey, 0))
343*2139Sjp161948 			{
344*2139Sjp161948 			perror(outfile);
345*2139Sjp161948 			ERR_print_errors(bio_err);
346*2139Sjp161948 			goto end;
347*2139Sjp161948 			}
348*2139Sjp161948 
349*2139Sjp161948 	if (noout)
350*2139Sjp161948 		goto end;
351*2139Sjp161948 
352*2139Sjp161948 	BIO_printf(bio_err, "writing EC key\n");
353*2139Sjp161948 	if (outformat == FORMAT_ASN1)
354*2139Sjp161948 		{
355*2139Sjp161948 		if (param_out)
356*2139Sjp161948 			i = i2d_ECPKParameters_bio(out, group);
357*2139Sjp161948 		else if (pubin || pubout)
358*2139Sjp161948 			i = i2d_EC_PUBKEY_bio(out, eckey);
359*2139Sjp161948 		else
360*2139Sjp161948 			i = i2d_ECPrivateKey_bio(out, eckey);
361*2139Sjp161948 		}
362*2139Sjp161948 	else if (outformat == FORMAT_PEM)
363*2139Sjp161948 		{
364*2139Sjp161948 		if (param_out)
365*2139Sjp161948 			i = PEM_write_bio_ECPKParameters(out, group);
366*2139Sjp161948 		else if (pubin || pubout)
367*2139Sjp161948 			i = PEM_write_bio_EC_PUBKEY(out, eckey);
368*2139Sjp161948 		else
369*2139Sjp161948 			i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
370*2139Sjp161948 						NULL, 0, NULL, passout);
371*2139Sjp161948 		}
372*2139Sjp161948 	else
373*2139Sjp161948 		{
374*2139Sjp161948 		BIO_printf(bio_err, "bad output format specified for "
375*2139Sjp161948 			"outfile\n");
376*2139Sjp161948 		goto end;
377*2139Sjp161948 		}
378*2139Sjp161948 
379*2139Sjp161948 	if (!i)
380*2139Sjp161948 		{
381*2139Sjp161948 		BIO_printf(bio_err, "unable to write private key\n");
382*2139Sjp161948 		ERR_print_errors(bio_err);
383*2139Sjp161948 		}
384*2139Sjp161948 	else
385*2139Sjp161948 		ret=0;
386*2139Sjp161948 end:
387*2139Sjp161948 	if (in)
388*2139Sjp161948 		BIO_free(in);
389*2139Sjp161948 	if (out)
390*2139Sjp161948 		BIO_free_all(out);
391*2139Sjp161948 	if (eckey)
392*2139Sjp161948 		EC_KEY_free(eckey);
393*2139Sjp161948 	if (passin)
394*2139Sjp161948 		OPENSSL_free(passin);
395*2139Sjp161948 	if (passout)
396*2139Sjp161948 		OPENSSL_free(passout);
397*2139Sjp161948 	apps_shutdown();
398*2139Sjp161948 	OPENSSL_EXIT(ret);
399*2139Sjp161948 }
400*2139Sjp161948 #endif
401