public void ReadSignedArchiveMetadata_WhenReaderNull_Throws()
        {
            var exception = Assert.Throws <ArgumentNullException>(
                () => SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader: null));

            Assert.Equal("reader", exception.ParamName);
        }
        public void HashBytes_WhenHashAlgorithmNull_Throws()
        {
            var exception = Assert.Throws <ArgumentNullException>(
                () => SignedPackageArchiveIOUtility.HashBytes(
                    hashAlgorithm: null, bytes: new byte[] { 0 }));

            Assert.Equal("hashAlgorithm", exception.ParamName);
        }
Exemplo n.º 3
0
        public void SeekReaderForwardToMatchByteSignature_WhenReaderNull_Throws()
        {
            var exception = Assert.Throws <ArgumentNullException>(
                () => SignedPackageArchiveIOUtility.SeekReaderForwardToMatchByteSignature(
                    reader: null,
                    byteSignature: new byte[] { 0 }));

            Assert.Equal("reader", exception.ParamName);
        }
        public void ReadSignedArchiveMetadata_WithUnsignedPackage_Throws()
        {
            using (var stream = new MemoryStream(GetNonEmptyZip()))
                using (var reader = new BinaryReader(stream))
                {
                    var exception = Assert.Throws <SignatureException>(
                        () => SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader));

                    Assert.Equal(NuGetLogCode.NU3005, exception.Code);
                    Assert.Equal("The package does not contain a valid package signature file.", exception.Message);
                }
        }
        public void HashBytes_WhenBytesNullOrEmpty_Throws(byte[] bytes)
        {
            using (var hashAlgorithm = SHA256.Create())
            {
                var exception = Assert.Throws <ArgumentException>(
                    () => SignedPackageArchiveIOUtility.HashBytes(
                        hashAlgorithm,
                        bytes));

                Assert.Equal("bytes", exception.ParamName);
            }
        }
Exemplo n.º 6
0
        public void SeekReaderForwardToMatchByteSignature_WhenByteSignatureNullOrEmpty_Throws(byte[] byteSignature)
        {
            using (var test = new ReadTest())
            {
                var exception = Assert.Throws <ArgumentException>(
                    () => SignedPackageArchiveIOUtility.SeekReaderForwardToMatchByteSignature(
                        test.Reader,
                        byteSignature));

                Assert.Equal("byteSignature", exception.ParamName);
                Assert.Equal(0, test.Reader.BaseStream.Position);
            }
        }
        public void HashBytes_WithInputBytes_Hashes()
        {
            using (var hashAlgorithm = SHA256.Create())
            {
                SignedPackageArchiveIOUtility.HashBytes(hashAlgorithm, new byte[] { 0, 1, 2 });

                hashAlgorithm.TransformFinalBlock(new byte[0], inputOffset: 0, inputCount: 0);

                var actualHash = Convert.ToBase64String(hashAlgorithm.Hash);

                Assert.Equal("rksygOVuL6+D9BSm49q+nV++GJdlRMBf7RIazLhbU/w=", actualHash);
            }
        }
        public void ReadAndWriteUntilPosition_WhenReaderNull_Throws()
        {
            using (var test = new ReadWriteTest())
            {
                var exception = Assert.Throws <ArgumentNullException>(
                    () => SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(
                        reader: null,
                        writer: test.Writer,
                        position: 0));

                Assert.Equal("reader", exception.ParamName);
            }
        }
