summaryrefslogtreecommitdiffstats
path: root/apps/pkcs12.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/pkcs12.c')
-rw-r--r--apps/pkcs12.c92
1 files changed, 70 insertions, 22 deletions
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index e6fbc574a5..7ef4d586c3 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -70,7 +70,7 @@ typedef enum OPTION_choice {
OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE,
- OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST,
+ OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST, OPT_PBMAC1_PBKDF2, OPT_PBMAC1_PBKDF2_MD,
#ifndef OPENSSL_NO_DES
OPT_LEGACY_ALG
#endif
@@ -147,6 +147,8 @@ const OPTIONS pkcs12_options[] = {
#endif
{"macalg", OPT_MACALG, 's',
"Digest algorithm to use in MAC (default SHA256)"},
+ {"pbmac1_pbkdf2", OPT_PBMAC1_PBKDF2, '-', "Use PBMAC1 with PBKDF2 instead of MAC"},
+ {"pbmac1_pbkdf2_md", OPT_PBMAC1_PBKDF2_MD, 's', "Digest to use for PBMAC1 KDF (default SHA256)"},
{"iter", OPT_ITER, 'p', "Specify the iteration count for encryption and MAC"},
{"noiter", OPT_NOITER, '-', "Don't use encryption iteration"},
{"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration)"},
@@ -170,14 +172,14 @@ int pkcs12_main(int argc, char **argv)
int use_legacy = 0;
#endif
/* use library defaults for the iter, maciter, cert, and key PBE */
- int iter = 0, maciter = 0;
+ int iter = 0, maciter = 0, pbmac1_pbkdf2 = 0;
int macsaltlen = PKCS12_SALT_LEN;
int cert_pbe = NID_undef;
int key_pbe = NID_undef;
int ret = 1, macver = 1, add_lmk = 0, private = 0;
int noprompt = 0;
char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
- char *passin = NULL, *passout = NULL, *macalg = NULL;
+ char *passin = NULL, *passout = NULL, *macalg = NULL, *pbmac1_pbkdf2_md = NULL;
char *cpass = NULL, *mpass = NULL, *badpass = NULL;
const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL, *prog;
int noCApath = 0, noCAfile = 0, noCAstore = 0;
@@ -283,6 +285,12 @@ int pkcs12_main(int argc, char **argv)
case OPT_MACALG:
macalg = opt_arg();
break;
+ case OPT_PBMAC1_PBKDF2:
+ pbmac1_pbkdf2 = 1;
+ break;
+ case OPT_PBMAC1_PBKDF2_MD:
+ pbmac1_pbkdf2_md = opt_arg();
+ break;
case OPT_CERTPBE:
if (!set_pbe(&cert_pbe, opt_arg()))
goto opthelp;
@@ -700,10 +708,20 @@ int pkcs12_main(int argc, char **argv)
}
if (maciter != -1) {
- if (!PKCS12_set_mac(p12, mpass, -1, NULL, macsaltlen, maciter, macmd)) {
- BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n");
- BIO_printf(bio_err, "Use -nomac if MAC not required and PKCS12KDF support not available.\n");
- goto export_end;
+ if (pbmac1_pbkdf2 == 1) {
+ if (!PKCS12_set_pbmac1_pbkdf2(p12, mpass, -1, NULL,
+ macsaltlen, maciter,
+ macmd, pbmac1_pbkdf2_md)) {
+ BIO_printf(bio_err, "Error creating PBMAC1\n");
+ goto export_end;
+ }
+ } else {
+ if (!PKCS12_set_mac(p12, mpass, -1, NULL, macsaltlen, maciter, macmd)) {
+ BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n");
+ BIO_printf(bio_err,
+ "Use -nomac or -pbmac1_pbkdf2 if PKCS12KDF support not available\n");
+ goto export_end;
+ }
}
}
assert(private);
@@ -774,23 +792,54 @@ int pkcs12_main(int argc, char **argv)
X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
BIO_puts(bio_err, "MAC: ");
i2a_ASN1_OBJECT(bio_err, macobj);
- BIO_printf(bio_err, ", Iteration %ld\n",
- tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
- BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n",
- tmac != NULL ? ASN1_STRING_length(tmac) : 0L,
- tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L);
+ if (OBJ_obj2nid(macobj) == NID_pbmac1) {
+ PBKDF2PARAM *pbkdf2_param = PBMAC1_get1_pbkdf2_param(macalgid);
+
+ if (pbkdf2_param == NULL) {
+ BIO_printf(bio_err, ", Unsupported KDF or params for PBMAC1\n");
+ } else {
+ const ASN1_OBJECT *prfobj;
+
+ BIO_printf(bio_err, " using PBKDF2, Iteration %ld\n",
+ ASN1_INTEGER_get(pbkdf2_param->iter));
+ BIO_printf(bio_err, "Key length: %ld, Salt length: %d\n",
+ ASN1_INTEGER_get(pbkdf2_param->keylength),
+ ASN1_STRING_length(pbkdf2_param->salt->value.octet_string));
+ X509_ALGOR_get0(&prfobj, NULL, NULL, pbkdf2_param->prf);
+ BIO_printf(bio_err, "PBKDF2 PRF: ");
+ i2a_ASN1_OBJECT(bio_err, prfobj);
+ BIO_printf(bio_err, "\n");
+ }
+ PBKDF2PARAM_free(pbkdf2_param);
+ } else {
+ BIO_printf(bio_err, ", Iteration %ld\n",
+ tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
+ BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n",
+ tmac != NULL ? ASN1_STRING_length(tmac) : 0L,
+ tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L);
+ }
}
+
if (macver) {
- EVP_KDF *pkcs12kdf;
+ const X509_ALGOR *macalgid;
+ const ASN1_OBJECT *macobj;
- pkcs12kdf = EVP_KDF_fetch(app_get0_libctx(), "PKCS12KDF",
- app_get0_propq());
- if (pkcs12kdf == NULL) {
- BIO_printf(bio_err, "Error verifying PKCS12 MAC; no PKCS12KDF support.\n");
- BIO_printf(bio_err, "Use -nomacver if MAC verification is not required.\n");
- goto end;
+ PKCS12_get0_mac(NULL, &macalgid, NULL, NULL, p12);
+ X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
+
+ if (OBJ_obj2nid(macobj) != NID_pbmac1) {
+ EVP_KDF *pkcs12kdf;
+
+ pkcs12kdf = EVP_KDF_fetch(app_get0_libctx(), "PKCS12KDF",
+ app_get0_propq());
+ if (pkcs12kdf == NULL) {
+ BIO_printf(bio_err, "Error verifying PKCS12 MAC; no PKCS12KDF support.\n");
+ BIO_printf(bio_err, "Use -nomacver if MAC verification is not required.\n");
+ goto end;
+ }
+ EVP_KDF_free(pkcs12kdf);
}
- EVP_KDF_free(pkcs12kdf);
+
/* If we enter empty password try no password first */
if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
/* If mac and crypto pass the same set it to NULL too */
@@ -1257,8 +1306,7 @@ int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
}
if (X509_ATTRIBUTE_count(attr)) {
- for (j = 0; j < X509_ATTRIBUTE_count(attr); j++)
- {
+ for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) {
av = X509_ATTRIBUTE_get0_type(attr, j);
print_attribute(out, av);
}