Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/bcrypt/gnutls.c
4395 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
pgnutls_global_deinit();
488
dlclose( libgnutls_handle );
489
libgnutls_handle = NULL;
490
}
491
return STATUS_SUCCESS;
492
}
493
494
struct buffer
495
{
496
BYTE *buffer;
497
DWORD length;
498
DWORD pos;
499
BOOL error;
500
};
501
502
static void buffer_init( struct buffer *buffer )
503
{
504
buffer->buffer = NULL;
505
buffer->length = 0;
506
buffer->pos = 0;
507
buffer->error = FALSE;
508
}
509
510
static void buffer_free( struct buffer *buffer )
511
{
512
free( buffer->buffer );
513
}
514
515
static void buffer_append( struct buffer *buffer, BYTE *data, DWORD len )
516
{
517
if (!len) return;
518
519
if (buffer->pos + len > buffer->length)
520
{
521
DWORD new_length = max( max( buffer->pos + len, buffer->length * 2 ), 64 );
522
BYTE *new_buffer;
523
524
if (!(new_buffer = realloc( buffer->buffer, new_length )))
525
{
526
ERR( "out of memory\n" );
527
buffer->error = TRUE;
528
return;
529
}
530
531
buffer->buffer = new_buffer;
532
buffer->length = new_length;
533
}
534
535
memcpy( &buffer->buffer[buffer->pos], data, len );
536
buffer->pos += len;
537
}
538
539
static void buffer_append_byte( struct buffer *buffer, BYTE value )
540
{
541
buffer_append( buffer, &value, sizeof(value) );
542
}
543
544
static void buffer_append_asn1_length( struct buffer *buffer, DWORD length )
545
{
546
DWORD num_bytes;
547
548
if (length < 128)
549
{
550
buffer_append_byte( buffer, length );
551
return;
552
}
553
554
if (length <= 0xff) num_bytes = 1;
555
else if (length <= 0xffff) num_bytes = 2;
556
else if (length <= 0xffffff) num_bytes = 3;
557
else num_bytes = 4;
558
559
buffer_append_byte( buffer, 0x80 | num_bytes );
560
while (num_bytes--) buffer_append_byte( buffer, length >> (num_bytes * 8) );
561
}
562
563
static void buffer_append_asn1_integer( struct buffer *buffer, BYTE *data, DWORD len )
564
{
565
DWORD leading_zero = (*data & 0x80) != 0;
566
567
buffer_append_byte( buffer, 0x02 ); /* tag */
568
buffer_append_asn1_length( buffer, len + leading_zero );
569
if (leading_zero) buffer_append_byte( buffer, 0 );
570
buffer_append( buffer, data, len );
571
}
572
573
static void buffer_append_asn1_sequence( struct buffer *buffer, struct buffer *content )
574
{
575
if (content->error)
576
{
577
buffer->error = TRUE;
578
return;
579
}
580
581
buffer_append_byte( buffer, 0x30 ); /* tag */
582
buffer_append_asn1_length( buffer, content->pos );
583
buffer_append( buffer, content->buffer, content->pos );
584
}
585
586
static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *s, DWORD s_len )
587
{
588
struct buffer value;
589
590
buffer_init( &value );
591
buffer_append_asn1_integer( &value, r, r_len );
592
buffer_append_asn1_integer( &value, s, s_len );
593
buffer_append_asn1_sequence( buffer, &value );
594
buffer_free( &value );
595
}
596
597
static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
598
{
599
switch (key->alg_id)
600
{
601
case ALG_ID_3DES:
602
WARN( "handle block size\n" );
603
switch (key->u.s.mode)
604
{
605
case CHAIN_MODE_CBC:
606
return GNUTLS_CIPHER_3DES_CBC;
607
default:
608
break;
609
}
610
FIXME( "3DES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
611
return GNUTLS_CIPHER_UNKNOWN;
612
613
case ALG_ID_AES:
614
WARN( "handle block size\n" );
615
switch (key->u.s.mode)
616
{
617
case CHAIN_MODE_GCM:
618
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_GCM;
619
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_GCM;
620
break;
621
case CHAIN_MODE_ECB: /* can be emulated with CBC + empty IV */
622
case CHAIN_MODE_CBC:
623
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CBC;
624
if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CBC;
625
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CBC;
626
break;
627
case CHAIN_MODE_CFB:
628
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CFB8;
629
if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CFB8;
630
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CFB8;
631
break;
632
default:
633
break;
634
}
635
FIXME( "AES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
636
return GNUTLS_CIPHER_UNKNOWN;
637
638
default:
639
FIXME( "algorithm %u not supported\n", key->alg_id );
640
return GNUTLS_CIPHER_UNKNOWN;
641
}
642
}
643
644
static NTSTATUS key_symmetric_vector_reset( void *args )
645
{
646
struct key *key = args;
647
648
if (!key_data(key)->cipher) return STATUS_SUCCESS;
649
TRACE( "invalidating cipher handle\n" );
650
pgnutls_cipher_deinit( key_data(key)->cipher );
651
key_data(key)->cipher = NULL;
652
return STATUS_SUCCESS;
653
}
654
655
static NTSTATUS init_cipher_handle( struct key *key )
656
{
657
gnutls_cipher_algorithm_t cipher;
658
gnutls_datum_t secret, vector;
659
int ret;
660
661
if (key_data(key)->cipher) return STATUS_SUCCESS;
662
if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
663
664
secret.data = key->u.s.secret;
665
secret.size = key->u.s.secret_len;
666
667
vector.data = key->u.s.vector;
668
vector.size = key->u.s.vector_len;
669
670
if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
671
{
672
pgnutls_perror( ret );
673
return STATUS_INTERNAL_ERROR;
674
}
675
676
return STATUS_SUCCESS;
677
}
678
679
static NTSTATUS key_symmetric_set_auth_data( void *args )
680
{
681
const struct key_symmetric_set_auth_data_params *params = args;
682
NTSTATUS status;
683
int ret;
684
685
if (!params->auth_data) return STATUS_SUCCESS;
686
if ((status = init_cipher_handle( params->key ))) return status;
687
688
if ((ret = pgnutls_cipher_add_auth( key_data(params->key)->cipher, params->auth_data, params->len )))
689
{
690
pgnutls_perror( ret );
691
return STATUS_INTERNAL_ERROR;
692
}
693
return STATUS_SUCCESS;
694
}
695
696
static NTSTATUS key_symmetric_encrypt( void *args )
697
{
698
const struct key_symmetric_encrypt_params *params = args;
699
NTSTATUS status;
700
int ret;
701
702
if ((status = init_cipher_handle( params->key ))) return status;
703
704
if ((ret = pgnutls_cipher_encrypt2( key_data(params->key)->cipher, params->input, params->input_len,
705
params->output, params->output_len )))
706
{
707
pgnutls_perror( ret );
708
return STATUS_INTERNAL_ERROR;
709
}
710
return STATUS_SUCCESS;
711
}
712
713
static NTSTATUS key_symmetric_decrypt( void *args )
714
{
715
const struct key_symmetric_decrypt_params *params = args;
716
NTSTATUS status;
717
int ret;
718
719
if ((status = init_cipher_handle( params->key ))) return status;
720
721
if ((ret = pgnutls_cipher_decrypt2( key_data(params->key)->cipher, params->input, params->input_len,
722
params->output, params->output_len )))
723
{
724
pgnutls_perror( ret );
725
return STATUS_INTERNAL_ERROR;
726
}
727
return STATUS_SUCCESS;
728
}
729
730
static NTSTATUS key_symmetric_get_tag( void *args )
731
{
732
const struct key_symmetric_get_tag_params *params = args;
733
NTSTATUS status;
734
int ret;
735
736
if ((status = init_cipher_handle( params->key ))) return status;
737
738
if ((ret = pgnutls_cipher_tag( key_data(params->key)->cipher, params->tag, params->len )))
739
{
740
pgnutls_perror( ret );
741
return STATUS_INTERNAL_ERROR;
742
}
743
return STATUS_SUCCESS;
744
}
745
746
static NTSTATUS key_symmetric_destroy( void *args )
747
{
748
struct key *key = args;
749
750
if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
751
return STATUS_SUCCESS;
752
}
753
754
static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d, BOOL zero_pad )
755
{
756
ULONG size = d->size;
757
UCHAR *src = d->data;
758
ULONG offset = 0;
759
760
assert( size <= buflen + 1 );
761
if (size == buflen + 1)
762
{
763
assert( !src[0] );
764
src++;
765
size--;
766
}
767
if (zero_pad)
768
{
769
offset = buflen - size;
770
if (buffer) memset( buffer, 0, offset );
771
size = buflen;
772
}
773
774
if (buffer) memcpy( buffer + offset, src, size - offset );
775
return size;
776
}
777
778
#define EXPORT_SIZE(d,l,p) export_gnutls_datum( NULL, l, &d, p )
779
static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
780
{
781
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
782
gnutls_datum_t m, e;
783
ULONG size = len_from_bitlen( key->u.a.bitlen );
784
UCHAR *dst;
785
int ret;
786
787
if (key_data(key)->a.pubkey)
788
ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e );
789
else
790
return STATUS_INVALID_PARAMETER;
791
792
if (ret)
793
{
794
pgnutls_perror( ret );
795
return STATUS_INTERNAL_ERROR;
796
}
797
798
*ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 );
799
if (len >= *ret_len && buf)
800
{
801
dst = (UCHAR *)(rsa_blob + 1);
802
rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
803
804
dst += rsa_blob->cbPublicExp;
805
rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
806
807
rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
808
rsa_blob->BitLength = key->u.a.bitlen;
809
rsa_blob->cbPrime1 = 0;
810
rsa_blob->cbPrime2 = 0;
811
}
812
813
free( e.data ); free( m.data );
814
return STATUS_SUCCESS;
815
}
816
817
static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
818
{
819
BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
820
gnutls_ecc_curve_t curve;
821
gnutls_datum_t x, y;
822
DWORD magic, size;
823
UCHAR *dst;
824
int ret;
825
826
switch (key->alg_id)
827
{
828
case ALG_ID_ECDH_P256:
829
magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
830
size = 32;
831
break;
832
833
case ALG_ID_ECDH_P384:
834
magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;
835
size = 48;
836
break;
837
838
case ALG_ID_ECDH_P521:
839
magic = BCRYPT_ECDH_PUBLIC_P521_MAGIC;
840
size = 66;
841
break;
842
843
case ALG_ID_ECDSA_P256:
844
magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
845
size = 32;
846
break;
847
848
case ALG_ID_ECDSA_P384:
849
magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
850
size = 48;
851
break;
852
853
case ALG_ID_ECDSA_P521:
854
magic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC;
855
size = 66;
856
break;
857
858
default:
859
FIXME( "algorithm %u not supported\n", key->alg_id );
860
return STATUS_NOT_IMPLEMENTED;
861
}
862
863
if (key_data(key)->a.pubkey)
864
ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
865
else
866
return STATUS_INVALID_PARAMETER;
867
868
if (ret)
869
{
870
pgnutls_perror( ret );
871
return STATUS_INTERNAL_ERROR;
872
}
873
874
if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1 && curve != GNUTLS_ECC_CURVE_SECP521R1)
875
{
876
FIXME( "curve %u not supported\n", curve );
877
free( x.data ); free( y.data );
878
return STATUS_NOT_IMPLEMENTED;
879
}
880
881
*ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 );
882
if (len >= *ret_len && buf)
883
{
884
ecc_blob->dwMagic = magic;
885
ecc_blob->cbKey = size;
886
887
dst = (UCHAR *)(ecc_blob + 1);
888
dst += export_gnutls_datum( dst, size, &x, 1 );
889
export_gnutls_datum( dst, size, &y, 1 );
890
}
891
892
free( x.data ); free( y.data );
893
return STATUS_SUCCESS;
894
}
895
896
static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
897
{
898
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
899
gnutls_datum_t p, q, g, y;
900
ULONG size = len_from_bitlen( key->u.a.bitlen );
901
NTSTATUS status = STATUS_SUCCESS;
902
UCHAR *dst;
903
int ret;
904
905
if (key->u.a.bitlen > 1024)
906
{
907
FIXME( "bitlen > 1024 not supported\n" );
908
return STATUS_NOT_IMPLEMENTED;
909
}
910
911
if (key_data(key)->a.pubkey)
912
ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &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 (EXPORT_SIZE( q, sizeof(dsa_blob->q), 1 ) > sizeof(dsa_blob->q))
923
{
924
status = STATUS_INVALID_PARAMETER;
925
goto done;
926
}
927
928
*ret_len = sizeof(*dsa_blob) + EXPORT_SIZE( p, size, 1 ) + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
929
if (len >= *ret_len && buf)
930
{
931
dst = (UCHAR *)(dsa_blob + 1);
932
dst += export_gnutls_datum( dst, size, &p, 1 );
933
dst += export_gnutls_datum( dst, size, &g, 1 );
934
export_gnutls_datum( dst, size, &y, 1 );
935
936
dst = dsa_blob->q;
937
export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
938
939
dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
940
dsa_blob->cbKey = size;
941
memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
942
memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
943
}
944
945
done:
946
free( p.data ); free( q.data ); free( g.data ); free( y.data );
947
return status;
948
}
949
950
static void reverse_bytes( UCHAR *buf, ULONG len )
951
{
952
unsigned int i;
953
UCHAR tmp;
954
955
for (i = 0; i < len / 2; ++i)
956
{
957
tmp = buf[i];
958
buf[i] = buf[len - i - 1];
959
buf[len - i - 1] = tmp;
960
}
961
}
962
963
#define Q_SIZE 20
964
static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
965
{
966
BLOBHEADER *hdr = (BLOBHEADER *)buf;
967
DSSPUBKEY *dsskey;
968
gnutls_datum_t p, q, g, y;
969
ULONG size = len_from_bitlen( key->u.a.bitlen );
970
NTSTATUS status = STATUS_SUCCESS;
971
UCHAR *dst;
972
int ret;
973
974
if (key->u.a.bitlen > 1024)
975
{
976
FIXME( "bitlen > 1024 not supported\n" );
977
return STATUS_NOT_IMPLEMENTED;
978
}
979
980
if (key_data(key)->a.pubkey)
981
ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
982
else if (key_data(key)->a.privkey)
983
ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
984
else
985
return STATUS_INVALID_PARAMETER;
986
987
if (ret)
988
{
989
pgnutls_perror( ret );
990
return STATUS_INTERNAL_ERROR;
991
}
992
993
if (EXPORT_SIZE( q, Q_SIZE, 1 ) > Q_SIZE)
994
{
995
status = STATUS_INVALID_PARAMETER;
996
goto done;
997
}
998
999
*ret_len = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed) +
1000
EXPORT_SIZE( p, size, 1 ) + Q_SIZE + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
1001
if (len >= *ret_len && buf)
1002
{
1003
hdr->bType = PUBLICKEYBLOB;
1004
hdr->bVersion = 2;
1005
hdr->reserved = 0;
1006
hdr->aiKeyAlg = CALG_DSS_SIGN;
1007
1008
dsskey = (DSSPUBKEY *)(hdr + 1);
1009
dsskey->magic = MAGIC_DSS1;
1010
dsskey->bitlen = key->u.a.bitlen;
1011
1012
dst = (UCHAR *)(dsskey + 1);
1013
export_gnutls_datum( dst, size, &p, 1 );
1014
reverse_bytes( dst, size );
1015
dst += size;
1016
1017
export_gnutls_datum( dst, Q_SIZE, &q, 1 );
1018
reverse_bytes( dst, Q_SIZE );
1019
dst += Q_SIZE;
1020
1021
export_gnutls_datum( dst, size, &g, 1 );
1022
reverse_bytes( dst, size );
1023
dst += size;
1024
1025
export_gnutls_datum( dst, size, &y, 1 );
1026
reverse_bytes( dst, size );
1027
dst += size;
1028
1029
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1030
}
1031
1032
done:
1033
free( p.data ); free( q.data ); free( g.data ); free( y.data );
1034
return status;
1035
}
1036
1037
static gnutls_privkey_t create_privkey( gnutls_pk_algorithm_t pk_alg, unsigned int bitlen,
1038
const gnutls_keygen_data_st *data, unsigned int data_size )
1039
{
1040
gnutls_privkey_t privkey;
1041
int ret;
1042
1043
if ((ret = pgnutls_privkey_init( &privkey )))
1044
{
1045
pgnutls_perror( ret );
1046
return NULL;
1047
}
1048
1049
if ((ret = pgnutls_privkey_generate2( privkey, pk_alg, bitlen, 0, data, data_size )))
1050
{
1051
pgnutls_perror( ret );
1052
pgnutls_privkey_deinit( privkey );
1053
return NULL;
1054
}
1055
1056
return privkey;
1057
}
1058
1059
static gnutls_pubkey_t create_pubkey_from_privkey( gnutls_privkey_t privkey )
1060
{
1061
gnutls_pubkey_t pubkey;
1062
int ret;
1063
1064
if ((ret = pgnutls_pubkey_init( &pubkey )))
1065
{
1066
pgnutls_perror( ret );
1067
return NULL;
1068
}
1069
1070
if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
1071
{
1072
pgnutls_perror( ret );
1073
pgnutls_pubkey_deinit( pubkey );
1074
return NULL;
1075
}
1076
1077
return pubkey;
1078
}
1079
1080
static gnutls_dh_params_t get_dh_params( gnutls_privkey_t privkey )
1081
{
1082
gnutls_dh_params_t params;
1083
gnutls_datum_t x;
1084
int ret;
1085
1086
if ((ret = pgnutls_dh_params_init( &params )))
1087
{
1088
pgnutls_perror( ret );
1089
return NULL;
1090
}
1091
1092
if ((ret = pgnutls_privkey_export_dh_raw( privkey, params, NULL, &x, 0 )))
1093
{
1094
pgnutls_perror( ret );
1095
pgnutls_dh_params_deinit( params );
1096
return NULL;
1097
}
1098
1099
free( x.data );
1100
return params;
1101
}
1102
1103
static NTSTATUS key_asymmetric_generate( void *args )
1104
{
1105
struct key *key = args;
1106
gnutls_pk_algorithm_t pk_alg;
1107
gnutls_privkey_t privkey;
1108
gnutls_pubkey_t pubkey;
1109
unsigned int bitlen;
1110
1111
if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
1112
if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
1113
1114
switch (key->alg_id)
1115
{
1116
case ALG_ID_RSA:
1117
case ALG_ID_RSA_SIGN:
1118
pk_alg = GNUTLS_PK_RSA;
1119
bitlen = key->u.a.bitlen;
1120
break;
1121
1122
case ALG_ID_DH:
1123
pk_alg = GNUTLS_PK_DH;
1124
bitlen = key->u.a.bitlen;
1125
break;
1126
1127
case ALG_ID_DSA:
1128
pk_alg = GNUTLS_PK_DSA;
1129
bitlen = key->u.a.bitlen;
1130
break;
1131
1132
case ALG_ID_ECDH_P256:
1133
case ALG_ID_ECDSA_P256:
1134
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1135
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
1136
break;
1137
1138
case ALG_ID_ECDH_P384:
1139
case ALG_ID_ECDSA_P384:
1140
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1141
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
1142
break;
1143
1144
case ALG_ID_ECDH_P521:
1145
case ALG_ID_ECDSA_P521:
1146
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1147
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP521R1 );
1148
break;
1149
1150
default:
1151
FIXME( "algorithm %u not supported\n", key->alg_id );
1152
return STATUS_NOT_SUPPORTED;
1153
}
1154
1155
if (key->alg_id == ALG_ID_DH && key_data(key)->a.dh_params)
1156
{
1157
gnutls_keygen_data_st data;
1158
1159
data.type = GNUTLS_KEYGEN_DH;
1160
data.data = (unsigned char *)key_data(key)->a.dh_params;
1161
data.size = 0;
1162
if (!(privkey = create_privkey( pk_alg, bitlen, &data, 1 ))) return STATUS_INTERNAL_ERROR;
1163
}
1164
else if (!(privkey = create_privkey( pk_alg, bitlen, NULL, 0 ))) return STATUS_INTERNAL_ERROR;
1165
1166
if (key->alg_id == ALG_ID_DH && !key_data(key)->a.dh_params &&
1167
!(key_data(key)->a.dh_params = get_dh_params( privkey )))
1168
{
1169
pgnutls_privkey_deinit( privkey );
1170
return STATUS_INTERNAL_ERROR;
1171
}
1172
1173
if (!(pubkey = create_pubkey_from_privkey( privkey )))
1174
{
1175
pgnutls_privkey_deinit( privkey );
1176
return STATUS_INTERNAL_ERROR;
1177
}
1178
1179
key_data(key)->a.privkey = privkey;
1180
key_data(key)->a.pubkey = pubkey;
1181
return STATUS_SUCCESS;
1182
}
1183
1184
static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1185
{
1186
BCRYPT_ECCKEY_BLOB *ecc_blob;
1187
gnutls_ecc_curve_t curve;
1188
gnutls_datum_t x, y, d;
1189
DWORD magic, size;
1190
UCHAR *dst;
1191
int ret;
1192
1193
switch (key->alg_id)
1194
{
1195
case ALG_ID_ECDH_P256:
1196
magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
1197
size = 32;
1198
break;
1199
1200
case ALG_ID_ECDH_P384:
1201
magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC;
1202
size = 48;
1203
break;
1204
1205
case ALG_ID_ECDH_P521:
1206
magic = BCRYPT_ECDH_PRIVATE_P521_MAGIC;
1207
size = 66;
1208
break;
1209
1210
case ALG_ID_ECDSA_P256:
1211
magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
1212
size = 32;
1213
break;
1214
1215
case ALG_ID_ECDSA_P384:
1216
magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
1217
size = 48;
1218
break;
1219
1220
case ALG_ID_ECDSA_P521:
1221
magic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC;
1222
size = 66;
1223
break;
1224
1225
default:
1226
FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
1227
return STATUS_NOT_IMPLEMENTED;
1228
}
1229
1230
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1231
1232
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
1233
{
1234
pgnutls_perror( ret );
1235
return STATUS_INTERNAL_ERROR;
1236
}
1237
1238
if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1 && curve != GNUTLS_ECC_CURVE_SECP521R1)
1239
{
1240
FIXME( "curve %u not supported\n", curve );
1241
free( x.data ); free( y.data ); free( d.data );
1242
return STATUS_NOT_IMPLEMENTED;
1243
}
1244
1245
*ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ) + EXPORT_SIZE( d, size, 1 );
1246
if (len >= *ret_len && buf)
1247
{
1248
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1249
ecc_blob->dwMagic = magic;
1250
ecc_blob->cbKey = size;
1251
1252
dst = (UCHAR *)(ecc_blob + 1);
1253
dst += export_gnutls_datum( dst, size, &x, 1 );
1254
dst += export_gnutls_datum( dst, size, &y, 1 );
1255
export_gnutls_datum( dst, size, &d, 1 );
1256
}
1257
1258
free( x.data ); free( y.data ); free( d.data );
1259
return STATUS_SUCCESS;
1260
}
1261
1262
static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1263
{
1264
BCRYPT_ECCKEY_BLOB *ecc_blob;
1265
gnutls_ecc_curve_t curve;
1266
gnutls_privkey_t handle;
1267
gnutls_datum_t x, y, k;
1268
int ret;
1269
1270
switch (key->alg_id)
1271
{
1272
case ALG_ID_ECDH_P256:
1273
case ALG_ID_ECDSA_P256:
1274
curve = GNUTLS_ECC_CURVE_SECP256R1;
1275
break;
1276
1277
case ALG_ID_ECDH_P384:
1278
case ALG_ID_ECDSA_P384:
1279
curve = GNUTLS_ECC_CURVE_SECP384R1;
1280
break;
1281
1282
case ALG_ID_ECDH_P521:
1283
case ALG_ID_ECDSA_P521:
1284
curve = GNUTLS_ECC_CURVE_SECP521R1;
1285
break;
1286
1287
default:
1288
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1289
return STATUS_NOT_IMPLEMENTED;
1290
}
1291
1292
if ((ret = pgnutls_privkey_init( &handle )))
1293
{
1294
pgnutls_perror( ret );
1295
return STATUS_INTERNAL_ERROR;
1296
}
1297
1298
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1299
x.data = (unsigned char *)(ecc_blob + 1);
1300
x.size = ecc_blob->cbKey;
1301
y.data = x.data + ecc_blob->cbKey;
1302
y.size = ecc_blob->cbKey;
1303
k.data = y.data + ecc_blob->cbKey;
1304
k.size = ecc_blob->cbKey;
1305
1306
if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1307
{
1308
pgnutls_perror( ret );
1309
pgnutls_privkey_deinit( handle );
1310
return STATUS_INTERNAL_ERROR;
1311
}
1312
1313
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1314
key_data(key)->a.privkey = handle;
1315
return STATUS_SUCCESS;
1316
}
1317
1318
static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1319
{
1320
BCRYPT_RSAKEY_BLOB *rsa_blob;
1321
gnutls_datum_t m, e, d, p, q, u, e1, e2;
1322
ULONG size = len_from_bitlen( key->u.a.bitlen );
1323
BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
1324
UCHAR *dst;
1325
int ret;
1326
1327
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1328
1329
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1330
{
1331
pgnutls_perror( ret );
1332
return STATUS_INTERNAL_ERROR;
1333
}
1334
1335
*ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ) +
1336
EXPORT_SIZE( p, size / 2, 1 ) + EXPORT_SIZE( q, size / 2, 1 );
1337
1338
if (full) *ret_len += EXPORT_SIZE( e1, size / 2, 1 ) + EXPORT_SIZE( e2, size / 2, 1 ) +
1339
EXPORT_SIZE( u, size / 2, 1 ) + EXPORT_SIZE( d, size, 1 );
1340
1341
if (len >= *ret_len && buf)
1342
{
1343
rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1344
rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
1345
rsa_blob->BitLength = key->u.a.bitlen;
1346
1347
dst = (UCHAR *)(rsa_blob + 1);
1348
rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
1349
1350
dst += rsa_blob->cbPublicExp;
1351
rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
1352
1353
dst += rsa_blob->cbModulus;
1354
rsa_blob->cbPrime1 = export_gnutls_datum( dst, size / 2, &p, 1 );
1355
1356
dst += rsa_blob->cbPrime1;
1357
rsa_blob->cbPrime2 = export_gnutls_datum( dst, size / 2, &q, 1 );
1358
1359
if (full)
1360
{
1361
dst += rsa_blob->cbPrime2;
1362
export_gnutls_datum( dst, size / 2, &e1, 1 );
1363
1364
dst += rsa_blob->cbPrime1;
1365
export_gnutls_datum( dst, size / 2, &e2, 1 );
1366
1367
dst += rsa_blob->cbPrime2;
1368
export_gnutls_datum( dst, size / 2, &u, 1 );
1369
1370
dst += rsa_blob->cbPrime1;
1371
export_gnutls_datum( dst, size, &d, 1 );
1372
}
1373
}
1374
1375
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1376
free( e1.data ); free( e2.data );
1377
return STATUS_SUCCESS;
1378
}
1379
1380
static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1381
{
1382
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1383
gnutls_datum_t m, e, p, q;
1384
gnutls_privkey_t handle;
1385
int ret;
1386
1387
if ((ret = pgnutls_privkey_init( &handle )))
1388
{
1389
pgnutls_perror( ret );
1390
return STATUS_INTERNAL_ERROR;
1391
}
1392
1393
e.data = (unsigned char *)(rsa_blob + 1);
1394
e.size = rsa_blob->cbPublicExp;
1395
m.data = e.data + e.size;
1396
m.size = rsa_blob->cbModulus;
1397
p.data = m.data + m.size;
1398
p.size = rsa_blob->cbPrime1;
1399
q.data = p.data + p.size;
1400
q.size = rsa_blob->cbPrime2;
1401
1402
if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1403
{
1404
pgnutls_perror( ret );
1405
pgnutls_privkey_deinit( handle );
1406
return STATUS_INTERNAL_ERROR;
1407
}
1408
1409
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1410
key_data(key)->a.privkey = handle;
1411
return STATUS_SUCCESS;
1412
}
1413
1414
static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1415
{
1416
BLOBHEADER *hdr;
1417
DSSPUBKEY *pubkey;
1418
gnutls_datum_t p, q, g, y, x;
1419
ULONG size = len_from_bitlen( key->u.a.bitlen );
1420
UCHAR *dst;
1421
int ret;
1422
1423
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1424
1425
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1426
{
1427
pgnutls_perror( ret );
1428
return STATUS_INTERNAL_ERROR;
1429
}
1430
1431
if (q.size > 21 || x.size > 21)
1432
{
1433
ERR( "can't export key in this format\n" );
1434
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1435
return STATUS_NOT_SUPPORTED;
1436
}
1437
1438
*ret_len = sizeof(*hdr) + sizeof(*pubkey) + sizeof(key->u.a.dss_seed) +
1439
EXPORT_SIZE( p, size, 1 ) + 20 + EXPORT_SIZE( g, size, 1 ) + 20;
1440
if (len >= *ret_len && buf)
1441
{
1442
hdr = (BLOBHEADER *)buf;
1443
hdr->bType = PRIVATEKEYBLOB;
1444
hdr->bVersion = 2;
1445
hdr->reserved = 0;
1446
hdr->aiKeyAlg = CALG_DSS_SIGN;
1447
1448
pubkey = (DSSPUBKEY *)(hdr + 1);
1449
pubkey->magic = MAGIC_DSS2;
1450
pubkey->bitlen = key->u.a.bitlen;
1451
1452
dst = (UCHAR *)(pubkey + 1);
1453
export_gnutls_datum( dst, size, &p, 1 );
1454
reverse_bytes( dst, size );
1455
dst += size;
1456
1457
export_gnutls_datum( dst, 20, &q, 1 );
1458
reverse_bytes( dst, 20 );
1459
dst += 20;
1460
1461
export_gnutls_datum( dst, size, &g, 1 );
1462
reverse_bytes( dst, size );
1463
dst += size;
1464
1465
export_gnutls_datum( dst, 20, &x, 1 );
1466
reverse_bytes( dst, 20 );
1467
dst += 20;
1468
1469
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1470
}
1471
1472
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1473
return STATUS_SUCCESS;
1474
}
1475
1476
static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1477
{
1478
BLOBHEADER *hdr = (BLOBHEADER *)buf;
1479
DSSPUBKEY *pubkey;
1480
gnutls_privkey_t handle;
1481
gnutls_datum_t p, q, g, x;
1482
unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1483
int i, ret, size;
1484
1485
if ((ret = pgnutls_privkey_init( &handle )))
1486
{
1487
pgnutls_perror( ret );
1488
return STATUS_INTERNAL_ERROR;
1489
}
1490
1491
pubkey = (DSSPUBKEY *)(hdr + 1);
1492
if ((size = len_from_bitlen( pubkey->bitlen )) > sizeof(p_data))
1493
{
1494
FIXME( "size %u not supported\n", size );
1495
pgnutls_privkey_deinit( handle );
1496
return STATUS_NOT_SUPPORTED;
1497
}
1498
data = (unsigned char *)(pubkey + 1);
1499
1500
p.data = p_data;
1501
p.size = size;
1502
for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1503
data += p.size;
1504
1505
q.data = q_data;
1506
q.size = sizeof(q_data);
1507
for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1508
data += q.size;
1509
1510
g.data = g_data;
1511
g.size = size;
1512
for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1513
data += g.size;
1514
1515
x.data = x_data;
1516
x.size = sizeof(x_data);
1517
for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1518
data += x.size;
1519
1520
if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1521
{
1522
pgnutls_perror( ret );
1523
pgnutls_privkey_deinit( handle );
1524
return STATUS_INTERNAL_ERROR;
1525
}
1526
1527
memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1528
1529
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1530
key_data(key)->a.privkey = handle;
1531
return STATUS_SUCCESS;
1532
}
1533
1534
static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1535
{
1536
BCRYPT_ECCKEY_BLOB *ecc_blob;
1537
gnutls_ecc_curve_t curve;
1538
gnutls_datum_t x, y;
1539
gnutls_pubkey_t handle;
1540
int ret;
1541
1542
switch (key->alg_id)
1543
{
1544
case ALG_ID_ECDH_P256:
1545
case ALG_ID_ECDSA_P256:
1546
curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1547
1548
case ALG_ID_ECDH_P384:
1549
case ALG_ID_ECDSA_P384:
1550
curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1551
1552
case ALG_ID_ECDH_P521:
1553
case ALG_ID_ECDSA_P521:
1554
curve = GNUTLS_ECC_CURVE_SECP521R1; break;
1555
1556
default:
1557
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1558
return STATUS_NOT_IMPLEMENTED;
1559
}
1560
1561
if ((ret = pgnutls_pubkey_init( &handle )))
1562
{
1563
pgnutls_perror( ret );
1564
return STATUS_INTERNAL_ERROR;
1565
}
1566
1567
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1568
x.data = buf + sizeof(*ecc_blob);
1569
x.size = ecc_blob->cbKey;
1570
y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1571
y.size = ecc_blob->cbKey;
1572
1573
if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1574
{
1575
pgnutls_perror( ret );
1576
pgnutls_pubkey_deinit( handle );
1577
return STATUS_INTERNAL_ERROR;
1578
}
1579
1580
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1581
key_data(key)->a.pubkey = handle;
1582
return STATUS_SUCCESS;
1583
}
1584
1585
static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1586
{
1587
BCRYPT_RSAKEY_BLOB *rsa_blob;
1588
gnutls_pubkey_t handle;
1589
gnutls_datum_t m, e;
1590
int ret;
1591
1592
if ((ret = pgnutls_pubkey_init( &handle )))
1593
{
1594
pgnutls_perror( ret );
1595
return STATUS_INTERNAL_ERROR;
1596
}
1597
1598
rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1599
e.data = buf + sizeof(*rsa_blob);
1600
e.size = rsa_blob->cbPublicExp;
1601
m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1602
m.size = rsa_blob->cbModulus;
1603
1604
if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1605
{
1606
pgnutls_perror( ret );
1607
pgnutls_pubkey_deinit( handle );
1608
return STATUS_INTERNAL_ERROR;
1609
}
1610
1611
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1612
key_data(key)->a.pubkey = handle;
1613
return STATUS_SUCCESS;
1614
}
1615
1616
static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1617
{
1618
BCRYPT_DSA_KEY_BLOB *dsa_blob;
1619
gnutls_datum_t p, q, g, y;
1620
gnutls_pubkey_t handle;
1621
int ret;
1622
1623
if ((ret = pgnutls_pubkey_init( &handle )))
1624
{
1625
pgnutls_perror( ret );
1626
return STATUS_INTERNAL_ERROR;
1627
}
1628
1629
dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1630
p.data = buf + sizeof(*dsa_blob);
1631
p.size = dsa_blob->cbKey;
1632
q.data = dsa_blob->q;
1633
q.size = sizeof(dsa_blob->q);
1634
g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1635
g.size = dsa_blob->cbKey;
1636
y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1637
y.size = dsa_blob->cbKey;
1638
1639
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1640
{
1641
pgnutls_perror( ret );
1642
pgnutls_pubkey_deinit( handle );
1643
return STATUS_INTERNAL_ERROR;
1644
}
1645
1646
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1647
key_data(key)->a.pubkey = handle;
1648
return STATUS_SUCCESS;
1649
}
1650
1651
static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1652
{
1653
BLOBHEADER *hdr;
1654
DSSPUBKEY *pubkey;
1655
gnutls_datum_t p, q, g, y;
1656
gnutls_pubkey_t handle;
1657
unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1658
int i, ret, size;
1659
1660
if ((ret = pgnutls_pubkey_init( &handle )))
1661
{
1662
pgnutls_perror( ret );
1663
return STATUS_INTERNAL_ERROR;
1664
}
1665
1666
hdr = (BLOBHEADER *)buf;
1667
pubkey = (DSSPUBKEY *)(hdr + 1);
1668
size = len_from_bitlen( pubkey->bitlen );
1669
data = (unsigned char *)(pubkey + 1);
1670
1671
p.data = p_data;
1672
p.size = size;
1673
for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1674
data += p.size;
1675
1676
q.data = q_data;
1677
q.size = sizeof(q_data);
1678
for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1679
data += q.size;
1680
1681
g.data = g_data;
1682
g.size = size;
1683
for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1684
data += g.size;
1685
1686
y.data = y_data;
1687
y.size = sizeof(y_data);
1688
for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1689
1690
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1691
{
1692
pgnutls_perror( ret );
1693
pgnutls_pubkey_deinit( handle );
1694
return STATUS_INTERNAL_ERROR;
1695
}
1696
1697
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1698
key_data(key)->a.pubkey = handle;
1699
return STATUS_SUCCESS;
1700
}
1701
1702
static NTSTATUS key_export_dh_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1703
{
1704
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1705
ULONG size = len_from_bitlen( key->u.a.bitlen );
1706
gnutls_dh_params_t params;
1707
gnutls_datum_t p, g, y;
1708
UCHAR *dst;
1709
int ret = GNUTLS_E_INVALID_REQUEST;
1710
1711
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1712
{
1713
pgnutls_perror( ret );
1714
return STATUS_INTERNAL_ERROR;
1715
}
1716
1717
if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key)->a.pubkey, params, &y, 0 )))
1718
{
1719
pgnutls_perror( ret );
1720
pgnutls_dh_params_deinit( params );
1721
return STATUS_INTERNAL_ERROR;
1722
}
1723
1724
if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1725
{
1726
pgnutls_perror( ret );
1727
free( y.data );
1728
pgnutls_dh_params_deinit( params );
1729
return STATUS_INTERNAL_ERROR;
1730
}
1731
1732
*ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) + EXPORT_SIZE(y, size, 1);
1733
if (len >= *ret_len && buf)
1734
{
1735
dst = (UCHAR *)(dh_blob + 1);
1736
dst += export_gnutls_datum( dst, size, &p, 1 );
1737
dst += export_gnutls_datum( dst, size, &g, 1 );
1738
dst += export_gnutls_datum( dst, size, &y, 1 );
1739
1740
dh_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
1741
dh_blob->cbKey = size;
1742
}
1743
1744
free( p.data ); free( g.data ); free( y.data );
1745
return STATUS_SUCCESS;
1746
}
1747
1748
static NTSTATUS key_export_dh( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1749
{
1750
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1751
gnutls_datum_t p, g, y, x;
1752
gnutls_dh_params_t params;
1753
ULONG size = len_from_bitlen( key->u.a.bitlen );
1754
UCHAR *dst;
1755
int ret;
1756
1757
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1758
1759
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1760
{
1761
pgnutls_perror( ret );
1762
return STATUS_INTERNAL_ERROR;
1763
}
1764
1765
if ((ret = pgnutls_privkey_export_dh_raw( key_data(key)->a.privkey, params, &y, &x, 0 )))
1766
{
1767
pgnutls_perror( ret );
1768
pgnutls_dh_params_deinit( params );
1769
return STATUS_INTERNAL_ERROR;
1770
}
1771
1772
if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1773
{
1774
pgnutls_perror( ret );
1775
free( y.data ); free( x.data );
1776
pgnutls_dh_params_deinit( params );
1777
return STATUS_INTERNAL_ERROR;
1778
}
1779
1780
*ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) +
1781
EXPORT_SIZE(y, size, 1) + EXPORT_SIZE(x, size, 1);
1782
if (len >= *ret_len && buf)
1783
{
1784
dst = (UCHAR *)(dh_blob + 1);
1785
dst += export_gnutls_datum( dst, size, &p, 1 );
1786
dst += export_gnutls_datum( dst, size, &g, 1 );
1787
dst += export_gnutls_datum( dst, size, &y, 1 );
1788
dst += export_gnutls_datum( dst, size, &x, 1 );
1789
1790
dh_blob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
1791
dh_blob->cbKey = size;
1792
}
1793
1794
free( p.data ); free( g.data ); free( y.data ); free( x.data );
1795
pgnutls_dh_params_deinit( params );
1796
return STATUS_SUCCESS;
1797
}
1798
1799
static NTSTATUS key_export_dh_params( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1800
{
1801
BCRYPT_DH_PARAMETER_HEADER *hdr = (BCRYPT_DH_PARAMETER_HEADER *)buf;
1802
unsigned int size = sizeof(*hdr) + len_from_bitlen( key->u.a.bitlen ) * 2;
1803
gnutls_datum_t p, g;
1804
NTSTATUS status = STATUS_SUCCESS;
1805
UCHAR *dst;
1806
int ret;
1807
1808
if (!key_data(key)->a.dh_params) return STATUS_INVALID_PARAMETER;
1809
1810
if ((ret = pgnutls_dh_params_export_raw( key_data(key)->a.dh_params, &p, &g, NULL )))
1811
{
1812
pgnutls_perror( ret );
1813
return STATUS_INTERNAL_ERROR;
1814
}
1815
1816
*ret_len = size;
1817
if (len < size) status = STATUS_BUFFER_TOO_SMALL;
1818
else if (buf)
1819
{
1820
hdr->cbLength = size;
1821
hdr->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
1822
hdr->cbKeyLength = len_from_bitlen( key->u.a.bitlen );
1823
1824
dst = (UCHAR *)(hdr + 1);
1825
dst += export_gnutls_datum( dst, hdr->cbKeyLength, &p, 1 );
1826
dst += export_gnutls_datum( dst, hdr->cbKeyLength, &g, 1 );
1827
}
1828
1829
free( p.data ); free( g.data );
1830
return status;
1831
}
1832
1833
static NTSTATUS key_asymmetric_export( void *args )
1834
{
1835
const struct key_asymmetric_export_params *params = args;
1836
struct key *key = params->key;
1837
unsigned flags = params->flags;
1838
1839
if (!(key->u.a.flags & KEY_FLAG_FINALIZED)) return STATUS_INVALID_HANDLE;
1840
1841
switch (key->alg_id)
1842
{
1843
case ALG_ID_ECDH_P256:
1844
case ALG_ID_ECDH_P384:
1845
case ALG_ID_ECDH_P521:
1846
case ALG_ID_ECDSA_P256:
1847
case ALG_ID_ECDSA_P384:
1848
case ALG_ID_ECDSA_P521:
1849
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1850
return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
1851
return key_export_ecc( key, params->buf, params->len, params->ret_len );
1852
1853
case ALG_ID_RSA:
1854
case ALG_ID_RSA_SIGN:
1855
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1856
return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
1857
return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
1858
1859
case ALG_ID_DSA:
1860
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1861
{
1862
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1863
return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
1864
return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
1865
}
1866
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1867
return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
1868
return STATUS_NOT_IMPLEMENTED;
1869
1870
case ALG_ID_DH:
1871
if (flags & KEY_EXPORT_FLAG_DH_PARAMETERS)
1872
return key_export_dh_params( key, params->buf, params->len, params->ret_len );
1873
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1874
return key_export_dh_public( key, params->buf, params->len, params->ret_len );
1875
return key_export_dh( key, params->buf, params->len, params->ret_len );
1876
1877
default:
1878
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1879
return STATUS_NOT_IMPLEMENTED;
1880
}
1881
}
1882
1883
static NTSTATUS key_import_dh_public( struct key *key, UCHAR *buf, ULONG len )
1884
{
1885
BCRYPT_DH_KEY_BLOB *dh_blob;
1886
gnutls_dh_params_t params;
1887
gnutls_datum_t p, g, y;
1888
gnutls_pubkey_t handle;
1889
int ret;
1890
1891
if ((ret = pgnutls_pubkey_init( &handle )))
1892
{
1893
pgnutls_perror( ret );
1894
return STATUS_INTERNAL_ERROR;
1895
}
1896
1897
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1898
{
1899
pgnutls_perror( ret );
1900
pgnutls_pubkey_deinit( handle );
1901
return STATUS_INTERNAL_ERROR;
1902
}
1903
1904
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1905
p.data = buf + sizeof(*dh_blob);
1906
p.size = dh_blob->cbKey;
1907
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
1908
g.size = dh_blob->cbKey;
1909
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
1910
y.size = dh_blob->cbKey;
1911
1912
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
1913
{
1914
pgnutls_perror( ret );
1915
pgnutls_dh_params_deinit( params );
1916
pgnutls_pubkey_deinit( handle );
1917
return STATUS_INTERNAL_ERROR;
1918
}
1919
1920
if ((ret = pgnutls_pubkey_import_dh_raw( handle, params, &y )))
1921
{
1922
pgnutls_perror( ret );
1923
pgnutls_dh_params_deinit( params );
1924
pgnutls_pubkey_deinit( handle );
1925
return STATUS_INTERNAL_ERROR;
1926
}
1927
1928
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1929
key_data(key)->a.pubkey = handle;
1930
1931
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
1932
key_data(key)->a.dh_params = params;
1933
return STATUS_SUCCESS;
1934
}
1935
1936
static NTSTATUS key_import_dh( struct key *key, UCHAR *buf, ULONG len )
1937
{
1938
BCRYPT_DH_KEY_BLOB *dh_blob;
1939
gnutls_dh_params_t params;
1940
gnutls_datum_t p, g, y, x;
1941
gnutls_privkey_t handle;
1942
int ret;
1943
1944
if ((ret = pgnutls_privkey_init( &handle )))
1945
{
1946
pgnutls_perror( ret );
1947
return STATUS_INTERNAL_ERROR;
1948
}
1949
1950
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1951
{
1952
pgnutls_perror( ret );
1953
pgnutls_privkey_deinit( handle );
1954
return STATUS_INTERNAL_ERROR;
1955
}
1956
1957
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1958
p.data = buf + sizeof(*dh_blob);
1959
p.size = dh_blob->cbKey;
1960
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
1961
g.size = dh_blob->cbKey;
1962
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
1963
y.size = dh_blob->cbKey;
1964
x.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 3;
1965
x.size = dh_blob->cbKey;
1966
1967
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
1968
{
1969
pgnutls_perror( ret );
1970
pgnutls_dh_params_deinit( params );
1971
pgnutls_privkey_deinit( handle );
1972
return STATUS_INTERNAL_ERROR;
1973
}
1974
1975
if ((ret = pgnutls_privkey_import_dh_raw( handle, params, &y, &x )))
1976
{
1977
pgnutls_perror( ret );
1978
pgnutls_dh_params_deinit( params );
1979
pgnutls_privkey_deinit( handle );
1980
return STATUS_INTERNAL_ERROR;
1981
}
1982
1983
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1984
key_data(key)->a.privkey = handle;
1985
1986
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
1987
key_data(key)->a.dh_params = params;
1988
return STATUS_SUCCESS;
1989
}
1990
1991
static NTSTATUS key_import_dh_params( struct key *key, UCHAR *buf, ULONG len )
1992
{
1993
BCRYPT_DH_PARAMETER_HEADER *dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buf;
1994
gnutls_dh_params_t params;
1995
gnutls_datum_t p, g;
1996
int ret;
1997
1998
if ((ret = pgnutls_dh_params_init( &params )))
1999
{
2000
pgnutls_perror( ret );
2001
return STATUS_INTERNAL_ERROR;
2002
}
2003
2004
p.data = (unsigned char *)(dh_header + 1);
2005
p.size = dh_header->cbKeyLength;
2006
g.data = p.data + dh_header->cbKeyLength;
2007
g.size = dh_header->cbKeyLength;
2008
2009
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )))
2010
{
2011
pgnutls_perror( ret );
2012
pgnutls_dh_params_deinit( params );
2013
return STATUS_INTERNAL_ERROR;
2014
}
2015
2016
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2017
key_data(key)->a.dh_params = params;
2018
return STATUS_SUCCESS;
2019
}
2020
2021
static NTSTATUS key_asymmetric_import( void *args )
2022
{
2023
const struct key_asymmetric_import_params *params = args;
2024
struct key *key = params->key;
2025
unsigned flags = params->flags;
2026
gnutls_pubkey_t pubkey;
2027
NTSTATUS ret;
2028
2029
switch (key->alg_id)
2030
{
2031
case ALG_ID_ECDH_P256:
2032
case ALG_ID_ECDH_P384:
2033
case ALG_ID_ECDH_P521:
2034
case ALG_ID_ECDSA_P256:
2035
case ALG_ID_ECDSA_P384:
2036
case ALG_ID_ECDSA_P521:
2037
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2038
return key_import_ecc_public( key, params->buf, params->len );
2039
ret = key_import_ecc( key, params->buf, params->len );
2040
break;
2041
2042
case ALG_ID_RSA:
2043
case ALG_ID_RSA_SIGN:
2044
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2045
return key_import_rsa_public( key, params->buf, params->len );
2046
ret = key_import_rsa( key, params->buf, params->len );
2047
break;
2048
2049
case ALG_ID_DSA:
2050
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2051
{
2052
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2053
return key_import_dsa_capi_public( key, params->buf, params->len );
2054
return key_import_dsa_public( key, params->buf, params->len );
2055
}
2056
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2057
{
2058
ret = key_import_dsa_capi( key, params->buf, params->len );
2059
break;
2060
}
2061
FIXME( "DSA private key not supported\n" );
2062
return STATUS_NOT_IMPLEMENTED;
2063
2064
case ALG_ID_DH:
2065
if (flags & KEY_IMPORT_FLAG_DH_PARAMETERS)
2066
return key_import_dh_params( key, params->buf, params->len );
2067
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2068
return key_import_dh_public( key, params->buf, params->len );
2069
ret = key_import_dh( key, params->buf, params->len );
2070
break;
2071
2072
default:
2073
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2074
return STATUS_NOT_IMPLEMENTED;
2075
}
2076
2077
if (ret) return ret;
2078
2079
if ((ret = pgnutls_pubkey_init( &pubkey )))
2080
{
2081
pgnutls_perror( ret );
2082
return STATUS_INTERNAL_ERROR;
2083
}
2084
2085
if (pgnutls_pubkey_import_privkey( pubkey, key_data(params->key)->a.privkey, 0, 0 ))
2086
{
2087
/* Imported private key may be legitimately missing public key, so ignore the failure here. */
2088
pgnutls_pubkey_deinit( pubkey );
2089
}
2090
else
2091
{
2092
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2093
key_data(key)->a.pubkey = pubkey;
2094
}
2095
return STATUS_SUCCESS;
2096
}
2097
2098
static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
2099
gnutls_datum_t *gnutls_signature )
2100
{
2101
struct buffer buffer;
2102
DWORD r_len = signature_len / 2;
2103
DWORD s_len = r_len;
2104
BYTE *r = signature;
2105
BYTE *s = signature + r_len;
2106
2107
buffer_init( &buffer );
2108
buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
2109
if (buffer.error)
2110
{
2111
buffer_free( &buffer );
2112
return STATUS_NO_MEMORY;
2113
}
2114
2115
gnutls_signature->data = buffer.buffer;
2116
gnutls_signature->size = buffer.pos;
2117
return STATUS_SUCCESS;
2118
}
2119
2120
static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
2121
gnutls_datum_t *gnutls_signature )
2122
{
2123
gnutls_signature->data = signature;
2124
gnutls_signature->size = signature_len;
2125
return STATUS_SUCCESS;
2126
}
2127
2128
static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
2129
gnutls_datum_t *gnutls_signature )
2130
{
2131
switch (key->alg_id)
2132
{
2133
case ALG_ID_ECDSA_P256:
2134
case ALG_ID_ECDSA_P384:
2135
case ALG_ID_ECDSA_P521:
2136
case ALG_ID_DSA:
2137
return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
2138
2139
case ALG_ID_RSA:
2140
case ALG_ID_RSA_SIGN:
2141
return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
2142
2143
default:
2144
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2145
return STATUS_NOT_IMPLEMENTED;
2146
}
2147
}
2148
2149
static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
2150
{
2151
if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
2152
if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
2153
if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
2154
if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
2155
if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
2156
if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
2157
return GNUTLS_DIG_UNKNOWN;
2158
}
2159
2160
static NTSTATUS pubkey_set_rsa_pss_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2161
{
2162
gnutls_x509_spki_t spki;
2163
int ret;
2164
2165
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2166
{
2167
pgnutls_perror( ret );
2168
return STATUS_INTERNAL_ERROR;
2169
}
2170
pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2171
ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2172
pgnutls_x509_spki_deinit( spki );
2173
if (ret < 0)
2174
{
2175
pgnutls_perror( ret );
2176
return STATUS_INTERNAL_ERROR;
2177
}
2178
return STATUS_SUCCESS;
2179
}
2180
2181
static NTSTATUS key_asymmetric_verify( void *args )
2182
{
2183
#ifdef GNUTLS_VERIFY_ALLOW_BROKEN
2184
unsigned int verify_flags = GNUTLS_VERIFY_ALLOW_BROKEN;
2185
#else
2186
unsigned int verify_flags = 0;
2187
#endif
2188
const struct key_asymmetric_verify_params *params = args;
2189
struct key *key = params->key;
2190
unsigned flags = params->flags;
2191
gnutls_digest_algorithm_t hash_alg;
2192
gnutls_sign_algorithm_t sign_alg;
2193
gnutls_datum_t gnutls_hash, gnutls_signature;
2194
gnutls_pk_algorithm_t pk_alg;
2195
NTSTATUS status;
2196
int ret;
2197
2198
switch (key->alg_id)
2199
{
2200
case ALG_ID_ECDSA_P256:
2201
case ALG_ID_ECDSA_P384:
2202
case ALG_ID_ECDSA_P521:
2203
{
2204
if (flags) FIXME( "flags %#x not supported\n", flags );
2205
2206
/* only the hash size must match, not the actual hash function */
2207
switch (params->hash_len)
2208
{
2209
case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2210
case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2211
case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2212
2213
default:
2214
FIXME( "hash size %u not yet supported\n", params->hash_len );
2215
return STATUS_INVALID_SIGNATURE;
2216
}
2217
pk_alg = GNUTLS_PK_ECC;
2218
break;
2219
}
2220
case ALG_ID_RSA:
2221
case ALG_ID_RSA_SIGN:
2222
{
2223
if (flags & BCRYPT_PAD_PKCS1)
2224
{
2225
BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
2226
2227
if (!info) return STATUS_INVALID_PARAMETER;
2228
if (!info->pszAlgId)
2229
{
2230
hash_alg = GNUTLS_DIG_UNKNOWN;
2231
verify_flags |= GNUTLS_VERIFY_USE_TLS1_RSA;
2232
}
2233
else if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2234
{
2235
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2236
return STATUS_NOT_SUPPORTED;
2237
}
2238
pk_alg = GNUTLS_PK_RSA;
2239
}
2240
else if (flags & BCRYPT_PAD_PSS)
2241
{
2242
BCRYPT_PSS_PADDING_INFO *info = params->padding;
2243
2244
if (!info) return STATUS_INVALID_PARAMETER;
2245
if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
2246
if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2247
{
2248
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2249
return STATUS_NOT_SUPPORTED;
2250
}
2251
if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status;
2252
pk_alg = GNUTLS_PK_RSA_PSS;
2253
}
2254
else return STATUS_INVALID_PARAMETER;
2255
break;
2256
}
2257
case ALG_ID_DSA:
2258
{
2259
if (flags) FIXME( "flags %#x not supported\n", flags );
2260
if (params->hash_len != 20)
2261
{
2262
FIXME( "hash size %u not supported\n", params->hash_len );
2263
return STATUS_INVALID_PARAMETER;
2264
}
2265
hash_alg = GNUTLS_DIG_SHA1;
2266
pk_alg = GNUTLS_PK_DSA;
2267
break;
2268
}
2269
default:
2270
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2271
return STATUS_NOT_IMPLEMENTED;
2272
}
2273
2274
if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
2275
{
2276
FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
2277
return STATUS_NOT_IMPLEMENTED;
2278
}
2279
2280
if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
2281
return status;
2282
2283
gnutls_hash.data = params->hash;
2284
gnutls_hash.size = params->hash_len;
2285
2286
ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, verify_flags, &gnutls_hash, &gnutls_signature );
2287
if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
2288
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
2289
}
2290
2291
static unsigned int get_signature_length( enum alg_id id )
2292
{
2293
switch (id)
2294
{
2295
case ALG_ID_ECDSA_P256: return 64;
2296
case ALG_ID_ECDSA_P384: return 96;
2297
case ALG_ID_ECDSA_P521: return 132;
2298
case ALG_ID_DSA: return 40;
2299
default:
2300
FIXME( "unhandled algorithm %u\n", id );
2301
return 0;
2302
}
2303
}
2304
2305
static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
2306
UCHAR *output, ULONG output_len, ULONG *ret_len )
2307
{
2308
switch (type)
2309
{
2310
case ALG_ID_RSA:
2311
case ALG_ID_RSA_SIGN:
2312
{
2313
*ret_len = signature.size;
2314
if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
2315
if (output) memcpy( output, signature.data, signature.size );
2316
return STATUS_SUCCESS;
2317
}
2318
case ALG_ID_ECDSA_P256:
2319
case ALG_ID_ECDSA_P384:
2320
case ALG_ID_ECDSA_P521:
2321
case ALG_ID_DSA:
2322
{
2323
int err;
2324
unsigned int sig_len = get_signature_length( type );
2325
gnutls_datum_t r, s; /* format as r||s */
2326
2327
if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
2328
{
2329
pgnutls_perror( err );
2330
return STATUS_INTERNAL_ERROR;
2331
}
2332
2333
*ret_len = sig_len;
2334
if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
2335
2336
if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
2337
{
2338
ERR( "we didn't get a correct signature\n" );
2339
return STATUS_INTERNAL_ERROR;
2340
}
2341
2342
if (output)
2343
{
2344
export_gnutls_datum( output, sig_len / 2, &r, 1 );
2345
export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
2346
}
2347
2348
free( r.data ); free( s.data );
2349
return STATUS_SUCCESS;
2350
}
2351
default:
2352
return STATUS_INTERNAL_ERROR;
2353
}
2354
}
2355
2356
static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2357
{
2358
gnutls_x509_spki_t spki;
2359
int ret;
2360
2361
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2362
{
2363
pgnutls_perror( ret );
2364
return STATUS_INTERNAL_ERROR;
2365
}
2366
pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2367
ret = pgnutls_privkey_set_spki( key, spki, 0 );
2368
pgnutls_x509_spki_deinit( spki );
2369
if (ret < 0)
2370
{
2371
pgnutls_perror( ret );
2372
return STATUS_INTERNAL_ERROR;
2373
}
2374
return STATUS_SUCCESS;
2375
}
2376
2377
static NTSTATUS key_asymmetric_sign( void *args )
2378
{
2379
const struct key_asymmetric_sign_params *params = args;
2380
struct key *key = params->key;
2381
unsigned int flags = params->flags, gnutls_flags = 0;
2382
gnutls_datum_t hash, signature;
2383
gnutls_digest_algorithm_t hash_alg;
2384
NTSTATUS status;
2385
int ret;
2386
2387
if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384 || key->alg_id == ALG_ID_ECDSA_P521)
2388
{
2389
/* With ECDSA, we find the digest algorithm from the hash length, and verify it */
2390
switch (params->input_len)
2391
{
2392
case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2393
case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2394
case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2395
case 64: hash_alg = GNUTLS_DIG_SHA512; break;
2396
2397
default:
2398
FIXME( "hash size %u not yet supported\n", params->input_len );
2399
return STATUS_INVALID_PARAMETER;
2400
}
2401
2402
if (flags == BCRYPT_PAD_PKCS1)
2403
{
2404
BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2405
if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
2406
{
2407
WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
2408
return STATUS_INVALID_PARAMETER;
2409
}
2410
}
2411
}
2412
else if (key->alg_id == ALG_ID_DSA)
2413
{
2414
if (flags) FIXME( "flags %#x not supported\n", flags );
2415
if (params->input_len != 20)
2416
{
2417
FIXME( "hash size %u not supported\n", params->input_len );
2418
return STATUS_INVALID_PARAMETER;
2419
}
2420
hash_alg = GNUTLS_DIG_SHA1;
2421
}
2422
else if (flags == BCRYPT_PAD_PKCS1)
2423
{
2424
BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2425
2426
if (!pad)
2427
{
2428
WARN( "padding info not found\n" );
2429
return STATUS_INVALID_PARAMETER;
2430
}
2431
if (!pad->pszAlgId) hash_alg = GNUTLS_DIG_UNKNOWN;
2432
else if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2433
{
2434
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2435
return STATUS_NOT_SUPPORTED;
2436
}
2437
}
2438
else if (flags == BCRYPT_PAD_PSS)
2439
{
2440
BCRYPT_PSS_PADDING_INFO *pad = params->padding;
2441
2442
if (!pad || !pad->pszAlgId)
2443
{
2444
WARN( "padding info not found\n" );
2445
return STATUS_INVALID_PARAMETER;
2446
}
2447
if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
2448
{
2449
FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id );
2450
return STATUS_NOT_SUPPORTED;
2451
}
2452
if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2453
{
2454
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2455
return STATUS_NOT_SUPPORTED;
2456
}
2457
2458
if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status;
2459
gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS;
2460
}
2461
else if (!flags)
2462
{
2463
WARN( "invalid flags %#x\n", flags );
2464
return STATUS_INVALID_PARAMETER;
2465
}
2466
else
2467
{
2468
FIXME( "flags %#x not implemented\n", flags );
2469
return STATUS_NOT_IMPLEMENTED;
2470
}
2471
2472
if (!params->output)
2473
{
2474
*params->ret_len = len_from_bitlen( key->u.a.bitlen );
2475
return STATUS_SUCCESS;
2476
}
2477
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
2478
2479
hash.data = params->input;
2480
hash.size = params->input_len;
2481
2482
signature.data = NULL;
2483
signature.size = 0;
2484
2485
if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature )))
2486
{
2487
pgnutls_perror( ret );
2488
return STATUS_INTERNAL_ERROR;
2489
}
2490
2491
status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
2492
free( signature.data );
2493
return status;
2494
}
2495
2496
static NTSTATUS key_asymmetric_destroy( void *args )
2497
{
2498
struct key *key = args;
2499
2500
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2501
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2502
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2503
return STATUS_SUCCESS;
2504
}
2505
2506
static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy )
2507
{
2508
gnutls_privkey_t privkey;
2509
int ret;
2510
2511
if ((ret = pgnutls_privkey_init( &privkey )))
2512
{
2513
pgnutls_perror( ret );
2514
return STATUS_INTERNAL_ERROR;
2515
}
2516
2517
switch (key_orig->alg_id)
2518
{
2519
case ALG_ID_RSA:
2520
case ALG_ID_RSA_SIGN:
2521
{
2522
gnutls_datum_t m, e, d, p, q, u, e1, e2;
2523
2524
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
2525
break;
2526
ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
2527
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
2528
free( e1.data ); free( e2.data );
2529
break;
2530
}
2531
case ALG_ID_DSA:
2532
{
2533
gnutls_datum_t p, q, g, y, x;
2534
2535
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x ))) break;
2536
ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
2537
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
2538
if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2539
break;
2540
}
2541
case ALG_ID_ECDH_P256:
2542
case ALG_ID_ECDH_P384:
2543
case ALG_ID_ECDH_P521:
2544
case ALG_ID_ECDSA_P256:
2545
case ALG_ID_ECDSA_P384:
2546
case ALG_ID_ECDSA_P521:
2547
{
2548
gnutls_ecc_curve_t curve;
2549
gnutls_datum_t x, y, k;
2550
2551
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k ))) break;
2552
ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
2553
free( x.data ); free( y.data ); free( k.data );
2554
break;
2555
}
2556
case ALG_ID_DH:
2557
{
2558
gnutls_dh_params_t params;
2559
gnutls_datum_t y, x;
2560
2561
if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2562
if ((ret = pgnutls_privkey_export_dh_raw( key_data(key_orig)->a.privkey, params, &y, &x, 0 )) < 0)
2563
{
2564
pgnutls_dh_params_deinit( params );
2565
break;
2566
}
2567
ret = pgnutls_privkey_import_dh_raw( privkey, params, &y, &x );
2568
pgnutls_dh_params_deinit( params );
2569
free( x.data ); free( y.data );
2570
break;
2571
}
2572
default:
2573
ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2574
pgnutls_privkey_deinit( privkey );
2575
return STATUS_INTERNAL_ERROR;
2576
}
2577
2578
if (ret < 0)
2579
{
2580
pgnutls_perror( ret );
2581
pgnutls_privkey_deinit( privkey );
2582
return STATUS_INTERNAL_ERROR;
2583
}
2584
2585
key_data(key_copy)->a.privkey = privkey;
2586
return STATUS_SUCCESS;
2587
}
2588
2589
static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy )
2590
{
2591
gnutls_pubkey_t pubkey;
2592
int ret;
2593
2594
if ((ret = pgnutls_pubkey_init( &pubkey )))
2595
{
2596
pgnutls_perror( ret );
2597
return STATUS_INTERNAL_ERROR;
2598
}
2599
2600
switch (key_orig->alg_id)
2601
{
2602
case ALG_ID_RSA:
2603
case ALG_ID_RSA_SIGN:
2604
{
2605
gnutls_datum_t m, e;
2606
2607
if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e ))) break;
2608
ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e );
2609
free( m.data ); free( e.data );
2610
break;
2611
}
2612
case ALG_ID_DSA:
2613
{
2614
gnutls_datum_t p, q, g, y;
2615
2616
if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y ))) break;
2617
ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y );
2618
free( p.data ); free( q.data ); free( g.data ); free( y.data );
2619
if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2620
break;
2621
}
2622
case ALG_ID_ECDH_P256:
2623
case ALG_ID_ECDH_P384:
2624
case ALG_ID_ECDH_P521:
2625
case ALG_ID_ECDSA_P256:
2626
case ALG_ID_ECDSA_P384:
2627
case ALG_ID_ECDSA_P521:
2628
{
2629
gnutls_ecc_curve_t curve;
2630
gnutls_datum_t x, y;
2631
2632
if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y ))) break;
2633
ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y );
2634
free( x.data ); free( y.data );
2635
break;
2636
}
2637
case ALG_ID_DH:
2638
{
2639
gnutls_dh_params_t params;
2640
gnutls_datum_t y;
2641
2642
if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2643
if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key_orig)->a.pubkey, params, &y, 0 )) < 0)
2644
{
2645
pgnutls_dh_params_deinit( params );
2646
break;
2647
}
2648
ret = pgnutls_pubkey_import_dh_raw( pubkey, params, &y );
2649
pgnutls_dh_params_deinit( params );
2650
free( y.data );
2651
break;
2652
}
2653
default:
2654
ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2655
pgnutls_pubkey_deinit( pubkey );
2656
return STATUS_INTERNAL_ERROR;
2657
}
2658
2659
if (ret < 0)
2660
{
2661
pgnutls_perror( ret );
2662
pgnutls_pubkey_deinit( pubkey );
2663
return STATUS_INTERNAL_ERROR;
2664
}
2665
2666
key_data(key_copy)->a.pubkey = pubkey;
2667
return STATUS_SUCCESS;
2668
}
2669
2670
static NTSTATUS key_asymmetric_duplicate( void *args )
2671
{
2672
const struct key_asymmetric_duplicate_params *params = args;
2673
NTSTATUS status;
2674
2675
if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy )))
2676
return status;
2677
2678
if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy )))
2679
return status;
2680
2681
return STATUS_SUCCESS;
2682
}
2683
2684
static NTSTATUS privkey_set_rsa_oaep_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2685
{
2686
gnutls_x509_spki_t spki;
2687
int ret;
2688
2689
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2690
{
2691
pgnutls_perror( ret );
2692
return STATUS_INTERNAL_ERROR;
2693
}
2694
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2695
ret = pgnutls_privkey_set_spki( key, spki, 0 );
2696
pgnutls_x509_spki_deinit( spki );
2697
if (ret < 0)
2698
{
2699
pgnutls_perror( ret );
2700
return STATUS_INTERNAL_ERROR;
2701
}
2702
return STATUS_SUCCESS;
2703
}
2704
2705
static NTSTATUS key_asymmetric_decrypt( void *args )
2706
{
2707
const struct key_asymmetric_decrypt_params *params = args;
2708
gnutls_datum_t e, d = { 0 };
2709
NTSTATUS status = STATUS_SUCCESS;
2710
int ret;
2711
2712
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2713
{
2714
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2715
gnutls_digest_algorithm_t dig;
2716
gnutls_datum_t label;
2717
2718
if (!pad || !pad->pszAlgId)
2719
{
2720
WARN( "padding info not found\n" );
2721
return STATUS_INVALID_PARAMETER;
2722
}
2723
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2724
{
2725
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2726
return STATUS_NOT_SUPPORTED;
2727
}
2728
2729
label.data = pad->pbLabel;
2730
label.size = pad->cbLabel;
2731
if ((status = privkey_set_rsa_oaep_params( key_data(params->key)->a.privkey, dig, &label ))) return status;
2732
}
2733
2734
e.data = params->input;
2735
e.size = params->input_len;
2736
if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
2737
{
2738
pgnutls_perror( ret );
2739
return STATUS_INTERNAL_ERROR;
2740
}
2741
2742
*params->ret_len = d.size;
2743
if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
2744
else if (params->output) status = STATUS_BUFFER_TOO_SMALL;
2745
2746
free( d.data );
2747
return status;
2748
}
2749
2750
static NTSTATUS pubkey_set_rsa_oaep_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2751
{
2752
gnutls_x509_spki_t spki;
2753
int ret;
2754
2755
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2756
{
2757
pgnutls_perror( ret );
2758
return STATUS_INTERNAL_ERROR;
2759
}
2760
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2761
ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2762
pgnutls_x509_spki_deinit( spki );
2763
if (ret < 0)
2764
{
2765
pgnutls_perror( ret );
2766
return STATUS_INTERNAL_ERROR;
2767
}
2768
return STATUS_SUCCESS;
2769
}
2770
2771
static NTSTATUS key_asymmetric_encrypt( void *args )
2772
{
2773
const struct key_asymmetric_encrypt_params *params = args;
2774
gnutls_datum_t d, e = { 0 };
2775
NTSTATUS status = STATUS_SUCCESS;
2776
int ret;
2777
2778
if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
2779
2780
if (params->key->alg_id == ALG_ID_RSA
2781
&& (!params->output || len_from_bitlen( params->key->u.a.bitlen ) > params->output_len))
2782
{
2783
*params->ret_len = len_from_bitlen( params->key->u.a.bitlen );
2784
return !params->output ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
2785
}
2786
2787
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2788
{
2789
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2790
gnutls_digest_algorithm_t dig;
2791
gnutls_datum_t label;
2792
2793
if (!pad || !pad->pszAlgId || !pad->pbLabel)
2794
{
2795
WARN( "padding info not found\n" );
2796
return STATUS_INVALID_PARAMETER;
2797
}
2798
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2799
{
2800
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2801
return STATUS_NOT_SUPPORTED;
2802
}
2803
2804
label.data = pad->pbLabel;
2805
label.size = pad->cbLabel;
2806
if ((status = pubkey_set_rsa_oaep_params( key_data(params->key)->a.pubkey, dig, &label ))) return status;
2807
}
2808
2809
d.data = params->input;
2810
d.size = params->input_len;
2811
if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
2812
{
2813
pgnutls_perror( ret );
2814
return STATUS_INTERNAL_ERROR;
2815
}
2816
2817
*params->ret_len = e.size;
2818
if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
2819
else if (params->output_len == 0) status = STATUS_SUCCESS;
2820
else status = STATUS_BUFFER_TOO_SMALL;
2821
2822
free( e.data );
2823
return status;
2824
}
2825
2826
static NTSTATUS key_asymmetric_derive_key( void *args )
2827
{
2828
const struct key_asymmetric_derive_key_params *params = args;
2829
gnutls_datum_t s;
2830
NTSTATUS status = STATUS_SUCCESS;
2831
int ret;
2832
2833
if ((ret = pgnutls_privkey_derive_secret( key_data(params->privkey)->a.privkey,
2834
key_data(params->pubkey)->a.pubkey, NULL, &s, 0 )))
2835
{
2836
pgnutls_perror( ret );
2837
return STATUS_INTERNAL_ERROR;
2838
}
2839
2840
*params->ret_len = EXPORT_SIZE( s, len_from_bitlen( params->privkey->u.a.bitlen ), 1 );
2841
if (params->output)
2842
{
2843
if (params->output_len < *params->ret_len) status = STATUS_BUFFER_TOO_SMALL;
2844
else export_gnutls_datum( params->output, *params->ret_len, &s, 1 );
2845
}
2846
2847
free( s.data );
2848
return status;
2849
}
2850
2851
const unixlib_entry_t __wine_unix_call_funcs[] =
2852
{
2853
gnutls_process_attach,
2854
gnutls_process_detach,
2855
key_symmetric_vector_reset,
2856
key_symmetric_set_auth_data,
2857
key_symmetric_encrypt,
2858
key_symmetric_decrypt,
2859
key_symmetric_get_tag,
2860
key_symmetric_destroy,
2861
key_asymmetric_generate,
2862
key_asymmetric_decrypt,
2863
key_asymmetric_encrypt,
2864
key_asymmetric_duplicate,
2865
key_asymmetric_sign,
2866
key_asymmetric_verify,
2867
key_asymmetric_destroy,
2868
key_asymmetric_export,
2869
key_asymmetric_import,
2870
key_asymmetric_derive_key,
2871
};
2872
2873
C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
2874
2875
#ifdef _WIN64
2876
2877
typedef ULONG PTR32;
2878
2879
struct key_symmetric32
2880
{
2881
enum chain_mode mode;
2882
ULONG block_size;
2883
PTR32 vector;
2884
ULONG vector_len;
2885
PTR32 secret;
2886
ULONG secret_len;
2887
ULONG __cs[6];
2888
};
2889
2890
struct key_asymmetric32
2891
{
2892
ULONG bitlen; /* ignored for ECC keys */
2893
ULONG flags;
2894
DSSSEED dss_seed;
2895
};
2896
2897
struct key32
2898
{
2899
struct object hdr;
2900
enum alg_id alg_id;
2901
UINT64 private[PRIVATE_DATA_SIZE]; /* private data for backend */
2902
union
2903
{
2904
struct key_symmetric32 s;
2905
struct key_asymmetric32 a;
2906
} u;
2907
};
2908
2909
union padding
2910
{
2911
BCRYPT_OAEP_PADDING_INFO oaep;
2912
BCRYPT_PKCS1_PADDING_INFO pkcs1;
2913
BCRYPT_PSS_PADDING_INFO pss;
2914
};
2915
2916
union padding32
2917
{
2918
struct
2919
{
2920
PTR32 pszAlgId;
2921
PTR32 pbLabel;
2922
ULONG cbLabel;
2923
} oaep;
2924
struct
2925
{
2926
PTR32 pszAlgId;
2927
} pkcs1;
2928
struct
2929
{
2930
PTR32 pszAlgId;
2931
ULONG cbSalt;
2932
} pss;
2933
};
2934
2935
static union padding *get_padding( union padding32 *padding32, union padding *padding, ULONG flags)
2936
{
2937
if (!padding32) return NULL;
2938
2939
switch (flags)
2940
{
2941
case BCRYPT_PAD_OAEP:
2942
padding->oaep.pszAlgId = ULongToPtr( padding32->oaep.pszAlgId );
2943
padding->oaep.pbLabel = ULongToPtr( padding32->oaep.pbLabel );
2944
padding->oaep.cbLabel = padding32->oaep.cbLabel;
2945
return padding;
2946
2947
case BCRYPT_PAD_PKCS1:
2948
padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
2949
return padding;
2950
2951
case BCRYPT_PAD_PSS:
2952
padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
2953
padding->pss.cbSalt = padding32->pss.cbSalt;
2954
return padding;
2955
2956
default:
2957
break;
2958
}
2959
return NULL;
2960
}
2961
2962
static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
2963
{
2964
key->hdr = key32->hdr;
2965
key->alg_id = key32->alg_id;
2966
memcpy( key->private, key32->private, sizeof(key->private) );
2967
key->u.s.mode = key32->u.s.mode;
2968
key->u.s.block_size = key32->u.s.block_size;
2969
key->u.s.vector = ULongToPtr(key32->u.s.vector);
2970
key->u.s.vector_len = key32->u.s.vector_len;
2971
key->u.s.secret = ULongToPtr(key32->u.s.secret);
2972
key->u.s.secret_len = key32->u.s.secret_len;
2973
return key;
2974
}
2975
2976
static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
2977
{
2978
key->hdr = key32->hdr;
2979
key->alg_id = key32->alg_id;
2980
memcpy( key->private, key32->private, sizeof(key->private) );
2981
key->u.a.bitlen = key32->u.a.bitlen;
2982
key->u.a.flags = key32->u.a.flags;
2983
key->u.a.dss_seed = key32->u.a.dss_seed;
2984
return key;
2985
}
2986
2987
static void put_symmetric_key32( struct key *key, struct key32 *key32 )
2988
{
2989
memcpy( key32->private, key->private, sizeof(key32->private) );
2990
}
2991
2992
static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
2993
{
2994
memcpy( key32->private, key->private, sizeof(key32->private) );
2995
key32->u.a.flags = key->u.a.flags;
2996
key32->u.a.dss_seed = key->u.a.dss_seed;
2997
}
2998
2999
static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
3000
{
3001
NTSTATUS ret;
3002
struct key key;
3003
struct key32 *key32 = args;
3004
3005
ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
3006
put_symmetric_key32( &key, key32 );
3007
return ret;
3008
}
3009
3010
static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
3011
{
3012
struct
3013
{
3014
PTR32 key;
3015
PTR32 auth_data;
3016
ULONG len;
3017
} const *params32 = args;
3018
3019
NTSTATUS ret;
3020
struct key key;
3021
struct key32 *key32 = ULongToPtr( params32->key );
3022
struct key_symmetric_set_auth_data_params params =
3023
{
3024
get_symmetric_key( key32, &key ),
3025
ULongToPtr(params32->auth_data),
3026
params32->len
3027
};
3028
3029
ret = key_symmetric_set_auth_data( &params );
3030
put_symmetric_key32( &key, key32 );
3031
return ret;
3032
}
3033
3034
static NTSTATUS wow64_key_symmetric_encrypt( void *args )
3035
{
3036
struct
3037
{
3038
PTR32 key;
3039
PTR32 input;
3040
ULONG input_len;
3041
PTR32 output;
3042
ULONG output_len;
3043
} const *params32 = args;
3044
3045
NTSTATUS ret;
3046
struct key key;
3047
struct key32 *key32 = ULongToPtr( params32->key );
3048
struct key_symmetric_encrypt_params params =
3049
{
3050
get_symmetric_key( key32, &key ),
3051
ULongToPtr(params32->input),
3052
params32->input_len,
3053
ULongToPtr(params32->output),
3054
params32->output_len
3055
};
3056
3057
ret = key_symmetric_encrypt( &params );
3058
put_symmetric_key32( &key, key32 );
3059
return ret;
3060
}
3061
3062
static NTSTATUS wow64_key_symmetric_decrypt( void *args )
3063
{
3064
struct
3065
{
3066
PTR32 key;
3067
PTR32 input;
3068
ULONG input_len;
3069
PTR32 output;
3070
ULONG output_len;
3071
} const *params32 = args;
3072
3073
NTSTATUS ret;
3074
struct key key;
3075
struct key32 *key32 = ULongToPtr( params32->key );
3076
struct key_symmetric_decrypt_params params =
3077
{
3078
get_symmetric_key( key32, &key ),
3079
ULongToPtr(params32->input),
3080
params32->input_len,
3081
ULongToPtr(params32->output),
3082
params32->output_len
3083
};
3084
3085
ret = key_symmetric_decrypt( &params );
3086
put_symmetric_key32( &key, key32 );
3087
return ret;
3088
}
3089
3090
static NTSTATUS wow64_key_symmetric_get_tag( void *args )
3091
{
3092
struct
3093
{
3094
PTR32 key;
3095
PTR32 tag;
3096
ULONG len;
3097
} const *params32 = args;
3098
3099
NTSTATUS ret;
3100
struct key key;
3101
struct key32 *key32 = ULongToPtr( params32->key );
3102
struct key_symmetric_get_tag_params params =
3103
{
3104
get_symmetric_key( key32, &key ),
3105
ULongToPtr(params32->tag),
3106
params32->len
3107
};
3108
3109
ret = key_symmetric_get_tag( &params );
3110
put_symmetric_key32( &key, key32 );
3111
return ret;
3112
}
3113
3114
static NTSTATUS wow64_key_symmetric_destroy( void *args )
3115
{
3116
struct key32 *key32 = args;
3117
struct key key;
3118
3119
return key_symmetric_destroy( get_symmetric_key( key32, &key ));
3120
}
3121
3122
static NTSTATUS wow64_key_asymmetric_generate( void *args )
3123
{
3124
struct key32 *key32 = args;
3125
struct key key;
3126
NTSTATUS ret;
3127
3128
ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
3129
put_asymmetric_key32( &key, key32 );
3130
return ret;
3131
}
3132
3133
static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
3134
{
3135
struct
3136
{
3137
PTR32 key;
3138
PTR32 input;
3139
ULONG input_len;
3140
PTR32 padding;
3141
PTR32 output;
3142
ULONG output_len;
3143
PTR32 ret_len;
3144
ULONG flags;
3145
} const *params32 = args;
3146
3147
NTSTATUS ret;
3148
struct key key;
3149
union padding padding;
3150
struct key32 *key32 = ULongToPtr( params32->key );
3151
struct key_asymmetric_decrypt_params params =
3152
{
3153
get_asymmetric_key( key32, &key ),
3154
ULongToPtr(params32->input),
3155
params32->input_len,
3156
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
3157
ULongToPtr(params32->output),
3158
params32->output_len,
3159
ULongToPtr(params32->ret_len),
3160
params32->flags
3161
};
3162
3163
ret = key_asymmetric_decrypt( &params );
3164
put_asymmetric_key32( &key, key32 );
3165
return ret;
3166
}
3167
3168
static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
3169
{
3170
struct
3171
{
3172
PTR32 key;
3173
PTR32 input;
3174
ULONG input_len;
3175
PTR32 padding;
3176
PTR32 output;
3177
ULONG output_len;
3178
PTR32 ret_len;
3179
ULONG flags;
3180
} const *params32 = args;
3181
3182
NTSTATUS ret;
3183
struct key key;
3184
union padding padding;
3185
struct key32 *key32 = ULongToPtr( params32->key );
3186
struct key_asymmetric_encrypt_params params =
3187
{
3188
get_asymmetric_key( key32, &key ),
3189
ULongToPtr(params32->input),
3190
params32->input_len,
3191
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
3192
ULongToPtr(params32->output),
3193
params32->output_len,
3194
ULongToPtr(params32->ret_len),
3195
params32->flags
3196
};
3197
3198
ret = key_asymmetric_encrypt( &params );
3199
put_asymmetric_key32( &key, key32 );
3200
return ret;
3201
}
3202
3203
static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
3204
{
3205
struct
3206
{
3207
PTR32 key_orig;
3208
PTR32 key_copy;
3209
} const *params32 = args;
3210
3211
NTSTATUS ret;
3212
struct key key_orig, key_copy;
3213
struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
3214
struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
3215
struct key_asymmetric_duplicate_params params =
3216
{
3217
get_asymmetric_key( key_orig32, &key_orig ),
3218
get_asymmetric_key( key_copy32, &key_copy )
3219
};
3220
3221
ret = key_asymmetric_duplicate( &params );
3222
put_asymmetric_key32( &key_copy, key_copy32 );
3223
return ret;
3224
}
3225
3226
static NTSTATUS wow64_key_asymmetric_sign( void *args )
3227
{
3228
struct
3229
{
3230
PTR32 key;
3231
PTR32 padding;
3232
PTR32 input;
3233
ULONG input_len;
3234
PTR32 output;
3235
ULONG output_len;
3236
PTR32 ret_len;
3237
ULONG flags;
3238
} const *params32 = args;
3239
3240
NTSTATUS ret;
3241
struct key key;
3242
union padding padding;
3243
struct key32 *key32 = ULongToPtr( params32->key );
3244
struct key_asymmetric_sign_params params =
3245
{
3246
get_asymmetric_key( key32, &key ),
3247
get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
3248
ULongToPtr(params32->input),
3249
params32->input_len,
3250
ULongToPtr(params32->output),
3251
params32->output_len,
3252
ULongToPtr(params32->ret_len),
3253
params32->flags
3254
};
3255
3256
ret = key_asymmetric_sign( &params );
3257
put_asymmetric_key32( &key, key32 );
3258
return ret;
3259
}
3260
3261
static NTSTATUS wow64_key_asymmetric_verify( void *args )
3262
{
3263
struct
3264
{
3265
PTR32 key;
3266
PTR32 padding;
3267
PTR32 hash;
3268
ULONG hash_len;
3269
PTR32 signature;
3270
ULONG signature_len;
3271
ULONG flags;
3272
} const *params32 = args;
3273
3274
NTSTATUS ret;
3275
struct key key;
3276
union padding padding;
3277
struct key32 *key32 = ULongToPtr( params32->key );
3278
struct key_asymmetric_verify_params params =
3279
{
3280
get_asymmetric_key( key32, &key ),
3281
get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
3282
ULongToPtr(params32->hash),
3283
params32->hash_len,
3284
ULongToPtr(params32->signature),
3285
params32->signature_len,
3286
params32->flags
3287
};
3288
3289
ret = key_asymmetric_verify( &params );
3290
put_asymmetric_key32( &key, key32 );
3291
return ret;
3292
}
3293
3294
static NTSTATUS wow64_key_asymmetric_destroy( void *args )
3295
{
3296
struct key32 *key32 = args;
3297
struct key key;
3298
3299
return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
3300
}
3301
3302
static NTSTATUS wow64_key_asymmetric_export( void *args )
3303
{
3304
struct
3305
{
3306
PTR32 key;
3307
ULONG flags;
3308
PTR32 buf;
3309
ULONG len;
3310
PTR32 ret_len;
3311
} const *params32 = args;
3312
3313
NTSTATUS ret;
3314
struct key key;
3315
struct key32 *key32 = ULongToPtr( params32->key );
3316
struct key_asymmetric_export_params params =
3317
{
3318
get_asymmetric_key( key32, &key ),
3319
params32->flags,
3320
ULongToPtr(params32->buf),
3321
params32->len,
3322
ULongToPtr(params32->ret_len),
3323
};
3324
3325
ret = key_asymmetric_export( &params );
3326
put_asymmetric_key32( &key, key32 );
3327
return ret;
3328
}
3329
3330
static NTSTATUS wow64_key_asymmetric_import( void *args )
3331
{
3332
struct
3333
{
3334
PTR32 key;
3335
ULONG flags;
3336
PTR32 buf;
3337
ULONG len;
3338
} const *params32 = args;
3339
3340
NTSTATUS ret;
3341
struct key key;
3342
struct key32 *key32 = ULongToPtr( params32->key );
3343
struct key_asymmetric_import_params params =
3344
{
3345
get_asymmetric_key( key32, &key ),
3346
params32->flags,
3347
ULongToPtr(params32->buf),
3348
params32->len
3349
};
3350
3351
ret = key_asymmetric_import( &params );
3352
put_asymmetric_key32( &key, key32 );
3353
return ret;
3354
}
3355
3356
static NTSTATUS wow64_key_asymmetric_derive_key( void *args )
3357
{
3358
struct
3359
{
3360
PTR32 privkey;
3361
PTR32 pubkey;
3362
PTR32 output;
3363
ULONG output_len;
3364
PTR32 ret_len;
3365
} const *params32 = args;
3366
3367
NTSTATUS ret;
3368
struct key privkey, pubkey;
3369
struct key32 *privkey32 = ULongToPtr( params32->privkey );
3370
struct key32 *pubkey32 = ULongToPtr( params32->pubkey );
3371
struct key_asymmetric_derive_key_params params =
3372
{
3373
get_asymmetric_key( privkey32, &privkey ),
3374
get_asymmetric_key( pubkey32, &pubkey ),
3375
ULongToPtr(params32->output),
3376
params32->output_len,
3377
ULongToPtr(params32->ret_len),
3378
};
3379
3380
ret = key_asymmetric_derive_key( &params );
3381
put_asymmetric_key32( &privkey, privkey32 );
3382
put_asymmetric_key32( &pubkey, pubkey32 );
3383
return ret;
3384
}
3385
3386
const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
3387
{
3388
gnutls_process_attach,
3389
gnutls_process_detach,
3390
wow64_key_symmetric_vector_reset,
3391
wow64_key_symmetric_set_auth_data,
3392
wow64_key_symmetric_encrypt,
3393
wow64_key_symmetric_decrypt,
3394
wow64_key_symmetric_get_tag,
3395
wow64_key_symmetric_destroy,
3396
wow64_key_asymmetric_generate,
3397
wow64_key_asymmetric_decrypt,
3398
wow64_key_asymmetric_encrypt,
3399
wow64_key_asymmetric_duplicate,
3400
wow64_key_asymmetric_sign,
3401
wow64_key_asymmetric_verify,
3402
wow64_key_asymmetric_destroy,
3403
wow64_key_asymmetric_export,
3404
wow64_key_asymmetric_import,
3405
wow64_key_asymmetric_derive_key,
3406
};
3407
3408
C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count );
3409
3410
#endif /* _WIN64 */
3411
3412
#endif /* HAVE_GNUTLS_CIPHER_INIT */
3413
3414