Support broken PKCS#12 key generation.

OpenSSL versions before 1.1.0 didn't convert non-ASCII
UTF8 PKCS#12 passwords to Unicode correctly.

To correctly decrypt older files, if MAC verification fails
with the supplied password attempt to use the broken format
which is compatible with earlier versions of OpenSSL.

Reviewed-by: Richard Levitte <levitte@openssl.org>
This commit is contained in:
Dr. Stephen Henson 2016-08-24 18:55:51 +01:00 committed by Matt Caswell
parent 0fe17491c3
commit 647ac8d3d7

View file

@ -132,7 +132,7 @@ int pkcs12_main(int argc, char **argv)
int noprompt = 0; int noprompt = 0;
char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL; char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL;
char *cpass = NULL, *mpass = NULL; char *cpass = NULL, *mpass = NULL, *badpass = NULL;
const char *CApath = NULL, *CAfile = NULL, *prog; const char *CApath = NULL, *CAfile = NULL, *prog;
int noCApath = 0, noCAfile = 0; int noCApath = 0, noCAfile = 0;
ENGINE *e = NULL; ENGINE *e = NULL;
@ -539,9 +539,27 @@ int pkcs12_main(int argc, char **argv)
if (!twopass) if (!twopass)
cpass = NULL; cpass = NULL;
} else if (!PKCS12_verify_mac(p12, mpass, -1)) { } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
BIO_printf(bio_err, "Mac verify error: invalid password?\n"); /*
ERR_print_errors(bio_err); * May be UTF8 from previous version of OpenSSL:
goto end; * convert to a UTF8 form which will translate
* to the same Unicode password.
*/
unsigned char *utmp;
int utmplen;
utmp = OPENSSL_asc2uni(mpass, -1, NULL, &utmplen);
if (utmp == NULL)
goto end;
badpass = OPENSSL_uni2utf8(utmp, utmplen);
OPENSSL_free(utmp);
if (!PKCS12_verify_mac(p12, badpass, -1)) {
BIO_printf(bio_err, "Mac verify error: invalid password?\n");
ERR_print_errors(bio_err);
goto end;
} else {
BIO_printf(bio_err, "Warning: using broken algorithm\n");
if (!twopass)
cpass = badpass;
}
} }
} }
@ -559,6 +577,7 @@ int pkcs12_main(int argc, char **argv)
BIO_free(in); BIO_free(in);
BIO_free_all(out); BIO_free_all(out);
sk_OPENSSL_STRING_free(canames); sk_OPENSSL_STRING_free(canames);
OPENSSL_free(badpass);
OPENSSL_free(passin); OPENSSL_free(passin);
OPENSSL_free(passout); OPENSSL_free(passout);
return (ret); return (ret);