public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 != 0 || apdu.P2 != 0) return Error.P1OrP2NotValid; if (apdu.Data == null || apdu.Data.Length == 0) return Error.DataFieldNotValid; if (context.CurEF == null) return Error.NoCurrentEFSelected; if (!(context.CurEF is EFRecord)) return Error.CommandIncompatibleWithFileStructure; var efRec = context.CurEF as EFRecord; if (!handler.IsVerifiedAC(efRec,EF_AC.AC_APPEND)) return Error.SecurityStatusNotSatisfied; int recNum=efRec.Append(apdu.Data); context.CurRecord = recNum; return Error.Ok; }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (context.CurEF == null) return Error.NoCurrentEFSelected; if (!(context.CurEF is EFBinary)) return Error.CommandIncompatibleWithFileStructure; var efBin=context.CurEF as EFBinary; if (!handler.IsVerifiedAC(efBin,EF_AC.AC_UPDATE)) return Error.SecurityStatusNotSatisfied; var offset = (apdu.P1 << 8) | apdu.P2; if (efBin.Data.Length<offset+apdu.Data.Length) return Error.WrongLength; if (apdu.Data==null || apdu.Data.Length==0) return Error.DataFieldNotValid; Array.Copy(apdu.Data, 0, efBin.Data, offset, apdu.Data.Length); return Error.Ok; }
public void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { CardContext context = handler.Context; sigIn = null; encIn = null; sigOut = null; encOut = null; 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) throw new ISO7816Exception(Error.ObjectNotFound); encIn = handler.getSMKey(pin, BSO_SM.SM_ENC_USE); sigIn = handler.getSMKey(pin, BSO_SM.SM_SIG_USE); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (context.CurEF == null) return Error.NoCurrentEFSelected; if (apdu.Data != null && apdu.Data.Length > 0) return Error.DataFieldNotValid; if (!(context.CurEF is EFBinary)) return Error.CommandIncompatibleWithFileStructure; var efBin=context.CurEF as EFBinary; if (!handler.IsVerifiedAC(efBin, EF_AC.AC_READ)) return Error.SecurityStatusNotSatisfied; var offset = (apdu.P1 << 8) | apdu.P2; int len = 0; if (apdu.UseLE) { if (apdu.LE == 0) len = 256; else len = apdu.LE; } if (efBin.Data.Length < offset) return Error.P1OrP2NotValid; if (efBin.Data.Length < offset + len) len = efBin.Data.Length - offset; return Util.Response(efBin.Data, offset, len, Error.Ok); }
public void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { sigIn = null; encIn = null; sigOut = null; encOut = null; }
public void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { CardContext context = handler.Context; sigIn = null; encIn = null; sigOut = null; encOut = null; 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) throw new ISO7816Exception(Error.ObjectNotFound); encIn = handler.getSMKey(bso, BSO_SM.SM_ENC_UNBLOCK); sigIn = handler.getSMKey(bso, BSO_SM.SM_SIG_UNBLOCK); }
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; }
public void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { var context = handler.Context; sigOut = null; encOut = null; encIn = handler.getSMKey(context.CurDF, DF_SM.SM_ENC_CREATE); sigIn = handler.getSMKey(context.CurDF, DF_SM.SM_SIG_CREATE); }
public void PutDataSEKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { sigOut = null; encOut = null; if (context.CurDF == null) throw new ISO7816Exception(Error.ClaNotValid); encIn = handler.getSMKey(context.CurDF, DF_SM.SM_ENC_UPDATE_APPEND); sigIn = handler.getSMKey(context.CurDF, DF_SM.SM_SIG_UPDATE_APPEND); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 != 0 || apdu.P2 != 0) return Error.P1OrP2NotValid; if (!apdu.UseLE) return Error.DataFieldNotValid; return Util.Response(handler.GetChallenge(apdu.LE), Error.Ok); }
public virtual byte[] processCommand(Apdu apdu) { context = handler.Context; if (apdu.P1 == 0x01 && apdu.P2 == 0x6E) return PutDataOCI(apdu); if (apdu.P1 == 0x01 && apdu.P2 == 0x6F) return PutDataFCI(apdu); if (apdu.P1 == 0x01 && apdu.P2 == 0x6D) return PutDataSE(apdu); return Error.P1OrP2NotValid; }
public void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { context = handler.Context; if (apdu.P1 == 0x01 && apdu.P2 == 0x6E) PutDataOCIKeys(apdu, out sigIn, out encIn, out sigOut, out encOut); else if (apdu.P1 == 0x01 && apdu.P2 == 0x6F) PutDataFCIKeys(apdu, out sigIn, out encIn, out sigOut, out encOut); else if (apdu.P1 == 0x01 && apdu.P2 == 0x6D) PutDataSEKeys(apdu, out sigIn, out encIn, out sigOut, out encOut); else throw new ISO7816Exception(Error.P1OrP2NotValid); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 != 0 || apdu.P2 != 0) return Error.P1OrP2NotValid; if (apdu.Data == null || apdu.Data.Length != 8) return Error.DataFieldNotValid; ByteArray data = apdu.Data; if (data[4]!=0 || data[5]!=0) return Error.DataFieldNotValid; ushort pubExpLen=Util.ToUShort(data,6); if (pubExpLen == 0) pubExpLen = 24; if (pubExpLen<16 || pubExpLen>64) return Error.DataFieldNotValid; var Module = context.CurDF.GetChildBSO(Util.ToUShort(data[0],data[1]), false); if (Module == null) return Error.ObjectNotFound; if (Module.Algo != BSOAlgo.RSA_DS_Test && Module.Algo != BSOAlgo.RSA_Enc) return Error.InsNotValid; if (!handler.IsVerifiedAC(Module, BSO_AC.AC_GENKEYPAIR)) return Error.SecurityStatusNotSatisfied; var privExp = context.CurDF.GetChildBSO(Util.ToUShort((byte)(data[0] | 1), data[1]), false); if (privExp == null) return Error.ObjectNotFound; if (privExp.Algo != BSOAlgo.RSA_DS_Test && privExp.Algo != BSOAlgo.RSA_Enc) return Error.InsNotValid; var pubKey = context.CurDF.GetChildEF(Util.ToUShort(data.Sub(2, 2))); if (pubKey == null) return Error.FileNotFound; if (!(pubKey is EFLinearTLV)) return Error.CommandIncompatibleWithFileStructure; if (!handler.IsVerifiedAC(pubKey, EF_AC.AC_APPEND)) return Error.SecurityStatusNotSatisfied; handler.GenerateKey(privExp, Module, pubKey as EFLinearTLV, pubExpLen); return Error.Ok; }
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 void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { CardContext context = handler.Context; sigIn = null; encIn = null; sigOut = null; encOut = null; var efBin = context.CurEF as EFBinary; if (efBin == null) return; encIn = handler.getSMKey(efBin, EF_SM.SM_ENC_UPDATE); sigIn = handler.getSMKey(efBin, EF_SM.SM_SIG_UPDATE); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 != 0 || apdu.P2 != 0) return Error.P1OrP2NotValid; if (apdu.Data != null && apdu.Data.Length != 0) return Error.DataFieldNotValid; var ef = context.CurFile; if (ef == null) return Error.NoCurrentEFSelected; if (ef.Active) return Error.InsNotValid; ef.Active = true; return Error.Ok; }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 != 0xf3 && apdu.P1 != 0xf1) return Error.P1OrP2NotValid; if (apdu.P1 == 0xf3) { var se = context.CurDF.GetChildSE(apdu.P2, true); if (se == null) return Error.RecordNotFound; if (!handler.IsVerifiedAC(se, SE_AC.AC_RESTORE)) return Error.SecurityStatusNotSatisfied; handler.RestoreSE(se); } else if (apdu.P1 == 0xf1) { TLV se=new TLV(apdu.Data); byte[] id=se[0x83]; if (id==null) id=se[0x84]; if (id==null) return Error.DataFieldNotValid; if (id.Length!=1) return Error.DataFieldNotValid; SecurityEnvironmentComponent comp = 0; switch (apdu.P2) { case 0xb8: comp = SecurityEnvironmentComponent.CON; break; case 0xa4: comp = SecurityEnvironmentComponent.TEST; break; case 0xb6: comp = SecurityEnvironmentComponent.CDS; break; default: return Error.P1OrP2NotValid; } if (comp == 0) return Error.P1OrP2NotValid; handler.RestoreSE(comp,id[0]); } return Error.Ok; }
public void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { sigOut = null; encOut = null; BSO key =null; if (apdu.P1 == 0x80 && apdu.P2 == 0x86) key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CON); else if (apdu.P1 == 0x86 && apdu.P2 == 0x80) key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CON); else if (apdu.P1 == 0x9E && apdu.P2 == 0x9A) key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CDS); encIn = handler.getSMKey(key, BSO_SM.SM_ENC_USE); sigIn = handler.getSMKey(key, BSO_SM.SM_SIG_USE); encOut = handler.getSMKey(key, BSO_SM.SM_ENC_USE_OUT); sigOut = handler.getSMKey(key, BSO_SM.SM_SIG_USE_OUT); }
public void getSMKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { CardContext context = handler.Context; sigIn = null; encIn = null; sigOut = null; encOut = null; var efBin = context.CurEF as EFRecord; if (efBin == null) return; encIn = handler.getSMKey(efBin, EF_SM.SM_ENC_READ_IN); sigIn = handler.getSMKey(efBin, EF_SM.SM_SIG_READ_IN); encOut = handler.getSMKey(efBin, EF_SM.SM_ENC_READ_OUT); sigOut = handler.getSMKey(efBin, EF_SM.SM_SIG_READ_OUT); }
public void PutDataFCIKeys(Apdu apdu, out BSO sigIn, out BSO encIn, out BSO sigOut, out BSO encOut) { if (context.CurFile == null) throw new ISO7816Exception(Error.NoCurrentEFSelected); sigOut = null; encOut = null; if (context.CurFile is DF) { encIn = handler.getSMKey(context.CurFile, DF_SM.SM_ENC_ADMIN); sigIn = handler.getSMKey(context.CurFile, DF_SM.SM_SIG_ADMIN); } else if (context.CurFile is EF) { encIn = handler.getSMKey(context.CurFile, EF_SM.SM_ENC_ADMIN); sigIn = handler.getSMKey(context.CurFile, EF_SM.SM_SIG_ADMIN); } else throw new ISO7816Exception(Error.NoCurrentEFSelected); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; ushort bsoId = Util.ToUShort(apdu.P1, (byte)(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 (!handler.IsVerifiedAC(bso, BSO_AC.AC_CHANGE)) return Error.SecurityStatusNotSatisfied; if (bso.Data.Length != apdu.Data.Length) return Error.DataFieldNotValid; bso.Data = apdu.Data; handler.UnblockBSO(bso); return Error.Ok; }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 != 0) return Error.P1OrP2NotValid; 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.ObjectNotFound; 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 (context.CurDF == null) return Error.ClaNotValid; TLV fciExt = new TLV(apdu.Data); if (fciExt[0x62] == null) return Error.DataFieldNotValid; TLV fci = new TLV(fciExt[0x62]); var Size1 = fci[0x80]; var Size2 = fci[0x81]; var Options = fci[0x82]; var Id = fci[0x83]; var Fixed = fci[0x85]; var AC = fci[0x86]; var SM = card.GetSMTLV(fci); if (Size1 != null && Size2 != null) return Error.DataFieldNotValid; if (Options==null) return Error.DataFieldNotValid; if (Id == null) return Error.DataFieldNotValid; if (Fixed == null) return Error.DataFieldNotValid; if (AC == null) return Error.DataFieldNotValid; if (Options.Length != 3) return Error.DataFieldNotValid; if (Id.Length != 2) return Error.DataFieldNotValid; if (Fixed.Length != 1) return Error.DataFieldNotValid; if (Fixed[0] != 1) return Error.DataFieldNotValid; if (Options[0] == 0x38 && Size2 == null) return Error.DataFieldNotValid; if (!handler.IsVerifiedAC(context.CurDF, DF_AC.AC_CREATE)) return Error.SecurityStatusNotSatisfied; ushort newId=Util.ToUShort(Id); if (newId == 0x3F00 || newId == 0x3FFF || newId == 0xFFFF) return Error.DataFieldNotValid; if (context.CurDF.GetChildEForDF(newId) != null) return Error.FileAlreadyExists; CardSelectable obj = null; if (Options[0] == 0x38) obj = card.CreateDF(newId, context.CurDF); else if (Options[0] == 0x01) obj = card.CreateEF(newId, context.CurDF,Util.ToUInt(Size1)); else if (Options[0] == 0x02) obj = new EFLinearFixed(newId, card, context.CurDF, Util.ToUInt(Size1), Options[2]); else if (Options[0] == 0x05) obj = card.CreateEFLinearTLV(newId, context.CurDF, Util.ToUInt(Size1)); else if (Options[0] == 0x06) obj = new EFCyclic(newId, card, context.CurDF, Util.ToUInt(Size1), Options[2]); else return Error.DataFieldNotValid; if (AC != null) obj.AC.Set(AC); if (SM != null) obj.SM.Set(SM); if (obj != null) context.CurFile = obj; return Error.Ok; }
public virtual byte[] PutDataFCI(Apdu apdu) { TLV fci = new TLV(apdu.Data); var Aid = fci[0x84]; var AC = fci[0x86]; var SM = card.GetSMTLV(fci); if (Aid!=null && Aid.Length > 16) return Error.DataFieldNotValid; if (context.CurFile is EF) { if (!handler.IsVerifiedAC(context.CurFile, EF_AC.AC_ADMIN)) return Error.SecurityStatusNotSatisfied; } else if (context.CurFile is DF) { if (!handler.IsVerifiedAC(context.CurFile, DF_AC.AC_ADMIN)) return Error.SecurityStatusNotSatisfied; } if (context.CurEF != null && Aid != null) return Error.CommandIncompatibleWithFileStructure; if (AC != null) context.CurFile.AC.Set(AC); if (SM != null) context.CurFile.SM.Set(SM); if (context.CurDF != null) if (Aid != null) context.CurDF.AID = Aid; return Error.Ok; }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 != 0xf3 && apdu.P1 != 0xf1) { return(Error.P1OrP2NotValid); } if (apdu.P1 == 0xf3) { var se = context.CurDF.GetChildSE(apdu.P2, true); if (se == null) { return(Error.RecordNotFound); } if (!handler.IsVerifiedAC(se, SE_AC.AC_RESTORE)) { return(Error.SecurityStatusNotSatisfied); } handler.RestoreSE(se); } else if (apdu.P1 == 0xf1) { TLV se = new TLV(apdu.Data); byte[] id = se[0x83]; if (id == null) { id = se[0x84]; } if (id == null) { return(Error.DataFieldNotValid); } if (id.Length != 1) { return(Error.DataFieldNotValid); } SecurityEnvironmentComponent comp = 0; switch (apdu.P2) { case 0xb8: comp = SecurityEnvironmentComponent.CON; break; case 0xa4: comp = SecurityEnvironmentComponent.TEST; break; case 0xb6: comp = SecurityEnvironmentComponent.CDS; break; default: return(Error.P1OrP2NotValid); } if (comp == 0) { return(Error.P1OrP2NotValid); } handler.RestoreSE(comp, id[0]); } return(Error.Ok); }
public byte[] ProcessApdu(byte[] apdu) { try { Apdu Apdu = new Apdu(apdu); card.Log(Apdu); Apdu initialApdu = Apdu; ushort key = Util.ToUShort((byte)(Apdu.CLA & 0xf0), Apdu.INS); if (commandMap.ContainsKey(key)) { BSO sigIn, encIn, sigOut, encOut; commandMap[key].getSMKeys(Apdu, out sigIn, out encIn, out sigOut, out encOut); var challenge = context.Challenge; if (sigIn != null || encIn != null || sigOut != null || encOut != null) { if (!Apdu.IsSM) { return(Error.SMObjectMissing); } if (sigIn != null) { context.Challenge = null; } Apdu = Apdu.GetClearApdu(Apdu, encIn, sigIn, encOut, sigOut, challenge); } else { if (Apdu.IsSM) { return(Error.ConditionsOfUseNotSatisfied); } } var resp = commandMap[key].processCommand(Apdu); card.Log(resp); var random = context.Random; if (encOut != null || sigOut != null || sigIn != null || encIn != null) { if (sigOut != null) { context.Challenge = null; } context.Random = null; return(Apdu.GetSMResponse(initialApdu, resp, encOut, sigOut, random)); } else { return(resp); } } card.Log("Comando non riconosciuto"); card.Log(Error.InsNotValid); return(Error.InsNotValid); } catch (ISO7816Exception cex) { card.Log((byte[])cex.CardError); return(cex.CardError); } catch (Exception ex) { card.Log(ex.ToString()); return(Error.InternalError); } }
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); }
public byte[] Should_the_result_match_the_expected_result(Apdu apdu) { return(apdu.ToArray()); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (context.CurEF == null) { return(Error.NoCurrentEFSelected); } if (!(context.CurEF is EFRecord)) { return(Error.CommandIncompatibleWithFileStructure); } if (apdu.Data == null || apdu.Data.Length == 0) { return(Error.DataFieldNotValid); } var efRec = context.CurEF as EFRecord; if (!handler.IsVerifiedAC(efRec, EF_AC.AC_UPDATE)) { return(Error.SecurityStatusNotSatisfied); } int?recNum = 0; if (apdu.P1 == 0) { if (apdu.P2 == 0) { recNum = 0; } else if (apdu.P2 == 1) { recNum = efRec.Data.Count - 1; } else if (apdu.P2 == 2) { if (!context.CurRecord.HasValue) { recNum = 0; } else { recNum = context.CurRecord.Value + 1; } } else if (apdu.P2 == 3) { if (!context.CurRecord.HasValue) { recNum = efRec.Data.Count - 1; } else { recNum = context.CurRecord.Value - 1; } } else if (apdu.P2 == 4) { if (!context.CurRecord.HasValue) { recNum = 0; } else { recNum = context.CurRecord.Value; } } } else if (apdu.P2 == 4) { if (apdu.P1 <= efRec.Data.Count && apdu.P1 > 0) { recNum = apdu.P1 - 1; } else { return(Error.RecordNotFound); } } else if (efRec is EFLinearTLV) { var efl = efRec as EFLinearTLV; if (apdu.P2 == 0) { recNum = efl.SearchRecord(apdu.P1); } else if (apdu.P2 == 1) { recNum = efl.SearchRecordRev(apdu.P1); } else if (apdu.P2 == 2) { if (context.CurRecord.HasValue) { recNum = efl.SearchRecord(context.CurRecord.Value, apdu.P1); } else { recNum = efl.SearchRecord(apdu.P1); } } else if (apdu.P2 == 3) { if (context.CurRecord.HasValue) { recNum = efl.SearchRecordRev(context.CurRecord.Value, apdu.P1); } else { recNum = efl.SearchRecordRev(apdu.P1); } } } if (!recNum.HasValue) { return(Error.RecordNotFound); } if (apdu.P2 != 4) { if (!(efRec is EFCyclic)) { context.CurRecord = recNum; } else { context.CurRecord = 0; } } if (recNum.Value >= efRec.Data.Count) { return(Error.RecordNotFound); } efRec.Update(recNum.Value, apdu.Data); return(Error.Ok); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 == 0x80 && apdu.P2 == 0x86) { // DEC BSO key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CON); if (key.Class != BSOClass.PSO) return Error.P1OrP2NotValid; if (key.Algo!=BSOAlgo.RSA_Enc && key.Algo!=BSOAlgo.DES3_Enc_SMEnc) return Error.P1OrP2NotValid; if (!handler.IsVerifiedAC(key, BSO_AC.AC_USE)) return Error.SecurityStatusNotSatisfied; byte[] data=handler.Decrypt(key, new ByteArray(apdu.Data).Sub(1)); // devo paddare per arrivare alla lunghezza del modulo if (key.Algo == BSOAlgo.RSA_Enc) { if (data.Length < (key.data.Length - 2)) { var dataPad = new byte[key.data.Length - 2]; data.CopyTo(dataPad, dataPad.Length - data.Length); data = dataPad; } } return Util.Response(data, Error.Ok); } else if (apdu.P1 == 0x86 && apdu.P2 == 0x80) { // ENC BSO key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CON); if (key.Class != BSOClass.PSO) return Error.P1OrP2NotValid; if (key.Algo != BSOAlgo.RSA_Enc && key.Algo != BSOAlgo.DES3_Enc_SMEnc) return Error.P1OrP2NotValid; if (!handler.IsVerifiedAC(key, BSO_AC.AC_USE)) return Error.SecurityStatusNotSatisfied; byte[] data = handler.Encrypt(key, apdu.Data); if (key.Algo == BSOAlgo.RSA_Enc && data.Length < (key.data.Length - 2)) { var dataPad = new byte[key.data.Length - 2]; data.CopyTo(dataPad, dataPad.Length - data.Length); data = dataPad; } return Util.Response(new ByteArray(0).Append(data), Error.Ok); } else if (apdu.P1 == 0x9E && apdu.P2 == 0x9A) { // CDS BSO key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CDS); if (key.Class != BSOClass.PSO) return Error.P1OrP2NotValid; if (key.Algo != BSOAlgo.RSA_DS_Test) return Error.P1OrP2NotValid; if (!handler.IsVerifiedAC(key, BSO_AC.AC_USE)) return Error.SecurityStatusNotSatisfied; byte[] data = handler.DigitalSignature(key, apdu.Data); if (data.Length < (key.data.Length - 2)) { var dataPad = new byte[key.data.Length - 2]; data.CopyTo(dataPad, dataPad.Length - data.Length); data = dataPad; } return Util.Response(data, Error.Ok); } return Error.P1OrP2NotValid; }
/// <summary> /// Read Property. /// </summary> /// <param name="recipient">The recipient.</param> /// <param name="arrayidx">The arrayidx.</param> /// <param name="objtype">The objtype.</param> /// <param name="objprop">The objprop.</param> /// <param name="property">The property.</param> /// <returns></returns> public bool SendReadProperty( Device recipient, int arrayidx, BacnetEnums.BacnetObjectType objtype, BacnetEnums.BacnetPropertyId objprop, Property property) { // Create and send an Confirmed Request //value = "(none)"; if (recipient == null) { return(false); } if (property == null) { return(false); } //uint instance = BACnetData.Devices[deviceidx].Instance; var sendBytes = new byte[50]; // BVLL sendBytes[0] = Bvlc.BacnetBvlcTypeBip; sendBytes[1] = Bvlc.BacnetBvlcFuncUnicastNpdu; sendBytes[2] = 0x00; sendBytes[3] = 0x00; // BVLL Length, fix later (24?) // NPDU sendBytes[4] = BacnetEnums.BacnetProtocolVersion; if (recipient.SourceLength == 0) { sendBytes[5] = 0x04; // Control flags, no destination address } else { sendBytes[5] = 0x24; // Control flags, with broadcast or destination address } uint len = 6; if (recipient.SourceLength > 0) { // Get the (MSTP) Network number (2001) var temp2 = BitConverter.GetBytes(recipient.Network); sendBytes[len++] = temp2[1]; sendBytes[len++] = temp2[0]; // Get the MAC address (0x0D) var temp4 = BitConverter.GetBytes(recipient.MacAddress); sendBytes[len++] = 0x01; // MAC address length - adjust for other lengths ... sendBytes[len++] = temp4[0]; sendBytes[len++] = 0xFF; // Hop count = 255 } // APDU sendBytes[len++] = 0x00; // Control flags sendBytes[len++] = 0x05; // Max APDU length (1476) // Create invoke counter sendBytes[len++] = (byte)(invokeCounter); invokeCounter = ((invokeCounter + 1) & 0xFF); sendBytes[len++] = 0x0C; // Service Choice: Read Property request // Service Request (var part of APDU): // Set up Object ID (Context Tag) len = Apdu.SetObjectId(ref sendBytes, len, objtype, recipient.Instance); // Set up Property ID (Context Tag) len = Apdu.SetPropertyId(ref sendBytes, len, objprop); // Optional array index goes here if (arrayidx >= 0) { len = Apdu.SetArrayIdx(ref sendBytes, len, arrayidx); } // Fix the BVLL length sendBytes[3] = (byte)len; var getResponse = false; var count = 0; while (count < BacnetUnicastRequestRepeatCount && !getResponse) { sendUdp.EnableBroadcast = false; sendUdp.Send(sendBytes, (int)len, recipient.ServerEp); while (!getResponse) { if (sendUdp.Client.Available <= 0) { continue; } //recvBytes = SendUDP.Receive(ref RemoteEP); var sendTo = recipient.ServerEp; var recvBytes = sendUdp.Receive(ref sendTo); var apduOffset = Npdu.Parse(recvBytes, Bvlc.BacnetBvlcHeaderLen); // BVLL is always 4 bytes // Check for APDU response // 0x - Confirmed Request // 1x - Un-Confirmed Request // 2x - Simple ACK // 3x - Complex ACK // 4x - Segment ACK // 5x - Error // 6x - Reject // 7x - Abort if (recvBytes[apduOffset] != 0x30) { continue; } // Verify the Invoke ID is the same var ic = (byte)(invokeCounter == 0 ? 255 : invokeCounter - 1); if (ic != recvBytes[apduOffset + 1]) { continue; } Apdu.ParseProperty(ref recvBytes, apduOffset, property); getResponse = true; // This will still execute the finally } count++; } return(getResponse); }
/// <summary> /// Write Property. /// </summary> /// <param name="recipient">The receipient.</param> /// <param name="arrayidx">The arrayidx.</param> /// <param name="objtype">The objtype.</param> /// <param name="objprop">The objprop.</param> /// <param name="property">The property.</param> /// <param name="priority">The priority.</param> /// <returns></returns> public bool SendWriteProperty( Device recipient, int arrayidx, BacnetEnums.BacnetObjectType objtype, BacnetEnums.BacnetPropertyId objprop, Property property, int priority) { // Create and send an Confirmed Request if (recipient == null) { return(false); } if (property == null) { return(false); } var sendBytes = new byte[50]; // BVLL var len = Bvlc.Fill(ref sendBytes, Bvlc.BacnetBvlcFuncUnicastNpdu, 0); // NPDU sendBytes[len++] = BacnetEnums.BacnetProtocolVersion; if (recipient.SourceLength == 0) { sendBytes[len++] = 0x04; // Control flags, no destination address } else { sendBytes[len++] = 0x24; // Control flags, with broadcast or destination } if (recipient.SourceLength > 0) { // Get the (MSTP) Network number (2001) //sendBytes[6] = 0x07; // Destination network address (2001) //sendBytes[7] = 0xD1; var temp2 = BitConverter.GetBytes(recipient.Network); sendBytes[len++] = temp2[1]; sendBytes[len++] = temp2[0]; // Get the MAC address (0x0D) //sendBytes[8] = 0x01; // MAC address length //sendBytes[9] = 0x0D; // Destination MAC layer address var temp4 = BitConverter.GetBytes(recipient.MacAddress); sendBytes[len++] = 0x01; // MAC address length - adjust for other lengths ... sendBytes[len++] = temp4[0]; sendBytes[len++] = 0xFF; // Hop count = 255 } // APDU sendBytes[len++] = 0x00; // Control flags sendBytes[len++] = 0x05; // Max APDU length (1476) // Create invoke counter //sendBytes[len++] = InvokeCounter++; // Invoke ID sendBytes[len++] = (byte)(invokeCounter); invokeCounter = ((invokeCounter + 1) & 0xFF); sendBytes[len++] = 0x0F; // Service Choice: Write Property request // Service Request (var part of APDU): // Set up Object ID (Context Tag) len = Apdu.SetObjectId(ref sendBytes, len, objtype, recipient.Instance); // Set up Property ID (Context Tag) len = Apdu.SetPropertyId(ref sendBytes, len, objprop); // Optional array index goes here if (arrayidx >= 0) { len = Apdu.SetArrayIdx(ref sendBytes, len, arrayidx); } // Set the value to send len = Apdu.SetProperty(ref sendBytes, len, property); //PEP Optional array index goes here // Set priority if (priority > 0) { len = Apdu.SetPriority(ref sendBytes, len, priority); } // Fix the BVLL length sendBytes[3] = (byte)len; var count = 0; var getResponse = false; while (count < BacnetUnicastRequestRepeatCount && !getResponse) { sendUdp.EnableBroadcast = false; sendUdp.Send(sendBytes, (int)len, recipient.ServerEp); while (!getResponse) { if (sendUdp.Client.Available <= 0) { continue; } //recvBytes = SendUDP.Receive(ref RemoteEP); var sendTo = recipient.ServerEp; var recvBytes = sendUdp.Receive(ref sendTo); var apduOffset = Npdu.Parse(recvBytes, 4); // BVLL is always 4 bytes // Check for APDU response, and decide what to do // 0x - Confirmed Request // 1x - Un-Confirmed Request // 2x - Simple ACK // 3x - Complex ACK // 4x - Segment ACK // 5x - Error // 6x - Reject // 7x - Abort if (recvBytes[apduOffset] != 0x20) { continue; } // Verify the Invoke ID is the same var ic = (byte)(invokeCounter == 0 ? 255 : invokeCounter - 1); if (ic == recvBytes[apduOffset + 1]) { getResponse = true; // This will still execute the finally } } count++; } return(getResponse); // This will still execute the finally }
/// <summary> /// Collect Who-Is information from a single IP address. /// @todo: Use exceptions for timeout. /// </summary> /// <param name="bIpAddress">IP host address of suspected BACnet device.</param> /// <param name="milliseconds">I-Am receive timeout in milliseconds.</param> /// <returns>A BACnet Device object representation MAYBE with filled properties.</returns> public Device UnicastWhoIsOnSingleIp(IPEndPoint bIpAddress, int milliseconds) { var sendBytes = new byte[12]; var device = new Device(); try { //PEP Use NPDU.Create and APDU.Create (when written) sendBytes[0] = Bvlc.BacnetBvlcTypeBip; sendBytes[1] = Bvlc.BacnetBvlcFuncUnicastNpdu; sendBytes[2] = 0; sendBytes[3] = 12; sendBytes[4] = BacnetEnums.BacnetProtocolVersion; sendBytes[5] = 0x20; // Control flags sendBytes[6] = 0xFF; // Destination network address (65535) sendBytes[7] = 0xFF; sendBytes[8] = 0; // Destination MAC layer address length, 0 = Broadcast sendBytes[9] = 0xFF; // Hop count = 255 sendBytes[10] = (byte)BacnetEnums.BacnetPduType.PduTypeUnconfirmedServiceRequest; sendBytes[11] = (byte)BacnetEnums.BacnetUnconfirmedService.ServiceUnconfirmedWhoIs; sendUdp.EnableBroadcast = false; sendUdp.Send(sendBytes, 12, bIpAddress); var watch = new Stopwatch(); watch.Start(); while (true) { if (watch.Elapsed.TotalMilliseconds >= milliseconds) { break; } // Process the response packets //if (WinSockRecvReady() > 0) //{ // if (WinSockRecvFrom(recvBytes, ref count, ref ipaddr) > 0) // Process the response packets if (sendUdp.Client.Available > 0) { var recvBytes = sendUdp.Receive(ref bIpAddress); { // Parse and save the BACnet data var npduOffset = Bvlc.Parse(recvBytes, 0); var apduOffset = Npdu.Parse(recvBytes, npduOffset); if (Apdu.ParseIAm(recvBytes, apduOffset) <= 0) { continue; } device.Name = "Device"; device.SourceLength = Npdu.Slen; device.ServerEp = bIpAddress; device.Network = Npdu.Snet; device.MacAddress = Npdu.SAddress; device.Instance = Apdu.ObjectId; // We should now have enough info to read/write properties for this device } } } watch.Stop(); } catch (Exception e) { Log.ErrorFormat("Error on UnicastWhoIsOnSingleIp {0}", e.Message); } return(device); }
/// <summary> /// Who-Is, and collect the device about who answers /// </summary> /// <param name="milliseconds"></param> /// <returns></returns> public List <Device> GetDevices(int milliseconds) { // Get the host data, send a Who-Is, accept responses and save in the DeviceList var sendBytes = new byte[12]; devices.Clear(); // Send the request try { //PEP Use NPDU.Create and APDU.Create (when written) sendBytes[0] = Bvlc.BacnetBvlcTypeBip; sendBytes[1] = Bvlc.BacnetBvlcFuncUnicastNpdu; sendBytes[2] = 0; sendBytes[3] = 12; sendBytes[4] = BacnetEnums.BacnetProtocolVersion; sendBytes[5] = 0x20; // Control flags sendBytes[6] = 0xFF; // Destination network address (65535) sendBytes[7] = 0xFF; sendBytes[8] = 0; // Destination MAC layer address length, 0 = Broadcast sendBytes[9] = 0xFF; // Hop count = 255 sendBytes[10] = (byte)BacnetEnums.BacnetPduType.PduTypeUnconfirmedServiceRequest; sendBytes[11] = (byte)BacnetEnums.BacnetUnconfirmedService.ServiceUnconfirmedWhoIs; sendUdp.EnableBroadcast = false; sendUdp.Send(sendBytes, 12, broadcastEp); var watch = new Stopwatch(); watch.Start(); while (true) { if (watch.Elapsed.TotalMilliseconds >= milliseconds) { break; } var remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); if (sendUdp.Client.Available > 0) { var recvBytes = sendUdp.Receive(ref remoteIpEndPoint); // Parse and save the BACnet data var npduOffset = Bvlc.Parse(recvBytes, 0); var apduOffset = Npdu.Parse(recvBytes, npduOffset); if (Apdu.ParseIAm(recvBytes, apduOffset) <= 0) { continue; } var device = new Device { Name = "Device", SourceLength = Npdu.Slen, ServerEp = remoteIpEndPoint, Network = Npdu.Snet, MacAddress = Npdu.SAddress, Instance = Apdu.ObjectId }; if (!devices.Contains(device)) { devices.Add(device); } } } watch.Stop(); } catch (Exception ex) { Log.ErrorFormat("Error GetDevices {0}", ex.Message); } return(devices); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (context.CurEF == null) { return(Error.NoCurrentEFSelected); } if (!(context.CurEF is EFRecord)) { return(Error.CommandIncompatibleWithFileStructure); } var efRec = context.CurEF as EFRecord; if (!handler.IsVerifiedAC(efRec, EF_AC.AC_READ)) { return(Error.SecurityStatusNotSatisfied); } int?recNum = 0; if (apdu.P1 == 0) { if (apdu.P2 == 0) { recNum = 0; } else if (apdu.P2 == 1) { recNum = efRec.Data.Count - 1; } else if (apdu.P2 == 2) { if (!context.CurRecord.HasValue) { recNum = 0; } else { recNum = context.CurRecord.Value + 1; } } else if (apdu.P2 == 3) { if (!context.CurRecord.HasValue) { recNum = efRec.Data.Count - 1; } else { recNum = context.CurRecord.Value - 1; } } else if (apdu.P2 == 4) { if (!context.CurRecord.HasValue) { recNum = 0; } else { recNum = context.CurRecord.Value; } } } else if (apdu.P2 == 4) { if (apdu.P1 <= efRec.Data.Count && apdu.P1 > 0) { recNum = apdu.P1 - 1; } else { return(Error.RecordNotFound); } } else if (efRec is EFLinearTLV) { var efl = efRec as EFLinearTLV; if (apdu.P2 == 0) { recNum = efl.SearchRecord(apdu.P1); } else if (apdu.P2 == 1) { recNum = efl.SearchRecordRev(apdu.P1); } else if (apdu.P2 == 2) { if (context.CurRecord.HasValue) { recNum = efl.SearchRecord(context.CurRecord.Value, apdu.P1); } else { recNum = efl.SearchRecord(apdu.P1); } } else if (apdu.P2 == 3) { if (context.CurRecord.HasValue) { recNum = efl.SearchRecordRev(context.CurRecord.Value, apdu.P1); } else { recNum = efl.SearchRecordRev(apdu.P1); } } } if (!recNum.HasValue) { return(Error.RecordNotFound); } if (apdu.P2 != 4) { context.CurRecord = recNum; } if (recNum.Value >= efRec.Data.Count) { return(Error.RecordNotFound); } var recVal = efRec.Read(recNum.Value); if (apdu.UseLE && apdu.LE != 0) { recVal = new ByteArray(recVal).Left(apdu.LE); } return(Util.Response(recVal, Error.Ok)); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P2 != 0) return Error.P1OrP2NotValid; CardSelectable obj = null; switch (apdu.P1) { case 0: if (apdu.Data == null || apdu.Data.Length == 0) obj = card.MasterFile; else { if (apdu.Data.Length != 2) return Error.DataFieldNotValid; ushort id = Util.ToUShort(apdu.Data); if (id == 0x3f00) obj = card.MasterFile; else { obj = context.CurDF.GetChildEForDF(id); if (obj == null && context.CurDF.Parent != null) obj = context.CurDF.Parent.GetChildEForDF(id); if (obj == null && context.CurDF.Parent != null && id == context.CurDF.ID) obj = context.CurDF.Parent; } } if (obj == null) return Error.FileNotFound; context.CurFile = obj; break; case 1: if (apdu.Data == null || apdu.Data.Length != 2) return Error.DataFieldNotValid; ushort id2 = Util.ToUShort(apdu.Data); obj = context.CurDF.GetChildDF(id2); if (obj == null) return Error.FileNotFound; context.CurFile = obj; break; case 2: if (apdu.Data == null || apdu.Data.Length != 2) return Error.DataFieldNotValid; ushort id3 = Util.ToUShort(apdu.Data); obj = context.CurDF.GetChildDF(id3); if (obj == null) return Error.FileNotFound; context.CurFile = obj; break; case 3: if (apdu.Data != null && apdu.Data.Length != 0) return Error.DataFieldNotValid; if (context.CurDF.Parent == null) return Error.FileNotFound; context.CurFile = context.CurDF.Parent; break; case 4: if (apdu.Data == null || apdu.Data.Length == 0) return Error.DataFieldNotValid; DF namedDF = handler.GetNamedDF(card.MasterFile, apdu.Data); if (namedDF == null) return Error.FileNotFound; context.CurFile = namedDF; break; case 8: if (apdu.Data == null || apdu.Data.Length == 0) obj = card.MasterFile; else if (apdu.Data != null && apdu.Data.Length == 2 && Util.ToUShort(apdu.Data) == 0x3f00) obj = card.MasterFile; else { if ((apdu.Data.Length % 2) != 0) return Error.DataFieldNotValid; obj = handler.GetSelectablePath(card.MasterFile, apdu.Data, 0); if (obj == null) return Error.FileNotFound; } context.CurFile = obj; break; case 9: if (apdu.Data == null || apdu.Data.Length == 0) return Error.DataFieldNotValid; else { if ((apdu.Data.Length % 2) != 0) return Error.DataFieldNotValid; if (context.CurDF == null) return Error.ClaNotValid; obj = handler.GetSelectablePath(context.CurDF, apdu.Data, 0); if (obj == null) return Error.FileNotFound; } context.CurFile = obj; break; default: return Error.P1OrP2NotValid; } if (context.CurFile == null) return Error.FileNotFound; var outData = (context.CurFile as IObjectWithFCI).FCI; TLV tlv = new TLV(); TLV tlv2 = new TLV(); tlv2.elems.AddRange(outData); tlv.addTag(0x6f, tlv2.GetBytes()); return Util.Response(tlv.GetBytes(), Error.Ok); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (context.CurEF == null) return Error.NoCurrentEFSelected; if (!(context.CurEF is EFRecord)) return Error.CommandIncompatibleWithFileStructure; var efRec = context.CurEF as EFRecord; if (!handler.IsVerifiedAC(efRec, EF_AC.AC_READ)) return Error.SecurityStatusNotSatisfied; int? recNum=0; if (apdu.P1 == 0) { if (apdu.P2 == 0) recNum = 0; else if (apdu.P2 == 1) recNum = efRec.Data.Count - 1; else if (apdu.P2 == 2) { if (!context.CurRecord.HasValue) recNum = 0; else recNum = context.CurRecord.Value+1; } else if (apdu.P2 == 3) { if (!context.CurRecord.HasValue) recNum = efRec.Data.Count - 1; else recNum = context.CurRecord.Value - 1; } else if (apdu.P2 == 4) { if (!context.CurRecord.HasValue) recNum = 0; else recNum = context.CurRecord.Value; } } else if (apdu.P2 == 4) { if (apdu.P1 <= efRec.Data.Count && apdu.P1 > 0) recNum = apdu.P1 - 1; else return Error.RecordNotFound; } else if (efRec is EFLinearTLV) { var efl = efRec as EFLinearTLV; if (apdu.P2 == 0) { recNum = efl.SearchRecord(apdu.P1); } else if (apdu.P2 == 1) { recNum = efl.SearchRecordRev(apdu.P1); } else if (apdu.P2 == 2) { if (context.CurRecord.HasValue) recNum = efl.SearchRecord(context.CurRecord.Value, apdu.P1); else recNum = efl.SearchRecord(apdu.P1); } else if (apdu.P2 == 3) { if (context.CurRecord.HasValue) recNum = efl.SearchRecordRev(context.CurRecord.Value, apdu.P1); else recNum = efl.SearchRecordRev(apdu.P1); } } if (!recNum.HasValue) return Error.RecordNotFound; if (apdu.P2 != 4) context.CurRecord = recNum; if (recNum.Value >= efRec.Data.Count) return Error.RecordNotFound; var recVal=efRec.Read(recNum.Value); if (apdu.UseLE && apdu.LE!=0) recVal=new ByteArray(recVal).Left(apdu.LE); return Util.Response(recVal, Error.Ok); }
public virtual byte[] PutDataOCI(Apdu apdu) { TLV oci = new TLV(apdu.Data); ushort id = Util.ToUShort(oci[0x83]); if (context.CurDF == null) return Error.ClaNotValid; var obj = context.CurDF.GetChildBSO(id); if (obj == null) return CreateBSO(oci); else { if (!(obj is BSO)) return Error.DataFieldNotValid; return UpdateBSO(obj as BSO, oci); } }
public void sendCommand(ref Apdu apdu) { apduCommand = apdu; sendCommand(); apdu = apduCommand; }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P1 == 0x80 && apdu.P2 == 0x86) { // DEC BSO key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CON); if (key.Class != BSOClass.PSO) { return(Error.P1OrP2NotValid); } if (key.Algo != BSOAlgo.RSA_Enc && key.Algo != BSOAlgo.DES3_Enc_SMEnc) { return(Error.P1OrP2NotValid); } if (!handler.IsVerifiedAC(key, BSO_AC.AC_USE)) { return(Error.SecurityStatusNotSatisfied); } byte[] data = handler.Decrypt(key, new ByteArray(apdu.Data).Sub(1)); // devo paddare per arrivare alla lunghezza del modulo if (key.Algo == BSOAlgo.RSA_Enc) { if (data.Length < (key.data.Length - 2)) { var dataPad = new byte[key.data.Length - 2]; data.CopyTo(dataPad, dataPad.Length - data.Length); data = dataPad; } } return(Util.Response(data, Error.Ok)); } else if (apdu.P1 == 0x86 && apdu.P2 == 0x80) { // ENC BSO key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CON); if (key.Class != BSOClass.PSO) { return(Error.P1OrP2NotValid); } if (key.Algo != BSOAlgo.RSA_Enc && key.Algo != BSOAlgo.DES3_Enc_SMEnc) { return(Error.P1OrP2NotValid); } if (!handler.IsVerifiedAC(key, BSO_AC.AC_USE)) { return(Error.SecurityStatusNotSatisfied); } byte[] data = handler.Encrypt(key, apdu.Data); if (key.Algo == BSOAlgo.RSA_Enc && data.Length < (key.data.Length - 2)) { var dataPad = new byte[key.data.Length - 2]; data.CopyTo(dataPad, dataPad.Length - data.Length); data = dataPad; } return(Util.Response(new ByteArray(0).Append(data), Error.Ok)); } else if (apdu.P1 == 0x9E && apdu.P2 == 0x9A) { // CDS BSO key = handler.GetEnvironmentKey(SecurityEnvironmentComponent.CDS); if (key.Class != BSOClass.PSO) { return(Error.P1OrP2NotValid); } if (key.Algo != BSOAlgo.RSA_DS_Test) { return(Error.P1OrP2NotValid); } if (!handler.IsVerifiedAC(key, BSO_AC.AC_USE)) { return(Error.SecurityStatusNotSatisfied); } byte[] data = handler.DigitalSignature(key, apdu.Data); if (data.Length < (key.data.Length - 2)) { var dataPad = new byte[key.data.Length - 2]; data.CopyTo(dataPad, dataPad.Length - data.Length); data = dataPad; } return(Util.Response(data, Error.Ok)); } return(Error.P1OrP2NotValid); }
public byte[] ProcessApdu(byte[] apdu) { try { Apdu Apdu = new Apdu(apdu); card.Log(Apdu); Apdu initialApdu = Apdu; ushort key = Util.ToUShort((byte)(Apdu.CLA & 0xf0),Apdu.INS); if (commandMap.ContainsKey(key)) { BSO sigIn, encIn, sigOut, encOut; commandMap[key].getSMKeys(Apdu, out sigIn, out encIn, out sigOut, out encOut); var challenge = context.Challenge; if (sigIn != null || encIn != null || sigOut != null || encOut != null) { if (!Apdu.IsSM) return Error.SMObjectMissing; if (sigIn != null) context.Challenge = null; Apdu = Apdu.GetClearApdu(Apdu, encIn, sigIn, encOut, sigOut, challenge); } else { if (Apdu.IsSM) return Error.ConditionsOfUseNotSatisfied; } var resp=commandMap[key].processCommand(Apdu); card.Log(resp); var random = context.Random; if (encOut != null || sigOut != null || sigIn != null || encIn != null) { if (sigOut != null) context.Challenge = null; context.Random = null; return Apdu.GetSMResponse(initialApdu, resp, encOut, sigOut, random); } else { return resp; } } card.Log("Comando non riconosciuto"); card.Log(Error.InsNotValid); return Error.InsNotValid; } catch (ISO7816Exception cex) { card.Log((byte[])cex.CardError); return cex.CardError; } catch (Exception ex) { card.Log(ex.ToString()); return Error.InternalError; } }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (apdu.P2 != 0) { return(Error.P1OrP2NotValid); } CardSelectable obj = null; switch (apdu.P1) { case 0: if (apdu.Data == null || apdu.Data.Length == 0) { obj = card.MasterFile; } else { if (apdu.Data.Length != 2) { return(Error.DataFieldNotValid); } ushort id = Util.ToUShort(apdu.Data); if (id == 0x3f00) { obj = card.MasterFile; } else { obj = context.CurDF.GetChildEForDF(id); if (obj == null && context.CurDF.Parent != null) { obj = context.CurDF.Parent.GetChildEForDF(id); } if (obj == null && context.CurDF.Parent != null && id == context.CurDF.ID) { obj = context.CurDF.Parent; } } } if (obj == null) { return(Error.FileNotFound); } context.CurFile = obj; break; case 1: if (apdu.Data == null || apdu.Data.Length != 2) { return(Error.DataFieldNotValid); } ushort id2 = Util.ToUShort(apdu.Data); obj = context.CurDF.GetChildDF(id2); if (obj == null) { return(Error.FileNotFound); } context.CurFile = obj; break; case 2: if (apdu.Data == null || apdu.Data.Length != 2) { return(Error.DataFieldNotValid); } ushort id3 = Util.ToUShort(apdu.Data); obj = context.CurDF.GetChildDF(id3); if (obj == null) { return(Error.FileNotFound); } context.CurFile = obj; break; case 3: if (apdu.Data != null && apdu.Data.Length != 0) { return(Error.DataFieldNotValid); } if (context.CurDF.Parent == null) { return(Error.FileNotFound); } context.CurFile = context.CurDF.Parent; break; case 4: if (apdu.Data == null || apdu.Data.Length == 0) { return(Error.DataFieldNotValid); } DF namedDF = handler.GetNamedDF(card.MasterFile, apdu.Data); if (namedDF == null) { return(Error.FileNotFound); } context.CurFile = namedDF; break; case 8: if (apdu.Data == null || apdu.Data.Length == 0) { obj = card.MasterFile; } else if (apdu.Data != null && apdu.Data.Length == 2 && Util.ToUShort(apdu.Data) == 0x3f00) { obj = card.MasterFile; } else { if ((apdu.Data.Length % 2) != 0) { return(Error.DataFieldNotValid); } obj = handler.GetSelectablePath(card.MasterFile, apdu.Data, 0); if (obj == null) { return(Error.FileNotFound); } } context.CurFile = obj; break; case 9: if (apdu.Data == null || apdu.Data.Length == 0) { return(Error.DataFieldNotValid); } else { if ((apdu.Data.Length % 2) != 0) { return(Error.DataFieldNotValid); } if (context.CurDF == null) { return(Error.ClaNotValid); } obj = handler.GetSelectablePath(context.CurDF, apdu.Data, 0); if (obj == null) { return(Error.FileNotFound); } } context.CurFile = obj; break; default: return(Error.P1OrP2NotValid); } if (context.CurFile == null) { return(Error.FileNotFound); } var outData = (context.CurFile as IObjectWithFCI).FCI; TLV tlv = new TLV(); TLV tlv2 = new TLV(); tlv2.elems.AddRange(outData); tlv.addTag(0x6f, tlv2.GetBytes()); return(Util.Response(tlv.GetBytes(), Error.Ok)); }
public virtual byte[] processCommand(Apdu apdu) { CardContext context = handler.Context; if (context.CurEF == null) return Error.NoCurrentEFSelected; if (!(context.CurEF is EFRecord)) return Error.CommandIncompatibleWithFileStructure; if (apdu.Data == null || apdu.Data.Length == 0) return Error.DataFieldNotValid; var efRec = context.CurEF as EFRecord; if (!handler.IsVerifiedAC(efRec, EF_AC.AC_UPDATE)) return Error.SecurityStatusNotSatisfied; int? recNum=0; if (apdu.P1 == 0) { if (apdu.P2 == 0) recNum = 0; else if (apdu.P2 == 1) recNum = efRec.Data.Count - 1; else if (apdu.P2 == 2) { if (!context.CurRecord.HasValue) recNum = 0; else recNum = context.CurRecord.Value+1; } else if (apdu.P2 == 3) { if (!context.CurRecord.HasValue) recNum = efRec.Data.Count - 1; else recNum = context.CurRecord.Value - 1; } else if (apdu.P2 == 4) { if (!context.CurRecord.HasValue) recNum = 0; else recNum = context.CurRecord.Value; } } else if (apdu.P2 == 4) { if (apdu.P1 <= efRec.Data.Count && apdu.P1 > 0) recNum = apdu.P1 - 1; else return Error.RecordNotFound; } else if (efRec is EFLinearTLV) { var efl = efRec as EFLinearTLV; if (apdu.P2 == 0) { recNum = efl.SearchRecord(apdu.P1); } else if (apdu.P2 == 1) { recNum = efl.SearchRecordRev(apdu.P1); } else if (apdu.P2 == 2) { if (context.CurRecord.HasValue) recNum = efl.SearchRecord(context.CurRecord.Value, apdu.P1); else recNum = efl.SearchRecord(apdu.P1); } else if (apdu.P2 == 3) { if (context.CurRecord.HasValue) recNum = efl.SearchRecordRev(context.CurRecord.Value, apdu.P1); else recNum = efl.SearchRecordRev(apdu.P1); } } if (!recNum.HasValue) return Error.RecordNotFound; if (apdu.P2 != 4) if (!(efRec is EFCyclic)) context.CurRecord = recNum; else context.CurRecord = 0; if (recNum.Value >= efRec.Data.Count) return Error.RecordNotFound; efRec.Update(recNum.Value, apdu.Data); return Error.Ok; }
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.P2 != 0) { return(Error.P1OrP2NotValid); } if (apdu.Data == null || apdu.Data.Length != 8) { return(Error.DataFieldNotValid); } ByteArray data = apdu.Data; if (data[4] != 0 || data[5] != 0) { return(Error.DataFieldNotValid); } ushort pubExpLen = Util.ToUShort(data, 6); if (pubExpLen == 0) { pubExpLen = 24; } if (pubExpLen < 16 || pubExpLen > 64) { return(Error.DataFieldNotValid); } var Module = context.CurDF.GetChildBSO(Util.ToUShort(data[0], data[1]), false); if (Module == null) { return(Error.ObjectNotFound); } if (Module.Algo != BSOAlgo.RSA_DS_Test && Module.Algo != BSOAlgo.RSA_Enc) { return(Error.InsNotValid); } if (!handler.IsVerifiedAC(Module, BSO_AC.AC_GENKEYPAIR)) { return(Error.SecurityStatusNotSatisfied); } var privExp = context.CurDF.GetChildBSO(Util.ToUShort((byte)(data[0] | 1), data[1]), false); if (privExp == null) { return(Error.ObjectNotFound); } if (privExp.Algo != BSOAlgo.RSA_DS_Test && privExp.Algo != BSOAlgo.RSA_Enc) { return(Error.InsNotValid); } var pubKey = context.CurDF.GetChildEF(Util.ToUShort(data.Sub(2, 2))); if (pubKey == null) { return(Error.FileNotFound); } if (!(pubKey is EFLinearTLV)) { return(Error.CommandIncompatibleWithFileStructure); } if (!handler.IsVerifiedAC(pubKey, EF_AC.AC_APPEND)) { return(Error.SecurityStatusNotSatisfied); } handler.GenerateKey(privExp, Module, pubKey as EFLinearTLV, pubExpLen); return(Error.Ok); }