private static bool DoDEKIfNeeded(KernelDatabaseBase database, KernelQ qManager)
        {
            TLVList toRemove = new TLVList();

            foreach (TLV tlv in database.TagsToReadYet)
            {
                if (database.IsNotEmpty(tlv.Tag.TagLable))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                    toRemove.AddToList(tlv);
                }
            }
            foreach (TLV tlv in toRemove)
            {
                database.TagsToReadYet.RemoveFromList(tlv);
            }

            if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)
            {
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                return(true);
            }
            return(false);
        }
Exemple #2
0
        public static byte[] OWHF2AES_8_3(KernelDatabaseBase database, byte[] c)
        {
            byte[] oid = new byte[8];
            if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag) &&
                (database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2).Value[0] & 0x80) == 0x80 && // Permanent slot type

                (database.Get(EMVTagsEnum.DS_ODS_INFO_DF62_KRN2).Value[0] & 0x40) == 0x40                   //Volatile slot type
                )
            {
                oid = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
            }
            else
            {
                oid = database.Get(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2).Value;
            }

            List <byte[]> keyComps = new List <byte[]>();

            keyComps.Add(c);
            keyComps.Add(oid);
            byte[] m = keyComps.SelectMany(x => x).ToArray();

            byte[] dsid = database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value;

            byte[] y = new byte[11];
            Array.Copy(dsid, 0, y, 0, y.Length);//this will be padded

            keyComps = new List <byte[]>();
            keyComps.Add(y);
            keyComps.Add(new byte[] { oid[5], oid[6], oid[7], oid[8] });
            keyComps.Add(new byte[] { 0x3F });
            byte[] k = keyComps.SelectMany(x => x).ToArray();

            Aes aes = Aes.Create();

            aes.Key     = k;
            aes.Mode    = CipherMode.CBC;
            aes.Padding = PaddingMode.None;

            MemoryStream ms = new MemoryStream();

            using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(m, 0, m.Length);
            }
            byte[] t = ms.ToArray();
            ms.Dispose();
            t = XOR(t, m);

            byte[] r = new byte[8];
            Array.Copy(t, 0, r, 0, 8);
            return(r);
        }
 private static bool DoDEKIfNeeded(KernelDatabaseBase database, KernelQ qManager)
 {
     if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) ||
         (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag)))
     {
         CommonRoutines.PostDEK(database, qManager);
         database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
         database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
         return(true);
     }
     return(false);
 }
Exemple #4
0
        public static bool DoDDA(KernelDatabaseBase database, KernelQ qManager, CAPublicKeyCertificate capk, TLV sdadTLV)
        {
            try
            {
                TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);
                tsi.Value.OfflineDataAuthenticationWasPerformed = true;
                tsi.UpdateDB();

                if (database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN) == null)
                {
                    return(false);
                }

                if (capk == null)
                {
                    return(false);
                }

                TLV aip    = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag);
                int length = database.StaticDataToBeAuthenticated.Serialize().Length;
                if (aip != null && database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_SDA_TAG_LIST_9F4A_KRN3.Tag))
                {
                    if (2048 - length >= aip.Value.Length)
                    {
                        database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN));
                    }
                    else
                    {
                        return(false);
                    }
                }

                if (sdadTLV != null)
                {
                    ICCDynamicData iccdd = VerifySAD.VerifySDAD(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadTLV.Value);
                    if (iccdd == null)
                    {
                        return(false);
                    }

                    VerifySAD.AddSDADDataToDatabase(database, iccdd);
                    return(true);
                }

                return(false);
            }
            catch
            {
                return(false);
            }
        }
