Not all remotes showing in Push/Pull/Fetch/Sync dialogs
[TortoiseGit.git] / src / TortoiseProc / CheckCertificateDlg.cpp
blob25ef6b3b4a5592983600dc91ba2a75a4cefeaf42
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 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.
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 /*=NULL*/)
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 = _T("unknown");
56 std::unique_ptr<BYTE[]> pHash(nullptr);
57 HCRYPTHASH hHash = NULL;
59 if (!hCryptProv)
60 goto finish;
62 if (!CryptCreateHash(hCryptProv, algId, 0, 0, &hHash))
63 goto finish;
65 if (!CryptHashData(hHash, certificate, (DWORD)len, 0))
66 goto finish;
68 DWORD hashLen;
69 DWORD hashLenLen = sizeof(DWORD);
70 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &hashLenLen, 0))
71 goto finish;
73 pHash.reset(new BYTE[hashLen]);
74 if (!CryptGetHashParam(hHash, HP_HASHVAL, pHash.get(), &hashLen, 0))
75 goto finish;
77 readable.Empty();
78 for (const BYTE* it = pHash.get(); it < pHash.get() + hashLen; ++it)
80 CString tmp;
81 tmp.Format(L"%02X", *it);
82 if (!readable.IsEmpty())
83 readable += L":";
84 readable += tmp;
87 finish:
88 if (hHash)
89 CryptDestroyHash(hHash);
91 return readable;
94 BOOL CCheckCertificateDlg::OnInitDialog()
96 CStandAloneDialog::OnInitDialog();
97 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
99 HCRYPTPROV hCryptProv = 0;
100 CryptAcquireContext(&hCryptProv, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
102 m_sSHA1 = getCertificateHash(hCryptProv, CALG_SHA1, (BYTE*)cert->data, cert->len);
103 m_sSHA256 = getCertificateHash(hCryptProv, CALG_SHA_256, (BYTE*)cert->data, cert->len);
104 if (m_sSHA256.GetLength() > 57)
105 m_sSHA256 = m_sSHA256.Left(57) + L"\r\n" + m_sSHA256.Mid(57);
107 CryptReleaseContext(hCryptProv, 0);
109 CString error;
110 error.Format(IDS_ERR_SSL_VALIDATE, m_sHostname);
111 SetDlgItemText(IDC_ERRORDESC, error);
113 UpdateData(FALSE);
115 GetDlgItem(IDCANCEL)->SetFocus();
117 return FALSE;
120 void CCheckCertificateDlg::OnBnClickedOpencert()
122 CTGitPath tempFile = CTempFiles::Instance().GetTempFilePath(true, CTGitPath(_T("certificate.der")));
126 CFile file(tempFile.GetWinPathString(), CFile::modeReadWrite);
127 file.Write(cert->data, (UINT)cert->len);
128 file.Close();
130 catch (CFileException* e)
132 MessageBox(_T("Could not write to file."), _T("TortoiseGit"), MB_ICONERROR);
133 e->Delete();
134 return;
137 CAppUtils::ShellOpen(tempFile.GetWinPathString(), GetSafeHwnd());