Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/bcrypt/gnutls.c
8686 views
1
/*
2
* Copyright 2009 Henri Verbeet for CodeWeavers
3
* Copyright 2018 Hans Leidekker for CodeWeavers
4
*
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
9
*
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18
*
19
*/
20
21
#if 0
22
#pragma makedep unix
23
#endif
24
25
#include "config.h"
26
27
#ifdef HAVE_GNUTLS_CIPHER_INIT
28
29
#include <stdarg.h>
30
#include <stdlib.h>
31
#include <assert.h>
32
#include <sys/types.h>
33
#include <dlfcn.h>
34
#include <gnutls/gnutls.h>
35
#include <gnutls/crypto.h>
36
#include <gnutls/abstract.h>
37
38
#include "ntstatus.h"
39
#define WIN32_NO_STATUS
40
#include "windef.h"
41
#include "winbase.h"
42
#include "winternl.h"
43
#include "ntsecapi.h"
44
#include "wincrypt.h"
45
#include "bcrypt.h"
46
47
#include "bcrypt_internal.h"
48
49
#include "wine/debug.h"
50
51
WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
52
WINE_DECLARE_DEBUG_CHANNEL(winediag);
53
54
#if GNUTLS_VERSION_MAJOR < 3
55
#define GNUTLS_CIPHER_AES_192_CBC 92
56
#define GNUTLS_CIPHER_AES_128_GCM 93
57
#define GNUTLS_CIPHER_AES_256_GCM 94
58
#define GNUTLS_PK_ECC 4
59
60
#define GNUTLS_CURVE_TO_BITS(curve) (unsigned int)(((unsigned int)1<<31)|((unsigned int)(curve)))
61
62
typedef enum
63
{
64
GNUTLS_ECC_CURVE_INVALID,
65
GNUTLS_ECC_CURVE_SECP224R1,
66
GNUTLS_ECC_CURVE_SECP256R1,
67
GNUTLS_ECC_CURVE_SECP384R1,
68
GNUTLS_ECC_CURVE_SECP521R1,
69
} gnutls_ecc_curve_t;
70
#endif
71
72
#if GNUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 6)
73
#define GNUTLS_CIPHER_AES_128_CFB8 29
74
#define GNUTLS_CIPHER_AES_192_CFB8 30
75
#define GNUTLS_CIPHER_AES_256_CFB8 31
76
77
#define GNUTLS_PK_RSA_PSS 6
78
#define GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS (1 << 7)
79
typedef struct gnutls_x509_spki_st *gnutls_x509_spki_t;
80
#endif
81
82
#if GUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 8)
83
#define GNUTLS_KEYGEN_DH 4
84
#endif
85
86
union key_data
87
{
88
gnutls_cipher_hd_t cipher;
89
struct
90
{
91
gnutls_privkey_t privkey;
92
gnutls_pubkey_t pubkey;
93
gnutls_dh_params_t dh_params;
94
} a;
95
};
96
C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
97
98
static union key_data *key_data( struct key *key )
99
{
100
return (union key_data *)key->private;
101
}
102
103
/* Not present in gnutls version < 3.0 */
104
static int (*pgnutls_cipher_tag)(gnutls_cipher_hd_t, void *, size_t);
105
static int (*pgnutls_cipher_add_auth)(gnutls_cipher_hd_t, const void *, size_t);
106
static gnutls_sign_algorithm_t (*pgnutls_pk_to_sign)(gnutls_pk_algorithm_t, gnutls_digest_algorithm_t);
107
static int (*pgnutls_pubkey_import_ecc_raw)(gnutls_pubkey_t, gnutls_ecc_curve_t,
108
const gnutls_datum_t *, const gnutls_datum_t *);
109
static int (*pgnutls_pubkey_export_ecc_raw)(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
110
gnutls_datum_t *x, gnutls_datum_t *y);
111
static int (*pgnutls_privkey_import_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t, const gnutls_datum_t *,
112
const gnutls_datum_t *, const gnutls_datum_t *);
113
static int (*pgnutls_pubkey_verify_hash2)(gnutls_pubkey_t, gnutls_sign_algorithm_t, unsigned int,
114
const gnutls_datum_t *, const gnutls_datum_t *);
115
static int (*pgnutls_pubkey_encrypt_data)(gnutls_pubkey_t, unsigned int flags, const gnutls_datum_t *,
116
gnutls_datum_t *);
117
118
/* Not present in gnutls version < 2.11.0 */
119
static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *);
120
121
/* Not present in gnutls version < 2.12.0 */
122
static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
123
const gnutls_datum_t *, const gnutls_datum_t *);
124
static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
125
static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *,
126
gnutls_datum_t *);
127
128
/* Not present in gnutls version < 3.3.0 */
129
static int (*pgnutls_pubkey_export_dsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
130
gnutls_datum_t *);
131
static int (*pgnutls_pubkey_export_rsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *);
132
static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
133
gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
134
static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
135
gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
136
gnutls_datum_t *);
137
static int (*pgnutls_privkey_export_dsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
138
gnutls_datum_t *, gnutls_datum_t *);
139
static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
140
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
141
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
142
143
/* Not present in gnutls version < 3.5.0 */
144
static int (*pgnutls_privkey_generate2)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int,
145
const gnutls_keygen_data_st *, unsigned);
146
147
/* Not present in gnutls version < 3.6.0 */
148
static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
149
static int (*pgnutls_x509_spki_init)(gnutls_x509_spki_t *);
150
static void (*pgnutls_x509_spki_deinit)(gnutls_x509_spki_t);
151
static void (*pgnutls_x509_spki_set_rsa_pss_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, unsigned int);
152
static int (*pgnutls_pubkey_set_spki)(gnutls_pubkey_t, const gnutls_x509_spki_t, unsigned int);
153
static int (*pgnutls_privkey_set_spki)(gnutls_privkey_t, const gnutls_x509_spki_t, unsigned int);
154
155
/* Not present in gnutls version < 3.8.2 */
156
static int (*pgnutls_privkey_derive_secret)(gnutls_privkey_t, gnutls_pubkey_t, const gnutls_datum_t *,
157
gnutls_datum_t *, unsigned int);
158
static int (*pgnutls_privkey_export_dh_raw)(gnutls_privkey_t, gnutls_dh_params_t, gnutls_datum_t *, gnutls_datum_t *,
159
unsigned int);
160
static int (*pgnutls_pubkey_export_dh_raw)(gnutls_pubkey_t, gnutls_dh_params_t, gnutls_datum_t *, unsigned);
161
static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_params_t, const gnutls_datum_t *,
162
const gnutls_datum_t *);
163
static int (*pgnutls_pubkey_import_dh_raw)(gnutls_pubkey_t, const gnutls_dh_params_t, const gnutls_datum_t *);
164
165
/* Not present in gnutls version < 3.8.4 */
166
static int (*pgnutls_x509_spki_set_rsa_oaep_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, gnutls_datum_t *);
167
168
static void *libgnutls_handle;
169
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
170
MAKE_FUNCPTR(gnutls_cipher_decrypt2);
171
MAKE_FUNCPTR(gnutls_cipher_deinit);
172
MAKE_FUNCPTR(gnutls_cipher_encrypt2);
173
MAKE_FUNCPTR(gnutls_cipher_init);
174
MAKE_FUNCPTR(gnutls_dh_params_deinit);
175
MAKE_FUNCPTR(gnutls_dh_params_export_raw);
176
MAKE_FUNCPTR(gnutls_dh_params_import_raw);
177
MAKE_FUNCPTR(gnutls_dh_params_init);
178
MAKE_FUNCPTR(gnutls_global_deinit);
179
MAKE_FUNCPTR(gnutls_global_init);
180
MAKE_FUNCPTR(gnutls_global_set_log_function);
181
MAKE_FUNCPTR(gnutls_global_set_log_level);
182
MAKE_FUNCPTR(gnutls_perror);
183
MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
184
MAKE_FUNCPTR(gnutls_privkey_deinit);
185
MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
186
MAKE_FUNCPTR(gnutls_privkey_init);
187
MAKE_FUNCPTR(gnutls_privkey_sign_hash);
188
MAKE_FUNCPTR(gnutls_pubkey_deinit);
189
MAKE_FUNCPTR(gnutls_pubkey_encrypt_data);
190
MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
191
MAKE_FUNCPTR(gnutls_pubkey_init);
192
#undef MAKE_FUNCPTR
193
194
static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle, void *tag, size_t tag_size)
195
{
196
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
197
}
198
199
static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle, const void *ptext, size_t ptext_size)
200
{
201
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
202
}
203
204
static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
205
const gnutls_datum_t *x, const gnutls_datum_t *y)
206
{
207
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
208
}
209
210
static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
211
gnutls_datum_t *x, gnutls_datum_t *y)
212
{
213
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
214
}
215
216
static int compat_gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
217
gnutls_datum_t *g, gnutls_datum_t *y)
218
{
219
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
220
}
221
222
static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m, gnutls_datum_t *e)
223
{
224
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
225
}
226
227
static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t *m, gnutls_datum_t *e,
228
gnutls_datum_t *d, gnutls_datum_t *p, gnutls_datum_t *q,
229
gnutls_datum_t *u, gnutls_datum_t *e1, gnutls_datum_t *e2)
230
{
231
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
232
}
233
234
static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t *curve,
235
gnutls_datum_t *x, gnutls_datum_t *y, gnutls_datum_t *k)
236
{
237
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
238
}
239
240
static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t curve,
241
const gnutls_datum_t *x, const gnutls_datum_t *y,
242
const gnutls_datum_t *k)
243
{
244
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
245
}
246
247
static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
248
gnutls_datum_t *g, gnutls_datum_t *y, gnutls_datum_t *x)
249
{
250
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
251
}
252
253
static gnutls_sign_algorithm_t compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
254
{
255
return GNUTLS_SIGN_UNKNOWN;
256
}
257
258
static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo,
259
unsigned int flags, const gnutls_datum_t *hash,
260
const gnutls_datum_t *signature)
261
{
262
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
263
}
264
265
static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e)
266
{
267
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
268
}
269
270
static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p, const gnutls_datum_t *q,
271
const gnutls_datum_t *g, const gnutls_datum_t *y)
272
{
273
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
274
}
275
276
static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
277
{
278
return GNUTLS_E_INTERNAL_ERROR;
279
}
280
281
static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e,
282
const gnutls_datum_t *d, const gnutls_datum_t *p, const gnutls_datum_t *q,
283
const gnutls_datum_t *u, const gnutls_datum_t *e1, const gnutls_datum_t *e2)
284
{
285
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
286
}
287
288
static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
289
gnutls_datum_t *plain_text)
290
{
291
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
292
}
293
294
static int compat_gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
295
gnutls_datum_t *plain_text)
296
{
297
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
298
}
299
300
static int compat_gnutls_x509_spki_init(gnutls_x509_spki_t *spki)
301
{
302
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
303
}
304
305
static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki)
306
{
307
}
308
309
static int compat_gnutls_x509_spki_set_rsa_oaep_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
310
gnutls_datum_t *label)
311
{
312
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
313
}
314
315
static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
316
unsigned int salt_size)
317
{
318
}
319
320
static int compat_gnutls_pubkey_set_spki(gnutls_pubkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
321
{
322
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
323
}
324
325
static int compat_gnutls_privkey_set_spki(gnutls_privkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
326
{
327
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
328
}
329
330
static int compat_gnutls_privkey_derive_secret(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey, const gnutls_datum_t *nonce,
331
gnutls_datum_t *secret, unsigned int flags)
332
{
333
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
334
}
335
336
static int compat_gnutls_privkey_export_dh_raw(gnutls_privkey_t privkey, gnutls_dh_params_t params, gnutls_datum_t *y,
337
gnutls_datum_t *x, unsigned int flags )
338
{
339
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
340
}
341
342
static int compat_gnutls_pubkey_export_dh_raw(gnutls_pubkey_t pubkey, gnutls_dh_params_t params, gnutls_datum_t *y,
343
unsigned flags)
344
{
345
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
346
}
347
348
static int compat_gnutls_privkey_import_dh_raw(gnutls_privkey_t privkey, const gnutls_dh_params_t params,
349
const gnutls_datum_t *y, const gnutls_datum_t *x)
350
{
351
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
352
}
353
354
static int compat_gnutls_pubkey_import_dh_raw(gnutls_pubkey_t pubkey, const gnutls_dh_params_t params,
355
const gnutls_datum_t *y)
356
{
357
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
358
}
359
360
static int compat_gnutls_privkey_generate2(gnutls_privkey_t privkey, gnutls_pk_algorithm_t alg, unsigned int bits,
361
unsigned int flags, const gnutls_keygen_data_st *data, unsigned data_size)
362
{
363
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
364
}
365
366
static void gnutls_log( int level, const char *msg )
367
{
368
TRACE( "<%d> %s", level, msg );
369
}
370
371
static NTSTATUS gnutls_process_attach( void *args )
372
{
373
const char *env_str;
374
int ret;
375
376
if ((env_str = getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
377
{
378
WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str));
379
}
380
else
381
{
382
WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
383
setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
384
}
385
386
if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
387
{
388
ERR_(winediag)( "failed to load libgnutls, no support for encryption\n" );
389
return STATUS_DLL_NOT_FOUND;
390
}
391
392
#define LOAD_FUNCPTR(f) \
393
if (!(p##f = dlsym( libgnutls_handle, #f ))) \
394
{ \
395
ERR( "failed to load %s\n", #f ); \
396
goto fail; \
397
}
398
399
LOAD_FUNCPTR(gnutls_cipher_decrypt2)
400
LOAD_FUNCPTR(gnutls_cipher_deinit)
401
LOAD_FUNCPTR(gnutls_cipher_encrypt2)
402
LOAD_FUNCPTR(gnutls_cipher_init)
403
LOAD_FUNCPTR(gnutls_dh_params_deinit)
404
LOAD_FUNCPTR(gnutls_dh_params_export_raw)
405
LOAD_FUNCPTR(gnutls_dh_params_import_raw)
406
LOAD_FUNCPTR(gnutls_dh_params_init)
407
LOAD_FUNCPTR(gnutls_global_deinit)
408
LOAD_FUNCPTR(gnutls_global_init)
409
LOAD_FUNCPTR(gnutls_global_set_log_function)
410
LOAD_FUNCPTR(gnutls_global_set_log_level)
411
LOAD_FUNCPTR(gnutls_perror)
412
LOAD_FUNCPTR(gnutls_privkey_deinit);
413
LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw);
414
LOAD_FUNCPTR(gnutls_privkey_init);
415
LOAD_FUNCPTR(gnutls_privkey_sign_hash);
416
LOAD_FUNCPTR(gnutls_pubkey_deinit);
417
LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
418
LOAD_FUNCPTR(gnutls_pubkey_init);
419
#undef LOAD_FUNCPTR
420
421
#define LOAD_FUNCPTR_OPT(f) \
422
if (!(p##f = dlsym( libgnutls_handle, #f ))) \
423
{ \
424
WARN( "failed to load %s\n", #f ); \
425
p##f = compat_##f; \
426
}
427
428
LOAD_FUNCPTR_OPT(gnutls_cipher_tag)
429
LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth)
430
LOAD_FUNCPTR_OPT(gnutls_decode_rs_value)
431
LOAD_FUNCPTR_OPT(gnutls_pk_to_sign)
432
LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data)
433
LOAD_FUNCPTR_OPT(gnutls_privkey_derive_secret)
434
LOAD_FUNCPTR_OPT(gnutls_privkey_export_dh_raw)
435
LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw)
436
LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw)
437
LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw)
438
LOAD_FUNCPTR_OPT(gnutls_privkey_generate2)
439
LOAD_FUNCPTR_OPT(gnutls_privkey_import_dh_raw)
440
LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw)
441
LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw)
442
LOAD_FUNCPTR_OPT(gnutls_privkey_set_spki)
443
LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data)
444
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dh_raw)
445
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw)
446
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw)
447
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw)
448
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dh_raw)
449
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw)
450
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw)
451
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw)
452
LOAD_FUNCPTR_OPT(gnutls_pubkey_set_spki)
453
LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
454
LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit)
455
LOAD_FUNCPTR_OPT(gnutls_x509_spki_init)
456
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_oaep_params)
457
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params)
458
459
#undef LOAD_FUNCPTR_OPT
460
461
if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
462
{
463
pgnutls_perror( ret );
464
goto fail;
465
}
466
467
if (TRACE_ON( bcrypt ))
468
{
469
char *env = getenv("GNUTLS_DEBUG_LEVEL");
470
int level = env ? atoi(env) : 4;
471
pgnutls_global_set_log_level(level);
472
pgnutls_global_set_log_function( gnutls_log );
473
}
474
475
return STATUS_SUCCESS;
476
477
fail:
478
dlclose( libgnutls_handle );
479
libgnutls_handle = NULL;
480
return STATUS_DLL_NOT_FOUND;
481
}
482
483
static NTSTATUS gnutls_process_detach( void *args )
484
{
485
if (libgnutls_handle)
486
{
487
if (TRACE_ON( bcrypt ))
488
pgnutls_global_set_log_function( NULL );
489
pgnutls_global_deinit();
490
dlclose( libgnutls_handle );
491
libgnutls_handle = NULL;
492
}
493
return STATUS_SUCCESS;
494
}
495
496
struct buffer
497
{
498
BYTE *buffer;
499
DWORD length;
500
DWORD pos;
501
BOOL error;
502
};
503
504
static void buffer_init( struct buffer *buffer )
505
{
506
buffer->buffer = NULL;
507
buffer->length = 0;
508
buffer->pos = 0;
509
buffer->error = FALSE;
510
}
511
512
static void buffer_free( struct buffer *buffer )
513
{
514
free( buffer->buffer );
515
}
516
517
static void buffer_append( struct buffer *buffer, BYTE *data, DWORD len )
518
{
519
if (!len) return;
520
521
if (buffer->pos + len > buffer->length)
522
{
523
DWORD new_length = max( max( buffer->pos + len, buffer->length * 2 ), 64 );
524
BYTE *new_buffer;
525
526
if (!(new_buffer = realloc( buffer->buffer, new_length )))
527
{
528
ERR( "out of memory\n" );
529
buffer->error = TRUE;
530
return;
531
}
532
533
buffer->buffer = new_buffer;
534
buffer->length = new_length;
535
}
536
537
memcpy( &buffer->buffer[buffer->pos], data, len );
538
buffer->pos += len;
539
}
540
541
static void buffer_append_byte( struct buffer *buffer, BYTE value )
542
{
543
buffer_append( buffer, &value, sizeof(value) );
544
}
545
546
static void buffer_append_asn1_length( struct buffer *buffer, DWORD length )
547
{
548
DWORD num_bytes;
549
550
if (length < 128)
551
{
552
buffer_append_byte( buffer, length );
553
return;
554
}
555
556
if (length <= 0xff) num_bytes = 1;
557
else if (length <= 0xffff) num_bytes = 2;
558
else if (length <= 0xffffff) num_bytes = 3;
559
else num_bytes = 4;
560
561
buffer_append_byte( buffer, 0x80 | num_bytes );
562
while (num_bytes--) buffer_append_byte( buffer, length >> (num_bytes * 8) );
563
}
564
565
static void buffer_append_asn1_integer( struct buffer *buffer, BYTE *data, DWORD len )
566
{
567
DWORD leading_zero = (*data & 0x80) != 0;
568
569
buffer_append_byte( buffer, 0x02 ); /* tag */
570
buffer_append_asn1_length( buffer, len + leading_zero );
571
if (leading_zero) buffer_append_byte( buffer, 0 );
572
buffer_append( buffer, data, len );
573
}
574
575
static void buffer_append_asn1_sequence( struct buffer *buffer, struct buffer *content )
576
{
577
if (content->error)
578
{
579
buffer->error = TRUE;
580
return;
581
}
582
583
buffer_append_byte( buffer, 0x30 ); /* tag */
584
buffer_append_asn1_length( buffer, content->pos );
585
buffer_append( buffer, content->buffer, content->pos );
586
}
587
588
static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *s, DWORD s_len )
589
{
590
struct buffer value;
591
592
buffer_init( &value );
593
buffer_append_asn1_integer( &value, r, r_len );
594
buffer_append_asn1_integer( &value, s, s_len );
595
buffer_append_asn1_sequence( buffer, &value );
596
buffer_free( &value );
597
}
598
599
static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
600
{
601
switch (key->alg_id)
602
{
603
case ALG_ID_3DES:
604
WARN( "handle block size\n" );
605
switch (key->u.s.mode)
606
{
607
case CHAIN_MODE_CBC:
608
return GNUTLS_CIPHER_3DES_CBC;
609
default:
610
break;
611
}
612
FIXME( "3DES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
613
return GNUTLS_CIPHER_UNKNOWN;
614
615
case ALG_ID_AES:
616
WARN( "handle block size\n" );
617
switch (key->u.s.mode)
618
{
619
case CHAIN_MODE_GCM:
620
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_GCM;
621
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_GCM;
622
break;
623
case CHAIN_MODE_ECB: /* can be emulated with CBC + empty IV */
624
case CHAIN_MODE_CBC:
625
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CBC;
626
if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CBC;
627
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CBC;
628
break;
629
case CHAIN_MODE_CFB:
630
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CFB8;
631
if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CFB8;
632
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CFB8;
633
break;
634
default:
635
break;
636
}
637
FIXME( "AES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
638
return GNUTLS_CIPHER_UNKNOWN;
639
640
default:
641
FIXME( "algorithm %u not supported\n", key->alg_id );
642
return GNUTLS_CIPHER_UNKNOWN;
643
}
644
}
645
646
static NTSTATUS key_symmetric_vector_reset( void *args )
647
{
648
struct key *key = args;
649
650
if (!key_data(key)->cipher) return STATUS_SUCCESS;
651
TRACE( "invalidating cipher handle\n" );
652
pgnutls_cipher_deinit( key_data(key)->cipher );
653
key_data(key)->cipher = NULL;
654
return STATUS_SUCCESS;
655
}
656
657
static NTSTATUS init_cipher_handle( struct key *key )
658
{
659
gnutls_cipher_algorithm_t cipher;
660
gnutls_datum_t secret, vector;
661
int ret;
662
663
if (key_data(key)->cipher) return STATUS_SUCCESS;
664
if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
665
666
secret.data = key->u.s.secret;
667
secret.size = key->u.s.secret_len;
668
669
vector.data = key->u.s.vector;
670
vector.size = key->u.s.vector_len;
671
672
if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
673
{
674
pgnutls_perror( ret );
675
return STATUS_INTERNAL_ERROR;
676
}
677
678
return STATUS_SUCCESS;
679
}
680
681
static NTSTATUS key_symmetric_set_auth_data( void *args )
682
{
683
const struct key_symmetric_set_auth_data_params *params = args;
684
NTSTATUS status;
685
int ret;
686
687
if (!params->auth_data) return STATUS_SUCCESS;
688
if ((status = init_cipher_handle( params->key ))) return status;
689
690
if ((ret = pgnutls_cipher_add_auth( key_data(params->key)->cipher, params->auth_data, params->len )))
691
{
692
pgnutls_perror( ret );
693
return STATUS_INTERNAL_ERROR;
694
}
695
return STATUS_SUCCESS;
696
}
697
698
static NTSTATUS key_symmetric_encrypt( void *args )
699
{
700
const struct key_symmetric_encrypt_params *params = args;
701
NTSTATUS status;
702
int ret;
703
704
if ((status = init_cipher_handle( params->key ))) return status;
705
706
if ((ret = pgnutls_cipher_encrypt2( key_data(params->key)->cipher, params->input, params->input_len,
707
params->output, params->output_len )))
708
{
709
pgnutls_perror( ret );
710
return STATUS_INTERNAL_ERROR;
711
}
712
return STATUS_SUCCESS;
713
}
714
715
static NTSTATUS key_symmetric_decrypt( void *args )
716
{
717
const struct key_symmetric_decrypt_params *params = args;
718
NTSTATUS status;
719
int ret;
720
721
if ((status = init_cipher_handle( params->key ))) return status;
722
723
if ((ret = pgnutls_cipher_decrypt2( key_data(params->key)->cipher, params->input, params->input_len,
724
params->output, params->output_len )))
725
{
726
pgnutls_perror( ret );
727
return STATUS_INTERNAL_ERROR;
728
}
729
return STATUS_SUCCESS;
730
}
731
732
static NTSTATUS key_symmetric_get_tag( void *args )
733
{
734
const struct key_symmetric_get_tag_params *params = args;
735
NTSTATUS status;
736
int ret;
737
738
if ((status = init_cipher_handle( params->key ))) return status;
739
740
if ((ret = pgnutls_cipher_tag( key_data(params->key)->cipher, params->tag, params->len )))
741
{
742
pgnutls_perror( ret );
743
return STATUS_INTERNAL_ERROR;
744
}
745
return STATUS_SUCCESS;
746
}
747
748
static NTSTATUS key_symmetric_destroy( void *args )
749
{
750
struct key *key = args;
751
752
if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
753
return STATUS_SUCCESS;
754
}
755
756
static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d, BOOL zero_pad )
757
{
758
ULONG size = d->size;
759
UCHAR *src = d->data;
760
ULONG offset = 0;
761
762
assert( size <= buflen + 1 );
763
if (size == buflen + 1)
764
{
765
assert( !src[0] );
766
src++;
767
size--;
768
}
769
if (zero_pad)
770
{
771
offset = buflen - size;
772
if (buffer) memset( buffer, 0, offset );
773
size = buflen;
774
}
775
776
if (buffer) memcpy( buffer + offset, src, size - offset );
777
return size;
778
}
779
780
#define EXPORT_SIZE(d,l,p) export_gnutls_datum( NULL, l, &d, p )
781
static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
782
{
783
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
784
gnutls_datum_t m, e;
785
ULONG size = len_from_bitlen( key->u.a.bitlen );
786
UCHAR *dst;
787
int ret;
788
789
if (key_data(key)->a.pubkey)
790
ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e );
791
else
792
return STATUS_INVALID_PARAMETER;
793
794
if (ret)
795
{
796
pgnutls_perror( ret );
797
return STATUS_INTERNAL_ERROR;
798
}
799
800
*ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 );
801
if (len >= *ret_len && buf)
802
{
803
dst = (UCHAR *)(rsa_blob + 1);
804
rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
805
806
dst += rsa_blob->cbPublicExp;
807
rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
808
809
rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
810
rsa_blob->BitLength = key->u.a.bitlen;
811
rsa_blob->cbPrime1 = 0;
812
rsa_blob->cbPrime2 = 0;
813
}
814
815
free( e.data ); free( m.data );
816
return STATUS_SUCCESS;
817
}
818
819
static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
820
{
821
BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
822
gnutls_ecc_curve_t curve;
823
gnutls_datum_t x, y;
824
DWORD magic, size;
825
UCHAR *dst;
826
int ret;
827
828
switch (key->alg_id)
829
{
830
case ALG_ID_ECDH:
831
switch (key->u.a.curve_id)
832
{
833
case ECC_CURVE_25519:
834
magic = BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC;
835
size = 32;
836
break;
837
case ECC_CURVE_P256R1:
838
magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
839
size = 32;
840
break;
841
case ECC_CURVE_P384R1:
842
magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;
843
size = 48;
844
break;
845
case ECC_CURVE_P521R1:
846
magic = BCRYPT_ECDH_PUBLIC_P521_MAGIC;
847
size = 66;
848
break;
849
default:
850
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
851
return STATUS_NOT_IMPLEMENTED;
852
}
853
break;
854
855
case ALG_ID_ECDH_P256:
856
magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
857
size = 32;
858
break;
859
860
case ALG_ID_ECDH_P384:
861
magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;
862
size = 48;
863
break;
864
865
case ALG_ID_ECDH_P521:
866
magic = BCRYPT_ECDH_PUBLIC_P521_MAGIC;
867
size = 66;
868
break;
869
870
case ALG_ID_ECDSA:
871
switch (key->u.a.curve_id)
872
{
873
case ECC_CURVE_P256R1:
874
magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
875
size = 32;
876
break;
877
case ECC_CURVE_P384R1:
878
magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
879
size = 48;
880
break;
881
case ECC_CURVE_P521R1:
882
magic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC;
883
size = 66;
884
break;
885
default:
886
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
887
return STATUS_NOT_IMPLEMENTED;
888
}
889
break;
890
891
case ALG_ID_ECDSA_P256:
892
magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
893
size = 32;
894
break;
895
896
case ALG_ID_ECDSA_P384:
897
magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
898
size = 48;
899
break;
900
901
case ALG_ID_ECDSA_P521:
902
magic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC;
903
size = 66;
904
break;
905
906
default:
907
FIXME( "algorithm %u not supported\n", key->alg_id );
908
return STATUS_NOT_IMPLEMENTED;
909
}
910
911
if (key_data(key)->a.pubkey)
912
ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
913
else
914
return STATUS_INVALID_PARAMETER;
915
916
if (ret)
917
{
918
pgnutls_perror( ret );
919
return STATUS_INTERNAL_ERROR;
920
}
921
922
if (curve != GNUTLS_ECC_CURVE_X25519 && curve != GNUTLS_ECC_CURVE_SECP256R1 &&
923
curve != GNUTLS_ECC_CURVE_SECP384R1 && curve != GNUTLS_ECC_CURVE_SECP521R1)
924
{
925
FIXME( "curve %u not supported\n", curve );
926
free( x.data ); free( y.data );
927
return STATUS_NOT_IMPLEMENTED;
928
}
929
930
*ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 );
931
if (len >= *ret_len && buf)
932
{
933
ecc_blob->dwMagic = magic;
934
ecc_blob->cbKey = size;
935
936
dst = (UCHAR *)(ecc_blob + 1);
937
dst += export_gnutls_datum( dst, size, &x, 1 );
938
export_gnutls_datum( dst, size, &y, 1 );
939
}
940
941
free( x.data ); free( y.data );
942
return STATUS_SUCCESS;
943
}
944
945
static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
946
{
947
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
948
gnutls_datum_t p, q, g, y;
949
ULONG size = len_from_bitlen( key->u.a.bitlen );
950
NTSTATUS status = STATUS_SUCCESS;
951
UCHAR *dst;
952
int ret;
953
954
if (key->u.a.bitlen > 1024)
955
{
956
FIXME( "bitlen > 1024 not supported\n" );
957
return STATUS_NOT_IMPLEMENTED;
958
}
959
960
if (key_data(key)->a.pubkey)
961
ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
962
else
963
return STATUS_INVALID_PARAMETER;
964
965
if (ret)
966
{
967
pgnutls_perror( ret );
968
return STATUS_INTERNAL_ERROR;
969
}
970
971
if (EXPORT_SIZE( q, sizeof(dsa_blob->q), 1 ) > sizeof(dsa_blob->q))
972
{
973
status = STATUS_INVALID_PARAMETER;
974
goto done;
975
}
976
977
*ret_len = sizeof(*dsa_blob) + EXPORT_SIZE( p, size, 1 ) + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
978
if (len >= *ret_len && buf)
979
{
980
dst = (UCHAR *)(dsa_blob + 1);
981
dst += export_gnutls_datum( dst, size, &p, 1 );
982
dst += export_gnutls_datum( dst, size, &g, 1 );
983
export_gnutls_datum( dst, size, &y, 1 );
984
985
dst = dsa_blob->q;
986
export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
987
988
dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
989
dsa_blob->cbKey = size;
990
memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
991
memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
992
}
993
994
done:
995
free( p.data ); free( q.data ); free( g.data ); free( y.data );
996
return status;
997
}
998
999
static void reverse_bytes( UCHAR *buf, ULONG len )
1000
{
1001
unsigned int i;
1002
UCHAR tmp;
1003
1004
for (i = 0; i < len / 2; ++i)
1005
{
1006
tmp = buf[i];
1007
buf[i] = buf[len - i - 1];
1008
buf[len - i - 1] = tmp;
1009
}
1010
}
1011
1012
#define Q_SIZE 20
1013
static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1014
{
1015
BLOBHEADER *hdr = (BLOBHEADER *)buf;
1016
DSSPUBKEY *dsskey;
1017
gnutls_datum_t p, q, g, y;
1018
ULONG size = len_from_bitlen( key->u.a.bitlen );
1019
NTSTATUS status = STATUS_SUCCESS;
1020
UCHAR *dst;
1021
int ret;
1022
1023
if (key->u.a.bitlen > 1024)
1024
{
1025
FIXME( "bitlen > 1024 not supported\n" );
1026
return STATUS_NOT_IMPLEMENTED;
1027
}
1028
1029
if (key_data(key)->a.pubkey)
1030
ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
1031
else if (key_data(key)->a.privkey)
1032
ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
1033
else
1034
return STATUS_INVALID_PARAMETER;
1035
1036
if (ret)
1037
{
1038
pgnutls_perror( ret );
1039
return STATUS_INTERNAL_ERROR;
1040
}
1041
1042
if (EXPORT_SIZE( q, Q_SIZE, 1 ) > Q_SIZE)
1043
{
1044
status = STATUS_INVALID_PARAMETER;
1045
goto done;
1046
}
1047
1048
*ret_len = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed) +
1049
EXPORT_SIZE( p, size, 1 ) + Q_SIZE + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
1050
if (len >= *ret_len && buf)
1051
{
1052
hdr->bType = PUBLICKEYBLOB;
1053
hdr->bVersion = 2;
1054
hdr->reserved = 0;
1055
hdr->aiKeyAlg = CALG_DSS_SIGN;
1056
1057
dsskey = (DSSPUBKEY *)(hdr + 1);
1058
dsskey->magic = MAGIC_DSS1;
1059
dsskey->bitlen = key->u.a.bitlen;
1060
1061
dst = (UCHAR *)(dsskey + 1);
1062
export_gnutls_datum( dst, size, &p, 1 );
1063
reverse_bytes( dst, size );
1064
dst += size;
1065
1066
export_gnutls_datum( dst, Q_SIZE, &q, 1 );
1067
reverse_bytes( dst, Q_SIZE );
1068
dst += Q_SIZE;
1069
1070
export_gnutls_datum( dst, size, &g, 1 );
1071
reverse_bytes( dst, size );
1072
dst += size;
1073
1074
export_gnutls_datum( dst, size, &y, 1 );
1075
reverse_bytes( dst, size );
1076
dst += size;
1077
1078
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1079
}
1080
1081
done:
1082
free( p.data ); free( q.data ); free( g.data ); free( y.data );
1083
return status;
1084
}
1085
1086
static gnutls_privkey_t create_privkey( gnutls_pk_algorithm_t pk_alg, unsigned int bitlen,
1087
const gnutls_keygen_data_st *data, unsigned int data_size )
1088
{
1089
gnutls_privkey_t privkey;
1090
int ret;
1091
1092
if ((ret = pgnutls_privkey_init( &privkey )))
1093
{
1094
pgnutls_perror( ret );
1095
return NULL;
1096
}
1097
1098
if ((ret = pgnutls_privkey_generate2( privkey, pk_alg, bitlen, 0, data, data_size )))
1099
{
1100
pgnutls_perror( ret );
1101
pgnutls_privkey_deinit( privkey );
1102
return NULL;
1103
}
1104
1105
return privkey;
1106
}
1107
1108
static gnutls_pubkey_t create_pubkey_from_privkey( gnutls_privkey_t privkey )
1109
{
1110
gnutls_pubkey_t pubkey;
1111
int ret;
1112
1113
if ((ret = pgnutls_pubkey_init( &pubkey )))
1114
{
1115
pgnutls_perror( ret );
1116
return NULL;
1117
}
1118
1119
if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
1120
{
1121
pgnutls_perror( ret );
1122
pgnutls_pubkey_deinit( pubkey );
1123
return NULL;
1124
}
1125
1126
return pubkey;
1127
}
1128
1129
static gnutls_dh_params_t get_dh_params( gnutls_privkey_t privkey )
1130
{
1131
gnutls_dh_params_t params;
1132
gnutls_datum_t x;
1133
int ret;
1134
1135
if ((ret = pgnutls_dh_params_init( &params )))
1136
{
1137
pgnutls_perror( ret );
1138
return NULL;
1139
}
1140
1141
if ((ret = pgnutls_privkey_export_dh_raw( privkey, params, NULL, &x, 0 )))
1142
{
1143
pgnutls_perror( ret );
1144
pgnutls_dh_params_deinit( params );
1145
return NULL;
1146
}
1147
1148
free( x.data );
1149
return params;
1150
}
1151
1152
static NTSTATUS key_asymmetric_generate( void *args )
1153
{
1154
struct key *key = args;
1155
gnutls_pk_algorithm_t pk_alg;
1156
gnutls_privkey_t privkey;
1157
gnutls_pubkey_t pubkey;
1158
unsigned int bitlen;
1159
1160
if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
1161
if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
1162
1163
switch (key->alg_id)
1164
{
1165
case ALG_ID_RSA:
1166
case ALG_ID_RSA_SIGN:
1167
pk_alg = GNUTLS_PK_RSA;
1168
bitlen = key->u.a.bitlen;
1169
break;
1170
1171
case ALG_ID_DH:
1172
pk_alg = GNUTLS_PK_DH;
1173
bitlen = key->u.a.bitlen;
1174
break;
1175
1176
case ALG_ID_DSA:
1177
pk_alg = GNUTLS_PK_DSA;
1178
bitlen = key->u.a.bitlen;
1179
break;
1180
1181
case ALG_ID_ECDH:
1182
case ALG_ID_ECDSA:
1183
pk_alg = GNUTLS_PK_ECC;
1184
switch (key->u.a.curve_id)
1185
{
1186
case ECC_CURVE_25519:
1187
assert( key->alg_id == ALG_ID_ECDH );
1188
pk_alg = GNUTLS_PK_ECDH_X25519;
1189
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_X25519 );
1190
break;
1191
case ECC_CURVE_P256R1:
1192
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
1193
break;
1194
case ECC_CURVE_P384R1:
1195
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
1196
break;
1197
case ECC_CURVE_P521R1:
1198
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP521R1 );
1199
break;
1200
default:
1201
FIXME( "unsupported ECDH/ECDSA curve %u\n", key->u.a.curve_id );
1202
return STATUS_INVALID_PARAMETER;
1203
}
1204
break;
1205
1206
case ALG_ID_ECDH_P256:
1207
case ALG_ID_ECDSA_P256:
1208
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1209
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
1210
break;
1211
1212
case ALG_ID_ECDH_P384:
1213
case ALG_ID_ECDSA_P384:
1214
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1215
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
1216
break;
1217
1218
case ALG_ID_ECDH_P521:
1219
case ALG_ID_ECDSA_P521:
1220
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1221
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP521R1 );
1222
break;
1223
1224
default:
1225
FIXME( "algorithm %u not supported\n", key->alg_id );
1226
return STATUS_NOT_SUPPORTED;
1227
}
1228
1229
if (key->alg_id == ALG_ID_DH && key_data(key)->a.dh_params)
1230
{
1231
gnutls_keygen_data_st data;
1232
1233
data.type = GNUTLS_KEYGEN_DH;
1234
data.data = (unsigned char *)key_data(key)->a.dh_params;
1235
data.size = 0;
1236
if (!(privkey = create_privkey( pk_alg, bitlen, &data, 1 ))) return STATUS_INTERNAL_ERROR;
1237
}
1238
else if (!(privkey = create_privkey( pk_alg, bitlen, NULL, 0 ))) return STATUS_INTERNAL_ERROR;
1239
1240
if (key->alg_id == ALG_ID_DH && !key_data(key)->a.dh_params &&
1241
!(key_data(key)->a.dh_params = get_dh_params( privkey )))
1242
{
1243
pgnutls_privkey_deinit( privkey );
1244
return STATUS_INTERNAL_ERROR;
1245
}
1246
1247
if (!(pubkey = create_pubkey_from_privkey( privkey )))
1248
{
1249
pgnutls_privkey_deinit( privkey );
1250
return STATUS_INTERNAL_ERROR;
1251
}
1252
1253
key_data(key)->a.privkey = privkey;
1254
key_data(key)->a.pubkey = pubkey;
1255
return STATUS_SUCCESS;
1256
}
1257
1258
static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1259
{
1260
BCRYPT_ECCKEY_BLOB *ecc_blob;
1261
gnutls_ecc_curve_t curve;
1262
gnutls_datum_t x, y, d;
1263
DWORD magic, size;
1264
UCHAR *dst;
1265
int ret;
1266
1267
switch (key->alg_id)
1268
{
1269
case ALG_ID_ECDH:
1270
switch (key->u.a.curve_id)
1271
{
1272
case ECC_CURVE_25519:
1273
magic = BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC;
1274
size = 32;
1275
break;
1276
case ECC_CURVE_P256R1:
1277
magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
1278
size = 32;
1279
break;
1280
case ECC_CURVE_P384R1:
1281
magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC;
1282
size = 48;
1283
break;
1284
case ECC_CURVE_P521R1:
1285
magic = BCRYPT_ECDH_PRIVATE_P521_MAGIC;
1286
size = 66;
1287
break;
1288
default:
1289
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
1290
return STATUS_NOT_IMPLEMENTED;
1291
}
1292
break;
1293
1294
case ALG_ID_ECDH_P256:
1295
magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
1296
size = 32;
1297
break;
1298
1299
case ALG_ID_ECDH_P384:
1300
magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC;
1301
size = 48;
1302
break;
1303
1304
case ALG_ID_ECDH_P521:
1305
magic = BCRYPT_ECDH_PRIVATE_P521_MAGIC;
1306
size = 66;
1307
break;
1308
1309
case ALG_ID_ECDSA:
1310
switch (key->u.a.curve_id)
1311
{
1312
case ECC_CURVE_P256R1:
1313
magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
1314
size = 32;
1315
break;
1316
case ECC_CURVE_P384R1:
1317
magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
1318
size = 48;
1319
break;
1320
case ECC_CURVE_P521R1:
1321
magic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC;
1322
size = 66;
1323
break;
1324
default:
1325
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
1326
return STATUS_NOT_IMPLEMENTED;
1327
}
1328
break;
1329
1330
case ALG_ID_ECDSA_P256:
1331
magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
1332
size = 32;
1333
break;
1334
1335
case ALG_ID_ECDSA_P384:
1336
magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
1337
size = 48;
1338
break;
1339
1340
case ALG_ID_ECDSA_P521:
1341
magic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC;
1342
size = 66;
1343
break;
1344
1345
default:
1346
FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
1347
return STATUS_NOT_IMPLEMENTED;
1348
}
1349
1350
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1351
1352
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
1353
{
1354
pgnutls_perror( ret );
1355
return STATUS_INTERNAL_ERROR;
1356
}
1357
1358
if (curve != GNUTLS_ECC_CURVE_X25519 && curve != GNUTLS_ECC_CURVE_SECP256R1 &&
1359
curve != GNUTLS_ECC_CURVE_SECP384R1 && curve != GNUTLS_ECC_CURVE_SECP521R1)
1360
{
1361
FIXME( "curve %u not supported\n", curve );
1362
free( x.data ); free( y.data ); free( d.data );
1363
return STATUS_NOT_IMPLEMENTED;
1364
}
1365
1366
*ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ) + EXPORT_SIZE( d, size, 1 );
1367
if (len >= *ret_len && buf)
1368
{
1369
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1370
ecc_blob->dwMagic = magic;
1371
ecc_blob->cbKey = size;
1372
1373
dst = (UCHAR *)(ecc_blob + 1);
1374
dst += export_gnutls_datum( dst, size, &x, 1 );
1375
dst += export_gnutls_datum( dst, size, &y, 1 );
1376
export_gnutls_datum( dst, size, &d, 1 );
1377
}
1378
1379
free( x.data ); free( y.data ); free( d.data );
1380
return STATUS_SUCCESS;
1381
}
1382
1383
static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1384
{
1385
BCRYPT_ECCKEY_BLOB *ecc_blob;
1386
gnutls_ecc_curve_t curve;
1387
gnutls_privkey_t handle;
1388
gnutls_datum_t x, y, k;
1389
int ret;
1390
1391
switch (key->alg_id)
1392
{
1393
case ALG_ID_ECDH:
1394
switch (key->u.a.curve_id)
1395
{
1396
case ECC_CURVE_25519: curve = GNUTLS_ECC_CURVE_X25519; break;
1397
case ECC_CURVE_P256R1: curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1398
case ECC_CURVE_P384R1: curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1399
case ECC_CURVE_P521R1: curve = GNUTLS_ECC_CURVE_SECP521R1; break;
1400
default:
1401
FIXME( "curve %u not supported\n", key->u.a.curve_id );
1402
return STATUS_NOT_IMPLEMENTED;
1403
}
1404
break;
1405
1406
case ALG_ID_ECDH_P256:
1407
case ALG_ID_ECDSA_P256:
1408
curve = GNUTLS_ECC_CURVE_SECP256R1;
1409
break;
1410
1411
case ALG_ID_ECDH_P384:
1412
case ALG_ID_ECDSA_P384:
1413
curve = GNUTLS_ECC_CURVE_SECP384R1;
1414
break;
1415
1416
case ALG_ID_ECDH_P521:
1417
case ALG_ID_ECDSA_P521:
1418
curve = GNUTLS_ECC_CURVE_SECP521R1;
1419
break;
1420
1421
default:
1422
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1423
return STATUS_NOT_IMPLEMENTED;
1424
}
1425
1426
if ((ret = pgnutls_privkey_init( &handle )))
1427
{
1428
pgnutls_perror( ret );
1429
return STATUS_INTERNAL_ERROR;
1430
}
1431
1432
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1433
x.data = (unsigned char *)(ecc_blob + 1);
1434
x.size = ecc_blob->cbKey;
1435
y.data = x.data + ecc_blob->cbKey;
1436
y.size = ecc_blob->cbKey;
1437
k.data = y.data + ecc_blob->cbKey;
1438
k.size = ecc_blob->cbKey;
1439
1440
if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1441
{
1442
pgnutls_perror( ret );
1443
pgnutls_privkey_deinit( handle );
1444
return STATUS_INTERNAL_ERROR;
1445
}
1446
1447
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1448
key_data(key)->a.privkey = handle;
1449
return STATUS_SUCCESS;
1450
}
1451
1452
static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1453
{
1454
BCRYPT_RSAKEY_BLOB *rsa_blob;
1455
gnutls_datum_t m, e, d, p, q, u, e1, e2;
1456
ULONG size = len_from_bitlen( key->u.a.bitlen );
1457
BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
1458
UCHAR *dst;
1459
int ret;
1460
1461
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1462
1463
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1464
{
1465
pgnutls_perror( ret );
1466
return STATUS_INTERNAL_ERROR;
1467
}
1468
1469
*ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ) +
1470
EXPORT_SIZE( p, size / 2, 1 ) + EXPORT_SIZE( q, size / 2, 1 );
1471
1472
if (full) *ret_len += EXPORT_SIZE( e1, size / 2, 1 ) + EXPORT_SIZE( e2, size / 2, 1 ) +
1473
EXPORT_SIZE( u, size / 2, 1 ) + EXPORT_SIZE( d, size, 1 );
1474
1475
if (len >= *ret_len && buf)
1476
{
1477
rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1478
rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
1479
rsa_blob->BitLength = key->u.a.bitlen;
1480
1481
dst = (UCHAR *)(rsa_blob + 1);
1482
rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
1483
1484
dst += rsa_blob->cbPublicExp;
1485
rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
1486
1487
dst += rsa_blob->cbModulus;
1488
rsa_blob->cbPrime1 = export_gnutls_datum( dst, size / 2, &p, 1 );
1489
1490
dst += rsa_blob->cbPrime1;
1491
rsa_blob->cbPrime2 = export_gnutls_datum( dst, size / 2, &q, 1 );
1492
1493
if (full)
1494
{
1495
dst += rsa_blob->cbPrime2;
1496
export_gnutls_datum( dst, size / 2, &e1, 1 );
1497
1498
dst += rsa_blob->cbPrime1;
1499
export_gnutls_datum( dst, size / 2, &e2, 1 );
1500
1501
dst += rsa_blob->cbPrime2;
1502
export_gnutls_datum( dst, size / 2, &u, 1 );
1503
1504
dst += rsa_blob->cbPrime1;
1505
export_gnutls_datum( dst, size, &d, 1 );
1506
}
1507
}
1508
1509
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1510
free( e1.data ); free( e2.data );
1511
return STATUS_SUCCESS;
1512
}
1513
1514
static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1515
{
1516
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1517
gnutls_datum_t m, e, p, q;
1518
gnutls_privkey_t handle;
1519
int ret;
1520
1521
if ((ret = pgnutls_privkey_init( &handle )))
1522
{
1523
pgnutls_perror( ret );
1524
return STATUS_INTERNAL_ERROR;
1525
}
1526
1527
e.data = (unsigned char *)(rsa_blob + 1);
1528
e.size = rsa_blob->cbPublicExp;
1529
m.data = e.data + e.size;
1530
m.size = rsa_blob->cbModulus;
1531
p.data = m.data + m.size;
1532
p.size = rsa_blob->cbPrime1;
1533
q.data = p.data + p.size;
1534
q.size = rsa_blob->cbPrime2;
1535
1536
if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1537
{
1538
pgnutls_perror( ret );
1539
pgnutls_privkey_deinit( handle );
1540
return STATUS_INTERNAL_ERROR;
1541
}
1542
1543
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1544
key_data(key)->a.privkey = handle;
1545
return STATUS_SUCCESS;
1546
}
1547
1548
static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1549
{
1550
BLOBHEADER *hdr;
1551
DSSPUBKEY *pubkey;
1552
gnutls_datum_t p, q, g, y, x;
1553
ULONG size = len_from_bitlen( key->u.a.bitlen );
1554
UCHAR *dst;
1555
int ret;
1556
1557
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1558
1559
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1560
{
1561
pgnutls_perror( ret );
1562
return STATUS_INTERNAL_ERROR;
1563
}
1564
1565
if (q.size > 21 || x.size > 21)
1566
{
1567
ERR( "can't export key in this format\n" );
1568
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1569
return STATUS_NOT_SUPPORTED;
1570
}
1571
1572
*ret_len = sizeof(*hdr) + sizeof(*pubkey) + sizeof(key->u.a.dss_seed) +
1573
EXPORT_SIZE( p, size, 1 ) + 20 + EXPORT_SIZE( g, size, 1 ) + 20;
1574
if (len >= *ret_len && buf)
1575
{
1576
hdr = (BLOBHEADER *)buf;
1577
hdr->bType = PRIVATEKEYBLOB;
1578
hdr->bVersion = 2;
1579
hdr->reserved = 0;
1580
hdr->aiKeyAlg = CALG_DSS_SIGN;
1581
1582
pubkey = (DSSPUBKEY *)(hdr + 1);
1583
pubkey->magic = MAGIC_DSS2;
1584
pubkey->bitlen = key->u.a.bitlen;
1585
1586
dst = (UCHAR *)(pubkey + 1);
1587
export_gnutls_datum( dst, size, &p, 1 );
1588
reverse_bytes( dst, size );
1589
dst += size;
1590
1591
export_gnutls_datum( dst, 20, &q, 1 );
1592
reverse_bytes( dst, 20 );
1593
dst += 20;
1594
1595
export_gnutls_datum( dst, size, &g, 1 );
1596
reverse_bytes( dst, size );
1597
dst += size;
1598
1599
export_gnutls_datum( dst, 20, &x, 1 );
1600
reverse_bytes( dst, 20 );
1601
dst += 20;
1602
1603
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1604
}
1605
1606
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1607
return STATUS_SUCCESS;
1608
}
1609
1610
static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1611
{
1612
BLOBHEADER *hdr = (BLOBHEADER *)buf;
1613
DSSPUBKEY *pubkey;
1614
gnutls_privkey_t handle;
1615
gnutls_datum_t p, q, g, x;
1616
unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1617
int i, ret, size;
1618
1619
if ((ret = pgnutls_privkey_init( &handle )))
1620
{
1621
pgnutls_perror( ret );
1622
return STATUS_INTERNAL_ERROR;
1623
}
1624
1625
pubkey = (DSSPUBKEY *)(hdr + 1);
1626
if ((size = len_from_bitlen( pubkey->bitlen )) > sizeof(p_data))
1627
{
1628
FIXME( "size %u not supported\n", size );
1629
pgnutls_privkey_deinit( handle );
1630
return STATUS_NOT_SUPPORTED;
1631
}
1632
data = (unsigned char *)(pubkey + 1);
1633
1634
p.data = p_data;
1635
p.size = size;
1636
for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1637
data += p.size;
1638
1639
q.data = q_data;
1640
q.size = sizeof(q_data);
1641
for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1642
data += q.size;
1643
1644
g.data = g_data;
1645
g.size = size;
1646
for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1647
data += g.size;
1648
1649
x.data = x_data;
1650
x.size = sizeof(x_data);
1651
for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1652
data += x.size;
1653
1654
if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1655
{
1656
pgnutls_perror( ret );
1657
pgnutls_privkey_deinit( handle );
1658
return STATUS_INTERNAL_ERROR;
1659
}
1660
1661
memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1662
1663
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1664
key_data(key)->a.privkey = handle;
1665
return STATUS_SUCCESS;
1666
}
1667
1668
static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1669
{
1670
BCRYPT_ECCKEY_BLOB *ecc_blob;
1671
gnutls_ecc_curve_t curve;
1672
gnutls_datum_t x, y;
1673
gnutls_pubkey_t handle;
1674
int ret;
1675
1676
switch (key->alg_id)
1677
{
1678
case ALG_ID_ECDH:
1679
switch (key->u.a.curve_id)
1680
{
1681
case ECC_CURVE_25519: curve = GNUTLS_ECC_CURVE_X25519; break;
1682
case ECC_CURVE_P256R1: curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1683
case ECC_CURVE_P384R1: curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1684
case ECC_CURVE_P521R1: curve = GNUTLS_ECC_CURVE_SECP521R1; break;
1685
default:
1686
FIXME( "curve %u not supported\n", key->u.a.curve_id );
1687
return STATUS_NOT_IMPLEMENTED;
1688
}
1689
break;
1690
1691
case ALG_ID_ECDH_P256:
1692
case ALG_ID_ECDSA_P256:
1693
curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1694
1695
case ALG_ID_ECDH_P384:
1696
case ALG_ID_ECDSA_P384:
1697
curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1698
1699
case ALG_ID_ECDH_P521:
1700
case ALG_ID_ECDSA_P521:
1701
curve = GNUTLS_ECC_CURVE_SECP521R1; break;
1702
1703
default:
1704
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1705
return STATUS_NOT_IMPLEMENTED;
1706
}
1707
1708
if ((ret = pgnutls_pubkey_init( &handle )))
1709
{
1710
pgnutls_perror( ret );
1711
return STATUS_INTERNAL_ERROR;
1712
}
1713
1714
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1715
x.data = buf + sizeof(*ecc_blob);
1716
x.size = ecc_blob->cbKey;
1717
y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1718
y.size = ecc_blob->cbKey;
1719
1720
if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1721
{
1722
pgnutls_perror( ret );
1723
pgnutls_pubkey_deinit( handle );
1724
return STATUS_INTERNAL_ERROR;
1725
}
1726
1727
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1728
key_data(key)->a.pubkey = handle;
1729
return STATUS_SUCCESS;
1730
}
1731
1732
static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1733
{
1734
BCRYPT_RSAKEY_BLOB *rsa_blob;
1735
gnutls_pubkey_t handle;
1736
gnutls_datum_t m, e;
1737
int ret;
1738
1739
if ((ret = pgnutls_pubkey_init( &handle )))
1740
{
1741
pgnutls_perror( ret );
1742
return STATUS_INTERNAL_ERROR;
1743
}
1744
1745
rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1746
e.data = buf + sizeof(*rsa_blob);
1747
e.size = rsa_blob->cbPublicExp;
1748
m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1749
m.size = rsa_blob->cbModulus;
1750
1751
if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1752
{
1753
pgnutls_perror( ret );
1754
pgnutls_pubkey_deinit( handle );
1755
return STATUS_INTERNAL_ERROR;
1756
}
1757
1758
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1759
key_data(key)->a.pubkey = handle;
1760
return STATUS_SUCCESS;
1761
}
1762
1763
static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1764
{
1765
BCRYPT_DSA_KEY_BLOB *dsa_blob;
1766
gnutls_datum_t p, q, g, y;
1767
gnutls_pubkey_t handle;
1768
int ret;
1769
1770
if ((ret = pgnutls_pubkey_init( &handle )))
1771
{
1772
pgnutls_perror( ret );
1773
return STATUS_INTERNAL_ERROR;
1774
}
1775
1776
dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1777
p.data = buf + sizeof(*dsa_blob);
1778
p.size = dsa_blob->cbKey;
1779
q.data = dsa_blob->q;
1780
q.size = sizeof(dsa_blob->q);
1781
g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1782
g.size = dsa_blob->cbKey;
1783
y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1784
y.size = dsa_blob->cbKey;
1785
1786
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1787
{
1788
pgnutls_perror( ret );
1789
pgnutls_pubkey_deinit( handle );
1790
return STATUS_INTERNAL_ERROR;
1791
}
1792
1793
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1794
key_data(key)->a.pubkey = handle;
1795
return STATUS_SUCCESS;
1796
}
1797
1798
static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1799
{
1800
BLOBHEADER *hdr;
1801
DSSPUBKEY *pubkey;
1802
gnutls_datum_t p, q, g, y;
1803
gnutls_pubkey_t handle;
1804
unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1805
int i, ret, size;
1806
1807
if ((ret = pgnutls_pubkey_init( &handle )))
1808
{
1809
pgnutls_perror( ret );
1810
return STATUS_INTERNAL_ERROR;
1811
}
1812
1813
hdr = (BLOBHEADER *)buf;
1814
pubkey = (DSSPUBKEY *)(hdr + 1);
1815
size = len_from_bitlen( pubkey->bitlen );
1816
data = (unsigned char *)(pubkey + 1);
1817
1818
p.data = p_data;
1819
p.size = size;
1820
for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1821
data += p.size;
1822
1823
q.data = q_data;
1824
q.size = sizeof(q_data);
1825
for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1826
data += q.size;
1827
1828
g.data = g_data;
1829
g.size = size;
1830
for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1831
data += g.size;
1832
1833
y.data = y_data;
1834
y.size = sizeof(y_data);
1835
for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1836
1837
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1838
{
1839
pgnutls_perror( ret );
1840
pgnutls_pubkey_deinit( handle );
1841
return STATUS_INTERNAL_ERROR;
1842
}
1843
1844
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1845
key_data(key)->a.pubkey = handle;
1846
return STATUS_SUCCESS;
1847
}
1848
1849
static NTSTATUS key_export_dh_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1850
{
1851
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1852
ULONG size = len_from_bitlen( key->u.a.bitlen );
1853
gnutls_dh_params_t params;
1854
gnutls_datum_t p, g, y;
1855
UCHAR *dst;
1856
int ret = GNUTLS_E_INVALID_REQUEST;
1857
1858
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1859
{
1860
pgnutls_perror( ret );
1861
return STATUS_INTERNAL_ERROR;
1862
}
1863
1864
if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key)->a.pubkey, params, &y, 0 )))
1865
{
1866
pgnutls_perror( ret );
1867
pgnutls_dh_params_deinit( params );
1868
return STATUS_INTERNAL_ERROR;
1869
}
1870
1871
if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1872
{
1873
pgnutls_perror( ret );
1874
free( y.data );
1875
pgnutls_dh_params_deinit( params );
1876
return STATUS_INTERNAL_ERROR;
1877
}
1878
1879
*ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) + EXPORT_SIZE(y, size, 1);
1880
if (len >= *ret_len && buf)
1881
{
1882
dst = (UCHAR *)(dh_blob + 1);
1883
dst += export_gnutls_datum( dst, size, &p, 1 );
1884
dst += export_gnutls_datum( dst, size, &g, 1 );
1885
dst += export_gnutls_datum( dst, size, &y, 1 );
1886
1887
dh_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
1888
dh_blob->cbKey = size;
1889
}
1890
1891
free( p.data ); free( g.data ); free( y.data );
1892
return STATUS_SUCCESS;
1893
}
1894
1895
static NTSTATUS key_export_dh( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1896
{
1897
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1898
gnutls_datum_t p, g, y, x;
1899
gnutls_dh_params_t params;
1900
ULONG size = len_from_bitlen( key->u.a.bitlen );
1901
UCHAR *dst;
1902
int ret;
1903
1904
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1905
1906
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1907
{
1908
pgnutls_perror( ret );
1909
return STATUS_INTERNAL_ERROR;
1910
}
1911
1912
if ((ret = pgnutls_privkey_export_dh_raw( key_data(key)->a.privkey, params, &y, &x, 0 )))
1913
{
1914
pgnutls_perror( ret );
1915
pgnutls_dh_params_deinit( params );
1916
return STATUS_INTERNAL_ERROR;
1917
}
1918
1919
if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1920
{
1921
pgnutls_perror( ret );
1922
free( y.data ); free( x.data );
1923
pgnutls_dh_params_deinit( params );
1924
return STATUS_INTERNAL_ERROR;
1925
}
1926
1927
*ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) +
1928
EXPORT_SIZE(y, size, 1) + EXPORT_SIZE(x, size, 1);
1929
if (len >= *ret_len && buf)
1930
{
1931
dst = (UCHAR *)(dh_blob + 1);
1932
dst += export_gnutls_datum( dst, size, &p, 1 );
1933
dst += export_gnutls_datum( dst, size, &g, 1 );
1934
dst += export_gnutls_datum( dst, size, &y, 1 );
1935
dst += export_gnutls_datum( dst, size, &x, 1 );
1936
1937
dh_blob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
1938
dh_blob->cbKey = size;
1939
}
1940
1941
free( p.data ); free( g.data ); free( y.data ); free( x.data );
1942
pgnutls_dh_params_deinit( params );
1943
return STATUS_SUCCESS;
1944
}
1945
1946
static NTSTATUS key_export_dh_params( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1947
{
1948
BCRYPT_DH_PARAMETER_HEADER *hdr = (BCRYPT_DH_PARAMETER_HEADER *)buf;
1949
unsigned int size = sizeof(*hdr) + len_from_bitlen( key->u.a.bitlen ) * 2;
1950
gnutls_datum_t p, g;
1951
NTSTATUS status = STATUS_SUCCESS;
1952
UCHAR *dst;
1953
int ret;
1954
1955
if (!key_data(key)->a.dh_params) return STATUS_INVALID_PARAMETER;
1956
1957
if ((ret = pgnutls_dh_params_export_raw( key_data(key)->a.dh_params, &p, &g, NULL )))
1958
{
1959
pgnutls_perror( ret );
1960
return STATUS_INTERNAL_ERROR;
1961
}
1962
1963
*ret_len = size;
1964
if (len < size) status = STATUS_BUFFER_TOO_SMALL;
1965
else if (buf)
1966
{
1967
hdr->cbLength = size;
1968
hdr->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
1969
hdr->cbKeyLength = len_from_bitlen( key->u.a.bitlen );
1970
1971
dst = (UCHAR *)(hdr + 1);
1972
dst += export_gnutls_datum( dst, hdr->cbKeyLength, &p, 1 );
1973
dst += export_gnutls_datum( dst, hdr->cbKeyLength, &g, 1 );
1974
}
1975
1976
free( p.data ); free( g.data );
1977
return status;
1978
}
1979
1980
static NTSTATUS key_asymmetric_export( void *args )
1981
{
1982
const struct key_asymmetric_export_params *params = args;
1983
struct key *key = params->key;
1984
unsigned flags = params->flags;
1985
1986
if (!(key->u.a.flags & KEY_FLAG_FINALIZED)) return STATUS_INVALID_HANDLE;
1987
1988
switch (key->alg_id)
1989
{
1990
case ALG_ID_ECDH:
1991
case ALG_ID_ECDH_P256:
1992
case ALG_ID_ECDH_P384:
1993
case ALG_ID_ECDH_P521:
1994
case ALG_ID_ECDSA:
1995
case ALG_ID_ECDSA_P256:
1996
case ALG_ID_ECDSA_P384:
1997
case ALG_ID_ECDSA_P521:
1998
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1999
return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
2000
return key_export_ecc( key, params->buf, params->len, params->ret_len );
2001
2002
case ALG_ID_RSA:
2003
case ALG_ID_RSA_SIGN:
2004
if (flags & KEY_EXPORT_FLAG_PUBLIC)
2005
return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
2006
return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
2007
2008
case ALG_ID_DSA:
2009
if (flags & KEY_EXPORT_FLAG_PUBLIC)
2010
{
2011
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2012
return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
2013
return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
2014
}
2015
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2016
return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
2017
return STATUS_NOT_IMPLEMENTED;
2018
2019
case ALG_ID_DH:
2020
if (flags & KEY_EXPORT_FLAG_DH_PARAMETERS)
2021
return key_export_dh_params( key, params->buf, params->len, params->ret_len );
2022
if (flags & KEY_EXPORT_FLAG_PUBLIC)
2023
return key_export_dh_public( key, params->buf, params->len, params->ret_len );
2024
return key_export_dh( key, params->buf, params->len, params->ret_len );
2025
2026
default:
2027
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2028
return STATUS_NOT_IMPLEMENTED;
2029
}
2030
}
2031
2032
static NTSTATUS key_import_dh_public( struct key *key, UCHAR *buf, ULONG len )
2033
{
2034
BCRYPT_DH_KEY_BLOB *dh_blob;
2035
gnutls_dh_params_t params;
2036
gnutls_datum_t p, g, y;
2037
gnutls_pubkey_t handle;
2038
int ret;
2039
2040
if ((ret = pgnutls_pubkey_init( &handle )))
2041
{
2042
pgnutls_perror( ret );
2043
return STATUS_INTERNAL_ERROR;
2044
}
2045
2046
if ((ret = pgnutls_dh_params_init( &params )) < 0)
2047
{
2048
pgnutls_perror( ret );
2049
pgnutls_pubkey_deinit( handle );
2050
return STATUS_INTERNAL_ERROR;
2051
}
2052
2053
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
2054
p.data = buf + sizeof(*dh_blob);
2055
p.size = dh_blob->cbKey;
2056
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
2057
g.size = dh_blob->cbKey;
2058
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
2059
y.size = dh_blob->cbKey;
2060
2061
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
2062
{
2063
pgnutls_perror( ret );
2064
pgnutls_dh_params_deinit( params );
2065
pgnutls_pubkey_deinit( handle );
2066
return STATUS_INTERNAL_ERROR;
2067
}
2068
2069
if ((ret = pgnutls_pubkey_import_dh_raw( handle, params, &y )))
2070
{
2071
pgnutls_perror( ret );
2072
pgnutls_dh_params_deinit( params );
2073
pgnutls_pubkey_deinit( handle );
2074
return STATUS_INTERNAL_ERROR;
2075
}
2076
2077
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2078
key_data(key)->a.pubkey = handle;
2079
2080
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2081
key_data(key)->a.dh_params = params;
2082
return STATUS_SUCCESS;
2083
}
2084
2085
static NTSTATUS key_import_dh( struct key *key, UCHAR *buf, ULONG len )
2086
{
2087
BCRYPT_DH_KEY_BLOB *dh_blob;
2088
gnutls_dh_params_t params;
2089
gnutls_datum_t p, g, y, x;
2090
gnutls_privkey_t handle;
2091
int ret;
2092
2093
if ((ret = pgnutls_privkey_init( &handle )))
2094
{
2095
pgnutls_perror( ret );
2096
return STATUS_INTERNAL_ERROR;
2097
}
2098
2099
if ((ret = pgnutls_dh_params_init( &params )) < 0)
2100
{
2101
pgnutls_perror( ret );
2102
pgnutls_privkey_deinit( handle );
2103
return STATUS_INTERNAL_ERROR;
2104
}
2105
2106
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
2107
p.data = buf + sizeof(*dh_blob);
2108
p.size = dh_blob->cbKey;
2109
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
2110
g.size = dh_blob->cbKey;
2111
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
2112
y.size = dh_blob->cbKey;
2113
x.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 3;
2114
x.size = dh_blob->cbKey;
2115
2116
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
2117
{
2118
pgnutls_perror( ret );
2119
pgnutls_dh_params_deinit( params );
2120
pgnutls_privkey_deinit( handle );
2121
return STATUS_INTERNAL_ERROR;
2122
}
2123
2124
if ((ret = pgnutls_privkey_import_dh_raw( handle, params, &y, &x )))
2125
{
2126
pgnutls_perror( ret );
2127
pgnutls_dh_params_deinit( params );
2128
pgnutls_privkey_deinit( handle );
2129
return STATUS_INTERNAL_ERROR;
2130
}
2131
2132
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2133
key_data(key)->a.privkey = handle;
2134
2135
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2136
key_data(key)->a.dh_params = params;
2137
return STATUS_SUCCESS;
2138
}
2139
2140
static NTSTATUS key_import_dh_params( struct key *key, UCHAR *buf, ULONG len )
2141
{
2142
BCRYPT_DH_PARAMETER_HEADER *dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buf;
2143
gnutls_dh_params_t params;
2144
gnutls_datum_t p, g;
2145
int ret;
2146
2147
if ((ret = pgnutls_dh_params_init( &params )))
2148
{
2149
pgnutls_perror( ret );
2150
return STATUS_INTERNAL_ERROR;
2151
}
2152
2153
p.data = (unsigned char *)(dh_header + 1);
2154
p.size = dh_header->cbKeyLength;
2155
g.data = p.data + dh_header->cbKeyLength;
2156
g.size = dh_header->cbKeyLength;
2157
2158
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )))
2159
{
2160
pgnutls_perror( ret );
2161
pgnutls_dh_params_deinit( params );
2162
return STATUS_INTERNAL_ERROR;
2163
}
2164
2165
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2166
key_data(key)->a.dh_params = params;
2167
return STATUS_SUCCESS;
2168
}
2169
2170
static NTSTATUS key_asymmetric_import( void *args )
2171
{
2172
const struct key_asymmetric_import_params *params = args;
2173
struct key *key = params->key;
2174
unsigned flags = params->flags;
2175
gnutls_pubkey_t pubkey;
2176
NTSTATUS ret;
2177
2178
switch (key->alg_id)
2179
{
2180
case ALG_ID_ECDH:
2181
case ALG_ID_ECDH_P256:
2182
case ALG_ID_ECDH_P384:
2183
case ALG_ID_ECDH_P521:
2184
case ALG_ID_ECDSA:
2185
case ALG_ID_ECDSA_P256:
2186
case ALG_ID_ECDSA_P384:
2187
case ALG_ID_ECDSA_P521:
2188
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2189
return key_import_ecc_public( key, params->buf, params->len );
2190
ret = key_import_ecc( key, params->buf, params->len );
2191
break;
2192
2193
case ALG_ID_RSA:
2194
case ALG_ID_RSA_SIGN:
2195
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2196
return key_import_rsa_public( key, params->buf, params->len );
2197
ret = key_import_rsa( key, params->buf, params->len );
2198
break;
2199
2200
case ALG_ID_DSA:
2201
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2202
{
2203
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2204
return key_import_dsa_capi_public( key, params->buf, params->len );
2205
return key_import_dsa_public( key, params->buf, params->len );
2206
}
2207
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2208
{
2209
ret = key_import_dsa_capi( key, params->buf, params->len );
2210
break;
2211
}
2212
FIXME( "DSA private key not supported\n" );
2213
return STATUS_NOT_IMPLEMENTED;
2214
2215
case ALG_ID_DH:
2216
if (flags & KEY_IMPORT_FLAG_DH_PARAMETERS)
2217
return key_import_dh_params( key, params->buf, params->len );
2218
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2219
return key_import_dh_public( key, params->buf, params->len );
2220
ret = key_import_dh( key, params->buf, params->len );
2221
break;
2222
2223
default:
2224
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2225
return STATUS_NOT_IMPLEMENTED;
2226
}
2227
2228
if (ret) return ret;
2229
2230
if ((ret = pgnutls_pubkey_init( &pubkey )))
2231
{
2232
pgnutls_perror( ret );
2233
return STATUS_INTERNAL_ERROR;
2234
}
2235
2236
if (pgnutls_pubkey_import_privkey( pubkey, key_data(params->key)->a.privkey, 0, 0 ))
2237
{
2238
/* Imported private key may be legitimately missing public key, so ignore the failure here. */
2239
pgnutls_pubkey_deinit( pubkey );
2240
}
2241
else
2242
{
2243
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2244
key_data(key)->a.pubkey = pubkey;
2245
}
2246
return STATUS_SUCCESS;
2247
}
2248
2249
static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
2250
gnutls_datum_t *gnutls_signature )
2251
{
2252
struct buffer buffer;
2253
DWORD r_len = signature_len / 2;
2254
DWORD s_len = r_len;
2255
BYTE *r = signature;
2256
BYTE *s = signature + r_len;
2257
2258
buffer_init( &buffer );
2259
buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
2260
if (buffer.error)
2261
{
2262
buffer_free( &buffer );
2263
return STATUS_NO_MEMORY;
2264
}
2265
2266
gnutls_signature->data = buffer.buffer;
2267
gnutls_signature->size = buffer.pos;
2268
return STATUS_SUCCESS;
2269
}
2270
2271
static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
2272
gnutls_datum_t *gnutls_signature )
2273
{
2274
gnutls_signature->data = signature;
2275
gnutls_signature->size = signature_len;
2276
return STATUS_SUCCESS;
2277
}
2278
2279
static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
2280
gnutls_datum_t *gnutls_signature )
2281
{
2282
switch (key->alg_id)
2283
{
2284
case ALG_ID_ECDSA_P256:
2285
case ALG_ID_ECDSA_P384:
2286
case ALG_ID_ECDSA_P521:
2287
case ALG_ID_DSA:
2288
return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
2289
2290
case ALG_ID_RSA:
2291
case ALG_ID_RSA_SIGN:
2292
return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
2293
2294
default:
2295
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2296
return STATUS_NOT_IMPLEMENTED;
2297
}
2298
}
2299
2300
static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
2301
{
2302
if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
2303
if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
2304
if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
2305
if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
2306
if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
2307
if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
2308
return GNUTLS_DIG_UNKNOWN;
2309
}
2310
2311
static NTSTATUS pubkey_set_rsa_pss_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2312
{
2313
gnutls_x509_spki_t spki;
2314
int ret;
2315
2316
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2317
{
2318
pgnutls_perror( ret );
2319
return STATUS_INTERNAL_ERROR;
2320
}
2321
pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2322
ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2323
pgnutls_x509_spki_deinit( spki );
2324
if (ret < 0)
2325
{
2326
pgnutls_perror( ret );
2327
return STATUS_INTERNAL_ERROR;
2328
}
2329
return STATUS_SUCCESS;
2330
}
2331
2332
static NTSTATUS key_asymmetric_verify( void *args )
2333
{
2334
#ifdef GNUTLS_VERIFY_ALLOW_BROKEN
2335
unsigned int verify_flags = GNUTLS_VERIFY_ALLOW_BROKEN;
2336
#else
2337
unsigned int verify_flags = 0;
2338
#endif
2339
const struct key_asymmetric_verify_params *params = args;
2340
struct key *key = params->key;
2341
unsigned flags = params->flags;
2342
gnutls_digest_algorithm_t hash_alg;
2343
gnutls_sign_algorithm_t sign_alg;
2344
gnutls_datum_t gnutls_hash, gnutls_signature;
2345
gnutls_pk_algorithm_t pk_alg;
2346
NTSTATUS status;
2347
int ret;
2348
2349
switch (key->alg_id)
2350
{
2351
case ALG_ID_ECDSA_P256:
2352
case ALG_ID_ECDSA_P384:
2353
case ALG_ID_ECDSA_P521:
2354
{
2355
if (flags) FIXME( "flags %#x not supported\n", flags );
2356
2357
/* only the hash size must match, not the actual hash function */
2358
switch (params->hash_len)
2359
{
2360
case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2361
case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2362
case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2363
2364
default:
2365
FIXME( "hash size %u not yet supported\n", params->hash_len );
2366
return STATUS_INVALID_SIGNATURE;
2367
}
2368
pk_alg = GNUTLS_PK_ECC;
2369
break;
2370
}
2371
case ALG_ID_RSA:
2372
case ALG_ID_RSA_SIGN:
2373
{
2374
if (flags & BCRYPT_PAD_PKCS1)
2375
{
2376
BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
2377
2378
if (!info) return STATUS_INVALID_PARAMETER;
2379
if (!info->pszAlgId)
2380
{
2381
hash_alg = GNUTLS_DIG_UNKNOWN;
2382
verify_flags |= GNUTLS_VERIFY_USE_TLS1_RSA;
2383
}
2384
else if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2385
{
2386
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2387
return STATUS_NOT_SUPPORTED;
2388
}
2389
pk_alg = GNUTLS_PK_RSA;
2390
}
2391
else if (flags & BCRYPT_PAD_PSS)
2392
{
2393
BCRYPT_PSS_PADDING_INFO *info = params->padding;
2394
2395
if (!info) return STATUS_INVALID_PARAMETER;
2396
if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
2397
if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2398
{
2399
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2400
return STATUS_NOT_SUPPORTED;
2401
}
2402
if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status;
2403
pk_alg = GNUTLS_PK_RSA_PSS;
2404
}
2405
else return STATUS_INVALID_PARAMETER;
2406
break;
2407
}
2408
case ALG_ID_DSA:
2409
{
2410
if (flags) FIXME( "flags %#x not supported\n", flags );
2411
if (params->hash_len != 20)
2412
{
2413
FIXME( "hash size %u not supported\n", params->hash_len );
2414
return STATUS_INVALID_PARAMETER;
2415
}
2416
hash_alg = GNUTLS_DIG_SHA1;
2417
pk_alg = GNUTLS_PK_DSA;
2418
break;
2419
}
2420
default:
2421
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2422
return STATUS_NOT_IMPLEMENTED;
2423
}
2424
2425
if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
2426
{
2427
FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
2428
return STATUS_NOT_IMPLEMENTED;
2429
}
2430
2431
if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
2432
return status;
2433
2434
gnutls_hash.data = params->hash;
2435
gnutls_hash.size = params->hash_len;
2436
2437
ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, verify_flags, &gnutls_hash, &gnutls_signature );
2438
if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
2439
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
2440
}
2441
2442
static unsigned int get_signature_length( enum alg_id id )
2443
{
2444
switch (id)
2445
{
2446
case ALG_ID_ECDSA_P256: return 64;
2447
case ALG_ID_ECDSA_P384: return 96;
2448
case ALG_ID_ECDSA_P521: return 132;
2449
case ALG_ID_DSA: return 40;
2450
default:
2451
FIXME( "unhandled algorithm %u\n", id );
2452
return 0;
2453
}
2454
}
2455
2456
static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
2457
UCHAR *output, ULONG output_len, ULONG *ret_len )
2458
{
2459
switch (type)
2460
{
2461
case ALG_ID_RSA:
2462
case ALG_ID_RSA_SIGN:
2463
{
2464
*ret_len = signature.size;
2465
if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
2466
if (output) memcpy( output, signature.data, signature.size );
2467
return STATUS_SUCCESS;
2468
}
2469
case ALG_ID_ECDSA_P256:
2470
case ALG_ID_ECDSA_P384:
2471
case ALG_ID_ECDSA_P521:
2472
case ALG_ID_DSA:
2473
{
2474
int err;
2475
unsigned int sig_len = get_signature_length( type );
2476
gnutls_datum_t r, s; /* format as r||s */
2477
2478
if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
2479
{
2480
pgnutls_perror( err );
2481
return STATUS_INTERNAL_ERROR;
2482
}
2483
2484
*ret_len = sig_len;
2485
if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
2486
2487
if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
2488
{
2489
ERR( "we didn't get a correct signature\n" );
2490
return STATUS_INTERNAL_ERROR;
2491
}
2492
2493
if (output)
2494
{
2495
export_gnutls_datum( output, sig_len / 2, &r, 1 );
2496
export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
2497
}
2498
2499
free( r.data ); free( s.data );
2500
return STATUS_SUCCESS;
2501
}
2502
default:
2503
return STATUS_INTERNAL_ERROR;
2504
}
2505
}
2506
2507
static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2508
{
2509
gnutls_x509_spki_t spki;
2510
int ret;
2511
2512
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2513
{
2514
pgnutls_perror( ret );
2515
return STATUS_INTERNAL_ERROR;
2516
}
2517
pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2518
ret = pgnutls_privkey_set_spki( key, spki, 0 );
2519
pgnutls_x509_spki_deinit( spki );
2520
if (ret < 0)
2521
{
2522
pgnutls_perror( ret );
2523
return STATUS_INTERNAL_ERROR;
2524
}
2525
return STATUS_SUCCESS;
2526
}
2527
2528
static NTSTATUS key_asymmetric_sign( void *args )
2529
{
2530
const struct key_asymmetric_sign_params *params = args;
2531
struct key *key = params->key;
2532
unsigned int flags = params->flags, gnutls_flags = 0;
2533
gnutls_datum_t hash, signature;
2534
gnutls_digest_algorithm_t hash_alg;
2535
NTSTATUS status;
2536
int ret;
2537
2538
if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384 || key->alg_id == ALG_ID_ECDSA_P521)
2539
{
2540
/* With ECDSA, we find the digest algorithm from the hash length, and verify it */
2541
switch (params->input_len)
2542
{
2543
case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2544
case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2545
case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2546
case 64: hash_alg = GNUTLS_DIG_SHA512; break;
2547
2548
default:
2549
FIXME( "hash size %u not yet supported\n", params->input_len );
2550
return STATUS_INVALID_PARAMETER;
2551
}
2552
2553
if (flags == BCRYPT_PAD_PKCS1)
2554
{
2555
BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2556
if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
2557
{
2558
WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
2559
return STATUS_INVALID_PARAMETER;
2560
}
2561
}
2562
}
2563
else if (key->alg_id == ALG_ID_DSA)
2564
{
2565
if (flags) FIXME( "flags %#x not supported\n", flags );
2566
if (params->input_len != 20)
2567
{
2568
FIXME( "hash size %u not supported\n", params->input_len );
2569
return STATUS_INVALID_PARAMETER;
2570
}
2571
hash_alg = GNUTLS_DIG_SHA1;
2572
}
2573
else if (flags == BCRYPT_PAD_PKCS1)
2574
{
2575
BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2576
2577
if (!pad)
2578
{
2579
WARN( "padding info not found\n" );
2580
return STATUS_INVALID_PARAMETER;
2581
}
2582
if (!pad->pszAlgId) hash_alg = GNUTLS_DIG_UNKNOWN;
2583
else if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2584
{
2585
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2586
return STATUS_NOT_SUPPORTED;
2587
}
2588
}
2589
else if (flags == BCRYPT_PAD_PSS)
2590
{
2591
BCRYPT_PSS_PADDING_INFO *pad = params->padding;
2592
2593
if (!pad || !pad->pszAlgId)
2594
{
2595
WARN( "padding info not found\n" );
2596
return STATUS_INVALID_PARAMETER;
2597
}
2598
if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
2599
{
2600
FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id );
2601
return STATUS_NOT_SUPPORTED;
2602
}
2603
if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2604
{
2605
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2606
return STATUS_NOT_SUPPORTED;
2607
}
2608
2609
if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status;
2610
gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS;
2611
}
2612
else if (!flags)
2613
{
2614
WARN( "invalid flags %#x\n", flags );
2615
return STATUS_INVALID_PARAMETER;
2616
}
2617
else
2618
{
2619
FIXME( "flags %#x not implemented\n", flags );
2620
return STATUS_NOT_IMPLEMENTED;
2621
}
2622
2623
if (!params->output)
2624
{
2625
*params->ret_len = len_from_bitlen( key->u.a.bitlen );
2626
return STATUS_SUCCESS;
2627
}
2628
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
2629
2630
hash.data = params->input;
2631
hash.size = params->input_len;
2632
2633
signature.data = NULL;
2634
signature.size = 0;
2635
2636
if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature )))
2637
{
2638
pgnutls_perror( ret );
2639
return STATUS_INTERNAL_ERROR;
2640
}
2641
2642
status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
2643
free( signature.data );
2644
return status;
2645
}
2646
2647
static NTSTATUS key_asymmetric_destroy( void *args )
2648
{
2649
struct key *key = args;
2650
2651
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2652
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2653
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2654
return STATUS_SUCCESS;
2655
}
2656
2657
static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy )
2658
{
2659
gnutls_privkey_t privkey;
2660
int ret;
2661
2662
if ((ret = pgnutls_privkey_init( &privkey )))
2663
{
2664
pgnutls_perror( ret );
2665
return STATUS_INTERNAL_ERROR;
2666
}
2667
2668
switch (key_orig->alg_id)
2669
{
2670
case ALG_ID_RSA:
2671
case ALG_ID_RSA_SIGN:
2672
{
2673
gnutls_datum_t m, e, d, p, q, u, e1, e2;
2674
2675
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
2676
break;
2677
ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
2678
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
2679
free( e1.data ); free( e2.data );
2680
break;
2681
}
2682
case ALG_ID_DSA:
2683
{
2684
gnutls_datum_t p, q, g, y, x;
2685
2686
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x ))) break;
2687
ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
2688
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
2689
if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2690
break;
2691
}
2692
case ALG_ID_ECDH:
2693
case ALG_ID_ECDH_P256:
2694
case ALG_ID_ECDH_P384:
2695
case ALG_ID_ECDH_P521:
2696
case ALG_ID_ECDSA:
2697
case ALG_ID_ECDSA_P256:
2698
case ALG_ID_ECDSA_P384:
2699
case ALG_ID_ECDSA_P521:
2700
{
2701
gnutls_ecc_curve_t curve;
2702
gnutls_datum_t x, y, k;
2703
2704
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k ))) break;
2705
ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
2706
free( x.data ); free( y.data ); free( k.data );
2707
break;
2708
}
2709
case ALG_ID_DH:
2710
{
2711
gnutls_dh_params_t params;
2712
gnutls_datum_t y, x;
2713
2714
if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2715
if ((ret = pgnutls_privkey_export_dh_raw( key_data(key_orig)->a.privkey, params, &y, &x, 0 )) < 0)
2716
{
2717
pgnutls_dh_params_deinit( params );
2718
break;
2719
}
2720
ret = pgnutls_privkey_import_dh_raw( privkey, params, &y, &x );
2721
pgnutls_dh_params_deinit( params );
2722
free( x.data ); free( y.data );
2723
break;
2724
}
2725
default:
2726
ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2727
pgnutls_privkey_deinit( privkey );
2728
return STATUS_INTERNAL_ERROR;
2729
}
2730
2731
if (ret < 0)
2732
{
2733
pgnutls_perror( ret );
2734
pgnutls_privkey_deinit( privkey );
2735
return STATUS_INTERNAL_ERROR;
2736
}
2737
2738
key_data(key_copy)->a.privkey = privkey;
2739
return STATUS_SUCCESS;
2740
}
2741
2742
static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy )
2743
{
2744
gnutls_pubkey_t pubkey;
2745
int ret;
2746
2747
if ((ret = pgnutls_pubkey_init( &pubkey )))
2748
{
2749
pgnutls_perror( ret );
2750
return STATUS_INTERNAL_ERROR;
2751
}
2752
2753
switch (key_orig->alg_id)
2754
{
2755
case ALG_ID_RSA:
2756
case ALG_ID_RSA_SIGN:
2757
{
2758
gnutls_datum_t m, e;
2759
2760
if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e ))) break;
2761
ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e );
2762
free( m.data ); free( e.data );
2763
break;
2764
}
2765
case ALG_ID_DSA:
2766
{
2767
gnutls_datum_t p, q, g, y;
2768
2769
if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y ))) break;
2770
ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y );
2771
free( p.data ); free( q.data ); free( g.data ); free( y.data );
2772
if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2773
break;
2774
}
2775
case ALG_ID_ECDH:
2776
case ALG_ID_ECDH_P256:
2777
case ALG_ID_ECDH_P384:
2778
case ALG_ID_ECDH_P521:
2779
case ALG_ID_ECDSA:
2780
case ALG_ID_ECDSA_P256:
2781
case ALG_ID_ECDSA_P384:
2782
case ALG_ID_ECDSA_P521:
2783
{
2784
gnutls_ecc_curve_t curve;
2785
gnutls_datum_t x, y;
2786
2787
if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y ))) break;
2788
ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y );
2789
free( x.data ); free( y.data );
2790
break;
2791
}
2792
case ALG_ID_DH:
2793
{
2794
gnutls_dh_params_t params;
2795
gnutls_datum_t y;
2796
2797
if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2798
if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key_orig)->a.pubkey, params, &y, 0 )) < 0)
2799
{
2800
pgnutls_dh_params_deinit( params );
2801
break;
2802
}
2803
ret = pgnutls_pubkey_import_dh_raw( pubkey, params, &y );
2804
pgnutls_dh_params_deinit( params );
2805
free( y.data );
2806
break;
2807
}
2808
default:
2809
ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2810
pgnutls_pubkey_deinit( pubkey );
2811
return STATUS_INTERNAL_ERROR;
2812
}
2813
2814
if (ret < 0)
2815
{
2816
pgnutls_perror( ret );
2817
pgnutls_pubkey_deinit( pubkey );
2818
return STATUS_INTERNAL_ERROR;
2819
}
2820
2821
key_data(key_copy)->a.pubkey = pubkey;
2822
return STATUS_SUCCESS;
2823
}
2824
2825
static NTSTATUS key_asymmetric_duplicate( void *args )
2826
{
2827
const struct key_asymmetric_duplicate_params *params = args;
2828
NTSTATUS status;
2829
2830
if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy )))
2831
return status;
2832
2833
if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy )))
2834
return status;
2835
2836
return STATUS_SUCCESS;
2837
}
2838
2839
static NTSTATUS privkey_set_rsa_oaep_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2840
{
2841
gnutls_x509_spki_t spki;
2842
int ret;
2843
2844
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2845
{
2846
pgnutls_perror( ret );
2847
return STATUS_INTERNAL_ERROR;
2848
}
2849
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2850
ret = pgnutls_privkey_set_spki( key, spki, 0 );
2851
pgnutls_x509_spki_deinit( spki );
2852
if (ret < 0)
2853
{
2854
pgnutls_perror( ret );
2855
return STATUS_INTERNAL_ERROR;
2856
}
2857
return STATUS_SUCCESS;
2858
}
2859
2860
static NTSTATUS key_asymmetric_decrypt( void *args )
2861
{
2862
const struct key_asymmetric_decrypt_params *params = args;
2863
gnutls_datum_t e, d = { 0 };
2864
NTSTATUS status = STATUS_SUCCESS;
2865
int ret;
2866
2867
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2868
{
2869
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2870
gnutls_digest_algorithm_t dig;
2871
gnutls_datum_t label;
2872
2873
if (!pad || !pad->pszAlgId)
2874
{
2875
WARN( "padding info not found\n" );
2876
return STATUS_INVALID_PARAMETER;
2877
}
2878
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2879
{
2880
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2881
return STATUS_NOT_SUPPORTED;
2882
}
2883
2884
label.data = pad->pbLabel;
2885
label.size = pad->cbLabel;
2886
if ((status = privkey_set_rsa_oaep_params( key_data(params->key)->a.privkey, dig, &label ))) return status;
2887
}
2888
2889
e.data = params->input;
2890
e.size = params->input_len;
2891
if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
2892
{
2893
pgnutls_perror( ret );
2894
return STATUS_INTERNAL_ERROR;
2895
}
2896
2897
*params->ret_len = d.size;
2898
if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
2899
else if (params->output) status = STATUS_BUFFER_TOO_SMALL;
2900
2901
free( d.data );
2902
return status;
2903
}
2904
2905
static NTSTATUS pubkey_set_rsa_oaep_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2906
{
2907
gnutls_x509_spki_t spki;
2908
int ret;
2909
2910
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2911
{
2912
pgnutls_perror( ret );
2913
return STATUS_INTERNAL_ERROR;
2914
}
2915
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2916
ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2917
pgnutls_x509_spki_deinit( spki );
2918
if (ret < 0)
2919
{
2920
pgnutls_perror( ret );
2921
return STATUS_INTERNAL_ERROR;
2922
}
2923
return STATUS_SUCCESS;
2924
}
2925
2926
static NTSTATUS key_asymmetric_encrypt( void *args )
2927
{
2928
const struct key_asymmetric_encrypt_params *params = args;
2929
gnutls_datum_t d, e = { 0 };
2930
NTSTATUS status = STATUS_SUCCESS;
2931
int ret;
2932
2933
if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
2934
2935
if (params->key->alg_id == ALG_ID_RSA
2936
&& (!params->output || len_from_bitlen( params->key->u.a.bitlen ) > params->output_len))
2937
{
2938
*params->ret_len = len_from_bitlen( params->key->u.a.bitlen );
2939
return !params->output ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
2940
}
2941
2942
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2943
{
2944
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2945
gnutls_digest_algorithm_t dig;
2946
gnutls_datum_t label;
2947
2948
if (!pad || !pad->pszAlgId || !pad->pbLabel)
2949
{
2950
WARN( "padding info not found\n" );
2951
return STATUS_INVALID_PARAMETER;
2952
}
2953
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2954
{
2955
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2956
return STATUS_NOT_SUPPORTED;
2957
}
2958
2959
label.data = pad->pbLabel;
2960
label.size = pad->cbLabel;
2961
if ((status = pubkey_set_rsa_oaep_params( key_data(params->key)->a.pubkey, dig, &label ))) return status;
2962
}
2963
2964
d.data = params->input;
2965
d.size = params->input_len;
2966
if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
2967
{
2968
pgnutls_perror( ret );
2969
return STATUS_INTERNAL_ERROR;
2970
}
2971
2972
*params->ret_len = e.size;
2973
if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
2974
else if (params->output_len == 0) status = STATUS_SUCCESS;
2975
else status = STATUS_BUFFER_TOO_SMALL;
2976
2977
free( e.data );
2978
return status;
2979
}
2980
2981
static NTSTATUS key_asymmetric_derive_key( void *args )
2982
{
2983
const struct key_asymmetric_derive_key_params *params = args;
2984
gnutls_datum_t s;
2985
NTSTATUS status = STATUS_SUCCESS;
2986
int ret;
2987
2988
if ((ret = pgnutls_privkey_derive_secret( key_data(params->privkey)->a.privkey,
2989
key_data(params->pubkey)->a.pubkey, NULL, &s, 0 )))
2990
{
2991
pgnutls_perror( ret );
2992
return STATUS_INTERNAL_ERROR;
2993
}
2994
2995
*params->ret_len = EXPORT_SIZE( s, len_from_bitlen( params->privkey->u.a.bitlen ), 1 );
2996
if (params->output)
2997
{
2998
if (params->output_len < *params->ret_len) status = STATUS_BUFFER_TOO_SMALL;
2999
else export_gnutls_datum( params->output, *params->ret_len, &s, 1 );
3000
}
3001
3002
free( s.data );
3003
return status;
3004
}
3005
3006
const unixlib_entry_t __wine_unix_call_funcs[] =
3007
{
3008
gnutls_process_attach,
3009
gnutls_process_detach,
3010
key_symmetric_vector_reset,
3011
key_symmetric_set_auth_data,
3012
key_symmetric_encrypt,
3013
key_symmetric_decrypt,
3014
key_symmetric_get_tag,
3015
key_symmetric_destroy,
3016
key_asymmetric_generate,
3017
key_asymmetric_decrypt,
3018
key_asymmetric_encrypt,
3019
key_asymmetric_duplicate,
3020
key_asymmetric_sign,
3021
key_asymmetric_verify,
3022
key_asymmetric_destroy,
3023
key_asymmetric_export,
3024
key_asymmetric_import,
3025
key_asymmetric_derive_key,
3026
};
3027
3028
C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
3029
3030
#ifdef _WIN64
3031
3032
typedef ULONG PTR32;
3033
3034
struct key_symmetric32
3035
{
3036
enum chain_mode mode;
3037
ULONG block_size;
3038
PTR32 vector;
3039
ULONG vector_len;
3040
PTR32 secret;
3041
ULONG secret_len;
3042
ULONG __cs[6];
3043
};
3044
3045
struct key_asymmetric32
3046
{
3047
ULONG bitlen; /* ignored for ECC keys */
3048
enum ecc_curve_id curve_id;
3049
ULONG flags;
3050
DSSSEED dss_seed;
3051
};
3052
3053
struct key32
3054
{
3055
struct object hdr;
3056
enum alg_id alg_id;
3057
UINT64 private[PRIVATE_DATA_SIZE]; /* private data for backend */
3058
union
3059
{
3060
struct key_symmetric32 s;
3061
struct key_asymmetric32 a;
3062
} u;
3063
};
3064
3065
union padding
3066
{
3067
BCRYPT_OAEP_PADDING_INFO oaep;
3068
BCRYPT_PKCS1_PADDING_INFO pkcs1;
3069
BCRYPT_PSS_PADDING_INFO pss;
3070
};
3071
3072
union padding32
3073
{
3074
struct
3075
{
3076
PTR32 pszAlgId;
3077
PTR32 pbLabel;
3078
ULONG cbLabel;
3079
} oaep;
3080
struct
3081
{
3082
PTR32 pszAlgId;
3083
} pkcs1;
3084
struct
3085
{
3086
PTR32 pszAlgId;
3087
ULONG cbSalt;
3088
} pss;
3089
};
3090
3091
static union padding *get_padding( union padding32 *padding32, union padding *padding, ULONG flags)
3092
{
3093
if (!padding32) return NULL;
3094
3095
switch (flags)
3096
{
3097
case BCRYPT_PAD_OAEP:
3098
padding->oaep.pszAlgId = ULongToPtr( padding32->oaep.pszAlgId );
3099
padding->oaep.pbLabel = ULongToPtr( padding32->oaep.pbLabel );
3100
padding->oaep.cbLabel = padding32->oaep.cbLabel;
3101
return padding;
3102
3103
case BCRYPT_PAD_PKCS1:
3104
padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
3105
return padding;
3106
3107
case BCRYPT_PAD_PSS:
3108
padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
3109
padding->pss.cbSalt = padding32->pss.cbSalt;
3110
return padding;
3111
3112
default:
3113
break;
3114
}
3115
return NULL;
3116
}
3117
3118
static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
3119
{
3120
key->hdr = key32->hdr;
3121
key->alg_id = key32->alg_id;
3122
memcpy( key->private, key32->private, sizeof(key->private) );
3123
key->u.s.mode = key32->u.s.mode;
3124
key->u.s.block_size = key32->u.s.block_size;
3125
key->u.s.vector = ULongToPtr(key32->u.s.vector);
3126
key->u.s.vector_len = key32->u.s.vector_len;
3127
key->u.s.secret = ULongToPtr(key32->u.s.secret);
3128
key->u.s.secret_len = key32->u.s.secret_len;
3129
return key;
3130
}
3131
3132
static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
3133
{
3134
key->hdr = key32->hdr;
3135
key->alg_id = key32->alg_id;
3136
memcpy( key->private, key32->private, sizeof(key->private) );
3137
key->u.a.bitlen = key32->u.a.bitlen;
3138
key->u.a.curve_id = key32->u.a.curve_id;
3139
key->u.a.flags = key32->u.a.flags;
3140
key->u.a.dss_seed = key32->u.a.dss_seed;
3141
return key;
3142
}
3143
3144
static void put_symmetric_key32( struct key *key, struct key32 *key32 )
3145
{
3146
memcpy( key32->private, key->private, sizeof(key32->private) );
3147
}
3148
3149
static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
3150
{
3151
memcpy( key32->private, key->private, sizeof(key32->private) );
3152
key32->u.a.curve_id = key->u.a.curve_id;
3153
key32->u.a.flags = key->u.a.flags;
3154
key32->u.a.dss_seed = key->u.a.dss_seed;
3155
}
3156
3157
static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
3158
{
3159
NTSTATUS ret;
3160
struct key key;
3161
struct key32 *key32 = args;
3162
3163
ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
3164
put_symmetric_key32( &key, key32 );
3165
return ret;
3166
}
3167
3168
static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
3169
{
3170
struct
3171
{
3172
PTR32 key;
3173
PTR32 auth_data;
3174
ULONG len;
3175
} const *params32 = args;
3176
3177
NTSTATUS ret;
3178
struct key key;
3179
struct key32 *key32 = ULongToPtr( params32->key );
3180
struct key_symmetric_set_auth_data_params params =
3181
{
3182
get_symmetric_key( key32, &key ),
3183
ULongToPtr(params32->auth_data),
3184
params32->len
3185
};
3186
3187
ret = key_symmetric_set_auth_data( &params );
3188
put_symmetric_key32( &key, key32 );
3189
return ret;
3190
}
3191
3192
static NTSTATUS wow64_key_symmetric_encrypt( void *args )
3193
{
3194
struct
3195
{
3196
PTR32 key;
3197
PTR32 input;
3198
ULONG input_len;
3199
PTR32 output;
3200
ULONG output_len;
3201
} const *params32 = args;
3202
3203
NTSTATUS ret;
3204
struct key key;
3205
struct key32 *key32 = ULongToPtr( params32->key );
3206
struct key_symmetric_encrypt_params params =
3207
{
3208
get_symmetric_key( key32, &key ),
3209
ULongToPtr(params32->input),
3210
params32->input_len,
3211
ULongToPtr(params32->output),
3212
params32->output_len
3213
};
3214
3215
ret = key_symmetric_encrypt( &params );
3216
put_symmetric_key32( &key, key32 );
3217
return ret;
3218
}
3219
3220
static NTSTATUS wow64_key_symmetric_decrypt( void *args )
3221
{
3222
struct
3223
{
3224
PTR32 key;
3225
PTR32 input;
3226
ULONG input_len;
3227
PTR32 output;
3228
ULONG output_len;
3229
} const *params32 = args;
3230
3231
NTSTATUS ret;
3232
struct key key;
3233
struct key32 *key32 = ULongToPtr( params32->key );
3234
struct key_symmetric_decrypt_params params =
3235
{
3236
get_symmetric_key( key32, &key ),
3237
ULongToPtr(params32->input),
3238
params32->input_len,
3239
ULongToPtr(params32->output),
3240
params32->output_len
3241
};
3242
3243
ret = key_symmetric_decrypt( &params );
3244
put_symmetric_key32( &key, key32 );
3245
return ret;
3246
}
3247
3248
static NTSTATUS wow64_key_symmetric_get_tag( void *args )
3249
{
3250
struct
3251
{
3252
PTR32 key;
3253
PTR32 tag;
3254
ULONG len;
3255
} const *params32 = args;
3256
3257
NTSTATUS ret;
3258
struct key key;
3259
struct key32 *key32 = ULongToPtr( params32->key );
3260
struct key_symmetric_get_tag_params params =
3261
{
3262
get_symmetric_key( key32, &key ),
3263
ULongToPtr(params32->tag),
3264
params32->len
3265
};
3266
3267
ret = key_symmetric_get_tag( &params );
3268
put_symmetric_key32( &key, key32 );
3269
return ret;
3270
}
3271
3272
static NTSTATUS wow64_key_symmetric_destroy( void *args )
3273
{
3274
struct key32 *key32 = args;
3275
struct key key;
3276
3277
return key_symmetric_destroy( get_symmetric_key( key32, &key ));
3278
}
3279
3280
static NTSTATUS wow64_key_asymmetric_generate( void *args )
3281
{
3282
struct key32 *key32 = args;
3283
struct key key;
3284
NTSTATUS ret;
3285
3286
ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
3287
put_asymmetric_key32( &key, key32 );
3288
return ret;
3289
}
3290
3291
static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
3292
{
3293
struct
3294
{
3295
PTR32 key;
3296
PTR32 input;
3297
ULONG input_len;
3298
PTR32 padding;
3299
PTR32 output;
3300
ULONG output_len;
3301
PTR32 ret_len;
3302
ULONG flags;
3303
} const *params32 = args;
3304
3305
NTSTATUS ret;
3306
struct key key;
3307
union padding padding;
3308
struct key32 *key32 = ULongToPtr( params32->key );
3309
struct key_asymmetric_decrypt_params params =
3310
{
3311
get_asymmetric_key( key32, &key ),
3312
ULongToPtr(params32->input),
3313
params32->input_len,
3314
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
3315
ULongToPtr(params32->output),
3316
params32->output_len,
3317
ULongToPtr(params32->ret_len),
3318
params32->flags
3319
};
3320
3321
ret = key_asymmetric_decrypt( &params );
3322
put_asymmetric_key32( &key, key32 );
3323
return ret;
3324
}
3325
3326
static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
3327
{
3328
struct
3329
{
3330
PTR32 key;
3331
PTR32 input;
3332
ULONG input_len;
3333
PTR32 padding;
3334
PTR32 output;
3335
ULONG output_len;
3336
PTR32 ret_len;
3337
ULONG flags;
3338
} const *params32 = args;
3339
3340
NTSTATUS ret;
3341
struct key key;
3342
union padding padding;
3343
struct key32 *key32 = ULongToPtr( params32->key );
3344
struct key_asymmetric_encrypt_params params =
3345
{
3346
get_asymmetric_key( key32, &key ),
3347
ULongToPtr(params32->input),
3348
params32->input_len,
3349
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
3350
ULongToPtr(params32->output),
3351
params32->output_len,
3352
ULongToPtr(params32->ret_len),
3353
params32->flags
3354
};
3355
3356
ret = key_asymmetric_encrypt( &params );
3357
put_asymmetric_key32( &key, key32 );
3358
return ret;
3359
}
3360
3361
static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
3362
{
3363
struct
3364
{
3365
PTR32 key_orig;
3366
PTR32 key_copy;
3367
} const *params32 = args;
3368
3369
NTSTATUS ret;
3370
struct key key_orig, key_copy;
3371
struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
3372
struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
3373
struct key_asymmetric_duplicate_params params =
3374
{
3375
get_asymmetric_key( key_orig32, &key_orig ),
3376
get_asymmetric_key( key_copy32, &key_copy )
3377
};
3378
3379
ret = key_asymmetric_duplicate( &params );
3380
put_asymmetric_key32( &key_copy, key_copy32 );
3381
return ret;
3382
}
3383
3384
static NTSTATUS wow64_key_asymmetric_sign( void *args )
3385
{
3386
struct
3387
{
3388
PTR32 key;
3389
PTR32 padding;
3390
PTR32 input;
3391
ULONG input_len;
3392
PTR32 output;
3393
ULONG output_len;
3394
PTR32 ret_len;
3395
ULONG flags;
3396
} const *params32 = args;
3397
3398
NTSTATUS ret;
3399
struct key key;
3400
union padding padding;
3401
struct key32 *key32 = ULongToPtr( params32->key );
3402
struct key_asymmetric_sign_params params =
3403
{
3404
get_asymmetric_key( key32, &key ),
3405
get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
3406
ULongToPtr(params32->input),
3407
params32->input_len,
3408
ULongToPtr(params32->output),
3409
params32->output_len,
3410
ULongToPtr(params32->ret_len),
3411
params32->flags
3412
};
3413
3414
ret = key_asymmetric_sign( &params );
3415
put_asymmetric_key32( &key, key32 );
3416
return ret;
3417
}
3418
3419
static NTSTATUS wow64_key_asymmetric_verify( void *args )
3420
{
3421
struct
3422
{
3423
PTR32 key;
3424
PTR32 padding;
3425
PTR32 hash;
3426
ULONG hash_len;
3427
PTR32 signature;
3428
ULONG signature_len;
3429
ULONG flags;
3430
} const *params32 = args;
3431
3432
NTSTATUS ret;
3433
struct key key;
3434
union padding padding;
3435
struct key32 *key32 = ULongToPtr( params32->key );
3436
struct key_asymmetric_verify_params params =
3437
{
3438
get_asymmetric_key( key32, &key ),
3439
get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
3440
ULongToPtr(params32->hash),
3441
params32->hash_len,
3442
ULongToPtr(params32->signature),
3443
params32->signature_len,
3444
params32->flags
3445
};
3446
3447
ret = key_asymmetric_verify( &params );
3448
put_asymmetric_key32( &key, key32 );
3449
return ret;
3450
}
3451
3452
static NTSTATUS wow64_key_asymmetric_destroy( void *args )
3453
{
3454
struct key32 *key32 = args;
3455
struct key key;
3456
3457
return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
3458
}
3459
3460
static NTSTATUS wow64_key_asymmetric_export( void *args )
3461
{
3462
struct
3463
{
3464
PTR32 key;
3465
ULONG flags;
3466
PTR32 buf;
3467
ULONG len;
3468
PTR32 ret_len;
3469
} const *params32 = args;
3470
3471
NTSTATUS ret;
3472
struct key key;
3473
struct key32 *key32 = ULongToPtr( params32->key );
3474
struct key_asymmetric_export_params params =
3475
{
3476
get_asymmetric_key( key32, &key ),
3477
params32->flags,
3478
ULongToPtr(params32->buf),
3479
params32->len,
3480
ULongToPtr(params32->ret_len),
3481
};
3482
3483
ret = key_asymmetric_export( &params );
3484
put_asymmetric_key32( &key, key32 );
3485
return ret;
3486
}
3487
3488
static NTSTATUS wow64_key_asymmetric_import( void *args )
3489
{
3490
struct
3491
{
3492
PTR32 key;
3493
ULONG flags;
3494
PTR32 buf;
3495
ULONG len;
3496
} const *params32 = args;
3497
3498
NTSTATUS ret;
3499
struct key key;
3500
struct key32 *key32 = ULongToPtr( params32->key );
3501
struct key_asymmetric_import_params params =
3502
{
3503
get_asymmetric_key( key32, &key ),
3504
params32->flags,
3505
ULongToPtr(params32->buf),
3506
params32->len
3507
};
3508
3509
ret = key_asymmetric_import( &params );
3510
put_asymmetric_key32( &key, key32 );
3511
return ret;
3512
}
3513
3514
static NTSTATUS wow64_key_asymmetric_derive_key( void *args )
3515
{
3516
struct
3517
{
3518
PTR32 privkey;
3519
PTR32 pubkey;
3520
PTR32 output;
3521
ULONG output_len;
3522
PTR32 ret_len;
3523
} const *params32 = args;
3524
3525
NTSTATUS ret;
3526
struct key privkey, pubkey;
3527
struct key32 *privkey32 = ULongToPtr( params32->privkey );
3528
struct key32 *pubkey32 = ULongToPtr( params32->pubkey );
3529
struct key_asymmetric_derive_key_params params =
3530
{
3531
get_asymmetric_key( privkey32, &privkey ),
3532
get_asymmetric_key( pubkey32, &pubkey ),
3533
ULongToPtr(params32->output),
3534
params32->output_len,
3535
ULongToPtr(params32->ret_len),
3536
};
3537
3538
ret = key_asymmetric_derive_key( &params );
3539
put_asymmetric_key32( &privkey, privkey32 );
3540
put_asymmetric_key32( &pubkey, pubkey32 );
3541
return ret;
3542
}
3543
3544
const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
3545
{
3546
gnutls_process_attach,
3547
gnutls_process_detach,
3548
wow64_key_symmetric_vector_reset,
3549
wow64_key_symmetric_set_auth_data,
3550
wow64_key_symmetric_encrypt,
3551
wow64_key_symmetric_decrypt,
3552
wow64_key_symmetric_get_tag,
3553
wow64_key_symmetric_destroy,
3554
wow64_key_asymmetric_generate,
3555
wow64_key_asymmetric_decrypt,
3556
wow64_key_asymmetric_encrypt,
3557
wow64_key_asymmetric_duplicate,
3558
wow64_key_asymmetric_sign,
3559
wow64_key_asymmetric_verify,
3560
wow64_key_asymmetric_destroy,
3561
wow64_key_asymmetric_export,
3562
wow64_key_asymmetric_import,
3563
wow64_key_asymmetric_derive_key,
3564
};
3565
3566
C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count );
3567
3568
#endif /* _WIN64 */
3569
3570
#endif /* HAVE_GNUTLS_CIPHER_INIT */
3571
3572