summaryrefslogtreecommitdiff
path: root/lib/x509
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x509')
-rw-r--r--lib/x509/pkcs12_encr.c20
-rw-r--r--lib/x509/privkey.c17
-rw-r--r--lib/x509/privkey_pkcs8.c10
3 files changed, 29 insertions, 18 deletions
diff --git a/lib/x509/pkcs12_encr.c b/lib/x509/pkcs12_encr.c
index 68b5286864..8c02b1e354 100644
--- a/lib/x509/pkcs12_encr.c
+++ b/lib/x509/pkcs12_encr.c
@@ -47,6 +47,9 @@ _pkcs12_check_pass (const char *pass, size_t plen)
* 3 for MAC
* 2 for IV
* 1 for encryption key
+ *
+ * Note that this function produces different key for the
+ * NULL password, and for the password with zero length.
*/
int
_gnutls_pkcs12_string_to_key (unsigned int id, const uint8_t * salt,
@@ -64,12 +67,13 @@ _gnutls_pkcs12_string_to_key (unsigned int id, const uint8_t * salt,
size_t cur_keylen;
size_t n, m;
const uint8_t buf_512[] = /* 2^64 */
- { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00
};
cur_keylen = 0;
@@ -132,14 +136,12 @@ _gnutls_pkcs12_string_to_key (unsigned int id, const uint8_t * salt,
_gnutls_hash_deinit (&md, hash);
for (i = 1; i < iter; i++)
{
- rc = _gnutls_hash_init (&md, GNUTLS_MAC_SHA1);
+ rc = _gnutls_hash_fast (GNUTLS_MAC_SHA1, hash, 20, hash);
if (rc < 0)
{
gnutls_assert ();
goto cleanup;
}
- _gnutls_hash (&md, hash, 20);
- _gnutls_hash_deinit (&md, hash);
}
for (i = 0; i < 20 && cur_keylen < req_keylen; i++)
keybuf[cur_keylen++] = hash[i];
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index 9d32025db0..98095aa5a0 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -564,6 +564,7 @@ failover:
* @data: The DER or PEM encoded certificate.
* @format: One of DER or PEM
* @password: A password (optional)
+ * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
*
* This function will import the given DER or PEM encoded key, to
* the native #gnutls_x509_privkey_t format, irrespective of the
@@ -582,11 +583,11 @@ int
gnutls_x509_privkey_import2 (gnutls_x509_privkey_t key,
const gnutls_datum_t * data,
gnutls_x509_crt_fmt_t format,
- const char* password)
+ const char* password, unsigned int flags)
{
int ret = 0;
- if (password == NULL)
+ if (password == NULL && !(flags & GNUTLS_PKCS_NULL_PASSWORD))
{
ret = gnutls_x509_privkey_import(key, data, format);
if (ret < 0)
@@ -595,12 +596,12 @@ gnutls_x509_privkey_import2 (gnutls_x509_privkey_t key,
}
}
- if (password != NULL || ret < 0)
+ if ((password != NULL || (flags & GNUTLS_PKCS_NULL_PASSWORD)) || ret < 0)
{
- ret = gnutls_x509_privkey_import_pkcs8(key, data, format, password, 0);
+ ret = gnutls_x509_privkey_import_pkcs8(key, data, format, password, flags);
if (ret < 0)
{
- if (format == GNUTLS_X509_FMT_PEM)
+ if (format == GNUTLS_X509_FMT_PEM && password != NULL)
{
int err;
err = gnutls_x509_privkey_import_openssl(key, data, password);
@@ -611,8 +612,12 @@ gnutls_x509_privkey_import2 (gnutls_x509_privkey_t key,
goto cleanup;
}
}
+ else
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
}
-
}
ret = 0;
diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c
index 95711ce865..d5b02437e2 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -626,7 +626,7 @@ gnutls_x509_privkey_export_pkcs8 (gnutls_x509_privkey_t key,
schema = _gnutls_pkcs_flags_to_schema (flags);
- if ((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
+ if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL) && !(flags & GNUTLS_PKCS_NULL_PASSWORD))
{
_gnutls_free_datum (&tmp);
@@ -640,7 +640,7 @@ gnutls_x509_privkey_export_pkcs8 (gnutls_x509_privkey_t key,
else
{
asn1_delete_structure (&pkey_info); /* we don't need it */
-
+
ret = encode_to_pkcs8_key (schema, &tmp, password, &pkcs8_asn);
_gnutls_free_datum (&tmp);
@@ -1239,7 +1239,11 @@ gnutls_x509_privkey_import_pkcs8 (gnutls_x509_privkey_t key,
need_free = 1;
}
- if (password == NULL || (flags & GNUTLS_PKCS_PLAIN))
+ /* Here we don't check for password == NULL to maintain a backwards
+ * compatibility behavior, with old versions that were encrypting using
+ * a NULL password.
+ */
+ if (flags & GNUTLS_PKCS_PLAIN)
{
result = decode_private_key_info (&_data, key);
if (result < 0)