⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acos1.cpp

📁 This is a code relatesd to smart card secuiry DES/3-DES
💻 CPP
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) 1999-2005  Matt Brunk  <info@smartcache.net>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License VERSION 2 as
// published by the Free Software Foundation.  You are not allowed to
// use any other version of the license; unless you got the explicit
// permission from the author to do so.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//------------------------------------------------------------------------------
#include "stdafx.h"
#include "ACOS1.h"
#include "sdes.h"

unsigned char SUBMIT_CODE[]		= {0x80, 0x20, 0x07, 0x00, 0x08};
unsigned char SELECT_FILE[]		= {0x80, 0xA4, 0x00, 0x00, 0x02};
unsigned char START_SESSION[]	= {0x80, 0x84, 0x00, 0x00, 0x08};

static void EncryptBuffer(unsigned char *buf, size_t length);

void CACOS1::SetStopBits(int num)
{
	if ( num == 1 )
	{
		m_stopBits = CSerialPort::OneStopBit;
	}
	else
	{
		m_stopBits = CSerialPort::TwoStopBits;
	}
}

CACOS1::CACOS1()
{
	m_iPort				= 1;
	m_iBaud				= 9600;
	m_stopBits			= CSerialPort::TwoStopBits;
	m_pEdit				= NULL;
	m_bEnableEncryption	= false;
	m_bVerbose			= true;
	::ZeroMemory(m_buf, sizeof m_buf);
	::ZeroMemory(m_inBuf, sizeof m_inBuf);
}

CACOS1::~CACOS1()
{
	try
	{
		if ( m_port.IsOpen() )
		{
			m_port.Close();
		}
	}
	catch (...)
	{

	}
}	//lint !e1740: pointer member 'CACOS1::m_pEdit' not freed

void CACOS1::EnableEncryption(bool bEnable)
{
	m_bEnableEncryption = bEnable;
}

void CACOS1::SetVerbose(bool bEnable)
{
	m_bVerbose = bEnable;
}

CString	CACOS1::GetLastErrorMsg()
{
	return m_lastErrorMsg;
}

bool CACOS1::OpenPort()
{
	bool success = true;
	try
	{
		m_port.Open
		(
			m_iPort,
			m_iBaud,
			CSerialPort::EvenParity,
			8, 
			m_stopBits,
			CSerialPort::NoFlowControl,
			FALSE
		);


		m_port.SetMask(0);

		COMMTIMEOUTS timeouts;

		timeouts.ReadIntervalTimeout			= MAXDWORD;
		timeouts.ReadTotalTimeoutMultiplier		= MAXDWORD;
		timeouts.ReadTotalTimeoutConstant		= 200;
		timeouts.WriteTotalTimeoutMultiplier	= 1;
		timeouts.WriteTotalTimeoutConstant		= 1000;

		m_port.SetTimeouts(timeouts);
		m_port.Setup(8192, 1024);
		Sleep(200);
		m_port.Purge(PURGE_RXABORT | PURGE_RXCLEAR );
	}
	catch (CSerialException* pEx)	//lint !e1752 catch parameter 1 is not a reference
	{
		TRACE(_T("Handle Exception, Message:%s\n"), (LPCTSTR)pEx->SerialGetErrorMessage());	//lint !e506 Constant value Boolean
		m_lastErrorMsg = pEx->SerialGetErrorMessage();
		pEx->Delete();
		success = false;
	}
	return success;
}

void CACOS1::ClosePort()
{
	if ( m_port.IsOpen() )
	{
		m_port.Close();
	}
}

bool CACOS1::GetATR(unsigned char *outBuf, DWORD &nLength)
{
	ASSERT(m_port.IsOpen());

	AppendText(_T("Resetting card ..."));

	DWORD	inBufLength = nLength;
	nLength = 0;

	m_port.SetRTS();
	Sleep(50);
	m_port.ClearRTS();

	unsigned char buf[128];
	DWORD dwRead = 0;
	DWORD nn = 0;

	do
	{
		nn = m_port.Read(&buf[dwRead], 1);
		dwRead += nn;
	} while ((nn > 0) && (dwRead < inBufLength));

	CString atr;
	CString ccc;

	if ( dwRead > 0 )
	{
		//if ( m_bVerbose )
		{
			for ( DWORD ii = 0; ii < dwRead; ii++ )
			{
				outBuf[ii] = buf[ii];
				ccc.Format(_T("%02X "), buf[ii]);
				atr += ccc;
			}

			atr += _T("\r\n");
			AppendText(atr);
		}
#if 0
		else
		{
			AppendText(_T("SUCCESS"));
		}
#endif
	}
	else
	{
		AppendText(_T("ATR not received."));
	}

	nLength = dwRead;

	return dwRead > 0;
}