Exemple #5
0
        public static SignalsEnum Initiate2ndCardActionAnalysis(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse, bool entryFromScriptProcessingCompleted = false)
        {
            if (!entryFromScriptProcessingCompleted)
            {
                //check if scripts need to be run
                TLV _71 = database.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN);
                if (_71 != null)
                {
                    ((KernelDatabase)database).ScriptsToRunBeforeGenAC = BuildScriptList(_71);
                    if (((KernelDatabase)database).ScriptsToRunBeforeGenAC.Count > 0)
                    {
                        ((KernelDatabase)database).IsScriptProcessingBeforeGenACInProgress = true;
                        //post first script
                        TLV firstScript = ((KernelDatabase)database).ScriptsToRunBeforeGenAC.GetFirstAndRemoveFromList();
                        EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest();
                        scriptRequest.Deserialize(firstScript.Value);
                        cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU));
                        return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING);
                    }
                }
            }

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            TERMINAL_CAPABILITIES_9F33_KRN         tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            //section 6.5.5 in Book 3
            TLV cdol2 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_2_CDOL2_8D_KRN);

            byte[] cdol2Data = CommonRoutines.PackRelatedDataTag(database, cdol2);

            REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpST = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database);

            rcpST.Value.ACTypeEnum = GetDSACType(database);
            if (aip.Value.CDASupported && tc.Value.CDACapable)
            {
                rcpST.Value.CDASignatureRequested = true;
            }
            else
            {
                rcpST.Value.CDASignatureRequested = false;
            }
            rcpST.UpdateDB();

            EMVGenerateACRequest request = new EMVGenerateACRequest(cdol2Data, null, rcpST);

            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));

            return(SignalsEnum.WAITING_FOR_GEN_AC_2);
        }
 private void AddTTL(EMVTagMeta tag, KernelDatabaseBase database)
 {
     if (database.IsNotEmpty(tag.Tag))
     {
         Children.AddToList(TLV.Create(tag.Tag, database.Get(tag).Value));
     }
 }
        private static EMVGenerateACRequest DoPart3(KernelDatabaseBase database)
        {
            TLV cdol1 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN);

            CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2, cdol1);

            REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpST = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database);

            rcpST.Value.ACTypeEnum            = GetDSACType(database);
            rcpST.Value.CDASignatureRequested = GetODAStatus(database) == 0x80 ? true : false;
            rcpST.UpdateDB();

            EMVGenerateACRequest request = new EMVGenerateACRequest(database.Get(EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2), null, rcpST);

            return(request);
        }
Exemple #8
0
        private static SignalsEnum EntryPointDET(KernelDatabaseBase database, KernelRequest kernel1Request, CardQ cardQManager, Stopwatch sw)
        {
            database.UpdateWithDETData(kernel1Request.InputData);

            bool    missingPDOLData            = false;
            TLV     _9f38                      = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN);
            TLVList pdolList                   = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0);
            DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);

            foreach (TLV tlv in pdolList)
            {
                if (database.IsEmpty(tlv.Tag.TagLable))
                {
                    missingPDOLData = true;
                    dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                }
            }
            dataNeeded.UpdateDB();

            if (missingPDOLData)
            {
                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }

            database.Initialize(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2.Tag);
            CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2, pdolList);
            EMVGetProcessingOptionsRequest request = new EMVGetProcessingOptionsRequest(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2));

            sw.Stop();
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
        private static EMVGenerateACRequest DoIDSWrite(KernelDatabaseBase database)
        {
            #region GAC.40
            TLVList tags = TLV.DeserializeChildrenWithNoV(database.Get(EMVTagsEnum.DSDOL_9F5B_KRN2).Value, 0);
            if (tags.Get(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2.Tag) != null)
            #endregion
            {
                #region GAC.41
                if (database.IsPresent(EMVTagsEnum.DS_INPUT_TERM_DF8109_KRN2.Tag))
                #endregion
                {
                    #region GAC.42
                    APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                    TLV dsit = database.Get(EMVTagsEnum.DS_INPUT_TERM_DF8109_KRN2);
                    TLV dsdh = database.Get(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2.Tag);
                    if (aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_1)
                    #endregion
                    {
                        #region GAC.43
                        dsdh.Value = OWHF2.OWHF2_8_2(database, dsit.Value);
                        #endregion
                    }
                    else
                    {
                        #region GAC.44
                        dsdh.Value = OWHF2.OWHF2AES_8_3(database, dsit.Value);
                        #endregion
                    }
                    return(DoPart4(database));
                }
                else
                {
                    #region GAC.45
                    return(DoPart4(database));

                    #endregion
                }
            }
            else
            {
                #region GAC.45
                return(DoPart4(database));

                #endregion
            }
        }
        public static SignalsEnum DoOnlineProcess(KernelDatabaseBase database, CardQ cardQManager)
        {
            #region 3.5.1.1
            TLV tvr = database.Get(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN);
            if (tvr == null)
            {
                tvr = TLV.Create(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00 });
                database.AddToList(tvr);
            }
            TLV    cdol1            = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN);
            byte[] cdol1RelatedData = CommonRoutines.PackRelatedDataTag(database, cdol1);

            EMVGenerateACRequest request = new EMVGenerateACRequest(cdol1RelatedData);
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            return(SignalsEnum.WAITING_FOR_GEN_AC_1);

            #endregion
        }
        public static SignalsEnum DoOfflineProcess(KernelDatabaseBase database, CardQ cardQManager)
        {
            #region 3.4.1.1 and 3.4.1.2
            TLV    ddol = database.Get(EMVTagsEnum.DYNAMIC_DATA_AUTHENTICATION_DATA_OBJECT_LIST_DDOL_9F49_KRN);
            byte[] ddolRelatedData;
            if (ddol == null)
            {
                TLV unpred = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN);
                unpred.Val.PackValue(unpred.Val.GetLength());
                ddolRelatedData = unpred.Value;
            }
            else
            {
                ddolRelatedData = CommonRoutines.PackRelatedDataTag(database, ddol);
            }
            EMVInternalAuthenticateRequest request = new EMVInternalAuthenticateRequest(ddolRelatedData);
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE);

            #endregion
        }
        public static SignalsEnum DoCommonProcessing(string source, KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse)
        {
            if (database.ActiveAFL == null)
            {
                return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));
            }
            else
            {
                EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.READ_RECORD;
            }

            if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) ||
                (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0))
            {
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
            }

            return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
        }
