Make PKCS#12 code handle missing passwords.
Add a couple of FAQs.
This commit is contained in:
parent
316e6a66f2
commit
a331a305e9
13
CHANGES
13
CHANGES
@ -4,6 +4,19 @@
|
||||
|
||||
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
|
||||
|
||||
*) Make PKCS#12 code work with no password. The PKCS#12 spec
|
||||
is a little unclear about how a blank password is handled.
|
||||
Since the password in encoded as a BMPString with terminating
|
||||
double NULL a zero length password would end up as just the
|
||||
double NULL. However no password at all is different and is
|
||||
handled differently in the PKCS#12 key generation code. NS
|
||||
treats a blank password as zero length. MSIE treats it as no
|
||||
password on export: but it will try both on import. We now do
|
||||
the same: PKCS12_parse() tries zero length and no password if
|
||||
the password is set to "" or NULL (NULL is now a valid password:
|
||||
it wasn't before) as does the pkcs12 application.
|
||||
[Steve Henson]
|
||||
|
||||
*) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use
|
||||
perror when PEM_read_bio_X509_REQ fails, the error message must
|
||||
be obtained from the error queue.
|
||||
|
27
FAQ
27
FAQ
@ -16,8 +16,10 @@ OpenSSL - Frequently Asked Questions
|
||||
* How do I create certificates or certificate requests?
|
||||
* Why can't I create certificate requests?
|
||||
* Why does <SSL program> fail with a certificate verify error?
|
||||
* Why can I only use weak ciphers when I connect to a server using OpenSSL?
|
||||
* How can I create DSA certificates?
|
||||
* Why can't I make an SSL connection using a DSA certificate?
|
||||
* How can I remove the passphrase on a private key?
|
||||
* Why can't the OpenSSH configure script detect OpenSSL?
|
||||
|
||||
|
||||
@ -232,6 +234,13 @@ or file and the relevant program configured to read it. The OpenSSL program
|
||||
the verify(1) program manual page for more information.
|
||||
|
||||
|
||||
* Why can I only use weak ciphers when I connect to a server using OpenSSL?
|
||||
|
||||
This is almost certainly because you are using an old "export grade" browser
|
||||
which only supports weak encryption. Upgrade your browser to support 128 bit
|
||||
ciphers.
|
||||
|
||||
|
||||
* How can I create DSA certificates?
|
||||
|
||||
Check the CA.pl(1) manual page for a DSA certificate example.
|
||||
@ -242,11 +251,19 @@ Check the CA.pl(1) manual page for a DSA certificate example.
|
||||
Typically you'll see a message saying there are no shared ciphers when
|
||||
the same setup works fine with an RSA certificate. There are two possible
|
||||
causes. The client may not support connections to DSA servers most web
|
||||
browsers only support connections to servers supporting RSA cipher suites.
|
||||
The other cause is that a set of DH parameters has not been supplied to
|
||||
the server. DH parameters can be created with the dhparam(1) command and
|
||||
loaded using the SSL_CTX_set_tmp_dh() for example: check the source to
|
||||
s_server in apps/s_server.c for an example.
|
||||
browsers (including Netscape and MSIE) only support connections to servers
|
||||
supporting RSA cipher suites. The other cause is that a set of DH parameters
|
||||
has not been supplied to the server. DH parameters can be created with the
|
||||
dhparam(1) command and loaded using the SSL_CTX_set_tmp_dh() for example:
|
||||
check the source to s_server in apps/s_server.c for an example.
|
||||
|
||||
|
||||
* How can I remove the passphrase on a private key?
|
||||
|
||||
Firstly you should be really *really* sure you want to do this. Leaving
|
||||
a private key unencrypted is a major security risk. If you decide that
|
||||
you do have to do this check the EXAMPLES sections of the rsa(1) and
|
||||
dsa(1) manual pages.
|
||||
|
||||
|
||||
* Why can't the OpenSSH configure script detect OpenSSL?
|
||||
|
@ -528,11 +528,16 @@ int MAIN(int argc, char **argv)
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
CRYPTO_push_info("verify MAC");
|
||||
#endif
|
||||
if (!PKCS12_verify_mac (p12, mpass, -1)) {
|
||||
/* If we enter empty password try no password first */
|
||||
if(!macpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
|
||||
/* If mac and crypto pass the same set it to NULL too */
|
||||
if(!twopass) cpass = NULL;
|
||||
} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
|
||||
BIO_printf (bio_err, "Mac verify error: invalid password?\n");
|
||||
ERR_print_errors (bio_err);
|
||||
goto end;
|
||||
} else BIO_printf (bio_err, "MAC verified OK\n");
|
||||
}
|
||||
BIO_printf (bio_err, "MAC verified OK\n");
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
@ -549,9 +554,9 @@ int MAIN(int argc, char **argv)
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
PKCS12_free(p12);
|
||||
ret = 0;
|
||||
end:
|
||||
PKCS12_free(p12);
|
||||
if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
CRYPTO_remove_all_info();
|
||||
|
@ -92,7 +92,8 @@ int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
|
||||
ERR_add_error_data(2, "TYPE=", obj_tmp);
|
||||
return 0;
|
||||
}
|
||||
if (passlen == -1) passlen = strlen(pass);
|
||||
if(!pass) passlen = 0;
|
||||
else if (passlen == -1) passlen = strlen(pass);
|
||||
pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
|
||||
i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher,
|
||||
pbetmp->md, en_de);
|
||||
|
@ -125,6 +125,9 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
|
||||
salt = pbe->salt->data;
|
||||
saltlen = pbe->salt->length;
|
||||
|
||||
if(!pass) passlen = 0;
|
||||
else if(passlen == -1) passlen = strlen(pass);
|
||||
|
||||
EVP_DigestInit (&ctx, md);
|
||||
EVP_DigestUpdate (&ctx, pass, passlen);
|
||||
EVP_DigestUpdate (&ctx, salt, saltlen);
|
||||
|
@ -86,7 +86,8 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
||||
HMAC_CTX hctx;
|
||||
p = out;
|
||||
tkeylen = keylen;
|
||||
if(passlen == -1) passlen = strlen(pass);
|
||||
if(!pass) passlen = 0;
|
||||
else if(passlen == -1) passlen = strlen(pass);
|
||||
while(tkeylen) {
|
||||
if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH;
|
||||
else cplen = tkeylen;
|
||||
|
@ -74,25 +74,30 @@ void h__dump (unsigned char *p, int len);
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
int PKCS12_key_gen_asc (const char *pass, int passlen, unsigned char *salt,
|
||||
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
|
||||
int saltlen, int id, int iter, int n, unsigned char *out,
|
||||
const EVP_MD *md_type)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *unipass;
|
||||
int uniplen;
|
||||
if (!asc2uni (pass, &unipass, &uniplen)) {
|
||||
if(!pass) {
|
||||
unipass = NULL;
|
||||
uniplen = 0;
|
||||
} else if (!asc2uni(pass, &unipass, &uniplen)) {
|
||||
PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
ret = PKCS12_key_gen_uni (unipass, uniplen, salt, saltlen,
|
||||
ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
|
||||
id, iter, n, out, md_type);
|
||||
memset(unipass, 0, uniplen); /* Clear password from memory */
|
||||
Free(unipass);
|
||||
if(unipass) {
|
||||
memset(unipass, 0, uniplen); /* Clear password from memory */
|
||||
Free(unipass);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PKCS12_key_gen_uni (unsigned char *pass, int passlen, unsigned char *salt,
|
||||
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
|
||||
int saltlen, int id, int iter, int n, unsigned char *out,
|
||||
const EVP_MD *md_type)
|
||||
{
|
||||
@ -106,10 +111,12 @@ int PKCS12_key_gen_uni (unsigned char *pass, int passlen, unsigned char *salt,
|
||||
int tmpn = n;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (!pass) {
|
||||
PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_KEYGEN
|
||||
fprintf(stderr, "KEYGEN DEBUG\n");
|
||||
@ -125,7 +132,8 @@ int PKCS12_key_gen_uni (unsigned char *pass, int passlen, unsigned char *salt,
|
||||
Ai = Malloc (u);
|
||||
B = Malloc (v + 1);
|
||||
Slen = v * ((saltlen+v-1)/v);
|
||||
Plen = v * ((passlen+v-1)/v);
|
||||
if(passlen) Plen = v * ((passlen+v-1)/v);
|
||||
else Plen = 0;
|
||||
Ilen = Slen + Plen;
|
||||
I = Malloc (Ilen);
|
||||
Ij = BN_new();
|
||||
|
@ -106,11 +106,23 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
|
||||
|
||||
/* Check the mac */
|
||||
|
||||
if (!PKCS12_verify_mac (p12, pass, -1))
|
||||
{
|
||||
/* If password is zero length or NULL then try verifying both cases
|
||||
* to determine which password is correct. The reason for this is that
|
||||
* under PKCS#12 password based encryption no password and a zero length
|
||||
* password are two different things...
|
||||
*/
|
||||
|
||||
if(!pass || !*pass) {
|
||||
if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL;
|
||||
else if(PKCS12_verify_mac(p12, "", 0)) pass = "";
|
||||
else {
|
||||
PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
} else if (!PKCS12_verify_mac(p12, pass, -1)) {
|
||||
PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parse_pk12 (p12, pass, -1, pkey, cert, ca))
|
||||
{
|
||||
|
@ -106,10 +106,7 @@ int PKCS12_verify_mac (PKCS12 *p12, const char *pass, int passlen)
|
||||
return 0;
|
||||
}
|
||||
if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
|
||||
|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) {
|
||||
PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_VERIFY_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user