diff options
Diffstat (limited to 'apps/pkcs12.c')
-rw-r--r-- | apps/pkcs12.c | 92 |
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); } |