1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013-2014 - 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 HTTPSPolicyCallbackData polHttps
;
25 CERT_CHAIN_POLICY_PARA PolicyPara
;
26 CERT_CHAIN_POLICY_STATUS PolicyStatus
;
27 CERT_CHAIN_PARA ChainPara
;
28 PCCERT_CHAIN_CONTEXT pChainContext
= nullptr;
30 LPSTR rgszUsages
[] = { szOID_PKIX_KP_SERVER_AUTH
, szOID_SERVER_GATED_CRYPTO
, szOID_SGC_NETSCAPE
};
32 DWORD cUsages
= sizeof(rgszUsages
) / sizeof(LPSTR
);
34 if (pServerCert
== nullptr || pwszServerName
== nullptr)
36 Status
= (DWORD
)SEC_E_WRONG_PRINCIPAL
;
40 // Build certificate chain.
41 SecureZeroMemory(&ChainPara
, sizeof(ChainPara
));
42 ChainPara
.cbSize
= sizeof(ChainPara
);
43 ChainPara
.RequestedUsage
.dwType
= USAGE_MATCH_TYPE_OR
;
44 ChainPara
.RequestedUsage
.Usage
.cUsageIdentifier
= cUsages
;
45 ChainPara
.RequestedUsage
.Usage
.rgpszUsageIdentifier
= rgszUsages
;
47 if (!CertGetCertificateChain(nullptr, pServerCert
, nullptr, pServerCert
->hCertStore
, &ChainPara
, 0, nullptr, &pChainContext
))
49 Status
= GetLastError();
53 // Validate certificate chain.
54 SecureZeroMemory(&polHttps
, sizeof(HTTPSPolicyCallbackData
));
55 polHttps
.cbStruct
= sizeof(HTTPSPolicyCallbackData
);
56 polHttps
.dwAuthType
= AUTHTYPE_SERVER
;
57 polHttps
.fdwChecks
= dwCertFlags
;
58 polHttps
.pwszServerName
= pwszServerName
;
60 SecureZeroMemory(&PolicyPara
, sizeof(PolicyPara
));
61 PolicyPara
.cbSize
= sizeof(PolicyPara
);
62 PolicyPara
.pvExtraPolicyPara
= &polHttps
;
64 SecureZeroMemory(&PolicyStatus
, sizeof(PolicyStatus
));
65 PolicyStatus
.cbSize
= sizeof(PolicyStatus
);
67 if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL
, pChainContext
, &PolicyPara
, &PolicyStatus
))
69 Status
= GetLastError();
73 if (PolicyStatus
.dwError
)
75 Status
= PolicyStatus
.dwError
;
83 CertFreeCertificateChain(pChainContext
);