Beispiel #1
0
        private static void Do22_25(KernelDatabaseBase database, CardHolderVerificationRule cvrCurrentlySelected)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            KernelCVMEnum cvmEnum = KernelCVMEnum.N_A;

            #region cvm.22
            cvmEnum = KernelCVMEnum.NO_CVM;
            tvr.Value.CardholderVerificationWasNotSuccessful = true;
            CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
            tvr.UpdateDB();
            #endregion

            #region cvm.23
            if (((byte)cvrCurrentlySelected.CVMConditionCode & 0x3F) == 0x00)
            #endregion
            {
                #region cvm.24
                cvr.Value.CVMPerformed = cvrCurrentlySelected.CVMRule;
                cvr.Value.CVMCondition = (byte)cvrCurrentlySelected.CVMConditionCode;
                cvr.Value.CVMResult    = 0x01;//failed
                #endregion
            }
            else
            {
                #region cvm.25
                cvr.Value.CVMPerformed = 0x3F;
                cvr.Value.CVMCondition = 0x00;
                cvr.Value.CVMResult    = 0x01;//failed
                #endregion
            }
            cvr.UpdateDB();
        }
Beispiel #2
0
        internal static void UpdateOutcomeParameterSet(KernelDatabaseBase database, KernelCVMEnum cvmEnum)
        {
            OUTCOME_PARAMETER_SET_DF8129_KRN2 kops = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database);

            kops.Value.CVM = cvmEnum;
            kops.UpdateDB();
        }
Beispiel #3
0
        private static void Do_CVM_14(KernelDatabaseBase database, CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr)
        {
            KernelCVMEnum cvmEnum = KernelCVMEnum.N_A;

            #region cvm.14
            cvmEnum = KernelCVMEnum.NO_CVM;
            cvr.Value.CVMPerformed = 0x3F; //No CVM performed
            cvr.Value.CVMCondition = 0x00;
            cvr.Value.CVMResult    = 0x01; //failed
            CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
            cvr.UpdateDB();
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            tvr.Value.CardholderVerificationWasNotSuccessful = true;
            tvr.UpdateDB();
            #endregion
        }
Beispiel #4
0
 internal static SignalsEnum PostOutcomeOnly(KernelDatabaseBase database, KernelQ qManager,
                                             Kernel2OutcomeStatusEnum k2OutcomeStatus,
                                             KernelCVMEnum cvmStatus,
                                             bool receipt)
 {
     return(PostOutcome(database, qManager,
                        KernelMessageidentifierEnum.N_A,
                        KernelStatusEnum.N_A,
                        null,
                        k2OutcomeStatus,
                        Kernel2StartEnum.N_A,
                        true,
                        KernelMessageidentifierEnum.N_A,
                        L1Enum.NOT_SET,
                        null,
                        L2Enum.NOT_SET,
                        L3Enum.NOT_SET,
                        ValueQualifierEnum.NONE,
                        null,
                        null,
                        receipt,
                        cvmStatus));
 }
