Exemplo n.º 1
0
        private static SignalsEnum EntryPointRA(Kernel3Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, CardExceptionManager cardExceptionManager)
        {
            #region 5.2.2.2
            if (!cardResponse.ApduResponse.Succeeded)
            {
                TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database);
                if (cardResponse.ApduResponse.SW1 == 0x69 && cardResponse.ApduResponse.SW2 == 0x84 && ttq.Value.EMVModeSupported)
                {
                    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,
                                                      cardResponse.ApduResponse.SW12,
                                                      L2Enum.STATUS_BYTES,
                                                      L3Enum.NOT_SET));
                }
                if (cardResponse.ApduResponse.SW1 == 0x69 && cardResponse.ApduResponse.SW2 == 0x85)
                {
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.N_A,
                                                      KernelStatusEnum.N_A,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.SELECT_NEXT,
                                                      Kernel2StartEnum.C,
                                                      null,
                                                      KernelMessageidentifierEnum.N_A,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.NOT_SET,
                                                      L3Enum.NOT_SET));
                }
                if (cardResponse.ApduResponse.SW1 == 0x69 && cardResponse.ApduResponse.SW2 == 0x86 && ttq.Value.EMVModeSupported)
                {
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.SEE_PHONE,
                                                      KernelStatusEnum.READY_TO_READ,
                                                      new byte[] { 0x00, 0x00, 0x0D },
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.B,
                                                      true,
                                                      KernelMessageidentifierEnum.SEE_PHONE,
                                                      L1Enum.NOT_SET,
                                                      cardResponse.ApduResponse.SW12,
                                                      L2Enum.STATUS_BYTES,
                                                      L3Enum.NOT_SET));
                }

                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,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));
            }
            #endregion

            bool parsingResult = false;
            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse;
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80)
                {
                    EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse;
                    if (cardResponse.ApduResponse.ResponseData.Length < 6 ||
                        ((cardResponse.ApduResponse.ResponseData.Length - 2) % 4 != 0) ||
                        database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag) ||
                        database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag))
                    {
                        parsingResult = false;
                    }
                    else
                    {
                        database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag, response.GetResponseTags().Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag).Value));
                        database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag, response.GetResponseTags().Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag).Value));
                        parsingResult = true;
                    }
                }
            }

            if (!parsingResult)
            {
                return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
            }
            else
            {
                #region 5.4.1.1
                CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true);
                #endregion

                if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) &&
                    database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag))
                {
                    return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));
                }
                else
                {
                    TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database);
                    if (ttq.Value.MagStripeModeSupported && !ttq.Value.EMVModeSupported)
                    {
                        return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.MAGSTRIPE_NOT_SUPPORTED, L3Enum.NOT_SET));
                    }
                    else
                    {
                        if (!ttq.Value.MagStripeModeSupported && ttq.Value.EMVModeSupported)
                        {
                            return(DoEMVMode(database, qManager, cardQManager, cardResponse, sw, publicKeyCertificateManager, cardExceptionManager));
                        }
                        else
                        {
                            return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.MAGSTRIPE_NOT_SUPPORTED, L3Enum.NOT_SET));
                        }
                    }
                }
            }
        }
        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);
        }