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
99e2f4ca
Commit
99e2f4ca
authored
Jun 20, 2022
by
Hans Leidekker
Committed by
Alexandre Julliard
Jun 21, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
secur32: Implement SECPKG_ATTR_CIPHER_INFO.
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=53180
parent
4ce39cd0
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
266 additions
and
0 deletions
+266
-0
schannel.c
dlls/secur32/schannel.c
+8
-0
schannel_gnutls.c
dlls/secur32/schannel_gnutls.c
+222
-0
secur32_priv.h
dlls/secur32/secur32_priv.h
+7
-0
schannel.c
dlls/secur32/tests/schannel.c
+29
-0
No files found.
dlls/secur32/schannel.c
View file @
99e2f4ca
...
...
@@ -1244,6 +1244,12 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
struct
get_application_protocol_params
params
=
{
ctx
->
session
,
protocol
};
return
GNUTLS_CALL
(
get_application_protocol
,
&
params
);
}
case
SECPKG_ATTR_CIPHER_INFO
:
{
SecPkgContext_CipherInfo
*
info
=
buffer
;
struct
get_cipher_info_params
params
=
{
ctx
->
session
,
info
};
return
GNUTLS_CALL
(
get_cipher_info
,
&
params
);
}
default:
FIXME
(
"Unhandled attribute %#lx
\n
"
,
attribute
);
...
...
@@ -1282,6 +1288,8 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesA(
return
schan_QueryContextAttributesW
(
context_handle
,
attribute
,
buffer
);
case
SECPKG_ATTR_APPLICATION_PROTOCOL
:
return
schan_QueryContextAttributesW
(
context_handle
,
attribute
,
buffer
);
case
SECPKG_ATTR_CIPHER_INFO
:
return
schan_QueryContextAttributesW
(
context_handle
,
attribute
,
buffer
);
default:
FIXME
(
"Unhandled attribute %#lx
\n
"
,
attribute
);
...
...
dlls/secur32/schannel_gnutls.c
View file @
99e2f4ca
...
...
@@ -698,6 +698,211 @@ static NTSTATUS schan_get_connection_info( void *args )
return
SEC_E_OK
;
}
static
DWORD
get_protocol_version
(
gnutls_session_t
session
)
{
gnutls_protocol_t
proto
=
pgnutls_protocol_get_version
(
session
);
switch
(
proto
)
{
case
GNUTLS_SSL3
:
return
0x300
;
case
GNUTLS_TLS1_0
:
return
0x301
;
case
GNUTLS_TLS1_1
:
return
0x302
;
case
GNUTLS_TLS1_2
:
return
0x303
;
case
GNUTLS_DTLS1_0
:
return
0x201
;
case
GNUTLS_DTLS1_2
:
return
0x202
;
default:
FIXME
(
"unknown protocol %u
\n
"
,
proto
);
return
0
;
}
}
static
const
WCHAR
*
get_cipher_str
(
gnutls_session_t
session
)
{
static
const
WCHAR
aesW
[]
=
{
'A'
,
'E'
,
'S'
,
0
};
static
const
WCHAR
unknownW
[]
=
{
'<'
,
'u'
,
'n'
,
'k'
,
'n'
,
'o'
,
'w'
,
'n'
,
'>'
,
0
};
gnutls_cipher_algorithm_t
cipher
=
pgnutls_cipher_get
(
session
);
switch
(
cipher
)
{
case
GNUTLS_CIPHER_AES_128_CBC
:
case
GNUTLS_CIPHER_AES_192_CBC
:
case
GNUTLS_CIPHER_AES_256_CBC
:
case
GNUTLS_CIPHER_AES_128_GCM
:
case
GNUTLS_CIPHER_AES_256_GCM
:
case
GNUTLS_CIPHER_AES_128_CCM
:
case
GNUTLS_CIPHER_AES_256_CCM
:
return
aesW
;
default:
FIXME
(
"unknown cipher %u
\n
"
,
cipher
);
return
unknownW
;
}
}
static
DWORD
get_cipher_len
(
gnutls_session_t
session
)
{
gnutls_cipher_algorithm_t
cipher
=
pgnutls_cipher_get
(
session
);
switch
(
cipher
)
{
case
GNUTLS_CIPHER_AES_128_CBC
:
case
GNUTLS_CIPHER_AES_128_GCM
:
case
GNUTLS_CIPHER_AES_128_CCM
:
return
128
;
case
GNUTLS_CIPHER_AES_192_CBC
:
return
192
;
case
GNUTLS_CIPHER_AES_256_CBC
:
case
GNUTLS_CIPHER_AES_256_GCM
:
case
GNUTLS_CIPHER_AES_256_CCM
:
return
256
;
default:
FIXME
(
"unknown cipher %u
\n
"
,
cipher
);
return
0
;
}
}
static
DWORD
get_cipher_block_len
(
gnutls_session_t
session
)
{
gnutls_cipher_algorithm_t
cipher
=
pgnutls_cipher_get
(
session
);
return
pgnutls_cipher_get_block_size
(
cipher
);
}
static
const
WCHAR
*
get_hash_str
(
gnutls_session_t
session
,
BOOL
full
)
{
static
const
WCHAR
shaW
[]
=
{
'S'
,
'H'
,
'A'
,
0
};
static
const
WCHAR
sha1W
[]
=
{
'S'
,
'H'
,
'A'
,
'1'
,
0
};
static
const
WCHAR
sha224W
[]
=
{
'S'
,
'H'
,
'A'
,
'2'
,
'2'
,
'4'
,
0
};
static
const
WCHAR
sha256W
[]
=
{
'S'
,
'H'
,
'A'
,
'2'
,
'5'
,
'6'
,
0
};
static
const
WCHAR
sha384W
[]
=
{
'S'
,
'H'
,
'A'
,
'3'
,
'8'
,
'4'
,
0
};
static
const
WCHAR
sha512W
[]
=
{
'S'
,
'H'
,
'A'
,
'5'
,
'1'
,
'2'
,
0
};
static
const
WCHAR
unknownW
[]
=
{
'<'
,
'u'
,
'n'
,
'k'
,
'n'
,
'o'
,
'w'
,
'n'
,
'>'
,
0
};
gnutls_mac_algorithm_t
mac
=
pgnutls_mac_get
(
session
);
switch
(
mac
)
{
case
GNUTLS_MAC_SHA1
:
return
full
?
sha1W
:
shaW
;
case
GNUTLS_MAC_SHA224
:
return
sha224W
;
case
GNUTLS_MAC_SHA256
:
return
sha256W
;
case
GNUTLS_MAC_SHA384
:
return
sha384W
;
case
GNUTLS_MAC_SHA512
:
return
sha512W
;
default:
FIXME
(
"unknown mac %u
\n
"
,
mac
);
return
unknownW
;
}
}
static
DWORD
get_hash_len
(
gnutls_session_t
session
)
{
gnutls_mac_algorithm_t
mac
=
pgnutls_mac_get
(
session
);
return
pgnutls_mac_get_key_size
(
mac
)
*
8
;
}
static
const
WCHAR
*
get_exchange_str
(
gnutls_session_t
session
,
BOOL
full
)
{
static
const
WCHAR
ecdhW
[]
=
{
'E'
,
'C'
,
'D'
,
'H'
,
0
};
static
const
WCHAR
ecdheW
[]
=
{
'E'
,
'C'
,
'D'
,
'H'
,
'E'
,
0
};
static
const
WCHAR
unknownW
[]
=
{
'<'
,
'u'
,
'n'
,
'k'
,
'n'
,
'o'
,
'w'
,
'n'
,
'>'
,
0
};
gnutls_kx_algorithm_t
kx
=
pgnutls_kx_get
(
session
);
switch
(
kx
)
{
case
GNUTLS_KX_ECDHE_RSA
:
case
GNUTLS_KX_ECDHE_ECDSA
:
return
full
?
ecdheW
:
ecdhW
;
default:
FIXME
(
"unknown kx %u
\n
"
,
kx
);
return
unknownW
;
}
}
static
const
WCHAR
*
get_certificate_str
(
gnutls_session_t
session
)
{
static
const
WCHAR
rsaW
[]
=
{
'R'
,
'S'
,
'A'
,
0
};
static
const
WCHAR
ecdsaW
[]
=
{
'E'
,
'C'
,
'D'
,
'S'
,
'A'
,
0
};
static
const
WCHAR
unknownW
[]
=
{
'<'
,
'u'
,
'n'
,
'k'
,
'n'
,
'o'
,
'w'
,
'n'
,
'>'
,
0
};
gnutls_kx_algorithm_t
kx
=
pgnutls_kx_get
(
session
);
switch
(
kx
)
{
case
GNUTLS_KX_RSA
:
case
GNUTLS_KX_RSA_EXPORT
:
case
GNUTLS_KX_DHE_RSA
:
case
GNUTLS_KX_ECDHE_RSA
:
return
rsaW
;
case
GNUTLS_KX_ECDHE_ECDSA
:
return
ecdsaW
;
default:
FIXME
(
"unknown kx %u
\n
"
,
kx
);
return
unknownW
;
}
}
static
const
WCHAR
*
get_chaining_mode_str
(
gnutls_session_t
session
)
{
static
const
WCHAR
cbcW
[]
=
{
'C'
,
'B'
,
'C'
,
0
};
static
const
WCHAR
ccmW
[]
=
{
'C'
,
'C'
,
'M'
,
0
};
static
const
WCHAR
gcmW
[]
=
{
'G'
,
'C'
,
'M'
,
0
};
static
const
WCHAR
unknownW
[]
=
{
'<'
,
'u'
,
'n'
,
'k'
,
'n'
,
'o'
,
'w'
,
'n'
,
'>'
,
0
};
gnutls_cipher_algorithm_t
cipher
=
pgnutls_cipher_get
(
session
);
switch
(
cipher
)
{
case
GNUTLS_CIPHER_AES_128_CBC
:
case
GNUTLS_CIPHER_AES_192_CBC
:
case
GNUTLS_CIPHER_AES_256_CBC
:
return
cbcW
;
case
GNUTLS_CIPHER_AES_128_GCM
:
case
GNUTLS_CIPHER_AES_256_GCM
:
return
gcmW
;
case
GNUTLS_CIPHER_AES_128_CCM
:
case
GNUTLS_CIPHER_AES_256_CCM
:
return
ccmW
;
default:
FIXME
(
"unknown cipher %u
\n
"
,
cipher
);
return
unknownW
;
}
}
static
NTSTATUS
schan_get_cipher_info
(
void
*
args
)
{
const
WCHAR
tlsW
[]
=
{
'T'
,
'L'
,
'S'
,
'_'
,
0
};
const
WCHAR
underscoreW
[]
=
{
'_'
,
0
};
const
WCHAR
widthW
[]
=
{
'_'
,
'W'
,
'I'
,
'T'
,
'H'
,
'_'
,
0
};
const
struct
get_cipher_info_params
*
params
=
args
;
gnutls_session_t
session
=
session_from_handle
(
params
->
session
);
SecPkgContext_CipherInfo
*
info
=
params
->
info
;
char
buf
[
11
];
WCHAR
*
ptr
;
int
len
;
info
->
dwProtocol
=
get_protocol_version
(
session
);
info
->
dwCipherSuite
=
0
;
/* FIXME */
info
->
dwBaseCipherSuite
=
0
;
/* FIXME */
wcscpy
(
info
->
szCipher
,
get_cipher_str
(
session
)
);
info
->
dwCipherLen
=
get_cipher_len
(
session
);
info
->
dwCipherBlockLen
=
get_cipher_block_len
(
session
);
wcscpy
(
info
->
szHash
,
get_hash_str
(
session
,
TRUE
)
);
info
->
dwHashLen
=
get_hash_len
(
session
);
wcscpy
(
info
->
szExchange
,
get_exchange_str
(
session
,
FALSE
)
);
info
->
dwMinExchangeLen
=
0
;
info
->
dwMaxExchangeLen
=
65536
;
wcscpy
(
info
->
szCertificate
,
get_certificate_str
(
session
)
);
info
->
dwKeyType
=
0
;
/* FIXME */
wcscpy
(
info
->
szCipherSuite
,
tlsW
);
wcscat
(
info
->
szCipherSuite
,
get_exchange_str
(
session
,
TRUE
)
);
wcscat
(
info
->
szCipherSuite
,
underscoreW
);
wcscat
(
info
->
szCipherSuite
,
info
->
szCertificate
);
wcscat
(
info
->
szCipherSuite
,
widthW
);
wcscat
(
info
->
szCipherSuite
,
info
->
szCipher
);
wcscat
(
info
->
szCipherSuite
,
underscoreW
);
len
=
sprintf
(
buf
,
"%u"
,
(
unsigned
int
)
info
->
dwCipherLen
)
+
1
;
ptr
=
info
->
szCipherSuite
+
wcslen
(
info
->
szCipherSuite
);
ntdll_umbstowcs
(
buf
,
len
,
ptr
,
len
);
wcscat
(
info
->
szCipherSuite
,
underscoreW
);
wcscat
(
info
->
szCipherSuite
,
get_chaining_mode_str
(
session
)
);
wcscat
(
info
->
szCipherSuite
,
underscoreW
);
wcscat
(
info
->
szCipherSuite
,
get_hash_str
(
session
,
FALSE
)
);
return
SEC_E_OK
;
}
static
NTSTATUS
schan_get_unique_channel_binding
(
void
*
args
)
{
const
struct
get_unique_channel_binding_params
*
params
=
args
;
...
...
@@ -1271,6 +1476,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
schan_dispose_session
,
schan_free_certificate_credentials
,
schan_get_application_protocol
,
schan_get_cipher_info
,
schan_get_connection_info
,
schan_get_enabled_protocols
,
schan_get_key_signature_algorithm
,
...
...
@@ -1386,6 +1592,21 @@ static NTSTATUS wow64_schan_get_connection_info( void *args )
return
schan_get_connection_info
(
&
params
);
}
static
NTSTATUS
wow64_schan_get_cipher_info
(
void
*
args
)
{
struct
{
schan_session
session
;
PTR32
info
;
}
const
*
params32
=
args
;
struct
get_cipher_info_params
params
=
{
params32
->
session
,
ULongToPtr
(
params32
->
info
),
};
return
schan_get_cipher_info
(
&
params
);
}
static
NTSTATUS
wow64_schan_get_session_peer_certificate
(
void
*
args
)
{
struct
...
...
@@ -1582,6 +1803,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
schan_dispose_session
,
wow64_schan_free_certificate_credentials
,
wow64_schan_get_application_protocol
,
wow64_schan_get_cipher_info
,
wow64_schan_get_connection_info
,
schan_get_enabled_protocols
,
schan_get_key_signature_algorithm
,
...
...
dlls/secur32/secur32_priv.h
View file @
99e2f4ca
...
...
@@ -126,6 +126,12 @@ struct get_connection_info_params
SecPkgContext_ConnectionInfo
*
info
;
};
struct
get_cipher_info_params
{
schan_session
session
;
SecPkgContext_CipherInfo
*
info
;
};
struct
get_session_peer_certificate_params
{
schan_session
session
;
...
...
@@ -206,6 +212,7 @@ enum schan_funcs
unix_dispose_session
,
unix_free_certificate_credentials
,
unix_get_application_protocol
,
unix_get_cipher_info
,
unix_get_connection_info
,
unix_get_enabled_protocols
,
unix_get_key_signature_algorithm
,
...
...
dlls/secur32/tests/schannel.c
View file @
99e2f4ca
...
...
@@ -1038,6 +1038,7 @@ static void test_communication(void)
CRYPT_DATA_BLOB
pfx
;
HCERTSTORE
store
;
SecPkgContext_NegotiationInfoA
info
;
SecPkgContext_CipherInfo
cipher
;
SecBufferDesc
buffers
[
2
];
SecBuffer
*
buf
;
unsigned
buf_size
=
8192
;
...
...
@@ -1291,6 +1292,34 @@ static void test_communication(void)
ok
(
conn_info
.
dwHashStrength
>=
128
,
"conn_info.dwHashStrength = %ld
\n
"
,
conn_info
.
dwHashStrength
);
}
memset
(
&
cipher
,
0
,
sizeof
(
cipher
));
cipher
.
dwVersion
=
SECPKGCONTEXT_CIPHERINFO_V1
;
status
=
pQueryContextAttributesA
(
&
context
,
SECPKG_ATTR_CIPHER_INFO
,
&
cipher
);
ok
(
status
==
SEC_E_OK
||
broken
(
status
==
SEC_E_UNSUPPORTED_FUNCTION
)
/* < vista */
,
"got %08lx
\n
"
,
status
);
if
(
status
==
SEC_E_OK
)
{
ok
(
cipher
.
dwProtocol
==
0x301
,
"got %lx
\n
"
,
cipher
.
dwProtocol
);
todo_wine
ok
(
cipher
.
dwCipherSuite
==
0xc014
,
"got %lx
\n
"
,
cipher
.
dwCipherSuite
);
todo_wine
ok
(
cipher
.
dwBaseCipherSuite
==
0xc014
,
"got %lx
\n
"
,
cipher
.
dwBaseCipherSuite
);
ok
(
!
wcscmp
(
cipher
.
szCipherSuite
,
L"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
)
||
!
wcscmp
(
cipher
.
szCipherSuite
,
L"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256"
),
/* < win10 */
"got %s
\n
"
,
wine_dbgstr_w
(
cipher
.
szCipherSuite
));
ok
(
!
wcscmp
(
cipher
.
szCipher
,
L"AES"
),
"got %s
\n
"
,
wine_dbgstr_w
(
cipher
.
szCipher
));
ok
(
cipher
.
dwCipherLen
==
256
,
"got %lu
\n
"
,
cipher
.
dwCipherLen
);
ok
(
cipher
.
dwCipherBlockLen
==
16
,
"got %lu
\n
"
,
cipher
.
dwCipherBlockLen
);
ok
(
!
wcscmp
(
cipher
.
szHash
,
L"SHA1"
),
"got %s
\n
"
,
wine_dbgstr_w
(
cipher
.
szHash
));
ok
(
cipher
.
dwHashLen
==
160
,
"got %lu
\n
"
,
cipher
.
dwHashLen
);
ok
(
!
wcscmp
(
cipher
.
szExchange
,
L"ECDH"
)
||
!
wcscmp
(
cipher
.
szExchange
,
L"ECDH_P256"
),
/* < win10 */
"got %s
\n
"
,
wine_dbgstr_w
(
cipher
.
szExchange
));
ok
(
cipher
.
dwMinExchangeLen
==
0
||
cipher
.
dwMinExchangeLen
==
256
,
/* < win10 */
"got %lu
\n
"
,
cipher
.
dwMinExchangeLen
);
ok
(
cipher
.
dwMaxExchangeLen
==
65536
||
cipher
.
dwMaxExchangeLen
==
256
,
/* < win10 */
"got %lu
\n
"
,
cipher
.
dwMaxExchangeLen
);
ok
(
!
wcscmp
(
cipher
.
szCertificate
,
L"RSA"
),
"got %s
\n
"
,
wine_dbgstr_w
(
cipher
.
szCertificate
));
todo_wine
ok
(
cipher
.
dwKeyType
==
0x1d
||
cipher
.
dwKeyType
==
0x17
,
/* < win10 */
"got %#lx
\n
"
,
cipher
.
dwKeyType
);
}
status
=
pQueryContextAttributesA
(
&
context
,
SECPKG_ATTR_KEY_INFO
,
&
key_info
);
ok
(
status
==
SEC_E_OK
,
"QueryContextAttributesW(SECPKG_ATTR_KEY_INFO) failed: %08lx
\n
"
,
status
);
if
(
status
==
SEC_E_OK
)
{
...
...
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