Example #1
0
        private static SignalsEnum EntryPointPIN(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager)
        {
            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);

            //store the pin
            database.AddToList(kernel1Request.InputData.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag));
            string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);

            //online pin
            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline)
            {
                PinProcessing.VerifyOnlinePin(pin, tvr, cvr);
                return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
            }

            //offline pin
            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper ||
                cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper)
            {
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN.Tag));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GET_PIN_TRY_COUNTER);
            }

            throw new EMVProtocolException("Invalid cvr in State_5a_WaitingForGetPinReponse");
        }
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            EMVGetDataResponse response = (EMVGetDataResponse)cardResponse.ApduResponse;

            if (!response.Succeeded)
            {
                cvr.Value.CVMResult = 0x01;//failed
                cvr.UpdateDB();
                return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
            }

            //store the pin try counter value
            database.AddToList(response.GetResponseTag());
            int pinTryCounter = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN).Value);

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper)
            {
                string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);
                if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr))
                {
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }
                //fire off get challenge command
                EMVGetChallengeRequest request = new EMVGetChallengeRequest();
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GET_CHALLENGE);
            }

            if (cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper)
            {
                string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);
                if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr))
                {
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }

                byte[] pinData = PinProcessing.BuildPlainTextPinBlock(pin);

                //fire off verify for plain text pin
                EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Plaintext_PIN, pinData);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));

                return(SignalsEnum.WAITING_FOR_VERIFY);
            }

            throw new EMVProtocolException("Invalid cvr in State_5b_WaitingForGetPinTryCounter");
        }
Example #3
0
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, PublicKeyCertificateManager pkcm, EMVSelectApplicationResponse emvSelectApplicationResponse, Stopwatch sw)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            EMVGetChallengeResponse response = (EMVGetChallengeResponse)cardResponse.ApduResponse;

            if (!response.Succeeded)
            {
                cvr.Value.CVMResult = 0x01;//failed
                cvr.UpdateDB();
                return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
            }

            //store the challenge
            byte[] pinChallenge = response.ResponseData;

            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper)
            {
                string  aid                 = emvSelectApplicationResponse.GetDFName();
                string  rid                 = aid.Substring(0, 10);
                RIDEnum ridEnum             = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid);
                CAPublicKeyCertificate capk = pkcm.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);
                if (capk == null)
                {
                    cvr.Value.CVMResult = 0x01;//failed
                    cvr.UpdateDB();
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }

                string pin      = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);
                byte[] pinBlock = PinProcessing.BuildPlainTextPinBlock(pin);

                //encrypt the pin
                byte[] encipheredPin = PinProcessing.BuildPinVerifyData(database, capk, pinBlock, pinChallenge);
                if (encipheredPin == null)
                {
                    cvr.Value.CVMResult = 0x01;//failed
                    cvr.UpdateDB();
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }

                //fire off verify for enciphered pin
                EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Enciphered_PIN, encipheredPin);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            }


            //verify message for plain text pin fired in waiting for pin response
            return(SignalsEnum.WAITING_FOR_VERIFY);
        }
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            EMVVerifyResponse response = (EMVVerifyResponse)cardResponse.ApduResponse;
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            if (!response.Succeeded)
            {
                cvr.Value.CVMResult = 0x01;//failed
            }
            else
            {
                cvr.Value.CVMResult = 0x02; //successful
            }
            cvr.UpdateDB();

            return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
        }
