source: trunk/third/openssl/apps/pkcs8.c @ 18442

Revision 18442, 10.7 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18441, which included commits to RCS files with non-trunk default branches.
Line 
1/* pkcs8.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 *    software must display the following acknowledgment:
22 *    "This product includes software developed by the OpenSSL Project
23 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 *    endorse or promote products derived from this software without
27 *    prior written permission. For written permission, please contact
28 *    licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 *    nor may "OpenSSL" appear in their names without prior written
32 *    permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 *    acknowledgment:
36 *    "This product includes software developed by the OpenSSL Project
37 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com).  This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58#include <stdio.h>
59#include <string.h>
60#include "apps.h"
61#include <openssl/pem.h>
62#include <openssl/err.h>
63#include <openssl/evp.h>
64#include <openssl/pkcs12.h>
65
66#define PROG pkcs8_main
67
68int MAIN(int, char **);
69
70int MAIN(int argc, char **argv)
71{
72        ENGINE *e = NULL;
73        char **args, *infile = NULL, *outfile = NULL;
74        char *passargin = NULL, *passargout = NULL;
75        BIO *in = NULL, *out = NULL;
76        int topk8 = 0;
77        int pbe_nid = -1;
78        const EVP_CIPHER *cipher = NULL;
79        int iter = PKCS12_DEFAULT_ITER;
80        int informat, outformat;
81        int p8_broken = PKCS8_OK;
82        int nocrypt = 0;
83        X509_SIG *p8;
84        PKCS8_PRIV_KEY_INFO *p8inf;
85        EVP_PKEY *pkey=NULL;
86        char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
87        int badarg = 0;
88        char *engine=NULL;
89
90        if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
91
92        if (!load_config(bio_err, NULL))
93                goto end;
94
95        informat=FORMAT_PEM;
96        outformat=FORMAT_PEM;
97
98        ERR_load_crypto_strings();
99        OpenSSL_add_all_algorithms();
100        args = argv + 1;
101        while (!badarg && *args && *args[0] == '-') {
102                if (!strcmp(*args,"-v2")) {
103                        if (args[1]) {
104                                args++;
105                                cipher=EVP_get_cipherbyname(*args);
106                                if(!cipher) {
107                                        BIO_printf(bio_err,
108                                                 "Unknown cipher %s\n", *args);
109                                        badarg = 1;
110                                }
111                        } else badarg = 1;
112                } else if (!strcmp(*args,"-v1")) {
113                        if (args[1]) {
114                                args++;
115                                pbe_nid=OBJ_txt2nid(*args);
116                                if(pbe_nid == NID_undef) {
117                                        BIO_printf(bio_err,
118                                                 "Unknown PBE algorithm %s\n", *args);
119                                        badarg = 1;
120                                }
121                        } else badarg = 1;
122                } else if (!strcmp(*args,"-inform")) {
123                        if (args[1]) {
124                                args++;
125                                informat=str2fmt(*args);
126                        } else badarg = 1;
127                } else if (!strcmp(*args,"-outform")) {
128                        if (args[1]) {
129                                args++;
130                                outformat=str2fmt(*args);
131                        } else badarg = 1;
132                } else if (!strcmp (*args, "-topk8")) topk8 = 1;
133                else if (!strcmp (*args, "-noiter")) iter = 1;
134                else if (!strcmp (*args, "-nocrypt")) nocrypt = 1;
135                else if (!strcmp (*args, "-nooct")) p8_broken = PKCS8_NO_OCTET;
136                else if (!strcmp (*args, "-nsdb")) p8_broken = PKCS8_NS_DB;
137                else if (!strcmp (*args, "-embed")) p8_broken = PKCS8_EMBEDDED_PARAM;
138                else if (!strcmp(*args,"-passin"))
139                        {
140                        if (!args[1]) goto bad;
141                        passargin= *(++args);
142                        }
143                else if (!strcmp(*args,"-passout"))
144                        {
145                        if (!args[1]) goto bad;
146                        passargout= *(++args);
147                        }
148                else if (strcmp(*args,"-engine") == 0)
149                        {
150                        if (!args[1]) goto bad;
151                        engine= *(++args);
152                        }
153                else if (!strcmp (*args, "-in")) {
154                        if (args[1]) {
155                                args++;
156                                infile = *args;
157                        } else badarg = 1;
158                } else if (!strcmp (*args, "-out")) {
159                        if (args[1]) {
160                                args++;
161                                outfile = *args;
162                        } else badarg = 1;
163                } else badarg = 1;
164                args++;
165        }
166
167        if (badarg) {
168                bad:
169                BIO_printf(bio_err, "Usage pkcs8 [options]\n");
170                BIO_printf(bio_err, "where options are\n");
171                BIO_printf(bio_err, "-in file        input file\n");
172                BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
173                BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
174                BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
175                BIO_printf(bio_err, "-out file       output file\n");
176                BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
177                BIO_printf(bio_err, "-topk8          output PKCS8 file\n");
178                BIO_printf(bio_err, "-nooct          use (nonstandard) no octet format\n");
179                BIO_printf(bio_err, "-embed          use (nonstandard) embedded DSA parameters format\n");
180                BIO_printf(bio_err, "-nsdb           use (nonstandard) DSA Netscape DB format\n");
181                BIO_printf(bio_err, "-noiter         use 1 as iteration count\n");
182                BIO_printf(bio_err, "-nocrypt        use or expect unencrypted private key\n");
183                BIO_printf(bio_err, "-v2 alg         use PKCS#5 v2.0 and cipher \"alg\"\n");
184                BIO_printf(bio_err, "-v1 obj         use PKCS#5 v1.5 and cipher \"alg\"\n");
185                BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
186                return (1);
187        }
188
189        e = setup_engine(bio_err, engine, 0);
190
191        if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
192                BIO_printf(bio_err, "Error getting passwords\n");
193                return (1);
194        }
195
196        if ((pbe_nid == -1) && !cipher) pbe_nid = NID_pbeWithMD5AndDES_CBC;
197
198        if (infile) {
199                if (!(in = BIO_new_file(infile, "rb"))) {
200                        BIO_printf(bio_err,
201                                 "Can't open input file %s\n", infile);
202                        return (1);
203                }
204        } else in = BIO_new_fp (stdin, BIO_NOCLOSE);
205
206        if (outfile) {
207                if (!(out = BIO_new_file (outfile, "wb"))) {
208                        BIO_printf(bio_err,
209                                 "Can't open output file %s\n", outfile);
210                        return (1);
211                }
212        } else {
213                out = BIO_new_fp (stdout, BIO_NOCLOSE);
214#ifdef OPENSSL_SYS_VMS
215                {
216                        BIO *tmpbio = BIO_new(BIO_f_linebuffer());
217                        out = BIO_push(tmpbio, out);
218                }
219#endif
220        }
221        if (topk8)
222                {
223                BIO_free(in); /* Not needed in this section */
224                pkey = load_key(bio_err, infile, informat, 1,
225                        passin, e, "key");
226                if (!pkey) {
227                        return (1);
228                }
229                if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) {
230                        BIO_printf(bio_err, "Error converting key\n", outfile);
231                        ERR_print_errors(bio_err);
232                        return (1);
233                }
234                if(nocrypt) {
235                        if(outformat == FORMAT_PEM)
236                                PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
237                        else if(outformat == FORMAT_ASN1)
238                                i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
239                        else {
240                                BIO_printf(bio_err, "Bad format specified for key\n");
241                                return (1);
242                        }
243                } else {
244                        if(passout) p8pass = passout;
245                        else {
246                                p8pass = pass;
247                                if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
248                                        return (1);
249                        }
250                        app_RAND_load_file(NULL, bio_err, 0);
251                        if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
252                                        p8pass, strlen(p8pass),
253                                        NULL, 0, iter, p8inf))) {
254                                BIO_printf(bio_err, "Error encrypting key\n",
255                                                                 outfile);
256                                ERR_print_errors(bio_err);
257                                return (1);
258                        }
259                        app_RAND_write_file(NULL, bio_err);
260                        if(outformat == FORMAT_PEM)
261                                PEM_write_bio_PKCS8(out, p8);
262                        else if(outformat == FORMAT_ASN1)
263                                i2d_PKCS8_bio(out, p8);
264                        else {
265                                BIO_printf(bio_err, "Bad format specified for key\n");
266                                return (1);
267                        }
268                        X509_SIG_free(p8);
269                }
270                PKCS8_PRIV_KEY_INFO_free (p8inf);
271                EVP_PKEY_free(pkey);
272                BIO_free_all(out);
273                if(passin) OPENSSL_free(passin);
274                if(passout) OPENSSL_free(passout);
275                return (0);
276        }
277
278        if(nocrypt) {
279                if(informat == FORMAT_PEM)
280                        p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
281                else if(informat == FORMAT_ASN1)
282                        p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
283                else {
284                        BIO_printf(bio_err, "Bad format specified for key\n");
285                        return (1);
286                }
287        } else {
288                if(informat == FORMAT_PEM)
289                        p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
290                else if(informat == FORMAT_ASN1)
291                        p8 = d2i_PKCS8_bio(in, NULL);
292                else {
293                        BIO_printf(bio_err, "Bad format specified for key\n");
294                        return (1);
295                }
296
297                if (!p8) {
298                        BIO_printf (bio_err, "Error reading key\n", outfile);
299                        ERR_print_errors(bio_err);
300                        return (1);
301                }
302                if(passin) p8pass = passin;
303                else {
304                        p8pass = pass;
305                        EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
306                }
307                p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
308                X509_SIG_free(p8);
309        }
310
311        if (!p8inf) {
312                BIO_printf(bio_err, "Error decrypting key\n", outfile);
313                ERR_print_errors(bio_err);
314                return (1);
315        }
316
317        if (!(pkey = EVP_PKCS82PKEY(p8inf))) {
318                BIO_printf(bio_err, "Error converting key\n", outfile);
319                ERR_print_errors(bio_err);
320                return (1);
321        }
322       
323        if (p8inf->broken) {
324                BIO_printf(bio_err, "Warning: broken key encoding: ");
325                switch (p8inf->broken) {
326                        case PKCS8_NO_OCTET:
327                        BIO_printf(bio_err, "No Octet String in PrivateKey\n");
328                        break;
329
330                        case PKCS8_EMBEDDED_PARAM:
331                        BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
332                        break;
333
334                        case PKCS8_NS_DB:
335                        BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
336                        break;
337
338                        default:
339                        BIO_printf(bio_err, "Unknown broken type\n");
340                        break;
341                }
342        }
343       
344        PKCS8_PRIV_KEY_INFO_free(p8inf);
345        if(outformat == FORMAT_PEM)
346                PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
347        else if(outformat == FORMAT_ASN1)
348                i2d_PrivateKey_bio(out, pkey);
349        else {
350                BIO_printf(bio_err, "Bad format specified for key\n");
351                        return (1);
352        }
353
354        end:
355        EVP_PKEY_free(pkey);
356        BIO_free_all(out);
357        BIO_free(in);
358        if(passin) OPENSSL_free(passin);
359        if(passout) OPENSSL_free(passout);
360
361        return (0);
362}
Note: See TracBrowser for help on using the repository browser.