Exemplo n.º 9
0
        public void SeekReaderForwardToMatchByteSignature_WhenInitialPositionAtStartAndByteSignatureNotFound_Throws()
        {
            using (var test = new ReadTest())
            {
                var byteSignature = new byte[] { 3, 2 };

                Assert.Throws <InvalidDataException>(
                    () => SignedPackageArchiveIOUtility.SeekReaderForwardToMatchByteSignature(
                        test.Reader,
                        byteSignature));

                Assert.Equal(0, test.Reader.BaseStream.Position);
            }
        }
        public void ReadAndWriteUntilPosition_WhenPositionInMiddle_ReadsAndWrites()
        {
            using (var test = new ReadWriteTest())
            {
                test.Reader.BaseStream.Seek(offset: 2, origin: SeekOrigin.Begin);

                SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(test.Reader, test.Writer, position: 5);

                var actual = test.GetWrittenBytes();

                Assert.Equal(new byte[] { 2, 3, 4 }, actual);
                Assert.Equal(5, test.Reader.BaseStream.Position);
            }
        }
        private static Task ShiftSignatureMetadata(SigningSpecifications spec, BinaryReader reader, BinaryWriter writer, int centralDirectoryIndex, int fileHeaderIndex)
        {
            // Read metadata
            var metadata = SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader);

            // Update central directory records by excluding the signature entry
            SignedPackageArchiveIOUtility.UpdateSignedPackageArchiveMetadata(reader, metadata);

            // Calculate new central directory record metadata with the the signature record and entry shifted
            var shiftedCdr = ShiftMetadata(spec, metadata, newSignatureFileEntryIndex: fileHeaderIndex, newSignatureCentralDirectoryRecordIndex: centralDirectoryIndex);

            // Order records by shifted ofset (new offset = old offset + change in offset).
            // This is the order they will appear in the new shifted package, but not necesarily the same order they were in the old package
            shiftedCdr.Sort((x, y) => (x.OffsetToFileHeader + x.ChangeInOffset).CompareTo(y.OffsetToFileHeader + y.ChangeInOffset));

            // Write data from start of file to first file entry
            reader.BaseStream.Seek(offset: 0, origin: SeekOrigin.Begin);
            SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(reader, writer, metadata.StartOfFileHeaders);

            // Write all file entries in the new order
            foreach (var entry in shiftedCdr)
            {
                // We need to read each entry from their position in the old package and write them sequencially to the new package
                // The order in which they will appear in the new shited package is defined by the sorting done before starting to write
                reader.BaseStream.Seek(offset: entry.OffsetToFileHeader, origin: SeekOrigin.Begin);
                SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(reader, writer, entry.OffsetToFileHeader + entry.FileEntryTotalSize);
            }

            // Write all central directory records with updated offsets
            // We first need to sort them in the order they will appear in the new shifted package
            shiftedCdr.Sort((x, y) => x.IndexInHeaders.CompareTo(y.IndexInHeaders));
            foreach (var entry in shiftedCdr)
            {
                reader.BaseStream.Seek(offset: entry.Position, origin: SeekOrigin.Begin);
                // Read and write from the start of the central directory record until the relative offset of local file header (42 from the start of central directory record, incluing signature length)
                SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(reader, writer, reader.BaseStream.Position + 42);

                var relativeOffsetOfLocalFileHeader = (uint)(reader.ReadUInt32() + entry.ChangeInOffset);
                writer.Write(relativeOffsetOfLocalFileHeader);

                // We already read and hash the whole header, skip only filenameLength + extraFieldLength + fileCommentLength (46 is the size of the header without those lengths)
                SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(reader, writer, reader.BaseStream.Position + entry.HeaderSize - CentralDirectoryFileHeaderSizeWithoutSignature);
            }

            // Write everything after central directory records
            reader.BaseStream.Seek(offset: metadata.EndOfCentralDirectory, origin: SeekOrigin.Begin);
            SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(reader, writer, reader.BaseStream.Length);

            return(Task.FromResult(0));
        }
        public void ReadAndWriteUntilPosition_WhenPositionTooBig_Throws()
        {
            using (var test = new ReadWriteTest())
            {
                var exception = Assert.Throws <ArgumentOutOfRangeException>(
                    () => SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(
                        test.Reader,
                        test.Writer,
                        test.Reader.BaseStream.Length + 1));

                Assert.Equal("position", exception.ParamName);
                Assert.Equal(0, test.Reader.BaseStream.Position);
            }
        }
        public void ReadAndWriteUntilPosition_WhenPositionAtStart_ReadsAndWrites()
        {
            using (var test = new ReadWriteTest())
            {
                SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(
                    test.Reader,
                    test.Writer,
                    test.Reader.BaseStream.Length);

                var actual = test.GetWrittenBytes();

                Assert.Equal(test.Bytes, actual);
                Assert.Equal(test.Reader.BaseStream.Length, test.Reader.BaseStream.Position);
            }
        }
