[PATCH 4/6] bcrypt: Merge the various key import Unix calls into one.

Hans Leidekker hans at codeweavers.com
Mon Mar 21 03:50:09 CDT 2022


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/bcrypt/bcrypt_internal.h |   8 +--
 dlls/bcrypt/bcrypt_main.c     |  87 ++++++++++++++++------
 dlls/bcrypt/gnutls.c          | 132 ++++++++++++++++------------------
 3 files changed, 132 insertions(+), 95 deletions(-)

diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
index d299def6e11..7342b66479a 100644
--- a/dlls/bcrypt/bcrypt_internal.h
+++ b/dlls/bcrypt/bcrypt_internal.h
@@ -279,9 +279,11 @@ struct key_asymmetric_export_params
     ULONG       *ret_len;
 };
 
-struct key_import_params
+#define KEY_IMPORT_FLAG_PUBLIC   0x00000001
+struct key_asymmetric_import_params
 {
     struct key  *key;
+    ULONG        flags;
     UCHAR       *buf;
     ULONG        len;
 };
@@ -303,9 +305,7 @@ enum key_funcs
     unix_key_asymmetric_verify,
     unix_key_asymmetric_destroy,
     unix_key_asymmetric_export,
-    unix_key_import_dsa_capi,
-    unix_key_import_ecc,
-    unix_key_import_rsa,
+    unix_key_asymmetric_import,
 };
 
 #endif /* __BCRYPT_INTERNAL_H */
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 408c477b92f..23f30833235 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1339,7 +1339,7 @@ static void key_destroy( struct key *key )
 static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
                                  ULONG input_len )
 {
-    struct key_import_params params;
+    struct key_asymmetric_import_params params;
     struct key *key;
     NTSTATUS status;
     ULONG size;
@@ -1378,7 +1378,19 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
             return STATUS_INVALID_PARAMETER;
 
         size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
-        return key_asymmetric_create( (struct key **)ret_key, alg->id, key_size * 8, (BYTE *)ecc_blob, size );
+        if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, (BYTE *)ecc_blob, size ))) return status;
+        params.key   = key;
+        params.flags = KEY_IMPORT_FLAG_PUBLIC;
+        params.buf   = input;
+        params.len   = input_len;
+        if ((status = UNIX_CALL( key_asymmetric_import, &params )))
+        {
+            key_destroy( key );
+            return status;
+        }
+
+        *ret_key = key;
+        return STATUS_SUCCESS;
     }
     else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
     {
@@ -1409,11 +1421,11 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
 
         size = sizeof(*ecc_blob) + key_size * 2;
         if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, NULL, size ))) return status;
-
-        params.key = key;
-        params.buf = input;
-        params.len = input_len;
-        if ((status = UNIX_CALL( key_import_ecc, &params )))
+        params.key   = key;
+        params.flags = 0;
+        params.buf   = input;
+        params.len   = input_len;
+        if ((status = UNIX_CALL( key_asymmetric_import, &params )))
         {
             key_destroy( key );
             return status;
@@ -1432,7 +1444,20 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
 
         size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
         if (size != input_len) return NTE_BAD_DATA;
-        return key_asymmetric_create( (struct key **)ret_key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
+
+        if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status;
+        params.key   = key;
+        params.flags = KEY_IMPORT_FLAG_PUBLIC;
+        params.buf   = input;
+        params.len   = input_len;
+        if ((status = UNIX_CALL( key_asymmetric_import, &params )))
+        {
+            key_destroy( key );
+            return status;
+        }
+
+        *ret_key = key;
+        return STATUS_SUCCESS;
     }
     else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
     {
@@ -1443,12 +1468,12 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
             rsa_blob->Magic != BCRYPT_RSAFULLPRIVATE_MAGIC)) return STATUS_NOT_SUPPORTED;
 
         size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
