Code signing Visual Studio 2010 extensions (VSIX)

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.

  • Pingback: Dew Drop – March 3, 2010 | Alvin Ashcraft's Morning Dew

  • Stefan Wenig

    Great tool! The signed vsix works as expected for local installation.

    However, if I try and load it into VS Code Gallery, I get: “Invalid Certificate in VSIX”. So I have to provide a link instead. Do you have any experience with Code Gallery? Any idea if your tool causes this, or something else? We use a GoDaddy authenticode cert.

    Here’s the thing: http://licensemanager.codeplex.com/releases

    Any help appreciated!

    Thanks, Stefan

  • Anonymous

    Unfortunately I believe my code signing certificate expired and I didn’t
    properly sign it the first time (with a time server).

  • Stefan Wenig

    ok, now i’m confused. what kind of certificate would you – as the tool’s author – need, and how does this affect me?
    I’m using our own Go Daddy certificate, and like I said, it works for VS, but not for Code Gallery.

    intended for:
    Ensures software came from software publisher
    Protects software from alteration after publication
    2.16.840.1.114413.1.7.23.2

    issued to: rubicon informationstechn gmbh
    issued by: Go Daddy Secure Certification Authority
    valid from 2010-04-13 to 2013-04-13

    issuer stmt: https://certs.godaddy.com/anonymous/repository.seam

    sig. algorithm: sha1RSA
    hash alg.: sha1
    key usage: Digital Signature (80)
    thumbprint alg.: sha1

    cert path:
    Go Daddy Class 2 Certification Authority
    Go Daddy Secure Certification Authority
    rubicon informationstechn gmbh

    any idea what’s going on?

    thanks for your help!

  • Anonymous

    You need and Authenticode cert… which it sounds like you have. Maybe an
    issue with the final package?