void CACOS1::AppendText(LPCTSTR Text)
{
	if ( !m_pEdit )
	{
		return;
	}

	CString msg = Text;

	msg += _T("\r\n");

	int Length = m_pEdit->GetWindowTextLength();

	m_pEdit->SetSel(Length, Length);
	m_pEdit->ReplaceSel(msg);
	m_pEdit->LineScroll( m_pEdit->GetLineCount() );
}

static void EncryptBuffer(unsigned char *buf, size_t length)
{
	for ( size_t ii = 0; ii < length; ii++ )
	{
		buf[ii] = SDES::Encrypt(buf[ii]);
	}
}
bool CACOS1::SendCommand(unsigned char *cmd)
{
	bool success = false;
	CString ccc;

	ASSERT(m_port.IsOpen());

	if ( SendData(cmd, 5) )
	{
		DWORD	nn;
		DWORD	numRead = 0;

		nn = m_port.Read(&m_buf[numRead], 1);
		if ( nn == 1 )
		{
			numRead++;
		}

		if ( numRead == 1 )
		{
			if ( m_buf[0] == cmd[1] )
			{
				if ( m_bVerbose )
				{
					ccc.Format(_T("CORRECT procedure byte %02X == %02X"), m_buf[0], cmd[1]);
					AppendText(ccc);
				}
				success = true;
			}
			else
			{
				nn = m_port.Read(&m_buf[numRead], 1);
				if ( nn == 1 )
				{
					numRead++;
					ccc.Format(_T("error status = %02X %02X"), m_buf[0], m_buf[1]);
					AppendText(ccc);
				}
			}
		}
		else
		{
			ccc.Format(_T("SendCommand ERROR: numRead = %lu"), numRead);
			AppendText(ccc);
		}
	}

	return success;
}

bool CACOS1::SendData(unsigned char *data, DWORD dwLength)
{
	ASSERT(m_port.IsOpen());

	DWORD	nn;
	CString sss;
	bool	success = true;

	for ( size_t ii = 0; ii < dwLength; ii++ )
	{
		m_port.Write(&data[ii], 1);
		nn = m_port.Read(&m_buf[0], 1);
		if ( nn == 1 )
		{
			if ( m_buf[0] != data[ii] )
			{
				sss.Format(_T("Echo error -- mismatch %02X != %02X"), m_buf[0], data[ii]);
				AppendText(sss);
				success = false;
			}
			else if ( m_bVerbose )
			{
				sss.Format(_T("Echo SUCCESS -- %02X"), m_buf[0]);
				AppendText(sss);	
			}
		}
		else
		{
			AppendText(_T("Echo error -- no echo..."));	
			success = false;
		}
	}

	return success;
}

bool CACOS1::GetData(unsigned char *data, DWORD &dwLength)
{
	ASSERT(m_port.IsOpen());
	bool success = false;

	dwLength = 0;

	DWORD	dwRead = 0;
	DWORD	nn;

	do
	{
		nn		= m_port.Read(&data[dwRead], 1);
		dwRead += nn;
	} while (nn > 0);

	if ( (dwRead >= 3) )
	{
		U8 c1 = 0x90;
		U8 c2 = 0x00;

		if ( m_bEnableEncryption )
		{
			c1 = SDES::Encrypt(c1);
			c2 = SDES::Encrypt(c2);
		}

		if ( (data[dwRead - 2] == c1) && (data[dwRead - 1] == c2) )
		{
			success  = true;
			dwLength = dwRead - 2;
		}
	}

	return success;
}

