Fixed issue #3307: Abort Merge on a single file always results in a parameter error...
[TortoiseGit.git] / src / TortoiseProc / CheckCertificateDlg.cpp
blob3b60960f2b88d41501bd27448946868dc54d6f7c
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2014-2016 - 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.
20 #include "stdafx.h"
21 #include "CheckCertificateDlg.h"
22 #include "AppUtils.h"
23 #include "TempFile.h"
24 #include <WinCrypt.h>
26 IMPLEMENT_DYNAMIC(CCheckCertificateDlg, CStandAloneDialog)
27 CCheckCertificateDlg::CCheckCertificateDlg(CWnd* pParent /*=nullptr*/)
28 : CStandAloneDialog(CCheckCertificateDlg::IDD, pParent)
29 , cert(nullptr)
33 void CCheckCertificateDlg::DoDataExchange(CDataExchange* pDX)
35 CStandAloneDialog::DoDataExchange(pDX);
36 DDX_Text(pDX, IDC_ERROR, m_sError);
37 DDX_Text(pDX, IDC_COMMONNAME, m_sCertificateCN);
38 DDX_Text(pDX, IDC_ISSUER, m_sCertificateIssuer);
39 DDX_Text(pDX, IDC_SHA1, m_sSHA1);
40 DDX_Text(pDX, IDC_SHA256, m_sSHA256);
43 BEGIN_MESSAGE_MAP(CCheckCertificateDlg, CStandAloneDialog)
44 ON_BN_CLICKED(IDOK, OnBnClickedOk)
45 ON_BN_CLICKED(IDC_OPENCERT, &CCheckCertificateDlg::OnBnClickedOpencert)
46 END_MESSAGE_MAP()
48 void CCheckCertificateDlg::OnBnClickedOk()
50 OnOK();
53 static CString getCertificateHash(HCRYPTPROV hCryptProv, ALG_ID algId, BYTE* certificate, size_t len)
55 CString readable = L"unknown";
57 if (!hCryptProv)
58 return readable;
60 HCRYPTHASH hHash = NULL;
61 if (!CryptCreateHash(hCryptProv, algId, 0, 0, &hHash))
62 return readable;
63 SCOPE_EXIT { CryptDestroyHash(hHash); };
65 if (!CryptHashData(hHash, certificate, (DWORD)len, 0))
66 return readable;
68 DWORD hashLen;
69 DWORD hashLenLen = sizeof(DWORD);
70 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &hashLenLen, 0))
71 return readable;
73 auto pHash = std::make_unique<BYTE[]>(hashLen);
74 if (!CryptGetHashParam(hHash, HP_HASHVAL, pHash.get(), &hashLen, 0))
75 return readable;
77 readable.Empty();
78 for (const BYTE* it = pHash.get(); it < pHash.get() + hashLen; ++it)
79 readable.AppendFormat(L"%02X:", *it);
81 return readable.TrimRight(L":");
84 BOOL CCheckCertificateDlg::OnInitDialog()
86 CStandAloneDialog::OnInitDialog();
87 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
89 HCRYPTPROV hCryptProv = NULL;
90 CryptAcquireContext(&hCryptProv, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
91 SCOPE_EXIT
93 if (hCryptProv)
94 CryptReleaseContext(hCryptProv, 0);
97 m_sSHA1 = getCertificateHash(hCryptProv, CALG_SHA1, (BYTE*)cert->data, cert->len);
98 m_sSHA256 = getCertificateHash(hCryptProv, CALG_SHA_256, (BYTE*)cert->data, cert->len);
99 if (m_sSHA256.GetLength() > 57)
100 m_sSHA256 = m_sSHA256.Left(57) + L"\r\n" + m_sSHA256.Mid(57);
102 CString error;
103 error.Format(IDS_ERR_SSL_VALIDATE, (LPCTSTR)m_sHostname);
104 SetDlgItemText(IDC_ERRORDESC, error);
106 UpdateData(FALSE);
108 GetDlgItem(IDCANCEL)->SetFocus();
110 return FALSE;
113 void CCheckCertificateDlg::OnBnClickedOpencert()
115 CTGitPath tempFile = CTempFiles::Instance().GetTempFilePath(true, CTGitPath(L"certificate.der"));
119 CFile file(tempFile.GetWinPathString(), CFile::modeReadWrite);
120 file.Write(cert->data, (UINT)cert->len);
121 file.Close();
123 catch (CFileException* e)
125 MessageBox(L"Could not write to file.", L"TortoiseGit", MB_ICONERROR);
126 e->Delete();
127 return;
130 CAppUtils::ShellOpen(tempFile.GetWinPathString(), GetSafeHwnd());