public ElementaryFile(byte[] AID, CardReader cardReader, byte[] FileID) { TS.TraceI("Constructing ElementaryFile with AID \"{0}\" and FileID \"{1}\".", Helper.ByteArrayToString(AID), Helper.ByteArrayToString(FileID)); this.AID = AID; this.cardReader = cardReader; this.FileID = FileID; try { this.Value = cardReader.ReadFile(AID, FileID); } catch (CardReaderException ex) { throw new ElementaryFileException(FileID, "Error reading EF.", ex); } if (this.Value == null) { throw new ElementaryFileException(FileID, string.Format("Error reading EF: AID = \"{0}\", FileID = \"{1}\".", Helper.ByteArrayToString(AID), Helper.ByteArrayToString(FileID))); } this.tagListEF = TLV.Parse(new MemoryStream(this.Value)); TS.TraceI("Number of elements in EF: \"{0}\".", this.tagListEF.Count); TS.TraceI("ElementaryFile constructed."); }
public void Load_With_DAP_Block() { byte[] data = new byte[new Random().Next(1, 32767)]; byte blockSize = (byte)new Random().Next(128, 240); var apdus = LoadCommand.Build .WithDapBlock(SecurityDomainAID, Signature) .Load(data) .WithBlockSize(blockSize) .AsApdus() .ToList(); var tlvs = TLV.Parse(apdus.First().CommandData); tlvs.Count.Should().Be(2); tlvs.First().Tag.ShouldAllBeEquivalentTo((byte)Tag.DapBlock); tlvs.Single((byte)Tag.DapBlock).NestedTags.Count.Should().Be(2); tlvs.Single((byte)Tag.DapBlock).NestedTags.First().Tag.ShouldAllBeEquivalentTo((byte)Tag.SecurityDomainAID); tlvs.Single((byte)Tag.DapBlock).NestedTags.Last().Tag.ShouldAllBeEquivalentTo((byte)Tag.LoadFileDataBlockSignature); tlvs.Last().Tag.ShouldAllBeEquivalentTo((byte)Tag.LoadFileDataBlock); tlvs.Single((byte)Tag.LoadFileDataBlock).NestedTags.Count.Should().Be(0); byte[] dataBlock = apdus.SelectMany(apdu => apdu.CommandData).ToArray(); apdus.ForEach((apdu, index, isLast) => { byte p1 = isLast ? (byte)0x80 : (byte)0x00; apdu.Assert(ApduClass.GlobalPlatform, ApduInstruction.Load, p1, (byte)index); apdu.Lc.ShouldAllBeEquivalentTo((byte)(isLast ? dataBlock.Length % blockSize : blockSize)); }); }
public void TLV_Should_Parse_Tags_With_Definite_Long_Length() { var data = new byte[] { 0x4F, 0x81, 0x02, 0xDD, 0xDD }; var tlvs = TLV.Parse(data); tlvs.Count.Should().Be(1); tlvs.First().Tag.ShouldAllBeEquivalentTo(0x4F); tlvs.First().Length.Should().Be(2); tlvs.First().Value.ShouldAllBeEquivalentTo(new byte[] { 0xDD, 0xDD }); }
public void TLV_Should_Parse_Tags_With_Definite_Short_Length() { var tlv = TLV.Build(0x4F, 0xDD, 0xDD); var tags = TLV.Parse(tlv.Data); tags.Count.Should().Be(1); tags.First().Tag.ShouldAllBeEquivalentTo(0x4F); tags.First().Length.Should().Be(2); tags.First().Value.ShouldAllBeEquivalentTo(new byte[] { 0xDD, 0xDD }); }
public void TLV_Should_Not_Parse_Tags_With_Indefinite_Length() { var data = new byte[] { 0x4F, 0x80, 0x00, 0x00, 0xDD, 0x00, 0x00 }; Action action = () => { TLV.Parse(data); }; action.ShouldThrow <NotSupportedException>(); }
public void TLV_Should_Recursively_Parse_Tags_With_Definite_Short_Length() { var data = new byte[] { 0xE3, 0x05, 0x4F, 0x02, 0xDD, 0xDD }; var tlvs = TLV.Parse(data); tlvs.Count.Should().Be(1); tlvs.First().Tag.ShouldAllBeEquivalentTo(0xE3); tlvs.First().Length.Should().Be(4); tlvs.First().NestedTags.Count.Should().Be(1); tlvs.First().NestedTags.First().Tag.ShouldAllBeEquivalentTo(0x4F); tlvs.First().NestedTags.First().Length.Should().Be(2); tlvs.First().NestedTags.First().Value.ShouldAllBeEquivalentTo(new byte[] { 0xDD, 0xDD }); }
/// <summary> /// Het complete RDWSecurityObject in het SOD (waarde van tag ‘04’) opnieuw laten parsen. /// </summary> /// <param name="efSod"></param> /// <param name="oidORdataGroupHashValues"></param> /// <returns>TLV</returns> public TLV ParseEFSOD(EFSOd efSod, string oidORdataGroupHashValues) { if (string.IsNullOrEmpty(oidORdataGroupHashValues)) { throw new ArgumentException("Argument should not be null or empty", "oidORdataGroupHashValues"); } if (efSod == null) { return(null); } TLV tlv = efSod.GetTag("1,30|1,A0|1,30|1,30|1,A0|1,04"); MemoryStream ms = new MemoryStream(tlv.Value); TLVList l = TLV.Parse(ms); return(l.getTag(oidORdataGroupHashValues)); }
public byte[] ReadFile(byte[] AID, byte[] FileID) { TS.TraceI("Readfile with AID \"{0}\" and FileID \"{1}\".", Helper.ByteArrayToString(AID), Helper.ByteArrayToString(FileID)); SelectApplet(AID); if (FileID.Length != 0x02) { throw new ArgumentException("Invalid length FileID", "FileID"); } if (this.crdReader == null) { throw new CardReaderException("No valid reader available"); } byte[] pbRecvBuffer = new byte[256]; //// Send SELECT File byte[] selectFile = new byte[] { 0x00, 0xA4, 0x02, 0x04, 0x02, FileID[0], FileID[1], 0x00 }; TS.TraceV("Select file with command: \"{0}\".", Helper.ByteArrayToString(selectFile)); /* * 00 = Class * A4 = Instructie * 02 = P1 (select EF under current DF) * 04 = P2 (return FCP data) * 02 = Lc * XX = Data * XX = Data * 00 = Le */ SCardError err = this.crdReader.Transmit(selectFile, ref pbRecvBuffer); if (err != SCardError.Success) { throw new CardReaderException(err, SCardHelper.StringifyError(err)); } ResponseApdu resp = new ResponseApdu(pbRecvBuffer, IsoCase.Case4Extended, this.crdReader.ActiveProtocol); if ((resp.SW1 != 0x90) && (resp.SW2 != 0x00)) { return(null); } byte[] fileInfo = resp.GetData(); if (fileInfo == null) { throw new CardReaderException(string.Format( "No data available reading FileID \"{0}\" with AID \"{1}\".", Helper.ByteArrayToString(FileID), Helper.ByteArrayToString(AID))); } TLVList myanswer = TLV.Parse(new MemoryStream(fileInfo)); TLV fileLengthTLV = myanswer.getTag("1,62|1,80"); if (fileLengthTLV == null) { throw new CardReaderException("Missing tag: 1,62|1,80"); } int fileLength = Helper.ByteArrayToInt(fileLengthTLV.Value); TS.TraceV("File length = \"{0}\".", fileLength); //// Read the remaining bytes for this file byte[] fileData = new byte[fileLength]; int bytesRead = 0; const int blockSize = 255; TS.TraceV("Start reading file with blocksize \"{0}\".", blockSize); while (bytesRead < fileLength) { int lngth = blockSize; if (fileLength - bytesRead < blockSize) { //// Cannot read an entire block anymore; adjust length of data to read lngth = fileLength - bytesRead; if (lngth == 0) { break; } } byte[] nextBlock = ReadFileNextBlock(bytesRead, lngth); Buffer.BlockCopy(nextBlock, 0, fileData, bytesRead, nextBlock.Length); bytesRead += nextBlock.Length; TS.TraceV("\"{0}\" bytes read.", bytesRead); } TS.TraceI("File read."); return(fileData); }