diff options
Diffstat (limited to 'lib/x509')
-rw-r--r-- | lib/x509/pkcs12_encr.c | 20 | ||||
-rw-r--r-- | lib/x509/privkey.c | 17 | ||||
-rw-r--r-- | lib/x509/privkey_pkcs8.c | 10 |
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) |