Example #5
0
        /*
         * S1.1, S1.7 - S1.23
         */
        private static SignalsEnum EntryPointACT(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            #region S1.7
            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);
                    }
                }
            }

            if (database.IsNotEmpty(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN.Tag))
            {
                byte[] languagePrefFromCard       = database.Get(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN).Value;
                byte[] languagePrefFromCardPadded = new byte[8]; //will be padded with trailing 0's
                Array.Copy(languagePrefFromCard, languagePrefFromCardPadded, languagePrefFromCard.Length);
                CommonRoutines.UpdateUserInterfaceRequestData(database, languagePrefFromCardPadded);
            }

            #region S1.8
            if (database.IsNotPresent(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag) || database.IsEmpty(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag))
            {
                return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));
            }
            #endregion

            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
            {
                APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aciVal = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                if (aciVal.Value.SupportForFieldOffDetection)
                {
                    byte[] holdTimeValue = database.GetDefault(EMVTagsEnum.HOLD_TIME_VALUE_DF8130_KRN2).Value;
                    CommonRoutines.UpdateOutcomeParameterSet(database, holdTimeValue[0]);
                }
            }
            #endregion

            #region S1.9
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);
            cvmr.UpdateDB();

            database.ACType = new DS_AC_TYPE_DF8108_KRN2(database);
            database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC;

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            tvr.UpdateDB();

            database.ODAStatus = 0x00;

            database.AddToList(TLV.Create(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2.Tag, new byte[] { 0x00 }));

            //CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2 df8117 = new CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2(database);
            //SECURITY_CAPABILITY_DF811F_KRN2 df811f = new SECURITY_CAPABILITY_DF811F_KRN2(database);

            TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database);
            //_9f33.Value.SetCardDataInputCapabilityValue(df8117);
            //_9f33.Value.SetSecurityCapabilityValue(df811f);
            _9f33.UpdateDB();

            database.StaticDataToBeAuthenticated.Initialize();

            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();

            //REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpv = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2();
            //rcpv.Value.ACTypeEnum = ACTypeEnum.TC;
            //rcpv.UpdateDB();
            #endregion

            #region S1.10
            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();
            }
            #endregion

            #region S1.11
            bool MissingPDOLDataFlag = false;
            #endregion

            #region S1.12
            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();

            #region S1.13 and S1.14
            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));
            }
            #endregion

            #endregion

            #region S1.15
            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);
            }
            #endregion

            #region S1.16
            database.Initialize(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2.Tag);
            database.Initialize(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2.Tag);
            database.Initialize(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2.Tag);

            database.Get(EMVTagsEnum.IDS_STATUS_DF8128_KRN2).Value                 = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value          = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2).Value  = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2).Value = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };

            database.TagsToWriteAfterGenACYet.Initialize();
            database.TagsToWriteBeforeGenACYet.Initialize();

            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            {
                database.TagsToWriteBeforeGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2).Children);
            }
            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            {
                database.TagsToWriteAfterGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2).Children);
            }

            if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2);
            }
            if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2);
            }

            dataNeeded.UpdateDB();
            #endregion

            #region S1.17
            if (database.IsNotEmpty(EMVTagsEnum.DSVN_TERM_DF810D_KRN2.Tag) && database.IsPresent(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2.Tag))
            {
                #region S1.18
                if (database.IsPresent(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2));
                }
                else
                {
                    TLV dsid = TLV.Create(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag);
                    dsid.Val.PackValue(EMVTagsEnum.DS_ID_9F5E_KRN2.DataFormatter.GetMaxLength());
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(dsid);
                }

                if (database.IsPresent(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2));
                }
                else
                {
                    TLV aci = TLV.Create(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag);
                    aci.Val.PackValue(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.DataFormatter.GetMaxLength());
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(aci);
                }
                #endregion

                #region S1.19
                if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
                {
                    APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                    if ((aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_1 || aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_2) &&
                        database.IsNotEmpty(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag))
                    {
                        #region S1.20
                        IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                        ids.Value.IsRead = true;
                        ids.UpdateDB();
                        #endregion
                    }
                }
                #endregion
            }
            #endregion

            #region S1.21
            if (MissingPDOLDataFlag)
            {
                #region S1.22
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion

                #region S1.23
                sw.Restart();
                #endregion

                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }
            #endregion

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
Example #6
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);
        }
