public void IsSigned_WithIncorrectSignatureFileNameInLocalFileHeader_ReturnsFalse()
        {
            var zipBytes = SigningTestUtility.GetResourceBytes("SignatureFileEntry.zip");
            var fileName = Encoding.ASCII.GetBytes(SigningSpecifications.V1.SignaturePath.ToUpper());

            Array.Copy(fileName, sourceIndex: 0, destinationArray: zipBytes, destinationIndex: 0x1e, length: fileName.Length);

            using (var test = new Test(zipBytes))
            {
                var isSigned = SignedPackageArchiveUtility.IsSigned(test.Reader);

                Assert.False(isSigned);
            }
        }
Example #2
0
        public async Task RemoveRepositorySignaturesAsync_WithUnsignedPackage_DoesNotChangePackage()
        {
            using (var test = new RemoveTest(_fixture))
                using (var input = new MemoryStream(test.Zip.ToByteArray(), writable: false))
                {
                    var wasSomethingRemoved = await SignedPackageArchiveUtility.RemoveRepositorySignaturesAsync(
                        input,
                        test.UnsignedPackage,
                        CancellationToken.None);

                    Assert.False(wasSomethingRemoved);
                    Assert.Equal(0, test.UnsignedPackage.Length);
                }
        }
        public async Task RemoveRepositorySignaturesAsync_WithRepositoryPrimarySignature_ReturnsUnsignedPackage()
        {
            using (var test = new RemoveTest(_fixture))
            {
                await test.RepositorySignAsync();

                var wasSomethingRemoved = await SignedPackageArchiveUtility.RemoveRepositorySignaturesAsync(
                    test.SignedPackage,
                    test.UnsignedPackage,
                    CancellationToken.None);

                Assert.True(wasSomethingRemoved);
                Assert.Equal(test.Zip.ToByteArray(), test.UnsignedPackage.ToArray());
            }
        }
        public async Task RemoveRepositorySignaturesAsync_WithAuthorPrimarySignature_DoesNotChangePackage()
        {
            using (var test = new RemoveTest(_fixture))
            {
                await test.AuthorSignAsync();

                var wasSomethingRemoved = await SignedPackageArchiveUtility.RemoveRepositorySignaturesAsync(
                    test.SignedPackage,
                    test.UnsignedPackage,
                    CancellationToken.None);

                Assert.False(wasSomethingRemoved);
                Assert.Equal(0, test.UnsignedPackage.Length);
            }
        }
        public void OpenPackageSignatureFileStream_WithFakeContent_ReturnsContent()
        {
            using (var test = new Test(GetResource("SignatureFileWithFakeContent.zip")))
                using (var stream = SignedPackageArchiveUtility.OpenPackageSignatureFileStream(test.Reader))
                {
                    Assert.False(stream.CanWrite);

                    using (var reader = new BinaryReader(stream))
                    {
                        var expectedBytes = Encoding.ASCII.GetBytes("content");
                        var actualBytes   = reader.ReadBytes((int)reader.BaseStream.Length);

                        Assert.Equal(expectedBytes, actualBytes);
                    }
                }
        }
        public override async Task <PrimarySignature> GetPrimarySignatureAsync(CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            ThrowIfZipReadStreamIsNull();

            PrimarySignature signature = null;

            if (await IsSignedAsync(token))
            {
                using (var bufferedStream = new ReadOnlyBufferedStream(ZipReadStream, leaveOpen: true))
                    using (var reader = new BinaryReader(bufferedStream, new UTF8Encoding(), leaveOpen: true))
                        using (var stream = SignedPackageArchiveUtility.OpenPackageSignatureFileStream(reader))
                        {
#if IS_DESKTOP
                            signature = PrimarySignature.Load(stream);
#endif
                        }
            }

            return(signature);
        }
Example #7
0
        public override string GetContentHashForSignedPackage(CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            ThrowIfZipReadStreamIsNull();

            using (var zip = new ZipArchive(ZipReadStream, ZipArchiveMode.Read, leaveOpen: true))
            {
                var signatureEntry = zip.GetEntry(SigningSpecifications.SignaturePath);

                if (signatureEntry == null ||
                    !string.Equals(signatureEntry.Name, SigningSpecifications.SignaturePath, StringComparison.Ordinal))
                {
                    return(null);
                }
            }

            using (var bufferedStream = new ReadOnlyBufferedStream(ZipReadStream, leaveOpen: true))
                using (var reader = new BinaryReader(bufferedStream, new UTF8Encoding(), leaveOpen: true))
                {
                    return(SignedPackageArchiveUtility.GetPackageContentHash(reader));
                }
        }
