Change algorithm of selecting PKCS #15 applet
authorWonkyu Kwon <wonkyu.kwon@samsung.com>
Fri, 15 Feb 2013 04:26:56 +0000 (13:26 +0900)
committerWonkyu Kwon <wonkyu.kwon@samsung.com>
Mon, 18 Feb 2013 02:02:46 +0000 (11:02 +0900)
 - select by path of PKCS #15 when is failed to
   selecting by AID
 - implement Record class
 - minor fix

Change-Id: I2dc8e76d6caffb582cb78d2ff84e507a31864118

common/FileObject.cpp
common/PKCS15.cpp
common/PKCS15ODF.cpp
common/Record.cpp [deleted file]
common/TLVHelper.cpp
common/include/FileObject.h
common/include/PKCS15.h
common/include/Record.h

index c3f7b73..f4b5b18 100644 (file)
 
 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)
index 0e0beed..46236d7 100644 (file)
 
 /* 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 */
index dae18fd..686cef6 100644 (file)
 
 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 (file)
index 9ce633a..0000000
+++ /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 */
index 1166088..b577996 100644 (file)
@@ -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;
        }
 
index 64ade5b..a4d1270 100644 (file)
@@ -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();
index a2e3b62..b761eba 100644 (file)
@@ -36,6 +36,8 @@ namespace smartcard_service_api
                map<unsigned int, ByteArray> recordElement;
                PKCS15ODF *odf;
 
+               bool selectFromEFDIR();
+
        public:
                static ByteArray PKCS15_AID;
 
index e97b810..0044d4d 100644 (file)
@@ -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 */