Commit 2795c7f9 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

bcrypt: Add support for exporting RSA private keys.

parent a2263318
......@@ -274,6 +274,7 @@ struct key_export_params
UCHAR *buf;
ULONG len;
ULONG *ret_len;
BOOL full;
};
struct key_import_params
......@@ -301,6 +302,7 @@ enum key_funcs
unix_key_asymmetric_destroy,
unix_key_export_dsa_capi,
unix_key_export_ecc,
unix_key_export_rsa,
unix_key_import_dsa_capi,
unix_key_import_ecc,
unix_key_import_rsa,
......
......@@ -1101,6 +1101,15 @@ static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, U
if (output) memcpy( output, key->u.a.pubkey, key->u.a.pubkey_len );
return STATUS_SUCCESS;
}
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
{
params.key = key;
params.buf = output;
params.len = output_len;
params.ret_len = size;
params.full = wcscmp( type, BCRYPT_RSAPRIVATE_BLOB );
return UNIX_CALL( key_export_rsa, &params );
}
else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
{
params.key = key;
......@@ -1404,13 +1413,13 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
}
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ))
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
{
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC)
return STATUS_NOT_SUPPORTED;
if (alg->id != ALG_ID_RSA || (rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC &&
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, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
......
......@@ -1028,6 +1028,64 @@ static NTSTATUS key_import_ecc( void *args )
return STATUS_SUCCESS;
}
static NTSTATUS key_export_rsa( void *args )
{
const struct key_export_params *params = args;
struct key *key = params->key;
BCRYPT_RSAKEY_BLOB *rsa_blob;
gnutls_datum_t m, e, d, p, q, u, e1, e2;
ULONG bitlen = key->u.a.bitlen;
UCHAR *dst;
int ret;
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
*params->ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1) + EXPORT_SIZE(p,16,1) + EXPORT_SIZE(q,16,1);
if (params->full) *params->ret_len += EXPORT_SIZE(e1,16,1) + EXPORT_SIZE(e2,16,1) + EXPORT_SIZE(u,16,1) + EXPORT_SIZE(d,8,1);
if (params->len >= *params->ret_len && params->buf)
{
rsa_blob = (BCRYPT_RSAKEY_BLOB *)params->buf;
rsa_blob->Magic = params->full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
rsa_blob->BitLength = bitlen;
dst = (UCHAR *)(rsa_blob + 1);
rsa_blob->cbPublicExp = export_gnutls_datum( dst, bitlen / 8, &e, 0 );
dst += rsa_blob->cbPublicExp;
rsa_blob->cbModulus = export_gnutls_datum( dst, bitlen / 8, &m, 1 );
dst += rsa_blob->cbModulus;
rsa_blob->cbPrime1 = export_gnutls_datum( dst, bitlen / 16, &p, 1 );
dst += rsa_blob->cbPrime1;
rsa_blob->cbPrime2 = export_gnutls_datum( dst, bitlen / 16, &q, 1 );
if (params->full)
{
dst += rsa_blob->cbPrime2;
export_gnutls_datum( dst, bitlen / 16, &e1, 1 );
dst += rsa_blob->cbPrime1;
export_gnutls_datum( dst, bitlen / 16, &e2, 1 );
dst += rsa_blob->cbPrime2;
export_gnutls_datum( dst, bitlen / 16, &u, 1 );
dst += rsa_blob->cbPrime1;
export_gnutls_datum( dst, bitlen / 8, &d, 1 );
}
}
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
free( e1.data ); free( e2.data );
return STATUS_SUCCESS;
}
static NTSTATUS key_import_rsa( void *args )
{
const struct key_import_params *params = args;
......@@ -1805,6 +1863,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
key_asymmetric_destroy,
key_export_dsa_capi,
key_export_ecc,
key_export_rsa,
key_import_dsa_capi,
key_import_ecc,
key_import_rsa
......@@ -2269,6 +2328,34 @@ static NTSTATUS wow64_key_import_ecc( void *args )
return ret;
}
static NTSTATUS wow64_key_export_rsa( void *args )
{
struct
{
PTR32 key;
PTR32 buf;
ULONG len;
PTR32 ret_len;
BOOL full;
} const *params32 = args;
NTSTATUS ret;
struct key key;
struct key32 *key32 = ULongToPtr( params32->key );
struct key_export_params params =
{
get_asymmetric_key( key32, &key ),
ULongToPtr(params32->buf),
params32->len,
ULongToPtr(params32->ret_len),
params32->full
};
ret = key_export_rsa( &params );
put_asymmetric_key32( &key, key32 );
return ret;
}
static NTSTATUS wow64_key_import_rsa( void *args )
{
struct
......@@ -2311,6 +2398,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
wow64_key_asymmetric_destroy,
wow64_key_export_dsa_capi,
wow64_key_export_ecc,
wow64_key_export_rsa,
wow64_key_import_dsa_capi,
wow64_key_import_ecc,
wow64_key_import_rsa
......
......@@ -66,6 +66,7 @@ typedef LONG NTSTATUS;
#define BCRYPT_ECCPRIVATE_BLOB L"ECCPRIVATEBLOB"
#define BCRYPT_RSAPUBLIC_BLOB L"RSAPUBLICBLOB"
#define BCRYPT_RSAPRIVATE_BLOB L"RSAPRIVATEBLOB"
#define BCRYPT_RSAFULLPRIVATE_BLOB L"RSAFULLPRIVATEBLOB"
#define BCRYPT_DSA_PUBLIC_BLOB L"DSAPUBLICBLOB"
#define BCRYPT_DSA_PRIVATE_BLOB L"DSAPRIVATEBLOB"
#define BCRYPT_PUBLIC_KEY_BLOB L"PUBLICBLOB"
......@@ -137,6 +138,7 @@ static const WCHAR BCRYPT_ECCPUBLIC_BLOB[] = {'E','C','C','P','U','B','L','I','C
static const WCHAR BCRYPT_ECCPRIVATE_BLOB[] = {'E','C','C','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPUBLIC_BLOB[] = {'R','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPRIVATE_BLOB[] = {'R','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_RSAFULLPRIVATE_BLOB[] = {'R','S','A','F','U','L','L','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PUBLIC_BLOB[] = {'D','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PRIVATE_BLOB[] = {'D','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_PUBLIC_KEY_BLOB[] = {'P','U','B','L','I','C','B','L','O','B',0};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment