]>
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 OPT_SECTION("General"),
34 {"help", OPT_HELP
, '-', "Display this summary"},
35 #ifndef OPENSSL_NO_ENGINE
36 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
38 {"v1", OPT_V1
, 's', "Use PKCS#5 v1.5 and cipher"},
39 {"v2", OPT_V2
, 's', "Use PKCS#5 v2.0 and cipher"},
40 {"v2prf", OPT_V2PRF
, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
43 {"in", OPT_IN
, '<', "Input file"},
44 {"inform", OPT_INFORM
, 'F', "Input format (DER or PEM)"},
45 {"passin", OPT_PASSIN
, 's', "Input file pass phrase source"},
46 {"nocrypt", OPT_NOCRYPT
, '-', "Use or expect unencrypted private key"},
48 OPT_SECTION("Output"),
49 {"out", OPT_OUT
, '>', "Output file"},
50 {"outform", OPT_OUTFORM
, 'F', "Output format (DER or PEM)"},
51 {"topk8", OPT_TOPK8
, '-', "Output PKCS8 file"},
52 {"passout", OPT_PASSOUT
, 's', "Output file pass phrase source"},
53 {"traditional", OPT_TRADITIONAL
, '-', "use traditional format private key"},
54 {"iter", OPT_ITER
, 'p', "Specify the iteration count"},
55 {"noiter", OPT_NOITER
, '-', "Use 1 as iteration count"},
57 #ifndef OPENSSL_NO_SCRYPT
58 OPT_SECTION("Scrypt"),
59 {"scrypt", OPT_SCRYPT
, '-', "Use scrypt algorithm"},
60 {"scrypt_N", OPT_SCRYPT_N
, 's', "Set scrypt N parameter"},
61 {"scrypt_r", OPT_SCRYPT_R
, 's', "Set scrypt r parameter"},
62 {"scrypt_p", OPT_SCRYPT_P
, 's', "Set scrypt p parameter"},
69 int pkcs8_main(int argc
, char **argv
)
71 BIO
*in
= NULL
, *out
= NULL
;
73 EVP_PKEY
*pkey
= NULL
;
74 PKCS8_PRIV_KEY_INFO
*p8inf
= NULL
;
76 const EVP_CIPHER
*cipher
= NULL
;
77 char *infile
= NULL
, *outfile
= NULL
;
78 char *passinarg
= NULL
, *passoutarg
= NULL
, *prog
;
79 #ifndef OPENSSL_NO_UI_CONSOLE
80 char pass
[APP_PASS_LEN
];
82 char *passin
= NULL
, *passout
= NULL
, *p8pass
= NULL
;
84 int nocrypt
= 0, ret
= 1, iter
= PKCS12_DEFAULT_ITER
;
85 int informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, topk8
= 0, pbe_nid
= -1;
86 int private = 0, traditional
= 0;
87 #ifndef OPENSSL_NO_SCRYPT
88 long scrypt_N
= 0, scrypt_r
= 0, scrypt_p
= 0;
91 prog
= opt_init(argc
, argv
, pkcs8_options
);
92 while ((o
= opt_next()) != OPT_EOF
) {
97 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
100 opt_help(pkcs8_options
);
104 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
111 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
130 case OPT_TRADITIONAL
:
134 if (!opt_cipher(opt_arg(), &cipher
))
138 pbe_nid
= OBJ_txt2nid(opt_arg());
139 if (pbe_nid
== NID_undef
) {
141 "%s: Unknown PBE algorithm %s\n", prog
, opt_arg());
146 pbe_nid
= OBJ_txt2nid(opt_arg());
147 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF
, pbe_nid
, NULL
, NULL
, 0)) {
149 "%s: Unknown PRF algorithm %s\n", prog
, opt_arg());
153 cipher
= EVP_aes_256_cbc();
156 if (!opt_int(opt_arg(), &iter
))
160 passinarg
= opt_arg();
163 passoutarg
= opt_arg();
166 e
= setup_engine(opt_arg(), 0);
168 #ifndef OPENSSL_NO_SCRYPT
174 cipher
= EVP_aes_256_cbc();
177 if (!opt_long(opt_arg(), &scrypt_N
) || scrypt_N
<= 0)
181 if (!opt_long(opt_arg(), &scrypt_r
) || scrypt_r
<= 0)
185 if (!opt_long(opt_arg(), &scrypt_p
) || scrypt_p
<= 0)
191 argc
= opt_num_rest();
197 if (!app_passwd(passinarg
, passoutarg
, &passin
, &passout
)) {
198 BIO_printf(bio_err
, "Error getting passwords\n");
202 if ((pbe_nid
== -1) && cipher
== NULL
)
203 cipher
= EVP_aes_256_cbc();
205 in
= bio_open_default(infile
, 'r', informat
);
208 out
= bio_open_owner(outfile
, outformat
, private);
213 pkey
= load_key(infile
, informat
, 1, passin
, e
, "key");
216 if ((p8inf
= EVP_PKEY2PKCS8(pkey
)) == NULL
) {
217 BIO_printf(bio_err
, "Error converting key\n");
218 ERR_print_errors(bio_err
);
223 if (outformat
== FORMAT_PEM
) {
224 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out
, p8inf
);
225 } else if (outformat
== FORMAT_ASN1
) {
226 i2d_PKCS8_PRIV_KEY_INFO_bio(out
, p8inf
);
228 BIO_printf(bio_err
, "Bad format specified for key\n");
234 #ifndef OPENSSL_NO_SCRYPT
235 if (scrypt_N
&& scrypt_r
&& scrypt_p
)
236 pbe
= PKCS5_pbe2_set_scrypt(cipher
, NULL
, 0, NULL
,
237 scrypt_N
, scrypt_r
, scrypt_p
);
240 pbe
= PKCS5_pbe2_set_iv(cipher
, iter
, NULL
, 0, NULL
,
243 pbe
= PKCS5_pbe_set(pbe_nid
, iter
, NULL
, 0);
246 BIO_printf(bio_err
, "Error setting PBE algorithm\n");
247 ERR_print_errors(bio_err
);
250 if (passout
!= NULL
) {
253 /* To avoid bit rot */
254 #ifndef OPENSSL_NO_UI_CONSOLE
256 if (EVP_read_pw_string
257 (pass
, sizeof(pass
), "Enter Encryption Password:", 1)) {
258 X509_ALGOR_free(pbe
);
263 BIO_printf(bio_err
, "Password required\n");
266 p8
= PKCS8_set0_pbe(p8pass
, strlen(p8pass
), p8inf
, pbe
);
268 X509_ALGOR_free(pbe
);
269 BIO_printf(bio_err
, "Error encrypting key\n");
270 ERR_print_errors(bio_err
);
274 if (outformat
== FORMAT_PEM
)
275 PEM_write_bio_PKCS8(out
, p8
);
276 else if (outformat
== FORMAT_ASN1
)
277 i2d_PKCS8_bio(out
, p8
);
279 BIO_printf(bio_err
, "Bad format specified for key\n");
289 if (informat
== FORMAT_PEM
) {
290 p8inf
= PEM_read_bio_PKCS8_PRIV_KEY_INFO(in
, NULL
, NULL
, NULL
);
291 } else if (informat
== FORMAT_ASN1
) {
292 p8inf
= d2i_PKCS8_PRIV_KEY_INFO_bio(in
, NULL
);
294 BIO_printf(bio_err
, "Bad format specified for key\n");
298 if (informat
== FORMAT_PEM
) {
299 p8
= PEM_read_bio_PKCS8(in
, NULL
, NULL
, NULL
);
300 } else if (informat
== FORMAT_ASN1
) {
301 p8
= d2i_PKCS8_bio(in
, NULL
);
303 BIO_printf(bio_err
, "Bad format specified for key\n");
308 BIO_printf(bio_err
, "Error reading key\n");
309 ERR_print_errors(bio_err
);
312 if (passin
!= NULL
) {
315 #ifndef OPENSSL_NO_UI_CONSOLE
317 if (EVP_read_pw_string(pass
, sizeof(pass
), "Enter Password:", 0)) {
318 BIO_printf(bio_err
, "Can't read Password\n");
323 BIO_printf(bio_err
, "Password required\n");
326 p8inf
= PKCS8_decrypt(p8
, p8pass
, strlen(p8pass
));
330 BIO_printf(bio_err
, "Error decrypting key\n");
331 ERR_print_errors(bio_err
);
335 if ((pkey
= EVP_PKCS82PKEY(p8inf
)) == NULL
) {
336 BIO_printf(bio_err
, "Error converting key\n");
337 ERR_print_errors(bio_err
);
342 if (outformat
== FORMAT_PEM
) {
344 PEM_write_bio_PrivateKey_traditional(out
, pkey
, NULL
, NULL
, 0,
347 PEM_write_bio_PrivateKey(out
, pkey
, NULL
, NULL
, 0, NULL
, passout
);
348 } else if (outformat
== FORMAT_ASN1
) {
349 i2d_PrivateKey_bio(out
, pkey
);
351 BIO_printf(bio_err
, "Bad format specified for key\n");
358 PKCS8_PRIV_KEY_INFO_free(p8inf
);
363 OPENSSL_free(passin
);
364 OPENSSL_free(passout
);