[gnutls-dev] [gnutls-cvs PATCH] Fix handling of PKCS#12 and
contents without apassphrase
Nikos Mavrogiannopoulos
nmav at gnutls.org
Tue Sep 27 16:05:05 CEST 2005
On Tuesday 27 September 2005 11:34, Anton Altaparmakov wrote:
> 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.
Hello Anton,
Thank you for the patch. I've changed some things since some parts of gnutls
rely on this property of mpi_scan(). If the attached patch works for you I'll
apply it to the cvs.
--
Nikos Mavrogiannopoulos
-------------- next part --------------
Index: lib/auth_dh_common.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/auth_dh_common.c,v
retrieving revision 2.16
diff -u -r2.16 auth_dh_common.c
--- lib/auth_dh_common.c 26 May 2005 15:27:13 -0000 2.16
+++ lib/auth_dh_common.c 27 Sep 2005 14:00:07 -0000
@@ -64,7 +64,7 @@
_n_Y = n_Y;
DECR_LEN(data_size, n_Y);
- if (_gnutls_mpi_scan(&session->key->client_Y, &data[2], &_n_Y)) {
+ if (_gnutls_mpi_scan_nz(&session->key->client_Y, &data[2], &_n_Y)) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -204,16 +204,16 @@
_n_g = n_g;
_n_p = n_p;
- if (_gnutls_mpi_scan(&session->key->client_Y, data_Y, &_n_Y) != 0) {
+ if (_gnutls_mpi_scan_nz(&session->key->client_Y, data_Y, &_n_Y) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (_gnutls_mpi_scan(&session->key->client_g, data_g, &_n_g) != 0) {
+ if (_gnutls_mpi_scan_nz(&session->key->client_g, data_g, &_n_g) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (_gnutls_mpi_scan(&session->key->client_p, data_p, &_n_p) != 0) {
+ if (_gnutls_mpi_scan_nz(&session->key->client_p, data_p, &_n_p) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
Index: lib/auth_rsa_export.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/auth_rsa_export.c,v
retrieving revision 2.39
diff -u -r2.39 auth_rsa_export.c
--- lib/auth_rsa_export.c 30 Aug 2005 10:48:35 -0000 2.39
+++ lib/auth_rsa_export.c 27 Sep 2005 14:00:08 -0000
@@ -259,12 +259,12 @@
_n_e = n_e;
_n_m = n_m;
- if (_gnutls_mpi_scan(&session->key->rsa[0], data_m, &_n_m) != 0) {
+ if (_gnutls_mpi_scan_nz(&session->key->rsa[0], data_m, &_n_m) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (_gnutls_mpi_scan(&session->key->rsa[1], data_e, &_n_e) != 0) {
+ if (_gnutls_mpi_scan_nz(&session->key->rsa[1], data_e, &_n_e) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
Index: lib/auth_srp.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/auth_srp.c,v
retrieving revision 2.7
diff -u -r2.7 auth_srp.c
--- lib/auth_srp.c 27 May 2005 01:43:57 -0000 2.7
+++ lib/auth_srp.c 27 Sep 2005 14:00:08 -0000
@@ -162,19 +162,19 @@
}
/* copy from pwd_entry to local variables (actually in session) */
- if (_gnutls_mpi_scan(&G, pwd_entry->g.data, &pwd_entry->g.size) < 0) {
+ if (_gnutls_mpi_scan_nz(&G, pwd_entry->g.data, &pwd_entry->g.size) < 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
tmp_size = pwd_entry->n.size;
- if (_gnutls_mpi_scan(&N, pwd_entry->n.data, &tmp_size) < 0) {
+ if (_gnutls_mpi_scan_nz(&N, pwd_entry->n.data, &tmp_size) < 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
tmp_size = pwd_entry->v.size;
- if (_gnutls_mpi_scan(&V, pwd_entry->v.data, &tmp_size) < 0) {
+ if (_gnutls_mpi_scan_nz(&V, pwd_entry->v.data, &tmp_size) < 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -356,7 +356,7 @@
_n_A = _gnutls_read_uint16(&data[0]);
DECR_LEN(data_size, _n_A);
- if (_gnutls_mpi_scan(&A, &data[2], &_n_A) || A == NULL) {
+ if (_gnutls_mpi_scan_nz(&A, &data[2], &_n_A) || A == NULL) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -725,17 +725,17 @@
_n_n = n_n;
_n_b = n_b;
- if (_gnutls_mpi_scan(&N, data_n, &_n_n) != 0) {
+ if (_gnutls_mpi_scan_nz(&N, data_n, &_n_n) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (_gnutls_mpi_scan(&G, data_g, &_n_g) != 0) {
+ if (_gnutls_mpi_scan_nz(&G, data_g, &_n_g) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (_gnutls_mpi_scan(&B, data_b, &_n_b) != 0) {
+ if (_gnutls_mpi_scan_nz(&B, data_b, &_n_b) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -771,7 +771,7 @@
return ret;
}
- if (_gnutls_mpi_scan(&session->key->x, hd, &_n_g) != 0) {
+ if (_gnutls_mpi_scan_nz(&session->key->x, hd, &_n_g) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
Index: lib/gnutls_dh_primes.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_dh_primes.c,v
retrieving revision 2.64
diff -u -r2.64 gnutls_dh_primes.c
--- lib/gnutls_dh_primes.c 26 May 2005 15:27:14 -0000 2.64
+++ lib/gnutls_dh_primes.c 27 Sep 2005 14:00:08 -0000
@@ -148,13 +148,13 @@
size_t siz;
siz = prime->size;
- if (_gnutls_mpi_scan(&tmp_prime, prime->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&tmp_prime, prime->data, &siz)) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = generator->size;
- if (_gnutls_mpi_scan(&tmp_g, generator->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&tmp_g, generator->data, &siz)) {
_gnutls_mpi_release(&tmp_prime);
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
Index: lib/gnutls_mpi.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_mpi.c,v
retrieving revision 2.31
diff -u -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 14:00:08 -0000
@@ -53,6 +53,20 @@
if (ret)
return GNUTLS_E_MPI_SCAN_FAILED;
+ return 0;
+}
+
+/* returns zero on success. Fails if the number is zero.
+ */
+int _gnutls_mpi_scan_nz(mpi_t * ret_mpi, const opaque * buffer,
+ size_t * nbytes)
+{
+ int ret;
+
+ ret = gcry_mpi_scan(ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes);
+ if (ret)
+ return GNUTLS_E_MPI_SCAN_FAILED;
+
/* MPIs with 0 bits are illegal
*/
if (_gnutls_mpi_get_nbits(*ret_mpi) == 0) {
Index: lib/gnutls_mpi.h
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_mpi.h,v
retrieving revision 2.31
diff -u -r2.31 gnutls_mpi.h
--- lib/gnutls_mpi.h 26 May 2005 15:27:14 -0000 2.31
+++ lib/gnutls_mpi.h 27 Sep 2005 14:00:08 -0000
@@ -61,6 +61,8 @@
void _gnutls_mpi_release(mpi_t * x);
+int _gnutls_mpi_scan_nz(mpi_t * ret_mpi, const opaque * buffer,
+ size_t * nbytes);
int _gnutls_mpi_scan(mpi_t * ret_mpi, const opaque * buffer,
size_t * nbytes);
int _gnutls_mpi_scan_pgp(mpi_t * ret_mpi, const opaque * buffer,
Index: lib/gnutls_pk.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_pk.c,v
retrieving revision 1.78
diff -u -r1.78 gnutls_pk.c
--- lib/gnutls_pk.c 30 Aug 2005 10:48:35 -0000 1.78
+++ lib/gnutls_pk.c 27 Sep 2005 14:00:08 -0000
@@ -131,7 +131,7 @@
ps[psize] = 0;
memcpy(&ps[psize + 1], plaintext->data, plaintext->size);
- if (_gnutls_mpi_scan(&m, edata, &k) != 0) {
+ if (_gnutls_mpi_scan_nz(&m, edata, &k) != 0) {
gnutls_assert();
gnutls_afree(edata);
return GNUTLS_E_MPI_SCAN_FAILED;
@@ -209,7 +209,7 @@
return GNUTLS_E_PK_DECRYPTION_FAILED;
}
- if (_gnutls_mpi_scan(&c, ciphertext->data, &esize) != 0) {
+ if (_gnutls_mpi_scan_nz(&c, ciphertext->data, &esize) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -395,7 +395,7 @@
return GNUTLS_E_PK_SIGN_FAILED;
}
- if (_gnutls_mpi_scan(&mdata, hash->data, &k) != 0) {
+ if (_gnutls_mpi_scan_nz(&mdata, hash->data, &k) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -490,7 +490,7 @@
}
k = vdata->size;
- if (_gnutls_mpi_scan(&mdata, vdata->data, &k) != 0) {
+ if (_gnutls_mpi_scan_nz(&mdata, vdata->data, &k) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
Index: lib/gnutls_srp.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_srp.c,v
retrieving revision 2.51
diff -u -r2.51 gnutls_srp.c
--- lib/gnutls_srp.c 26 May 2005 15:27:14 -0000 2.51
+++ lib/gnutls_srp.c 27 Sep 2005 14:00:08 -0000
@@ -45,7 +45,7 @@
mpi_t x, e;
size_t result_size;
- if (_gnutls_mpi_scan(&x, text, &textsize)) {
+ if (_gnutls_mpi_scan_nz(&x, text, &textsize)) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -195,7 +195,7 @@
/* convert the bytes of hd to integer
*/
hash_size = 20; /* SHA */
- ret = _gnutls_mpi_scan(&res, hd, &hash_size);
+ ret = _gnutls_mpi_scan_nz(&res, hd, &hash_size);
gnutls_free(holder);
if (ret < 0) {
@@ -676,13 +676,13 @@
}
size = prime->size;
- if (_gnutls_mpi_scan(&_n, prime->data, &size)) {
+ if (_gnutls_mpi_scan_nz(&_n, prime->data, &size)) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
size = generator->size;
- if (_gnutls_mpi_scan(&_g, generator->data, &size)) {
+ if (_gnutls_mpi_scan_nz(&_g, generator->data, &size)) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
Index: lib/x509/pkcs12.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/x509/pkcs12.c,v
retrieving revision 1.39
diff -u -r1.39 pkcs12.c
--- lib/x509/pkcs12.c 30 Aug 2005 10:46:08 -0000 1.39
+++ lib/x509/pkcs12.c 27 Sep 2005 14:00:08 -0000
@@ -940,7 +940,7 @@
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 -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 14:00:08 -0000
@@ -87,12 +87,15 @@
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);
@@ -104,7 +107,7 @@
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.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/x509/privkey.c,v
retrieving revision 1.48
diff -u -r1.48 privkey.c
--- lib/x509/privkey.c 16 Jul 2005 10:48:15 -0000 1.48
+++ lib/x509/privkey.c 27 Sep 2005 14:00:08 -0000
@@ -457,35 +457,35 @@
}
siz = m->size;
- if (_gnutls_mpi_scan(&key->params[0], m->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[0], m->data, &siz)) {
gnutls_assert();
FREE_RSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = e->size;
- if (_gnutls_mpi_scan(&key->params[1], e->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[1], e->data, &siz)) {
gnutls_assert();
FREE_RSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = d->size;
- if (_gnutls_mpi_scan(&key->params[2], d->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[2], d->data, &siz)) {
gnutls_assert();
FREE_RSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = p->size;
- if (_gnutls_mpi_scan(&key->params[3], p->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[3], p->data, &siz)) {
gnutls_assert();
FREE_RSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = q->size;
- if (_gnutls_mpi_scan(&key->params[4], q->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[4], q->data, &siz)) {
gnutls_assert();
FREE_RSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
@@ -504,7 +504,7 @@
_gnutls_mpi_invm(key->params[5], key->params[3], key->params[4]);
#else
siz = u->size;
- if (_gnutls_mpi_scan(&key->params[5], u->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[5], u->data, &siz)) {
gnutls_assert();
FREE_RSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
@@ -553,35 +553,35 @@
}
siz = p->size;
- if (_gnutls_mpi_scan(&key->params[0], p->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[0], p->data, &siz)) {
gnutls_assert();
FREE_DSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = q->size;
- if (_gnutls_mpi_scan(&key->params[1], q->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[1], q->data, &siz)) {
gnutls_assert();
FREE_DSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = g->size;
- if (_gnutls_mpi_scan(&key->params[2], g->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[2], g->data, &siz)) {
gnutls_assert();
FREE_DSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = y->size;
- if (_gnutls_mpi_scan(&key->params[3], y->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[3], y->data, &siz)) {
gnutls_assert();
FREE_DSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
}
siz = x->size;
- if (_gnutls_mpi_scan(&key->params[4], x->data, &siz)) {
+ if (_gnutls_mpi_scan_nz(&key->params[4], x->data, &siz)) {
gnutls_assert();
FREE_DSA_PRIVATE_PARAMS;
return GNUTLS_E_MPI_SCAN_FAILED;
More information about the Gnutls-dev
mailing list