]>
git.ipfire.org Git - thirdparty/openssl.git/blob - apps/pkcs8.c
2 * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
15 #include <openssl/pem.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <openssl/pkcs12.h>
20 typedef enum OPTION_choice
{
21 OPT_ERR
= -1, OPT_EOF
= 0, OPT_HELP
,
22 OPT_INFORM
, OPT_OUTFORM
, OPT_ENGINE
, OPT_IN
, OPT_OUT
,
23 OPT_TOPK8
, OPT_NOITER
, OPT_NOCRYPT
,
24 #ifndef OPENSSL_NO_SCRYPT
25 OPT_SCRYPT
, OPT_SCRYPT_N
, OPT_SCRYPT_R
, OPT_SCRYPT_P
,
27 OPT_V2
, OPT_V1
, OPT_V2PRF
, OPT_ITER
, OPT_PASSIN
, OPT_PASSOUT
,
32 const OPTIONS pkcs8_options
[] = {
33 {"help", OPT_HELP
, '-', "Display this summary"},
34 {"inform", OPT_INFORM
, 'F', "Input format (DER or PEM)"},
35 {"outform", OPT_OUTFORM
, 'F', "Output format (DER or PEM)"},
36 {"in", OPT_IN
, '<', "Input file"},
37 {"out", OPT_OUT
, '>', "Output file"},
38 {"topk8", OPT_TOPK8
, '-', "Output PKCS8 file"},
39 {"noiter", OPT_NOITER
, '-', "Use 1 as iteration count"},
40 {"nocrypt", OPT_NOCRYPT
, '-', "Use or expect unencrypted private key"},
42 {"v2", OPT_V2
, 's', "Use PKCS#5 v2.0 and cipher"},
43 {"v1", OPT_V1
, 's', "Use PKCS#5 v1.5 and cipher"},
44 {"v2prf", OPT_V2PRF
, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
45 {"iter", OPT_ITER
, 'p', "Specify the iteration count"},
46 {"passin", OPT_PASSIN
, 's', "Input file pass phrase source"},
47 {"passout", OPT_PASSOUT
, 's', "Output file pass phrase source"},
48 {"traditional", OPT_TRADITIONAL
, '-', "use traditional format private key"},
49 #ifndef OPENSSL_NO_ENGINE
50 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
52 #ifndef OPENSSL_NO_SCRYPT
53 {"scrypt", OPT_SCRYPT
, '-', "Use scrypt algorithm"},
54 {"scrypt_N", OPT_SCRYPT_N
, 's', "Set scrypt N parameter"},
55 {"scrypt_r", OPT_SCRYPT_R
, 's', "Set scrypt r parameter"},
56 {"scrypt_p", OPT_SCRYPT_P
, 's', "Set scrypt p parameter"},
61 int pkcs8_main(int argc
, char **argv
)
63 BIO
*in
= NULL
, *out
= NULL
;
65 EVP_PKEY
*pkey
= NULL
;
66 PKCS8_PRIV_KEY_INFO
*p8inf
= NULL
;
68 const EVP_CIPHER
*cipher
= NULL
;
69 char *infile
= NULL
, *outfile
= NULL
;
70 char *passinarg
= NULL
, *passoutarg
= NULL
, *prog
;
71 #ifndef OPENSSL_NO_UI_CONSOLE
72 char pass
[APP_PASS_LEN
];
74 char *passin
= NULL
, *passout
= NULL
, *p8pass
= NULL
;
76 int nocrypt
= 0, ret
= 1, iter
= PKCS12_DEFAULT_ITER
;
77 int informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, topk8
= 0, pbe_nid
= -1;
78 int private = 0, traditional
= 0;
79 #ifndef OPENSSL_NO_SCRYPT
80 long scrypt_N
= 0, scrypt_r
= 0, scrypt_p
= 0;
83 prog
= opt_init(argc
, argv
, pkcs8_options
);
84 while ((o
= opt_next()) != OPT_EOF
) {
89 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
92 opt_help(pkcs8_options
);
96 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
103 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
122 case OPT_TRADITIONAL
:
126 if (!opt_cipher(opt_arg(), &cipher
))
130 pbe_nid
= OBJ_txt2nid(opt_arg());
131 if (pbe_nid
== NID_undef
) {
133 "%s: Unknown PBE algorithm %s\n", prog
, opt_arg());
138 pbe_nid
= OBJ_txt2nid(opt_arg());
139 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF
, pbe_nid
, NULL
, NULL
, 0)) {
141 "%s: Unknown PRF algorithm %s\n", prog
, opt_arg());
145 cipher
= EVP_aes_256_cbc();
148 if (!opt_int(opt_arg(), &iter
))
152 passinarg
= opt_arg();
155 passoutarg
= opt_arg();
158 e
= setup_engine(opt_arg(), 0);
160 #ifndef OPENSSL_NO_SCRYPT
166 cipher
= EVP_aes_256_cbc();
169 if (!opt_long(opt_arg(), &scrypt_N
) || scrypt_N
<= 0)
173 if (!opt_long(opt_arg(), &scrypt_r
) || scrypt_r
<= 0)
177 if (!opt_long(opt_arg(), &scrypt_p
) || scrypt_p
<= 0)
183 argc
= opt_num_rest();
189 if (!app_passwd(passinarg
, passoutarg
, &passin
, &passout
)) {
190 BIO_printf(bio_err
, "Error getting passwords\n");
194 if ((pbe_nid
== -1) && cipher
== NULL
)
195 cipher
= EVP_aes_256_cbc();
197 in
= bio_open_default(infile
, 'r', informat
);
200 out
= bio_open_owner(outfile
, outformat
, private);
205 pkey
= load_key(infile
, informat
, 1, passin
, e
, "key");
208 if ((p8inf
= EVP_PKEY2PKCS8(pkey
)) == NULL
) {
209 BIO_printf(bio_err
, "Error converting key\n");
210 ERR_print_errors(bio_err
);
215 if (outformat
== FORMAT_PEM
) {
216 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out
, p8inf
);
217 } else if (outformat
== FORMAT_ASN1
) {
218 i2d_PKCS8_PRIV_KEY_INFO_bio(out
, p8inf
);
220 BIO_printf(bio_err
, "Bad format specified for key\n");
226 #ifndef OPENSSL_NO_SCRYPT
227 if (scrypt_N
&& scrypt_r
&& scrypt_p
)
228 pbe
= PKCS5_pbe2_set_scrypt(cipher
, NULL
, 0, NULL
,
229 scrypt_N
, scrypt_r
, scrypt_p
);
232 pbe
= PKCS5_pbe2_set_iv(cipher
, iter
, NULL
, 0, NULL
,
235 pbe
= PKCS5_pbe_set(pbe_nid
, iter
, NULL
, 0);
238 BIO_printf(bio_err
, "Error setting PBE algorithm\n");
239 ERR_print_errors(bio_err
);
242 if (passout
!= NULL
) {
245 /* To avoid bit rot */
246 #ifndef OPENSSL_NO_UI_CONSOLE
248 if (EVP_read_pw_string
249 (pass
, sizeof(pass
), "Enter Encryption Password:", 1)) {
250 X509_ALGOR_free(pbe
);
255 BIO_printf(bio_err
, "Password required\n");
258 p8
= PKCS8_set0_pbe(p8pass
, strlen(p8pass
), p8inf
, pbe
);
260 X509_ALGOR_free(pbe
);
261 BIO_printf(bio_err
, "Error encrypting key\n");
262 ERR_print_errors(bio_err
);
266 if (outformat
== FORMAT_PEM
)
267 PEM_write_bio_PKCS8(out
, p8
);
268 else if (outformat
== FORMAT_ASN1
)
269 i2d_PKCS8_bio(out
, p8
);
271 BIO_printf(bio_err
, "Bad format specified for key\n");
281 if (informat
== FORMAT_PEM
) {
282 p8inf
= PEM_read_bio_PKCS8_PRIV_KEY_INFO(in
, NULL
, NULL
, NULL
);
283 } else if (informat
== FORMAT_ASN1
) {
284 p8inf
= d2i_PKCS8_PRIV_KEY_INFO_bio(in
, NULL
);
286 BIO_printf(bio_err
, "Bad format specified for key\n");
290 if (informat
== FORMAT_PEM
) {
291 p8
= PEM_read_bio_PKCS8(in
, NULL
, NULL
, NULL
);
292 } else if (informat
== FORMAT_ASN1
) {
293 p8
= d2i_PKCS8_bio(in
, NULL
);
295 BIO_printf(bio_err
, "Bad format specified for key\n");
300 BIO_printf(bio_err
, "Error reading key\n");
301 ERR_print_errors(bio_err
);
304 if (passin
!= NULL
) {
307 #ifndef OPENSSL_NO_UI_CONSOLE
309 if (EVP_read_pw_string(pass
, sizeof(pass
), "Enter Password:", 0)) {
310 BIO_printf(bio_err
, "Can't read Password\n");
315 BIO_printf(bio_err
, "Password required\n");
318 p8inf
= PKCS8_decrypt(p8
, p8pass
, strlen(p8pass
));
322 BIO_printf(bio_err
, "Error decrypting key\n");
323 ERR_print_errors(bio_err
);
327 if ((pkey
= EVP_PKCS82PKEY(p8inf
)) == NULL
) {
328 BIO_printf(bio_err
, "Error converting key\n");
329 ERR_print_errors(bio_err
);
334 if (outformat
== FORMAT_PEM
) {
336 PEM_write_bio_PrivateKey_traditional(out
, pkey
, NULL
, NULL
, 0,
339 PEM_write_bio_PrivateKey(out
, pkey
, NULL
, NULL
, 0, NULL
, passout
);
340 } else if (outformat
== FORMAT_ASN1
) {
341 i2d_PrivateKey_bio(out
, pkey
);
343 BIO_printf(bio_err
, "Bad format specified for key\n");
350 PKCS8_PRIV_KEY_INFO_free(p8inf
);
355 OPENSSL_free(passin
);
356 OPENSSL_free(passout
);