// KeyGenDialog.cpp : 実装ファイル
//

#include "stdafx.h"
#include "ServerController.h"
#include "KeyGenDialog.h"
#include "opensslutil.h"
#include "PathTools.h"
#include "Dir.h"


// CKeyGenDialog ダイアログ

IMPLEMENT_DYNAMIC(CKeyGenDialog, CDialog)
CKeyGenDialog::CKeyGenDialog(CWnd* pParent /*=NULL*/)
	: CDialog(CKeyGenDialog::IDD, pParent)
	, m_keyPath(_T(""))
	, m_pass1(_T(""))
	, m_pass2(_T(""))
	, m_caPath(_T(""))
	, m_c(_T(""))
	, m_st(_T(""))
	, m_l(_T(""))
	, m_o(_T(""))
	, m_ou(_T(""))
	, m_cn(_T(""))
	, m_mail(_T(""))
	, m_before(0)
	, m_after(365*10)
	, m_enableCSR(TRUE)
	, m_csrPath(_T(""))
	, m_bit(1)
{
}

CKeyGenDialog::~CKeyGenDialog()
{
}

void CKeyGenDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_KEY_PATH, m_keyPath);
	DDX_Text(pDX, IDC_PASS1, m_pass1);
	DDX_Text(pDX, IDC_PASS2, m_pass2);
	DDX_Text(pDX, IDC_C, m_c);
	DDX_Text(pDX, IDC_ST, m_st);
	DDX_Text(pDX, IDC_L, m_l);
	DDX_Text(pDX, IDC_O, m_o);
	DDX_Text(pDX, IDC_OU, m_ou);
	DDX_Text(pDX, IDC_CN, m_cn);
	DDX_Text(pDX, IDC_MAIL, m_mail);
	DDX_Text(pDX, IDC_BEFORE, m_before);
	DDX_Text(pDX, IDC_AFTER, m_after);
	DDX_Check(pDX, IDC_ENABLE_CSR, m_enableCSR);
	DDX_CBIndex(pDX, IDC_BIT, m_bit);
	DDX_Control(pDX, IDC_CA_PATH, m_caPathEdit);
	DDX_Control(pDX, IDC_CSR_PATH, m_csrPathEdit);
}


BEGIN_MESSAGE_MAP(CKeyGenDialog, CDialog)
	ON_BN_CLICKED(IDOK, OnBnClickedOk)
	ON_BN_CLICKED(IDC_KEY_BR, OnBnClickedKeyBr)
	ON_EN_CHANGE(IDC_KEY_PATH, &CKeyGenDialog::OnEnChangeKeyPath)
END_MESSAGE_MAP()


// CKeyGenDialog メッセージ ハンドラ

void CKeyGenDialog::OnBnClickedOk()
{
	UpdateData(TRUE);
	UpdateOtherPath();

	//	パスワード
	if(m_pass1.IsEmpty() || m_pass1 != m_pass2)
	{
		MessageBox("パスワードが一致しないか、空欄です。","04WebServer",MB_ICONEXCLAMATION | MB_OK);
		return;
	}

	//	国名
	if(m_c.GetLength() != 2)
	{
		MessageBox("国名は2文字です。","04WebServer",MB_ICONEXCLAMATION | MB_OK);
		return;
	}

	//	webサイト
	if(m_cn.GetLength() == 0)
	{
		MessageBox("Webサイトのアドレスを入力してください。","04WebServer",MB_ICONEXCLAMATION | MB_OK);
		return;
	}

	//	上書きチェック
	if(	CDir::FileExist(m_keyPath) != CDir::FILE_TYPE_NOTFOUND ||
		CDir::FileExist(m_caPath) != CDir::FILE_TYPE_NOTFOUND ||
		CDir::FileExist(m_csrPath) != CDir::FILE_TYPE_NOTFOUND)
	{
		if(MessageBox("ファイルが既に存在します。\r\n上書きしますか？","04WebServer",MB_ICONQUESTION | MB_YESNO) == IDNO)
			return;
	}

	//	ビットモード
	int	bit = 2048;
	switch(m_bit)
	{
	case 0:
		bit = 1024;
		break;

	case 1:
		bit = 2048;
		break;

	case 2:
		bit = 4096;
		break;

	case 3:
		bit = 8192;
		break;
	}

	//	キー生成
	COpenSSLUtil	util;
	util.SetPassword(m_pass1);
	BeginWaitCursor();
	if(util.GeneratePrivateKey(bit))
	{
		EndWaitCursor();
		MessageBox("RSA秘密鍵の生成に失敗しました。","04WebServer",MB_ICONEXCLAMATION | MB_OK);
		return;
	}
	EndWaitCursor();

	//	キーの保存
	if(util.SavePrivateKey(m_keyPath))
	{
		MessageBox("RSA秘密鍵の生成に失敗しました。","04WebServer",MB_ICONEXCLAMATION | MB_OK);
		return;
	}

	//	情報設定
	COpenSSLUtil::CX509Entry	entry;

	entry.m_serialNumber = 0;
	entry.m_notBeforeDays = m_before * 24 * 60 * 60;
	entry.m_notAfterDays = m_after * 24 * 60 * 60;

	entry.m_countryName = m_c;
	entry.m_statName = m_st;
	entry.m_localityName = m_l;
	entry.m_organizationName = m_o;
	entry.m_organizationalUnitName = m_ou;
	entry.m_commonName = m_cn;
	entry.m_email = m_mail;

	if(m_enableCSR)
	{
		//	認証要求ファイルの保存
		if(util.SaveCSR(m_csrPath,entry))
		{
			MessageBox("認証要求ファイルの生成に失敗しました。","04WebServer",MB_ICONEXCLAMATION | MB_OK);
			return;
		}
	}

	//	サイト証明ファイルの保存
	if(util.SaveCRT(m_caPath,entry))
	{
		MessageBox("認証要求ファイルの生成に失敗しました。","04WebServer",MB_ICONEXCLAMATION | MB_OK);
		return;
	}

	MessageBox("秘密鍵とサイト証明書の生成に成功しました。","04WebServer",MB_ICONINFORMATION | MB_OK);
	OnOK();
}

void CKeyGenDialog::OnBnClickedKeyBr()
{
	UpdateData(TRUE);
	
	CFileDialog	sel(FALSE,"pem",m_keyPath,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"PEM Files (*.pem)|*.pem||");;
	if(sel.DoModal()==IDOK)
		m_keyPath = sel.GetPathName();

	UpdateData(FALSE);
	UpdateOtherPath();
}


BOOL CKeyGenDialog::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_keyPath = GET_APP()->m_serverControl.GetServerRoot() + "SSLKey\\04WebServer.pem";
	m_c = "JP";

	UpdateData(FALSE);
	UpdateOtherPath();

	return TRUE;  // return TRUE unless you set the focus to a control
	// 例外 : OCX プロパティ ページは必ず FALSE を返します。
}

void CKeyGenDialog::OnEnChangeKeyPath()
{
	UpdateOtherPath();
}


//	パス更新
void CKeyGenDialog::UpdateOtherPath()
{
	UpdateData(TRUE);

	CString	dir = CPathTools::PathToDir(m_keyPath);
	CString	name = CPathTools::PathToNameNoExt(m_keyPath);

	m_caPath = dir + name + ".crt";
	m_csrPath = dir + name + "_csr.pem";
	m_caPathEdit.SetWindowText(m_caPath);
	m_csrPathEdit.SetWindowText(m_csrPath);
}
