static long TestReadLongFile(CReader & oReader, const std::string & csPath) { long lErrors = 0; printf("\nTesting CReader::ReadFile() for long files\n"); try { CByteArray oFullData = oReader.ReadFile(csPath, 0, FULL_FILE); CByteArray oData1 = oReader.ReadFile(csPath, 0, 252); if (oData1.Size() != 252 || memcmp(oFullData.GetBytes(), oData1.GetBytes(), 252) != 0) ERR_LOG("ERR: CReader::ReadFile(length != 252) failed\n", lErrors); CByteArray oData2 = oReader.ReadFile(csPath, 0, 253); if (oData2.Size() != 253 || memcmp(oFullData.GetBytes(), oData2.GetBytes(), 253) != 0) ERR_LOG("ERR: CReader::ReadFile(length != 253) failed\n", lErrors); CByteArray oData3 = oReader.ReadFile(csPath, 100, 400); if (oData3.Size() != 400 || memcmp(oFullData.GetBytes() + 100, oData3.GetBytes(), 400) != 0) ERR_LOG("ERR: CReader::ReadFile(offs=100, len = 400) failed\n", lErrors); } catch(const CMWException &e) { ERR_LOG("ERR: CReader::ReadFile() threw an MWException\n", lErrors); printf(" MWException code: 0x%0x\n", (unsigned)e.GetError()); } catch (...) { ERR_LOG("ERR: CReader::ReadFile() threw an MWException\n", lErrors); } return lErrors; }
static long TestReadShortFile(CReader & oReader, const std::string & csPath) { long lErrors = 0; printf("\nTesting CReader::ReadFile() for short files\n"); try { CByteArray oFullData = oReader.ReadFile(csPath, 0, FULL_FILE); CByteArray oData1 = oReader.ReadFile(csPath, 2, FULL_FILE); if (oData1.Size() + 2 != oFullData.Size() || memcmp(oData1.GetBytes(), oFullData.GetBytes() + 2, oData1.Size()) != 0) { ERR_LOG("ERR: CReader::ReadFile(offset != 0) failed\n", lErrors); } CByteArray oData2 = oReader.ReadFile(csPath, 2, oFullData.Size() - 3); if (oData2.Size() + 3 != oFullData.Size() || memcmp(oData2.GetBytes(), oFullData.GetBytes() + 2, oData2.Size()) != 0) { ERR_LOG("ERR: CReader::ReadFile(length != FULL_FILE) failed\n", lErrors); } CByteArray oData3 = oReader.ReadFile(csPath, 0, oFullData.Size() + 1); if (!oData3.Equals(oFullData)) ERR_LOG("ERR: CReader::ReadFile(length = too long) returned a wrong data\n", lErrors); bool bExceptionCaught = false; try { CByteArray oData4 = oReader.ReadFile(csPath, oFullData.Size() + 1, 1); } catch(CMWException & e) { bExceptionCaught = true; if ( (unsigned) e.GetError() != EIDMW_ERR_PARAM_RANGE) ERR_LOG("ERR: CReader::ReadFile(offset = too long) has thrown the wrong exception\n", lErrors); } if (!bExceptionCaught) ERR_LOG("ERR: CReader::ReadFile(offset = too long) didn't throw an exception\n", lErrors); CByteArray oData5 = oReader.ReadFile(csPath, 0, oFullData.Size()); if (!oData5.Equals(oFullData)) ERR_LOG("ERR: CReader::ReadFile(length = file size) failed\n", lErrors); } catch(const CMWException &e) { ERR_LOG("ERR: CReader::ReadFile() threw an MWException\n", lErrors); printf(" MWException code: 0x%0x\n", (unsigned) e.GetError()); } catch (...) { ERR_LOG("ERR: CReader::ReadFile() threw an Exception\n", lErrors); } return lErrors; }
CByteArray CPkiCard::GetRandom(unsigned long ulLen) { CAutoLock oAutoLock(this); if (m_selectAppletMode == ALW_SELECT_APPLET) { SelectApplet(); } CByteArray oRandom(ulLen); try_again: // Use a Get Challenge command to gather 8 bytes with each loop for (unsigned long i = 0; i < ulLen; i += 20) { unsigned char ucLen = (unsigned char) (ulLen - i > 20 ? 20 : ulLen - i); // Get challenge command CByteArray oResp = SendAPDU(0x84, 0x00, 0x00, (unsigned char) ucLen); if (ShouldSelectApplet(0x84, getSW12(oResp))) { // First try to select if (SelectApplet()) { m_selectAppletMode = ALW_SELECT_APPLET; goto try_again; } } getSW12(oResp, 0x9000); oRandom.Append(oResp.GetBytes(), oResp.Size() - 2); } return oRandom; }
/** * This is something you typically do just once, unless you * want to check if new readers were inserted/removed. * Note: PKCS#11 assumes that the number of readers never * change, so you have to call this function only in * C_GetSlotList(). */ CReadersInfo CCardLayer::ListReaders() { CReadersInfo theReadersInfo; CByteArray oReaders; // Do an SCardEstablishContext() if not done yet try { m_oPCSC.EstablishContext(); oReaders = m_oPCSC.ListReaders(); } catch(CMWException & e) { unsigned long err = e.GetError(); if (err == EIDMW_ERR_NO_READER) return theReadersInfo; throw; } theReadersInfo = CReadersInfo(oReaders); if (oReaders.Size() != 0) { m_szDefaultReaderName = (char *) oReaders.GetBytes(); } return theReadersInfo; }
void CPkiCard::WriteUncachedFile(const std::string & csPath, unsigned long ulOffset, const CByteArray & oData) { CAutoLock autolock(this); tFileInfo fileInfo = SelectFile(csPath, true); const unsigned char *pucData = oData.GetBytes(); unsigned long ulDataLen = oData.Size(); for (unsigned long i = 0; i < ulDataLen; i += MAX_APDU_WRITE_LEN) { unsigned long ulLen = ulDataLen - i; if (ulLen > MAX_APDU_WRITE_LEN) ulLen = MAX_APDU_WRITE_LEN; CByteArray oResp = UpdateBinary(ulOffset + i, CByteArray(pucData + i, ulLen)); unsigned long ulSW12 = getSW12(oResp); if (ulSW12 == 0x6982) throw CNotAuthenticatedException( EIDMW_ERR_NOT_AUTHENTICATED, fileInfo.lWritePINRef); else if (ulSW12 != 0x9000) throw CMWEXCEPTION(m_poContext->m_oPCSC.SW12ToErr(ulSW12)); } MWLOG(LEV_INFO, MOD_CAL, L"Written file %ls to card", utilStringWiden(csPath).c_str()); }
BOOL WINAPI eidmwGetHashParam( IN HCRYPTPROV hProv, //!< Handle to provider previously obtained through a call to CPAcquireContext IN HCRYPTHASH hHash, //!< A reference to the hash object for which to set the parameter IN DWORD dwParam, //!< Parameter to set OUT LPBYTE pbData, //!< A data buffer in which the parameter data will be returned IN OUT LPDWORD pcbDataLen, //!< Length of the data to be returned IN DWORD dwFlags) //!< No flags currently defined { BOOL bReturnVal = FALSE; DWORD dwLastError = 0; __CSP_TRY__ MWLOG(LEV_INFO, MOD_CSP, L"CPGetHashParam(hProv = %d) called", hProv); MWLOG(LEV_INFO, MOD_CSP, L" - IN: hHash = %d", hHash); MWLOG(LEV_INFO, MOD_CSP, L" - IN: dwParam = 0x%0x", dwParam); MWLOG(LEV_INFO, MOD_CSP, L" - IN: pbData = %p", pbData); CProviderContext *poProvCtx = g_oProviderContextPool.GetProviderContext(hProv); CProviderHash *poProvHash = poProvCtx->GetHash(hHash); switch(dwParam) { case HP_ALGID: { DWORD dwAlgID = (DWORD) poProvHash->GetAlgid(); bReturnVal = FillProvParam(pbData, pcbDataLen, &dwAlgID, sizeof(DWORD)); break; } case HP_HASHSIZE: { DWORD dwHashSize = (DWORD) poProvHash->GetLengthBytes(); bReturnVal = FillProvParam(pbData, pcbDataLen, &dwHashSize, sizeof(DWORD)); break; } case HP_HASHVAL: { CByteArray oHashValue = poProvHash->GetHashValue(); bReturnVal = FillProvParam(pbData, pcbDataLen, oHashValue.GetBytes(), oHashValue.Size()); break; } default: dwLastError = NTE_BAD_TYPE; } __STORE_LASTERROR__ MWLOG(LEV_INFO, MOD_CSP, L" Returning CPGetHashParam(hProv = %d) with code 0x%0x", hProv, bReturnVal ? 0 : dwLastError); if (bReturnVal) MWLOG(LEV_INFO, MOD_CSP, L" - OUT: *pcbDataLen = %d", *pcbDataLen); __CSP_CATCH_SETLASTERROR__ return (bReturnVal); }
void SODParser::ParseSodEncapsulatedContent(const CByteArray & contents){ ASN1_ITEM xLev0Item; ASN1_ITEM xLev1Item; ASN1_ITEM xLev2Item; ASN1_ITEM xLev3Item; ASN1_ITEM xLev4Item; xLev0Item.p_data = (unsigned char*)contents.GetBytes(); xLev0Item.l_data = contents.Size(); if ((asn1_next_item(&xLev0Item, &xLev1Item)!= 0) ||(xLev1Item.tag != ASN_SEQUENCE)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); if ((xLev1Item.l_data < 2)|| (asn1_next_item(&xLev1Item, &xLev2Item)!= 0) ||(xLev2Item.tag != ASN_INTEGER)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); if (bin2int(xLev2Item.p_data, xLev2Item.l_data)!=0) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_VALUE); if ((xLev1Item.l_data < 2)|| (asn1_next_item(&xLev1Item, &xLev2Item)!= 0) ||(xLev2Item.tag != ASN_SEQUENCE)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); if ((xLev2Item.l_data < 2)|| (asn1_next_item(&xLev2Item, &xLev3Item)!= 0) ||(xLev3Item.tag != ASN_OID)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); // martinho: not the intended way, but for now it will do just fine. if (memcmp(xLev3Item.p_data, OID_SHA256_ALGORITHM, xLev3Item.l_data) != 0) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ALGO_OID); if ((xLev2Item.l_data < 2)|| (asn1_next_item(&xLev2Item, &xLev3Item)!= 0) ||(xLev3Item.tag != ASN_NULL)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); if ((xLev1Item.l_data < 2)|| (asn1_next_item(&xLev1Item, &xLev2Item)!= 0) ||(xLev2Item.tag != ASN_SEQUENCE)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); attr = new SODAttributes(); int i=0; while(xLev2Item.l_data > 0){ if ((xLev2Item.l_data < 2)|| (asn1_next_item(&xLev2Item, &xLev3Item)!= 0) ||(xLev3Item.tag != ASN_SEQUENCE)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); if ((xLev3Item.l_data < 2)|| (asn1_next_item(&xLev3Item, &xLev4Item)!= 0) ||(xLev4Item.tag != ASN_INTEGER)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); if (bin2int(xLev4Item.p_data, xLev4Item.l_data)!=(i+1)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_VALUE); if ((xLev3Item.l_data < 2)|| (asn1_next_item(&xLev3Item, &xLev4Item)!= 0) ||(xLev4Item.tag != ASN_OCTET_STRING)) throw CMWEXCEPTION(EIDMW_SOD_UNEXPECTED_ASN1_TAG); attr->hashes[i].Append(xLev4Item.p_data,xLev4Item.l_data); i++; } }
bool APL_CryptoFwk::VerifyRoot(const CByteArray &cert, const unsigned char *const *roots) { const unsigned char *const *proot; for(proot=roots;*proot!=NULL;proot++) { if(memcmp(cert.GetBytes(),*proot,cert.Size())==0) return true; } return false; }
bool CByteArray::Equals(const CByteArray & oByteArray) const { if (m_bMallocError) throw CMWEXCEPTION(EIDMW_ERR_MEMORY); if (m_ulSize == 0 && oByteArray.Size() == 0) return true; return m_ulSize == oByteArray.Size() && memcmp(m_pucData, oByteArray.GetBytes(), m_ulSize) == 0; }
CSISCard::CSISCard( SCARDHANDLE hCard, CContext *poContext, CPinpad *poPinpad, const CByteArray & oData // is either the first 26 bytes, or the whole 404 bytes ) :CCard(hCard, poContext, poPinpad) { if (oData.Size() == 26) m_oCardAtr = oData; else { m_oCardAtr = CByteArray(oData.GetBytes(), 26); m_oCardData = oData; } }
std::string * CCardLayer::GetDefaultReader() { std::string * pRet = &m_szDefaultReaderName; if (m_szDefaultReaderName.size() == 0) { CByteArray csReaders = m_oPCSC.ListReaders(); if (csReaders.Size() != 0) { m_szDefaultReaderName = (char *)csReaders.GetBytes(); } } return pRet; }
BOOL WINAPI eidmwGenRandom( IN HCRYPTPROV hProv, //!< Handle to provider previously obtained through a call to CPAcquireContext IN DWORD cbLen, //!< Number of bytes of random data requested OUT LPBYTE pbBuffer) //!< Buffer to store the random data { BOOL bReturnVal = FALSE; DWORD dwLastError = 0; __CSP_TRY__ MWLOG(LEV_INFO, MOD_CSP, L"CPGenRandom(hProv = %d) called", hProv); MWLOG(LEV_INFO, MOD_CSP, L" - IN: cbLen = %d", cbLen); CProviderContext *poProvCtx = g_oProviderContextPool.GetProviderContext(hProv); std::string csContainerName = poProvCtx->GetContainerName(); if (csContainerName == "") { dwLastError = NTE_NO_KEY; } else { CAutoMutex oAutoMutex(&g_oCalMutex); CReader *poReader = FindCard(poProvCtx); if (poReader == NULL) { dwLastError = NTE_FAIL; } else { CByteArray oRandom = poReader->GetRandom(cbLen); memcpy(pbBuffer, oRandom.GetBytes(), oRandom.Size()); bReturnVal = TRUE; } } __STORE_LASTERROR__ MWLOG(LEV_INFO, MOD_CSP, L" Returning CPGenRandom(hProv = %d) with code 0x%0x", hProv, bReturnVal ? 0 : dwLastError); __CSP_CATCH_SETLASTERROR__ return (bReturnVal); }
CByteArray CPkiCard::ReadUncachedFile(const std::string & csPath, unsigned long ulOffset, unsigned long ulMaxLen) { CByteArray oData(ulMaxLen); CAutoLock autolock(this); tFileInfo fileInfo = SelectFile(csPath, true); // Loop until we've read ulMaxLen bytes or until EOF (End Of File) bool bEOF = false; for (unsigned long i = 0; i < ulMaxLen && !bEOF; i += MAX_APDU_READ_LEN) { unsigned long ulLen = ulMaxLen - i <= MAX_APDU_READ_LEN ? ulMaxLen - i : MAX_APDU_READ_LEN; CByteArray oResp = ReadBinary(ulOffset + i, ulLen); unsigned long ulSW12 = getSW12(oResp); // If the file is a multiple of the block read size, you will get // an SW12 = 6B00 (at least with BE eID) but that OK then.. if (ulSW12 == 0x9000 || (i != 0 && ulSW12 == 0x6B00)) oData.Append(oResp.GetBytes(), oResp.Size() - 2); else if (ulSW12 == 0x6982) { throw CNotAuthenticatedException( EIDMW_ERR_NOT_AUTHENTICATED, fileInfo.lReadPINRef); } else if (ulSW12 == 0x6B00) throw CMWEXCEPTION(EIDMW_ERR_PARAM_RANGE); else if (ulSW12 == 0x6D00) throw CMWEXCEPTION(EIDMW_ERR_NOT_ACTIVATED); else throw CMWEXCEPTION(m_poContext->m_oPCSC.SW12ToErr(ulSW12)); // If the driver/reader itself did the 6CXX handling, // we assume we're at the EOF if (oResp.Size() < MAX_APDU_READ_LEN) bEOF = true; } MWLOG(LEV_INFO, MOD_CAL, L" Read file %ls (%d bytes) from card", utilStringWiden(csPath).c_str(), oData.Size()); return oData; }
static void WriteFile(const std::string & csSerial, const std::string & csPath, const CByteArray &oData) { std::string csFileName; if (csSerial != "") csFileName += csSerial + "_"; csFileName += csPath; #ifdef WIN32 FILE *f; fopen_s(&f,csFileName.c_str(), "wb"); #else FILE *f = fopen(csFileName.c_str(), "wb"); #endif if (f != NULL) { fwrite(oData.GetBytes(), 1, oData.Size(), f); printf(" - Written %d bytes to %s\n", oData.Size(), csFileName.c_str()); fclose(f); } else printf(" - ERR: couldn't write file %s\n", csFileName.c_str()); }
CByteArray CPinpadLib::PinCmd(SCARDHANDLE hCard, unsigned long ulControl, CByteArray oCmd, unsigned char ucPintype, unsigned char ucOperation) { #if defined WIN32 && defined BEID_OLD_PINPAD if (m_oPinpadLibOldBeid.UseOldLib()) return m_oPinpadLibOldBeid.PinCmd(hCard, ulControl, oCmd, ucPintype, ucOperation); #endif if (m_ppCmd2 == NULL) throw CMWEXCEPTION(EIDMW_ERR_UNKNOWN); // shouldn't happen unsigned char tucOut[258]; DWORD dwOutLen = sizeof(tucOut); long lRet = m_ppCmd2(hCard, (int) ulControl, oCmd.GetBytes(), oCmd.Size(), tucOut, sizeof(tucOut), &dwOutLen, ucPintype, ucOperation, 0, NULL); if (lRet != SCARD_S_SUCCESS) throw CMWEXCEPTION(EIDMW_ERR_PINPAD); return CByteArray(tucOut, dwOutLen); }
void CHash::Update(const CByteArray & data, unsigned long ulOffset, unsigned long ulLen) { if (!m_bInitialized) throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD); if (ulLen != 0) { const unsigned char *pucData = data.GetBytes() + ulOffset; switch (m_Algo) { case ALGO_MD5: md5_process(&m_md1, pucData, ulLen); break; case ALGO_SHA1: sha1_process(&m_md1, pucData, ulLen); break; case ALGO_MD5_SHA1: md5_process(&m_md1, pucData, ulLen); sha1_process(&m_md2, pucData, ulLen); break; case ALGO_SHA256: sha256_process(&m_md1, pucData, ulLen); break; case ALGO_SHA384: sha384_process(&m_md1, pucData, ulLen); break; case ALGO_SHA512: sha512_process(&m_md1, pucData, ulLen); break; case ALGO_RIPEMD160: rmd160_process(&m_md1, pucData, ulLen); break; default: throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD); } } }
CByteArray APL_Certifs::getTLV() { //First we add all the certs in a tlv CTLVBuffer tlvNested; CByteArray baCount; baCount.AppendLong(countAll(true)); tlvNested.SetTagData(0x00,baCount.GetBytes(),baCount.Size()); //Tag 0x00 contain the number of certificates unsigned char j=1; for(unsigned long i=0;i<countAll(true);i++) { APL_Certif *cert=getCert(i,true); CByteArray baCert=cert->getTLV(); tlvNested.SetTagData(j++,baCert.GetBytes(),baCert.Size()); } unsigned long ulLen=tlvNested.GetLengthNeeded(); unsigned char *pucData= new unsigned char[ulLen]; tlvNested.Extract(pucData,ulLen); CByteArray baCerts(pucData,ulLen); delete[] pucData; //We nest the tlv into the enclosing tlv CTLVBuffer tlv; tlv.SetTagData(BEID_TLV_TAG_FILE_CERTS,baCerts.GetBytes(),baCerts.Size()); ulLen=tlv.GetLengthNeeded(); pucData= new unsigned char[ulLen]; tlv.Extract(pucData,ulLen); CByteArray ba(pucData,ulLen); delete[] pucData; return ba; }
BOOL WINAPI eidmwSignHash( IN HCRYPTPROV hProv, //!< Handle to provider previously obtained through a call to CPAcquireContext IN HCRYPTHASH hHash, //!< Handle to the hash object to be signed IN DWORD dwKeySpec, //!< Key specifier of the key with which to sign IN LPCWSTR szDescription, //!< Discription of the signature (this parameter should no longer be used) IN DWORD dwFlags, //!<Currently no flags defined, should be 0 OUT LPBYTE pbSignature, //!< Pointer to an output buffer that will contain the resulting signature IN OUT LPDWORD pcbSigLen) //!< Length of the resulting signature { BOOL bReturnVal = FALSE; DWORD dwLastError = 0; __CSP_TRY__ MWLOG(LEV_INFO, MOD_CSP, L"CPSignHash(hProv = %d) called", hProv); MWLOG(LEV_INFO, MOD_CSP, L" - IN: hHash = %d", hHash); MWLOG(LEV_INFO, MOD_CSP, L" - IN: dwKeySpec = %d", dwKeySpec); MWLOG(LEV_INFO, MOD_CSP, L" - IN: pbSignature = %p", pbSignature); CProviderContext *poProvCtx = g_oProviderContextPool.GetProviderContext(hProv); CProviderHash *poProvHash = poProvCtx->GetHash(hHash, false); std::string csContainerName = poProvCtx->GetContainerName(); if (csContainerName == "") { dwLastError = NTE_NO_KEY; } else if (poProvHash == NULL) { dwLastError = NTE_BAD_HASH; } else { CAutoMutex oAutoMutex(&g_oCalMutex); CReader *poReader = FindCard(poProvCtx); if (poReader == NULL) { dwLastError = NTE_NO_KEY; } else { tPrivKey privKey = FindKey(poReader, csContainerName); if (pbSignature == NULL) { *pcbSigLen = privKey.ulKeyLenBytes; if (*pcbSigLen == 0) *pcbSigLen = 128; // Default, just in case bReturnVal = TRUE; } else { unsigned long ulSignAlgo = GetSignAlgo(poProvHash->GetAlgid()); CByteArray oSignature; // If the hash has already been calculated (or given via CPSetHashParam()) // then we present this value. Otherwise we present the hash object itself CByteArray & oHashValue = poProvHash->GetHashValue(); if (oHashValue.Size() == 0) oSignature = poReader->Sign(privKey, ulSignAlgo, poProvHash->GetHashObject()); else oSignature = poReader->Sign(privKey, ulSignAlgo, oHashValue); bReturnVal = FillProvParam(pbSignature, pcbSigLen, oSignature.GetBytes(), oSignature.Size()); if (bReturnVal) ReverseByteOrder(pbSignature, *pcbSigLen); } } } __STORE_LASTERROR__ MWLOG(LEV_INFO, MOD_CSP, L" Returning CPSignHash(hProv = %d) with code 0x%0x", hProv, bReturnVal ? 0 : dwLastError); if (bReturnVal) MWLOG(LEV_INFO, MOD_CSP, L" - OUT: *pcbSigLen = %d", *pcbSigLen); __CSP_CATCH_SETLASTERROR__ return (bReturnVal); }
void CByteArray::Append(const CByteArray & oByteArray) { Append(oByteArray.GetBytes(), oByteArray.Size()); }
//copy object into new object CByteArray::CByteArray(const CByteArray & oByteArray) { MakeArray(oByteArray.GetBytes(), oByteArray.Size()); }
CByteArray CBeidCard::Ctrl(long ctrl, const CByteArray & oCmdData) { CAutoLock oAutoLock(this); switch(ctrl) { case CTRL_BEID_GETCARDDATA: return m_oCardData; case CTRL_BEID_GETSIGNEDCARDDATA: if (m_ucAppletVersion < 0x17) throw CMWEXCEPTION(EIDMW_ERR_NOT_SUPPORTED); else { if (m_selectAppletMode == ALW_SELECT_APPLET) SelectApplet(); m_ucCLA = 0x80; CByteArray oRet = SendAPDU(0xE4, 0x02, 0x00, 0x9C); m_ucCLA = 0; getSW12(oRet, 0x9000); oRet.Chop(2); return oRet; } case CTRL_BEID_GETSIGNEDPINSTATUS: // oCmdData must contain: // - the pin reference (1 byte) if (m_ucAppletVersion < 0x17) throw CMWEXCEPTION(EIDMW_ERR_NOT_SUPPORTED); else { if (m_selectAppletMode == ALW_SELECT_APPLET) SelectApplet(); unsigned char ucPinRef = oCmdData.GetByte(0); m_ucCLA = 0x80; CByteArray oRet = SendAPDU(0xEA, 0x02, ucPinRef, 0x81); m_ucCLA = 0; if (ShouldSelectApplet(0xEA, getSW12(oRet))) { if (SelectApplet()) { m_selectAppletMode = ALW_SELECT_APPLET; m_ucCLA = 0x80; CByteArray oRet = SendAPDU(0xEA, 0x02, ucPinRef, 0x81); m_ucCLA = 0; } } getSW12(oRet, 0x9000); oRet.Chop(2); return oRet; } case CTRL_BEID_INTERNAL_AUTH: // oCmdData must contain: // - the key reference (1 byte) // - the challenge to be signed (20 bytes) if (oCmdData.Size() != 21) throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD); else { if (m_selectAppletMode == ALW_SELECT_APPLET) SelectApplet(); unsigned char ucKeyRef = oCmdData.GetByte(0); CByteArray oData(22); oData.Append(0x94); oData.Append(0x14); oData.Append(oCmdData.GetBytes() + 1, 20); CByteArray oRet = SendAPDU(0x88, 0x02, ucKeyRef, oData); if (ShouldSelectApplet(0x88, getSW12(oRet))) { if (SelectApplet()) { m_selectAppletMode = ALW_SELECT_APPLET; CByteArray oRet = SendAPDU(0x88, 0x02, ucKeyRef, oData); } } getSW12(oRet, 0x9000); oRet.Chop(2); return oRet; } default: MWLOG(LEV_WARN, MOD_CAL, L"Ctrl(): Unknown CRTL code %d (0x%0x) specified", ctrl, ctrl); throw CMWEXCEPTION(EIDMW_ERR_PARAM_BAD); } }
static bool VerifySignature(const CByteArray &oData, const CByteArray & oSignature, const CByteArray & oCert, unsigned long ulSignAlgo) { if (!bOpensslInitialized) { OpenSSL_add_all_algorithms(); bOpensslInitialized = true; } unsigned long ulCertLen = oCert.Size(); unsigned char *pucCert = new unsigned char[ulCertLen]; memcpy(pucCert, oCert.GetBytes(), ulCertLen); BIO *pBio = BIO_new_mem_buf(pucCert, ulCertLen); X509 *pCert = d2i_X509_bio(pBio, NULL); EVP_PKEY *pKey = X509_get_pubkey(pCert); EVP_MD_CTX mdCtx; const EVP_MD *pEvpMdAlgo = GetOpensslHash(ulSignAlgo); int res = 0; if (ulSignAlgo == SIGN_ALGO_SHA1_RSA_PSS) { // Can't use the EVP_xxx() functions for PSS CByteArray oHash = CHash().Hash(ALGO_SHA1, oData); RSA *rsa = (RSA *) pKey->pkey.rsa; unsigned char tucDecrypted[512]; RSA_public_decrypt(oSignature.Size(), oSignature.GetBytes(), tucDecrypted, rsa, RSA_NO_PADDING); res = RSA_verify_PKCS1_PSS(rsa, oHash.GetBytes(), pEvpMdAlgo, tucDecrypted, -2); } else { EVP_VerifyInit(&mdCtx, pEvpMdAlgo); EVP_VerifyUpdate(&mdCtx, oData.GetBytes(), oData.Size()); #if (OPENSSL_VERSION_NUMBER > 0x009070ffL) res = EVP_VerifyFinal(&mdCtx, oSignature.GetBytes(), oSignature.Size(), pKey); #else unsigned char* signatureBytes = const_cast<unsigned char*> (oSignature.GetBytes()); res = EVP_VerifyFinal(&mdCtx, signatureBytes, oSignature.Size(), pKey); #endif } X509_free(pCert); BIO_free(pBio); free(pucCert); // Result res: 1 = signature OK, 0 = bad signature, other = other err if (res == 1) return true; else { if (res == 0) printf(" ERR: verification of algo %s failed\n", SignAlgo2String(ulSignAlgo)); else printf(" ERR: openssl verification of algo %s returned 0x%0x (%d)\n", SignAlgo2String(ulSignAlgo), res, res); return false; } }