|
|
// ACard.cpp: implementation of the CAbstractCard class.
//
// (c) Copyright Schlumberger Technology Corp., unpublished work, created
// 1999. This computer program includes Confidential, Proprietary
// Information and is a Trade Secret of Schlumberger Technology Corp. All
// use, disclosure, and/or reproduction is prohibited unless authorized
// in writing. All Rights Reserved.
//////////////////////////////////////////////////////////////////////
#include "NoWarning.h"
#include <functional>
#include "ACard.h"
#include "V1Card.h"
#include "V2Card.h"
#include "TransactionWrap.h"
using namespace std; using namespace iop; using namespace cci; using namespace scu;
/////////////////////////// LOCAL/HELPER /////////////////////////////////
namespace { // Like std::mem_fun1_t but for constant member functions
template<class R, class T, class A> class ConstMemFun1Type : public binary_function<T const *, A, R> { public: explicit ConstMemFun1Type(R (T::*Pm)(A) const) : m_Ptr(Pm) {}
R operator()(T const *P, A Arg) const { return ((P->*m_Ptr)(Arg)); }
private: R (T::*m_Ptr)(A) const; };
// Like std::mem_fun1 but for constant member functions
template<class R, class T, class A> inline ConstMemFun1Type<R, T, A> ConstMemFun1(R (T::*Pm)(A) const) { return (ConstMemFun1Type<R, T, A>(Pm)); }
template<class R> ConstMemFun1Type<vector<R>, CAbstractCard const, ObjectAccess> const PriviledgedEnumFun(vector<R> (CAbstractCard::*pmf)(ObjectAccess) const) { return ConstMemFun1Type<vector<R>, CAbstractCard const, ObjectAccess>(pmf); }
template<class T, class Op> vector<T> EnumAll(Op Enumerator) { vector<T> vResult = Enumerator(oaPublicAccess); vector<T> vPriv = Enumerator(oaPrivateAccess);
vResult.reserve(vResult.size() + vPriv.size()); vResult.insert(vResult.end(), vPriv.begin(), vPriv.end()); return vResult; };
} // namespace
/////////////////////////// PUBLIC /////////////////////////////////
// Types
// C'tors/D'tors
CAbstractCard::~CAbstractCard() {}
// Operators
bool CAbstractCard::operator==(CAbstractCard const &rhs) const { CTransactionWrap wrap(this); CTransactionWrap rhswrap(rhs); // will throw if the card is pulled.
return m_strReaderName == rhs.m_strReaderName; }
bool CAbstractCard::operator!=(CAbstractCard const &rhs) const { return !(*this == rhs); }
// Operations
void CAbstractCard::AuthenticateUser(SecureArray<BYTE> const &rstrBuffer) { m_apSmartCard->VerifyCHV(1, rstrBuffer.data()); }
void CAbstractCard::ChangePIN(SecureArray<BYTE> const &rstrOldPIN, SecureArray<BYTE> const &rstrNewPIN) { if ((rstrOldPIN.size() != 0x08) || (rstrNewPIN.size() != 0x08)) throw Exception(ccBadPinLength);
m_apSmartCard->ChangeCHV(1, rstrOldPIN.data(), rstrNewPIN.data()); }
void CAbstractCard::Logout() { m_apSmartCard->LogoutAll(); }
CAbstractCard * CAbstractCard::Make(string const &rstrReader) { auto_ptr<CIOP> apiop(new CIOP()); auto_ptr<CSmartCard> apSmartCard(apiop->Connect(rstrReader.c_str()));
typedef auto_ptr<CAbstractCard>(*PCardMakerFun)(string const &rstrReader, auto_ptr<CIOP> &rapiop, auto_ptr<CSmartCard> &rapSmartCard); static PCardMakerFun aCardMakers[] = { CV2Card::DoMake, CV1Card::DoMake, 0 }; auto_ptr<CAbstractCard> apCard; for (PCardMakerFun *ppcmf = aCardMakers; (*ppcmf && !apCard.get()); ++ppcmf) apCard = auto_ptr<CAbstractCard>((*ppcmf)(rstrReader, apiop, apSmartCard));
if (!apCard.get()) throw Exception(ccNotPersonalized);
apCard->Setup();
return apCard.release(); // caller given ownership
}
void CAbstractCard::SetUserPIN(string const &rstrPin) { if (rstrPin.size() != 8) throw Exception(ccBadPinLength);
m_apSmartCard->ChangeCHV(1, reinterpret_cast<BYTE const *>(rstrPin.data())); }
void CAbstractCard::VerifyKey(string const &rstrKey, BYTE bKeyNum) { m_apSmartCard->VerifyKey(bKeyNum, static_cast<WORD>(rstrKey.size()), reinterpret_cast<BYTE const *>(rstrKey.data())); }
void CAbstractCard::VerifyTransportKey(string const &rstrKey) { m_apSmartCard->VerifyTransportKey(reinterpret_cast<BYTE const *>(rstrKey.data())); }
void CAbstractCard::GenRandom(DWORD dwNumBytes, BYTE *bpRand) { m_apSmartCard->GetChallenge(dwNumBytes, bpRand); } // Access
SCardType CAbstractCard::CardType() { char const *szCardName = m_apSmartCard->getCardName();
// TO DO: Kludge Alert--a better type interface is needed in the
// IOP to determine the card type rather than keying on the name.
// For now, the Cryptoflex8K type is interpreted to mean it's a
// Cryptoflex card and Access16K means it's an Access card. Thus
// any "Cryptoflex" will map to Cryptoflex8K (including 4K) and
// any "Cyberflex" will map to Access16K. The folded mapping was
// to minimize impact to PKCS with the impending release.
//
// All of this should be revisited with the IOP.
SCardType sct = UnknownCard;
if (strstr(szCardName, "Cryptoflex")) sct = Cryptoflex8K; if (strstr(szCardName, "Cyberflex")) sct = Access16K;
return sct;
}
vector<CCertificate> CAbstractCard::EnumCertificates() const { CTransactionWrap wrap(this);
return EnumAll<CCertificate>(bind1st(PriviledgedEnumFun<CCertificate>(EnumCertificates), this)); }
vector<CDataObject> CAbstractCard::EnumDataObjects() const { CTransactionWrap wrap(this);
return EnumAll<CDataObject>(bind1st(PriviledgedEnumFun<CDataObject>(EnumDataObjects), this)); }
vector <CPrivateKey> CAbstractCard::EnumPrivateKeys() const { CTransactionWrap wrap(this);
return EnumAll<CPrivateKey>(bind1st(PriviledgedEnumFun<CPrivateKey>(EnumPrivateKeys), this)); }
vector<CPublicKey> CAbstractCard::EnumPublicKeys() const { CTransactionWrap wrap(this);
return EnumAll<CPublicKey>(bind1st(PriviledgedEnumFun<CPublicKey>(EnumPublicKeys), this));
}
string CAbstractCard::ReaderName() const { return m_strReaderName; }
CSmartCard & CAbstractCard::SmartCard() const { return *m_apSmartCard; }
// Predicates
// Card is connected and available (e.g. in the reader)
bool CAbstractCard::IsAvailable() const { bool fIsAvailable = false;
try { CTransactionWrap wrap(this);
DWORD dwState; DWORD dwProtocol; m_apSmartCard->GetState(dwState, dwProtocol); fIsAvailable = (SCARD_SPECIFIC == dwState); }
catch (...) { }
return fIsAvailable; }
// Static Variables
/////////////////////////// PROTECTED /////////////////////////////////
// C'tors/D'tors
CAbstractCard::CAbstractCard(string const &rstrReaderName, auto_ptr<iop::CIOP> &rapiop, auto_ptr<CSmartCard> &rapSmartCard) : CCryptFactory(), slbRefCnt::RCObject(), m_strReaderName(rstrReaderName), m_apiop(rapiop), m_apSmartCard(rapSmartCard) {}
// Operators
// Operations
void CAbstractCard::DoSetup() {}
// Access
// Predicates
// Static Variables
/////////////////////////// PRIVATE /////////////////////////////////
// C'tors/D'tors
// Operators
// Operations
void CAbstractCard::Setup() { CTransactionWrap wrap(this);
DoSetup(); }
// Access
// Predicates
// Static Variables
|