Exemplo n.º 1
0
        public override byte[] Wrap(GPCommand command)
        {
            byte[] cmd_mac = null;

            try
            {
                if (!mac && !enc)
                {
                    return(command.Serialize());
                }

                int    cla  = command.CLA;
                int    lc   = command.CommandData.Length;
                byte[] data = command.CommandData;

                // Encrypt if needed
                if (enc)
                {
                    cla = 0x84;
                    // Counter shall always be incremented
                    Buffer_increment(encryption_counter);
                    if (command.CommandData.Length > 0)
                    {
                        byte[] d = Pad80(command.CommandData, 16);
                        // Encrypt with S-ENC, after increasing the counter
                        byte[] iv = GPCrypto.DoEncrypt_AES_CBC(sessionKeys.GetKeyFor(KeySessionType.ENC).GetEncoded(), encryption_counter);
                        data = GPCrypto.DoEncrypt_AES_CBC(sessionKeys.GetKeyFor(KeySessionType.ENC).GetEncoded(), d, iv);

                        //Cipher c = Cipher.getInstance(GPCrypto.AES_CBC_CIPHER);
                        //c.init(Cipher.ENCRYPT_MODE, sessionKeys.getKeyFor(KeySessionType.ENC), GPCrypto.null_bytes_16);
                        //byte[] iv = c.doFinal(encryption_counter);

                        // Now encrypt the data with S-ENC.
                        //c.init(Cipher.ENCRYPT_MODE, sessionKeys.getKeyFor(KeySessionType.ENC), new IvParameterSpec(iv));
                        //data = c.doFinal(d);
                        lc = data.Length;
                    }
                }
                // Calculate C-MAC
                if (mac)
                {
                    cla = 0x84;
                    lc  = lc + 8;

                    ByteArrayOutputStream bo = new ByteArrayOutputStream();
                    bo.Write(chaining_value);
                    bo.Write(cla);
                    bo.Write(command.INS);
                    bo.Write(command.P1);
                    bo.Write(command.P2);
                    bo.Write(lc);
                    bo.Write(data);
                    byte[] cmac_input = bo.ToByteArray();
                    byte[] cmac       = Scp03_mac(sessionKeys.GetKey(KeySessionType.MAC), cmac_input, 128);
                    // Set new chaining value
                    Array.Copy(cmac, 0, chaining_value, 0, chaining_value.Length);
                    // 8 bytes for actual mac
                    cmd_mac = Arrays.CopyOf(cmac, 8);
                }
                // Construct new command
                ByteArrayOutputStream na = new ByteArrayOutputStream();
                na.Write(cla); // possibly fiddled
                na.Write(command.INS);
                na.Write(command.P1);
                na.Write(command.P2);
                na.Write(lc);
                na.Write(data);
                if (mac)
                {
                    na.Write(cmd_mac);
                }
                return(na.ToByteArray());
            }
            catch (Exception e)
            {
                throw new Exception("APDU wrapping failed", e);
            }
        }
Exemplo n.º 2
0
        private void loadCapFile(String sAID, CapFile cap, bool includeDebug, bool separateComponents, bool loadParam, bool useHash)
        {
            //if (getRegistry().allAIDs().Contains(cap.getPackageAID()))
            //{
            //    giveStrictWarning("Package with AID " + cap.getPackageAID() + " is already present on card");
            //}
            byte[] hash = useHash ? cap.getLoadFileDataHash("SHA1", includeDebug) : new byte[0];
            int    len  = cap.getCodeLength(includeDebug);

            // FIXME: parameters are optional for load
            byte[] loadParams = loadParam ? new byte[] { (byte)0xEF, 0x04, (byte)0xC6, 0x02, (byte)((len & 0xFF00) >> 8),
                                                         (byte)(len & 0xFF) } : new byte[0];

            ByteArrayOutputStream bo = new ByteArrayOutputStream();

            try
            {
                bo.Write((byte)cap.getPackageAID().getLength());
                bo.Write(cap.getPackageAID().getBytes());

                AID aid = new AID(sAID);
                bo.Write((byte)aid.getLength());
                bo.Write(aid.getBytes());

                bo.Write((byte)hash.Length);
                bo.Write(hash);

                bo.Write((byte)loadParams.Length);
                bo.Write(loadParams);

                bo.Write((byte)0x00); //no load token
            }
            catch (IOException ioe)
            {
                throw new Exception(ioe.Message);
            }

            GPInstallRequest installForLoad = new GPInstallRequest(GPInstructionEnum.Install, bo.ToByteArray(), 0x02, 0x00);
            //System.Diagnostics.Debug.WriteLine(installForLoad.ToPrintString());
            GPInstallResponse response = (GPInstallResponse)SendCommand(installForLoad);

            if (response.SW != (ushort)ISO7816ReturnCodes.SW_NO_ERROR)
            {
                throw new Exception("Install for Load failed");
            }

            List <byte[]> blocks = cap.getLoadBlocks(includeDebug, separateComponents, wrapper.getBlockSize());

            for (int i = 0; i < blocks.Count; i++)
            {
                GPInstallRequest load = new GPInstallRequest(GPInstructionEnum.Load, blocks[i], (byte)((i == (blocks.Count - 1)) ? 0x80 : 0x00), (byte)i);
                //System.Diagnostics.Debug.WriteLine(load.ToPrintString());
                response = (GPInstallResponse)SendCommand(load);
                if (response.SW != (ushort)ISO7816ReturnCodes.SW_NO_ERROR)
                {
                    throw new Exception("Load failed");
                }
            }
        }
