예제 #1
0
        public virtual byte[] processCommand(Apdu apdu)
        {
            CardContext context = handler.Context;

            if (apdu.P1 != 0)
            {
                return(Error.P1OrP2NotValid);
            }
            ushort pinId = (ushort)(apdu.P2 & 0x7f);
            BSO    pin   = null;

            if (pinId != 0)
            {
                bool backTrack = (apdu.P2 & 0x80) != 0;
                if (backTrack)
                {
                    pin = context.CurDF.GetChildBSO(pinId, backTrack);
                }
                else
                {
                    pin = context.CurDF.Owner.MasterFile.GetChildBSO(pinId, false);
                }
            }
            else
            {
                pin = handler.GetEnvironmentKey(SecurityEnvironmentComponent.TEST);
            }

            if (pin == null)
            {
                return(Error.FileNotFound);
            }
            if (pin.Class != BSOClass.Test || pin.Algo == BSOAlgo.PIN)
            {
                return(Error.InsNotValid);
            }

            if (!handler.IsVerifiedAC(pin, BSO_AC.AC_USE))
            {
                return(Error.SecurityStatusNotSatisfied);
            }

            if (handler.VerifyBSO(pin, apdu.Data))
            {
                return(Error.Ok);
            }
            else
            {
                return(Error.VerificationFailed);
            }
        }
예제 #2
0
        public virtual byte[] processCommand(Apdu apdu)
        {
            CardContext context = handler.Context;

            if (apdu.P1 != 0 && apdu.P1 != 1)
            {
                return(Error.P1OrP2NotValid);
            }
            bool verify = apdu.P1 == 0;

            ushort pinId     = (ushort)(apdu.P2 & 0x7f);
            bool   backTrack = (apdu.P2 & 0x80) != 0;
            BSO    pin       = null;

            if (backTrack)
            {
                pin = context.CurDF.GetChildBSO(pinId, backTrack);
            }
            else
            {
                pin = context.CurDF.Owner.MasterFile.GetChildBSO(pinId, false);
            }
            if (pin == null)
            {
                return(Error.FileNotFound);
            }
            // deve essere un test object di tipo PIN
            if (pin.Class != BSOClass.Test || pin.Algo != BSOAlgo.PIN)
            {
                return(Error.InsNotValid);
            }

            int startPin = 0;

            if (verify)
            {
                // cerco il BSO referenziato dall' AC_CHANGE del PIN
                byte condition = pin.AC[BSO_AC.AC_CHANGE];
                if (condition == AC.Never)
                {
                    return(Error.ObjectNotFound);
                }
                if (condition != AC.Always)
                {
                    BSO changePin = pin.Parent.GetChildBSO(condition, true);
                    if (changePin == null)
                    {
                        return(Error.FileNotFound);
                    }

                    if (changePin.Class != BSOClass.Test || changePin.Algo != BSOAlgo.PIN)
                    {
                        return(Error.InsNotValid);
                    }

                    if (!handler.VerifyBSO(changePin, new ByteArray(apdu.Data).Left(changePin.Data.Length)))
                    {
                        return(Error.VerificationFailed);
                    }
                    startPin = changePin.Data.Length;
                }
            }
            if (startPin == apdu.Data.Length)
            {
                return(Error.WrongLength);
            }
            if (handler.IsVerifiedAC(pin, BSO_AC.AC_CHANGE))
            {
                pin.Data = new ByteArray(apdu.Data).Sub(startPin);
            }
            else
            {
                return(Error.SecurityStatusNotSatisfied);
            }

            handler.UnblockBSO(pin);
            return(Error.Ok);
        }
        public virtual byte[] processCommand(Apdu apdu)
        {
            CardContext context = handler.Context;

            if (apdu.P1 != 0 &&
                apdu.P1 != 1 &&
                apdu.P1 != 3)
            {
                return(Error.P1OrP2NotValid);
            }
            bool setNewPin = apdu.P1 == 0;
            bool verifyPin = apdu.P1 != 3;

            if (apdu.P1 == 3 && (apdu.Data != null && apdu.Data.Length > 0))
            {
                return(Error.DataFieldNotValid);
            }

            ushort bsoId     = (ushort)(apdu.P2 & 0x7f);
            bool   backTrack = (apdu.P2 & 0x80) != 0;
            BSO    bso       = null;

            if (backTrack)
            {
                bso = context.CurDF.GetChildBSO(bsoId, backTrack);
            }
            else
            {
                bso = context.CurDF.Owner.MasterFile.GetChildBSO(bsoId, false);
            }
            if (bso == null)
            {
                return(Error.FileNotFound);
            }
            if (bso.Class != BSOClass.Test)
            {
                return(Error.InsNotValid);
            }

            // deve essere un test object di tipo PIN
            if (setNewPin && bso.Algo != BSOAlgo.PIN)
            {
                return(Error.InsNotValid);
            }

            int startPin = 0;

            if (verifyPin)
            {
                // cerco il BSO referenziato dall' AC_CHANGE del PIN
                byte condition = bso.AC[BSO_AC.AC_UNBLOCK];
                if (condition == AC.Always || condition == AC.Never)
                {
                    return(Error.ObjectNotFound);
                }
                BSO changePin = bso.Parent.GetChildBSO(condition, true);
                if (changePin == null)
                {
                    return(Error.FileNotFound);
                }

                if (changePin.Class != BSOClass.Test || changePin.Algo != BSOAlgo.PIN)
                {
                    return(Error.InsNotValid);
                }
                int pinLen = 0;
                if (!setNewPin)
                {
                    pinLen = apdu.Data != null ? apdu.Data.Length : 0;
                }
                else
                {
                    pinLen = changePin.Data.Length;
                }
                if (!handler.VerifyBSO(changePin, new ByteArray(apdu.Data).Left(pinLen)))
                {
                    return(Error.VerificationFailed);
                }
                startPin = changePin.Data.Length;
            }
            if (!handler.IsVerifiedAC(bso, BSO_AC.AC_UNBLOCK))
            {
                throw new ISO7816Exception(Error.SecurityStatusNotSatisfied);
            }

            handler.UnblockBSO(bso);

            if (setNewPin)
            {
                bso.Data = new ByteArray(apdu.Data).Sub(startPin);
            }
            return(Error.Ok);
        }