]>
git.ipfire.org Git - thirdparty/openssl.git/blob - apps/pkcs8.c
2 * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (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
14 #include <openssl/pem.h>
15 #include <openssl/err.h>
16 #include <openssl/evp.h>
17 #include <openssl/pkcs12.h>
19 typedef enum OPTION_choice
{
20 OPT_ERR
= -1, OPT_EOF
= 0, OPT_HELP
,
21 OPT_INFORM
, OPT_OUTFORM
, OPT_ENGINE
, OPT_IN
, OPT_OUT
,
22 OPT_TOPK8
, OPT_NOITER
, OPT_NOCRYPT
,
23 #ifndef OPENSSL_NO_SCRYPT
24 OPT_SCRYPT
, OPT_SCRYPT_N
, OPT_SCRYPT_R
, OPT_SCRYPT_P
,
26 OPT_V2
, OPT_V1
, OPT_V2PRF
, OPT_ITER
, OPT_PASSIN
, OPT_PASSOUT
,
30 const OPTIONS pkcs8_options
[] = {
31 {"help", OPT_HELP
, '-', "Display this summary"},
32 {"inform", OPT_INFORM
, 'F', "Input format (DER or PEM)"},
33 {"outform", OPT_OUTFORM
, 'F', "Output format (DER or PEM)"},
34 {"in", OPT_IN
, '<', "Input file"},
35 {"out", OPT_OUT
, '>', "Output file"},
36 {"topk8", OPT_TOPK8
, '-', "Output PKCS8 file"},
37 {"noiter", OPT_NOITER
, '-', "Use 1 as iteration count"},
38 {"nocrypt", OPT_NOCRYPT
, '-', "Use or expect unencrypted private key"},
39 {"v2", OPT_V2
, 's', "Use PKCS#5 v2.0 and cipher"},
40 {"v1", OPT_V1
, 's', "Use PKCS#5 v1.5 and cipher"},
41 {"v2prf", OPT_V2PRF
, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
42 {"iter", OPT_ITER
, 'p', "Specify the iteration count"},
43 {"passin", OPT_PASSIN
, 's', "Input file pass phrase source"},
44 {"passout", OPT_PASSOUT
, 's', "Output file pass phrase source"},
45 {"traditional", OPT_TRADITIONAL
, '-', "use traditional format private key"},
46 #ifndef OPENSSL_NO_ENGINE
47 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
49 #ifndef OPENSSL_NO_SCRYPT
50 {"scrypt", OPT_SCRYPT
, '-', "Use scrypt algorithm"},
51 {"scrypt_N", OPT_SCRYPT_N
, 's', "Set scrypt N parameter"},
52 {"scrypt_r", OPT_SCRYPT_R
, 's', "Set scrypt r parameter"},
53 {"scrypt_p", OPT_SCRYPT_P
, 's', "Set scrypt p parameter"},
58 int pkcs8_main(int argc
, char **argv
)
60 BIO
*in
= NULL
, *out
= NULL
;
62 EVP_PKEY
*pkey
= NULL
;
63 PKCS8_PRIV_KEY_INFO
*p8inf
= NULL
;
65 const EVP_CIPHER
*cipher
= NULL
;
66 char *infile
= NULL
, *outfile
= NULL
;
67 char *passinarg
= NULL
, *passoutarg
= NULL
, *prog
;
68 #ifndef OPENSSL_NO_UI_CONSOLE
69 char pass
[APP_PASS_LEN
];
71 char *passin
= NULL
, *passout
= NULL
, *p8pass
= NULL
;
73 int nocrypt
= 0, ret
= 1, iter
= PKCS12_DEFAULT_ITER
;
74 int informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, topk8
= 0, pbe_nid
= -1;
75 int private = 0, traditional
= 0;
76 #ifndef OPENSSL_NO_SCRYPT
77 long scrypt_N
= 0, scrypt_r
= 0, scrypt_p
= 0;
80 prog
= opt_init(argc
, argv
, pkcs8_options
);
81 while ((o
= opt_next()) != OPT_EOF
) {
86 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
89 opt_help(pkcs8_options
);
93 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
100 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
115 case OPT_TRADITIONAL
:
119 if (!opt_cipher(opt_arg(), &cipher
))
123 pbe_nid
= OBJ_txt2nid(opt_arg());
124 if (pbe_nid
== NID_undef
) {
126 "%s: Unknown PBE algorithm %s\n", prog
, opt_arg());
131 pbe_nid
= OBJ_txt2nid(opt_arg());
132 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF
, pbe_nid
, NULL
, NULL
, 0)) {
134 "%s: Unknown PRF algorithm %s\n", prog
, opt_arg());
138 cipher
= EVP_aes_256_cbc();
141 if (!opt_int(opt_arg(), &iter
))
145 passinarg
= opt_arg();
148 passoutarg
= opt_arg();
151 e
= setup_engine(opt_arg(), 0);
153 #ifndef OPENSSL_NO_SCRYPT
159 cipher
= EVP_aes_256_cbc();
162 if (!opt_long(opt_arg(), &scrypt_N
) || scrypt_N
<= 0)
166 if (!opt_long(opt_arg(), &scrypt_r
) || scrypt_r
<= 0)
170 if (!opt_long(opt_arg(), &scrypt_p
) || scrypt_p
<= 0)
176 argc
= opt_num_rest();
182 if (!app_passwd(passinarg
, passoutarg
, &passin
, &passout
)) {
183 BIO_printf(bio_err
, "Error getting passwords\n");
187 if ((pbe_nid
== -1) && cipher
== NULL
)
188 cipher
= EVP_aes_256_cbc();
190 in
= bio_open_default(infile
, 'r', informat
);
193 out
= bio_open_owner(outfile
, outformat
, private);
198 pkey
= load_key(infile
, informat
, 1, passin
, e
, "key");
201 if ((p8inf
= EVP_PKEY2PKCS8(pkey
)) == NULL
) {
202 BIO_printf(bio_err
, "Error converting key\n");
203 ERR_print_errors(bio_err
);
208 if (outformat
== FORMAT_PEM
) {
209 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out
, p8inf
);
210 } else if (outformat
== FORMAT_ASN1
) {
211 i2d_PKCS8_PRIV_KEY_INFO_bio(out
, p8inf
);
213 BIO_printf(bio_err
, "Bad format specified for key\n");
219 #ifndef OPENSSL_NO_SCRYPT
220 if (scrypt_N
&& scrypt_r
&& scrypt_p
)
221 pbe
= PKCS5_pbe2_set_scrypt(cipher
, NULL
, 0, NULL
,
222 scrypt_N
, scrypt_r
, scrypt_p
);
225 pbe
= PKCS5_pbe2_set_iv(cipher
, iter
, NULL
, 0, NULL
,
228 pbe
= PKCS5_pbe_set(pbe_nid
, iter
, NULL
, 0);
231 BIO_printf(bio_err
, "Error setting PBE algorithm\n");
232 ERR_print_errors(bio_err
);
235 if (passout
!= NULL
) {
238 /* To avoid bit rot */
239 #ifndef OPENSSL_NO_UI_CONSOLE
241 if (EVP_read_pw_string
242 (pass
, sizeof pass
, "Enter Encryption Password:", 1)) {
243 X509_ALGOR_free(pbe
);
248 BIO_printf(bio_err
, "Password required\n");
251 app_RAND_load_file(NULL
, 0);
252 p8
= PKCS8_set0_pbe(p8pass
, strlen(p8pass
), p8inf
, pbe
);
254 X509_ALGOR_free(pbe
);
255 BIO_printf(bio_err
, "Error encrypting key\n");
256 ERR_print_errors(bio_err
);
259 app_RAND_write_file(NULL
);
261 if (outformat
== FORMAT_PEM
)
262 PEM_write_bio_PKCS8(out
, p8
);
263 else if (outformat
== FORMAT_ASN1
)
264 i2d_PKCS8_bio(out
, p8
);
266 BIO_printf(bio_err
, "Bad format specified for key\n");
276 if (informat
== FORMAT_PEM
) {
277 p8inf
= PEM_read_bio_PKCS8_PRIV_KEY_INFO(in
, NULL
, NULL
, NULL
);
278 } else if (informat
== FORMAT_ASN1
) {
279 p8inf
= d2i_PKCS8_PRIV_KEY_INFO_bio(in
, NULL
);
281 BIO_printf(bio_err
, "Bad format specified for key\n");
285 if (informat
== FORMAT_PEM
) {
286 p8
= PEM_read_bio_PKCS8(in
, NULL
, NULL
, NULL
);
287 } else if (informat
== FORMAT_ASN1
) {
288 p8
= d2i_PKCS8_bio(in
, NULL
);
290 BIO_printf(bio_err
, "Bad format specified for key\n");
295 BIO_printf(bio_err
, "Error reading key\n");
296 ERR_print_errors(bio_err
);
299 if (passin
!= NULL
) {
302 #ifndef OPENSSL_NO_UI_CONSOLE
304 if (EVP_read_pw_string(pass
, sizeof pass
, "Enter Password:", 0)) {
305 BIO_printf(bio_err
, "Can't read Password\n");
310 BIO_printf(bio_err
, "Password required\n");
313 p8inf
= PKCS8_decrypt(p8
, p8pass
, strlen(p8pass
));
317 BIO_printf(bio_err
, "Error decrypting key\n");
318 ERR_print_errors(bio_err
);
322 if ((pkey
= EVP_PKCS82PKEY(p8inf
)) == NULL
) {
323 BIO_printf(bio_err
, "Error converting key\n");
324 ERR_print_errors(bio_err
);
329 if (outformat
== FORMAT_PEM
) {
331 PEM_write_bio_PrivateKey_traditional(out
, pkey
, NULL
, NULL
, 0,
334 PEM_write_bio_PrivateKey(out
, pkey
, NULL
, NULL
, 0, NULL
, passout
);
335 } else if (outformat
== FORMAT_ASN1
) {
336 i2d_PrivateKey_bio(out
, pkey
);
338 BIO_printf(bio_err
, "Bad format specified for key\n");
345 PKCS8_PRIV_KEY_INFO_free(p8inf
);
350 OPENSSL_free(passin
);
351 OPENSSL_free(passout
);