Example #8
0
        public override async Task <PrimarySignature> GetPrimarySignatureAsync(CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            if (ZipReadStream == null)
            {
                throw new SignatureException(Strings.SignedPackageUnableToAccessSignature);
            }

            PrimarySignature signature = null;

            if (await IsSignedAsync(token))
            {
                using (var reader = new BinaryReader(ZipReadStream, new UTF8Encoding(), leaveOpen: true))
                    using (var stream = SignedPackageArchiveUtility.OpenPackageSignatureFileStream(reader))
                    {
#if IS_DESKTOP
                        signature = PrimarySignature.Load(stream);
#endif
                    }
            }

            return(signature);
        }
        internal static bool VerifySignedNupkgIntegrity(string filePath)
        {
            bool isSigned = false;

            using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(filePath)))
            {
                isSigned = SignedPackageArchiveUtility.IsSigned(binaryReader);
#if NETFRAMEWORK
                if (isSigned)
                {
                    try
                    {
                        // A package will fail integrity checks if, for example, the package is signed and then:
                        // - it is repacked
                        // - it has its symbols stripped
                        // - it is otherwise modified
                        using (Stream stream = SignedPackageArchiveUtility.OpenPackageSignatureFileStream(binaryReader))
                        {
                            using (PackageArchiveReader par = new PackageArchiveReader(filePath))
                            {
                                var signature = par.GetPrimarySignatureAsync(CancellationToken.None).Result;

                                var task = par.ValidateIntegrityAsync(signature.SignatureContent, CancellationToken.None);
                                task.Wait();
                            }
                        }
                    }
                    catch (Exception)
                    {
                        isSigned = false;
                    }
                }
#endif
            }
            return(isSigned);
        }
Example #10
0
        private async Task <SignatureValidatorResult> StripRepositorySignaturesAsync(Context context)
        {
            Stream packageStreamToDispose = null;

            try
            {
                packageStreamToDispose = FileStreamUtility.GetTemporaryFile();

                var stopwatch = Stopwatch.StartNew();

                var changed = await SignedPackageArchiveUtility.RemoveRepositorySignaturesAsync(
                    context.PackageStream,
                    packageStreamToDispose,
                    context.CancellationToken);

                _telemetryService.TrackDurationToStripRepositorySignatures(
                    stopwatch.Elapsed,
                    context.Message.PackageId,
                    context.Message.PackageVersion,
                    context.Message.ValidationId,
                    changed);

                if (changed)
                {
                    _logger.LogInformation(
                        "Repository signatures were removed from package {PackageId} {PackageVersion} for validation {ValidationId}.",
                        context.Message.PackageId,
                        context.Message.PackageVersion,
                        context.Message.ValidationId);

                    // The input stream and the input signed package reader are no longer useful since they contain
                    // the removed repository signatures. We need to initialize the new signed package archive
                    // reader and signature.
                    context.PackageReader.Dispose();
                    context.PackageStream.Dispose();

                    context.PackageStream  = packageStreamToDispose;
                    context.Changed        = true;
                    packageStreamToDispose = null;
                    context.PackageReader  = new SignedPackageArchive(context.PackageStream, packageWriteStream: Stream.Null);

                    var initialSignature = context.Signature;

                    if (await context.PackageReader.IsSignedAsync(context.CancellationToken))
                    {
                        _logger.LogInformation(
                            "The package {PackageId} {PackageVersion} for validation {ValidationId} is still signed.",
                            context.Message.PackageId,
                            context.Message.PackageVersion,
                            context.Message.ValidationId);

                        context.Signature = await context.PackageReader.GetPrimarySignatureAsync(context.CancellationToken);

                        _telemetryService.TrackStrippedRepositorySignatures(
                            context.Message.PackageId,
                            context.Message.PackageVersion,
                            context.Message.ValidationId,
                            initialSignature,
                            context.Signature);
                    }
                    else
                    {
                        _logger.LogInformation(
                            "The package {PackageId} {PackageVersion} for validation {ValidationId} is no longer signed.",
                            context.Message.PackageId,
                            context.Message.PackageVersion,
                            context.Message.ValidationId);

                        // The package is now unsigned. This would happen if the primary signature was a repository
                        // signature that was removed.
                        context.Signature = null;

                        _telemetryService.TrackStrippedRepositorySignatures(
                            context.Message.PackageId,
                            context.Message.PackageVersion,
                            context.Message.ValidationId,
                            initialSignature,
                            outputSignature: null);

                        return(await HandleUnsignedPackageAsync(context));
                    }
                }
                else
                {
                    _logger.LogInformation(
                        "No repository signatures were removed from package {PackageId} {PackageVersion} for validation {ValidationId}.",
                        context.Message.PackageId,
                        context.Message.PackageVersion,
                        context.Message.ValidationId);
                }
            }
            finally
            {
                packageStreamToDispose?.Dispose();
            }

            return(null);
        }