Example #7
0
        //X in diagram
        public static bool VerifyOfflinePin(string pin, int pinTryCounter, TERMINAL_VERIFICATION_RESULTS_95_KRN tvr, CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr)
        {
            if (pinTryCounter == 0)
            {
                tvr.Value.PINTryLimitExceeded = true;
                cvr.Value.CVMResult           = 0x01;//failed

                cvr.UpdateDB();
                tvr.UpdateDB();
                return(false);
            }
            if (string.IsNullOrEmpty(pin))
            {
                tvr.Value.PINEntryRequiredPINPadPresentButPINWasNotEntered = true;
                cvr.Value.CVMResult = 0x01;//failed

                cvr.UpdateDB();
                tvr.UpdateDB();
                return(false);
            }

            return(true);
        }
Example #8
0
        //U in diagram
        public static bool VerifyOnlinePin(string pin, TERMINAL_VERIFICATION_RESULTS_95_KRN tvr, CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr)
        {
            if (string.IsNullOrEmpty(pin))
            {
                tvr.Value.PINEntryRequiredPINPadPresentButPINWasNotEntered = true;
                cvr.Value.CVMResult = 0x01;//failed

                cvr.UpdateDB();
                tvr.UpdateDB();
                return(false);
            }
            //cvm and tvr already set correctly in CVM selection
            return(true);
        }
