From 13e10400261db0eb3725c7e685c33a9a2d702bda Mon Sep 17 00:00:00 2001 From: Wonkyu Kwon Date: Fri, 15 Feb 2013 13:26:56 +0900 Subject: [PATCH] Change algorithm of selecting PKCS #15 applet - select by path of PKCS #15 when is failed to selecting by AID - implement Record class - minor fix Change-Id: I2dc8e76d6caffb582cb78d2ff84e507a31864118 --- common/FileObject.cpp | 55 ++++++++++++++++++++++++---------------- common/PKCS15.cpp | 61 +++++++++++++++++++++++++++++++++++++++------ common/PKCS15ODF.cpp | 14 +++++------ common/Record.cpp | 34 ------------------------- common/TLVHelper.cpp | 18 ++++++++----- common/include/FileObject.h | 2 ++ common/include/PKCS15.h | 2 ++ common/include/Record.h | 13 +++++----- 8 files changed, 117 insertions(+), 82 deletions(-) delete mode 100644 common/Record.cpp diff --git a/common/FileObject.cpp b/common/FileObject.cpp index c3f7b73..f4b5b18 100644 --- a/common/FileObject.cpp +++ b/common/FileObject.cpp @@ -26,12 +26,14 @@ namespace smartcard_service_api { - FileObject::FileObject(Channel *channel):ProviderHelper(channel) + FileObject::FileObject(Channel *channel) + : ProviderHelper(channel) { opened = false; } - FileObject::FileObject(Channel *channel, ByteArray selectResponse):ProviderHelper(channel) + FileObject::FileObject(Channel *channel, ByteArray selectResponse) + : ProviderHelper(channel) { opened = false; setSelectResponse(selectResponse); @@ -63,7 +65,8 @@ namespace smartcard_service_api } else { - SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2()); + SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", + resp.getStatus(), resp.getSW1(), resp.getSW2()); } } else @@ -91,18 +94,28 @@ namespace smartcard_service_api ret = channel->transmitSync(command, result); if (ret == 0) { - if (setSelectResponse(result) == true) + ResponseHelper resp(result); + + if (resp.getStatus() == 0) { - ret = SUCCESS; + if (setSelectResponse(result) == true) + { + ret = SUCCESS; + } + else + { + ret = ERROR_ILLEGAL_STATE; + } } - else + else if (resp.getStatus() == ResponseHelper::ERROR_FILE_NOT_FOUND) { - ret = ERROR_ILLEGAL_STATE; + ret = ResponseHelper::ERROR_FILE_NOT_FOUND; } } else { - SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength()); + SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", + ret, result.getLength()); ret = ERROR_ILLEGAL_STATE; } @@ -117,7 +130,6 @@ namespace smartcard_service_api /* make apdu command */ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, 0, aid); - SCARD_DEBUG("command : %s", command.toString()); ret = _select(command); @@ -136,9 +148,16 @@ namespace smartcard_service_api } else { - command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, path); + ByteArray temp(path); + + if (path.getLength() > 2 && path[0] == 0x3f && path[1] == 0x00) /* check MF */ + { + /* remove MF from path */ + temp.setBuffer(path.getBuffer(2), path.getLength() - 2); + } + + command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, temp); } - SCARD_DEBUG("command : %s", command.toString()); ret = _select(command); @@ -152,7 +171,6 @@ namespace smartcard_service_api /* make apdu command */ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, fidData); - SCARD_DEBUG("command : %s", command.toString()); ret = _select(command); @@ -166,7 +184,6 @@ namespace smartcard_service_api /* make apdu command */ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_PARENT_DF, 0, ByteArray::EMPTY); - SCARD_DEBUG("command : %s", command.toString()); ret = _select(command); @@ -189,22 +206,20 @@ namespace smartcard_service_api APDUCommand apdu; int ret; - apdu.setCommand(0, APDUCommand::INS_READ_RECORD, recordId, 4, ByteArray::EMPTY, 0); + apdu.setCommand(0, APDUCommand::INS_READ_RECORD, recordId, 4, ByteArray::EMPTY, APDUCommand::LE_MAX); apdu.getBuffer(command); - SCARD_DEBUG("command : %s", command.toString()); ret = channel->transmitSync(command, response); if (ret == 0 && response.getLength() >= 2) { ResponseHelper resp(response); - if (resp.getStatus() == 0) + ret = resp.getStatus(); + if (ret == 0) { SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString()); -// result = resp.getDataField(); - - ret = SUCCESS; + result = Record(recordId, resp.getDataField()); } else { @@ -237,7 +252,6 @@ namespace smartcard_service_api apdu.setCommand(0, APDUCommand::INS_READ_BINARY, offset, 0, ByteArray::EMPTY, length); apdu.getBuffer(command); - SCARD_DEBUG("command : %s", command.toString()); ret = channel->transmitSync(command, response); if (ret == 0 && response.getLength() >= 2) @@ -273,7 +287,6 @@ namespace smartcard_service_api apdu.setCommand(0, APDUCommand::INS_WRITE_BINARY, offset, 0, data, 0); apdu.getBuffer(command); - SCARD_DEBUG("command : %s", command.toString()); ret = channel->transmitSync(command, response); if (ret == 0 && response.getLength() >= 2) diff --git a/common/PKCS15.cpp b/common/PKCS15.cpp index 0e0beed..46236d7 100644 --- a/common/PKCS15.cpp +++ b/common/PKCS15.cpp @@ -20,28 +20,47 @@ /* local header */ #include "Debug.h" +#include "APDUHelper.h" +#include "EFDIR.h" #include "PKCS15.h" namespace smartcard_service_api { - static unsigned char aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 }; + static unsigned char aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, + 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 }; ByteArray PKCS15::PKCS15_AID(ARRAY_AND_SIZE(aid)); - PKCS15::PKCS15(Channel *channel):PKCS15Object(channel), odf(NULL) + PKCS15::PKCS15(Channel *channel) + : PKCS15Object(channel), odf(NULL) { - int ret = 0; + int ret; - if ((ret = select(PKCS15::PKCS15_AID)) == 0) + ret = select(PKCS15::PKCS15_AID); + if (ret == FileObject::SUCCESS) { SCARD_DEBUG("response : %s", selectResponse.toString()); } + else if (ret == ResponseHelper::ERROR_FILE_NOT_FOUND) + { + SCARD_DEBUG_ERR("PKCS15 AID not found, search in EF DIR"); + + if (selectFromEFDIR() == true) + { + SCARD_DEBUG("response : %s", selectResponse.toString()); + } + else + { + SCARD_DEBUG_ERR("PKCS15 select failed, [%d]", ret); + } + } else { - SCARD_DEBUG_ERR("select failed, [%d]", ret); + SCARD_DEBUG_ERR("PKCS15 select failed, [%d]", ret); } } - PKCS15::PKCS15(Channel *channel, ByteArray selectResponse):PKCS15Object(channel, selectResponse), odf(NULL) + PKCS15::PKCS15(Channel *channel, ByteArray selectResponse) + : PKCS15Object(channel, selectResponse), odf(NULL) { } @@ -54,6 +73,35 @@ namespace smartcard_service_api } } + bool PKCS15::selectFromEFDIR() + { + bool result = false; + ByteArray path; + EFDIR dir(channel); + + path = dir.getPathByAID(PKCS15_AID); + if (path.getLength() > 0) + { + int ret; + + ret = select(path, false); + if (ret == FileObject::SUCCESS) + { + result = true; + } + else + { + SCARD_DEBUG_ERR("path select failed, [%d]", ret); + } + } + else + { + SCARD_DEBUG_ERR("PKCS15 not found"); + } + + return result; + } + PKCS15ODF *PKCS15::getODF() { if (odf == NULL) @@ -73,5 +121,4 @@ namespace smartcard_service_api return odf; } - } /* namespace smartcard_service_api */ diff --git a/common/PKCS15ODF.cpp b/common/PKCS15ODF.cpp index dae18fd..686cef6 100644 --- a/common/PKCS15ODF.cpp +++ b/common/PKCS15ODF.cpp @@ -26,12 +26,8 @@ namespace smartcard_service_api { -// PKCS15ODF::PKCS15ODF():PKCS15Object() -// { -// -// } - - PKCS15ODF::PKCS15ODF(Channel *channel):PKCS15Object(channel), dodf(NULL) + PKCS15ODF::PKCS15ODF(Channel *channel) + : PKCS15Object(channel), dodf(NULL) { int ret = 0; @@ -58,7 +54,8 @@ namespace smartcard_service_api } } - PKCS15ODF::PKCS15ODF(Channel *channel, ByteArray selectResponse):PKCS15Object(channel, selectResponse), dodf(NULL) + PKCS15ODF::PKCS15ODF(Channel *channel, ByteArray selectResponse) + : PKCS15Object(channel, selectResponse), dodf(NULL) { int ret = 0; ByteArray odfData; @@ -124,7 +121,8 @@ namespace smartcard_service_api break; default : - SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.getLength(), tlv.getValue().toString()); + SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", + tlv.getTag(), tlv.getLength(), tlv.getValue().toString()); break; } diff --git a/common/Record.cpp b/common/Record.cpp deleted file mode 100644 index 9ce633a..0000000 --- a/common/Record.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* standard library header */ - -/* SLP library header */ - -/* local header */ -#include "Record.h" - -namespace smartcard_service_api -{ - Record::Record() - { - } - - Record::~Record() - { - } - -} /* namespace smartcard_service_api */ diff --git a/common/TLVHelper.cpp b/common/TLVHelper.cpp index 1166088..b577996 100644 --- a/common/TLVHelper.cpp +++ b/common/TLVHelper.cpp @@ -80,6 +80,7 @@ namespace smartcard_service_api bool TLVHelper::_decodeTLV() { int result; + int temp = 0; currentT = 0; currentL = 0; @@ -89,26 +90,31 @@ namespace smartcard_service_api return false; /* T */ - if ((result = decodeTag(tlvBuffer.getBuffer(offset))) < 0) + if ((result = decodeTag(tlvBuffer.getBuffer(offset + temp))) < 0) return false; - offset += result; + temp += result; /* L */ - if ((result = decodeLength(tlvBuffer.getBuffer(offset))) < 0) + if ((result = decodeLength(tlvBuffer.getBuffer(offset + temp))) < 0) return false; - offset += result; + temp += result; if (currentL > 0) { + if (currentL > (tlvBuffer.getLength() - (offset + temp))) + return false; + /* V */ - if ((result = decodeValue(tlvBuffer.getBuffer(offset))) < 0) + if ((result = decodeValue(tlvBuffer.getBuffer(offset + temp))) < 0) return false; - offset += result; + temp += result; } + offset += temp; + return true; } diff --git a/common/include/FileObject.h b/common/include/FileObject.h index 64ade5b..a4d1270 100644 --- a/common/include/FileObject.h +++ b/common/include/FileObject.h @@ -55,6 +55,8 @@ namespace smartcard_service_api static const int ERROR_IO = -6; static const int ERROR_UNKNOWN = -99; + static const unsigned int MF_FID = 0x003F; + FileObject(Channel *channel); FileObject(Channel *channel, ByteArray selectResponse); ~FileObject(); diff --git a/common/include/PKCS15.h b/common/include/PKCS15.h index a2e3b62..b761eba 100644 --- a/common/include/PKCS15.h +++ b/common/include/PKCS15.h @@ -36,6 +36,8 @@ namespace smartcard_service_api map recordElement; PKCS15ODF *odf; + bool selectFromEFDIR(); + public: static ByteArray PKCS15_AID; diff --git a/common/include/Record.h b/common/include/Record.h index e97b810..0044d4d 100644 --- a/common/include/Record.h +++ b/common/include/Record.h @@ -24,16 +24,17 @@ namespace smartcard_service_api class Record { private: - ByteArray data; unsigned int id; + ByteArray data; public: - Record(); - Record(unsigned int id, ByteArray buffer); - ~Record(); + Record() : id(0) {} + Record(unsigned int id, ByteArray buffer) + : id(id), data(buffer) {}; + ~Record() {} - unsigned int getID(); - int getData(ByteArray &buffer); + inline unsigned int getID() { return id; } + inline ByteArray getData() { return data; } }; } /* namespace smartcard_service_api */ -- 2.7.4