1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013-2015 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 static DWORD
VerifyServerCertificate(PCCERT_CONTEXT pServerCert
, PTSTR pwszServerName
, DWORD dwCertFlags
)
24 if (pServerCert
== nullptr || pwszServerName
== nullptr)
25 return (DWORD
)SEC_E_WRONG_PRINCIPAL
;
27 LPSTR rgszUsages
[] = { szOID_PKIX_KP_SERVER_AUTH
, szOID_SERVER_GATED_CRYPTO
, szOID_SGC_NETSCAPE
};
28 DWORD cUsages
= sizeof(rgszUsages
) / sizeof(LPSTR
);
30 // Build certificate chain.
31 CERT_CHAIN_PARA ChainPara
= { 0 };
32 ChainPara
.cbSize
= sizeof(ChainPara
);
33 ChainPara
.RequestedUsage
.dwType
= USAGE_MATCH_TYPE_OR
;
34 ChainPara
.RequestedUsage
.Usage
.cUsageIdentifier
= cUsages
;
35 ChainPara
.RequestedUsage
.Usage
.rgpszUsageIdentifier
= rgszUsages
;
37 PCCERT_CHAIN_CONTEXT pChainContext
= nullptr;
38 if (!CertGetCertificateChain(nullptr, pServerCert
, nullptr, pServerCert
->hCertStore
, &ChainPara
, 0, nullptr, &pChainContext
))
39 return GetLastError();
40 SCOPE_EXIT
{ CertFreeCertificateChain(pChainContext
); };
42 // Validate certificate chain.
43 HTTPSPolicyCallbackData polHttps
= { 0 };
44 polHttps
.cbStruct
= sizeof(HTTPSPolicyCallbackData
);
45 polHttps
.dwAuthType
= AUTHTYPE_SERVER
;
46 polHttps
.fdwChecks
= dwCertFlags
;
47 polHttps
.pwszServerName
= pwszServerName
;
49 CERT_CHAIN_POLICY_PARA PolicyPara
= { 0 };
50 PolicyPara
.cbSize
= sizeof(PolicyPara
);
51 PolicyPara
.pvExtraPolicyPara
= &polHttps
;
53 CERT_CHAIN_POLICY_STATUS PolicyStatus
= { 0 };
54 PolicyStatus
.cbSize
= sizeof(PolicyStatus
);
56 if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL
, pChainContext
, &PolicyPara
, &PolicyStatus
))
57 return GetLastError();
59 if (PolicyStatus
.dwError
)
60 return PolicyStatus
.dwError
;