Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f18ccfef
Commit
f18ccfef
authored
Oct 31, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
crypt32: Split the import_cert_store function to move memory allocations to the PE side.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
67710737
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
111 additions
and
66 deletions
+111
-66
crypt32_private.h
dlls/crypt32/crypt32_private.h
+8
-2
pfx.c
dlls/crypt32/pfx.c
+29
-20
unixlib.c
dlls/crypt32/unixlib.c
+74
-44
No files found.
dlls/crypt32/crypt32_private.h
View file @
f18ccfef
...
...
@@ -460,11 +460,17 @@ void init_empty_store(void) DECLSPEC_HIDDEN;
/* Unix interface */
struct
cert_store_data
;
struct
unix_funcs
{
BOOL
(
WINAPI
*
enum_root_certs
)(
void
*
buffer
,
SIZE_T
size
,
SIZE_T
*
needed
);
BOOL
(
WINAPI
*
import_cert_store
)(
CRYPT_DATA_BLOB
*
pfx
,
const
WCHAR
*
password
,
DWORD
flags
,
void
**
key_ret
,
void
***
chain_ret
,
DWORD
*
count_ret
);
BOOL
(
WINAPI
*
open_cert_store
)(
CRYPT_DATA_BLOB
*
pfx
,
const
WCHAR
*
password
,
struct
cert_store_data
**
data_ret
);
NTSTATUS
(
WINAPI
*
import_store_key
)(
struct
cert_store_data
*
data
,
void
*
buf
,
DWORD
*
buf_size
);
NTSTATUS
(
WINAPI
*
import_store_cert
)(
struct
cert_store_data
*
data
,
unsigned
int
index
,
void
*
buf
,
DWORD
*
buf_size
);
void
(
WINAPI
*
close_cert_store
)(
struct
cert_store_data
*
data
);
};
extern
const
struct
unix_funcs
*
unix_funcs
DECLSPEC_HIDDEN
;
...
...
dlls/crypt32/pfx.c
View file @
f18ccfef
...
...
@@ -17,7 +17,10 @@
*/
#include <stdarg.h>
#include <stdlib.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
...
...
@@ -29,13 +32,15 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
crypt
);
static
HCRYPTPROV
import_key
(
void
*
key
,
DWORD
flags
)
static
HCRYPTPROV
import_key
(
struct
cert_store_data
*
data
,
DWORD
flags
)
{
HCRYPTPROV
prov
=
0
;
HCRYPTKEY
cryptkey
;
DWORD
size
,
acquire_flags
;
void
*
key
;
if
(
unix_funcs
->
import_store_key
(
data
,
NULL
,
&
size
)
!=
STATUS_BUFFER_TOO_SMALL
)
return
0
;
size
=
HeapSize
(
GetProcessHeap
(),
0
,
key
);
acquire_flags
=
(
flags
&
CRYPT_MACHINE_KEYSET
)
|
CRYPT_NEWKEYSET
;
if
(
!
CryptAcquireContextW
(
&
prov
,
NULL
,
MS_ENHANCED_PROV_W
,
PROV_RSA_FULL
,
acquire_flags
))
{
...
...
@@ -49,13 +54,17 @@ static HCRYPTPROV import_key( void *key, DWORD flags )
}
}
if
(
!
CryptImportKey
(
prov
,
key
,
size
,
0
,
flags
&
CRYPT_EXPORTABLE
,
&
cryptkey
))
key
=
malloc
(
size
);
if
(
unix_funcs
->
import_store_key
(
data
,
key
,
&
size
)
||
!
CryptImportKey
(
prov
,
key
,
size
,
0
,
flags
&
CRYPT_EXPORTABLE
,
&
cryptkey
))
{
WARN
(
"CryptImportKey failed %08x
\n
"
,
GetLastError
()
);
CryptReleaseContext
(
prov
,
0
);
free
(
key
);
return
0
;
}
CryptDestroyKey
(
cryptkey
);
free
(
key
);
return
prov
;
}
...
...
@@ -132,10 +141,10 @@ static BOOL set_key_prov_info( const void *ctx, HCRYPTPROV prov )
HCERTSTORE
WINAPI
PFXImportCertStore
(
CRYPT_DATA_BLOB
*
pfx
,
const
WCHAR
*
password
,
DWORD
flags
)
{
void
*
key
,
**
chain
;
DWORD
i
,
chain_len
=
0
;
DWORD
i
=
0
,
size
;
HCERTSTORE
store
=
NULL
;
HCRYPTPROV
prov
=
0
;
struct
cert_store_data
*
data
=
NULL
;
if
(
!
pfx
)
{
...
...
@@ -147,15 +156,14 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
FIXME
(
"flags %08x not supported
\n
"
,
flags
);
return
NULL
;
}
if
(
!
unix_funcs
->
import
_cert_store
)
if
(
!
unix_funcs
->
open
_cert_store
)
{
FIXME
(
"(%p, %p, %08x)
\n
"
,
pfx
,
password
,
flags
);
return
NULL
;
}
if
(
!
unix_funcs
->
import_cert_store
(
pfx
,
password
,
flags
,
&
key
,
&
chain
,
&
chain_len
))
return
NULL
;
if
(
!
unix_funcs
->
open_cert_store
(
pfx
,
password
,
&
data
))
return
NULL
;
prov
=
import_key
(
key
,
flags
);
heap_free
(
key
);
prov
=
import_key
(
data
,
flags
);
if
(
!
prov
)
goto
error
;
if
(
!
(
store
=
CertOpenStore
(
CERT_STORE_PROV_MEMORY
,
0
,
0
,
0
,
NULL
)))
...
...
@@ -164,14 +172,17 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
goto
error
;
}
if
(
chain_len
>
1
)
FIXME
(
"handle certificate chain
\n
"
);
for
(
i
=
0
;
i
<
chain_len
;
i
++
)
for
(;;)
{
const
void
*
ctx
;
size_t
size
=
HeapSize
(
GetProcessHeap
(),
0
,
chain
[
i
]
);
if
(
!
(
ctx
=
CertCreateContext
(
CERT_STORE_CERTIFICATE_CONTEXT
,
X509_ASN_ENCODING
,
chain
[
i
],
size
,
0
,
NULL
)))
const
void
*
ctx
=
NULL
;
void
*
cert
;
if
(
unix_funcs
->
import_store_cert
(
data
,
i
,
NULL
,
&
size
)
!=
STATUS_BUFFER_TOO_SMALL
)
break
;
cert
=
malloc
(
size
);
if
(
!
unix_funcs
->
import_store_cert
(
data
,
i
++
,
cert
,
&
size
))
ctx
=
CertCreateContext
(
CERT_STORE_CERTIFICATE_CONTEXT
,
X509_ASN_ENCODING
,
cert
,
size
,
0
,
NULL
);
free
(
cert
);
if
(
!
ctx
)
{
WARN
(
"CertCreateContext failed %08x
\n
"
,
GetLastError
()
);
goto
error
;
...
...
@@ -199,15 +210,13 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
}
CertFreeCertificateContext
(
ctx
);
}
while
(
chain_len
)
heap_free
(
chain
[
--
chain_len
]
);
heap_free
(
chain
);
unix_funcs
->
close_cert_store
(
data
);
return
store
;
error:
CryptReleaseContext
(
prov
,
0
);
CertCloseStore
(
store
,
0
);
while
(
chain_len
)
heap_free
(
chain
[
--
chain_len
]
);
heap_free
(
chain
);
if
(
data
)
unix_funcs
->
close_cert_store
(
data
);
return
NULL
;
}
...
...
dlls/crypt32/unixlib.c
View file @
f18ccfef
...
...
@@ -155,39 +155,38 @@ static void gnutls_uninitialize(void)
#define RSA_MAGIC_KEY ('R' | ('S' << 8) | ('A' << 16) | ('2' << 24))
#define RSA_PUBEXP 65537
static
DWORD
import_key
(
gnutls_x509_privkey_t
key
,
DWORD
flags
,
void
**
data_ret
)
struct
cert_store_data
{
gnutls_pkcs12_t
p12
;
gnutls_x509_privkey_t
key
;
gnutls_x509_crt_t
*
chain
;
unsigned
int
key_bitlen
;
unsigned
int
chain_len
;
};
static
NTSTATUS
WINAPI
import_store_key
(
struct
cert_store_data
*
data
,
void
*
buf
,
DWORD
*
buf_size
)
{
int
i
,
ret
;
unsigned
int
bitlen
;
unsigned
int
bitlen
=
data
->
key_bitlen
;
gnutls_datum_t
m
,
e
,
d
,
p
,
q
,
u
,
e1
,
e2
;
BLOBHEADER
*
hdr
;
RSAPUBKEY
*
rsakey
;
BYTE
*
buf
,
*
src
,
*
dst
;
BYTE
*
src
,
*
dst
;
DWORD
size
;
*
data_ret
=
NULL
;
if
((
ret
=
pgnutls_x509_privkey_get_pk_algorithm2
(
key
,
&
bitlen
))
<
0
)
{
pgnutls_perror
(
ret
);
return
0
;
}
if
(
ret
!=
GNUTLS_PK_RSA
)
size
=
sizeof
(
*
hdr
)
+
sizeof
(
*
rsakey
)
+
(
bitlen
*
9
/
16
);
if
(
!
buf
||
*
buf_size
<
size
)
{
FIXME
(
"key algorithm %u not supported
\n
"
,
ret
)
;
return
0
;
*
buf_size
=
size
;
return
STATUS_BUFFER_TOO_SMALL
;
}
if
((
ret
=
pgnutls_x509_privkey_export_rsa_raw2
(
key
,
&
m
,
&
e
,
&
d
,
&
p
,
&
q
,
&
u
,
&
e1
,
&
e2
))
<
0
)
if
((
ret
=
pgnutls_x509_privkey_export_rsa_raw2
(
data
->
key
,
&
m
,
&
e
,
&
d
,
&
p
,
&
q
,
&
u
,
&
e1
,
&
e2
))
<
0
)
{
pgnutls_perror
(
ret
);
return
0
;
return
STATUS_INVALID_PARAMETER
;
}
size
=
sizeof
(
*
hdr
)
+
sizeof
(
*
rsakey
)
+
(
bitlen
*
9
/
16
);
if
(
!
(
buf
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
size
)))
goto
done
;
hdr
=
(
BLOBHEADER
*
)
buf
;
hdr
->
bType
=
PRIVATEKEYBLOB
;
hdr
->
bVersion
=
CUR_BLOB_VERSION
;
...
...
@@ -235,8 +234,6 @@ static DWORD import_key( gnutls_x509_privkey_t key, DWORD flags, void **data_ret
else
src
=
d
.
data
;
for
(
i
=
bitlen
/
8
-
1
;
i
>=
0
;
i
--
)
*
dst
++
=
src
[
i
];
*
data_ret
=
buf
;
done:
free
(
m
.
data
);
free
(
e
.
data
);
...
...
@@ -246,8 +243,7 @@ done:
free
(
u
.
data
);
free
(
e1
.
data
);
free
(
e2
.
data
);
if
(
!*
data_ret
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
buf
);
return
size
;
return
STATUS_SUCCESS
;
}
static
char
*
password_to_ascii
(
const
WCHAR
*
str
)
...
...
@@ -265,16 +261,18 @@ static char *password_to_ascii( const WCHAR *str )
return
ret
;
}
static
BOOL
WINAPI
import_cert_store
(
CRYPT_DATA_BLOB
*
pfx
,
const
WCHAR
*
password
,
DWORD
flags
,
void
**
key_ret
,
void
***
chain_ret
,
DWORD
*
count
_ret
)
static
BOOL
WINAPI
open_cert_store
(
CRYPT_DATA_BLOB
*
pfx
,
const
WCHAR
*
password
,
struct
cert_store_data
**
data
_ret
)
{
gnutls_pkcs12_t
p12
;
gnutls_datum_t
pfx_data
;
gnutls_x509_privkey_t
key
;
gnutls_x509_crt_t
*
chain
;
unsigned
int
chain_len
,
i
;
unsigned
int
chain_len
;
unsigned
int
bitlen
;
char
*
pwd
=
NULL
;
int
ret
;
struct
cert_store_data
*
store_data
;
if
(
password
&&
!
(
pwd
=
password_to_ascii
(
password
)))
return
FALSE
;
...
...
@@ -287,27 +285,25 @@ static BOOL WINAPI import_cert_store( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
if
((
ret
=
pgnutls_pkcs12_simple_parse
(
p12
,
pwd
?
pwd
:
""
,
&
key
,
&
chain
,
&
chain_len
,
NULL
,
NULL
,
NULL
,
0
))
<
0
)
goto
error
;
if
(
!
import_key
(
key
,
flags
,
key_ret
))
goto
error
;
*
chain_ret
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
chain_len
*
sizeof
(
*
chain_ret
)
);
*
count_ret
=
chain_len
;
for
(
i
=
0
;
i
<
chain_len
;
i
++
)
{
size_t
size
=
0
;
if
((
ret
=
pgnutls_x509_crt_export
(
chain
[
i
],
GNUTLS_X509_FMT_DER
,
NULL
,
&
size
))
!=
GNUTLS_E_SHORT_MEMORY_BUFFER
)
if
((
ret
=
pgnutls_x509_privkey_get_pk_algorithm2
(
key
,
&
bitlen
))
<
0
)
goto
error
;
(
*
chain_ret
)[
i
]
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
size
);
if
((
ret
=
pgnutls_x509_crt_export
(
chain
[
i
],
GNUTLS_X509_FMT_DER
,
(
*
chain_ret
)[
i
],
&
size
))
<
0
)
free
(
pwd
);
if
(
ret
!=
GNUTLS_PK_RSA
)
{
i
++
;
while
(
i
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
(
*
chain_ret
)[
--
i
]
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
*
chain_ret
);
goto
error
;
}
}
FIXME
(
"key algorithm %u not supported
\n
"
,
ret
);
pgnutls_pkcs12_deinit
(
p12
);
return
FALSE
;
}
store_data
=
malloc
(
sizeof
(
*
store_data
)
);
store_data
->
p12
=
p12
;
store_data
->
key
=
key
;
store_data
->
chain
=
chain
;
store_data
->
key_bitlen
=
bitlen
;
store_data
->
chain_len
=
chain_len
;
*
data_ret
=
store_data
;
return
TRUE
;
error:
...
...
@@ -317,6 +313,34 @@ error:
return
FALSE
;
}
static
NTSTATUS
WINAPI
import_store_cert
(
struct
cert_store_data
*
data
,
unsigned
int
index
,
void
*
buf
,
DWORD
*
buf_size
)
{
size_t
size
=
0
;
int
ret
;
if
(
index
>=
data
->
chain_len
)
return
STATUS_NO_MORE_ENTRIES
;
if
((
ret
=
pgnutls_x509_crt_export
(
data
->
chain
[
index
],
GNUTLS_X509_FMT_DER
,
NULL
,
&
size
))
!=
GNUTLS_E_SHORT_MEMORY_BUFFER
)
return
STATUS_INVALID_PARAMETER
;
if
(
!
buf
||
*
buf_size
<
size
)
{
*
buf_size
=
size
;
return
STATUS_BUFFER_TOO_SMALL
;
}
if
((
ret
=
pgnutls_x509_crt_export
(
data
->
chain
[
index
],
GNUTLS_X509_FMT_DER
,
buf
,
&
size
))
<
0
)
return
STATUS_INVALID_PARAMETER
;
return
STATUS_SUCCESS
;
}
static
void
WINAPI
close_cert_store
(
struct
cert_store_data
*
data
)
{
pgnutls_pkcs12_deinit
(
data
->
p12
);
free
(
data
);
}
#endif
/* SONAME_LIBGNUTLS */
struct
root_cert
...
...
@@ -649,7 +673,13 @@ NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *p
{
case
DLL_PROCESS_ATTACH
:
#ifdef SONAME_LIBGNUTLS
if
(
gnutls_initialize
())
funcs
.
import_cert_store
=
import_cert_store
;
if
(
gnutls_initialize
())
{
funcs
.
open_cert_store
=
open_cert_store
;
funcs
.
import_store_key
=
import_store_key
;
funcs
.
import_store_cert
=
import_store_cert
;
funcs
.
close_cert_store
=
close_cert_store
;
}
#endif
*
(
const
struct
unix_funcs
**
)
ptr_out
=
&
funcs
;
break
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment