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]
|
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
|
*) 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
|
perror when PEM_read_bio_X509_REQ fails, the error message must
|
||||||
be obtained from the error queue.
|
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?
|
* How do I create certificates or certificate requests?
|
||||||
* Why can't I create certificate requests?
|
* Why can't I create certificate requests?
|
||||||
* Why does <SSL program> fail with a certificate verify error?
|
* 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?
|
* How can I create DSA certificates?
|
||||||
* Why can't I make an SSL connection using a DSA certificate?
|
* 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?
|
* 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.
|
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?
|
* How can I create DSA certificates?
|
||||||
|
|
||||||
Check the CA.pl(1) manual page for a DSA certificate example.
|
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
|
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
|
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
|
causes. The client may not support connections to DSA servers most web
|
||||||
browsers only support connections to servers supporting RSA cipher suites.
|
browsers (including Netscape and MSIE) only support connections to servers
|
||||||
The other cause is that a set of DH parameters has not been supplied to
|
supporting RSA cipher suites. The other cause is that a set of DH parameters
|
||||||
the server. DH parameters can be created with the dhparam(1) command and
|
has not been supplied to the server. DH parameters can be created with the
|
||||||
loaded using the SSL_CTX_set_tmp_dh() for example: check the source to
|
dhparam(1) command and loaded using the SSL_CTX_set_tmp_dh() for example:
|
||||||
s_server in apps/s_server.c for an 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?
|
* Why can't the OpenSSH configure script detect OpenSSL?
|
||||||
|
@ -528,11 +528,16 @@ int MAIN(int argc, char **argv)
|
|||||||
#ifdef CRYPTO_MDEBUG
|
#ifdef CRYPTO_MDEBUG
|
||||||
CRYPTO_push_info("verify MAC");
|
CRYPTO_push_info("verify MAC");
|
||||||
#endif
|
#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");
|
BIO_printf (bio_err, "Mac verify error: invalid password?\n");
|
||||||
ERR_print_errors (bio_err);
|
ERR_print_errors (bio_err);
|
||||||
goto end;
|
goto end;
|
||||||
} else BIO_printf (bio_err, "MAC verified OK\n");
|
}
|
||||||
|
BIO_printf (bio_err, "MAC verified OK\n");
|
||||||
#ifdef CRYPTO_MDEBUG
|
#ifdef CRYPTO_MDEBUG
|
||||||
CRYPTO_pop_info();
|
CRYPTO_pop_info();
|
||||||
#endif
|
#endif
|
||||||
@ -549,9 +554,9 @@ int MAIN(int argc, char **argv)
|
|||||||
#ifdef CRYPTO_MDEBUG
|
#ifdef CRYPTO_MDEBUG
|
||||||
CRYPTO_pop_info();
|
CRYPTO_pop_info();
|
||||||
#endif
|
#endif
|
||||||
PKCS12_free(p12);
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
end:
|
end:
|
||||||
|
PKCS12_free(p12);
|
||||||
if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
|
if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
|
||||||
#ifdef CRYPTO_MDEBUG
|
#ifdef CRYPTO_MDEBUG
|
||||||
CRYPTO_remove_all_info();
|
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);
|
ERR_add_error_data(2, "TYPE=", obj_tmp);
|
||||||
return 0;
|
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);
|
pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
|
||||||
i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher,
|
i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher,
|
||||||
pbetmp->md, en_de);
|
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;
|
salt = pbe->salt->data;
|
||||||
saltlen = pbe->salt->length;
|
saltlen = pbe->salt->length;
|
||||||
|
|
||||||
|
if(!pass) passlen = 0;
|
||||||
|
else if(passlen == -1) passlen = strlen(pass);
|
||||||
|
|
||||||
EVP_DigestInit (&ctx, md);
|
EVP_DigestInit (&ctx, md);
|
||||||
EVP_DigestUpdate (&ctx, pass, passlen);
|
EVP_DigestUpdate (&ctx, pass, passlen);
|
||||||
EVP_DigestUpdate (&ctx, salt, saltlen);
|
EVP_DigestUpdate (&ctx, salt, saltlen);
|
||||||
|
@ -86,7 +86,8 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
|||||||
HMAC_CTX hctx;
|
HMAC_CTX hctx;
|
||||||
p = out;
|
p = out;
|
||||||
tkeylen = keylen;
|
tkeylen = keylen;
|
||||||
if(passlen == -1) passlen = strlen(pass);
|
if(!pass) passlen = 0;
|
||||||
|
else if(passlen == -1) passlen = strlen(pass);
|
||||||
while(tkeylen) {
|
while(tkeylen) {
|
||||||
if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH;
|
if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH;
|
||||||
else cplen = tkeylen;
|
else cplen = tkeylen;
|
||||||
|
@ -74,25 +74,30 @@ void h__dump (unsigned char *p, int len);
|
|||||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
#endif
|
#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,
|
int saltlen, int id, int iter, int n, unsigned char *out,
|
||||||
const EVP_MD *md_type)
|
const EVP_MD *md_type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char *unipass;
|
unsigned char *unipass;
|
||||||
int uniplen;
|
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);
|
PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE);
|
||||||
return 0;
|
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);
|
id, iter, n, out, md_type);
|
||||||
|
if(unipass) {
|
||||||
memset(unipass, 0, uniplen); /* Clear password from memory */
|
memset(unipass, 0, uniplen); /* Clear password from memory */
|
||||||
Free(unipass);
|
Free(unipass);
|
||||||
|
}
|
||||||
return ret;
|
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,
|
int saltlen, int id, int iter, int n, unsigned char *out,
|
||||||
const EVP_MD *md_type)
|
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;
|
int tmpn = n;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (!pass) {
|
if (!pass) {
|
||||||
PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_PASSED_NULL_PARAMETER);
|
PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_PASSED_NULL_PARAMETER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_KEYGEN
|
#ifdef DEBUG_KEYGEN
|
||||||
fprintf(stderr, "KEYGEN DEBUG\n");
|
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);
|
Ai = Malloc (u);
|
||||||
B = Malloc (v + 1);
|
B = Malloc (v + 1);
|
||||||
Slen = v * ((saltlen+v-1)/v);
|
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;
|
Ilen = Slen + Plen;
|
||||||
I = Malloc (Ilen);
|
I = Malloc (Ilen);
|
||||||
Ij = BN_new();
|
Ij = BN_new();
|
||||||
|
@ -106,8 +106,20 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
|
|||||||
|
|
||||||
/* Check the mac */
|
/* 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);
|
PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -106,10 +106,7 @@ int PKCS12_verify_mac (PKCS12 *p12, const char *pass, int passlen)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
|
if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
|
||||||
|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) {
|
|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
|
||||||
PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_VERIFY_ERROR);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user