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 (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 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[] 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 (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 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.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[] 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 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 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 (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.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); }
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); }