2 * New cryptographic library (ncrypt.dll)
4 * Copyright 2016 Alex Henrie
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "ncrypt_internal.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ncrypt
);
33 SECURITY_STATUS WINAPI
NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider
, NCRYPT_KEY_HANDLE
*key
,
34 const WCHAR
*algid
, const WCHAR
*name
, DWORD keyspec
, DWORD flags
)
36 FIXME("(%#Ix, %p, %s, %s, %#lx, %#lx): stub\n", provider
, key
, wine_dbgstr_w(algid
),
37 wine_dbgstr_w(name
), keyspec
, flags
);
38 return NTE_NOT_SUPPORTED
;
41 SECURITY_STATUS WINAPI
NCryptDecrypt(NCRYPT_KEY_HANDLE key
, BYTE
*input
, DWORD insize
, void *padding
,
42 BYTE
*output
, DWORD outsize
, DWORD
*result
, DWORD flags
)
44 FIXME("(%#Ix, %p, %lu, %p, %p, %lu, %p, %#lx): stub\n", key
, input
, insize
, padding
,
45 output
, outsize
, result
, flags
);
46 return NTE_NOT_SUPPORTED
;
49 SECURITY_STATUS WINAPI
NCryptDeleteKey(NCRYPT_KEY_HANDLE key
, DWORD flags
)
51 FIXME("(%#Ix, %#lx): stub\n", key
, flags
);
52 return NTE_NOT_SUPPORTED
;
55 SECURITY_STATUS WINAPI
NCryptEncrypt(NCRYPT_KEY_HANDLE key
, BYTE
*input
, DWORD insize
, void *padding
,
56 BYTE
*output
, DWORD outsize
, DWORD
*result
, DWORD flags
)
58 FIXME("(%#Ix, %p, %lu, %p, %p, %lu, %p, %#lx): stub\n", key
, input
, insize
, padding
,
59 output
, outsize
, result
, flags
);
60 return NTE_NOT_SUPPORTED
;
63 SECURITY_STATUS WINAPI
NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE provider
, DWORD alg_ops
,
64 DWORD
*alg_count
, NCryptAlgorithmName
**alg_list
, DWORD flags
)
66 FIXME("(%#Ix, %#lx, %p, %p, %#lx): stub\n", provider
, alg_ops
, alg_count
, alg_list
, flags
);
67 return NTE_NOT_SUPPORTED
;
70 SECURITY_STATUS WINAPI
NCryptEnumKeys(NCRYPT_PROV_HANDLE provider
, const WCHAR
*scope
,
71 NCryptKeyName
**key_name
, PVOID
*enum_state
, DWORD flags
)
73 FIXME("(%#Ix, %p, %p, %p, %#lx): stub\n", provider
, scope
, key_name
, enum_state
, flags
);
74 return NTE_NOT_SUPPORTED
;
77 SECURITY_STATUS WINAPI
NCryptFinalizeKey(NCRYPT_KEY_HANDLE key
, DWORD flags
)
79 FIXME("(%#Ix, %#lx): stub\n", key
, flags
);
80 return NTE_NOT_SUPPORTED
;
83 SECURITY_STATUS WINAPI
NCryptFreeBuffer(PVOID buf
)
85 FIXME("(%p): stub\n", buf
);
86 return NTE_NOT_SUPPORTED
;
89 static SECURITY_STATUS
free_key_object(struct key
*key
)
95 free(key
->rsa
.modulus
);
96 free(key
->rsa
.public_exp
);
97 free(key
->rsa
.prime1
);
98 free(key
->rsa
.prime2
);
102 WARN("invalid key %p\n", key
);
103 return NTE_INVALID_HANDLE
;
105 return ERROR_SUCCESS
;
108 SECURITY_STATUS WINAPI
NCryptFreeObject(NCRYPT_HANDLE handle
)
110 struct object
*object
= (struct object
*)handle
;
111 SECURITY_STATUS ret
= ERROR_SUCCESS
;
114 TRACE("(%#Ix)\n", handle
);
118 WARN("invalid handle %#Ix\n", handle
);
119 return NTE_INVALID_HANDLE
;
122 switch (object
->type
)
126 if ((ret
= free_key_object(&object
->key
))) return ret
;
129 case STORAGE_PROVIDER
:
133 WARN("invalid handle %#Ix\n", handle
);
134 return NTE_INVALID_HANDLE
;
137 for (i
= 0; i
< object
->num_properties
; i
++)
139 free(object
->properties
[i
].key
);
140 free(object
->properties
[i
].value
);
142 free(object
->properties
);
147 static struct object_property
*get_object_property(struct object
*object
, const WCHAR
*name
)
150 for (i
= 0; i
< object
->num_properties
; i
++)
152 struct object_property
*property
= &object
->properties
[i
];
153 if (!lstrcmpW(property
->key
, name
)) return property
;
158 SECURITY_STATUS WINAPI
NCryptGetProperty(NCRYPT_HANDLE handle
, const WCHAR
*name
, BYTE
*output
,
159 DWORD outsize
, DWORD
*result
, DWORD flags
)
161 struct object
*object
= (struct object
*)handle
;
162 const struct object_property
*property
;
164 TRACE("(%#Ix, %s, %p, %lu, %p, %#lx)\n", handle
, wine_dbgstr_w(name
), output
, outsize
, result
, flags
);
165 if (flags
) FIXME("flags %#lx not supported\n", flags
);
167 if (!object
) return NTE_INVALID_HANDLE
;
168 if (!(property
= get_object_property(object
, name
))) return NTE_INVALID_PARAMETER
;
170 *result
= property
->value_size
;
171 if (!output
) return ERROR_SUCCESS
;
172 if (outsize
< property
->value_size
) return NTE_BUFFER_TOO_SMALL
;
174 memcpy(output
, property
->value
, property
->value_size
);
175 return ERROR_SUCCESS
;
178 static struct object
*allocate_object(enum object_type type
)
181 if (!(ret
= calloc(1, sizeof(*ret
)))) return NULL
;
186 struct object_property
*add_object_property(struct object
*object
, const WCHAR
*name
)
188 struct object_property
*property
;
190 if (!object
->num_properties
)
192 if (!(object
->properties
= malloc(sizeof(*property
))))
194 ERR("Error allocating memory.\n");
197 property
= &object
->properties
[object
->num_properties
++];
201 struct object_property
*tmp
;
202 if (!(tmp
= realloc(object
->properties
, sizeof(*property
) * (object
->num_properties
+ 1))))
204 ERR("Error allocating memory.\n");
207 object
->properties
= tmp
;
208 property
= &object
->properties
[object
->num_properties
++];
211 memset(property
, 0, sizeof(*property
));
212 if (!(property
->key
= malloc((lstrlenW(name
) + 1) * sizeof(WCHAR
))))
214 ERR("Error allocating memory.\n");
218 lstrcpyW(property
->key
, name
);
222 static SECURITY_STATUS
set_object_property(struct object
*object
, const WCHAR
*name
, BYTE
*value
, DWORD value_size
)
224 struct object_property
*property
= get_object_property(object
, name
);
227 if (!property
&& !(property
= add_object_property(object
, name
))) return NTE_NO_MEMORY
;
229 property
->value_size
= value_size
;
230 if (!(tmp
= realloc(property
->value
, value_size
)))
232 ERR("Error allocating memory.\n");
234 property
->key
= NULL
;
235 return NTE_NO_MEMORY
;
238 property
->value
= tmp
;
239 memcpy(property
->value
, value
, value_size
);
241 return ERROR_SUCCESS
;
244 SECURITY_STATUS WINAPI
NCryptImportKey(NCRYPT_PROV_HANDLE provider
, NCRYPT_KEY_HANDLE decrypt_key
,
245 const WCHAR
*type
, NCryptBufferDesc
*params
, NCRYPT_KEY_HANDLE
*handle
,
246 BYTE
*data
, DWORD datasize
, DWORD flags
)
248 BCRYPT_KEY_BLOB
*header
= (BCRYPT_KEY_BLOB
*)data
;
250 TRACE("(%#Ix, %#Ix, %s, %p, %p, %p, %lu, %#lx): stub\n", provider
, decrypt_key
, wine_dbgstr_w(type
),
251 params
, handle
, data
, datasize
, flags
);
255 FIXME("Key blob decryption not implemented\n");
256 return NTE_NOT_SUPPORTED
;
260 FIXME("Parameter information not implemented\n");
261 return NTE_NOT_SUPPORTED
;
263 if (flags
== NCRYPT_SILENT_FLAG
)
265 FIXME("Silent flag not implemented\n");
269 ERR("Invalid flags %#lx\n", flags
);
270 return NTE_BAD_FLAGS
;
273 switch (header
->Magic
)
275 case BCRYPT_RSAPUBLIC_MAGIC
:
278 struct object
*object
;
280 BYTE
*public_exp
, *modulus
;
281 BCRYPT_RSAKEY_BLOB
*rsaheader
= (BCRYPT_RSAKEY_BLOB
*)data
;
283 if (datasize
< sizeof(*rsaheader
))
285 ERR("Invalid buffer size.\n");
289 expected_size
= sizeof(*rsaheader
) + rsaheader
->cbPublicExp
+ rsaheader
->cbModulus
;
290 if (datasize
!= expected_size
)
292 ERR("Invalid buffer size.\n");
296 if (!(object
= allocate_object(KEY
)))
298 ERR("Error allocating memory.\n");
299 return NTE_NO_MEMORY
;
304 key
->rsa
.bit_length
= rsaheader
->BitLength
;
305 key
->rsa
.public_exp_size
= rsaheader
->cbPublicExp
;
306 key
->rsa
.modulus_size
= rsaheader
->cbModulus
;
307 if (!(key
->rsa
.public_exp
= malloc(rsaheader
->cbPublicExp
)))
309 ERR("Error allocating memory.\n");
311 return NTE_NO_MEMORY
;
313 if (!(key
->rsa
.modulus
= malloc(rsaheader
->cbModulus
)))
315 ERR("Error allocating memory.\n");
316 free(key
->rsa
.public_exp
);
318 return NTE_NO_MEMORY
;
321 public_exp
= &data
[sizeof(*rsaheader
)]; /* The public exp is after the header. */
322 modulus
= &public_exp
[rsaheader
->cbPublicExp
]; /* The modulus is after the public exponent. */
323 memcpy(key
->rsa
.public_exp
, public_exp
, rsaheader
->cbPublicExp
);
324 memcpy(key
->rsa
.modulus
, modulus
, rsaheader
->cbModulus
);
326 set_object_property(object
, NCRYPT_ALGORITHM_GROUP_PROPERTY
, (BYTE
*)L
"RSA", sizeof(L
"RSA"));
327 set_object_property(object
, NCRYPT_LENGTH_PROPERTY
, (BYTE
*)&key
->rsa
.bit_length
, sizeof(key
->rsa
.bit_length
));
328 set_object_property(object
, NCRYPT_PROVIDER_HANDLE_PROPERTY
, (BYTE
*)&provider
, sizeof(provider
));
329 *handle
= (NCRYPT_KEY_HANDLE
)object
;
333 FIXME("Unhandled key magic %#lx.\n", header
->Magic
);
334 return NTE_INVALID_PARAMETER
;
337 return ERROR_SUCCESS
;
340 SECURITY_STATUS WINAPI
NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider
, const WCHAR
*algid
, DWORD flags
)
342 FIXME("(%#Ix, %s, %#lx): stub\n", provider
, wine_dbgstr_w(algid
), flags
);
343 return NTE_NOT_SUPPORTED
;
346 BOOL WINAPI
NCryptIsKeyHandle(NCRYPT_KEY_HANDLE hKey
)
348 FIXME("(%#Ix): stub\n", hKey
);
352 SECURITY_STATUS WINAPI
NCryptOpenKey(NCRYPT_PROV_HANDLE provider
, NCRYPT_KEY_HANDLE
*key
,
353 const WCHAR
*name
, DWORD keyspec
, DWORD flags
)
355 FIXME("(%#Ix, %p, %s, %#lx, %#lx): stub\n", provider
, key
, wine_dbgstr_w(name
), keyspec
, flags
);
356 return NTE_NOT_SUPPORTED
;
359 SECURITY_STATUS WINAPI
NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE
*provider
, const WCHAR
*name
, DWORD flags
)
361 struct object
*object
;
363 FIXME("(%p, %s, %#lx): stub\n", provider
, wine_dbgstr_w(name
), flags
);
365 if (!(object
= allocate_object(STORAGE_PROVIDER
)))
367 ERR("Error allocating memory.\n");
368 return NTE_NO_MEMORY
;
370 *provider
= (NCRYPT_PROV_HANDLE
)object
;
371 return ERROR_SUCCESS
;
374 SECURITY_STATUS WINAPI
NCryptSetProperty(NCRYPT_HANDLE handle
, const WCHAR
*name
, BYTE
*input
, DWORD insize
, DWORD flags
)
376 struct object
*object
= (struct object
*)handle
;
378 TRACE("(%#Ix, %s, %p, %lu, %#lx)\n", handle
, wine_dbgstr_w(name
), input
, insize
, flags
);
379 if (flags
) FIXME("flags %#lx not supported\n", flags
);
381 if (!object
) return NTE_INVALID_HANDLE
;
382 return set_object_property(object
, name
, input
, insize
);
385 SECURITY_STATUS WINAPI
NCryptVerifySignature(NCRYPT_KEY_HANDLE handle
, void *padding
, BYTE
*hash
, DWORD hash_size
,
386 BYTE
*signature
, DWORD signature_size
, DWORD flags
)
388 FIXME("(%#Ix, %p, %p, %lu, %p, %lu, %#lx): stub\n", handle
, padding
, hash
, hash_size
, signature
,
389 signature_size
, flags
);
390 return ERROR_SUCCESS
;