diff --git a/README.md b/README.md index 302bcfd..e150767 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,12 @@ OpenVsixSignTool sign --sha1 7213125958254779abbaa5033a12fecdf2c7cdc8 --timestam This signs the VSIX using a certificate in the certificate store using the SHA1 thumbprint, and uses a SHA256 file digest and SHA256 timestamp digest algorithm. +```shell +OpenVsixSignTool sign --subjectname "My Certificate" --timestamp http://timestamp.digicert.com -ta sha256 -fd sha256 myvsix.vsix +``` + +This signs the VSIX using a certificate in the certificate store using the subject name. + For more information about usage, use `OpenVsixSignTool sign --help` for more information. ## Core Library diff --git a/src/OpenVsixSignTool/Program.cs b/src/OpenVsixSignTool/Program.cs index 8436c59..6d505cc 100644 --- a/src/OpenVsixSignTool/Program.cs +++ b/src/OpenVsixSignTool/Program.cs @@ -11,6 +11,7 @@ internal static int Main(string[] args) { signConfiguration.Description = "Signs a VSIX package."; signConfiguration.HelpOption("-? | -h | --help"); + var subjectName = signConfiguration.Option("-n | --subjectname", "Specifies the name of the subject of the signing certificate.", CommandOptionType.SingleValue); var sha1 = signConfiguration.Option("-s | --sha1", "A hex-encoded SHA-1 thumbprint of the certificate used to sign the opc file.", CommandOptionType.SingleValue); var pfxPath = signConfiguration.Option("-c | --certificate", "A path to a PFX file to perform the signature.", CommandOptionType.SingleValue); var password = signConfiguration.Option("-p | --password", "The password for the PFX file.", CommandOptionType.SingleValue); @@ -29,9 +30,9 @@ internal static int Main(string[] args) signConfiguration.OnExecute(() => { var sign = new SignCommand(signConfiguration); - if (sha1.HasValue() || pfxPath.HasValue() || password.HasValue() || pfxPath.HasValue()) + if (subjectName.HasValue() || sha1.HasValue() || pfxPath.HasValue() || password.HasValue() || pfxPath.HasValue()) { - return sign.SignAsync(sha1, pfxPath, password, timestamp, timestampAlgorithm, fileDigest, force, file); + return sign.SignAsync(subjectName, sha1, pfxPath, password, timestamp, timestampAlgorithm, fileDigest, force, file); } else { diff --git a/src/OpenVsixSignTool/SignCommand.cs b/src/OpenVsixSignTool/SignCommand.cs index 1843372..0112151 100644 --- a/src/OpenVsixSignTool/SignCommand.cs +++ b/src/OpenVsixSignTool/SignCommand.cs @@ -28,6 +28,7 @@ public SignCommand(CommandLineApplication signCommandApplication) internal Task SignAsync ( + CommandOption subjectName, CommandOption sha1, CommandOption pfxPath, CommandOption password, @@ -37,22 +38,31 @@ internal Task SignAsync CommandOption force, CommandArgument vsixPath) { - if (!(sha1.HasValue() ^ pfxPath.HasValue())) + if ((sha1.HasValue() ? 1 : 0) + (pfxPath.HasValue() ? 1 : 0) + (subjectName.HasValue() ? 1 : 0) != 1) { - _signCommandApplication.Out.WriteLine("Either --sha1 or --certificate must be specified, but not both."); + _signCommandApplication.Out.WriteLine("Either --sha1, --subjectname or --certificate must be specified, but not a combination."); _signCommandApplication.ShowHelp(); return Task.FromResult(EXIT_CODES.INVALID_OPTIONS); } X509Certificate2 certificate; if (sha1.HasValue()) { - certificate = GetCertificateFromCertificateStore(sha1.Value()); + certificate = GetCertificateFromCertificateStore(X509FindType.FindByThumbprint, sha1.Value()); if (certificate == null) { _signCommandApplication.Out.WriteLine("Unable to locate certificate by thumbprint."); return Task.FromResult(EXIT_CODES.FAILED); } } + else if (subjectName.HasValue()) + { + certificate = GetCertificateFromCertificateStore(X509FindType.FindBySubjectName, subjectName.Value()); + if (certificate == null) + { + _signCommandApplication.Out.WriteLine("Unable to locate certificate by subject name."); + return Task.FromResult(EXIT_CODES.FAILED); + } + } else { var pfxFilePath = pfxPath.Value(); @@ -296,12 +306,12 @@ private static AsymmetricAlgorithm GetSigningKeyFromCertificate(X509Certificate2 } } - private static X509Certificate2 GetCertificateFromCertificateStore(string sha1) + private static X509Certificate2 GetCertificateFromCertificateStore(X509FindType findType, string value) { using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine)) { store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); - var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, sha1, false); + var certificates = store.Certificates.Find(findType, value, false); if (certificates.Count > 0) { return certificates[0]; @@ -311,7 +321,7 @@ private static X509Certificate2 GetCertificateFromCertificateStore(string sha1) using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); - var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, sha1, false); + var certificates = store.Certificates.Find(findType, value, false); if (certificates.Count == 0) { return null;