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); } }
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); }