]>
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
,
29 OPT_R_ENUM
, OPT_PROV_ENUM
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"},
70 int pkcs8_main(int argc
, char **argv
)
72 BIO
*in
= NULL
, *out
= NULL
;
74 EVP_PKEY
*pkey
= NULL
;
75 PKCS8_PRIV_KEY_INFO
*p8inf
= NULL
;
77 const EVP_CIPHER
*cipher
= NULL
;
78 char *infile
= NULL
, *outfile
= NULL
;
79 char *passinarg
= NULL
, *passoutarg
= NULL
, *prog
;
80 #ifndef OPENSSL_NO_UI_CONSOLE
81 char pass
[APP_PASS_LEN
];
83 char *passin
= NULL
, *passout
= NULL
, *p8pass
= NULL
;
85 int nocrypt
= 0, ret
= 1, iter
= PKCS12_DEFAULT_ITER
;
86 int informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, topk8
= 0, pbe_nid
= -1;
87 int private = 0, traditional
= 0;
88 #ifndef OPENSSL_NO_SCRYPT
89 long scrypt_N
= 0, scrypt_r
= 0, scrypt_p
= 0;
92 prog
= opt_init(argc
, argv
, pkcs8_options
);
93 while ((o
= opt_next()) != OPT_EOF
) {
98 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
101 opt_help(pkcs8_options
);
105 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
112 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
132 if (!opt_provider(o
))
135 case OPT_TRADITIONAL
:
139 if (!opt_cipher(opt_arg(), &cipher
))
143 pbe_nid
= OBJ_txt2nid(opt_arg());
144 if (pbe_nid
== NID_undef
) {
146 "%s: Unknown PBE algorithm %s\n", prog
, opt_arg());
151 pbe_nid
= OBJ_txt2nid(opt_arg());
152 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF
, pbe_nid
, NULL
, NULL
, 0)) {
154 "%s: Unknown PRF algorithm %s\n", prog
, opt_arg());
158 cipher
= EVP_aes_256_cbc();
161 if (!opt_int(opt_arg(), &iter
))
165 passinarg
= opt_arg();
168 passoutarg
= opt_arg();
171 e
= setup_engine(opt_arg(), 0);
173 #ifndef OPENSSL_NO_SCRYPT
179 cipher
= EVP_aes_256_cbc();
182 if (!opt_long(opt_arg(), &scrypt_N
) || scrypt_N
<= 0)
186 if (!opt_long(opt_arg(), &scrypt_r
) || scrypt_r
<= 0)
190 if (!opt_long(opt_arg(), &scrypt_p
) || scrypt_p
<= 0)
196 argc
= opt_num_rest();
202 if (!app_passwd(passinarg
, passoutarg
, &passin
, &passout
)) {
203 BIO_printf(bio_err
, "Error getting passwords\n");
207 if ((pbe_nid
== -1) && cipher
== NULL
)
208 cipher
= EVP_aes_256_cbc();
210 in
= bio_open_default(infile
, 'r', informat
);
213 out
= bio_open_owner(outfile
, outformat
, private);
218 pkey
= load_key(infile
, informat
, 1, passin
, e
, "key");
221 if ((p8inf
= EVP_PKEY2PKCS8(pkey
)) == NULL
) {
222 BIO_printf(bio_err
, "Error converting key\n");
223 ERR_print_errors(bio_err
);
228 if (outformat
== FORMAT_PEM
) {
229 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out
, p8inf
);
230 } else if (outformat
== FORMAT_ASN1
) {
231 i2d_PKCS8_PRIV_KEY_INFO_bio(out
, p8inf
);
233 BIO_printf(bio_err
, "Bad format specified for key\n");
239 #ifndef OPENSSL_NO_SCRYPT
240 if (scrypt_N
&& scrypt_r
&& scrypt_p
)
241 pbe
= PKCS5_pbe2_set_scrypt(cipher
, NULL
, 0, NULL
,
242 scrypt_N
, scrypt_r
, scrypt_p
);
245 pbe
= PKCS5_pbe2_set_iv(cipher
, iter
, NULL
, 0, NULL
,
248 pbe
= PKCS5_pbe_set(pbe_nid
, iter
, NULL
, 0);
251 BIO_printf(bio_err
, "Error setting PBE algorithm\n");
252 ERR_print_errors(bio_err
);
255 if (passout
!= NULL
) {
258 /* To avoid bit rot */
259 #ifndef OPENSSL_NO_UI_CONSOLE
261 if (EVP_read_pw_string
262 (pass
, sizeof(pass
), "Enter Encryption Password:", 1)) {
263 X509_ALGOR_free(pbe
);
268 BIO_printf(bio_err
, "Password required\n");
271 p8
= PKCS8_set0_pbe(p8pass
, strlen(p8pass
), p8inf
, pbe
);
273 X509_ALGOR_free(pbe
);
274 BIO_printf(bio_err
, "Error encrypting key\n");
275 ERR_print_errors(bio_err
);
279 if (outformat
== FORMAT_PEM
)
280 PEM_write_bio_PKCS8(out
, p8
);
281 else if (outformat
== FORMAT_ASN1
)
282 i2d_PKCS8_bio(out
, p8
);
284 BIO_printf(bio_err
, "Bad format specified for key\n");
294 if (informat
== FORMAT_PEM
) {
295 p8inf
= PEM_read_bio_PKCS8_PRIV_KEY_INFO(in
, NULL
, NULL
, NULL
);
296 } else if (informat
== FORMAT_ASN1
) {
297 p8inf
= d2i_PKCS8_PRIV_KEY_INFO_bio(in
, NULL
);
299 BIO_printf(bio_err
, "Bad format specified for key\n");
303 if (informat
== FORMAT_PEM
) {
304 p8
= PEM_read_bio_PKCS8(in
, NULL
, NULL
, NULL
);
305 } else if (informat
== FORMAT_ASN1
) {
306 p8
= d2i_PKCS8_bio(in
, NULL
);
308 BIO_printf(bio_err
, "Bad format specified for key\n");
313 BIO_printf(bio_err
, "Error reading key\n");
314 ERR_print_errors(bio_err
);
317 if (passin
!= NULL
) {
320 #ifndef OPENSSL_NO_UI_CONSOLE
322 if (EVP_read_pw_string(pass
, sizeof(pass
), "Enter Password:", 0)) {
323 BIO_printf(bio_err
, "Can't read Password\n");
328 BIO_printf(bio_err
, "Password required\n");
331 p8inf
= PKCS8_decrypt(p8
, p8pass
, strlen(p8pass
));
335 BIO_printf(bio_err
, "Error decrypting key\n");
336 ERR_print_errors(bio_err
);
340 if ((pkey
= EVP_PKCS82PKEY(p8inf
)) == NULL
) {
341 BIO_printf(bio_err
, "Error converting key\n");
342 ERR_print_errors(bio_err
);
347 if (outformat
== FORMAT_PEM
) {
349 PEM_write_bio_PrivateKey_traditional(out
, pkey
, NULL
, NULL
, 0,
352 PEM_write_bio_PrivateKey(out
, pkey
, NULL
, NULL
, 0, NULL
, passout
);
353 } else if (outformat
== FORMAT_ASN1
) {
354 i2d_PrivateKey_bio(out
, pkey
);
356 BIO_printf(bio_err
, "Bad format specified for key\n");
363 PKCS8_PRIV_KEY_INFO_free(p8inf
);
368 OPENSSL_free(passin
);
369 OPENSSL_free(passout
);