-        if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
-            return status;
-        params.key = key;
-        params.buf = input;
-        params.len = input_len;
-        if ((status = UNIX_CALL( key_import_rsa, &params )))
+        if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status;
+        params.key   = key;
+        params.flags = 0;
+        params.buf   = input;
+        params.len   = input_len;
+        if ((status = UNIX_CALL( key_asymmetric_import, &params )))
         {
             key_destroy( key );
             return status;
@@ -1466,7 +1491,19 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
             return STATUS_NOT_SUPPORTED;
 
         size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
-        return key_asymmetric_create( (struct key **)ret_key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size );
+        if ((status = key_asymmetric_create( &key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size ))) return status;
+        params.key   = key;
+        params.flags = KEY_IMPORT_FLAG_PUBLIC;
+        params.buf   = input;
+        params.len   = input_len;
+        if ((status = UNIX_CALL( key_asymmetric_import, &params )))
+        {
+            key_destroy( key );
+            return status;
+        }
+
+        *ret_key = key;
+        return STATUS_SUCCESS;
     }
     else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB ))
     {
@@ -1495,11 +1532,12 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
 
         size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
         if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, NULL, size ))) return status;
-
-        params.key = key;
-        params.buf = input;
-        params.len = input_len;
-        if ((status = UNIX_CALL( key_import_dsa_capi, &params )))
+        key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+        params.key   = key;
+        params.flags = 0;
+        params.buf   = input;
+        params.len   = input_len;
+        if ((status = UNIX_CALL( key_asymmetric_import, &params )))
         {
             key_destroy( key );
             return status;
@@ -1531,6 +1569,15 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
 
         if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
         key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+        params.key   = key;
+        params.flags = KEY_IMPORT_FLAG_PUBLIC;
+        params.buf   = input;
+        params.len   = input_len;
+        if ((status = UNIX_CALL( key_asymmetric_import, &params )))
+        {
+            key_destroy( key );
+            return status;
+        }
 
         *ret_key = key;
         return STATUS_SUCCESS;
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 01e1fe72092..28119fc9e78 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1162,10 +1162,8 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS key_import_ecc( void *args )
+static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
 {
-    const struct key_import_params *params = args;
-    struct key *key = params->key;
     BCRYPT_ECCKEY_BLOB *ecc_blob;
     gnutls_ecc_curve_t curve;
     gnutls_privkey_t handle;
@@ -1191,7 +1189,7 @@ static NTSTATUS key_import_ecc( void *args )
         return STATUS_INTERNAL_ERROR;
     }
 
-    ecc_blob = (BCRYPT_ECCKEY_BLOB *)params->buf;
+    ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
     x.data = (unsigned char *)(ecc_blob + 1);
     x.size = ecc_blob->cbKey;
     y.data = x.data + ecc_blob->cbKey;
@@ -1212,6 +1210,7 @@ static NTSTATUS key_import_ecc( void *args )
         return status;
     }
 
+    if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
     key_data(key)->privkey = handle;
     return STATUS_SUCCESS;
 }
@@ -1273,10 +1272,9 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS key_import_rsa( void *args )
+static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
 {
-    const struct key_import_params *params = args;
-    BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)params->buf;
+    BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
     gnutls_datum_t m, e, p, q;
     gnutls_privkey_t handle;
     int ret;
@@ -1303,7 +1301,8 @@ static NTSTATUS key_import_rsa( void *args )
         return STATUS_INTERNAL_ERROR;
     }
 
-    key_data(params->key)->privkey = handle;
+    if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
+    key_data(key)->privkey = handle;
     return STATUS_SUCCESS;
 }
 
@@ -1366,11 +1365,9 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS key_import_dsa_capi( void *args )
+static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
 {
-    const struct key_import_params *params = args;
-    struct key *key = params->key;
-    BLOBHEADER *hdr = (BLOBHEADER *)params->buf;
+    BLOBHEADER *hdr = (BLOBHEADER *)buf;
     DSSPUBKEY *pubkey;
     gnutls_privkey_t handle;
     gnutls_datum_t p, q, g, y, x;
@@ -1435,9 +1432,8 @@ static NTSTATUS key_import_dsa_capi( void *args )
 
     memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
 
-    key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+    if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
     key_data(key)->privkey = handle;
-
     return STATUS_SUCCESS;
 }
 
@@ -1650,6 +1646,50 @@ static NTSTATUS key_asymmetric_export( void *args )
     }
 }
 
