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
e893a2c8
Commit
e893a2c8
authored
Sep 22, 2008
by
Juan Lang
Committed by
Alexandre Julliard
Sep 23, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cryptdlg: Implement CertTrustFinalPolicy.
parent
c84df406
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
257 additions
and
4 deletions
+257
-4
Makefile.in
dlls/cryptdlg/Makefile.in
+1
-1
main.c
dlls/cryptdlg/main.c
+256
-3
No files found.
dlls/cryptdlg/Makefile.in
View file @
e893a2c8
...
...
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
cryptdlg.dll
IMPORTS
=
cryptui crypt32 wintrust kernel32
IMPORTS
=
cryptui crypt32 wintrust
advapi32
kernel32
C_SRCS
=
\
main.c
...
...
dlls/cryptdlg/main.c
View file @
e893a2c8
...
...
@@ -23,6 +23,7 @@
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
#include "wincrypt.h"
#include "wintrust.h"
#include "winuser.h"
...
...
@@ -105,13 +106,265 @@ HRESULT WINAPI CertTrustCleanup(CRYPT_PROVIDER_DATA *pProvData)
return
E_NOTIMPL
;
}
static
BOOL
CRYPTDLG_CheckOnlineCRL
(
void
)
{
static
const
WCHAR
policyFlagsKey
[]
=
{
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'M'
,
'i'
,
'c'
,
'r'
,
'o'
,
's'
,
'o'
,
'f'
,
't'
,
'\\'
,
'C'
,
'r'
,
'y'
,
'p'
,
't'
,
'o'
,
'g'
,
'r'
,
'a'
,
'p'
,
'h'
,
'y'
,
'\\'
,
'{'
,
'7'
,
'8'
,
'0'
,
'1'
,
'e'
,
'b'
,
'd'
,
'0'
,
'-'
,
'c'
,
'f'
,
'4'
,
'b'
,
'-'
,
'1'
,
'1'
,
'd'
,
'0'
,
'-'
,
'8'
,
'5'
,
'1'
,
'f'
,
'-'
,
'0'
,
'0'
,
'6'
,
'0'
,
'9'
,
'7'
,
'9'
,
'3'
,
'8'
,
'7'
,
'e'
,
'a'
,
'}'
,
0
};
static
const
WCHAR
policyFlags
[]
=
{
'P'
,
'o'
,
'l'
,
'i'
,
'c'
,
'y'
,
'F'
,
'l'
,
'a'
,
'g'
,
's'
,
0
};
HKEY
key
;
BOOL
ret
=
FALSE
;
if
(
!
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
policyFlagsKey
,
0
,
KEY_READ
,
&
key
))
{
DWORD
type
,
flags
,
size
=
sizeof
(
flags
);
if
(
!
RegQueryValueExW
(
key
,
policyFlags
,
NULL
,
&
type
,
(
BYTE
*
)
&
flags
,
&
size
)
&&
type
==
REG_DWORD
)
{
/* The flag values aren't defined in any header I'm aware of, but
* this value is well documented on the net.
*/
if
(
flags
&
0x00010000
)
ret
=
TRUE
;
}
RegCloseKey
(
key
);
}
return
ret
;
}
/* Returns TRUE if pCert is not in the Disallowed system store, or FALSE if it
* is.
*/
static
BOOL
CRYPTDLG_IsCertAllowed
(
PCCERT_CONTEXT
pCert
)
{
BOOL
ret
;
BYTE
hash
[
20
];
DWORD
size
=
sizeof
(
hash
);
if
((
ret
=
CertGetCertificateContextProperty
(
pCert
,
CERT_SIGNATURE_HASH_PROP_ID
,
hash
,
&
size
)))
{
static
const
WCHAR
disallowedW
[]
=
{
'D'
,
'i'
,
's'
,
'a'
,
'l'
,
'l'
,
'o'
,
'w'
,
'e'
,
'd'
,
0
};
HCERTSTORE
disallowed
=
CertOpenStore
(
CERT_STORE_PROV_SYSTEM_W
,
X509_ASN_ENCODING
,
0
,
CERT_SYSTEM_STORE_CURRENT_USER
,
disallowedW
);
if
(
disallowed
)
{
PCCERT_CONTEXT
found
=
CertFindCertificateInStore
(
disallowed
,
X509_ASN_ENCODING
,
0
,
CERT_FIND_SIGNATURE_HASH
,
hash
,
NULL
);
if
(
found
)
{
ret
=
FALSE
;
CertFreeCertificateContext
(
found
);
}
CertCloseStore
(
disallowed
,
0
);
}
}
return
ret
;
}
static
DWORD
CRYPTDLG_TrustStatusToConfidence
(
DWORD
errorStatus
)
{
DWORD
confidence
=
0
;
confidence
=
0
;
if
(
!
(
errorStatus
&
CERT_TRUST_IS_NOT_SIGNATURE_VALID
))
confidence
|=
CERT_CONFIDENCE_SIG
;
if
(
!
(
errorStatus
&
CERT_TRUST_IS_NOT_TIME_VALID
))
confidence
|=
CERT_CONFIDENCE_TIME
;
if
(
!
(
errorStatus
&
CERT_TRUST_IS_NOT_TIME_NESTED
))
confidence
|=
CERT_CONFIDENCE_TIMENEST
;
return
confidence
;
}
static
BOOL
CRYPTDLG_CopyChain
(
CRYPT_PROVIDER_DATA
*
data
,
PCCERT_CHAIN_CONTEXT
chain
)
{
BOOL
ret
;
CRYPT_PROVIDER_SGNR
signer
;
PCERT_SIMPLE_CHAIN
simpleChain
=
chain
->
rgpChain
[
0
];
DWORD
i
;
memset
(
&
signer
,
0
,
sizeof
(
signer
));
signer
.
cbStruct
=
sizeof
(
signer
);
ret
=
data
->
psPfns
->
pfnAddSgnr2Chain
(
data
,
FALSE
,
0
,
&
signer
);
if
(
ret
)
{
CRYPT_PROVIDER_SGNR
*
sgnr
=
WTHelperGetProvSignerFromChain
(
data
,
0
,
FALSE
,
0
);
if
(
sgnr
)
{
sgnr
->
dwError
=
simpleChain
->
TrustStatus
.
dwErrorStatus
;
sgnr
->
pChainContext
=
CertDuplicateCertificateChain
(
chain
);
}
else
ret
=
FALSE
;
for
(
i
=
0
;
ret
&&
i
<
simpleChain
->
cElement
;
i
++
)
{
ret
=
data
->
psPfns
->
pfnAddCert2Chain
(
data
,
0
,
FALSE
,
0
,
simpleChain
->
rgpElement
[
i
]
->
pCertContext
);
if
(
ret
)
{
CRYPT_PROVIDER_CERT
*
cert
;
if
((
cert
=
WTHelperGetProvCertFromChain
(
sgnr
,
i
)))
{
CERT_CHAIN_ELEMENT
*
element
=
simpleChain
->
rgpElement
[
i
];
cert
->
dwConfidence
=
CRYPTDLG_TrustStatusToConfidence
(
element
->
TrustStatus
.
dwErrorStatus
);
cert
->
dwError
=
element
->
TrustStatus
.
dwErrorStatus
;
cert
->
pChainElement
=
element
;
}
else
ret
=
FALSE
;
}
}
}
return
ret
;
}
static
CERT_VERIFY_CERTIFICATE_TRUST
*
CRYPTDLG_GetVerifyData
(
CRYPT_PROVIDER_DATA
*
data
)
{
CERT_VERIFY_CERTIFICATE_TRUST
*
pCert
=
NULL
;
/* This should always be true, but just in case the calling function is
* called directly:
*/
if
(
data
->
pWintrustData
->
dwUnionChoice
==
WTD_CHOICE_BLOB
&&
data
->
pWintrustData
->
pBlob
&&
data
->
pWintrustData
->
pBlob
->
cbMemObject
==
sizeof
(
CERT_VERIFY_CERTIFICATE_TRUST
)
&&
data
->
pWintrustData
->
pBlob
->
pbMemObject
)
pCert
=
(
CERT_VERIFY_CERTIFICATE_TRUST
*
)
data
->
pWintrustData
->
pBlob
->
pbMemObject
;
return
pCert
;
}
static
HCERTCHAINENGINE
CRYPTDLG_MakeEngine
(
CERT_VERIFY_CERTIFICATE_TRUST
*
cert
)
{
HCERTCHAINENGINE
engine
=
NULL
;
HCERTSTORE
root
=
NULL
,
trust
=
NULL
;
DWORD
i
;
if
(
cert
->
cRootStores
)
{
root
=
CertOpenStore
(
CERT_STORE_PROV_COLLECTION
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
if
(
root
)
{
for
(
i
=
0
;
i
<
cert
->
cRootStores
;
i
++
)
CertAddStoreToCollection
(
root
,
cert
->
rghstoreRoots
[
i
],
0
,
0
);
}
}
if
(
cert
->
cTrustStores
)
{
trust
=
CertOpenStore
(
CERT_STORE_PROV_COLLECTION
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
if
(
root
)
{
for
(
i
=
0
;
i
<
cert
->
cTrustStores
;
i
++
)
CertAddStoreToCollection
(
trust
,
cert
->
rghstoreTrust
[
i
],
0
,
0
);
}
}
if
(
cert
->
cRootStores
||
cert
->
cStores
||
cert
->
cTrustStores
)
{
CERT_CHAIN_ENGINE_CONFIG
config
;
memset
(
&
config
,
0
,
sizeof
(
config
));
config
.
cbSize
=
sizeof
(
config
);
config
.
hRestrictedRoot
=
root
;
config
.
hRestrictedTrust
=
trust
;
config
.
cAdditionalStore
=
cert
->
cStores
;
config
.
rghAdditionalStore
=
cert
->
rghstoreCAs
;
config
.
hRestrictedRoot
=
root
;
CertCreateCertificateChainEngine
(
&
config
,
&
engine
);
CertCloseStore
(
root
,
0
);
CertCloseStore
(
trust
,
0
);
}
return
engine
;
}
/***********************************************************************
* CertTrustFinalPolicy (CRYPTDLG.@)
*/
HRESULT
WINAPI
CertTrustFinalPolicy
(
CRYPT_PROVIDER_DATA
*
pProvD
ata
)
HRESULT
WINAPI
CertTrustFinalPolicy
(
CRYPT_PROVIDER_DATA
*
d
ata
)
{
FIXME
(
"(%p)
\n
"
,
pProvData
);
return
E_NOTIMPL
;
BOOL
ret
;
DWORD
err
=
S_OK
;
CERT_VERIFY_CERTIFICATE_TRUST
*
pCert
=
CRYPTDLG_GetVerifyData
(
data
);
TRACE
(
"(%p)
\n
"
,
data
);
if
(
data
->
pWintrustData
->
dwUIChoice
!=
WTD_UI_NONE
)
FIXME
(
"unimplemented for UI choice %d
\n
"
,
data
->
pWintrustData
->
dwUIChoice
);
if
(
pCert
)
{
DWORD
flags
=
0
;
CERT_CHAIN_PARA
chainPara
;
HCERTCHAINENGINE
engine
;
memset
(
&
chainPara
,
0
,
sizeof
(
chainPara
));
chainPara
.
cbSize
=
sizeof
(
chainPara
);
if
(
CRYPTDLG_CheckOnlineCRL
())
flags
|=
CERT_CHAIN_REVOCATION_CHECK_END_CERT
;
engine
=
CRYPTDLG_MakeEngine
(
pCert
);
GetSystemTimeAsFileTime
(
&
data
->
sftSystemTime
);
ret
=
CRYPTDLG_IsCertAllowed
(
pCert
->
pccert
);
if
(
ret
)
{
PCCERT_CHAIN_CONTEXT
chain
;
ret
=
CertGetCertificateChain
(
engine
,
pCert
->
pccert
,
&
data
->
sftSystemTime
,
NULL
,
&
chainPara
,
flags
,
NULL
,
&
chain
);
if
(
ret
)
{
if
(
chain
->
cChain
!=
1
)
{
FIXME
(
"unimplemented for more than 1 simple chain
\n
"
);
err
=
TRUST_E_SUBJECT_FORM_UNKNOWN
;
ret
=
FALSE
;
}
else
if
((
ret
=
CRYPTDLG_CopyChain
(
data
,
chain
)))
{
if
(
CertVerifyTimeValidity
(
&
data
->
sftSystemTime
,
pCert
->
pccert
->
pCertInfo
))
{
ret
=
FALSE
;
err
=
CERT_E_EXPIRED
;
}
}
else
err
=
TRUST_E_SYSTEM_ERROR
;
CertFreeCertificateChain
(
chain
);
}
else
err
=
TRUST_E_SUBJECT_NOT_TRUSTED
;
}
CertFreeCertificateChainEngine
(
engine
);
}
else
{
ret
=
FALSE
;
err
=
TRUST_E_NOSIGNATURE
;
}
/* Oddly, native doesn't set the error in the trust step error location,
* probably because this action is more advisory than anything else.
* Instead it stores it as the final error, but the function "succeeds" in
* any case.
*/
if
(
!
ret
)
data
->
dwFinalError
=
err
;
TRACE
(
"returning %d (%08x)
\n
"
,
S_OK
,
data
->
dwFinalError
);
return
S_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