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
16d9f62b
Commit
16d9f62b
authored
Feb 07, 2019
by
Hans Leidekker
Committed by
Alexandre Julliard
Feb 07, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
secur32: Add support for client certificate authentication.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
88b20b2d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
345 additions
and
56 deletions
+345
-56
schannel.c
dlls/secur32/schannel.c
+43
-49
schannel_gnutls.c
dlls/secur32/schannel_gnutls.c
+299
-4
schannel_macosx.c
dlls/secur32/schannel_macosx.c
+2
-2
secur32_priv.h
dlls/secur32/secur32_priv.h
+1
-1
No files found.
dlls/secur32/schannel.c
View file @
16d9f62b
...
...
@@ -338,26 +338,26 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesW(
return
ret
;
}
static
SECURITY_STATUS
schan_CheckCreds
(
const
SCHANNEL_CRED
*
schanCred
)
static
SECURITY_STATUS
get_cert
(
const
SCHANNEL_CRED
*
cred
,
CERT_CONTEXT
const
**
cert
)
{
SECURITY_STATUS
st
;
SECURITY_STATUS
st
atus
;
DWORD
i
;
TRACE
(
"dwVersion = %
d
\n
"
,
schanC
red
->
dwVersion
);
TRACE
(
"cCreds = %
d
\n
"
,
schanC
red
->
cCreds
);
TRACE
(
"
hRootStore = %p
\n
"
,
schanCred
->
hRootStore
);
TRACE
(
"
cMappers = %d
\n
"
,
schanCred
->
cMappers
);
TRACE
(
"c
SupportedAlgs = %d:
\n
"
,
schanCred
->
cSupportedAlg
s
);
for
(
i
=
0
;
i
<
schanCred
->
cSupportedAlgs
;
i
++
)
TRACE
(
"%08x
\n
"
,
schanC
red
->
palgSupportedAlgs
[
i
]);
TRACE
(
"grbitEnabledProtocols = %08x
\n
"
,
schanC
red
->
grbitEnabledProtocols
);
TRACE
(
"dwMinimumCipherStrength = %
d
\n
"
,
schanC
red
->
dwMinimumCipherStrength
);
TRACE
(
"dwMaximumCipherStrength = %
d
\n
"
,
schanC
red
->
dwMaximumCipherStrength
);
TRACE
(
"dwSessionLifespan = %
d
\n
"
,
schanC
red
->
dwSessionLifespan
);
TRACE
(
"dwFlags = %08x
\n
"
,
schanC
red
->
dwFlags
);
TRACE
(
"dwCredFormat = %
d
\n
"
,
schanC
red
->
dwCredFormat
);
switch
(
schanC
red
->
dwVersion
)
TRACE
(
"dwVersion = %
u
\n
"
,
c
red
->
dwVersion
);
TRACE
(
"cCreds = %
u
\n
"
,
c
red
->
cCreds
);
TRACE
(
"
paCred = %p
\n
"
,
cred
->
paCred
);
TRACE
(
"
hRootStore = %p
\n
"
,
cred
->
hRootStore
);
TRACE
(
"c
Mappers = %u
\n
"
,
cred
->
cMapper
s
);
TRACE
(
"cSupportedAlgs = %u:
\n
"
,
cred
->
cSupportedAlgs
);
for
(
i
=
0
;
i
<
cred
->
cSupportedAlgs
;
i
++
)
TRACE
(
"%08x
\n
"
,
c
red
->
palgSupportedAlgs
[
i
]);
TRACE
(
"grbitEnabledProtocols = %08x
\n
"
,
c
red
->
grbitEnabledProtocols
);
TRACE
(
"dwMinimumCipherStrength = %
u
\n
"
,
c
red
->
dwMinimumCipherStrength
);
TRACE
(
"dwMaximumCipherStrength = %
u
\n
"
,
c
red
->
dwMaximumCipherStrength
);
TRACE
(
"dwSessionLifespan = %
u
\n
"
,
c
red
->
dwSessionLifespan
);
TRACE
(
"dwFlags = %08x
\n
"
,
c
red
->
dwFlags
);
TRACE
(
"dwCredFormat = %
u
\n
"
,
c
red
->
dwCredFormat
);
switch
(
c
red
->
dwVersion
)
{
case
SCH_CRED_V3
:
case
SCHANNEL_CRED_VERSION
:
...
...
@@ -366,29 +366,24 @@ static SECURITY_STATUS schan_CheckCreds(const SCHANNEL_CRED *schanCred)
return
SEC_E_INTERNAL_ERROR
;
}
if
(
schanCred
->
cCreds
==
0
)
st
=
SEC_E_NO_CREDENTIALS
;
else
if
(
schanCred
->
cCreds
>
1
)
st
=
SEC_E_UNKNOWN_CREDENTIALS
;
if
(
!
cred
->
cCreds
)
status
=
SEC_E_NO_CREDENTIALS
;
else
if
(
cred
->
cCreds
>
1
)
status
=
SEC_E_UNKNOWN_CREDENTIALS
;
else
{
DWORD
keySpec
;
HCRYPTPROV
csp
;
BOOL
ret
,
freeCSP
;
ret
=
CryptAcquireCertificatePrivateKey
(
schanCred
->
paCred
[
0
],
0
,
/* FIXME: what flags to use? */
NULL
,
&
csp
,
&
keySpec
,
&
freeCSP
);
if
(
ret
)
DWORD
spec
;
HCRYPTPROV
prov
;
BOOL
free
;
if
(
CryptAcquireCertificatePrivateKey
(
cred
->
paCred
[
0
],
CRYPT_ACQUIRE_CACHE_FLAG
,
NULL
,
&
prov
,
&
spec
,
&
free
))
{
st
=
SEC_E_OK
;
if
(
freeCSP
)
CryptReleaseContext
(
csp
,
0
)
;
if
(
free
)
CryptReleaseContext
(
prov
,
0
)
;
*
cert
=
cred
->
paCred
[
0
];
status
=
SEC_E_OK
;
}
else
st
=
SEC_E_UNKNOWN_CREDENTIALS
;
else
status
=
SEC_E_UNKNOWN_CREDENTIALS
;
}
return
st
;
return
status
;
}
static
SECURITY_STATUS
schan_AcquireClientCredentials
(
const
SCHANNEL_CRED
*
schanCred
,
...
...
@@ -397,17 +392,18 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan
struct
schan_credentials
*
creds
;
unsigned
enabled_protocols
;
ULONG_PTR
handle
;
SECURITY_STATUS
st
=
SEC_E_OK
;
SECURITY_STATUS
status
=
SEC_E_OK
;
const
CERT_CONTEXT
*
cert
=
NULL
;
TRACE
(
"schanCred %p, phCredential %p, ptsExpiry %p
\n
"
,
schanCred
,
phCredential
,
ptsExpiry
);
if
(
schanCred
)
{
st
=
schan_CheckCreds
(
schanCred
);
if
(
st
!=
SEC_E_OK
&&
st
!=
SEC_E_NO_CREDENTIALS
)
return
st
;
st
atus
=
get_cert
(
schanCred
,
&
cert
);
if
(
st
atus
!=
SEC_E_OK
&&
status
!=
SEC_E_NO_CREDENTIALS
)
return
st
atus
;
st
=
SEC_E_OK
;
st
atus
=
SEC_E_OK
;
}
read_config
();
...
...
@@ -420,9 +416,6 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan
return
SEC_E_NO_AUTHENTICATING_AUTHORITY
;
}
/* For now, the only thing I'm interested in is the direction of the
* connection, so just store it.
*/
creds
=
heap_alloc
(
sizeof
(
*
creds
));
if
(
!
creds
)
return
SEC_E_INSUFFICIENT_MEMORY
;
...
...
@@ -430,7 +423,7 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan
if
(
handle
==
SCHAN_INVALID_HANDLE
)
goto
fail
;
creds
->
credential_use
=
SECPKG_CRED_OUTBOUND
;
if
(
!
schan_imp_allocate_certificate_credentials
(
creds
))
if
(
!
schan_imp_allocate_certificate_credentials
(
creds
,
cert
))
{
schan_free_handle
(
handle
,
SCHAN_HANDLE_CRED
);
goto
fail
;
...
...
@@ -447,7 +440,7 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan
ptsExpiry
->
HighPart
=
0
;
}
return
st
;
return
st
atus
;
fail:
heap_free
(
creds
);
...
...
@@ -457,14 +450,15 @@ fail:
static
SECURITY_STATUS
schan_AcquireServerCredentials
(
const
SCHANNEL_CRED
*
schanCred
,
PCredHandle
phCredential
,
PTimeStamp
ptsExpiry
)
{
SECURITY_STATUS
st
;
SECURITY_STATUS
status
;
const
CERT_CONTEXT
*
cert
=
NULL
;
TRACE
(
"schanCred %p, phCredential %p, ptsExpiry %p
\n
"
,
schanCred
,
phCredential
,
ptsExpiry
);
if
(
!
schanCred
)
return
SEC_E_NO_CREDENTIALS
;
st
=
schan_CheckCreds
(
schanCred
);
if
(
st
==
SEC_E_OK
)
st
atus
=
get_cert
(
schanCred
,
&
cert
);
if
(
st
atus
==
SEC_E_OK
)
{
ULONG_PTR
handle
;
struct
schan_credentials
*
creds
;
...
...
@@ -485,7 +479,7 @@ static SECURITY_STATUS schan_AcquireServerCredentials(const SCHANNEL_CRED *schan
/* FIXME: get expiry from cert */
}
return
st
;
return
st
atus
;
}
static
SECURITY_STATUS
schan_AcquireCredentialsHandle
(
ULONG
fCredentialUse
,
...
...
dlls/secur32/schannel_gnutls.c
View file @
16d9f62b
...
...
@@ -24,18 +24,24 @@
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#ifdef SONAME_LIBGNUTLS
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include <gnutls/abstract.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "sspi.h"
#include "schannel.h"
#include "lmcons.h"
#include "winreg.h"
#include "secur32_priv.h"
#include "wine/debug.h"
#include "wine/library.h"
#include "wine/unicode.h"
#if defined(SONAME_LIBGNUTLS) && !defined(HAVE_SECURITY_SECURITY_H)
...
...
@@ -43,7 +49,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(secur32);
WINE_DECLARE_DEBUG_CHANNEL
(
winediag
);
/* Not present in gnutls version < 2.9.10. */
static
int
(
*
pgnutls_cipher_get_block_size
)(
gnutls_cipher_algorithm_t
algorithm
);
static
int
(
*
pgnutls_cipher_get_block_size
)(
gnutls_cipher_algorithm_t
);
/* Not present in gnutls version < 3.4.0. */
static
int
(
*
pgnutls_privkey_export_x509
)(
gnutls_privkey_t
,
gnutls_x509_privkey_t
*
);
static
void
*
libgnutls_handle
;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
...
...
@@ -52,6 +61,7 @@ MAKE_FUNCPTR(gnutls_alert_get_name);
MAKE_FUNCPTR
(
gnutls_certificate_allocate_credentials
);
MAKE_FUNCPTR
(
gnutls_certificate_free_credentials
);
MAKE_FUNCPTR
(
gnutls_certificate_get_peers
);
MAKE_FUNCPTR
(
gnutls_certificate_set_x509_key
);
MAKE_FUNCPTR
(
gnutls_cipher_get
);
MAKE_FUNCPTR
(
gnutls_cipher_get_key_size
);
MAKE_FUNCPTR
(
gnutls_credentials_set
);
...
...
@@ -68,6 +78,9 @@ MAKE_FUNCPTR(gnutls_mac_get_key_size);
MAKE_FUNCPTR
(
gnutls_perror
);
MAKE_FUNCPTR
(
gnutls_protocol_get_version
);
MAKE_FUNCPTR
(
gnutls_priority_set_direct
);
MAKE_FUNCPTR
(
gnutls_privkey_deinit
);
MAKE_FUNCPTR
(
gnutls_privkey_import_rsa_raw
);
MAKE_FUNCPTR
(
gnutls_privkey_init
);
MAKE_FUNCPTR
(
gnutls_record_get_max_size
);
MAKE_FUNCPTR
(
gnutls_record_recv
);
MAKE_FUNCPTR
(
gnutls_record_send
);
...
...
@@ -77,6 +90,10 @@ MAKE_FUNCPTR(gnutls_transport_set_errno);
MAKE_FUNCPTR
(
gnutls_transport_set_ptr
);
MAKE_FUNCPTR
(
gnutls_transport_set_pull_function
);
MAKE_FUNCPTR
(
gnutls_transport_set_push_function
);
MAKE_FUNCPTR
(
gnutls_x509_crt_deinit
);
MAKE_FUNCPTR
(
gnutls_x509_crt_import
);
MAKE_FUNCPTR
(
gnutls_x509_crt_init
);
MAKE_FUNCPTR
(
gnutls_x509_privkey_deinit
);
#undef MAKE_FUNCPTR
#if GNUTLS_VERSION_MAJOR < 3
...
...
@@ -115,6 +132,12 @@ static int compat_cipher_get_block_size(gnutls_cipher_algorithm_t cipher)
}
}
static
int
compat_gnutls_privkey_export_x509
(
gnutls_privkey_t
privkey
,
gnutls_x509_privkey_t
*
key
)
{
FIXME
(
"
\n
"
);
return
GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
}
static
ssize_t
schan_pull_adapter
(
gnutls_transport_ptr_t
transport
,
void
*
buff
,
size_t
buff_len
)
{
...
...
@@ -556,12 +579,271 @@ again:
return
SEC_E_OK
;
}
BOOL
schan_imp_allocate_certificate_credentials
(
schan_credentials
*
c
)
static
WCHAR
*
get_key_container_path
(
const
CERT_CONTEXT
*
ctx
)
{
static
const
WCHAR
rsabaseW
[]
=
{
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'W'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'C'
,
'r'
,
'y'
,
'p'
,
't'
,
'o'
,
'\\'
,
'R'
,
'S'
,
'A'
,
'\\'
,
0
};
DWORD
size
;
CERT_KEY_CONTEXT
keyctx
;
CRYPT_KEY_PROV_INFO
*
prov
;
WCHAR
username
[
UNLEN
+
1
],
*
ret
=
NULL
;
DWORD
len
=
ARRAY_SIZE
(
username
);
size
=
sizeof
(
keyctx
);
if
(
CertGetCertificateContextProperty
(
ctx
,
CERT_KEY_CONTEXT_PROP_ID
,
&
keyctx
,
&
size
))
{
char
*
str
;
if
(
!
CryptGetProvParam
(
keyctx
.
hCryptProv
,
PP_CONTAINER
,
NULL
,
&
size
,
0
))
return
NULL
;
if
(
!
(
str
=
heap_alloc
(
size
)))
return
NULL
;
if
(
!
CryptGetProvParam
(
keyctx
.
hCryptProv
,
PP_CONTAINER
,
(
BYTE
*
)
str
,
&
size
,
0
))
return
NULL
;
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
str
,
-
1
,
NULL
,
0
);
if
(
!
(
ret
=
heap_alloc
(
sizeof
(
rsabaseW
)
+
len
*
sizeof
(
WCHAR
))))
{
heap_free
(
str
);
return
NULL
;
}
strcpyW
(
ret
,
rsabaseW
);
MultiByteToWideChar
(
CP_ACP
,
0
,
str
,
-
1
,
ret
+
strlenW
(
ret
),
len
);
heap_free
(
str
);
}
else
{
size
=
0
;
if
(
!
CertGetCertificateContextProperty
(
ctx
,
CERT_KEY_PROV_INFO_PROP_ID
,
NULL
,
&
size
))
return
NULL
;
if
(
!
(
prov
=
heap_alloc
(
size
)))
return
NULL
;
if
(
!
CertGetCertificateContextProperty
(
ctx
,
CERT_KEY_PROV_INFO_PROP_ID
,
prov
,
&
size
))
{
heap_free
(
prov
);
return
NULL
;
}
if
(
!
(
ret
=
heap_alloc
(
sizeof
(
rsabaseW
)
+
strlenW
(
prov
->
pwszContainerName
)
*
sizeof
(
WCHAR
))))
{
heap_free
(
prov
);
return
NULL
;
}
strcpyW
(
ret
,
rsabaseW
);
strcatW
(
ret
,
prov
->
pwszContainerName
);
heap_free
(
prov
);
}
if
(
!
ret
&&
GetUserNameW
(
username
,
&
len
)
&&
(
ret
=
heap_alloc
(
sizeof
(
rsabaseW
)
+
len
*
sizeof
(
WCHAR
))))
{
strcpyW
(
ret
,
rsabaseW
);
strcatW
(
ret
,
username
);
}
return
ret
;
}
#define MAX_LEAD_BYTES 8
static
BYTE
*
get_key_blob
(
const
CERT_CONTEXT
*
ctx
,
ULONG
*
size
)
{
static
const
WCHAR
keyexchangeW
[]
=
{
'K'
,
'e'
,
'y'
,
'E'
,
'x'
,
'c'
,
'h'
,
'a'
,
'n'
,
'g'
,
'e'
,
'K'
,
'e'
,
'y'
,
'P'
,
'a'
,
'i'
,
'r'
,
0
};
static
const
WCHAR
signatureW
[]
=
{
'S'
,
'i'
,
'g'
,
'n'
,
'a'
,
't'
,
'u'
,
'r'
,
'e'
,
'K'
,
'e'
,
'y'
,
'P'
,
'a'
,
'i'
,
'r'
,
0
};
BYTE
*
buf
,
*
ret
=
NULL
;
DATA_BLOB
blob_in
,
blob_out
;
DWORD
spec
=
0
,
type
,
len
;
WCHAR
*
path
;
HKEY
hkey
;
if
(
!
(
path
=
get_key_container_path
(
ctx
)))
return
NULL
;
if
(
RegOpenKeyExW
(
HKEY_CURRENT_USER
,
path
,
0
,
KEY_READ
,
&
hkey
))
{
heap_free
(
path
);
return
NULL
;
}
if
(
!
RegQueryValueExW
(
hkey
,
keyexchangeW
,
0
,
&
type
,
NULL
,
&
len
))
spec
=
AT_KEYEXCHANGE
;
else
if
(
!
RegQueryValueExW
(
hkey
,
signatureW
,
0
,
&
type
,
NULL
,
&
len
))
spec
=
AT_SIGNATURE
;
else
{
RegCloseKey
(
hkey
);
return
NULL
;
}
if
(
!
(
buf
=
heap_alloc
(
len
+
MAX_LEAD_BYTES
)))
{
RegCloseKey
(
hkey
);
return
NULL
;
}
if
(
!
RegQueryValueExW
(
hkey
,
(
spec
==
AT_KEYEXCHANGE
)
?
keyexchangeW
:
signatureW
,
0
,
&
type
,
buf
,
&
len
))
{
blob_in
.
pbData
=
buf
;
blob_in
.
cbData
=
len
;
if
(
CryptUnprotectData
(
&
blob_in
,
NULL
,
NULL
,
NULL
,
NULL
,
0
,
&
blob_out
))
{
assert
(
blob_in
.
cbData
>=
blob_out
.
cbData
);
memcpy
(
buf
,
blob_out
.
pbData
,
blob_out
.
cbData
);
LocalFree
(
blob_out
.
pbData
);
*
size
=
blob_out
.
cbData
+
MAX_LEAD_BYTES
;
ret
=
buf
;
}
}
else
heap_free
(
buf
);
RegCloseKey
(
hkey
);
heap_free
(
path
);
return
ret
;
}
static
inline
void
reverse_bytes
(
BYTE
*
buf
,
ULONG
len
)
{
int
ret
=
pgnutls_certificate_allocate_credentials
((
gnutls_certificate_credentials_t
*
)
&
c
->
credentials
);
BYTE
tmp
;
ULONG
i
;
for
(
i
=
0
;
i
<
len
/
2
;
i
++
)
{
tmp
=
buf
[
i
];
buf
[
i
]
=
buf
[
len
-
i
-
1
];
buf
[
len
-
i
-
1
]
=
tmp
;
}
}
static
ULONG
set_component
(
gnutls_datum_t
*
comp
,
BYTE
*
data
,
ULONG
len
,
ULONG
*
buflen
)
{
comp
->
data
=
data
;
comp
->
size
=
len
;
reverse_bytes
(
comp
->
data
,
comp
->
size
);
if
(
comp
->
data
[
0
]
&
0x80
)
/* add leading 0 byte if most significant bit is set */
{
memmove
(
comp
->
data
+
1
,
comp
->
data
,
*
buflen
);
comp
->
data
[
0
]
=
0
;
comp
->
size
++
;
}
*
buflen
-=
comp
->
size
;
return
comp
->
size
;
}
static
gnutls_x509_privkey_t
get_x509_key
(
const
CERT_CONTEXT
*
ctx
)
{
gnutls_privkey_t
key
=
NULL
;
gnutls_x509_privkey_t
x509key
=
NULL
;
gnutls_datum_t
m
,
e
,
d
,
p
,
q
,
u
,
e1
,
e2
;
BYTE
*
ptr
,
*
buffer
;
RSAPUBKEY
*
rsakey
;
DWORD
size
;
int
ret
;
if
(
!
(
buffer
=
get_key_blob
(
ctx
,
&
size
)))
return
NULL
;
if
(
size
<
sizeof
(
BLOBHEADER
))
goto
done
;
rsakey
=
(
RSAPUBKEY
*
)(
buffer
+
sizeof
(
BLOBHEADER
));
TRACE
(
"RSA key bitlen %u pubexp %u
\n
"
,
rsakey
->
bitlen
,
rsakey
->
pubexp
);
size
-=
sizeof
(
BLOBHEADER
)
+
FIELD_OFFSET
(
RSAPUBKEY
,
pubexp
);
set_component
(
&
e
,
(
BYTE
*
)
&
rsakey
->
pubexp
,
sizeof
(
rsakey
->
pubexp
),
&
size
);
ptr
=
(
BYTE
*
)(
rsakey
+
1
);
ptr
+=
set_component
(
&
m
,
ptr
,
rsakey
->
bitlen
/
8
,
&
size
);
ptr
+=
set_component
(
&
p
,
ptr
,
rsakey
->
bitlen
/
16
,
&
size
);
ptr
+=
set_component
(
&
q
,
ptr
,
rsakey
->
bitlen
/
16
,
&
size
);
ptr
+=
set_component
(
&
e1
,
ptr
,
rsakey
->
bitlen
/
16
,
&
size
);
ptr
+=
set_component
(
&
e2
,
ptr
,
rsakey
->
bitlen
/
16
,
&
size
);
ptr
+=
set_component
(
&
u
,
ptr
,
rsakey
->
bitlen
/
16
,
&
size
);
ptr
+=
set_component
(
&
d
,
ptr
,
rsakey
->
bitlen
/
8
,
&
size
);
if
((
ret
=
pgnutls_privkey_init
(
&
key
))
<
0
)
{
pgnutls_perror
(
ret
);
goto
done
;
}
if
((
ret
=
pgnutls_privkey_import_rsa_raw
(
key
,
&
m
,
&
e
,
&
d
,
&
p
,
&
q
,
&
u
,
&
e1
,
&
e2
))
<
0
)
{
pgnutls_perror
(
ret
);
goto
done
;
}
if
((
ret
=
pgnutls_privkey_export_x509
(
key
,
&
x509key
))
<
0
)
{
pgnutls_perror
(
ret
);
}
done:
heap_free
(
buffer
);
pgnutls_privkey_deinit
(
key
);
return
x509key
;
}
static
gnutls_x509_crt_t
get_x509_crt
(
const
CERT_CONTEXT
*
ctx
)
{
gnutls_datum_t
data
;
gnutls_x509_crt_t
crt
;
int
ret
;
if
(
!
ctx
)
return
FALSE
;
if
(
ctx
->
dwCertEncodingType
!=
X509_ASN_ENCODING
)
{
FIXME
(
"encoding type %u not supported
\n
"
,
ctx
->
dwCertEncodingType
);
return
NULL
;
}
if
((
ret
=
pgnutls_x509_crt_init
(
&
crt
))
<
0
)
{
pgnutls_perror
(
ret
);
return
NULL
;
}
data
.
data
=
ctx
->
pbCertEncoded
;
data
.
size
=
ctx
->
cbCertEncoded
;
if
((
ret
=
pgnutls_x509_crt_import
(
crt
,
&
data
,
GNUTLS_X509_FMT_DER
))
<
0
)
{
pgnutls_perror
(
ret
);
pgnutls_x509_crt_deinit
(
crt
);
return
NULL
;
}
return
crt
;
}
BOOL
schan_imp_allocate_certificate_credentials
(
schan_credentials
*
c
,
const
CERT_CONTEXT
*
ctx
)
{
gnutls_certificate_credentials_t
creds
;
gnutls_x509_crt_t
crt
;
gnutls_x509_privkey_t
key
;
int
ret
;
ret
=
pgnutls_certificate_allocate_credentials
(
&
creds
);
if
(
ret
!=
GNUTLS_E_SUCCESS
)
{
pgnutls_perror
(
ret
);
return
FALSE
;
}
if
(
!
ctx
)
{
c
->
credentials
=
creds
;
return
TRUE
;
}
if
(
!
(
crt
=
get_x509_crt
(
ctx
)))
{
pgnutls_certificate_free_credentials
(
creds
);
return
FALSE
;
}
if
(
!
(
key
=
get_x509_key
(
ctx
)))
{
pgnutls_x509_crt_deinit
(
crt
);
pgnutls_certificate_free_credentials
(
creds
);
return
FALSE
;
}
ret
=
pgnutls_certificate_set_x509_key
(
creds
,
&
crt
,
1
,
key
);
pgnutls_x509_privkey_deinit
(
key
);
pgnutls_x509_crt_deinit
(
crt
);
if
(
ret
!=
GNUTLS_E_SUCCESS
)
{
pgnutls_perror
(
ret
);
return
(
ret
==
GNUTLS_E_SUCCESS
);
pgnutls_certificate_free_credentials
(
creds
);
return
FALSE
;
}
c
->
credentials
=
creds
;
return
TRUE
;
}
void
schan_imp_free_certificate_credentials
(
schan_credentials
*
c
)
...
...
@@ -597,6 +879,7 @@ BOOL schan_imp_init(void)
LOAD_FUNCPTR
(
gnutls_certificate_allocate_credentials
)
LOAD_FUNCPTR
(
gnutls_certificate_free_credentials
)
LOAD_FUNCPTR
(
gnutls_certificate_get_peers
)
LOAD_FUNCPTR
(
gnutls_certificate_set_x509_key
)
LOAD_FUNCPTR
(
gnutls_cipher_get
)
LOAD_FUNCPTR
(
gnutls_cipher_get_key_size
)
LOAD_FUNCPTR
(
gnutls_credentials_set
)
...
...
@@ -613,6 +896,9 @@ BOOL schan_imp_init(void)
LOAD_FUNCPTR
(
gnutls_perror
)
LOAD_FUNCPTR
(
gnutls_protocol_get_version
)
LOAD_FUNCPTR
(
gnutls_priority_set_direct
)
LOAD_FUNCPTR
(
gnutls_privkey_deinit
)
LOAD_FUNCPTR
(
gnutls_privkey_import_rsa_raw
)
LOAD_FUNCPTR
(
gnutls_privkey_init
)
LOAD_FUNCPTR
(
gnutls_record_get_max_size
);
LOAD_FUNCPTR
(
gnutls_record_recv
);
LOAD_FUNCPTR
(
gnutls_record_send
);
...
...
@@ -622,6 +908,10 @@ BOOL schan_imp_init(void)
LOAD_FUNCPTR
(
gnutls_transport_set_ptr
)
LOAD_FUNCPTR
(
gnutls_transport_set_pull_function
)
LOAD_FUNCPTR
(
gnutls_transport_set_push_function
)
LOAD_FUNCPTR
(
gnutls_x509_crt_deinit
)
LOAD_FUNCPTR
(
gnutls_x509_crt_import
)
LOAD_FUNCPTR
(
gnutls_x509_crt_init
)
LOAD_FUNCPTR
(
gnutls_x509_privkey_deinit
)
#undef LOAD_FUNCPTR
if
(
!
(
pgnutls_cipher_get_block_size
=
wine_dlsym
(
libgnutls_handle
,
"gnutls_cipher_get_block_size"
,
NULL
,
0
)))
...
...
@@ -629,6 +919,11 @@ BOOL schan_imp_init(void)
WARN
(
"gnutls_cipher_get_block_size not found
\n
"
);
pgnutls_cipher_get_block_size
=
compat_cipher_get_block_size
;
}
if
(
!
(
pgnutls_privkey_export_x509
=
wine_dlsym
(
libgnutls_handle
,
"gnutls_privkey_export_x509"
,
NULL
,
0
)))
{
WARN
(
"gnutls_privkey_export_x509 not found
\n
"
);
pgnutls_privkey_export_x509
=
compat_gnutls_privkey_export_x509
;
}
ret
=
pgnutls_global_init
();
if
(
ret
!=
GNUTLS_E_SUCCESS
)
...
...
dlls/secur32/schannel_macosx.c
View file @
16d9f62b
...
...
@@ -1185,9 +1185,9 @@ SECURITY_STATUS schan_imp_recv(schan_imp_session session, void *buffer,
return
SEC_E_OK
;
}
BOOL
schan_imp_allocate_certificate_credentials
(
schan_credentials
*
c
)
BOOL
schan_imp_allocate_certificate_credentials
(
schan_credentials
*
c
,
const
CERT_CONTEXT
*
cert
)
{
/* The certificate is never really used for anything. */
if
(
cert
)
FIXME
(
"no support for certificate credentials on this platform
\n
"
);
c
->
credentials
=
NULL
;
return
TRUE
;
}
...
...
dlls/secur32/secur32_priv.h
View file @
16d9f62b
...
...
@@ -247,7 +247,7 @@ extern SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buf
SIZE_T
*
length
)
DECLSPEC_HIDDEN
;
extern
SECURITY_STATUS
schan_imp_recv
(
schan_imp_session
session
,
void
*
buffer
,
SIZE_T
*
length
)
DECLSPEC_HIDDEN
;
extern
BOOL
schan_imp_allocate_certificate_credentials
(
schan_credentials
*
)
DECLSPEC_HIDDEN
;
extern
BOOL
schan_imp_allocate_certificate_credentials
(
schan_credentials
*
,
const
CERT_CONTEXT
*
)
DECLSPEC_HIDDEN
;
extern
void
schan_imp_free_certificate_credentials
(
schan_credentials
*
)
DECLSPEC_HIDDEN
;
extern
DWORD
schan_imp_enabled_protocols
(
void
)
DECLSPEC_HIDDEN
;
extern
BOOL
schan_imp_init
(
void
)
DECLSPEC_HIDDEN
;
...
...
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