/// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public CommandAPDU CreateExternalAuthCommand()
        {
            MemoryStream memStream = new MemoryStream();

            memStream.Write(mInitUpdateResponse, 12, 8);
            memStream.Write(mHostChallenge, 0, mHostChallenge.Length);

            byte[] hostCryptogram = CryptoUtil.FullTripleDESMAC(mSessionKeys.RetrieveKey(Key.KEY_TYPE_ENC),
                                                                CryptoUtil.BINARY_ZEROS_8_BYTE_BLOCK, CryptoUtil.DESPad(memStream.ToArray()));
            int P1 = mSecurityLevel;

            CommandAPDU externalAuth = new CommandAPDU(CLA_SECURE_GP, INS_EXT_AUTH, P1, 0x00, hostCryptogram);

            mSecureChannel = new SecureChannel(mSessionKeys, SecurityLevel.C_MAC, mSCPIdentifier,
                                               mSCPImplementationOption, CryptoUtil.BINARY_ZEROS_8_BYTE_BLOCK, CryptoUtil.BINARY_ZEROS_8_BYTE_BLOCK);
            externalAuth = mSecureChannel.wrap(externalAuth);
            return(externalAuth);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="keys"></param>
        /// <param name="replaceExisting"></param>
        /// <param name="keyFormat"></param>
        /// <returns></returns>
        public CommandAPDU CreatePutKeyCommand(List <Key> keys, bool replaceExisting, bool addKCV, int keyFormat)
        {
            int p1;
            int p2;

            if (keyFormat == KEY_FORMAT_2)
            {
                throw new Exception("Format 2 is reserved for futrue use.");
            }
            if (keyFormat != KEY_FORMAT_1)
            {
                throw new Exception("Unknown format");
            }

            int prevId = -1;

            for (int i = 0; i < keys.Count; i++)
            {
                Key key = keys[i];
                if (i > 1)
                {
                    if (key.KeyId != prevId + 1)
                    {
                        throw new Exception("Key Identifiers must sequentially increment. See See Global Platform 2.1.1 Card Spec section 9.8.2.3.1");
                    }
                }
                prevId = key.KeyId;
            }

            if (replaceExisting)
            {
                p1 = keys[0].KeyVersion;
            }
            else
            {
                p1 = 0;
            }

            p2 = keys[0].KeyId;

            // Multiple keys
            if (keys.Count > 1)
            {
                p2 |= 0x80;
            }

            Key kek = null;

            if (mSCPIdentifier == SCP_01)
            {
                kek = new Key(mStaticKeys.KekKey.BuildTripleDesKey());
            }
            else if (mSCPIdentifier == SCP_02)
            {
                kek = new Key(mSessionKeys.KekKey.BuildTripleDesKey());
            }

            MemoryStream allKeyData = new MemoryStream();

            allKeyData.WriteByte((byte)keys[0].KeyVersion);
            for (int i = 0; i < keys.Count; i++)
            {
                Key    key          = keys[i];
                byte[] keyDataBytes = EncodeKeyData(key, kek, addKCV, keyFormat);
                allKeyData.Write(keyDataBytes, 0, keyDataBytes.Length);
            }
            CommandAPDU putKeyCommand = new CommandAPDU(CLA_GP, INS_PUT_KEY, p1, p2, allKeyData.ToArray(), 0x00);

            putKeyCommand = mSecureChannel.wrap(putKeyCommand);
            return(putKeyCommand);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandAPDU CreateExternalAuthCommand()
        {
            MemoryStream memStream = new MemoryStream();
            memStream.Write(mInitUpdateResponse, 12, 8);
            memStream.Write(mHostChallenge, 0, mHostChallenge.Length);

            byte[] hostCryptogram = CryptoUtil.FullTripleDESMAC(mSessionKeys.RetrieveKey(Key.KEY_TYPE_ENC),
                CryptoUtil.BINARY_ZEROS_8_BYTE_BLOCK, CryptoUtil.DESPad(memStream.ToArray()));
            int P1 = mSecurityLevel;

            CommandAPDU externalAuth = new CommandAPDU(CLA_SECURE_GP, INS_EXT_AUTH, P1, 0x00, hostCryptogram);
            mSecureChannel = new SecureChannel(mSessionKeys, SecurityLevel.C_MAC, mSCPIdentifier,
                mSCPImplementationOption, CryptoUtil.BINARY_ZEROS_8_BYTE_BLOCK, CryptoUtil.BINARY_ZEROS_8_BYTE_BLOCK);
            externalAuth = mSecureChannel.wrap(externalAuth);
            return externalAuth;
        }