Exemplo n.º 3
0
        private void installAndMakeSelectable(AID packageAID, AID appletAID, AID instanceAID, Privileges privileges, byte[] installParams, byte[] installToken)
        {
            if (instanceAID == null)
            {
                instanceAID = appletAID;
            }
            //if (getRegistry().allAppletAIDs().Contains(instanceAID))
            //{
            //giveStrictWarning("Instance AID " + instanceAID + " is already present on card");
            //}
            if (installParams == null)
            {
                installParams = new byte[] { (byte)0xC9, 0x00 };
            }
            if (installToken == null)
            {
                installToken = new byte[0];
            }
            byte[] privs             = privileges.toBytes();
            ByteArrayOutputStream bo = new ByteArrayOutputStream();

            try
            {
                bo.Write((byte)packageAID.getLength());
                bo.Write(packageAID.getBytes());

                bo.Write((byte)appletAID.getLength());
                bo.Write(appletAID.getBytes());

                bo.Write((byte)instanceAID.getLength());
                bo.Write(instanceAID.getBytes());

                bo.Write((byte)privs.Length);
                bo.Write(privs);

                bo.Write((byte)installParams.Length);
                bo.Write(installParams);

                bo.Write((byte)installToken.Length);
                bo.Write(installToken);
            }
            catch (IOException ioe)
            {
                throw new Exception(ioe.Message);
            }
            GPInstallRequest install = new GPInstallRequest(GPInstructionEnum.Install, bo.ToByteArray(), 0x0C, 0x00);
            //System.Diagnostics.Debug.WriteLine(install.ToPrintString());
            GPInstallResponse response = (GPInstallResponse)SendCommand(install);

            if (response.SW != (ushort)ISO7816ReturnCodes.SW_NO_ERROR)
            {
                throw new Exception("Install for Install and make selectable failed");
            }
        }
