]>
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
,
31 const OPTIONS pkcs8_options
[] = {
32 {"help", OPT_HELP
, '-', "Display this summary"},
33 {"inform", OPT_INFORM
, 'F', "Input format (DER or PEM)"},
34 {"outform", OPT_OUTFORM
, 'F', "Output format (DER or PEM)"},
35 {"in", OPT_IN
, '<', "Input file"},
36 {"out", OPT_OUT
, '>', "Output file"},
37 {"topk8", OPT_TOPK8
, '-', "Output PKCS8 file"},
38 {"noiter", OPT_NOITER
, '-', "Use 1 as iteration count"},
39 {"nocrypt", OPT_NOCRYPT
, '-', "Use or expect unencrypted private key"},
41 {"v2", OPT_V2
, 's', "Use PKCS#5 v2.0 and cipher"},
42 {"v1", OPT_V1
, 's', "Use PKCS#5 v1.5 and cipher"},
43 {"v2prf", OPT_V2PRF
, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
44 {"iter", OPT_ITER
, 'p', "Specify the iteration count"},
45 {"passin", OPT_PASSIN
, 's', "Input file pass phrase source"},
46 {"passout", OPT_PASSOUT
, 's', "Output file pass phrase source"},
47 {"traditional", OPT_TRADITIONAL
, '-', "use traditional format private key"},
48 #ifndef OPENSSL_NO_ENGINE
49 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
51 #ifndef OPENSSL_NO_SCRYPT
52 {"scrypt", OPT_SCRYPT
, '-', "Use scrypt algorithm"},
53 {"scrypt_N", OPT_SCRYPT_N
, 's', "Set scrypt N parameter"},
54 {"scrypt_r", OPT_SCRYPT_R
, 's', "Set scrypt r parameter"},
55 {"scrypt_p", OPT_SCRYPT_P
, 's', "Set scrypt p parameter"},
60 int pkcs8_main(int argc
, char **argv
)
62 BIO
*in
= NULL
, *out
= NULL
;
64 EVP_PKEY
*pkey
= NULL
;
65 PKCS8_PRIV_KEY_INFO
*p8inf
= NULL
;
67 const EVP_CIPHER
*cipher
= NULL
;
68 char *infile
= NULL
, *outfile
= NULL
;
69 char *passinarg
= NULL
, *passoutarg
= NULL
, *prog
;
70 #ifndef OPENSSL_NO_UI_CONSOLE
71 char pass
[APP_PASS_LEN
];
73 char *passin
= NULL
, *passout
= NULL
, *p8pass
= NULL
;
75 int nocrypt
= 0, ret
= 1, iter
= PKCS12_DEFAULT_ITER
;
76 int informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, topk8
= 0, pbe_nid
= -1;
77 int private = 0, traditional
= 0;
78 #ifndef OPENSSL_NO_SCRYPT
79 long scrypt_N
= 0, scrypt_r
= 0, scrypt_p
= 0;
82 prog
= opt_init(argc
, argv
, pkcs8_options
);
83 while ((o
= opt_next()) != OPT_EOF
) {
88 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
91 opt_help(pkcs8_options
);
95 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
102 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
121 case OPT_TRADITIONAL
:
125 if (!opt_cipher(opt_arg(), &cipher
))
129 pbe_nid
= OBJ_txt2nid(opt_arg());
130 if (pbe_nid
== NID_undef
) {
132 "%s: Unknown PBE algorithm %s\n", prog
, opt_arg());
137 pbe_nid
= OBJ_txt2nid(opt_arg());
138 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF
, pbe_nid
, NULL
, NULL
, 0)) {
140 "%s: Unknown PRF algorithm %s\n", prog
, opt_arg());
144 cipher
= EVP_aes_256_cbc();
147 if (!opt_int(opt_arg(), &iter
))
151 passinarg
= opt_arg();
154 passoutarg
= opt_arg();
157 e
= setup_engine(opt_arg(), 0);
159 #ifndef OPENSSL_NO_SCRYPT
165 cipher
= EVP_aes_256_cbc();
168 if (!opt_long(opt_arg(), &scrypt_N
) || scrypt_N
<= 0)
172 if (!opt_long(opt_arg(), &scrypt_r
) || scrypt_r
<= 0)
176 if (!opt_long(opt_arg(), &scrypt_p
) || scrypt_p
<= 0)
182 argc
= opt_num_rest();
188 if (!app_passwd(passinarg
, passoutarg
, &passin
, &passout
)) {
189 BIO_printf(bio_err
, "Error getting passwords\n");
193 if ((pbe_nid
== -1) && cipher
== NULL
)
194 cipher
= EVP_aes_256_cbc();
196 in
= bio_open_default(infile
, 'r', informat
);
199 out
= bio_open_owner(outfile
, outformat
, private);
204 pkey
= load_key(infile
, informat
, 1, passin
, e
, "key");
207 if ((p8inf
= EVP_PKEY2PKCS8(pkey
)) == NULL
) {
208 BIO_printf(bio_err
, "Error converting key\n");
209 ERR_print_errors(bio_err
);
214 if (outformat
== FORMAT_PEM
) {
215 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out
, p8inf
);
216 } else if (outformat
== FORMAT_ASN1
) {
217 i2d_PKCS8_PRIV_KEY_INFO_bio(out
, p8inf
);
219 BIO_printf(bio_err
, "Bad format specified for key\n");
225 #ifndef OPENSSL_NO_SCRYPT
226 if (scrypt_N
&& scrypt_r
&& scrypt_p
)
227 pbe
= PKCS5_pbe2_set_scrypt(cipher
, NULL
, 0, NULL
,
228 scrypt_N
, scrypt_r
, scrypt_p
);
231 pbe
= PKCS5_pbe2_set_iv(cipher
, iter
, NULL
, 0, NULL
,
234 pbe
= PKCS5_pbe_set(pbe_nid
, iter
, NULL
, 0);
237 BIO_printf(bio_err
, "Error setting PBE algorithm\n");
238 ERR_print_errors(bio_err
);
241 if (passout
!= NULL
) {
244 /* To avoid bit rot */
245 #ifndef OPENSSL_NO_UI_CONSOLE
247 if (EVP_read_pw_string
248 (pass
, sizeof pass
, "Enter Encryption Password:", 1)) {
249 X509_ALGOR_free(pbe
);
254 BIO_printf(bio_err
, "Password required\n");
257 p8
= PKCS8_set0_pbe(p8pass
, strlen(p8pass
), p8inf
, pbe
);
259 X509_ALGOR_free(pbe
);
260 BIO_printf(bio_err
, "Error encrypting key\n");
261 ERR_print_errors(bio_err
);
265 if (outformat
== FORMAT_PEM
)
266 PEM_write_bio_PKCS8(out
, p8
);
267 else if (outformat
== FORMAT_ASN1
)
268 i2d_PKCS8_bio(out
, p8
);
270 BIO_printf(bio_err
, "Bad format specified for key\n");
280 if (informat
== FORMAT_PEM
) {
281 p8inf
= PEM_read_bio_PKCS8_PRIV_KEY_INFO(in
, NULL
, NULL
, NULL
);
282 } else if (informat
== FORMAT_ASN1
) {
283 p8inf
= d2i_PKCS8_PRIV_KEY_INFO_bio(in
, NULL
);
285 BIO_printf(bio_err
, "Bad format specified for key\n");
289 if (informat
== FORMAT_PEM
) {
290 p8
= PEM_read_bio_PKCS8(in
, NULL
, NULL
, NULL
);
291 } else if (informat
== FORMAT_ASN1
) {
292 p8
= d2i_PKCS8_bio(in
, NULL
);
294 BIO_printf(bio_err
, "Bad format specified for key\n");
299 BIO_printf(bio_err
, "Error reading key\n");
300 ERR_print_errors(bio_err
);
303 if (passin
!= NULL
) {
306 #ifndef OPENSSL_NO_UI_CONSOLE
308 if (EVP_read_pw_string(pass
, sizeof pass
, "Enter Password:", 0)) {
309 BIO_printf(bio_err
, "Can't read Password\n");
314 BIO_printf(bio_err
, "Password required\n");
317 p8inf
= PKCS8_decrypt(p8
, p8pass
, strlen(p8pass
));
321 BIO_printf(bio_err
, "Error decrypting key\n");
322 ERR_print_errors(bio_err
);
326 if ((pkey
= EVP_PKCS82PKEY(p8inf
)) == NULL
) {
327 BIO_printf(bio_err
, "Error converting key\n");
328 ERR_print_errors(bio_err
);
333 if (outformat
== FORMAT_PEM
) {
335 PEM_write_bio_PrivateKey_traditional(out
, pkey
, NULL
, NULL
, 0,
338 PEM_write_bio_PrivateKey(out
, pkey
, NULL
, NULL
, 0, NULL
, passout
);
339 } else if (outformat
== FORMAT_ASN1
) {
340 i2d_PrivateKey_bio(out
, pkey
);
342 BIO_printf(bio_err
, "Bad format specified for key\n");
349 PKCS8_PRIV_KEY_INFO_free(p8inf
);
354 OPENSSL_free(passin
);
355 OPENSSL_free(passout
);