+static NTSTATUS key_asymmetric_import( void *args )
+{
+    const struct key_asymmetric_import_params *params = args;
+    struct key *key = params->key;
+    unsigned flags = params->flags;
+
+    switch (key->alg_id)
+    {
+    case ALG_ID_ECDH_P256:
+    case ALG_ID_ECDSA_P256:
+    case ALG_ID_ECDSA_P384:
+        if (flags & KEY_IMPORT_FLAG_PUBLIC)
+        {
+            FIXME("\n");
+            return STATUS_SUCCESS;
+        }
+        return key_import_ecc( key, params->buf, params->len );
+
+    case ALG_ID_RSA:
+    case ALG_ID_RSA_SIGN:
+        if (flags & KEY_IMPORT_FLAG_PUBLIC)
+        {
+            FIXME("\n");
+            return STATUS_SUCCESS;
+        }
+        return key_import_rsa( key, params->buf, params->len );
+
+    case ALG_ID_DSA:
+        if (flags & KEY_IMPORT_FLAG_PUBLIC)
+        {
+            FIXME("\n");
+            return STATUS_SUCCESS;
+        }
+        if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
+            return key_import_dsa_capi( key, params->buf, params->len );
+        FIXME( "DSA private key not supported\n" );
+        return STATUS_NOT_IMPLEMENTED;
+
+    default:
+        FIXME( "algorithm %u not yet supported\n", key->alg_id );
+        return STATUS_NOT_IMPLEMENTED;
+    }
+}
+
 static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
                                               gnutls_datum_t *gnutls_signature )
 {
@@ -2085,9 +2125,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
     key_asymmetric_verify,
     key_asymmetric_destroy,
     key_asymmetric_export,
-    key_import_dsa_capi,
-    key_import_ecc,
-    key_import_rsa
+    key_asymmetric_import
 };
 
 #ifdef _WIN64
@@ -2477,59 +2515,12 @@ static NTSTATUS wow64_key_asymmetric_export( void *args )
     return ret;
 }
 
-static NTSTATUS wow64_key_import_dsa_capi( void *args )
-{
-    struct
-    {
-        PTR32 key;
-        PTR32 buf;
-        ULONG len;
-    } const *params32 = args;
-
-    NTSTATUS ret;
-    struct key key;
-    struct key32 *key32 = ULongToPtr( params32->key );
-    struct key_import_params params =
-    {
-        get_asymmetric_key( key32, &key ),
-        ULongToPtr(params32->buf),
-        params32->len
-    };
-
-    ret = key_import_dsa_capi( &params );
-    put_asymmetric_key32( &key, key32 );
-    return ret;
-}
-
-static NTSTATUS wow64_key_import_ecc( void *args )
-{
-    struct
-    {
-        PTR32 key;
-        PTR32 buf;
-        ULONG len;
-    } const *params32 = args;
-
-    NTSTATUS ret;
-    struct key key;
-    struct key32 *key32 = ULongToPtr( params32->key );
-    struct key_import_params params =
-    {
-        get_asymmetric_key( key32, &key ),
-        ULongToPtr(params32->buf),
-        params32->len
-    };
-
-    ret = key_import_ecc( &params );
-    put_asymmetric_key32( &key, key32 );
-    return ret;
-}
-
-static NTSTATUS wow64_key_import_rsa( void *args )
+static NTSTATUS wow64_key_asymmetric_import( void *args )
 {
     struct
     {
         PTR32 key;
+        ULONG flags;
         PTR32 buf;
         ULONG len;
     } const *params32 = args;
@@ -2537,14 +2528,15 @@ static NTSTATUS wow64_key_import_rsa( void *args )
     NTSTATUS ret;
     struct key key;
     struct key32 *key32 = ULongToPtr( params32->key );
-    struct key_import_params params =
+    struct key_asymmetric_import_params params =
     {
         get_asymmetric_key( key32, &key ),
+        params32->flags,
         ULongToPtr(params32->buf),
         params32->len
     };
 
-    ret = key_import_rsa( &params );
+    ret = key_asymmetric_import( &params );
     put_asymmetric_key32( &key, key32 );
     return ret;
 }
@@ -2566,9 +2558,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
     wow64_key_asymmetric_verify,
     wow64_key_asymmetric_destroy,
     wow64_key_asymmetric_export,
-    wow64_key_import_dsa_capi,
-    wow64_key_import_ecc,
-    wow64_key_import_rsa
+    wow64_key_asymmetric_import
 };
 
 #endif  /* _WIN64 */
-- 
2.30.2




More information about the wine-devel mailing list