From b0dc2b16fc43f5d29347a9c8c5cb42f37d9ef91e Mon Sep 17 00:00:00 2001 From: TheCakeIsNaOH Date: Sat, 15 Jul 2023 21:44:44 -0500 Subject: [PATCH] (#1144) Add validation for package hash --- .../services/NugetService.cs | 62 ++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 354fa6ca6..c484490aa 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -811,7 +811,36 @@ Version was specified as '{0}'. It is possible that version NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), _nugetLogger, CancellationToken.None).GetAwaiter().GetResult()) { - //TODO, do check on downloadResult + // Folder based sources and v3 api based sources do not provide package hashes when getting metadata + if (packageDependencyInfo.PackageHash is null) + { + this.Log().Debug("Source does not provide a package hash, skipping package checksum validation"); + } + else + { + using (var metadataFileStream = + downloadResult.PackageReader.GetStream(PackagingCoreConstants.NupkgMetadataFileExtension)) + { + var metadataFileContents = NupkgMetadataFileFormat.Read(metadataFileStream, _nugetLogger, + PackagingCoreConstants.NupkgMetadataFileExtension); + if (!packageDependencyInfo.PackageHash.Length.Equals(metadataFileContents.ContentHash.Length)) + { + this.Log().Warn("Package hash length mismatch, server may not be sending sha512 hash"); + } + else if (packageDependencyInfo.PackageHash.Equals(metadataFileContents.ContentHash, StringComparison.OrdinalIgnoreCase)) + { + this.Log().Debug("Package checksum matches expected checksum"); + } + else + { + var errorMessage = + "Package checksum '{0}' did not match expected checksum '{1}'" + .FormatWith(metadataFileContents.ContentHash, + packageDependencyInfo.PackageHash); + throw new InvalidDataException(errorMessage); + } + } + } nugetProject.InstallPackageAsync( packageDependencyInfo, @@ -1493,7 +1522,36 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), _nugetLogger, CancellationToken.None).GetAwaiter().GetResult()) { - //TODO, do check on downloadResult + // Folder based sources and v3 api based sources do not provide package hashes when getting metadata + if (packageDependencyInfo.PackageHash is null) + { + this.Log().Debug("Source does not provide a package hash, skipping package checksum validation"); + } + else + { + using (var metadataFileStream = + downloadResult.PackageReader.GetStream(PackagingCoreConstants.NupkgMetadataFileExtension)) + { + var metadataFileContents = NupkgMetadataFileFormat.Read(metadataFileStream, _nugetLogger, + PackagingCoreConstants.NupkgMetadataFileExtension); + if (!packageDependencyInfo.PackageHash.Length.Equals(metadataFileContents.ContentHash.Length)) + { + this.Log().Warn("Package hash length mismatch, server may not be sending sha512 hash"); + } + else if (packageDependencyInfo.PackageHash.Equals(metadataFileContents.ContentHash, StringComparison.OrdinalIgnoreCase)) + { + this.Log().Debug("Package checksum matches expected checksum"); + } + else + { + var errorMessage = + "Package checksum '{0}' did not match expected checksum '{1}'" + .FormatWith(metadataFileContents.ContentHash, + packageDependencyInfo.PackageHash); + throw new InvalidDataException(errorMessage); + } + } + } nugetProject.InstallPackageAsync( packageDependencyInfo,