ReactOS 0.4.17-dev-863-gc5f151a
gnutls.c
Go to the documentation of this file.
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#include "precomp.h"
22
23#ifdef HAVE_GNUTLS_HASH
24
25#include <stdarg.h>
26#include <stdlib.h>
27#include <assert.h>
28#include <sys/types.h>
29#include <dlfcn.h>
30#include <gnutls/gnutls.h>
31#include <gnutls/crypto.h>
32#include <gnutls/abstract.h>
33
34#include "ntstatus.h"
35#define WIN32_NO_STATUS
36#include "windef.h"
37#include "winbase.h"
38#include "winternl.h"
39#include "ntsecapi.h"
40#include "wincrypt.h"
41#include "bcrypt.h"
42
43#include "bcrypt_internal.h"
44
45#include "wine/debug.h"
46
49
50#if GNUTLS_VERSION_MAJOR < 3
51#define GNUTLS_CIPHER_AES_192_CBC 92
52#define GNUTLS_CIPHER_AES_128_GCM 93
53#define GNUTLS_CIPHER_AES_256_GCM 94
54#define GNUTLS_PK_ECC 4
55
56#define GNUTLS_CURVE_TO_BITS(curve) (unsigned int)(((unsigned int)1<<31)|((unsigned int)(curve)))
57
58typedef enum
59{
60 GNUTLS_ECC_CURVE_INVALID,
61 GNUTLS_ECC_CURVE_SECP224R1,
62 GNUTLS_ECC_CURVE_SECP256R1,
63 GNUTLS_ECC_CURVE_SECP384R1,
64 GNUTLS_ECC_CURVE_SECP521R1,
65} gnutls_ecc_curve_t;
66#endif
67
68#if GNUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 6)
69#define GNUTLS_CIPHER_AES_128_CFB8 29
70#define GNUTLS_CIPHER_AES_192_CFB8 30
71#define GNUTLS_CIPHER_AES_256_CFB8 31
72
73#define GNUTLS_PK_RSA_PSS 6
74#define GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS (1 << 7)
75typedef struct gnutls_x509_spki_st *gnutls_x509_spki_t;
76#endif
77
78#if GUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 8)
79#define GNUTLS_KEYGEN_DH 4
80#endif
81
82union key_data
83{
84 gnutls_cipher_hd_t cipher;
85 struct
86 {
87 gnutls_privkey_t privkey;
88 gnutls_pubkey_t pubkey;
89 gnutls_dh_params_t dh_params;
90 } a;
91};
92C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
93
94static union key_data *key_data( struct key *key )
95{
96 return (union key_data *)key->private;
97}
98
99/* Not present in gnutls version < 3.0 */
100static int (*pgnutls_cipher_tag)(gnutls_cipher_hd_t, void *, size_t);
101static int (*pgnutls_cipher_add_auth)(gnutls_cipher_hd_t, const void *, size_t);
102static gnutls_sign_algorithm_t (*pgnutls_pk_to_sign)(gnutls_pk_algorithm_t, gnutls_digest_algorithm_t);
103static int (*pgnutls_pubkey_import_ecc_raw)(gnutls_pubkey_t, gnutls_ecc_curve_t,
104 const gnutls_datum_t *, const gnutls_datum_t *);
105static int (*pgnutls_pubkey_export_ecc_raw)(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
106 gnutls_datum_t *x, gnutls_datum_t *y);
107static int (*pgnutls_privkey_import_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t, const gnutls_datum_t *,
108 const gnutls_datum_t *, const gnutls_datum_t *);
109static int (*pgnutls_pubkey_verify_hash2)(gnutls_pubkey_t, gnutls_sign_algorithm_t, unsigned int,
110 const gnutls_datum_t *, const gnutls_datum_t *);
111static int (*pgnutls_pubkey_encrypt_data)(gnutls_pubkey_t, unsigned int flags, const gnutls_datum_t *,
112 gnutls_datum_t *);
113
114/* Not present in gnutls version < 2.11.0 */
115static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *);
116
117/* Not present in gnutls version < 2.12.0 */
118static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
119 const gnutls_datum_t *, const gnutls_datum_t *);
120static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
121static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *,
122 gnutls_datum_t *);
123
124/* Not present in gnutls version < 3.3.0 */
125static int (*pgnutls_pubkey_export_dsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
126 gnutls_datum_t *);
127static int (*pgnutls_pubkey_export_rsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *);
128static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
129 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
130static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
131 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
132 gnutls_datum_t *);
133static int (*pgnutls_privkey_export_dsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
134 gnutls_datum_t *, gnutls_datum_t *);
135static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
136 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
137 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
138
139/* Not present in gnutls version < 3.5.0 */
140static int (*pgnutls_privkey_generate2)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int,
141 const gnutls_keygen_data_st *, unsigned);
142
143/* Not present in gnutls version < 3.6.0 */
144static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
145static int (*pgnutls_x509_spki_init)(gnutls_x509_spki_t *);
146static void (*pgnutls_x509_spki_deinit)(gnutls_x509_spki_t);
147static void (*pgnutls_x509_spki_set_rsa_pss_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, unsigned int);
148static int (*pgnutls_pubkey_set_spki)(gnutls_pubkey_t, const gnutls_x509_spki_t, unsigned int);
149static int (*pgnutls_privkey_set_spki)(gnutls_privkey_t, const gnutls_x509_spki_t, unsigned int);
150
151/* Not present in gnutls version < 3.8.2 */
152static int (*pgnutls_privkey_derive_secret)(gnutls_privkey_t, gnutls_pubkey_t, const gnutls_datum_t *,
153 gnutls_datum_t *, unsigned int);
154static int (*pgnutls_privkey_export_dh_raw)(gnutls_privkey_t, gnutls_dh_params_t, gnutls_datum_t *, gnutls_datum_t *,
155 unsigned int);
156static int (*pgnutls_pubkey_export_dh_raw)(gnutls_pubkey_t, gnutls_dh_params_t, gnutls_datum_t *, unsigned);
157static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_params_t, const gnutls_datum_t *,
158 const gnutls_datum_t *);
159static int (*pgnutls_pubkey_import_dh_raw)(gnutls_pubkey_t, const gnutls_dh_params_t, const gnutls_datum_t *);
160
161/* Not present in gnutls version < 3.8.4 */
162static int (*pgnutls_x509_spki_set_rsa_oaep_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, gnutls_datum_t *);
163
164static void *libgnutls_handle;
165#define MAKE_FUNCPTR(f) static typeof(f) * p##f
166MAKE_FUNCPTR(gnutls_cipher_decrypt2);
167MAKE_FUNCPTR(gnutls_cipher_deinit);
168MAKE_FUNCPTR(gnutls_cipher_encrypt2);
169MAKE_FUNCPTR(gnutls_cipher_init);
170MAKE_FUNCPTR(gnutls_dh_params_deinit);
171MAKE_FUNCPTR(gnutls_dh_params_export_raw);
172MAKE_FUNCPTR(gnutls_dh_params_import_raw);
173MAKE_FUNCPTR(gnutls_dh_params_init);
174MAKE_FUNCPTR(gnutls_global_deinit);
175MAKE_FUNCPTR(gnutls_global_init);
176MAKE_FUNCPTR(gnutls_global_set_log_function);
177MAKE_FUNCPTR(gnutls_global_set_log_level);
178MAKE_FUNCPTR(gnutls_hash);
179MAKE_FUNCPTR(gnutls_hash_deinit);
180MAKE_FUNCPTR(gnutls_hash_init);
181MAKE_FUNCPTR(gnutls_hmac);
182MAKE_FUNCPTR(gnutls_hmac_deinit);
183MAKE_FUNCPTR(gnutls_hmac_init);
184MAKE_FUNCPTR(gnutls_perror);
185MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
186MAKE_FUNCPTR(gnutls_privkey_deinit);
187MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
188MAKE_FUNCPTR(gnutls_privkey_init);
189MAKE_FUNCPTR(gnutls_privkey_sign_hash);
190MAKE_FUNCPTR(gnutls_pubkey_deinit);
191MAKE_FUNCPTR(gnutls_pubkey_encrypt_data);
192MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
193MAKE_FUNCPTR(gnutls_pubkey_init);
194#undef MAKE_FUNCPTR
195
196static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle, void *tag, size_t tag_size)
197{
198 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
199}
200
201static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle, const void *ptext, size_t ptext_size)
202{
203 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
204}
205
206static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
207 const gnutls_datum_t *x, const gnutls_datum_t *y)
208{
209 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
210}
211
212static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
213 gnutls_datum_t *x, gnutls_datum_t *y)
214{
215 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
216}
217
218static int compat_gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
219 gnutls_datum_t *g, gnutls_datum_t *y)
220{
221 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
222}
223
224static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m, gnutls_datum_t *e)
225{
226 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
227}
228
229static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t *m, gnutls_datum_t *e,
230 gnutls_datum_t *d, gnutls_datum_t *p, gnutls_datum_t *q,
231 gnutls_datum_t *u, gnutls_datum_t *e1, gnutls_datum_t *e2)
232{
233 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
234}
235
236static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t *curve,
237 gnutls_datum_t *x, gnutls_datum_t *y, gnutls_datum_t *k)
238{
239 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
240}
241
242static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t curve,
243 const gnutls_datum_t *x, const gnutls_datum_t *y,
244 const gnutls_datum_t *k)
245{
246 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
247}
248
249static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
250 gnutls_datum_t *g, gnutls_datum_t *y, gnutls_datum_t *x)
251{
252 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
253}
254
255static gnutls_sign_algorithm_t compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
256{
257 return GNUTLS_SIGN_UNKNOWN;
258}
259
260static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo,
261 unsigned int flags, const gnutls_datum_t *hash,
262 const gnutls_datum_t *signature)
263{
264 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
265}
266
267static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e)
268{
269 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
270}
271
272static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p, const gnutls_datum_t *q,
273 const gnutls_datum_t *g, const gnutls_datum_t *y)
274{
275 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
276}
277
278static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
279{
280 return GNUTLS_E_INTERNAL_ERROR;
281}
282
283static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e,
284 const gnutls_datum_t *d, const gnutls_datum_t *p, const gnutls_datum_t *q,
285 const gnutls_datum_t *u, const gnutls_datum_t *e1, const gnutls_datum_t *e2)
286{
287 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
288}
289
290static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
291 gnutls_datum_t *plain_text)
292{
293 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
294}
295
296static int compat_gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
297 gnutls_datum_t *plain_text)
298{
299 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
300}
301
302static int compat_gnutls_x509_spki_init(gnutls_x509_spki_t *spki)
303{
304 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
305}
306
307static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki)
308{
309}
310
311static int compat_gnutls_x509_spki_set_rsa_oaep_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
312 gnutls_datum_t *label)
313{
314 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
315}
316
317static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
318 unsigned int salt_size)
319{
320}
321
322static int compat_gnutls_pubkey_set_spki(gnutls_pubkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
323{
324 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
325}
326
327static int compat_gnutls_privkey_set_spki(gnutls_privkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
328{
329 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
330}
331
332static int compat_gnutls_privkey_derive_secret(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey, const gnutls_datum_t *nonce,
333 gnutls_datum_t *secret, unsigned int flags)
334{
335 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
336}
337
338static int compat_gnutls_privkey_export_dh_raw(gnutls_privkey_t privkey, gnutls_dh_params_t params, gnutls_datum_t *y,
339 gnutls_datum_t *x, unsigned int flags )
340{
341 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
342}
343
344static int compat_gnutls_pubkey_export_dh_raw(gnutls_pubkey_t pubkey, gnutls_dh_params_t params, gnutls_datum_t *y,
345 unsigned flags)
346{
347 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
348}
349
350static int compat_gnutls_privkey_import_dh_raw(gnutls_privkey_t privkey, const gnutls_dh_params_t params,
351 const gnutls_datum_t *y, const gnutls_datum_t *x)
352{
353 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
354}
355
356static int compat_gnutls_pubkey_import_dh_raw(gnutls_pubkey_t pubkey, const gnutls_dh_params_t params,
357 const gnutls_datum_t *y)
358{
359 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
360}
361
362static int compat_gnutls_privkey_generate2(gnutls_privkey_t privkey, gnutls_pk_algorithm_t alg, unsigned int bits,
363 unsigned int flags, const gnutls_keygen_data_st *data, unsigned data_size)
364{
365 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
366}
367
368static void gnutls_log( int level, const char *msg )
369{
370 TRACE( "<%d> %s", level, msg );
371}
372
374{
375 const char *env_str;
376 int ret;
377
378 if ((env_str = getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
379 {
380 WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str));
381 }
382 else
383 {
384 WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
385 setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
386 }
387
388 if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
389 {
390 ERR_(winediag)( "failed to load libgnutls, no support for encryption\n" );
392 }
393
394#define LOAD_FUNCPTR(f) \
395 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
396 { \
397 ERR( "failed to load %s\n", #f ); \
398 goto fail; \
399 }
400
401 LOAD_FUNCPTR(gnutls_cipher_decrypt2)
402 LOAD_FUNCPTR(gnutls_cipher_deinit)
403 LOAD_FUNCPTR(gnutls_cipher_encrypt2)
404 LOAD_FUNCPTR(gnutls_cipher_init)
405 LOAD_FUNCPTR(gnutls_dh_params_deinit)
406 LOAD_FUNCPTR(gnutls_dh_params_export_raw)
407 LOAD_FUNCPTR(gnutls_dh_params_import_raw)
408 LOAD_FUNCPTR(gnutls_dh_params_init)
409 LOAD_FUNCPTR(gnutls_global_deinit)
410 LOAD_FUNCPTR(gnutls_global_init)
411 LOAD_FUNCPTR(gnutls_global_set_log_function)
412 LOAD_FUNCPTR(gnutls_global_set_log_level)
413 LOAD_FUNCPTR(gnutls_hash);
414 LOAD_FUNCPTR(gnutls_hash_deinit);
415 LOAD_FUNCPTR(gnutls_hash_init);
416 LOAD_FUNCPTR(gnutls_hmac);
417 LOAD_FUNCPTR(gnutls_hmac_deinit);
418 LOAD_FUNCPTR(gnutls_hmac_init);
419 LOAD_FUNCPTR(gnutls_perror);
420 LOAD_FUNCPTR(gnutls_privkey_deinit);
421 LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw);
422 LOAD_FUNCPTR(gnutls_privkey_init);
423 LOAD_FUNCPTR(gnutls_privkey_sign_hash);
424 LOAD_FUNCPTR(gnutls_pubkey_deinit);
425 LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
426 LOAD_FUNCPTR(gnutls_pubkey_init);
427#undef LOAD_FUNCPTR
428
429#define LOAD_FUNCPTR_OPT(f) \
430 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
431 { \
432 WARN( "failed to load %s\n", #f ); \
433 p##f = compat_##f; \
434 }
435
436 LOAD_FUNCPTR_OPT(gnutls_cipher_tag)
437 LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth)
438 LOAD_FUNCPTR_OPT(gnutls_decode_rs_value)
439 LOAD_FUNCPTR_OPT(gnutls_pk_to_sign)
440 LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data)
441 LOAD_FUNCPTR_OPT(gnutls_privkey_derive_secret)
442 LOAD_FUNCPTR_OPT(gnutls_privkey_export_dh_raw)
443 LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw)
444 LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw)
445 LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw)
446 LOAD_FUNCPTR_OPT(gnutls_privkey_generate2)
447 LOAD_FUNCPTR_OPT(gnutls_privkey_import_dh_raw)
448 LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw)
449 LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw)
450 LOAD_FUNCPTR_OPT(gnutls_privkey_set_spki)
451 LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data)
452 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dh_raw)
453 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw)
454 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw)
455 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw)
456 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dh_raw)
457 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw)
458 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw)
459 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw)
460 LOAD_FUNCPTR_OPT(gnutls_pubkey_set_spki)
461 LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
462 LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit)
463 LOAD_FUNCPTR_OPT(gnutls_x509_spki_init)
464 LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_oaep_params)
465 LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params)
466
467#undef LOAD_FUNCPTR_OPT
468
469 if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
470 {
471 pgnutls_perror( ret );
472 goto fail;
473 }
474
475 if (TRACE_ON( bcrypt ))
476 {
477 char *env = getenv("GNUTLS_DEBUG_LEVEL");
478 int level = env ? atoi(env) : 4;
479 pgnutls_global_set_log_level(level);
480 pgnutls_global_set_log_function( gnutls_log );
481 }
482
483 return STATUS_SUCCESS;
484
485fail:
486 dlclose( libgnutls_handle );
487 libgnutls_handle = NULL;
489}
490
492{
493 if (libgnutls_handle)
494 {
495 pgnutls_global_deinit();
496 dlclose( libgnutls_handle );
497 libgnutls_handle = NULL;
498 }
499 return STATUS_SUCCESS;
500}
501
502struct buffer
503{
504 BYTE *buffer;
506 DWORD pos;
507 BOOL error;
508};
509
510static void buffer_init( struct buffer *buffer )
511{
512 buffer->buffer = NULL;
513 buffer->length = 0;
514 buffer->pos = 0;
515 buffer->error = FALSE;
516}
517
518static void buffer_free( struct buffer *buffer )
519{
520 free( buffer->buffer );
521}
522
523static void buffer_append( struct buffer *buffer, BYTE *data, DWORD len )
524{
525 if (!len) return;
526
527 if (buffer->pos + len > buffer->length)
528 {
529 DWORD new_length = max( max( buffer->pos + len, buffer->length * 2 ), 64 );
530 BYTE *new_buffer;
531
532 if (!(new_buffer = realloc( buffer->buffer, new_length )))
533 {
534 ERR( "out of memory\n" );
535 buffer->error = TRUE;
536 return;
537 }
538
539 buffer->buffer = new_buffer;
540 buffer->length = new_length;
541 }
542
543 memcpy( &buffer->buffer[buffer->pos], data, len );
544 buffer->pos += len;
545}
546
547static void buffer_append_byte( struct buffer *buffer, BYTE value )
548{
549 buffer_append( buffer, &value, sizeof(value) );
550}
551
552static void buffer_append_asn1_length( struct buffer *buffer, DWORD length )
553{
554 DWORD num_bytes;
555
556 if (length < 128)
557 {
558 buffer_append_byte( buffer, length );
559 return;
560 }
561
562 if (length <= 0xff) num_bytes = 1;
563 else if (length <= 0xffff) num_bytes = 2;
564 else if (length <= 0xffffff) num_bytes = 3;
565 else num_bytes = 4;
566
567 buffer_append_byte( buffer, 0x80 | num_bytes );
568 while (num_bytes--) buffer_append_byte( buffer, length >> (num_bytes * 8) );
569}
570
571static void buffer_append_asn1_integer( struct buffer *buffer, BYTE *data, DWORD len )
572{
573 DWORD leading_zero = (*data & 0x80) != 0;
574
575 buffer_append_byte( buffer, 0x02 ); /* tag */
576 buffer_append_asn1_length( buffer, len + leading_zero );
577 if (leading_zero) buffer_append_byte( buffer, 0 );
578 buffer_append( buffer, data, len );
579}
580
581static void buffer_append_asn1_sequence( struct buffer *buffer, struct buffer *content )
582{
583 if (content->error)
584 {
585 buffer->error = TRUE;
586 return;
587 }
588
589 buffer_append_byte( buffer, 0x30 ); /* tag */
590 buffer_append_asn1_length( buffer, content->pos );
591 buffer_append( buffer, content->buffer, content->pos );
592}
593
594static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *s, DWORD s_len )
595{
596 struct buffer value;
597
598 buffer_init( &value );
599 buffer_append_asn1_integer( &value, r, r_len );
600 buffer_append_asn1_integer( &value, s, s_len );
601 buffer_append_asn1_sequence( buffer, &value );
602 buffer_free( &value );
603}
604
605static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
606{
607 switch (key->alg_id)
608 {
609 case ALG_ID_3DES:
610 WARN( "handle block size\n" );
611 switch (key->u.s.mode)
612 {
613 case CHAIN_MODE_CBC:
614 return GNUTLS_CIPHER_3DES_CBC;
615 default:
616 break;
617 }
618 FIXME( "3DES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
619 return GNUTLS_CIPHER_UNKNOWN;
620
621 case ALG_ID_AES:
622 WARN( "handle block size\n" );
623 switch (key->u.s.mode)
624 {
625 case CHAIN_MODE_GCM:
626 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_GCM;
627 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_GCM;
628 break;
629 case CHAIN_MODE_ECB: /* can be emulated with CBC + empty IV */
630 case CHAIN_MODE_CBC:
631 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CBC;
632 if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CBC;
633 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CBC;
634 break;
635 case CHAIN_MODE_CFB:
636 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CFB8;
637 if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CFB8;
638 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CFB8;
639 break;
640 default:
641 break;
642 }
643 FIXME( "AES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
644 return GNUTLS_CIPHER_UNKNOWN;
645
646 default:
647 FIXME( "algorithm %u not supported\n", key->alg_id );
648 return GNUTLS_CIPHER_UNKNOWN;
649 }
650}
651
653{
654 struct key *key = args;
655
656 if (!key_data(key)->cipher) return STATUS_SUCCESS;
657 TRACE( "invalidating cipher handle\n" );
658 pgnutls_cipher_deinit( key_data(key)->cipher );
659 key_data(key)->cipher = NULL;
660 return STATUS_SUCCESS;
661}
662
663static NTSTATUS init_cipher_handle( struct key *key )
664{
665 gnutls_cipher_algorithm_t cipher;
666 gnutls_datum_t secret, vector;
667 int ret;
668
669 if (key_data(key)->cipher) return STATUS_SUCCESS;
670 if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
671
672 secret.data = key->u.s.secret;
673 secret.size = key->u.s.secret_len;
674
675 vector.data = key->u.s.vector;
676 vector.size = key->u.s.vector_len;
677
678 if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
679 {
680 pgnutls_perror( ret );
682 }
683
684 return STATUS_SUCCESS;
685}
686
688{
691 int ret;
692
693 if (!params->auth_data) return STATUS_SUCCESS;
694 if ((status = init_cipher_handle( params->key ))) return status;
695
696 if ((ret = pgnutls_cipher_add_auth( key_data(params->key)->cipher, params->auth_data, params->len )))
697 {
698 pgnutls_perror( ret );
700 }
701 return STATUS_SUCCESS;
702}
703
705{
708 int ret;
709
710 if ((status = init_cipher_handle( params->key ))) return status;
711
712 if ((ret = pgnutls_cipher_encrypt2( key_data(params->key)->cipher, params->input, params->input_len,
713 params->output, params->output_len )))
714 {
715 pgnutls_perror( ret );
717 }
718 return STATUS_SUCCESS;
719}
720
722{
725 int ret;
726
727 if ((status = init_cipher_handle( params->key ))) return status;
728
729 if ((ret = pgnutls_cipher_decrypt2( key_data(params->key)->cipher, params->input, params->input_len,
730 params->output, params->output_len )))
731 {
732 pgnutls_perror( ret );
734 }
735 return STATUS_SUCCESS;
736}
737
739{
742 int ret;
743
744 if ((status = init_cipher_handle( params->key ))) return status;
745
746 if ((ret = pgnutls_cipher_tag( key_data(params->key)->cipher, params->tag, params->len )))
747 {
748 pgnutls_perror( ret );
750 }
751 return STATUS_SUCCESS;
752}
753
755{
756 struct key *key = args;
757
758 if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
759 return STATUS_SUCCESS;
760}
761
762static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d, BOOL zero_pad )
763{
764 ULONG size = d->size;
765 UCHAR *src = d->data;
766 ULONG offset = 0;
767
768 assert( size <= buflen + 1 );
769 if (size == buflen + 1)
770 {
771 assert( !src[0] );
772 src++;
773 size--;
774 }
775 if (zero_pad)
776 {
777 offset = buflen - size;
778 if (buffer) memset( buffer, 0, offset );
779 size = buflen;
780 }
781
782 if (buffer) memcpy( buffer + offset, src, size - offset );
783 return size;
784}
785
786#define EXPORT_SIZE(d,l,p) export_gnutls_datum( NULL, l, &d, p )
787static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
788{
790 gnutls_datum_t m, e;
791 ULONG size = key->u.a.bitlen / 8;
792 UCHAR *dst;
793 int ret;
794
795 if (key_data(key)->a.pubkey)
796 ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e );
797 else
799
800 if (ret)
801 {
802 pgnutls_perror( ret );
804 }
805
806 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 );
807 if (len >= *ret_len && buf)
808 {
809 dst = (UCHAR *)(rsa_blob + 1);
810 rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
811
812 dst += rsa_blob->cbPublicExp;
813 rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
814
815 rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
816 rsa_blob->BitLength = key->u.a.bitlen;
817 rsa_blob->cbPrime1 = 0;
818 rsa_blob->cbPrime2 = 0;
819 }
820
821 free( e.data ); free( m.data );
822 return STATUS_SUCCESS;
823}
824
825static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
826{
828 gnutls_ecc_curve_t curve;
829 gnutls_datum_t x, y;
830 DWORD magic, size;
831 UCHAR *dst;
832 int ret;
833
834 switch (key->alg_id)
835 {
836 case ALG_ID_ECDH_P256:
838 size = 32;
839 break;
840
841 case ALG_ID_ECDH_P384:
843 size = 48;
844 break;
845
848 size = 32;
849 break;
850
853 size = 48;
854 break;
855
856 default:
857 FIXME( "algorithm %u not supported\n", key->alg_id );
859 }
860
861 if (key_data(key)->a.pubkey)
862 ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
863 else
865
866 if (ret)
867 {
868 pgnutls_perror( ret );
870 }
871
872 if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1)
873 {
874 FIXME( "curve %u not supported\n", curve );
875 free( x.data ); free( y.data );
877 }
878
879 *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 );
880 if (len >= *ret_len && buf)
881 {
882 ecc_blob->dwMagic = magic;
883 ecc_blob->cbKey = size;
884
885 dst = (UCHAR *)(ecc_blob + 1);
886 dst += export_gnutls_datum( dst, size, &x, 1 );
887 export_gnutls_datum( dst, size, &y, 1 );
888 }
889
890 free( x.data ); free( y.data );
891 return STATUS_SUCCESS;
892}
893
894static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
895{
897 gnutls_datum_t p, q, g, y;
898 ULONG size = key->u.a.bitlen / 8;
900 UCHAR *dst;
901 int ret;
902
903 if (key->u.a.bitlen > 1024)
904 {
905 FIXME( "bitlen > 1024 not supported\n" );
907 }
908
909 if (key_data(key)->a.pubkey)
910 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
911 else
913
914 if (ret)
915 {
916 pgnutls_perror( ret );
918 }
919
920 if (EXPORT_SIZE( q, sizeof(dsa_blob->q), 1 ) > sizeof(dsa_blob->q))
921 {
923 goto done;
924 }
925
926 *ret_len = sizeof(*dsa_blob) + EXPORT_SIZE( p, size, 1 ) + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
927 if (len >= *ret_len && buf)
928 {
929 dst = (UCHAR *)(dsa_blob + 1);
930 dst += export_gnutls_datum( dst, size, &p, 1 );
931 dst += export_gnutls_datum( dst, size, &g, 1 );
932 export_gnutls_datum( dst, size, &y, 1 );
933
934 dst = dsa_blob->q;
935 export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
936
938 dsa_blob->cbKey = size;
939 memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
940 memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
941 }
942
943done:
944 free( p.data ); free( q.data ); free( g.data ); free( y.data );
945 return status;
946}
947
948static void reverse_bytes( UCHAR *buf, ULONG len )
949{
950 unsigned int i;
951 UCHAR tmp;
952
953 for (i = 0; i < len / 2; ++i)
954 {
955 tmp = buf[i];
956 buf[i] = buf[len - i - 1];
957 buf[len - i - 1] = tmp;
958 }
959}
960
961#define Q_SIZE 20
962static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
963{
965 DSSPUBKEY *dsskey;
966 gnutls_datum_t p, q, g, y;
967 ULONG size = key->u.a.bitlen / 8;
969 UCHAR *dst;
970 int ret;
971
972 if (key->u.a.bitlen > 1024)
973 {
974 FIXME( "bitlen > 1024 not supported\n" );
976 }
977
978 if (key_data(key)->a.pubkey)
979 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
980 else if (key_data(key)->a.privkey)
981 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
982 else
984
985 if (ret)
986 {
987 pgnutls_perror( ret );
989 }
990
991 if (EXPORT_SIZE( q, Q_SIZE, 1 ) > Q_SIZE)
992 {
994 goto done;
995 }
996
997 *ret_len = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed) +
998 EXPORT_SIZE( p, size, 1 ) + Q_SIZE + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
999 if (len >= *ret_len && buf)
1000 {
1001 hdr->bType = PUBLICKEYBLOB;
1002 hdr->bVersion = 2;
1003 hdr->reserved = 0;
1004 hdr->aiKeyAlg = CALG_DSS_SIGN;
1005
1006 dsskey = (DSSPUBKEY *)(hdr + 1);
1007 dsskey->magic = MAGIC_DSS1;
1008 dsskey->bitlen = key->u.a.bitlen;
1009
1010 dst = (UCHAR *)(dsskey + 1);
1011 export_gnutls_datum( dst, size, &p, 1 );
1013 dst += size;
1014
1015 export_gnutls_datum( dst, Q_SIZE, &q, 1 );
1016 reverse_bytes( dst, Q_SIZE );
1017 dst += Q_SIZE;
1018
1019 export_gnutls_datum( dst, size, &g, 1 );
1021 dst += size;
1022
1023 export_gnutls_datum( dst, size, &y, 1 );
1025 dst += size;
1026
1027 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1028 }
1029
1030done:
1031 free( p.data ); free( q.data ); free( g.data ); free( y.data );
1032 return status;
1033}
1034
1035static gnutls_privkey_t create_privkey( gnutls_pk_algorithm_t pk_alg, unsigned int bitlen,
1036 const gnutls_keygen_data_st *data, unsigned int data_size )
1037{
1038 gnutls_privkey_t privkey;
1039 int ret;
1040
1041 if ((ret = pgnutls_privkey_init( &privkey )))
1042 {
1043 pgnutls_perror( ret );
1044 return NULL;
1045 }
1046
1047 if ((ret = pgnutls_privkey_generate2( privkey, pk_alg, bitlen, 0, data, data_size )))
1048 {
1049 pgnutls_perror( ret );
1050 pgnutls_privkey_deinit( privkey );
1051 return NULL;
1052 }
1053
1054 return privkey;
1055}
1056
1057static gnutls_pubkey_t create_pubkey_from_privkey( gnutls_privkey_t privkey )
1058{
1059 gnutls_pubkey_t pubkey;
1060 int ret;
1061
1062 if ((ret = pgnutls_pubkey_init( &pubkey )))
1063 {
1064 pgnutls_perror( ret );
1065 return NULL;
1066 }
1067
1068 if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
1069 {
1070 pgnutls_perror( ret );
1071 pgnutls_pubkey_deinit( pubkey );
1072 return NULL;
1073 }
1074
1075 return pubkey;
1076}
1077
1078static gnutls_dh_params_t get_dh_params( gnutls_privkey_t privkey )
1079{
1080 gnutls_dh_params_t params;
1081 gnutls_datum_t x;
1082 int ret;
1083
1084 if ((ret = pgnutls_dh_params_init( &params )))
1085 {
1086 pgnutls_perror( ret );
1087 return NULL;
1088 }
1089
1090 if ((ret = pgnutls_privkey_export_dh_raw( privkey, params, NULL, &x, 0 )))
1091 {
1092 pgnutls_perror( ret );
1093 pgnutls_dh_params_deinit( params );
1094 return NULL;
1095 }
1096
1097 free( x.data );
1098 return params;
1099}
1100
1102{
1103 struct key *key = args;
1104 gnutls_pk_algorithm_t pk_alg;
1105 gnutls_privkey_t privkey;
1106 gnutls_pubkey_t pubkey;
1107 unsigned int bitlen;
1108
1109 if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
1110 if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
1111
1112 switch (key->alg_id)
1113 {
1114 case ALG_ID_RSA:
1115 case ALG_ID_RSA_SIGN:
1116 pk_alg = GNUTLS_PK_RSA;
1117 bitlen = key->u.a.bitlen;
1118 break;
1119
1120 case ALG_ID_DH:
1121 pk_alg = GNUTLS_PK_DH;
1122 bitlen = key->u.a.bitlen;
1123 break;
1124
1125 case ALG_ID_DSA:
1126 pk_alg = GNUTLS_PK_DSA;
1127 bitlen = key->u.a.bitlen;
1128 break;
1129
1130 case ALG_ID_ECDH_P256:
1131 case ALG_ID_ECDSA_P256:
1132 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1133 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
1134 break;
1135
1136 case ALG_ID_ECDH_P384:
1137 case ALG_ID_ECDSA_P384:
1138 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1139 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
1140 break;
1141
1142 default:
1143 FIXME( "algorithm %u not supported\n", key->alg_id );
1144 return STATUS_NOT_SUPPORTED;
1145 }
1146
1147 if (key->alg_id == ALG_ID_DH && key_data(key)->a.dh_params)
1148 {
1149 gnutls_keygen_data_st data;
1150
1151 data.type = GNUTLS_KEYGEN_DH;
1152 data.data = (unsigned char *)key_data(key)->a.dh_params;
1153 data.size = 0;
1154 if (!(privkey = create_privkey( pk_alg, bitlen, &data, 1 ))) return STATUS_INTERNAL_ERROR;
1155 }
1156 else if (!(privkey = create_privkey( pk_alg, bitlen, NULL, 0 ))) return STATUS_INTERNAL_ERROR;
1157
1158 if (key->alg_id == ALG_ID_DH && !key_data(key)->a.dh_params &&
1159 !(key_data(key)->a.dh_params = get_dh_params( privkey )))
1160 {
1161 pgnutls_privkey_deinit( privkey );
1162 return STATUS_INTERNAL_ERROR;
1163 }
1164
1165 if (!(pubkey = create_pubkey_from_privkey( privkey )))
1166 {
1167 pgnutls_privkey_deinit( privkey );
1168 return STATUS_INTERNAL_ERROR;
1169 }
1170
1171 key_data(key)->a.privkey = privkey;
1172 key_data(key)->a.pubkey = pubkey;
1173 return STATUS_SUCCESS;
1174}
1175
1176static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1177{
1178 BCRYPT_ECCKEY_BLOB *ecc_blob;
1179 gnutls_ecc_curve_t curve;
1180 gnutls_datum_t x, y, d;
1181 DWORD magic, size;
1182 UCHAR *dst;
1183 int ret;
1184
1185 switch (key->alg_id)
1186 {
1187 case ALG_ID_ECDH_P256:
1189 size = 32;
1190 break;
1191
1192 case ALG_ID_ECDH_P384:
1194 size = 48;
1195 break;
1196
1197 case ALG_ID_ECDSA_P256:
1199 size = 32;
1200 break;
1201
1202 case ALG_ID_ECDSA_P384:
1204 size = 48;
1205 break;
1206
1207 default:
1208 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
1210 }
1211
1212 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1213
1214 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
1215 {
1216 pgnutls_perror( ret );
1217 return STATUS_INTERNAL_ERROR;
1218 }
1219
1220 if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1)
1221 {
1222 FIXME( "curve %u not supported\n", curve );
1223 free( x.data ); free( y.data ); free( d.data );
1225 }
1226
1227 *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ) + EXPORT_SIZE( d, size, 1 );
1228 if (len >= *ret_len && buf)
1229 {
1230 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1231 ecc_blob->dwMagic = magic;
1232 ecc_blob->cbKey = size;
1233
1234 dst = (UCHAR *)(ecc_blob + 1);
1235 dst += export_gnutls_datum( dst, size, &x, 1 );
1236 dst += export_gnutls_datum( dst, size, &y, 1 );
1237 export_gnutls_datum( dst, size, &d, 1 );
1238 }
1239
1240 free( x.data ); free( y.data ); free( d.data );
1241 return STATUS_SUCCESS;
1242}
1243
1244static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1245{
1246 BCRYPT_ECCKEY_BLOB *ecc_blob;
1247 gnutls_ecc_curve_t curve;
1248 gnutls_privkey_t handle;
1249 gnutls_datum_t x, y, k;
1250 int ret;
1251
1252 switch (key->alg_id)
1253 {
1254 case ALG_ID_ECDH_P256:
1255 case ALG_ID_ECDSA_P256:
1256 curve = GNUTLS_ECC_CURVE_SECP256R1;
1257 break;
1258
1259 case ALG_ID_ECDH_P384:
1260 case ALG_ID_ECDSA_P384:
1261 curve = GNUTLS_ECC_CURVE_SECP384R1;
1262 break;
1263
1264 default:
1265 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1267 }
1268
1269 if ((ret = pgnutls_privkey_init( &handle )))
1270 {
1271 pgnutls_perror( ret );
1272 return STATUS_INTERNAL_ERROR;
1273 }
1274
1275 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1276 x.data = (unsigned char *)(ecc_blob + 1);
1277 x.size = ecc_blob->cbKey;
1278 y.data = x.data + ecc_blob->cbKey;
1279 y.size = ecc_blob->cbKey;
1280 k.data = y.data + ecc_blob->cbKey;
1281 k.size = ecc_blob->cbKey;
1282
1283 if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1284 {
1285 pgnutls_perror( ret );
1286 pgnutls_privkey_deinit( handle );
1287 return STATUS_INTERNAL_ERROR;
1288 }
1289
1290 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1291 key_data(key)->a.privkey = handle;
1292 return STATUS_SUCCESS;
1293}
1294
1295static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1296{
1297 BCRYPT_RSAKEY_BLOB *rsa_blob;
1298 gnutls_datum_t m, e, d, p, q, u, e1, e2;
1299 ULONG size = key->u.a.bitlen / 8;
1301 UCHAR *dst;
1302 int ret;
1303
1304 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1305
1306 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1307 {
1308 pgnutls_perror( ret );
1309 return STATUS_INTERNAL_ERROR;
1310 }
1311
1312 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ) +
1313 EXPORT_SIZE( p, size / 2, 1 ) + EXPORT_SIZE( q, size / 2, 1 );
1314
1315 if (full) *ret_len += EXPORT_SIZE( e1, size / 2, 1 ) + EXPORT_SIZE( e2, size / 2, 1 ) +
1316 EXPORT_SIZE( u, size / 2, 1 ) + EXPORT_SIZE( d, size, 1 );
1317
1318 if (len >= *ret_len && buf)
1319 {
1320 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1322 rsa_blob->BitLength = key->u.a.bitlen;
1323
1324 dst = (UCHAR *)(rsa_blob + 1);
1325 rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
1326
1327 dst += rsa_blob->cbPublicExp;
1328 rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
1329
1330 dst += rsa_blob->cbModulus;
1331 rsa_blob->cbPrime1 = export_gnutls_datum( dst, size / 2, &p, 1 );
1332
1333 dst += rsa_blob->cbPrime1;
1334 rsa_blob->cbPrime2 = export_gnutls_datum( dst, size / 2, &q, 1 );
1335
1336 if (full)
1337 {
1338 dst += rsa_blob->cbPrime2;
1339 export_gnutls_datum( dst, size / 2, &e1, 1 );
1340
1341 dst += rsa_blob->cbPrime1;
1342 export_gnutls_datum( dst, size / 2, &e2, 1 );
1343
1344 dst += rsa_blob->cbPrime2;
1345 export_gnutls_datum( dst, size / 2, &u, 1 );
1346
1347 dst += rsa_blob->cbPrime1;
1348 export_gnutls_datum( dst, size, &d, 1 );
1349 }
1350 }
1351
1352 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1353 free( e1.data ); free( e2.data );
1354 return STATUS_SUCCESS;
1355}
1356
1357static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1358{
1360 gnutls_datum_t m, e, p, q;
1361 gnutls_privkey_t handle;
1362 int ret;
1363
1364 if ((ret = pgnutls_privkey_init( &handle )))
1365 {
1366 pgnutls_perror( ret );
1367 return STATUS_INTERNAL_ERROR;
1368 }
1369
1370 e.data = (unsigned char *)(rsa_blob + 1);
1371 e.size = rsa_blob->cbPublicExp;
1372 m.data = e.data + e.size;
1373 m.size = rsa_blob->cbModulus;
1374 p.data = m.data + m.size;
1375 p.size = rsa_blob->cbPrime1;
1376 q.data = p.data + p.size;
1377 q.size = rsa_blob->cbPrime2;
1378
1379 if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1380 {
1381 pgnutls_perror( ret );
1382 pgnutls_privkey_deinit( handle );
1383 return STATUS_INTERNAL_ERROR;
1384 }
1385
1386 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1387 key_data(key)->a.privkey = handle;
1388 return STATUS_SUCCESS;
1389}
1390
1391static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1392{
1393 BLOBHEADER *hdr;
1395 gnutls_datum_t p, q, g, y, x;
1396 ULONG size = key->u.a.bitlen / 8;
1397 UCHAR *dst;
1398 int ret;
1399
1400 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1401
1402 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1403 {
1404 pgnutls_perror( ret );
1405 return STATUS_INTERNAL_ERROR;
1406 }
1407
1408 if (q.size > 21 || x.size > 21)
1409 {
1410 ERR( "can't export key in this format\n" );
1411 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1412 return STATUS_NOT_SUPPORTED;
1413 }
1414
1415 *ret_len = sizeof(*hdr) + sizeof(*pubkey) + sizeof(key->u.a.dss_seed) +
1416 EXPORT_SIZE( p, size, 1 ) + 20 + EXPORT_SIZE( g, size, 1 ) + 20;
1417 if (len >= *ret_len && buf)
1418 {
1419 hdr = (BLOBHEADER *)buf;
1420 hdr->bType = PRIVATEKEYBLOB;
1421 hdr->bVersion = 2;
1422 hdr->reserved = 0;
1423 hdr->aiKeyAlg = CALG_DSS_SIGN;
1424
1425 pubkey = (DSSPUBKEY *)(hdr + 1);
1426 pubkey->magic = MAGIC_DSS2;
1427 pubkey->bitlen = key->u.a.bitlen;
1428
1429 dst = (UCHAR *)(pubkey + 1);
1430 export_gnutls_datum( dst, size, &p, 1 );
1432 dst += size;
1433
1434 export_gnutls_datum( dst, 20, &q, 1 );
1435 reverse_bytes( dst, 20 );
1436 dst += 20;
1437
1438 export_gnutls_datum( dst, size, &g, 1 );
1440 dst += size;
1441
1442 export_gnutls_datum( dst, 20, &x, 1 );
1443 reverse_bytes( dst, 20 );
1444 dst += 20;
1445
1446 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1447 }
1448
1449 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1450 return STATUS_SUCCESS;
1451}
1452
1453static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1454{
1457 gnutls_privkey_t handle;
1458 gnutls_datum_t p, q, g, x;
1459 unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1460 int i, ret, size;
1461
1462 if ((ret = pgnutls_privkey_init( &handle )))
1463 {
1464 pgnutls_perror( ret );
1465 return STATUS_INTERNAL_ERROR;
1466 }
1467
1468 pubkey = (DSSPUBKEY *)(hdr + 1);
1469 if ((size = pubkey->bitlen / 8) > sizeof(p_data))
1470 {
1471 FIXME( "size %u not supported\n", size );
1472 pgnutls_privkey_deinit( handle );
1473 return STATUS_NOT_SUPPORTED;
1474 }
1475 data = (unsigned char *)(pubkey + 1);
1476
1477 p.data = p_data;
1478 p.size = size;
1479 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1480 data += p.size;
1481
1482 q.data = q_data;
1483 q.size = sizeof(q_data);
1484 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1485 data += q.size;
1486
1487 g.data = g_data;
1488 g.size = size;
1489 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1490 data += g.size;
1491
1492 x.data = x_data;
1493 x.size = sizeof(x_data);
1494 for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1495 data += x.size;
1496
1497 if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1498 {
1499 pgnutls_perror( ret );
1500 pgnutls_privkey_deinit( handle );
1501 return STATUS_INTERNAL_ERROR;
1502 }
1503
1504 memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1505
1506 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1507 key_data(key)->a.privkey = handle;
1508 return STATUS_SUCCESS;
1509}
1510
1511static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1512{
1513 BCRYPT_ECCKEY_BLOB *ecc_blob;
1514 gnutls_ecc_curve_t curve;
1515 gnutls_datum_t x, y;
1516 gnutls_pubkey_t handle;
1517 int ret;
1518
1519 switch (key->alg_id)
1520 {
1521 case ALG_ID_ECDH_P256:
1522 case ALG_ID_ECDSA_P256:
1523 curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1524
1525 case ALG_ID_ECDH_P384:
1526 case ALG_ID_ECDSA_P384:
1527 curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1528
1529 default:
1530 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1532 }
1533
1534 if ((ret = pgnutls_pubkey_init( &handle )))
1535 {
1536 pgnutls_perror( ret );
1537 return STATUS_INTERNAL_ERROR;
1538 }
1539
1540 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1541 x.data = buf + sizeof(*ecc_blob);
1542 x.size = ecc_blob->cbKey;
1543 y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1544 y.size = ecc_blob->cbKey;
1545
1546 if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1547 {
1548 pgnutls_perror( ret );
1549 pgnutls_pubkey_deinit( handle );
1550 return STATUS_INTERNAL_ERROR;
1551 }
1552
1553 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1554 key_data(key)->a.pubkey = handle;
1555 return STATUS_SUCCESS;
1556}
1557
1558static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1559{
1560 BCRYPT_RSAKEY_BLOB *rsa_blob;
1561 gnutls_pubkey_t handle;
1562 gnutls_datum_t m, e;
1563 int ret;
1564
1565 if ((ret = pgnutls_pubkey_init( &handle )))
1566 {
1567 pgnutls_perror( ret );
1568 return STATUS_INTERNAL_ERROR;
1569 }
1570
1571 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1572 e.data = buf + sizeof(*rsa_blob);
1573 e.size = rsa_blob->cbPublicExp;
1574 m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1575 m.size = rsa_blob->cbModulus;
1576
1577 if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1578 {
1579 pgnutls_perror( ret );
1580 pgnutls_pubkey_deinit( handle );
1581 return STATUS_INTERNAL_ERROR;
1582 }
1583
1584 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1585 key_data(key)->a.pubkey = handle;
1586 return STATUS_SUCCESS;
1587}
1588
1589static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1590{
1591 BCRYPT_DSA_KEY_BLOB *dsa_blob;
1592 gnutls_datum_t p, q, g, y;
1593 gnutls_pubkey_t handle;
1594 int ret;
1595
1596 if ((ret = pgnutls_pubkey_init( &handle )))
1597 {
1598 pgnutls_perror( ret );
1599 return STATUS_INTERNAL_ERROR;
1600 }
1601
1602 dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1603 p.data = buf + sizeof(*dsa_blob);
1604 p.size = dsa_blob->cbKey;
1605 q.data = dsa_blob->q;
1606 q.size = sizeof(dsa_blob->q);
1607 g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1608 g.size = dsa_blob->cbKey;
1609 y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1610 y.size = dsa_blob->cbKey;
1611
1612 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1613 {
1614 pgnutls_perror( ret );
1615 pgnutls_pubkey_deinit( handle );
1616 return STATUS_INTERNAL_ERROR;
1617 }
1618
1619 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1620 key_data(key)->a.pubkey = handle;
1621 return STATUS_SUCCESS;
1622}
1623
1624static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1625{
1626 BLOBHEADER *hdr;
1628 gnutls_datum_t p, q, g, y;
1629 gnutls_pubkey_t handle;
1630 unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1631 int i, ret, size;
1632
1633 if ((ret = pgnutls_pubkey_init( &handle )))
1634 {
1635 pgnutls_perror( ret );
1636 return STATUS_INTERNAL_ERROR;
1637 }
1638
1639 hdr = (BLOBHEADER *)buf;
1640 pubkey = (DSSPUBKEY *)(hdr + 1);
1641 size = pubkey->bitlen / 8;
1642 data = (unsigned char *)(pubkey + 1);
1643
1644 p.data = p_data;
1645 p.size = size;
1646 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1647 data += p.size;
1648
1649 q.data = q_data;
1650 q.size = sizeof(q_data);
1651 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1652 data += q.size;
1653
1654 g.data = g_data;
1655 g.size = size;
1656 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1657 data += g.size;
1658
1659 y.data = y_data;
1660 y.size = sizeof(y_data);
1661 for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1662
1663 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1664 {
1665 pgnutls_perror( ret );
1666 pgnutls_pubkey_deinit( handle );
1667 return STATUS_INTERNAL_ERROR;
1668 }
1669
1670 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1671 key_data(key)->a.pubkey = handle;
1672 return STATUS_SUCCESS;
1673}
1674
1675static NTSTATUS key_export_dh_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1676{
1678 ULONG size = key->u.a.bitlen / 8;
1679 gnutls_dh_params_t params;
1680 gnutls_datum_t p, g, y;
1681 UCHAR *dst;
1682 int ret = GNUTLS_E_INVALID_REQUEST;
1683
1684 if ((ret = pgnutls_dh_params_init( &params )) < 0)
1685 {
1686 pgnutls_perror( ret );
1687 return STATUS_INTERNAL_ERROR;
1688 }
1689
1690 if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key)->a.pubkey, params, &y, 0 )))
1691 {
1692 pgnutls_perror( ret );
1693 pgnutls_dh_params_deinit( params );
1694 return STATUS_INTERNAL_ERROR;
1695 }
1696
1697 if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1698 {
1699 pgnutls_perror( ret );
1700 free( y.data );
1701 pgnutls_dh_params_deinit( params );
1702 return STATUS_INTERNAL_ERROR;
1703 }
1704
1705 *ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) + EXPORT_SIZE(y, size, 1);
1706 if (len >= *ret_len && buf)
1707 {
1708 dst = (UCHAR *)(dh_blob + 1);
1709 dst += export_gnutls_datum( dst, size, &p, 1 );
1710 dst += export_gnutls_datum( dst, size, &g, 1 );
1711 dst += export_gnutls_datum( dst, size, &y, 1 );
1712
1714 dh_blob->cbKey = size;
1715 }
1716
1717 free( p.data ); free( g.data ); free( y.data );
1718 return STATUS_SUCCESS;
1719}
1720
1721static NTSTATUS key_export_dh( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1722{
1724 gnutls_datum_t p, g, y, x;
1725 gnutls_dh_params_t params;
1726 ULONG size = key->u.a.bitlen / 8;
1727 UCHAR *dst;
1728 int ret;
1729
1730 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1731
1732 if ((ret = pgnutls_dh_params_init( &params )) < 0)
1733 {
1734 pgnutls_perror( ret );
1735 return STATUS_INTERNAL_ERROR;
1736 }
1737
1738 if ((ret = pgnutls_privkey_export_dh_raw( key_data(key)->a.privkey, params, &y, &x, 0 )))
1739 {
1740 pgnutls_perror( ret );
1741 pgnutls_dh_params_deinit( params );
1742 return STATUS_INTERNAL_ERROR;
1743 }
1744
1745 if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1746 {
1747 pgnutls_perror( ret );
1748 free( y.data ); free( x.data );
1749 pgnutls_dh_params_deinit( params );
1750 return STATUS_INTERNAL_ERROR;
1751 }
1752
1753 *ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) +
1754 EXPORT_SIZE(y, size, 1) + EXPORT_SIZE(x, size, 1);
1755 if (len >= *ret_len && buf)
1756 {
1757 dst = (UCHAR *)(dh_blob + 1);
1758 dst += export_gnutls_datum( dst, size, &p, 1 );
1759 dst += export_gnutls_datum( dst, size, &g, 1 );
1760 dst += export_gnutls_datum( dst, size, &y, 1 );
1761 dst += export_gnutls_datum( dst, size, &x, 1 );
1762
1764 dh_blob->cbKey = size;
1765 }
1766
1767 free( p.data ); free( g.data ); free( y.data ); free( x.data );
1768 pgnutls_dh_params_deinit( params );
1769 return STATUS_SUCCESS;
1770}
1771
1772static NTSTATUS key_export_dh_params( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1773{
1775 unsigned int size = sizeof(*hdr) + key->u.a.bitlen / 8 * 2;
1776 gnutls_datum_t p, g;
1778 UCHAR *dst;
1779 int ret;
1780
1781 if (!key_data(key)->a.dh_params) return STATUS_INVALID_PARAMETER;
1782
1783 if ((ret = pgnutls_dh_params_export_raw( key_data(key)->a.dh_params, &p, &g, NULL )))
1784 {
1785 pgnutls_perror( ret );
1786 return STATUS_INTERNAL_ERROR;
1787 }
1788
1789 *ret_len = size;
1791 else if (buf)
1792 {
1793 hdr->cbLength = size;
1795 hdr->cbKeyLength = key->u.a.bitlen / 8;
1796
1797 dst = (UCHAR *)(hdr + 1);
1798 dst += export_gnutls_datum( dst, hdr->cbKeyLength, &p, 1 );
1799 dst += export_gnutls_datum( dst, hdr->cbKeyLength, &g, 1 );
1800 }
1801
1802 free( p.data ); free( g.data );
1803 return status;
1804}
1805
1807{
1809 struct key *key = params->key;
1810 unsigned flags = params->flags;
1811
1812 if (!(key->u.a.flags & KEY_FLAG_FINALIZED)) return STATUS_INVALID_HANDLE;
1813
1814 switch (key->alg_id)
1815 {
1816 case ALG_ID_ECDH_P256:
1817 case ALG_ID_ECDH_P384:
1818 case ALG_ID_ECDSA_P256:
1819 case ALG_ID_ECDSA_P384:
1821 return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
1822 return key_export_ecc( key, params->buf, params->len, params->ret_len );
1823
1824 case ALG_ID_RSA:
1825 case ALG_ID_RSA_SIGN:
1827 return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
1828 return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
1829
1830 case ALG_ID_DSA:
1832 {
1833 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1834 return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
1835 return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
1836 }
1837 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1838 return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
1840
1841 case ALG_ID_DH:
1843 return key_export_dh_params( key, params->buf, params->len, params->ret_len );
1845 return key_export_dh_public( key, params->buf, params->len, params->ret_len );
1846 return key_export_dh( key, params->buf, params->len, params->ret_len );
1847
1848 default:
1849 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1851 }
1852}
1853
1854static NTSTATUS key_import_dh_public( struct key *key, UCHAR *buf, ULONG len )
1855{
1856 BCRYPT_DH_KEY_BLOB *dh_blob;
1857 gnutls_dh_params_t params;
1858 gnutls_datum_t p, g, y;
1859 gnutls_pubkey_t handle;
1860 int ret;
1861
1862 if ((ret = pgnutls_pubkey_init( &handle )))
1863 {
1864 pgnutls_perror( ret );
1865 return STATUS_INTERNAL_ERROR;
1866 }
1867
1868 if ((ret = pgnutls_dh_params_init( &params )) < 0)
1869 {
1870 pgnutls_perror( ret );
1871 pgnutls_pubkey_deinit( handle );
1872 return STATUS_INTERNAL_ERROR;
1873 }
1874
1875 dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1876 p.data = buf + sizeof(*dh_blob);
1877 p.size = dh_blob->cbKey;
1878 g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
1879 g.size = dh_blob->cbKey;
1880 y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
1881 y.size = dh_blob->cbKey;
1882
1883 if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
1884 {
1885 pgnutls_perror( ret );
1886 pgnutls_dh_params_deinit( params );
1887 pgnutls_pubkey_deinit( handle );
1888 return STATUS_INTERNAL_ERROR;
1889 }
1890
1891 if ((ret = pgnutls_pubkey_import_dh_raw( handle, params, &y )))
1892 {
1893 pgnutls_perror( ret );
1894 pgnutls_dh_params_deinit( params );
1895 pgnutls_pubkey_deinit( handle );
1896 return STATUS_INTERNAL_ERROR;
1897 }
1898
1899 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1900 key_data(key)->a.pubkey = handle;
1901
1902 if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
1903 key_data(key)->a.dh_params = params;
1904 return STATUS_SUCCESS;
1905}
1906
1907static NTSTATUS key_import_dh( struct key *key, UCHAR *buf, ULONG len )
1908{
1909 BCRYPT_DH_KEY_BLOB *dh_blob;
1910 gnutls_dh_params_t params;
1911 gnutls_datum_t p, g, y, x;
1912 gnutls_privkey_t handle;
1913 int ret;
1914
1915 if ((ret = pgnutls_privkey_init( &handle )))
1916 {
1917 pgnutls_perror( ret );
1918 return STATUS_INTERNAL_ERROR;
1919 }
1920
1921 if ((ret = pgnutls_dh_params_init( &params )) < 0)
1922 {
1923 pgnutls_perror( ret );
1924 pgnutls_privkey_deinit( handle );
1925 return STATUS_INTERNAL_ERROR;
1926 }
1927
1928 dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1929 p.data = buf + sizeof(*dh_blob);
1930 p.size = dh_blob->cbKey;
1931 g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
1932 g.size = dh_blob->cbKey;
1933 y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
1934 y.size = dh_blob->cbKey;
1935 x.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 3;
1936 x.size = dh_blob->cbKey;
1937
1938 if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
1939 {
1940 pgnutls_perror( ret );
1941 pgnutls_dh_params_deinit( params );
1942 pgnutls_privkey_deinit( handle );
1943 return STATUS_INTERNAL_ERROR;
1944 }
1945
1946 if ((ret = pgnutls_privkey_import_dh_raw( handle, params, &y, &x )))
1947 {
1948 pgnutls_perror( ret );
1949 pgnutls_dh_params_deinit( params );
1950 pgnutls_privkey_deinit( handle );
1951 return STATUS_INTERNAL_ERROR;
1952 }
1953
1954 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1955 key_data(key)->a.privkey = handle;
1956
1957 if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
1958 key_data(key)->a.dh_params = params;
1959 return STATUS_SUCCESS;
1960}
1961
1962static NTSTATUS key_import_dh_params( struct key *key, UCHAR *buf, ULONG len )
1963{
1965 gnutls_dh_params_t params;
1966 gnutls_datum_t p, g;
1967 int ret;
1968
1969 if ((ret = pgnutls_dh_params_init( &params )))
1970 {
1971 pgnutls_perror( ret );
1972 return STATUS_INTERNAL_ERROR;
1973 }
1974
1975 p.data = (unsigned char *)(dh_header + 1);
1976 p.size = dh_header->cbKeyLength;
1977 g.data = p.data + dh_header->cbKeyLength;
1978 g.size = dh_header->cbKeyLength;
1979
1980 if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )))
1981 {
1982 pgnutls_perror( ret );
1983 pgnutls_dh_params_deinit( params );
1984 return STATUS_INTERNAL_ERROR;
1985 }
1986
1987 if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
1988 key_data(key)->a.dh_params = params;
1989 return STATUS_SUCCESS;
1990}
1991
1993{
1995 struct key *key = params->key;
1996 unsigned flags = params->flags;
1997 gnutls_pubkey_t pubkey;
1998 NTSTATUS ret;
1999
2000 switch (key->alg_id)
2001 {
2002 case ALG_ID_ECDH_P256:
2003 case ALG_ID_ECDH_P384:
2004 case ALG_ID_ECDSA_P256:
2005 case ALG_ID_ECDSA_P384:
2007 return key_import_ecc_public( key, params->buf, params->len );
2008 ret = key_import_ecc( key, params->buf, params->len );
2009 break;
2010
2011 case ALG_ID_RSA:
2012 case ALG_ID_RSA_SIGN:
2014 return key_import_rsa_public( key, params->buf, params->len );
2015 ret = key_import_rsa( key, params->buf, params->len );
2016 break;
2017
2018 case ALG_ID_DSA:
2020 {
2021 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2022 return key_import_dsa_capi_public( key, params->buf, params->len );
2023 return key_import_dsa_public( key, params->buf, params->len );
2024 }
2025 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2026 {
2027 ret = key_import_dsa_capi( key, params->buf, params->len );
2028 break;
2029 }
2030 FIXME( "DSA private key not supported\n" );
2032
2033 case ALG_ID_DH:
2035 return key_import_dh_params( key, params->buf, params->len );
2037 return key_import_dh_public( key, params->buf, params->len );
2038 ret = key_import_dh( key, params->buf, params->len );
2039 break;
2040
2041 default:
2042 FIXME( "algorithm %u not yet supported\n", key->alg_id );
2044 }
2045
2046 if (ret) return ret;
2047
2048 if ((ret = pgnutls_pubkey_init( &pubkey )))
2049 {
2050 pgnutls_perror( ret );
2051 return STATUS_INTERNAL_ERROR;
2052 }
2053
2054 if (pgnutls_pubkey_import_privkey( pubkey, key_data(params->key)->a.privkey, 0, 0 ))
2055 {
2056 /* Imported private key may be legitimately missing public key, so ignore the failure here. */
2057 pgnutls_pubkey_deinit( pubkey );
2058 }
2059 else
2060 {
2061 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2062 key_data(key)->a.pubkey = pubkey;
2063 }
2064 return STATUS_SUCCESS;
2065}
2066
2067static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
2068 gnutls_datum_t *gnutls_signature )
2069{
2070 struct buffer buffer;
2071 DWORD r_len = signature_len / 2;
2072 DWORD s_len = r_len;
2073 BYTE *r = signature;
2074 BYTE *s = signature + r_len;
2075
2076 buffer_init( &buffer );
2077 buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
2078 if (buffer.error)
2079 {
2080 buffer_free( &buffer );
2081 return STATUS_NO_MEMORY;
2082 }
2083
2084 gnutls_signature->data = buffer.buffer;
2085 gnutls_signature->size = buffer.pos;
2086 return STATUS_SUCCESS;
2087}
2088
2089static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
2090 gnutls_datum_t *gnutls_signature )
2091{
2092 gnutls_signature->data = signature;
2093 gnutls_signature->size = signature_len;
2094 return STATUS_SUCCESS;
2095}
2096
2097static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
2098 gnutls_datum_t *gnutls_signature )
2099{
2100 switch (key->alg_id)
2101 {
2102 case ALG_ID_ECDSA_P256:
2103 case ALG_ID_ECDSA_P384:
2104 case ALG_ID_DSA:
2105 return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
2106
2107 case ALG_ID_RSA:
2108 case ALG_ID_RSA_SIGN:
2109 return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
2110
2111 default:
2112 FIXME( "algorithm %u not yet supported\n", key->alg_id );
2114 }
2115}
2116
2117static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
2118{
2119 if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
2120 if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
2121 if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
2122 if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
2123 if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
2124 if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
2125 return GNUTLS_DIG_UNKNOWN;
2126}
2127
2128static NTSTATUS pubkey_set_rsa_pss_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2129{
2130 gnutls_x509_spki_t spki;
2131 int ret;
2132
2133 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2134 {
2135 pgnutls_perror( ret );
2136 return STATUS_INTERNAL_ERROR;
2137 }
2138 pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2139 ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2140 pgnutls_x509_spki_deinit( spki );
2141 if (ret < 0)
2142 {
2143 pgnutls_perror( ret );
2144 return STATUS_INTERNAL_ERROR;
2145 }
2146 return STATUS_SUCCESS;
2147}
2148
2150{
2151#ifdef GNUTLS_VERIFY_ALLOW_BROKEN
2152 unsigned int verify_flags = GNUTLS_VERIFY_ALLOW_BROKEN;
2153#else
2154 unsigned int verify_flags = 0;
2155#endif
2157 struct key *key = params->key;
2158 unsigned flags = params->flags;
2159 gnutls_digest_algorithm_t hash_alg;
2160 gnutls_sign_algorithm_t sign_alg;
2161 gnutls_datum_t gnutls_hash, gnutls_signature;
2162 gnutls_pk_algorithm_t pk_alg;
2164 int ret;
2165
2166 switch (key->alg_id)
2167 {
2168 case ALG_ID_ECDSA_P256:
2169 case ALG_ID_ECDSA_P384:
2170 {
2171 if (flags) FIXME( "flags %#x not supported\n", flags );
2172
2173 /* only the hash size must match, not the actual hash function */
2174 switch (params->hash_len)
2175 {
2176 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2177 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2178 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2179
2180 default:
2181 FIXME( "hash size %u not yet supported\n", params->hash_len );
2183 }
2184 pk_alg = GNUTLS_PK_ECC;
2185 break;
2186 }
2187 case ALG_ID_RSA:
2188 case ALG_ID_RSA_SIGN:
2189 {
2190 if (flags & BCRYPT_PAD_PKCS1)
2191 {
2193
2194 if (!info) return STATUS_INVALID_PARAMETER;
2195 if (!info->pszAlgId)
2196 {
2197 hash_alg = GNUTLS_DIG_UNKNOWN;
2198 verify_flags |= GNUTLS_VERIFY_USE_TLS1_RSA;
2199 }
2200 else if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2201 {
2202 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2203 return STATUS_NOT_SUPPORTED;
2204 }
2205 pk_alg = GNUTLS_PK_RSA;
2206 }
2207 else if (flags & BCRYPT_PAD_PSS)
2208 {
2210
2211 if (!info) return STATUS_INVALID_PARAMETER;
2212 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
2213 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2214 {
2215 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2216 return STATUS_NOT_SUPPORTED;
2217 }
2218 if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status;
2219 pk_alg = GNUTLS_PK_RSA_PSS;
2220 }
2221 else return STATUS_INVALID_PARAMETER;
2222 break;
2223 }
2224 case ALG_ID_DSA:
2225 {
2226 if (flags) FIXME( "flags %#x not supported\n", flags );
2227 if (params->hash_len != 20)
2228 {
2229 FIXME( "hash size %u not supported\n", params->hash_len );
2231 }
2232 hash_alg = GNUTLS_DIG_SHA1;
2233 pk_alg = GNUTLS_PK_DSA;
2234 break;
2235 }
2236 default:
2237 FIXME( "algorithm %u not yet supported\n", key->alg_id );
2239 }
2240
2241 if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
2242 {
2243 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
2245 }
2246
2247 if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
2248 return status;
2249
2250 gnutls_hash.data = params->hash;
2251 gnutls_hash.size = params->hash_len;
2252
2253 ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, verify_flags, &gnutls_hash, &gnutls_signature );
2254 if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
2256}
2257
2258static unsigned int get_signature_length( enum alg_id id )
2259{
2260 switch (id)
2261 {
2262 case ALG_ID_ECDSA_P256: return 64;
2263 case ALG_ID_ECDSA_P384: return 96;
2264 case ALG_ID_DSA: return 40;
2265 default:
2266 FIXME( "unhandled algorithm %u\n", id );
2267 return 0;
2268 }
2269}
2270
2271static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
2272 UCHAR *output, ULONG output_len, ULONG *ret_len )
2273{
2274 switch (type)
2275 {
2276 case ALG_ID_RSA:
2277 case ALG_ID_RSA_SIGN:
2278 {
2279 *ret_len = signature.size;
2280 if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
2281 if (output) memcpy( output, signature.data, signature.size );
2282 return STATUS_SUCCESS;
2283 }
2284 case ALG_ID_ECDSA_P256:
2285 case ALG_ID_ECDSA_P384:
2286 case ALG_ID_DSA:
2287 {
2288 int err;
2289 unsigned int sig_len = get_signature_length( type );
2290 gnutls_datum_t r, s; /* format as r||s */
2291
2292 if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
2293 {
2294 pgnutls_perror( err );
2295 return STATUS_INTERNAL_ERROR;
2296 }
2297
2298 *ret_len = sig_len;
2299 if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
2300
2301 if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
2302 {
2303 ERR( "we didn't get a correct signature\n" );
2304 return STATUS_INTERNAL_ERROR;
2305 }
2306
2307 if (output)
2308 {
2309 export_gnutls_datum( output, sig_len / 2, &r, 1 );
2310 export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
2311 }
2312
2313 free( r.data ); free( s.data );
2314 return STATUS_SUCCESS;
2315 }
2316 default:
2317 return STATUS_INTERNAL_ERROR;
2318 }
2319}
2320
2321static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2322{
2323 gnutls_x509_spki_t spki;
2324 int ret;
2325
2326 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2327 {
2328 pgnutls_perror( ret );
2329 return STATUS_INTERNAL_ERROR;
2330 }
2331 pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2332 ret = pgnutls_privkey_set_spki( key, spki, 0 );
2333 pgnutls_x509_spki_deinit( spki );
2334 if (ret < 0)
2335 {
2336 pgnutls_perror( ret );
2337 return STATUS_INTERNAL_ERROR;
2338 }
2339 return STATUS_SUCCESS;
2340}
2341
2343{
2344 const struct key_asymmetric_sign_params *params = args;
2345 struct key *key = params->key;
2346 unsigned int flags = params->flags, gnutls_flags = 0;
2347 gnutls_datum_t hash, signature;
2348 gnutls_digest_algorithm_t hash_alg;
2350 int ret;
2351
2353 {
2354 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
2355 switch (params->input_len)
2356 {
2357 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2358 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2359 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2360 case 64: hash_alg = GNUTLS_DIG_SHA512; break;
2361
2362 default:
2363 FIXME( "hash size %u not yet supported\n", params->input_len );
2365 }
2366
2367 if (flags == BCRYPT_PAD_PKCS1)
2368 {
2369 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2370 if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
2371 {
2372 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
2374 }
2375 }
2376 }
2377 else if (key->alg_id == ALG_ID_DSA)
2378 {
2379 if (flags) FIXME( "flags %#x not supported\n", flags );
2380 if (params->input_len != 20)
2381 {
2382 FIXME( "hash size %u not supported\n", params->input_len );
2384 }
2385 hash_alg = GNUTLS_DIG_SHA1;
2386 }
2387 else if (flags == BCRYPT_PAD_PKCS1)
2388 {
2389 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2390
2391 if (!pad)
2392 {
2393 WARN( "padding info not found\n" );
2395 }
2396 if (!pad->pszAlgId) hash_alg = GNUTLS_DIG_UNKNOWN;
2397 else if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2398 {
2399 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2400 return STATUS_NOT_SUPPORTED;
2401 }
2402 }
2403 else if (flags == BCRYPT_PAD_PSS)
2404 {
2405 BCRYPT_PSS_PADDING_INFO *pad = params->padding;
2406
2407 if (!pad || !pad->pszAlgId)
2408 {
2409 WARN( "padding info not found\n" );
2411 }
2413 {
2414 FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id );
2415 return STATUS_NOT_SUPPORTED;
2416 }
2417 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2418 {
2419 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2420 return STATUS_NOT_SUPPORTED;
2421 }
2422
2423 if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status;
2424 gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS;
2425 }
2426 else if (!flags)
2427 {
2428 WARN( "invalid flags %#x\n", flags );
2430 }
2431 else
2432 {
2433 FIXME( "flags %#x not implemented\n", flags );
2435 }
2436
2437 if (!params->output)
2438 {
2439 *params->ret_len = key->u.a.bitlen / 8;
2440 return STATUS_SUCCESS;
2441 }
2442 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
2443
2444 hash.data = params->input;
2445 hash.size = params->input_len;
2446
2447 signature.data = NULL;
2448 signature.size = 0;
2449
2450 if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature )))
2451 {
2452 pgnutls_perror( ret );
2453 return STATUS_INTERNAL_ERROR;
2454 }
2455
2456 status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
2457 free( signature.data );
2458 return status;
2459}
2460
2462{
2463 struct key *key = args;
2464
2465 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2466 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2467 if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2468 return STATUS_SUCCESS;
2469}
2470
2471static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy )
2472{
2473 gnutls_privkey_t privkey;
2474 int ret;
2475
2476 if ((ret = pgnutls_privkey_init( &privkey )))
2477 {
2478 pgnutls_perror( ret );
2479 return STATUS_INTERNAL_ERROR;
2480 }
2481
2482 switch (key_orig->alg_id)
2483 {
2484 case ALG_ID_RSA:
2485 case ALG_ID_RSA_SIGN:
2486 {
2487 gnutls_datum_t m, e, d, p, q, u, e1, e2;
2488
2489 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
2490 break;
2491 ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
2492 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
2493 free( e1.data ); free( e2.data );
2494 break;
2495 }
2496 case ALG_ID_DSA:
2497 {
2498 gnutls_datum_t p, q, g, y, x;
2499
2500 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x ))) break;
2501 ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
2502 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
2503 if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2504 break;
2505 }
2506 case ALG_ID_ECDH_P256:
2507 case ALG_ID_ECDH_P384:
2508 case ALG_ID_ECDSA_P256:
2509 case ALG_ID_ECDSA_P384:
2510 {
2511 gnutls_ecc_curve_t curve;
2512 gnutls_datum_t x, y, k;
2513
2514 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k ))) break;
2515 ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
2516 free( x.data ); free( y.data ); free( k.data );
2517 break;
2518 }
2519 case ALG_ID_DH:
2520 {
2521 gnutls_dh_params_t params;
2522 gnutls_datum_t y, x;
2523
2524 if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2525 if ((ret = pgnutls_privkey_export_dh_raw( key_data(key_orig)->a.privkey, params, &y, &x, 0 )) < 0)
2526 {
2527 pgnutls_dh_params_deinit( params );
2528 break;
2529 }
2530 ret = pgnutls_privkey_import_dh_raw( privkey, params, &y, &x );
2531 pgnutls_dh_params_deinit( params );
2532 free( x.data ); free( y.data );
2533 break;
2534 }
2535 default:
2536 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2537 pgnutls_privkey_deinit( privkey );
2538 return STATUS_INTERNAL_ERROR;
2539 }
2540
2541 if (ret < 0)
2542 {
2543 pgnutls_perror( ret );
2544 pgnutls_privkey_deinit( privkey );
2545 return STATUS_INTERNAL_ERROR;
2546 }
2547
2548 key_data(key_copy)->a.privkey = privkey;
2549 return STATUS_SUCCESS;
2550}
2551
2552static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy )
2553{
2554 gnutls_pubkey_t pubkey;
2555 int ret;
2556
2557 if ((ret = pgnutls_pubkey_init( &pubkey )))
2558 {
2559 pgnutls_perror( ret );
2560 return STATUS_INTERNAL_ERROR;
2561 }
2562
2563 switch (key_orig->alg_id)
2564 {
2565 case ALG_ID_RSA:
2566 case ALG_ID_RSA_SIGN:
2567 {
2568 gnutls_datum_t m, e;
2569
2570 if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e ))) break;
2571 ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e );
2572 free( m.data ); free( e.data );
2573 break;
2574 }
2575 case ALG_ID_DSA:
2576 {
2577 gnutls_datum_t p, q, g, y;
2578
2579 if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y ))) break;
2580 ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y );
2581 free( p.data ); free( q.data ); free( g.data ); free( y.data );
2582 if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2583 break;
2584 }
2585 case ALG_ID_ECDH_P256:
2586 case ALG_ID_ECDH_P384:
2587 case ALG_ID_ECDSA_P256:
2588 case ALG_ID_ECDSA_P384:
2589 {
2590 gnutls_ecc_curve_t curve;
2591 gnutls_datum_t x, y;
2592
2593 if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y ))) break;
2594 ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y );
2595 free( x.data ); free( y.data );
2596 break;
2597 }
2598 case ALG_ID_DH:
2599 {
2600 gnutls_dh_params_t params;
2601 gnutls_datum_t y;
2602
2603 if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2604 if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key_orig)->a.pubkey, params, &y, 0 )) < 0)
2605 {
2606 pgnutls_dh_params_deinit( params );
2607 break;
2608 }
2609 ret = pgnutls_pubkey_import_dh_raw( pubkey, params, &y );
2610 pgnutls_dh_params_deinit( params );
2611 free( y.data );
2612 break;
2613 }
2614 default:
2615 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2616 pgnutls_pubkey_deinit( pubkey );
2617 return STATUS_INTERNAL_ERROR;
2618 }
2619
2620 if (ret < 0)
2621 {
2622 pgnutls_perror( ret );
2623 pgnutls_pubkey_deinit( pubkey );
2624 return STATUS_INTERNAL_ERROR;
2625 }
2626
2627 key_data(key_copy)->a.pubkey = pubkey;
2628 return STATUS_SUCCESS;
2629}
2630
2632{
2635
2636 if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy )))
2637 return status;
2638
2639 if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy )))
2640 return status;
2641
2642 return STATUS_SUCCESS;
2643}
2644
2645static NTSTATUS privkey_set_rsa_oaep_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2646{
2647 gnutls_x509_spki_t spki;
2648 int ret;
2649
2650 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2651 {
2652 pgnutls_perror( ret );
2653 return STATUS_INTERNAL_ERROR;
2654 }
2655 pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2656 ret = pgnutls_privkey_set_spki( key, spki, 0 );
2657 pgnutls_x509_spki_deinit( spki );
2658 if (ret < 0)
2659 {
2660 pgnutls_perror( ret );
2661 return STATUS_INTERNAL_ERROR;
2662 }
2663 return STATUS_SUCCESS;
2664}
2665
2667{
2669 gnutls_datum_t e, d = { 0 };
2671 int ret;
2672
2673 if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2674 {
2675 BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2676 gnutls_digest_algorithm_t dig;
2677 gnutls_datum_t label;
2678
2679 if (!pad || !pad->pszAlgId)
2680 {
2681 WARN( "padding info not found\n" );
2683 }
2684 if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2685 {
2686 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2687 return STATUS_NOT_SUPPORTED;
2688 }
2689
2690 label.data = pad->pbLabel;
2691 label.size = pad->cbLabel;
2692 if ((status = privkey_set_rsa_oaep_params( key_data(params->key)->a.privkey, dig, &label ))) return status;
2693 }
2694
2695 e.data = params->input;
2696 e.size = params->input_len;
2697 if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
2698 {
2699 pgnutls_perror( ret );
2700 return STATUS_INTERNAL_ERROR;
2701 }
2702
2703 *params->ret_len = d.size;
2704 if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
2705 else if (params->output) status = STATUS_BUFFER_TOO_SMALL;
2706
2707 free( d.data );
2708 return status;
2709}
2710
2711static NTSTATUS pubkey_set_rsa_oaep_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2712{
2713 gnutls_x509_spki_t spki;
2714 int ret;
2715
2716 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2717 {
2718 pgnutls_perror( ret );
2719 return STATUS_INTERNAL_ERROR;
2720 }
2721 pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2722 ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2723 pgnutls_x509_spki_deinit( spki );
2724 if (ret < 0)
2725 {
2726 pgnutls_perror( ret );
2727 return STATUS_INTERNAL_ERROR;
2728 }
2729 return STATUS_SUCCESS;
2730}
2731
2733{
2735 gnutls_datum_t d, e = { 0 };
2737 int ret;
2738
2739 if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
2740
2741 if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2742 {
2743 BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2744 gnutls_digest_algorithm_t dig;
2745 gnutls_datum_t label;
2746
2747 if (!pad || !pad->pszAlgId || !pad->pbLabel)
2748 {
2749 WARN( "padding info not found\n" );
2751 }
2752 if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2753 {
2754 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2755 return STATUS_NOT_SUPPORTED;
2756 }
2757
2758 label.data = pad->pbLabel;
2759 label.size = pad->cbLabel;
2760 if ((status = pubkey_set_rsa_oaep_params( key_data(params->key)->a.pubkey, dig, &label ))) return status;
2761 }
2762
2763 d.data = params->input;
2764 d.size = params->input_len;
2765 if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
2766 {
2767 pgnutls_perror( ret );
2768 return STATUS_INTERNAL_ERROR;
2769 }
2770
2771 *params->ret_len = e.size;
2772 if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
2773 else if (params->output_len == 0) status = STATUS_SUCCESS;
2775
2776 free( e.data );
2777 return status;
2778}
2779
2781{
2783 gnutls_datum_t s;
2785 int ret;
2786
2787 if ((ret = pgnutls_privkey_derive_secret( key_data(params->privkey)->a.privkey,
2788 key_data(params->pubkey)->a.pubkey, NULL, &s, 0 )))
2789 {
2790 pgnutls_perror( ret );
2791 return STATUS_INTERNAL_ERROR;
2792 }
2793
2794 *params->ret_len = EXPORT_SIZE( s, params->privkey->u.a.bitlen / 8, 1 );
2795 if (params->output)
2796 {
2797 if (params->output_len < *params->ret_len) status = STATUS_BUFFER_TOO_SMALL;
2798 else export_gnutls_datum( params->output, *params->ret_len, &s, 1 );
2799 }
2800
2801 free( s.data );
2802 return status;
2803}
2804
2805NTSTATUS hash_init( struct hash *hash )
2806{
2807 gnutls_digest_algorithm_t alg;
2808
2809 if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
2810
2811 switch (hash->alg_id)
2812 {
2813 case ALG_ID_MD5:
2814 alg = GNUTLS_DIG_MD5;
2815 break;
2816 case ALG_ID_SHA1:
2817 alg = GNUTLS_DIG_SHA1;
2818 break;
2819
2820 case ALG_ID_SHA256:
2821 alg = GNUTLS_DIG_SHA256;
2822 break;
2823
2824 case ALG_ID_SHA384:
2825 alg = GNUTLS_DIG_SHA384;
2826 break;
2827
2828 case ALG_ID_SHA512:
2829 alg = GNUTLS_DIG_SHA512;
2830 break;
2831
2832 default:
2833 ERR( "unhandled id %u\n", hash->alg_id );
2835 }
2836
2837 if (pgnutls_hash_init( &hash->u.hash_handle, alg )) return STATUS_INTERNAL_ERROR;
2838 return STATUS_SUCCESS;
2839}
2840
2841NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
2842{
2843 gnutls_mac_algorithm_t alg;
2844
2845 if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
2846
2847 switch (hash->alg_id)
2848 {
2849 case ALG_ID_MD5:
2850 alg = GNUTLS_MAC_MD5;
2851 break;
2852 case ALG_ID_SHA1:
2853 alg = GNUTLS_MAC_SHA1;
2854 break;
2855
2856 case ALG_ID_SHA256:
2857 alg = GNUTLS_MAC_SHA256;
2858 break;
2859
2860 case ALG_ID_SHA384:
2861 alg = GNUTLS_MAC_SHA384;
2862 break;
2863
2864 case ALG_ID_SHA512:
2865 alg = GNUTLS_MAC_SHA512;
2866 break;
2867
2868 default:
2869 ERR( "unhandled id %u\n", hash->alg_id );
2871 }
2872
2873 if (pgnutls_hmac_init( &hash->u.hmac_handle, alg, key, key_size )) return STATUS_INTERNAL_ERROR;
2874 return STATUS_SUCCESS;
2875}
2876
2878{
2879 if (pgnutls_hash( hash->u.hash_handle, input, size )) return STATUS_INTERNAL_ERROR;
2880 return STATUS_SUCCESS;
2881}
2882
2884{
2885 if (pgnutls_hmac( hash->u.hmac_handle, input, size )) return STATUS_INTERNAL_ERROR;
2886 return STATUS_SUCCESS;
2887}
2888
2890{
2891 pgnutls_hash_deinit( hash->u.hash_handle, output );
2892 return STATUS_SUCCESS;
2893}
2894
2896{
2897 pgnutls_hmac_deinit( hash->u.hmac_handle, output );
2898 return STATUS_SUCCESS;
2899}
2900
2901#endif /* HAVE_GNUTLS_HASH */
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define BCRYPT_DH_PUBLIC_MAGIC
Definition: bcrypt.h:280
#define BCRYPT_ECDH_PRIVATE_P256_MAGIC
Definition: bcrypt.h:133
#define BCRYPT_ECDSA_PUBLIC_P256_MAGIC
Definition: bcrypt.h:125
#define BCRYPT_ECDH_PUBLIC_P384_MAGIC
Definition: bcrypt.h:134
#define BCRYPT_ECDSA_PUBLIC_P384_MAGIC
Definition: bcrypt.h:127
#define BCRYPT_SHA512_ALGORITHM
Definition: bcrypt.h:107
#define BCRYPT_PAD_PKCS1
Definition: bcrypt.h:236
#define BCRYPT_RSAFULLPRIVATE_MAGIC
Definition: bcrypt.h:205
#define BCRYPT_MD2_ALGORITHM
Definition: bcrypt.h:96
#define BCRYPT_SHA256_ALGORITHM
Definition: bcrypt.h:105
#define BCRYPT_RSAPRIVATE_MAGIC
Definition: bcrypt.h:204
#define BCRYPT_PAD_PSS
Definition: bcrypt.h:238
#define BCRYPT_ECDH_PUBLIC_P256_MAGIC
Definition: bcrypt.h:132
#define BCRYPT_ECDSA_PRIVATE_P256_MAGIC
Definition: bcrypt.h:126
#define BCRYPT_ECDSA_PRIVATE_P384_MAGIC
Definition: bcrypt.h:128
#define BCRYPT_DH_PARAMETERS_MAGIC
Definition: bcrypt.h:289
#define BCRYPT_RSAPUBLIC_MAGIC
Definition: bcrypt.h:203
#define BCRYPT_ECDH_PRIVATE_P384_MAGIC
Definition: bcrypt.h:135
#define BCRYPT_PAD_OAEP
Definition: bcrypt.h:237
#define BCRYPT_SHA384_ALGORITHM
Definition: bcrypt.h:106
#define BCRYPT_DSA_PUBLIC_MAGIC
Definition: bcrypt.h:241
#define BCRYPT_SHA1_ALGORITHM
Definition: bcrypt.h:104
#define BCRYPT_MD5_ALGORITHM
Definition: bcrypt.h:98
#define BCRYPT_DH_PRIVATE_MAGIC
Definition: bcrypt.h:281
NTSTATUS hmac_init(struct hash *hash, UCHAR *key, ULONG key_size)
NTSTATUS key_symmetric_vector_reset(void *args)
NTSTATUS key_asymmetric_export(void *args)
#define KEY_FLAG_FINALIZED
NTSTATUS key_symmetric_set_auth_data(void *args)
NTSTATUS key_symmetric_get_tag(void *args)
NTSTATUS hash_update(struct hash *hash, UCHAR *input, ULONG size)
NTSTATUS key_asymmetric_encrypt(void *args)
NTSTATUS key_symmetric_destroy(void *args)
#define MAGIC_DSS1
@ CHAIN_MODE_ECB
@ CHAIN_MODE_CBC
@ CHAIN_MODE_GCM
@ CHAIN_MODE_CFB
#define KEY_EXPORT_FLAG_DH_PARAMETERS
NTSTATUS hmac_update(struct hash *hash, UCHAR *input, ULONG size)
NTSTATUS hash_finish(struct hash *hash, UCHAR *output)
#define KEY_IMPORT_FLAG_PUBLIC
NTSTATUS key_asymmetric_generate(void *args)
NTSTATUS key_asymmetric_destroy(void *args)
NTSTATUS process_attach(void *args)
#define KEY_EXPORT_FLAG_RSA_FULL
NTSTATUS key_asymmetric_verify(void *args)
NTSTATUS key_asymmetric_derive_key(void *args)
#define MAGIC_DSS2
NTSTATUS key_asymmetric_import(void *args)
NTSTATUS hash_init(struct hash *hash)
#define KEY_IMPORT_FLAG_DH_PARAMETERS
#define KEY_FLAG_LEGACY_DSA_V2
NTSTATUS key_asymmetric_sign(void *args)
NTSTATUS key_asymmetric_decrypt(void *args)
NTSTATUS key_asymmetric_duplicate(void *args)
NTSTATUS hmac_finish(struct hash *hash, UCHAR *output)
alg_id
@ ALG_ID_RSA
@ ALG_ID_DSA
@ ALG_ID_RSA_SIGN
@ ALG_ID_3DES
@ ALG_ID_ECDSA_P256
@ ALG_ID_SHA512
@ ALG_ID_ECDH_P256
@ ALG_ID_SHA384
@ ALG_ID_SHA1
@ ALG_ID_DH
@ ALG_ID_ECDSA_P384
@ ALG_ID_SHA256
@ ALG_ID_ECDH_P384
@ ALG_ID_AES
@ ALG_ID_MD5
#define KEY_EXPORT_FLAG_PUBLIC
static NTSTATUS key_symmetric_decrypt(struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:1234
static void reverse_bytes(UCHAR *buf, ULONG len)
Definition: bcrypt_main.c:2576
static NTSTATUS key_symmetric_encrypt(struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags)
Definition: bcrypt_main.c:1449
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:171
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
content
Definition: atl_ax.c:990
#define TRACE_ON(x)
Definition: compat.h:75
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
static const WCHAR pubkey[]
Definition: asmname.c:68
static void process_detach(void)
Definition: main.c:94
char *CDECL getenv(const char *name)
Definition: environ.c:227
#define assert(_expr)
Definition: assert.h:32
unsigned int size_t
Definition: corecrt.h:203
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl atoi(const char *)
Definition: string.c:1720
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:147
#define LOAD_FUNCPTR(f)
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint level
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLenum GLenum GLenum input
Definition: glext.h:9031
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define C_ASSERT(e)
Definition: intsafe.h:73
#define buffer_init
Definition: intsym.h:261
char hdr[14]
Definition: iptest.cpp:33
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define a
Definition: ke_i.h:78
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static const WCHAR label[]
Definition: itemdlg.c:1608
static DATA_BLOB cipher
Definition: protectdata.c:34
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:81
static unsigned(__cdecl *hash_bstr)(bstr_t s)
#define RTLD_NOW
Definition: port.h:100
int k
Definition: mpi.c:3369
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:639
#define STATUS_INVALID_SIGNATURE
Definition: ntstatus.h:1397
short WCHAR
Definition: pedump.c:58
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
#define err(...)
#define MAKE_FUNCPTR(f)
#define ERR_(ch,...)
Definition: debug.h:156
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE(s)
Definition: solgame.cpp:4
UCHAR Seed[20]
Definition: bcrypt.h:249
UCHAR Count[4]
Definition: bcrypt.h:248
DWORD magic
Definition: wincrypt.h:158
DWORD bitlen
Definition: wincrypt.h:159
Definition: match.c:390
enum alg_id alg_id
Definition: copy.c:22
struct key_asymmetric a
enum alg_id alg_id
struct key_symmetric s
union key::@320 u
UINT64 private[PRIVATE_DATA_SIZE]
Definition: ps.c:97
Definition: ecma_167.h:138
size_type size() const
Definition: _vector.h:192
_Tp * data()
Definition: _vector.h:213
#define max(a, b)
Definition: svc.c:63
unsigned char UCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: pdh_main.c:96
#define PRIVATEKEYBLOB
Definition: wincrypt.h:2445
#define PUBLICKEYBLOB
Definition: wincrypt.h:2444
#define CALG_DSS_SIGN
Definition: wincrypt.h:2070
unsigned char BYTE
Definition: xxhash.c:193