Exemplo n.º 14
0
        public void SeekReaderForwardToMatchByteSignature_WhenByteSignatureNotFound_MessageContainsByteSignature()
        {
            using (var test = new ReadTest())
            {
                var byteSignature = new byte[] { 6, 7 };

                var exception = Assert.Throws <InvalidDataException>(
                    () => SignedPackageArchiveIOUtility.SeekReaderForwardToMatchByteSignature(
                        test.Reader,
                        byteSignature));

                Assert.Contains(BitConverter.ToString(byteSignature).Replace("-", ""), exception.Message);
                Assert.Equal(0, test.Reader.BaseStream.Position);
            }
        }
        public void ReadSignedArchiveMetadata_WithOnlyPackageSignatureEntry_ReturnsMetadata()
        {
            using (var stream = new MemoryStream(GetResource("SignatureFileEntry.zip")))
                using (var reader = new BinaryReader(stream))
                {
                    var metadata = SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader);

                    Assert.Equal(1, metadata.CentralDirectoryHeaders.Count);
                    Assert.Equal(0, metadata.SignatureCentralDirectoryHeaderIndex);

                    var header = metadata.CentralDirectoryHeaders[0];

                    Assert.True(header.IsPackageSignatureFile);
                }
        }
        public void ReadAndHashUntilPosition_WhenPositionAtStart_ReadsAndHashes()
        {
            using (var test = new ReadHashTest())
            {
                SignedPackageArchiveIOUtility.ReadAndHashUntilPosition(
                    test.Reader,
                    test.HashAlgorithm,
                    test.Reader.BaseStream.Length);

                var actualHash = test.GetHash();

                Assert.Equal("F+iNsYev1iwW5d6/PmUnzQBrwBK8kLUagQzYDC1RH0M=", actualHash);
                Assert.Equal(test.Reader.BaseStream.Length, test.Reader.BaseStream.Position);
            }
        }
Exemplo n.º 17
0
        public void ReadSignedArchiveMetadata_WithSignedPackage_ReturnsMetadata()
        {
            using (var stream = new MemoryStream(GetResource("SignedPackage.1.0.0.nupkg")))
                using (var reader = new BinaryReader(stream))
                {
                    var metadata = SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader);

                    Assert.Equal(0, metadata.StartOfLocalFileHeaders);
                    Assert.Equal(0xbcc, metadata.EndOfLocalFileHeaders);

                    Assert.Equal(6, metadata.CentralDirectoryHeaders.Count);
                    Assert.Equal(0xd7c, metadata.EndOfCentralDirectory);

                    Assert.Equal(5, metadata.SignatureCentralDirectoryHeaderIndex);

                    var expectedHeaders = new[]
                    {
                        new { ChangeInOffset         = 0L, FileEntryTotalSize = 0x136, HeaderSize = 0x39, IndexInHeaders = 0,
                              IsPackageSignatureFile = false, OffsetToFileHeader = 0, Position = 0xbcc },
                        new { ChangeInOffset         = 0L, FileEntryTotalSize = 0x110, HeaderSize = 0x42, IndexInHeaders = 1,
                              IsPackageSignatureFile = false, OffsetToFileHeader = 0x136, Position = 0xc05 },
                        new { ChangeInOffset         = 0L, FileEntryTotalSize = 0x29, HeaderSize = 0x39, IndexInHeaders = 2,
                              IsPackageSignatureFile = false, OffsetToFileHeader = 0x246, Position = 0xc47 },
                        new { ChangeInOffset         = 0L, FileEntryTotalSize = 0xff, HeaderSize = 0x41, IndexInHeaders = 3,
                              IsPackageSignatureFile = false, OffsetToFileHeader = 0x26f, Position = 0xc80 },
                        new { ChangeInOffset         = 0L, FileEntryTotalSize = 0x1dd, HeaderSize = 0x7f, IndexInHeaders = 4,
                              IsPackageSignatureFile = false, OffsetToFileHeader = 0x36e, Position = 0xcc1 },
                        new { ChangeInOffset         = 0L, FileEntryTotalSize = 0x681, HeaderSize = 0x3c, IndexInHeaders = 5,
                              IsPackageSignatureFile = true, OffsetToFileHeader = 0x54b, Position = 0xd40 },
                    };

                    Assert.Equal(expectedHeaders.Length, metadata.CentralDirectoryHeaders.Count);

                    for (var i = 0; i < expectedHeaders.Length; ++i)
                    {
                        var expectedHeader = expectedHeaders[i];
                        var actualHeader   = metadata.CentralDirectoryHeaders[i];

                        Assert.Equal(expectedHeader.Position, actualHeader.Position);
                        Assert.Equal(expectedHeader.OffsetToFileHeader, actualHeader.OffsetToLocalFileHeader);
                        Assert.Equal(expectedHeader.FileEntryTotalSize, actualHeader.FileEntryTotalSize);
                        Assert.Equal(expectedHeader.IsPackageSignatureFile, actualHeader.IsPackageSignatureFile);
                        Assert.Equal(expectedHeader.HeaderSize, actualHeader.HeaderSize);
                        Assert.Equal(expectedHeader.ChangeInOffset, actualHeader.ChangeInOffset);
                        Assert.Equal(expectedHeader.IndexInHeaders, actualHeader.IndexInHeaders);
                    }
                }
        }
        public void ReadAndWriteUntilPosition_WhenPositionBeforeCurrentReadPosition_Throws()
        {
            using (var test = new ReadWriteTest())
            {
                test.Reader.BaseStream.Seek(offset: 1, origin: SeekOrigin.Begin);

                var exception = Assert.Throws <ArgumentOutOfRangeException>(
                    () => SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(
                        test.Reader,
                        test.Writer,
                        position: 0));

                Assert.Equal("position", exception.ParamName);
                Assert.Equal(1, test.Reader.BaseStream.Position);
            }
        }
