Annotation of src/usr.bin/openssl/spkac.c, Revision 1.2
1.2 ! jsing 1: /* $OpenBSD: spkac.c,v 1.1 2014/08/26 17:47:25 jsing Exp $ */
1.1 jsing 2: /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3: * project 1999. Based on an original idea by Massimiliano Pala
4: * (madwolf@openca.org).
5: */
6: /* ====================================================================
7: * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: *
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: *
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in
18: * the documentation and/or other materials provided with the
19: * distribution.
20: *
21: * 3. All advertising materials mentioning features or use of this
22: * software must display the following acknowledgment:
23: * "This product includes software developed by the OpenSSL Project
24: * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25: *
26: * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27: * endorse or promote products derived from this software without
28: * prior written permission. For written permission, please contact
29: * licensing@OpenSSL.org.
30: *
31: * 5. Products derived from this software may not be called "OpenSSL"
32: * nor may "OpenSSL" appear in their names without prior written
33: * permission of the OpenSSL Project.
34: *
35: * 6. Redistributions of any form whatsoever must retain the following
36: * acknowledgment:
37: * "This product includes software developed by the OpenSSL Project
38: * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39: *
40: * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41: * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51: * OF THE POSSIBILITY OF SUCH DAMAGE.
52: * ====================================================================
53: *
54: * This product includes cryptographic software written by Eric Young
55: * (eay@cryptsoft.com). This product includes software written by Tim
56: * Hudson (tjh@cryptsoft.com).
57: *
58: */
59:
60: #include <stdio.h>
61: #include <stdlib.h>
62: #include <string.h>
63: #include <time.h>
64:
65: #include "apps.h"
66:
67: #include <openssl/bio.h>
68: #include <openssl/conf.h>
69: #include <openssl/err.h>
70: #include <openssl/evp.h>
71: #include <openssl/lhash.h>
72: #include <openssl/pem.h>
73: #include <openssl/x509.h>
74:
75: /* -in arg - input file - default stdin
76: * -out arg - output file - default stdout
77: */
78:
79: int spkac_main(int, char **);
80:
81: int
82: spkac_main(int argc, char **argv)
83: {
84: ENGINE *e = NULL;
85: int i, badops = 0, ret = 1;
86: BIO *in = NULL, *out = NULL;
87: int verify = 0, noout = 0, pubkey = 0;
88: char *infile = NULL, *outfile = NULL, *prog;
89: char *passargin = NULL, *passin = NULL;
90: const char *spkac = "SPKAC", *spksect = "default";
91: char *spkstr = NULL;
92: char *challenge = NULL, *keyfile = NULL;
93: CONF *conf = NULL;
94: NETSCAPE_SPKI *spki = NULL;
95: EVP_PKEY *pkey = NULL;
96: #ifndef OPENSSL_NO_ENGINE
97: char *engine = NULL;
98: #endif
99:
100: prog = argv[0];
101: argc--;
102: argv++;
103: while (argc >= 1) {
104: if (strcmp(*argv, "-in") == 0) {
105: if (--argc < 1)
106: goto bad;
107: infile = *(++argv);
108: } else if (strcmp(*argv, "-out") == 0) {
109: if (--argc < 1)
110: goto bad;
111: outfile = *(++argv);
112: } else if (strcmp(*argv, "-passin") == 0) {
113: if (--argc < 1)
114: goto bad;
115: passargin = *(++argv);
116: } else if (strcmp(*argv, "-key") == 0) {
117: if (--argc < 1)
118: goto bad;
119: keyfile = *(++argv);
120: } else if (strcmp(*argv, "-challenge") == 0) {
121: if (--argc < 1)
122: goto bad;
123: challenge = *(++argv);
124: } else if (strcmp(*argv, "-spkac") == 0) {
125: if (--argc < 1)
126: goto bad;
127: spkac = *(++argv);
128: } else if (strcmp(*argv, "-spksect") == 0) {
129: if (--argc < 1)
130: goto bad;
131: spksect = *(++argv);
132: }
133: #ifndef OPENSSL_NO_ENGINE
134: else if (strcmp(*argv, "-engine") == 0) {
135: if (--argc < 1)
136: goto bad;
137: engine = *(++argv);
138: }
139: #endif
140: else if (strcmp(*argv, "-noout") == 0)
141: noout = 1;
142: else if (strcmp(*argv, "-pubkey") == 0)
143: pubkey = 1;
144: else if (strcmp(*argv, "-verify") == 0)
145: verify = 1;
146: else
147: badops = 1;
148: argc--;
149: argv++;
150: }
151:
152: if (badops) {
153: bad:
154: BIO_printf(bio_err, "%s [options]\n", prog);
155: BIO_printf(bio_err, "where options are\n");
156: BIO_printf(bio_err, " -in arg input file\n");
157: BIO_printf(bio_err, " -out arg output file\n");
158: BIO_printf(bio_err, " -key arg create SPKAC using private key\n");
159: BIO_printf(bio_err, " -passin arg input file pass phrase source\n");
160: BIO_printf(bio_err, " -challenge arg challenge string\n");
161: BIO_printf(bio_err, " -spkac arg alternative SPKAC name\n");
162: BIO_printf(bio_err, " -noout don't print SPKAC\n");
163: BIO_printf(bio_err, " -pubkey output public key\n");
164: BIO_printf(bio_err, " -verify verify SPKAC signature\n");
165: #ifndef OPENSSL_NO_ENGINE
166: BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n");
167: #endif
168: goto end;
169: }
1.2 ! jsing 170:
1.1 jsing 171: if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
172: BIO_printf(bio_err, "Error getting password\n");
173: goto end;
174: }
175: #ifndef OPENSSL_NO_ENGINE
176: e = setup_engine(bio_err, engine, 0);
177: #endif
178:
179: if (keyfile) {
180: pkey = load_key(bio_err,
181: strcmp(keyfile, "-") ? keyfile : NULL,
182: FORMAT_PEM, 1, passin, e, "private key");
183: if (!pkey) {
184: goto end;
185: }
186: spki = NETSCAPE_SPKI_new();
187: if (challenge)
188: ASN1_STRING_set(spki->spkac->challenge,
189: challenge, (int) strlen(challenge));
190: NETSCAPE_SPKI_set_pubkey(spki, pkey);
191: NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
192: spkstr = NETSCAPE_SPKI_b64_encode(spki);
193: if (spkstr == NULL) {
194: BIO_printf(bio_err, "Error encoding SPKAC\n");
195: ERR_print_errors(bio_err);
196: goto end;
197: }
198:
199: if (outfile)
200: out = BIO_new_file(outfile, "w");
201: else
202: out = BIO_new_fp(stdout, BIO_NOCLOSE);
203:
204: if (!out) {
205: BIO_printf(bio_err, "Error opening output file\n");
206: ERR_print_errors(bio_err);
207: } else {
208: BIO_printf(out, "SPKAC=%s\n", spkstr);
209: ret = 0;
210: }
211: free(spkstr);
212: goto end;
213: }
214: if (infile)
215: in = BIO_new_file(infile, "r");
216: else
217: in = BIO_new_fp(stdin, BIO_NOCLOSE);
218:
219: if (!in) {
220: BIO_printf(bio_err, "Error opening input file\n");
221: ERR_print_errors(bio_err);
222: goto end;
223: }
224: conf = NCONF_new(NULL);
225: i = NCONF_load_bio(conf, in, NULL);
226:
227: if (!i) {
228: BIO_printf(bio_err, "Error parsing config file\n");
229: ERR_print_errors(bio_err);
230: goto end;
231: }
232: spkstr = NCONF_get_string(conf, spksect, spkac);
233:
234: if (!spkstr) {
235: BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac);
236: ERR_print_errors(bio_err);
237: goto end;
238: }
239: spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
240:
241: if (!spki) {
242: BIO_printf(bio_err, "Error loading SPKAC\n");
243: ERR_print_errors(bio_err);
244: goto end;
245: }
246: if (outfile)
247: out = BIO_new_file(outfile, "w");
248: else {
249: out = BIO_new_fp(stdout, BIO_NOCLOSE);
250: }
251:
252: if (!out) {
253: BIO_printf(bio_err, "Error opening output file\n");
254: ERR_print_errors(bio_err);
255: goto end;
256: }
257: if (!noout)
258: NETSCAPE_SPKI_print(out, spki);
259: pkey = NETSCAPE_SPKI_get_pubkey(spki);
260: if (verify) {
261: i = NETSCAPE_SPKI_verify(spki, pkey);
262: if (i > 0)
263: BIO_printf(bio_err, "Signature OK\n");
264: else {
265: BIO_printf(bio_err, "Signature Failure\n");
266: ERR_print_errors(bio_err);
267: goto end;
268: }
269: }
270: if (pubkey)
271: PEM_write_bio_PUBKEY(out, pkey);
272:
273: ret = 0;
274:
275: end:
276: NCONF_free(conf);
277: NETSCAPE_SPKI_free(spki);
278: BIO_free(in);
279: BIO_free_all(out);
280: EVP_PKEY_free(pkey);
281: free(passin);
282:
283: return (ret);
284: }