public virtual byte[] GetSMTLV(TLV tlv)
 {
     return(tlv[0xcb]);
 }
Beispiel #2
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;
 }
Beispiel #3
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;
        }
        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);
        }