Exemplo n.º 19
0
        public void SeekReaderBackwardToMatchByteSignature_WhenInitialPositionNearEndAndByteSignatureNotFound_Throws()
        {
            using (var test = new ReadTest())
            {
                var byteSignature = new byte[] { 3, 2 };

                test.Reader.BaseStream.Seek(offset: -byteSignature.Length, origin: SeekOrigin.End);

                Assert.Throws <InvalidDataException>(
                    () => SignedPackageArchiveIOUtility.SeekReaderBackwardToMatchByteSignature(
                        test.Reader,
                        byteSignature));

                Assert.Equal(4, test.Reader.BaseStream.Position);
            }
        }
Exemplo n.º 20
0
        public void ReadSignedArchiveMetadata_WithNonEmptyZip_ReturnsMetadata()
        {
            using (var stream = new MemoryStream(GetResource("3Entries.zip")))
                using (var reader = new BinaryReader(stream))
                {
                    var metadata = SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader);

                    Assert.Equal(0, metadata.StartOfFileHeaders);
                    Assert.Equal(0x84, metadata.EndOfFileHeaders);

                    Assert.Equal(3, metadata.CentralDirectoryHeaders.Count);
                    Assert.Equal(0x11d, metadata.EndOfCentralDirectory);
                    Assert.Equal(0x11d, metadata.EndOfCentralDirectoryRecordPosition);

                    Assert.Equal(0, metadata.SignatureCentralDirectoryHeaderIndex);

                    var header = metadata.CentralDirectoryHeaders[0];

                    Assert.Equal(0x84, header.Position);
                    Assert.Equal(0, header.OffsetToFileHeader);
                    Assert.Equal(0x2a, header.FileEntryTotalSize);
                    Assert.Equal("1.txt", header.Filename);
                    Assert.Equal(0x33, header.HeaderSize);
                    Assert.Equal(0, header.ChangeInOffset);
                    Assert.Equal(0, header.IndexInHeaders);

                    header = metadata.CentralDirectoryHeaders[1];

                    Assert.Equal(0xb7, header.Position);
                    Assert.Equal(0x2a, header.OffsetToFileHeader);
                    Assert.Equal(0x2f, header.FileEntryTotalSize);
                    Assert.Equal("2.txt", header.Filename);
                    Assert.Equal(0x33, header.HeaderSize);
                    Assert.Equal(0, header.ChangeInOffset);
                    Assert.Equal(1, header.IndexInHeaders);

                    header = metadata.CentralDirectoryHeaders[2];

                    Assert.Equal(0xea, header.Position);
                    Assert.Equal(0x59, header.OffsetToFileHeader);
                    Assert.Equal(0x2b, header.FileEntryTotalSize);
                    Assert.Equal("3.txt", header.Filename);
                    Assert.Equal(0x33, header.HeaderSize);
                    Assert.Equal(0, header.ChangeInOffset);
                    Assert.Equal(2, header.IndexInHeaders);
                }
        }