Exemple #13
0
        /*
         * S17.2
         */
        private static SignalsEnum EntryPointRA(KernelDatabaseBase database, CardResponse cardResponse)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                return(SignalsEnum.NONE);
            }

            if (cardResponse.ApduResponse.ResponseData.Length == 9 &&
                cardResponse.ApduResponse.ResponseData[0] == 0x9F &&
                cardResponse.ApduResponse.ResponseData[1] == 0x50 &&
                cardResponse.ApduResponse.ResponseData[2] == 0x06)
            {
                byte[] bal = new byte[5];
                Array.Copy(cardResponse.ApduResponse.ResponseData, 3, bal, 0, bal.Length);
                database.Get(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2).Value = bal;
            }

            return(SignalsEnum.NONE);
        }
Exemple #14
0
        public static void ProcessingRestrictions(KernelDatabaseBase database)
        {
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN.Tag))
            {
                #region pre.2
                string pvnCard = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN).Value);
                string pvnTerm = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_TERMINAL_9F09_KRN).Value);
                if (pvnCard != pvnTerm)
                #endregion
                {
                    #region pre.3
                    tvr.Value.ICCAndTerminalHaveDifferentApplicationVersions = true;
                    tvr.UpdateDB();
                    #endregion
                }
            }

            DateTime transactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN).Value);
            DateTime appExpiryDate   = EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN).Value);

            #region pre.4
            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.Tag))
            #endregion
            {
                DateTime appEffectiveDate = EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN).Value);
                #region pre.5
                if (transactionDate < appEffectiveDate)
                #endregion
                {
                    #region pre.6
                    tvr.Value.ApplicationNotYetEffective = true;
                    tvr.UpdateDB();
                    #endregion
                }
            }

            #region pre.7
            if (transactionDate > appExpiryDate)
            #endregion
            {
                #region pre.8

                tvr.Value.ExpiredApplication = true;
                tvr.UpdateDB();
                #endregion
            }

            #region pre.9
            if (database.IsEmpty(EMVTagsEnum.APPLICATION_USAGE_CONTROL_9F07_KRN.Tag))
            {
                return;
            }
            #endregion

            #region pre.10
            TERMINAL_TYPE_9F35_KRN tt = new TERMINAL_TYPE_9F35_KRN(database);
            ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN atc = new ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN(database);
            APPLICATION_USAGE_CONTROL_9F07_KRN        auc = new APPLICATION_USAGE_CONTROL_9F07_KRN(database);

            if ((tt.Value.TerminalType.Code == 0x14 || tt.Value.TerminalType.Code == 0x15 || tt.Value.TerminalType.Code == 0x16) &&
                atc.Value.IsCash)
            #endregion
            {
                #region pre.12
                if (!auc.Value.IsValidAtATMs)
                #endregion
                {
                    #region pre.13
                    tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                    tvr.UpdateDB();
                    return;

                    #endregion
                }
            }
            else
            {
                #region pre.11
                if (!auc.Value.IsValidAtTerminalsOtherThanATMs)
                #endregion
                {
                    #region pre.13
                    tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                    tvr.UpdateDB();
                    return;

                    #endregion
                }
            }

            #region pre.14
            if (database.IsEmpty(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN.Tag))
            {
                tvr.UpdateDB();
                return;
            }
            #endregion

            string tcc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN).Value);
            string icc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN).Value);

            byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];


            #region pre.15
            if (transactionType == (byte)TransactionTypeEnum.CashWithdrawal ||
                transactionType == (byte)TransactionTypeEnum.CashDisbursement)
            #endregion
            {
                #region pre.16
                if (tcc == icc)
                #endregion
                {
                    #region pre.17
                    if (!auc.Value.IsValidForDomesticCashTransactions)
                    #endregion
                    {
                        #region pre.19
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
                else
                {
                    #region pre.18
                    if (!auc.Value.IsValidForInternationalCashTransactions)
                    #endregion
                    {
                        #region pre.19
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
            }

            #region pre.20
            if (transactionType == (byte)TransactionTypeEnum.PurchaseGoodsAndServices ||
                transactionType == (byte)TransactionTypeEnum.PurchaseWithCashback)
            #endregion
            {
                #region pre.21
                if (tcc == icc)
                #endregion
                {
                    #region pre.22
                    if (!(auc.Value.IsValidForDomesticGoods || auc.Value.IsValidForDomesticServices))
                    #endregion
                    {
                        #region pre.24
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
                else
                {
                    #region pre.23
                    if (!(auc.Value.IsValidForInternationalGoods || auc.Value.IsValidForInternationalServices))
                    #endregion
                    {
                        #region pre.24
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
            }

            #region pre.25
            if (database.IsNotPresent(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN.Tag))
            {
                tvr.UpdateDB();
                return;
            }

            if (Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN).Value) == 0)
            {
                tvr.UpdateDB();
                return;
            }
            #endregion

            #region pre.26
            if (tcc == icc)
            #endregion
            {
                #region pre.27
                if (auc.Value.IsDomesticCashbackAllowed)
                {
                    tvr.UpdateDB();
                    return;
                }
                #endregion
            }
            else
            {
                #region pre.28
                if (auc.Value.IsInternationalCashbackAllowed)
                {
                    tvr.UpdateDB();
                    return;
                }
                #endregion
            }

            #region pre.29
            tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
            tvr.UpdateDB();
            #endregion
        }
        public static ACTypeEnum TerminalActionAnalysis(KernelDatabaseBase database)
        {
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            ulong tvrAsNumber = Formatting.ConvertToInt64(tvr.Value.Value);
            ulong tacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_DENIAL_DF8121_KRN2).Value);

            #region taa.1
            if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DENIAL_9F0E_KRN.Tag))
            #endregion
            {
                #region taa.4
                ulong iacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DENIAL_9F0E_KRN).Value);
                if (!(
                        ((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0)
                    )
                #endregion
                {
                    #region taa.5
                    Logger.Log("Declining: !(((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0)):" + ((tacAsNumber | iacAsNumber) & tvrAsNumber));
                    Logger.Log("tacAsNumber: " + tacAsNumber);
                    Logger.Log("iacAsNumber: " + iacAsNumber);
                    int depth = 0;
                    Logger.Log(tvr.ToPrintString(ref depth));
                    return(ACTypeEnum.AAC);

                    #endregion
                }
            }
            else
            {
                #region taa.2
                if (!((tacAsNumber & tvrAsNumber) == 0))
                #endregion
                {
                    #region taa.3
                    Logger.Log("Declining: !((tacAsNumber & tvrAsNumber) == 0)");
                    Logger.Log("tacAsNumber: " + tacAsNumber);
                    int depth = 0;
                    Logger.Log(tvr.ToPrintString(ref depth));
                    return(ACTypeEnum.AAC);

                    #endregion
                }
            }

            #region taa.4.1
            TERMINAL_TYPE_9F35_KRN tt = new TERMINAL_TYPE_9F35_KRN(database);
            if (tt.Value.TerminalType.Code == 0x11 || tt.Value.TerminalType.Code == 0x21 ||
                tt.Value.TerminalType.Code == 0x14 || tt.Value.TerminalType.Code == 0x24 ||
                tt.Value.TerminalType.Code == 0x34)
            #endregion
            {
                #region taa.4.2
                return(ACTypeEnum.ARQC);

                #endregion
            }

            #region taa.6
            if (tt.Value.TerminalType.Code == 0x23 || tt.Value.TerminalType.Code == 0x26 ||
                tt.Value.TerminalType.Code == 0x36 || tt.Value.TerminalType.Code == 0x13 ||
                tt.Value.TerminalType.Code == 0x16)
            #endregion
            {
                #region taa.13
                if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN.Tag))
                #endregion
                {
                    ulong iacDefaultNumber  = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN).Value);
                    ulong taDefaultAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_DEFAULT_DF8120_KRN2).Value);
                    #region taa.16
                    if (((iacDefaultNumber | taDefaultAsNumber) & tvrAsNumber) == 0)
                    #endregion
                    {
                        #region taa.18
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.17
                        Logger.Log("Declining: ((iacDefaultNumber | taDefaultAsNumber) & tvrAsNumber) == 0");
                        Logger.Log("iacDefaultNumber: " + iacDefaultNumber);
                        Logger.Log("taDefaultAsNumber: " + taDefaultAsNumber);
                        int depth = 0;
                        Logger.Log(tvr.ToPrintString(ref depth));
                        return(ACTypeEnum.AAC);

                        #endregion
                    }
                }
                else
                {
                    #region taa.14
                    if (tvrAsNumber == 0)
                    #endregion
                    {
                        #region taa.15
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.17
                        Logger.Log("Declining: tvrAsNumber == 0");
                        int depth = 0;
                        Logger.Log(tvr.ToPrintString(ref depth));
                        return(ACTypeEnum.AAC);

                        #endregion
                    }
                }
            }
            else
            {
                #region taa.7
                if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_ONLINE_9F0F_KRN.Tag))
                #endregion
                {
                    ulong iacOnlineNumber   = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_ONLINE_9F0F_KRN).Value);
                    ulong tacOnlineAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_ONLINE_DF8122_KRN2).Value);
                    #region taa.10
                    if (((tacOnlineAsNumber | iacOnlineNumber) & tvrAsNumber) == 0)
                    #endregion
                    {
                        #region taa.12
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.11
                        return(ACTypeEnum.ARQC);

                        #endregion
                    }
                }
                else
                {
                    #region taa.8
                    if (tvrAsNumber == 0)
                    #endregion
                    {
                        #region taa.9
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.11
                        return(ACTypeEnum.ARQC);

                        #endregion
                    }
                }
            }
        }
        public static bool DoOfflineAuth(KernelDatabaseBase database, KernelQ qManager, PublicKeyCertificateManager pkcm)
        {
            try
            {
                TLV sdadTLV = database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN);
                TLV ssadTLV = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN);
                if (sdadTLV == null && ssadTLV == null)
                {
                    return(false);
                }

                if (database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN) == null)
                {
                    return(false);
                }

                CAPublicKeyCertificate capk = pkcm.GetCAPK(RIDEnum.A000000003, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);
                if (capk == null)
                {
                    return(false);
                }

                TLV aip    = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag);
                int length = database.StaticDataToBeAuthenticated.Serialize().Length;
                if (aip != null && database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_SDA_TAG_LIST_9F4A_KRN3.Tag))
                {
                    if (2048 - length >= aip.Value.Length)
                    {
                        database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN));
                    }
                    else
                    {
                        return(false);
                    }
                }

                if (sdadTLV != null)
                {
                    TLV card = database.Get(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3);
                    if (card == null || card.Value[0] != 0x01) //check version number of fdda
                    {
                        return(false);
                    }

                    byte[]         sdadRaw = database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN).Value;
                    ICCDynamicData iccdd   = VerifySAD.VerifySDAD_K3(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadRaw);
                    if (iccdd == null)
                    {
                        return(false);
                    }

                    VerifySAD.AddSDADDataToDatabase(database, iccdd);
                    return(true);
                }

                if (ssadTLV != null)
                {
                    byte[] sdadRaw  = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN).Value;
                    byte[] authCode = VerifySAD.VerifySSAD(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadRaw);
                    if (authCode == null)
                    {
                        return(false);
                    }
                    TLV dataAuthenticationCode = database.Get(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN);
                    if (dataAuthenticationCode == null)
                    {
                        dataAuthenticationCode = TLV.Create(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN.Tag, authCode);
                    }
                    database.AddToList(dataAuthenticationCode);
                    return(true);
                }

                return(false);
            }
            catch
            {
                return(false);
            }
        }