bool CACOS1::GetStatus()
{
	ASSERT(m_port.IsOpen());

	bool	success = false;
	DWORD	dwRead = 0;
	DWORD	nn;

	do
	{
		nn = m_port.Read(&m_buf[dwRead], 1);
		dwRead += nn;
	} while (nn > 0);

	if ( dwRead == 2 )
	{
		U8 c1 = 0x90;
		U8 c2 = 0x00;

		if ( m_bEnableEncryption )
		{
			c1 = SDES::Encrypt(c1);
			c2 = SDES::Encrypt(c2);
		}
				
		if ( (m_buf[0] == c1) && (m_buf[1] == c2) )
		{
			success = true;
		}
		else
		{
			CString ccc;
			ccc.Format(_T("Status: %02X %02X"), m_buf[0], m_buf[1]);
			AppendText(ccc);
		}
	}

	return success;
}

bool CACOS1::SubmitIC(unsigned char *ic)
{
	ASSERT(m_port.IsOpen());
	bool success = false;
	AppendText(_T("Sending submit code command ..."));

	::CopyMemory(m_inBuf, SUBMIT_CODE, 5);

	if ( m_bEnableEncryption )
	{
		EncryptBuffer(m_inBuf, 5);
	}

	if ( SendCommand(m_inBuf) )
	{
		::CopyMemory(m_inBuf, ic, 8);

		if ( m_bEnableEncryption )
		{
			EncryptBuffer(m_inBuf, 8);
		}

		if ( SendData(m_inBuf, 8) )
		{
			if ( GetStatus() )
			{
				AppendText(_T("SUCCESS"));
				success = true;
			}
			else
			{
				AppendText(_T("GetStatus ERROR"));
			}
		}
		else
		{
			AppendText(_T("SendCommand ERROR"));
		}
	}
	else
	{
		AppendText(_T("SendData ERROR"));
	}

	return success;
}

bool CACOS1::SelectFile(unsigned char *file)
{
	ASSERT(m_port.IsOpen());
	bool success = false;
	AppendText(_T("Sending select file command ..."));

	::CopyMemory(m_inBuf, SELECT_FILE, 5);

	if ( m_bEnableEncryption )
	{
		EncryptBuffer(m_inBuf, 5);
	}

	if ( SendCommand(m_inBuf) )
	{
		::CopyMemory(m_inBuf, file, 2);

		if ( m_bEnableEncryption )
		{
			EncryptBuffer(m_inBuf, 2);
		}

		if ( SendData(m_inBuf, 2) )
		{
			if ( GetStatus() )
			{
				AppendText(_T("SUCCESS"));
				success = true;
			}
			else
			{
				AppendText(_T("GetStatus ERROR"));
			}
		}
	}

	return success;
}

bool CACOS1::StartSession(unsigned char *key, DWORD &dwLength)
{
	ASSERT(m_port.IsOpen());
	bool success = false;
	AppendText(_T("Sending start session command ..."));

	::CopyMemory(m_inBuf, START_SESSION, 5);

	if ( m_bEnableEncryption )
	{
		EncryptBuffer(m_inBuf, 5);
	}

	if ( SendCommand(m_inBuf) )
	{
		if ( GetData(key, dwLength) )
		{
			AppendText(_T("SUCCESS"));
			success = true;
		}
	}

	return success;

}

bool CACOS1::ReadRecord(int recordNum, int numBytes, unsigned char *data, DWORD &dwLength)
{
	ASSERT(m_port.IsOpen());
	unsigned char cmd[] = {0x80, 0xB2, 0x00, 0x00, 0x00};
	cmd[2] = (unsigned char)recordNum;
	cmd[4] = (unsigned char)numBytes;

	bool success = false;
	AppendText(_T("Reading record ..."));

	::CopyMemory(m_inBuf, cmd, 5);

	if ( m_bEnableEncryption )
	{
		EncryptBuffer(m_inBuf, 5);
	}

	if ( SendCommand(m_inBuf) )
	{
		if ( GetData(data, dwLength) )
		{
			AppendText(_T("SUCCESS"));
			success = true;
		}
	}

	return success;
}