Exemplo n.º 4
0
        private byte[] getConcatenatedStatus(GPRegistry reg, byte p1, byte[] data)
        {
            // By default use tags
            byte p2 = (byte)(reg.tags ? 0x02 : 0x00);

            GPGetStatusRequest  cmd      = new GPGetStatusRequest(data, p1, p2);
            GPGetStatusResponse response = (GPGetStatusResponse)SendCommand(cmd);

            // Workaround for legacy cards, like SCE 6.0 FIXME: this does not work properly
            // Find a different way to adjust the response parser without touching the overall spec mode

            // If ISD-s are asked and none is returned, it could be either
            // - SSD
            // - no support for tags
            if (p1 == 0x80 && response.SW == 0x6A86)
            {
                if (p2 == 0x02)
                {
                    // If no support for tags. Re-issue command without requesting tags
                    reg.tags = false;
                    return(getConcatenatedStatus(reg, p1, data));
                }
            }

            int sw = response.SW;

            if ((sw != (int)ISO7816ReturnCodes.SW_NO_ERROR) && (sw != 0x6310))
            {
                // Possible values:
                if (sw == 0x6A88)
                {
                    // No data to report
                    return(response.ResponseData);
                }
                // 0x6A86 - no tags support or ISD asked from SSD
                // 0a6A81 - Same as 6A88 ?
                //logger.warn("GET STATUS failed for " + HexUtils.bin2hex(cmd.getBytes()) + " with " + Integer.toHexString(sw));
                return(response.ResponseData);
            }

            ByteArrayOutputStream bo = new ByteArrayOutputStream();

            try
            {
                bo.Write(response.ResponseData);

                while (response.SW == 0x6310)
                {
                    cmd      = new GPGetStatusRequest(data, p1, (byte)(p2 | 0x01));
                    response = (GPGetStatusResponse)SendCommand(cmd);

                    sw = response.SW;
                    if ((sw != (int)ISO7816ReturnCodes.SW_NO_ERROR) && (sw != 0x6310))
                    {
                        throw new Exception("GET STATUS failed for " + Formatting.ByteArrayToHexString(cmd.Serialize()));
                    }
                    bo.Write(response.ResponseData);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return(bo.ToByteArray());
        }
Exemplo n.º 5
0
        public void deleteAID(AID aid, bool deleteDeps)
        {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();

            try
            {
                bo.Write((byte)0x4F);
                bo.Write((byte)aid.getLength());
                bo.Write(aid.getBytes());
            }
            catch (IOException ioe)
            {
                throw new Exception(ioe.Message);
            }
            GPInstallRequest  delete   = new GPInstallRequest(GPInstructionEnum.Delete, bo.ToByteArray(), 0x00, (byte)(deleteDeps ? 0x80 : 0x00));
            GPInstallResponse response = (GPInstallResponse)SendCommand(delete);

            if (response.SW != (ushort)ISO7816ReturnCodes.SW_NO_ERROR)
            {
                throw new Exception("Deletion failed");
            }
        }
Exemplo n.º 6
0
        public override byte[] Wrap(GPCommand command)
        {
            try
            {
                if (!mac && !enc)
                {
                    return(command.Serialize());
                }

                if (rmac)
                {
                    rMac.Reset();
                    rMac.Write(ClearBits((byte)command.CLA, (byte)0x07));
                    rMac.Write(command.INS);
                    rMac.Write(command.P1);
                    rMac.Write(command.P2);
                    if (command.CommandData.Length >= 0)
                    {
                        rMac.Write(command.CommandData.Length);
                        rMac.Write(command.CommandData);
                    }
                }

                byte   origCLA          = command.CLA;
                byte   newCLA           = origCLA;
                byte   origINS          = command.INS;
                byte   origP1           = command.P1;
                byte   origP2           = command.P2;
                byte[] origData         = command.CommandData;
                byte   origLc           = (byte)command.CommandData.Length;
                byte   newLc            = origLc;
                byte[] newData          = null;
                byte   le               = command.Le.Value;
                ByteArrayOutputStream t = new ByteArrayOutputStream();

                if (origLc > GetBlockSize())
                {
                    throw new Exception("APDU too long for wrapping.");
                }

                if (mac)
                {
                    if (icv == null)
                    {
                        icv = new byte[8];
                    }
                    else if (icvEnc)
                    {
                        //IBufferedCipher c = null;
                        if (scp == 1)
                        {
                            icv = GPCrypto.DoEncrypt_DES3_ECB(sessionKeys.GetKeyFor(KeySessionType.MAC).GetEncoded(), icv);
                            //c = Cipher.getInstance(GPCrypto.DES3_ECB_CIPHER);
                            //c.init(Cipher.ENCRYPT_MODE, sessionKeys.getKeyFor(KeyType.MAC));
                        }
                        else
                        {
                            icv = GPCrypto.DoEncrypt_DES_ECB(sessionKeys.GetKey(KeySessionType.MAC).GetKey(KeyType.DES).GetEncoded(), icv);
                            //c = Cipher.getInstance(GPCrypto.DES_ECB_CIPHER);
                            //c.init(Cipher.ENCRYPT_MODE, sessionKeys.getKey(KeyType.MAC).getKey(Type.DES));
                        }
                        // encrypts the future ICV ?
                        //icv = c.doFinal(icv);
                    }

                    if (preAPDU)
                    {
                        newCLA = SetBits((byte)newCLA, (byte)0x04);
                        newLc  = (byte)(newLc + 8);
                    }
                    t.Write(newCLA);
                    t.Write(origINS);
                    t.Write(origP1);
                    t.Write(origP2);
                    t.Write(newLc);
                    t.Write(origData);

                    if (scp == 1)
                    {
                        icv = Mac_3des(sessionKeys.GetKey(KeySessionType.MAC), t.ToByteArray(), icv);
                    }
                    else if (scp == 2)
                    {
                        icv = Mac_des_3des(sessionKeys.GetKey(KeySessionType.MAC), t.ToByteArray(), icv);
                    }

                    if (postAPDU)
                    {
                        newCLA = SetBits((byte)newCLA, (byte)0x04);
                        newLc  = (byte)(newLc + 8);
                    }
                    t.Reset();
                    newData = origData;
                }

                if (enc && (origLc > 0))
                {
                    if (scp == 1)
                    {
                        t.Write(origLc);
                        t.Write(origData);
                        if ((t.Size() % 8) != 0)
                        {
                            byte[] x = Pad80(t.ToByteArray(), 8);
                            t.Reset();
                            t.Write(x);
                        }
                    }
                    else
                    {
                        t.Write(Pad80(origData, 8));
                    }
                    newLc += (byte)(t.Size() - origData.Length);

                    //Cipher c = Cipher.getInstance(GPCrypto.DES3_CBC_CIPHER);
                    //c.init(Cipher.ENCRYPT_MODE, sessionKeys.getKeyFor(KeyType.ENC), GPCrypto.iv_null_des);
                    //newData = c.doFinal(t.toByteArray());
                    newData = GPCrypto.DoEncrypt_DES3_CBC(sessionKeys.GetKeyFor(KeySessionType.ENC).GetEncoded(), t.ToByteArray());

                    t.Reset();
                }
                t.Write(newCLA);
                t.Write(origINS);
                t.Write(origP1);
                t.Write(origP2);
                if (newLc > 0)
                {
                    t.Write(newLc);
                    t.Write(newData);
                }
                if (mac)
                {
                    t.Write(icv);
                }
                if (le > 0)
                {
                    t.Write(le);
                }
                return(t.ToByteArray());
            }
            catch (Exception e)
            {
                throw new Exception("APDU wrapping failed", e);
            }
        }