Exemple #17
0
        public static SignalsEnum InitiateCardActionAnalysis(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            TERMINAL_CAPABILITIES_9F33_KRN         tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);
            TERMINAL_VERIFICATION_RESULTS_95_KRN   tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            //time to get signature data for dda cards, in order to do oda after 1st gen ac
            EMVGenerateACRequest request = null;

            if (aip.Value.CDASupported && tc.Value.CDACapable)
            {
                //cda done after gen ac 1, call gen ac1 now with signature requested
                request = CreateGenAC(database, true);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GEN_AC_1);
            }
            if (aip.Value.DDAsupported && tc.Value.DDACapable)
            {
                #region Book 3 Section 10.3
                //do dda signature request, internal authenticate will do oda once it has the signature
                TLV    ddol = database.Get(EMVTagsEnum.DYNAMIC_DATA_AUTHENTICATION_DATA_OBJECT_LIST_DDOL_9F49_KRN);
                byte[] ddolRelatedData;
                if (ddol == null)
                {
                    TLV unpred = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN);
                    unpred.Val.PackValue(unpred.Val.GetLength());
                    ddolRelatedData = unpred.Value;
                }
                else
                {
                    ddolRelatedData = CommonRoutines.PackRelatedDataTag(database, ddol);
                }
                EMVInternalAuthenticateRequest requestDDA = new EMVInternalAuthenticateRequest(ddolRelatedData);
                cardQManager.EnqueueToInput(new CardRequest(requestDDA, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE);

                #endregion
            }
            if (aip.Value.SDASupported && tc.Value.SDACapable)
            {
                string  aid                 = emvSelectApplicationResponse.GetDFName();
                string  rid                 = aid.Substring(0, 10);
                RIDEnum ridEnum             = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid);
                CAPublicKeyCertificate capk = database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);

                TLV ssadTLV = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN);
                if (capk == null || ssadTLV == null)
                {
                    tvr.Value.SDAFailed = true;
                    tvr.UpdateDB();
                }
                else
                {
                    TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);
                    tsi.Value.OfflineDataAuthenticationWasPerformed = true;
                    tsi.UpdateDB();

                    byte[] sdadRaw  = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN).Value;
                    byte[] authCode = VerifySAD.VerifySSAD(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadRaw);
                    if (authCode == null)
                    {
                        tvr.Value.SDAFailed = true;
                        tvr.UpdateDB();
                    }
                    else
                    {
                        TLV dataAuthenticationCode = database.Get(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN);
                        if (dataAuthenticationCode == null)
                        {
                            dataAuthenticationCode = TLV.Create(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN.Tag, authCode);
                        }
                        else
                        {
                            dataAuthenticationCode.Value = authCode;
                        }
                    }
                }

                //sda done after gen ac 1, call gen ac 1 now with no signature requested
                request = CreateGenAC(database, false);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GEN_AC_1);
            }

            tvr.Value.OfflineDataAuthenticationWasNotPerformed = true;
            tvr.UpdateDB();
            //to do: ceck this, is this correct for a card where no oda is supported
            request = CreateGenAC(database, false);
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            return(SignalsEnum.WAITING_FOR_GEN_AC_1);
        }