bool CACOS1::WriteRecord(int recordNum, unsigned char *data, int numBytes)
{
	ASSERT(m_port.IsOpen());
	unsigned char cmd[] = {0x80, 0xD2, 0x00, 0x00, 0x00};
	cmd[2] = (unsigned char)recordNum;
	cmd[4] = (unsigned char)numBytes;

	bool success = false;
	AppendText(_T("Writing record ..."));

	::CopyMemory(m_inBuf, cmd, 5);

	if ( m_bEnableEncryption )
	{
		EncryptBuffer(m_inBuf, 5);
	}

	if ( SendCommand(m_inBuf) )
	{
		::CopyMemory(m_inBuf, data, numBytes);

		if ( m_bEnableEncryption )
		{
			EncryptBuffer(m_inBuf, numBytes);
		}

		if ( SendData(m_inBuf, numBytes) )
		{
			if ( GetStatus() )
			{
				AppendText(_T("SUCCESS"));
				success = true;
			}
			else
			{
				AppendText(_T("GetStatus ERROR"));
			}
		}
	}

	return success;

}

void CACOS1::DumpDCB()
{
	ASSERT(m_port.IsOpen());

	DCB dcb;
	m_port.GetState(dcb);

	CString sss;

	AppendText(_T("---- DCB---"));
	sss.Format(_T("DCBlength         : %lu"), dcb.DCBlength);
	AppendText(sss);
	sss.Format(_T("BaudRate          : %lu"), dcb.BaudRate);
	AppendText(sss);
	sss.Format(_T("fBinary           : %lu"), dcb.fBinary);
	AppendText(sss);
	sss.Format(_T("fParity           : %lu"), dcb.fParity);
	AppendText(sss);
	sss.Format(_T("fOutxCtsFlow      : %lu"), dcb.fOutxCtsFlow);
	AppendText(sss);
	sss.Format(_T("fOutxDsrFlow      : %lu"), dcb.fOutxDsrFlow);
	AppendText(sss);
	sss.Format(_T("fDtrControl       : %lu"), dcb.fDtrControl);
	AppendText(sss);
	sss.Format(_T("fDsrSensitivity   : %lu"), dcb.fDsrSensitivity);
	AppendText(sss);
	sss.Format(_T("fTXContinueOnXoff : %lu"), dcb.fTXContinueOnXoff);
	AppendText(sss);
	sss.Format(_T("fOutX             : %lu"), dcb.fOutX);
	AppendText(sss);
	sss.Format(_T("fInX              : %lu"), dcb.fInX);
	AppendText(sss);
	sss.Format(_T("fErrorChar        : %lu"), dcb.fErrorChar);
	AppendText(sss);
	sss.Format(_T("fNull             : %lu"), dcb.fNull);
	AppendText(sss);
	sss.Format(_T("fRtsControl       : %lu"), dcb.fRtsControl);
	AppendText(sss);
	sss.Format(_T("fAbortOnError     : %lu"), dcb.fAbortOnError);
	AppendText(sss);
	sss.Format(_T("fDummy2           : %lu"), dcb.fDummy2);
	AppendText(sss);
	sss.Format(_T("wReserved         : %lu"), dcb.wReserved);
	AppendText(sss);
	sss.Format(_T("XonLim            : %lu"), dcb.XonLim);
	AppendText(sss);
	sss.Format(_T("XoffLim           : %lu"), dcb.XoffLim);
	AppendText(sss);
	sss.Format(_T("ByteSize          : %lu"), dcb.ByteSize);
	AppendText(sss);
	sss.Format(_T("Parity            : %lu"), dcb.Parity);
	AppendText(sss);
	sss.Format(_T("StopBits          : %lu"), dcb.StopBits);
	AppendText(sss);
	sss.Format(_T("XonChar           : %02X"), dcb.XonChar);
	AppendText(sss);
	sss.Format(_T("XoffChar          : %02X"), dcb.XoffChar);
	AppendText(sss);
	sss.Format(_T("ErrorChar         : %02X"), dcb.ErrorChar);
	AppendText(sss);
	sss.Format(_T("EofChar           : %02X"), dcb.EofChar);
	AppendText(sss);
	sss.Format(_T("EvtChar           : %02X"), dcb.EvtChar);
	AppendText(sss);
	sss.Format(_T("wReserved1        : %lu"), dcb.wReserved1);
	AppendText(sss);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -