[gnutls-dev] [gnutls-cvs PATCH] Fix handling of PKCS#12 and contents without apassphrase
Anton Altaparmakov
aia21 at cam.ac.uk
Tue Sep 27 11:34:25 CEST 2005
Hi,
Gnutls has bugs when handling PKCS#12 files and their contents when
they do not have a passphrase.
OpenSSL's "openssl pkcs12" utility worked fine to load and dump those
PKCS#12 files which made me look into the gnutls source code and I managed
to find out what was going on after a log of debugging. For example
gnutls didn't allow a 0 MPI which is perfectly valid. Also it had no
concept of empty passwords (it assumed password = NULL means not encrypted
which is wrong) and finally it did not understand the difference between
password = NULL and password = "".
The below patch fixes all the above problems. It is against the current
gnutls cvs (generated using "cvs diff"). Please apply.
Let me know if you need more info about anything...
Without this patch ntfsdecrypt (from linux-ntfs project, ntfsprogs cvs)
cannot load PKCS#12 files generated by Windows when the user generating
them used an empty passphrase. With the patch both older style and newer
style PKCS#12 files can be loaded. (The difference between the two is
that one uses password = NULL and the other password = "". It switched
between Windows XP SP1 and SP2 IIRC or it might have been between XP and
XP SP1, doesn't really matter as I have example PKCS#12 files I always
use for testing...)
Best regards,
Anton
--
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/
Index: lib/gnutls_mpi.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_mpi.c,v
retrieving revision 2.31
diff -u -p -r2.31 gnutls_mpi.c
--- lib/gnutls_mpi.c 26 May 2005 15:27:14 -0000 2.31
+++ lib/gnutls_mpi.c 27 Sep 2005 09:03:56 -0000
@@ -53,13 +53,6 @@ int _gnutls_mpi_scan(mpi_t * ret_mpi, co
if (ret)
return GNUTLS_E_MPI_SCAN_FAILED;
- /* MPIs with 0 bits are illegal
- */
- if (_gnutls_mpi_get_nbits(*ret_mpi) == 0) {
- _gnutls_mpi_release(ret_mpi);
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
-
return 0;
}
Index: lib/x509/pkcs12.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/x509/pkcs12.c,v
retrieving revision 1.39
diff -u -p -r1.39 pkcs12.c
--- lib/x509/pkcs12.c 30 Aug 2005 10:46:08 -0000 1.39
+++ lib/x509/pkcs12.c 27 Sep 2005 09:03:56 -0000
@@ -940,7 +940,7 @@ int gnutls_pkcs12_verify_mac(gnutls_pkcs
opaque sha_mac[20];
opaque sha_mac_orig[20];
- if (pkcs12 == NULL || pass == NULL) {
+ if (pkcs12 == NULL) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
Index: lib/x509/pkcs12_encr.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/x509/pkcs12_encr.c,v
retrieving revision 1.21
diff -u -p -r1.21 pkcs12_encr.c
--- lib/x509/pkcs12_encr.c 26 May 2005 15:27:24 -0000 1.21
+++ lib/x509/pkcs12_encr.c 27 Sep 2005 09:03:56 -0000
@@ -87,13 +87,15 @@ _pkcs12_string_to_key(unsigned int id, c
p = buf_i;
for (i = 0; i < 64; i++)
*p++ = salt[i % salt_size];
- for (i = j = 0; i < 64; i += 2) {
- *p++ = 0;
- *p++ = pw[j];
- if (++j > pwlen) /* Note, that we include the trailing zero */
- j = 0;
- }
-
+ if (pw) {
+ for (i = j = 0; i < 64; i += 2) {
+ *p++ = 0;
+ *p++ = pw[j];
+ if (++j > pwlen) /* Note, that we include the trailing zero */
+ j = 0;
+ }
+ } else
+ memset(p, 0, 64);
for (;;) {
rc = gc_hash_open(GC_SHA1, 0, &md);
if (rc) {
@@ -104,7 +106,7 @@ _pkcs12_string_to_key(unsigned int id, c
unsigned char lid = id & 0xFF;
gc_hash_write(md, 1, &lid);
}
- gc_hash_write(md, 128, buf_i);
+ gc_hash_write(md, pw ? 128 : 64, buf_i);
memcpy(hash, gc_hash_read(md), 20);
gc_hash_close(md);
for (i = 1; i < iter; i++)
Index: lib/x509/privkey_pkcs8.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/x509/privkey_pkcs8.c,v
retrieving revision 1.49
diff -u -p -r1.49 privkey_pkcs8.c
--- lib/x509/privkey_pkcs8.c 30 Aug 2005 10:46:08 -0000 1.49
+++ lib/x509/privkey_pkcs8.c 27 Sep 2005 09:03:56 -0000
@@ -810,7 +810,7 @@ int decode_private_key_info(const gnutls
* @data: The DER or PEM encoded key.
* @format: One of DER or PEM
* @password: the password to decrypt the key (if it is encrypted).
- * @flags: use 0.
+ * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
*
* This function will convert the given DER or PEM encoded PKCS8 2.0 encrypted key
* to the native gnutls_x509_privkey_t format. The output will be stored in @key.
@@ -880,7 +880,7 @@ int gnutls_x509_privkey_import_pkcs8(gnu
need_free = 1;
}
- if (flags & GNUTLS_PKCS_PLAIN || password == NULL) {
+ if (flags & GNUTLS_PKCS_PLAIN) {
result = decode_private_key_info(&_data, key, &key->key);
} else { /* encrypted. */
result = decode_pkcs8_key(&_data, password, key, &key->key);
More information about the Gnutls-devel
mailing list