Example #9
0
        private void ProcessCompletion(TerminalProcessingOutcomeEventArgs e, InterFaceType interFaceType)
        {
            TLV      data = null;
            TLV      discretionaryData = null;
            QRDEList qrData            = null;

            try
            {
                long?amount = Convert.ToInt64(totalAmount.Total);

                TerminalProcessingOutcome tpo = e.TerminalProcessingOutcome;
                if (tpo == null)//error occurred, error displayed via Ta_ExceptionOccured
                {
                    return;
                }

                if (tpo is EMVTerminalProcessingOutcome)
                {
                    data = ((EMVTerminalProcessingOutcome)tpo).DataRecord;
                    discretionaryData = ((EMVTerminalProcessingOutcome)tpo).DiscretionaryData;
                    qrData            = ((EMVTerminalProcessingOutcome)tpo).QRData;

                    if (data != null) //error
                    {
                        SetStatusLabel(new UIMessageEventArgs(MessageIdentifiersEnum.RemoveCard, StatusEnum.EndProcessing), interFaceType);

                        //may be a contactless magstripe transaction
                        if (data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag) == null)
                        {
                            txResult = TxResult.ContactlessMagOnline;
                        }
                        else
                        {
                            if (((data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag).Value[0] & 0xC0) >> 6) == (byte)ACTypeEnum.ARQC)
                            {
                                if (interFaceType == InterFaceType.Contact)
                                {
                                    throw new EMVProtocolException("Invalid state for contact, gen ac 2 returned arqc?");
                                }

                                CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(data.Children.Get(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN.Tag));
                                if (cvmr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline)
                                {
                                    ContactlessApp_PinRequest(data.Children);
                                }

                                txResult = TxResult.ContactlessOnline;
                            }
                            if (((data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag).Value[0] & 0xC0) >> 6) == (byte)ACTypeEnum.TC)
                            {
                                txResult = TxResult.Approved;
                            }
                            if (((data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag).Value[0] & 0xC0) >> 6) == (byte)ACTypeEnum.AAC)
                            {
                                txResult = TxResult.Declined;
                            }
                        }
                    }
                    else if (qrData != null)
                    {
                        if (interFaceType == InterFaceType.QRCodeScanned)
                        {
                            txResult = TxResult.QRCodeScanned;
                        }
                        else if (interFaceType == InterFaceType.QRCodeToPoll)
                        {
                            txResult = TxResult.QRCodeToPoll;
                        }
                    }
                    else
                    {
                        txResult = TxResult.Declined;
                    }

                    SetTxFinalResultLabel(txResult.ToString());
                }
                else
                {
                    SetStatusLabel(new UIMessageEventArgs(tpo.UserInterfaceRequest.MessageIdentifier, tpo.UserInterfaceRequest.Status), interFaceType);
                }
            }
            catch (Exception ex)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    UIMessageEventArgs ui = new UIMessageEventArgs(MessageIdentifiersEnum.TryAgain, StatusEnum.ProcessingError)
                    {
                        AdditionalMessage = ex.Message
                    };
                    SetStatusLabel(ui, interFaceType);
                });
            }
            finally
            {
                StopContactPaymentApp();
                StopContactlessPaymentApp();
                StopQRCodePollPaymentApp();

                #region Merge EMV Lists
                if (discretionaryData != null)
                {
                    if (data != null)
                    {
                        data.Children.AddListToList(discretionaryData.Children);
                    }
                }
                #endregion

                TxCompleted?.Invoke(this, new TxCompletedEventArgs(txResult, interFaceType, Optional <TLV> .Create(data), Optional <QRDEList> .Create(qrData)));
            }
        }
        private static SignalsEnum ProcessNextCVM(KernelDatabase database, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN      cvl = new CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN(database);
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            bool goToNextCVM = false;

            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline)
            {
                if (cvr.Value.GetCVMResult() == CVMResult.Failed)
                {
                    goToNextCVM = true;
                }
            }
            else
            {
                //if a previously run CVM failed then state returns here and we try the next CVM
                if (cvr.Value.GetCVMResult() != CVMResult.Success)
                {
                    goToNextCVM = true;
                }
            }

            if (goToNextCVM && database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count)
            {
                //if previous cvm was offline pin, check pin try counter
                if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper)
                {
                    TLV pinTryCounterTLV = database.Get(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN);
                    if (pinTryCounterTLV != null)
                    {
                        ushort pinTryCounter = Formatting.ConvertToInt16(pinTryCounterTLV.Value);
                        if (pinTryCounter > 1) //at this point the pin try counter on the card is 0, we are always 1 behind
                        {
                            qManager.EnqueueToOutput(new KernelPinResponse());
                            return(SignalsEnum.WAITING_FOR_PIN_RESPONSE);
                        }
                    }
                }

                #region Book 3 Section 10.5
                CVMSelection_7_5.CVMSelection(database, new Func <bool>(() => { return(true); }));
                cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);//update after calling cvm selection
                #endregion

                if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper ||
                    cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline)
                {
                    qManager.EnqueueToOutput(new KernelPinResponse());
                    return(SignalsEnum.WAITING_FOR_PIN_RESPONSE);
                }

                if (cvr.Value.GetCVMResult() == CVMResult.Failed)
                {
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }
            }

            if (cvr.Value.GetCVMPerformed() != CVMCode.NoCVMDone)
            {
                TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);
                tsi.Value.CardholderVerificationWasPerformed = true;
                tsi.UpdateDB();
            }

            #region Book 3 Section 10.6
            //Terminal Risk Management
            TLV lcol = database.Get(EMVTagsEnum.LOWER_CONSECUTIVE_OFFLINE_LIMIT_9F14_KRN);
            TLV ucol = database.Get(EMVTagsEnum.UPPER_CONSECUTIVE_OFFLINE_LIMIT_9F23_KRN);
            if (lcol != null && ucol != null)
            {
                EMVGetDataRequest requestATC           = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag));
                EMVGetDataRequest requestLastOnlineATC = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag));
                cardQManager.EnqueueToInput(new CardRequest(requestATC, CardinterfaceServiceRequestEnum.ADPU));
                cardQManager.EnqueueToInput(new CardRequest(requestLastOnlineATC, CardinterfaceServiceRequestEnum.ADPU));
            }

            //Get Floor Limit Data
            if (database.IsEmpty(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag))
            {
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                dataNeeded.Value.Tags.Add(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag);
                dataNeeded.UpdateDB();
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
            }

            qManager.EnqueueToOutput(new KernelTRMResponse());
            return(SignalsEnum.WAITING_FOR_TERMINAL_RISK_MANAGEMENT);

            #endregion
        }