Exemplo n.º 21
0
        public void SeekReaderBackwardToMatchByteSignature_WhenInitialPositionAtEnd_Throws()
        {
            using (var test = new ReadTest())
            {
                var byteSignature = new byte[] { 2, 3 };

                test.Reader.BaseStream.Seek(offset: 0, origin: SeekOrigin.End);

                var exception = Assert.Throws <ArgumentOutOfRangeException>(
                    () => SignedPackageArchiveIOUtility.SeekReaderBackwardToMatchByteSignature(
                        test.Reader,
                        byteSignature));

                Assert.Equal("byteSignature", exception.ParamName);
                Assert.Equal(test.Reader.BaseStream.Length, test.Reader.BaseStream.Position);
            }
        }
        public void ReadAndHashUntilPosition_WhenPositionInMiddle_ReadsAndHashes()
        {
            using (var test = new ReadHashTest())
            {
                test.Reader.BaseStream.Seek(offset: 2, origin: SeekOrigin.Begin);

                SignedPackageArchiveIOUtility.ReadAndHashUntilPosition(
                    test.Reader,
                    test.HashAlgorithm,
                    position: 5);

                var actualHash = test.GetHash();

                Assert.Equal("H1KP/SiVY0wXZTfAVdqlwJcbeRVRmZkzeg41VBDY/Zg=", actualHash);
                Assert.Equal(5, test.Reader.BaseStream.Position);
            }
        }
Exemplo n.º 23
0
        public void SeekReaderBackwardToMatchByteSignature_WhenInitialPositionNearEndAndByteSignatureAtStart_Seeks()
        {
            using (var test = new ReadTest())
            {
                var byteSignature = new byte[] { 0, 1 };

                test.Reader.BaseStream.Seek(offset: -byteSignature.Length, origin: SeekOrigin.End);

                SignedPackageArchiveIOUtility.SeekReaderBackwardToMatchByteSignature(test.Reader, byteSignature);

                Assert.Equal(0, test.Reader.BaseStream.Position);

                var actual = test.Reader.ReadBytes(byteSignature.Length);

                Assert.Equal(byteSignature, actual);
            }
        }
Exemplo n.º 24
0
        public void SeekReaderForwardToMatchByteSignature_WhenInitialPositionAtStartAndByteSignatureAtEnd_Seeks()
        {
            using (var test = new ReadTest())
            {
                var byteSignature = new byte[] { 4, 5 };

                test.Reader.BaseStream.Seek(offset: 0, origin: SeekOrigin.Begin);

                SignedPackageArchiveIOUtility.SeekReaderForwardToMatchByteSignature(test.Reader, byteSignature);

                Assert.Equal(4, test.Reader.BaseStream.Position);

                var actual = test.Reader.ReadBytes(byteSignature.Length);

                Assert.Equal(byteSignature, actual);
            }
        }
        public void ReadAndWriteUntilPosition_WhenPositionAtEnd_ReadsAndWrites()
        {
            using (var test = new ReadWriteTest())
            {
                test.Reader.BaseStream.Seek(offset: 0, origin: SeekOrigin.End);

                SignedPackageArchiveIOUtility.ReadAndWriteUntilPosition(
                    test.Reader,
                    test.Writer,
                    test.Reader.BaseStream.Length);

                var actual = test.GetWrittenBytes();

                Assert.Empty(actual);
                Assert.Equal(test.Reader.BaseStream.Length, test.Reader.BaseStream.Position);
            }
        }
        public void ReadAndHashUntilPosition_WhenPositionAtEnd_ReadsAndHashes()
        {
            using (var test = new ReadHashTest())
            {
                test.Reader.BaseStream.Seek(offset: 0, origin: SeekOrigin.End);

                SignedPackageArchiveIOUtility.ReadAndHashUntilPosition(
                    test.Reader,
                    test.HashAlgorithm,
                    test.Reader.BaseStream.Length);

                var actualHash = test.GetHash();

                Assert.Equal("47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", actualHash);
                Assert.Equal(test.Reader.BaseStream.Length, test.Reader.BaseStream.Position);
            }
        }
        public void ReadSignedArchiveMetadata_WithEmptyZip_Throws()
        {
            using (var stream = new MemoryStream())
            {
                using (var zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
                {
                }

                stream.Seek(offset: 0, loc: SeekOrigin.Begin);

                using (var reader = new BinaryReader(stream))
                {
                    Assert.Throws <InvalidDataException>(
                        () => SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader));
                }
            }
        }