Beispiel #5
0
        /*
         * 14.6
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager)
        {
            #region 14.9
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 14.10
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.STATUS_BYTES, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            #region 14.11
            bool parsingResult = false;
            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                EMVComputeCryptographicChecksumResponse response = cardResponse.ApduResponse as EMVComputeCryptographicChecksumResponse;
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                parsingResult = false;
            }
            #endregion

            #region 14.12
            if (!parsingResult)
            #endregion
            {
                #region 14.13
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            #region 14.12.1
            CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true);
            #endregion

            #region 14.14
            if (database.IsEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) ||
                database.IsEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag))
            #endregion
            {
                #region 14.17
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            long nUN = 0;
            #region 14.15
            if (database.IsNotEmpty(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2.Tag))
            #endregion
            {
                #region 14.16
                if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag) &&
                    (database.IsNotPresent(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag) ||
                     database.IsEmpty(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag)))
                #endregion
                {
                    #region 14.17
                    CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET);
                    return(DoInvalidResponse(database, qManager));

                    #endregion
                }

                #region 14.20
                byte pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1];
                #endregion
                if ((pcii & 0x10) == 0x10)   //OD-CVM verification successful
                {
                    #region 14.24
                    nUN = (nUN + 5) % 10;
                    #endregion
                }
                else
                {
                    #region 14.21
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    #endregion
                    {
                        #region 14.21.1
                        CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET);
                        return(DoInvalidResponse(database, qManager));

                        #endregion
                    }
                    else
                    {
                        #region 14.25
                        nUN = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value);
                        #endregion
                    }
                }

                #region 14.25.1
                database.FailedMSCntr = 0;
                #endregion

                #region 14.26
                TRACK_2_DATA_9F6B_KRN2 t2d = new TRACK_2_DATA_9F6B_KRN2(database);
                ushort t2 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK2_9F67_KRN2).Value);

                TLV       PCVC3_TRACK2_9F65_KRN2       = database.Get(EMVTagsEnum.PCVC3_TRACK2_9F65_KRN2);
                MagBitmap bitmapPCVC3_TRACK2_9F65_KRN2 = new MagBitmap(PCVC3_TRACK2_9F65_KRN2.Value);

                TLV    CVC3_TRACK2_9F61_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2);
                ushort cvc3T2AsShort         = Formatting.ConvertToInt16(CVC3_TRACK2_9F61_KRN2.Value.Reverse().ToArray());

                string q2LeastSigDigits = Convert.ToString(cvc3T2AsShort);
                q2LeastSigDigits            = q2LeastSigDigits.Substring(q2LeastSigDigits.Length - bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount);
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPCVC3_TRACK2_9F65_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), q2LeastSigDigits, bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount, true), false);

                TLV       PUNATC_TRACK2_9F66_KRN2       = database.Get(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2);
                MagBitmap bitmapPUNATC_TRACK2_9F66_KRN2 = new MagBitmap(PUNATC_TRACK2_9F66_KRN2.Value);
                uint      unpredInt    = Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2).Value.Reverse().ToArray());
                string    unpredString = Convert.ToString(unpredInt);
                unpredString = unpredString.Substring(unpredString.Length - database.NUN);
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), unpredString, database.NUN, true), false);

                if (t2 != 0)
                {
                    TLV    APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN);
                    uint   atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray());
                    string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort);
                    atcAsShortLeastSigDigits    = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t2);
                    t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t2, false), false);
                }
                #endregion

                #region 14.27
                StringBuilder dd = new StringBuilder(Formatting.BcdToString(t2d.Value.DiscretionaryData));
                dd[dd.Length - 1]           = Convert.ToString(nUN)[0];
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(dd.ToString(), false);
                #endregion

                t2d.Serialize(); //reserialize in case the length of discretionary data changed
                t2d.UpdateDB();

                #region 14.28
                if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag))
                #endregion
                {
                    #region 14.29
                    TRACK_1_DATA_56_KRN2 t1d = new TRACK_1_DATA_56_KRN2(database);
                    ushort t1 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK1_9F64_KRN2).Value);

                    TLV       PCVC3_TRACK1_9F62_KRN2       = database.Get(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2);
                    MagBitmap bitmapPCVC3_TRACK1_9F62_KRN2 = new MagBitmap(PCVC3_TRACK1_9F62_KRN2.Value);

                    TLV    CVC3_TRACK1_9F60_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2);
                    ushort cvc3T1AsShort         = Formatting.ConvertToInt16(CVC3_TRACK1_9F60_KRN2.Value.Reverse().ToArray());

                    string q1LeastSigDigits = Convert.ToString(cvc3T1AsShort);
                    q1LeastSigDigits            = q1LeastSigDigits.Substring(q1LeastSigDigits.Length - bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount);
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPCVC3_TRACK1_9F62_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), q1LeastSigDigits, bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount, true));

                    TLV       PUNATC_TRACK1_9F63_KRN2       = database.Get(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2);
                    MagBitmap bitmapPUNATC_TRACK1_9F63_KRN2 = new MagBitmap(PUNATC_TRACK1_9F63_KRN2.Value);
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), unpredString, database.NUN, true));

                    if (t2 != 0)
                    {
                        TLV    APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN);
                        uint   atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray());
                        string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort);
                        atcAsShortLeastSigDigits    = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t1);
                        t2d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t1, false));
                    }
                    #endregion

                    #region 14.30
                    StringBuilder dd1 = new StringBuilder(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData));
                    dd1[dd1.Length - 1]         = Convert.ToString(nUN)[0];
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(dd1.ToString());
                    #endregion

                    t1d.Serialize(); //reserialize in case the length of discretionary data changed
                    t1d.UpdateDB();
                }

                #region 14.32
                Kernel2OutcomeStatusEnum k2OutcomeStatus = Kernel2OutcomeStatusEnum.ONLINE_REQUEST;
                KernelCVMEnum            cvmEnum         = KernelCVMEnum.N_A;
                bool receipt = false;

                pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1];
                if ((pcii & 0x10) == 0x10)   //OD-CVM verification successful
                #endregion
                {
                    #region 14.34
                    cvmEnum = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    {
                        receipt = true;
                    }
                    #endregion
                }
                else
                {
                    #region 14.33
                    cvmEnum = KernelCVMEnum.NO_CVM;
                    #endregion
                }
                CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                CommonRoutines.CreateMSDataRecord(database);
                return(CommonRoutines.PostOutcomeOnly(database, qManager, k2OutcomeStatus, cvmEnum, receipt));
            }
            else
            {
                #region 14.19.1
                if (((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x00030F) != 0x000000)
                #endregion
                {
                    KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED;
                    KernelStatusEnum            k2Status            = KernelStatusEnum.READY_TO_READ;
                    byte[] holdTime = new byte[] { 0x00, 0x00, 0x00 };

                    #region 14.22
                    PHONE_MESSAGE_TABLE_DF8131_KRN2 pmt = (PHONE_MESSAGE_TABLE_DF8131_KRN2)database.GetDefault(EMVTagsEnum.PHONE_MESSAGE_TABLE_DF8131_KRN2);
                    foreach (PhoneMessageTableEntry_DF8131 entry in pmt.Value.Entries)
                    {
                        int pcii     = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value);
                        int pciMask  = (int)Formatting.ConvertToInt32(entry.PCIIMask);
                        int pciValue = (int)Formatting.ConvertToInt32(entry.PCIIValue);
                        if ((pciMask & pcii) == pciValue)
                        {
                            k2MessageIdentifier = entry.MessageIdentifier;
                            k2Status            = entry.Status;
                            holdTime            = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;
                            break;
                        }
                    }
                    #endregion

                    #region 14.21.1
                    int waitTime = ((2 ^ database.FailedMSCntr) * 300);
                    Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait();
                    #endregion

                    #region 14.21.2
                    database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5);
                    #endregion

                    #region 14.23
                    CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                    CommonRoutines.CreateMSDataRecord(database);

                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      k2MessageIdentifier,
                                                      k2Status,
                                                      holdTime,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.B,
                                                      false,
                                                      KernelMessageidentifierEnum.N_A,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.NOT_SET,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    #region 14.19.2.1
                    int waitTime = ((2 ^ database.FailedMSCntr) * 300);
                    Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait();
                    #endregion
                    #region 14.19.2.2
                    database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5);
                    #endregion

                    #region 14.19.3
                    CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                    CommonRoutines.CreateMSDataRecord(database);

                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.DECLINED,
                                                      KernelStatusEnum.NOT_READY,
                                                      database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.N_A,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.NOT_SET,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
            }
        }
        private static SignalsEnum EntryPointRA(Kernel1Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.N_A,
                                                  KernelStatusEnum.N_A,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));
            }

            bool parsingResult             = false;
            EMVGenerateACResponse response = cardResponse.ApduResponse as EMVGenerateACResponse;

            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                if (cardResponse.ApduResponse.ResponseData.Length < 11 ||
                    cardResponse.ApduResponse.ResponseData.Length > 43 ||
                    database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag) ||
                    database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) ||
                    database.IsNotEmpty(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag) ||
                    (cardResponse.ApduResponse.ResponseData.Length > 11 &&
                     database.IsNotEmpty(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag))
                    )
                {
                    parsingResult = false;
                }
                else
                {
                    database.AddToList(TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag, response.CryptogramInformationData.Value));
                    database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag, response.ApplicationTransactionCounter.Value));
                    database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag, response.ApplicationCryptogram.Value));
                    database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag, response.IssuerApplicationData.Value));
                    parsingResult = true;
                }
            }

            if (!parsingResult)
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.N_A,
                                                  KernelStatusEnum.N_A,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.PARSING_ERROR,
                                                  L3Enum.NOT_SET));
            }

            if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag)))
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.N_A,
                                                  KernelStatusEnum.N_A,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_MISSING,
                                                  L3Enum.NOT_SET));
            }

            #region 3.5.2.2
            TLV  cidTLV = database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN);
            byte cid    = cidTLV.Value[0];
            cid = (byte)(cid >> 6);
            if (cid != (byte)ACTypeEnum.ARQC)
            {
                #region 3.10.3.1
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.PROCESSING_ERROR,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_ERROR,
                                                  L3Enum.NOT_SET));

                #endregion
            }
            #endregion

            #region 3.6.1.1
            CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true);
            #endregion

            SignalsEnum result = DoProcessingRestrictions(database, qManager);
            if (result != SignalsEnum.NONE)
            {
                return(result);
            }

            #region 3.9
            KernelCVMEnum cvm = KernelCVMEnum.N_A;
            if (database.ProcessingIndicatorsForSelected.ReaderCVMRequiredLimitExceeded)
            {
                DoCVMProcessing(database, (ACTypeEnum)GetEnum(typeof(ACTypeEnum), cid));
                OUTCOME_PARAMETER_SET_DF8129_KRN2 ops = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database);
                if (ops.Value.CVM == KernelCVMEnum.NO_CVM)
                {
                    #region 3.10.3.1
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      KernelStatusEnum.PROCESSING_ERROR,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                cvm = ops.Value.CVM;
            }
            #endregion

            #region 3.9.2
            CommonRoutines.CreateEMVDataRecord(database);
            CommonRoutines.CreateEMVDiscretionaryData(database);
            return(CommonRoutines.PostOutcome(database, qManager,
                                              KernelMessageidentifierEnum.AUTHORISING_PLEASE_WAIT,
                                              KernelStatusEnum.NOT_READY,
                                              null,
                                              Kernel2OutcomeStatusEnum.ONLINE_REQUEST,
                                              Kernel2StartEnum.N_A,
                                              true,
                                              KernelMessageidentifierEnum.N_A,
                                              L1Enum.NOT_SET,
                                              null,
                                              L2Enum.NOT_SET,
                                              L3Enum.NOT_SET,
                                              ValueQualifierEnum.NONE,
                                              null,
                                              null,
                                              false,
                                              cvm));

            #endregion
        }
Beispiel #7
0
        public static void CVMSelection(KernelDatabaseBase database, Func <bool> kernelSupportedCallback)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmResults = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            //#region support for Refunds pg 177
            //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];
            //if (transactionType == (byte)TransactionTypeEnum.Refund)
            //{
            //    Do_CVM_14(database, cvmResults);
            //    return;
            //}
            //#endregion

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            KernelCVMEnum cvmEnum = KernelCVMEnum.N_A;

            CardHolderVerificationRule cvrCurrentlySelected;

            if (aip.Value.OnDeviceCardholderVerificationIsSupported && kernelSupportedCallback.Invoke())
            {
                #region cvm.2
                long aa    = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                long rcvml = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CVM_REQUIRED_LIMIT_DF8126_KRN2).Value);
                if (aa > rcvml)
                #endregion
                {
                    #region cvm.4
                    cvmEnum = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                    cvmResults.Value.CVMPerformed = 0x01; //on-device cardholder verification performed
                    cvmResults.Value.CVMCondition = 0x00;
                    cvmResults.Value.CVMResult    = 0x02; //successful
                    CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                    cvmResults.UpdateDB();
                    return;

                    #endregion
                }
                else
                {
                    #region cvm.3
                    cvmEnum = KernelCVMEnum.NO_CVM;
                    cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed
                    cvmResults.Value.CVMCondition = 0x00;
                    cvmResults.Value.CVMResult    = 0x02; //successful
                    CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                    cvmResults.UpdateDB();
                    return;

                    #endregion
                }
            }

            #region cvm.5
            if (!aip.Value.CardholderVerificationIsSupported)
            #endregion
            {
                #region cvm.6
                cvmEnum = KernelCVMEnum.NO_CVM;
                cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed
                cvmResults.Value.CVMCondition = 0x00;
                cvmResults.Value.CVMResult    = 0x00; //unknown
                CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                cvmResults.UpdateDB();
                return;

                #endregion
            }

            #region cvm.7
            if (database.IsNotPresent(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN.Tag) ||
                database.IsEmpty(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN.Tag))
            #endregion
            {
                #region cvm.8
                cvmEnum = KernelCVMEnum.NO_CVM;
                cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed
                cvmResults.Value.CVMCondition = 0x00;
                cvmResults.Value.CVMResult    = 0x00; //unknown
                CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                cvmResults.UpdateDB();
                tvr.Value.ICCDataMissing = true;
                tvr.UpdateDB();
                return;

                #endregion
            }

            #region cvm.9
            CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN cvl = new CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN(database);
            #endregion

BackToIterate:
            CVMListIterationReturn result;
            do
            {
                cvrCurrentlySelected = cvl.Value.CardHolderVerificationRules[database.CVMCurrentlySelectedCounter];
                #region cvm.10 cvm.11
                result = IterateCVM(database, cvrCurrentlySelected, cvl.Value.AmountX, cvl.Value.AmountY);
                #endregion
                database.CVMCurrentlySelectedCounter++;
                #region cvm.12 cvm.13
            } while (database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count &&
                     result != CVMListIterationReturn.ConditionsMet);
            #endregion

            if (result != CVMListIterationReturn.ConditionsMet)
            {
                Do_CVM_14(database, cvmResults);
                return;
            }

            #region cvm.15
            if (!cvrCurrentlySelected.IsCVMRecognised())
            #endregion
            {
                #region cvm.16
                tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.UnrecognisedCVM = true;
                tvr.UpdateDB();
                #endregion
            }
            else
            {
                #region cvm.17
                if (cvrCurrentlySelected.IsSupported(database) && cvrCurrentlySelected.GetCVMCode() != (byte)CVMCode.FailCVMProcessing)
                #endregion
                {
                    #region cvm.18 and from EMV Book 3 Section 10.5
                    switch ((byte)(cvrCurrentlySelected.CVMRule & 0x3F))
                    {
                    //Pin processing (U,X,Z) continues in PinProcessing Procedure after CVM Selection
                    case (byte)CVMCode.EncipheredPINVerifiedOnline:
                        cvmEnum = KernelCVMEnum.ONLINE_PIN;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        tvr.Value.OnlinePINEntered = true;
                        break;

                    case (byte)CVMCode.EncipheredPINVerificationPerformedByICC:
                    case (byte)CVMCode.PlaintextPINVerificationPerformedByICC:
                        cvmEnum = KernelCVMEnum.OFFLINE_PIN;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        break;

                    case (byte)CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper:
                    case (byte)CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper:
                        cvmEnum = KernelCVMEnum.COMBO;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        break;

                    //V in diagram
                    case (byte)CVMCode.Signature_Paper:
                        cvmEnum = KernelCVMEnum.OBTAIN_SIGNATURE;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        CommonRoutines.UpdateOutcomeParameterSet(database, true);
                        break;

                    //W in diagram
                    case (byte)CVMCode.NoCVMRequired:
                        cvmEnum = KernelCVMEnum.NO_CVM;
                        cvmResults.Value.CVMResult = 0x02;     //successful
                        break;

                    case (byte)CVMCode.RFU:
                        cvmEnum = KernelCVMEnum.N_A;
                        tvr.Value.UnrecognisedCVM  = true;
                        cvmResults.Value.CVMResult = 0x01;     //failed
                        break;

                    default:
                        goto BackToIterate;
                    }
                    #endregion
                    cvmResults.Value.CVMPerformed = cvrCurrentlySelected.CVMRule;
                    cvmResults.Value.CVMCondition = (byte)cvrCurrentlySelected.CVMConditionCode;
                    cvmResults.UpdateDB();
                    int depth = 0;
                    Logger.Log(cvmResults.ToPrintString(ref depth));
                    CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                    tvr.UpdateDB();
                    return;
                }
            }

            #region cvm.19
            if (((byte)cvrCurrentlySelected.CVMConditionCode & 0x40) == (byte)CVMFailureCondition.ApplySucceedingCVRuleIfThisCVMIsUnsuccessful)
            #endregion
            {
                #region cvm.20
                if (database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count)
                #endregion
                {
                    #region cvm.10
                    goto BackToIterate;
                    #endregion
                }
                else
                {
                    Do22_25(database, cvrCurrentlySelected);
                    return;
                }
            }
            else
            {
                Do22_25(database, cvrCurrentlySelected);
                return;
            }
        }
        public static SignalsEnum DoCommonProcessing(string source, KernelDatabaseBase databaseIn, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager pkcm, CardExceptionManager cardExceptionManager)
        {
            Kernel3Database database = (Kernel3Database)databaseIn;

            if (database.NextCommandEnum == NextCommandEnum.READ_RECORD)
            {
                DoDEKIfNeeded(database, qManager);
                return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
            }

            DoDEKIfNeeded(database, qManager);

            //ReaderContactlessTransactionLimit exceeded
            if (database.ProcessingIndicatorsForSelected.ContactlessApplicationNotAllowed)
            {
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET));
            }

            #region 5.4.3.1
            TLV cidTLV = database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN);
            if (cidTLV == null)
            {
                cidTLV = TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag);
                cidTLV.Val.PackValue(cidTLV.Val.DataFormatter.GetMaxLength());
                byte iad = database.Get(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN).Value[4];
                Formatting.SetBitPosition(ref cidTLV.Value[0], Formatting.GetBitPosition(iad, 6), 8);
                Formatting.SetBitPosition(ref cidTLV.Value[0], Formatting.GetBitPosition(iad, 5), 7);
                database.AddToList(cidTLV);
            }
            #endregion

            #region 5.4.3.2
            byte cid = cidTLV.Value[0];
            cid = (byte)(cid >> 6);
            TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database);
            if (cid == (byte)ACTypeEnum.AAC)
            {
                database.DeclineRequiredByReaderIndicator = true;
            }
            if (cid == (byte)ACTypeEnum.ARQC || ttq.Value.OnlineCryptogramRequired)
            {
                database.OnlineRequiredByReaderIndicator = true;
            }
            if (cid != (byte)ACTypeEnum.AAC && cid != (byte)ACTypeEnum.ARQC && cid != (byte)ACTypeEnum.TC)
            {
                database.DeclineRequiredByReaderIndicator = true;
            }
            #endregion

            #region 5.4.2.1
            if (!database.DeclineRequiredByReaderIndicator)
            {
                if (!CheckMandatoryFields(database, pkcm))
                {
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      KernelStatusEnum.PROCESSING_ERROR,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));
                }
            }
            #endregion

            if (!database.DeclineRequiredByReaderIndicator && !database.OnlineRequiredByReaderIndicator)
            {
                #region 5.5.1.1 to 5.5.1.5
                SignalsEnum result = DoProcessingRestrictions(database, qManager, cardExceptionManager);
                if (result != SignalsEnum.NONE)
                {
                    return(result);
                }
                #endregion

                #region  5.6.1.1, 5.6.1.2 and 5.6.2.1, 5.6.2.1
                if (!DoOfflineAuth(database, qManager, pkcm))
                #endregion
                {
                    CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);
                    if (ctq.Value.GoOnlineIfOfflineDataAuthenticationFailsAndReaderIsOnlineCapable && !database.ProcessingIndicatorsForSelected.TTQ.Value.OfflineOnlyReader)
                    {
                        database.OnlineRequiredByReaderIndicator = true;
                    }
                    else if (ctq.Value.SwitchInterfaceIfOfflineDataAuthenticationFailsAndReaderSupportsVIS && database.ProcessingIndicatorsForSelected.TTQ.Value.EMVContactChipSupported)
                    {
                        return(CommonRoutines.PostOutcome(database, qManager,
                                                          KernelMessageidentifierEnum.INSERT_CARD,
                                                          KernelStatusEnum.PROCESSING_ERROR,
                                                          null,
                                                          Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE,
                                                          Kernel2StartEnum.N_A,
                                                          true,
                                                          KernelMessageidentifierEnum.INSERT_CARD,
                                                          L1Enum.NOT_SET,
                                                          null,
                                                          L2Enum.TERMINAL_DATA_ERROR,
                                                          L3Enum.NOT_SET));
                    }
                    else
                    {
                        database.DeclineRequiredByReaderIndicator = true;
                    }
                }
            }


            #region 5.7.1.1, 5.7.1.2, 5.7.1.3
            KernelCVMEnum cvm = KernelCVMEnum.N_A;
            if (!database.DeclineRequiredByReaderIndicator)
            {
                cvm = DoCVMProcessing(database, (ACTypeEnum)Formatting.GetEnum(typeof(ACTypeEnum), cid));
                if (cvm == KernelCVMEnum.NO_CVM && ttq.Value.CVMRequired)
                {
                    database.DeclineRequiredByReaderIndicator = true;
                }
            }
            #endregion

            #region 4.3.1.1
            byte[]             currencyCode = null;
            byte[]             balance      = null;
            ValueQualifierEnum vq           = ValueQualifierEnum.NONE;
            if (database.Kernel3Configuration.DisplayAvailableSpendingAmount)
            {
                TLV balanceTLV = database.Get(EMVTagsEnum.AVAILABLE_OFFLINE_SPENDING_AMOUNT_AOSA_9F5D_KRN3);
                if (balanceTLV != null)
                {
                    vq           = ValueQualifierEnum.BALANCE;
                    balance      = balanceTLV.Value;
                    currencyCode = database.Get(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN).Value;
                }
            }
            #endregion

            //#region support for Refunds
            //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];
            //if (transactionType == (byte)TransactionTypeEnum.Refund)
            //    database.DeclineRequiredByReaderIndicator = true;
            //#endregion

            #region 5.8.1.1
            if (database.OnlineRequiredByReaderIndicator && !database.DeclineRequiredByReaderIndicator)
            {
                CommonRoutines.CreateEMVDataRecord(database);
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.AUTHORISING_PLEASE_WAIT,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.ONLINE_REQUEST,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.N_A,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.NOT_SET,
                                                  L3Enum.NOT_SET,
                                                  vq,
                                                  balance,
                                                  currencyCode,
                                                  false,
                                                  cvm));
            }
            #endregion

            #region 5.9.1.1
            if (!database.OnlineRequiredByReaderIndicator && !database.DeclineRequiredByReaderIndicator)
            {
                CommonRoutines.CreateEMVDataRecord(database);
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  cvm == KernelCVMEnum.OBTAIN_SIGNATURE ? KernelMessageidentifierEnum.APPROVED_SIGN : KernelMessageidentifierEnum.APPROVED,
                                                  KernelStatusEnum.READY_TO_READ,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.APPROVED,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.N_A,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.NOT_SET,
                                                  L3Enum.NOT_SET,
                                                  vq,
                                                  balance,
                                                  currencyCode,
                                                  false,
                                                  cvm));
            }
            #endregion

            CommonRoutines.CreateEMVDiscretionaryData(database);
            //#region support for Refunds
            //if (transactionType == (byte)TransactionTypeEnum.Refund)
            //#endregion
            //{
            //    //CommonRoutines.PostUIOnly(database, qManager, Kernel1MessageidentifierEnum.CLEAR_DISPLAY, Kernel1StatusEnum.N_A, true, new byte[] { 0x00, 0x00, 0x00 });

            //    CommonRoutines.CreateEMVDataRecord(database);
            //    return CommonRoutines.PostOutcome(database, qManager,
            //        KernelMessageidentifierEnum.N_A,
            //        KernelStatusEnum.N_A,
            //        null,
            //        Kernel2OutcomeStatusEnum.END_APPLICATION,
            //        Kernel2StartEnum.N_A,
            //        true,
            //        KernelMessageidentifierEnum.N_A,
            //        L1Enum.NOT_SET,
            //        null,
            //        L2Enum.NOT_SET,
            //        L3Enum.NOT_SET,
            //        ValueQualifierEnum.NONE,
            //        null,
            //        null,
            //        false,
            //        cvm);
            //}
            //else
            //{
            #region 5.9.1.2
            return(CommonRoutines.PostOutcome(database, qManager,
                                              KernelMessageidentifierEnum.DECLINED,
                                              KernelStatusEnum.READY_TO_READ,
                                              null,
                                              Kernel2OutcomeStatusEnum.DECLINED,
                                              Kernel2StartEnum.N_A,
                                              true,
                                              KernelMessageidentifierEnum.N_A,
                                              L1Enum.NOT_SET,
                                              null,
                                              L2Enum.NOT_SET,
                                              L3Enum.NOT_SET,
                                              vq,
                                              balance,
                                              currencyCode,
                                              false,
                                              cvm));

            #endregion
            //}
        }
        public static KernelCVMEnum DoCVMProcessing(Kernel3Database database, ACTypeEnum acType)
        {
            KernelCVMEnum cvm = KernelCVMEnum.N_A;
            TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database);

            if (!database.DeclineRequiredByReaderIndicator)
            {
                #region 5.7.1.1
                if (database.IsEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag) && ttq.Value.CVMRequired)
                #endregion
                {
                    if (ttq.Value.SignatureSupported)
                    {
                        cvm = KernelCVMEnum.OBTAIN_SIGNATURE;
                    }
                    else if (ttq.Value.ConsumerDeviceCVMSupported && ttq.Value.OnlinePINSupported)
                    {
                        cvm = KernelCVMEnum.ONLINE_PIN;
                    }
                    else// only ttq.Value.ConsumerDeviceCVMSupported
                    {
                        database.DeclineRequiredByReaderIndicator = true;
                    }
                }
                if (database.IsNotEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag))
                {
                    #region 5.7.1.2
                    CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);
                    if (ctq.Value.OnlinePINRequired && ttq.Value.OnlinePINSupported)
                    {
                        cvm = KernelCVMEnum.ONLINE_PIN;
                        database.OnlineRequiredByReaderIndicator = true;
                    }
                    else
                    {
                        if (ctq.Value.ConsumerDeviceCVMPerformed)
                        {
                            TLV card = database.Get(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3);
                            if (card != null)
                            {
                                byte[] card67 = new byte[2];
                                byte[] ctq12  = new byte[2];
                                Array.Copy(card.Value, 6, card67, 0, 2);
                                Array.Copy(ctq.Value.Value, 0, ctq12, 0, 2);
                                if (Formatting.ByteArrayToHexString(card67) == Formatting.ByteArrayToHexString(ctq12))
                                {
                                    cvm = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                                }
                                else
                                {
                                    database.DeclineRequiredByReaderIndicator = true;
                                }
                            }
                            else
                            {
                                if (acType == ACTypeEnum.ARQC)
                                {
                                    cvm = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                                }
                                else
                                {
                                    database.DeclineRequiredByReaderIndicator = true;
                                }
                            }
                        }
                    }

                    if (!ctq.Value.OnlinePINRequired && !ctq.Value.ConsumerDeviceCVMPerformed)
                    {
                        if (ttq.Value.SignatureSupported && ctq.Value.SignatureRequired)
                        {
                            cvm = KernelCVMEnum.OBTAIN_SIGNATURE;
                        }
                    }

                    #endregion
                }
            }
            if (cvm == KernelCVMEnum.N_A && ttq.Value.CVMRequired)
            {
                cvm = KernelCVMEnum.NO_CVM;
                database.DeclineRequiredByReaderIndicator = true;
            }
            if (cvm == KernelCVMEnum.N_A)
            {
                cvm = KernelCVMEnum.NO_CVM;
            }

            return(cvm);
        }
Beispiel #10
0
        internal static SignalsEnum PostOutcome(KernelDatabaseBase database, KernelQ qManager,
                                                KernelMessageidentifierEnum uiMessage,
                                                KernelStatusEnum uiStatus,
                                                byte[] holdTime,
                                                Kernel2OutcomeStatusEnum status,
                                                Kernel2StartEnum start,
                                                bool?isUIRequestOnOutcomePresent,
                                                KernelMessageidentifierEnum messageOnError,
                                                L1Enum l1Enum,
                                                byte[] SW12,
                                                L2Enum l2Enum,
                                                L3Enum l3Enum,
                                                ValueQualifierEnum valueQualifierEnum,
                                                byte[] valueQualifier,
                                                byte[] currencyCode,
                                                bool receipt,
                                                KernelCVMEnum cvmStatus)
        {
            if (messageOnError != KernelMessageidentifierEnum.N_A || l1Enum != L1Enum.NOT_SET || l2Enum != L2Enum.NOT_SET || l3Enum != L3Enum.NOT_SET)
            {
                TLV disc = InitializeDiscretionaryData(database);

                ERROR_INDICATION_DF8115_KRN2 kei = new ERROR_INDICATION_DF8115_KRN2(database);
                kei.Value.MsgOnError = messageOnError;
                kei.Value.L1Enum     = l1Enum;
                kei.Value.L2Enum     = l2Enum;
                kei.Value.L3Enum     = l3Enum;
                if (SW12 != null)
                {
                    kei.Value.SW12 = SW12;
                }
                kei.UpdateDB();

                disc.Children.AddToList(kei);
                disc.Serialize();
            }

            if (uiMessage != KernelMessageidentifierEnum.N_A || uiStatus != KernelStatusEnum.N_A)
            {
                USER_INTERFACE_REQUEST_DATA_DF8116_KRN2 uird = new USER_INTERFACE_REQUEST_DATA_DF8116_KRN2(database);
                uird.Value.KernelMessageidentifierEnum = uiMessage;
                uird.Value.KernelStatusEnum            = uiStatus;
                if (holdTime == null)
                {
                    TLV holdTimeTLV = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2);
                    if (holdTimeTLV != null)
                    {
                        holdTime = holdTimeTLV.Value;
                    }
                    else
                    {
                        holdTime = new byte[] { 0x00, 0x00, 0x00 }
                    };
                }
                uird.Value.HoldTime = holdTime;
                if (valueQualifier != null)
                {
                    uird.Value.ValueQualifier = valueQualifier;
                }
                uird.Value.ValueQualifierEnum = valueQualifierEnum;
                if (currencyCode != null)
                {
                    uird.Value.CurrencyCode = currencyCode;
                }
                uird.UpdateDB();
            }

            OUTCOME_PARAMETER_SET_DF8129_KRN2 kops = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database);

            kops.Value.Status = status;
            kops.Value.Start  = start;
            if (isUIRequestOnOutcomePresent == null)
            {
                kops.Value.UIRequestOnOutcomePresent = isUIRequestOnOutcomePresent == false;
                kops.Value.UIRequestOnRestartPresent = isUIRequestOnOutcomePresent == false;
            }
            else
            {
                kops.Value.UIRequestOnOutcomePresent = isUIRequestOnOutcomePresent == true ? true : false;
                kops.Value.UIRequestOnRestartPresent = isUIRequestOnOutcomePresent == true ? false : true;
            }
            kops.Value.DataRecordPresent        = database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2) != null ? true : false;
            kops.Value.DiscretionaryDataPresent = database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2) != null ? true : false;
            //kops.Value.Receipt = receipt;
            kops.Value.CVM = cvmStatus;
            kops.UpdateDB();

            qManager.EnqueueToOutput(new KernelOUTResponse(
                                         database.Get(EMVTagsEnum.OUTCOME_PARAMETER_SET_DF8129_KRN2),
                                         database.Get(EMVTagsEnum.ERROR_INDICATION_DF8115_KRN2),
                                         database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2),
                                         database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2),
                                         database.Get(EMVTagsEnum.USER_INTERFACE_REQUEST_DATA_DF8116_KRN2)));

            return(SignalsEnum.STOP);
        }