コード例 #1
0
        public static Apdu GetClearApdu(Apdu smApdu, BSO encKey, BSO sigKey, BSO outEncKey, BSO outSigKey, byte[] challenge)
        {
            if (sigKey == null && encKey == null)
            {
                Apdu apdu2 = new Apdu();
                apdu2.CLA   = 0;
                apdu2.INS   = smApdu.INS;
                apdu2.P1    = smApdu.P1;
                apdu2.P2    = smApdu.P2;
                apdu2.Data  = smApdu.Data;
                apdu2.LE    = smApdu.LE;
                apdu2.UseLE = smApdu.UseLE;
                return(apdu2);
            }
            TLV       tlv              = new TLV(smApdu.Data);
            ByteArray ClearData        = null;
            var       NetLEObject      = tlv[0x96];
            var       CypherTextObject = tlv[0x87];
            var       PlainTextObject  = tlv[0x81];
            var       MACObject        = tlv[0x8E];

            if (CypherTextObject != null && PlainTextObject != null)
            {
                throw new ISO7816Exception(Error.DataFieldNotValid);
            }

            if ((encKey != null && CypherTextObject == null) ||
                (encKey == null && CypherTextObject != null))
            {
                throw new ISO7816Exception(Error.ConditionsOfUseNotSatisfied);
            }

            if ((sigKey != null && MACObject == null) ||
                (sigKey == null && MACObject != null))
            {
                throw new ISO7816Exception(Error.ConditionsOfUseNotSatisfied);
            }

            if (PlainTextObject != null)
            {
                ClearData = PlainTextObject;
            }

            if (encKey != null && CypherTextObject != null)
            {
                ClearData = ByteArray.RemoveISOPad(CardHandler.decrypt3DES(encKey.Data, new ByteArray(CypherTextObject).Sub(1)));
            }

            if (sigKey != null && MACObject != null)
            {
                if (challenge == null)
                {
                    throw new ISO7816Exception(Error.ConditionsOfUseNotSatisfied);
                }
                var HeaderBlock = new ByteArray(challenge);
                HeaderBlock = HeaderBlock.Append(new ByteArray(smApdu.GetBytes()).Left(4));
                HeaderBlock = ByteArray.ANSIPad(HeaderBlock);
                byte[] toMAC = null;
                if (CypherTextObject != null && CypherTextObject.Length != 0)
                {
                    TLV ptb = new TLV();
                    ptb[0x87] = CypherTextObject;
                    toMAC     = ptb.GetBytes();
                }
                else
                {
                    if (ClearData != null && ClearData.Size != 0)
                    {
                        TLV ptb = new TLV();
                        ptb[0x81] = ClearData;
                        toMAC     = ptb.GetBytes();
                    }
                    else
                    {
                        if (PlainTextObject != null)
                        {
                            throw new ISO7816Exception(Error.SMDataObjectsIncorrect);
                        }
                        toMAC = new byte[0];
                    }
                }
                HeaderBlock = HeaderBlock.Append(ByteArray.ANSIPad(toMAC));
                var mac = CardHandler.getMAC(sigKey.Data, HeaderBlock);
                if (!new ByteArray(mac).CompareByteArray(MACObject))
                {
                    throw new ISO7816Exception(Error.VerificationFailed);
                }
            }

            Apdu ClearApdu = new Apdu((byte)(smApdu.CLA & 0xf0), smApdu.INS, smApdu.P1, smApdu.P2, ClearData);

            if (NetLEObject != null)
            {
                ClearApdu.UseLE = true;
                ClearApdu.LE    = NetLEObject[0];
            }
            else
            {
                ClearApdu.UseLE = smApdu.UseLE;
                if (ClearApdu.UseLE)
                {
                    int orLE = smApdu.LE;
                    if (orLE == 0)
                    {
                        orLE = 255;
                    }
                    if (outEncKey == null && outSigKey == null)
                    {
                        ClearApdu.LE = (byte)(orLE - 2);
                    }
                    else if (outEncKey != null && outSigKey == null)
                    {
                        ClearApdu.LE = (byte)((orLE - 3) & ~7);
                    }
                    else if (outEncKey == null && outSigKey != null)
                    {
                        ClearApdu.LE = (byte)(orLE - 12);
                    }
                    else if (outEncKey != null && outSigKey != null)
                    {
                        ClearApdu.LE = (byte)((orLE - 20) & ~7);
                    }
                }
            }
            return(ClearApdu);
        }