[PATCH 3/5] bcrypt: Convert legacy DSA key parameters to and from little-endian format.
Hans Leidekker
hans at codeweavers.com
Tue Oct 6 05:27:12 CDT 2020
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/bcrypt/gnutls.c | 54 +++++++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index be1a28e472..ed632dfd4c 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1003,7 +1003,7 @@ static NTSTATUS CDECL key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG le
DSSPUBKEY *pubkey;
gnutls_datum_t p, q, g, y, x;
UCHAR *src, *dst;
- int ret, size;
+ int i, ret, size;
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, &x )))
{
@@ -1033,24 +1033,24 @@ static NTSTATUS CDECL key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG le
pubkey->bitlen = key->u.a.bitlen;
dst = (UCHAR *)(pubkey + 1);
- if (p.size == size + 1) src = p.data + 1;
+ if (p.size % 2) src = p.data + 1;
else src = p.data;
- memcpy( dst, src, size );
+ for (i = 0; i < size; i++) dst[i] = src[size - i - 1];
dst += size;
- if (q.size == 21) src = q.data + 1;
+ if (q.size % 2) src = q.data + 1;
else src = q.data;
- memcpy( dst, src, 20 );
+ for (i = 0; i < 20; i++) dst[i] = src[20 - i - 1];
dst += 20;
- if (g.size == size + 1) src = g.data + 1;
+ if (g.size % 2) src = g.data + 1;
else src = g.data;
- memcpy( dst, src, size );
+ for (i = 0; i < size; i++) dst[i] = src[size - i - 1];
dst += size;
- if (x.size == 21) src = x.data + 1;
+ if (x.size % 2) src = x.data + 1;
else src = x.data;
- memcpy( dst, src, 20 );
+ for (i = 0; i < 20; i++) dst[i] = src[20 - i - 1];
dst += 20;
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
@@ -1067,7 +1067,8 @@ static NTSTATUS CDECL key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG le
gnutls_privkey_t handle;
gnutls_datum_t p, q, g, y, x;
unsigned char dummy[128];
- int ret, size;
+ unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
+ int i, ret, size;
if ((ret = pgnutls_privkey_init( &handle )))
{
@@ -1077,16 +1078,33 @@ static NTSTATUS CDECL key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG le
hdr = (BLOBHEADER *)buf;
pubkey = (DSSPUBKEY *)(hdr + 1);
- size = pubkey->bitlen / 8;
+ if ((size = pubkey->bitlen / 8) > sizeof(p_data))
+ {
+ FIXME( "size %u not supported\n", size );
+ pgnutls_privkey_deinit( handle );
+ return STATUS_NOT_SUPPORTED;
+ }
+ data = (unsigned char *)(pubkey + 1);
- p.data = (unsigned char *)(pubkey + 1);
+ p.data = p_data;
p.size = size;
- q.data = p.data + size;
- q.size = 20;
- g.data = q.data + 20;
+ for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
+ data += p.size;
+
+ q.data = q_data;
+ q.size = sizeof(q_data);
+ for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
+ data += q.size;
+
+ g.data = g_data;
g.size = size;
- x.data = g.data + size;
- x.size = 20;
+ for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
+ data += g.size;
+
+ x.data = x_data;
+ x.size = sizeof(x_data);
+ for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
+ data += x.size;
WARN( "using dummy public key\n" );
memset( dummy, 1, sizeof(dummy) );
@@ -1100,7 +1118,7 @@ static NTSTATUS CDECL key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG le
return STATUS_INTERNAL_ERROR;
}
- memcpy( &key->u.a.dss_seed, x.data + x.size, sizeof(key->u.a.dss_seed) );
+ memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
key_data(key)->privkey = handle;
return STATUS_SUCCESS;
--
2.28.0
More information about the wine-devel
mailing list