crypt32: Zero-pad RSA Private Key values as needed to fit PRIVATEKEYBLOB.

Vincent Povirk madewokherd at gmail.com
Tue Oct 13 15:54:05 CDT 2015


Sometimes the values we get from reading ASN.1 encoded RSA keys have
slightly different lengths from what's required by the structure we
convert to for use in crypt32 (documented by MSDN at
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375601%28v=vs.85%29.aspx).
I think this happens when the most significant byte of one of the
values happens to be 0.

This allows us to decode those keys.
-------------- next part --------------
From 6ba528dd37a02f1bfe46bcaa92e017132553f6e8 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Mon, 12 Oct 2015 16:05:50 -0500
Subject: [PATCH] crypt32: Zero-pad RSA Private Key values as needed to fit
 PRIVATEKEYBLOB.

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
 dlls/crypt32/decode.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 888ea05..09c9608 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -4002,18 +4002,19 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType,
          &size, NULL, NULL);
         if (ret)
         {
-            halflen = decodedKey->modulus.cbData / 2;
-            if ((decodedKey->modulus.cbData != halflen * 2) ||
-                (decodedKey->prime1.cbData != halflen) ||
-                (decodedKey->prime2.cbData != halflen) ||
-                (decodedKey->exponent1.cbData != halflen) ||
-                (decodedKey->exponent2.cbData != halflen) ||
-                (decodedKey->coefficient.cbData != halflen) ||
-                (decodedKey->privexp.cbData != halflen * 2))
-            {
-                ret = FALSE;
-                SetLastError(CRYPT_E_BAD_ENCODE);
-            }
+            halflen = decodedKey->prime1.cbData;
+            if (halflen < decodedKey->prime2.cbData)
+                halflen = decodedKey->prime2.cbData;
+            if (halflen < decodedKey->exponent1.cbData)
+                halflen = decodedKey->exponent1.cbData;
+            if (halflen < decodedKey->exponent2.cbData)
+                halflen = decodedKey->exponent2.cbData;
+            if (halflen < decodedKey->coefficient.cbData)
+                halflen = decodedKey->coefficient.cbData;
+            if (halflen * 2 < decodedKey->modulus.cbData)
+                halflen = decodedKey->modulus.cbData / 2 + decodedKey->modulus.cbData % 2;
+            if (halflen * 2 < decodedKey->privexp.cbData)
+                halflen = decodedKey->privexp.cbData / 2 + decodedKey->privexp.cbData % 2;
 
             if (ret)
             {
@@ -4048,20 +4049,21 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType,
                     rsaPubKey->bitlen = halflen * 16;
 
                     vardata = (BYTE*)(rsaPubKey + 1);
+                    memset(vardata, 0, halflen * 9);
                     memcpy(vardata,
-                     decodedKey->modulus.pbData, halflen * 2);
+                     decodedKey->modulus.pbData, decodedKey->modulus.cbData);
                     memcpy(vardata + halflen * 2,
-                     decodedKey->prime1.pbData, halflen);
+                     decodedKey->prime1.pbData, decodedKey->prime1.cbData);
                     memcpy(vardata + halflen * 3,
-                     decodedKey->prime2.pbData, halflen);
+                     decodedKey->prime2.pbData, decodedKey->prime2.cbData);
                     memcpy(vardata + halflen * 4,
-                     decodedKey->exponent1.pbData, halflen);
+                     decodedKey->exponent1.pbData, decodedKey->exponent1.cbData);
                     memcpy(vardata + halflen * 5,
-                     decodedKey->exponent2.pbData, halflen);
+                     decodedKey->exponent2.pbData, decodedKey->exponent2.cbData);
                     memcpy(vardata + halflen * 6,
-                     decodedKey->coefficient.pbData, halflen);
+                     decodedKey->coefficient.pbData, decodedKey->coefficient.cbData);
                     memcpy(vardata + halflen * 7,
-                     decodedKey->privexp.pbData, halflen * 2);
+                     decodedKey->privexp.pbData, decodedKey->privexp.cbData);
                 }
             }
 
-- 
2.1.4



More information about the wine-patches mailing list