示例#1
0
        public static byte[] GetSMResponse(Apdu apdu, byte[] resp, BSO encOut, BSO sigOut, byte[] random)
        {
            TLV       respTLV   = new TLV();
            ByteArray ClearData = new ByteArray(resp).Sub(0, resp.Length - 2);

            byte[] CypherTextObject = null;
            if (encOut == null && sigOut == null)
            {
                if (ClearData.Size != 0)
                {
                    respTLV[0x81] = ClearData;
                }
            }
            else
            {
                if (encOut != null)
                {
                    respTLV[0x87]    = new ByteArray(1).Append(CardHandler.encrypt3DES(encOut.Data, ClearData));
                    CypherTextObject = respTLV[0x87];
                }
                else
                {
                    if (ClearData.Size != 0)
                    {
                        respTLV[0x81] = ClearData;
                    }
                }
                if (sigOut != null)
                {
                    if (random == null)
                    {
                        throw new ISO7816Exception(Error.ConditionsOfUseNotSatisfied);
                    }
                    var MACObject = new ByteArray(random);
                    MACObject = MACObject.Append(ByteArray.ANSIPad(new ByteArray(apdu.GetBytes()).Left(4)));
                    TLV MacTLV = new TLV();
                    if (CypherTextObject != null)
                    {
                        MacTLV[0x87] = CypherTextObject;
                    }
                    else
                    {
                        MacTLV[0x81] = ClearData;
                    }
                    MACObject = MACObject.Append(MacTLV.GetBytes());
                    var mac = CardHandler.getMAC(sigOut.Data, ByteArray.ANSIPad(MACObject));
                    respTLV[0x8e] = mac;
                }
            }
            ByteArray smResp = new ByteArray(respTLV.GetBytes());

            smResp = smResp.Append(new byte[] { resp[resp.Length - 2], resp[resp.Length - 1] });
            return(smResp);
        }
示例#2
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);
        }