2

Is there a way to check a dll file inside a NuGet package when installing it using NuGet API.

Scenario:

I want a c#/.net application to be able to update itself at runtime using NuGet packages. Since this is obviously pretty risky I would like to verify that the package comes from the source I expect it to come from.

Problem:

NuGet does not support package signing. There is a paper addressing the issue here: https://blog.nuget.org/20150203/package-signing.html

What I have done so far:

  1. Build an empty project
  2. Sign the dll file (signtool sign /t http://timestamp.digicert.com /a ".\app.dll")
  3. Create a NuGet package from it (nuget spec add.dll, nuget pack .\app.dll.nuspec)

The dll file inside the NuGet package is now signed and I can upload it to a NuGet repo.

This is my application code:

public static void installPackage(string packageId, string connectionString, string path){
        IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(connectionString);

        PackageManager packageManager = new PackageManager(repo, path);

        packageManager.InstallPackage(packageId);
    }

The example is taken from here:

https://blog.nuget.org/20130520/Play-with-packages.html

The only possible solution I can imagine at the moment would be to use a download package function from the NuGet API, unpack the downloaded package, do the check and install afterwards. Sadly I can not find any hint in the API that the install process could be done in those two steps.

Alternatively, I could use PGP to create a detached signature, sign the NuGet package itself and do a check on the NuGet package with the detached signature. However, that leads to the same problem of first being able to download the package.

I would be grateful for any hint! Thank you.

--- Update ---

I think I have found a way to use NuGet and PGP signing for package verification. I am doing the following:

  1. Get list of available NuGets from NuGet Server (I am using Nexus)
  2. Mark a file for installation
  3. The Package provides a download link:

    IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(<connectionString>);
    
    DataServicePackage package = (DataServicePackage) repo.FindPackage(packageId);
    String downloadUrl = package.DownloadUrl.AbsoluteUri;
    
  4. Download the package and store on disk:

using (var client = new WebClient()){
    client.UseDefaultCredentials = true;
    client.Credentials = new NetworkCredential(<User>, <Pass>);
    var content = client.DownloadData(downloadUrl);
    using (MemoryStream memoryStream = new MemoryStream(content)){
        FileStream fs = new FileStream(<pathToLocalRepo>, FileMode.CreateNew);
        memoryStream.CopyTo(fs);
        fs.Close();
    }
}
  1. Download the detached signature from a different server
  2. Verify the detached signature and the downloaded nupkg (I used BouncyCastle)
  3. If verification succeeds:
  4. Use the directory the file is stored as new repository and install the package from there
//Initialize local repository
string path = <pathToLocalRepo>;
IPackageRepository localRepo = PackageRepositoryFactory.Default.CreateRepository(path);
var packages = repo.GetPackages();
//Initialize the package manager
PackageManager packageManager = new PackageManager(localRepo, path);
//Install
packageManager.InstallPackage(<packageId>);

Using this approach still leaves you with the possibility to authenticode the files inside the NuGet package.

Happy to hear what you guys think about this solution. Thanks!

Ritzelprimpf
  • 176
  • 1
  • 11

1 Answers1

1

Simply checking the dlls inside a package may not be the safest option as a malicious file can be added the package which can compromise your intent/machine. The NuGet team is working on allowing author signing for packages. In that process you will have NuGet.exe sign <package> and NuGet.exe verify <package> commands. You can read more about it the the blog post. The detailed specs are at - Sign Command and Verify Command.


Update - NuGet team has finished implementing package signing and verification. You can now sign a package, as described here and verify the integrity of a package (among other things) as described here.

You can read about the technical specifications here.

Ankit Mishra
  • 474
  • 3
  • 11
  • Your blog post link is pointing to a 404. However, I have read, that there is a plan to implement package signing with asp.net 5 - That still leaves the question what to do in between. – Ritzelprimpf Oct 19 '17 at 08:51
  • Thanks for pointing that out. i have updated the blog post link. – Ankit Mishra Oct 27 '17 at 23:35