Code signing Visual Studio 2010 extensions (VSIX)

2 March 2010

To follow up my “epic code signing” post, I wanted to share a small app I built to code sign Visual Studio 2010 Extensions.

VSIX files can contain a digital signature

Which extension would you rather install? Here’s one without a digital signature:

Download and Install

And one with:

Visual Studio Extension Installer

Download My SignExtension Tool

This is a simple .NET 4 app that allows you to select your .Vsix file, your .Pfx file, enter a password, and sign away.

SignExtension.zip (30 KB, contains the app only. App is signed.)
SignExtension.Source.zip (27 KB, contains the Visual Studio 2010 project source for .NET 4 only)

Visual Studio Extension Signing

How to manually sign an extension

The new .Vsix files are really glorified zip files, and the extensions manager is able to identify when such files have a verified digital signature. However, there isn’t a Subject Interface Package (SIP) for VSIX, so the traditional SignTool.exe program cannot sign extension packages.

Instead, you need to use the System.IO.Packaging namespace and the PackageDigitalSignatureManager type to sign, using a X509Certificate2 type.

It took some trial and error, plus discussion searching, to find the best common practice for this. Here’s some of that key code:

private static void SignAllParts(Package package, string pfx, string password, string timestamp)
        {
            var signatureManager = new PackageDigitalSignatureManager(package);
            signatureManager.CertificateOption = CertificateEmbeddingOption.InSignaturePart;

            List<Uri> toSign = new List<Uri>();
            foreach (PackagePart packagePart in package.GetParts())
            {
                toSign.Add(packagePart.Uri);
            }

            toSign.Add(PackUriHelper.GetRelationshipPartUri(signatureManager.SignatureOrigin));
            toSign.Add(signatureManager.SignatureOrigin);
            toSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute)));

            try
            {
                signatureManager.Sign(toSign, new System.Security.Cryptography.X509Certificates.X509Certificate2(pfx, password));
            }
            catch (System.Security.Cryptography.CryptographicException ex)
            {
                System.Windows.Forms.MessageBox.Show("Signing could not be completed: " + ex.Message, "Signing Failure");
            }
        }

Hope this helps.

Jeff Wilcox is a Software Engineer at Microsoft in the Open Source Programs Office (OSPO), helping Microsoft engineers use, contribute to and release open source at scale.

comments powered by Disqus