Exemple #18
0
        private static SignalsEnum EntryPointACT(KernelDatabaseBase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            foreach (TLV tlv in kernel1Request.InputData)
            {
                if (tlv.Tag.TagLable == EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag)
                {
                    if (!database.ParseAndStoreCardResponse(tlv))
                    {
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
                    }
                }
                else
                {
                    if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT))
                    {
                        database.AddToList(tlv);
                    }
                }
            }

            database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00 }));
            database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber();

            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            cvmr.UpdateDB();

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            tvr.UpdateDB();

            TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            _9f33.UpdateDB();

            database.Initialize(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag);

            DATA_NEEDED_DF8106_KRN2  dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
            DATA_TO_SEND_FF8104_KRN2 dataToSend = new DATA_TO_SEND_FF8104_KRN2(database);

            database.TagsToReadYet.Initialize();

            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2.Tag))
            {
                database.TagsToReadYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2).Children);
            }
            else
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2);
                dataNeeded.UpdateDB();
            }

            bool MissingPDOLDataFlag = false;

            TLV     _9f38    = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN);
            TLVList pdolList = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0);

            foreach (TLV tlv in pdolList)
            {
                if (database.IsEmpty(tlv.Tag.TagLable))
                {
                    MissingPDOLDataFlag = true;
                    dataNeeded.Value.AddTag(tlv.Tag.TagLable);
                }
            }
            dataNeeded.UpdateDB();

            if (!MissingPDOLDataFlag)
            {
                database.Initialize(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2.Tag);
                CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2, pdolList);
                EMVGetProcessingOptionsRequest request = new EMVGetProcessingOptionsRequest(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            }

            TLVList toRemove = new TLVList();

            foreach (TLV tlv in database.TagsToReadYet)
            {
                if (database.IsNotEmpty(tlv.Tag.TagLable))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                    toRemove.AddToList(tlv);
                }
            }

            foreach (TLV tlv in toRemove)
            {
                database.TagsToReadYet.RemoveFromList(tlv);
            }

            dataNeeded.UpdateDB();

            if (MissingPDOLDataFlag)
            {
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();

                sw.Restart();
                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
Exemple #19
0
        public static byte[] OWHF2_8_2(KernelDatabaseBase database, byte[] pd)
        {
            int pl = database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value.Length;

            byte[] dsid = database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value;

            byte[] dspkl = new byte[6];
            byte[] dspkr = new byte[6];

            for (int i = 0; i < 6; i++)
            {
                dspkl[i] = (byte)(((dsid[i] / 16) * 10 + (dsid[i] % 16)) * 2);
                dspkr[i] = (byte)(((dsid[pl - 6 + i] / 16) * 10 + (dsid[pl - 6 + i] % 16)) * 2);
            }

            byte[] oid = new byte[8];
            if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag) &&
                (database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2).Value[0] & 0x80) == 0x80 && // Permanent slot type

                (database.Get(EMVTagsEnum.DS_ODS_INFO_DF62_KRN2).Value[0] & 0x40) == 0x40                   //Volatile slot type
                )
            {
                oid = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
            }
            else
            {
                oid = database.Get(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2).Value;
            }

            byte[] kl = new byte[8];
            byte[] kr = new byte[8];
            for (int i = 0; i < 6; i++)
            {
                kl[i] = dspkl[i];
                kr[i] = dspkr[i];
            }
            for (int i = 6; i < 8; i++)
            {
                kl[i] = oid[i - 2];
                kr[i] = oid[i];
            }

            TripleDES des = TripleDES.Create();

            List <byte[]> keyComps = new List <byte[]>();

            keyComps.Add(kl);
            keyComps.Add(kr);
            keyComps.Add(kl);
            byte[] key = keyComps.SelectMany(x => x).ToArray();

            des.Key     = key;
            des.Mode    = CipherMode.CBC;
            des.Padding = PaddingMode.None;

            byte[] exOrData = XOR(oid, pd);

            MemoryStream ms = new MemoryStream();

            using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(exOrData, 0, exOrData.Length);
            }
            byte[] r = ms.ToArray();
            ms.Dispose();
            return(XOR(r, pd));
        }