public void TestMessage() { var output = ("The following certificates were considered:\r\n " + "Issued to: localhost\r\n Issued by: localhost\r\n " + "Expires: Wed May 05 23:39:42 2021\r\n " + "SHA1 hash: E323874CD3FB890842AB09791CD605F8D3A5340F\r\n " + "Issued to: ddfe70e5-4d2b-4940-a550-66f4f7d8307c\r\n " + "Issued by: MS-Organization-Access\r\n " + "Expires: Sun May 05 23:57:34 2030\r\n " + "SHA1 hash: D1AABEE4733FE30E1D6317427E88CA973406025B\r\n " + "Issued to: Marcin Otorowski\r\n " + "Issued by: Certum Code Signing CA SHA2\r\n " + "Expires: Tue Dec 29 13:55:03 2020\r\n " + "SHA1 hash: C362045164EFCDA4E40473F0B3B6B1D3E647CA6F\r\n " + "Issued to: bc64c50169ddad94\r\n " + "Issued by: Token Signing Public Key\r\n " + "Expires: Wed May 13 01:07:14 2020\r\n " + "SHA1 hash: A33983F854D4C7C6FAC5CC754656DC7CCA5ACEEF\r\n" + "After EKU filter, 1 certs were left.\r\n" + "After expiry filter, 1 certs were left.\r\n" + "After Hash filter, 0 certs were left.\r\n" + "After Private Key filter, 0 certs were left. \r\n") .Split("\r\n").ToList(); MsixSdkWrapper.TryGetErrorMessageFromSignToolOutput(output, out var error); Assert.IsTrue(error.Contains("EKU", StringComparison.CurrentCultureIgnoreCase)); }
public override async Task <int> Execute() { var msixSdkWrapper = new MsixSdkWrapper(); Logger.Info($"Packing [{this.Verb.Directory}] to [{this.Verb.Package}]..."); try { await this.Console.WriteInfo($"Packing [{this.Verb.Directory}] to [{this.Verb.Package}]...").ConfigureAwait(false); await msixSdkWrapper.PackPackageDirectory(this.Verb.Directory, this.Verb.Package, !this.Verb.NoCompression, !this.Verb.NoValidation).ConfigureAwait(false); await this.Console.WriteSuccess($"Package [{this.Verb.Package}] has been created."); return(0); } catch (SdkException e) { Logger.Error(e); await this.Console.WriteError(e.Message); return(e.ExitCode); } catch (Exception e) { Logger.Error(e); await this.Console.WriteError(e.Message); return(1); } }
public override async Task <int> Execute() { var msixSdkWrapper = new MsixSdkWrapper(); Logger.Info($"Unpacking [{this.Verb.Package}] to [{this.Verb.Directory}]..."); try { await this.Console.WriteInfo($"Unpacking [{this.Verb.Directory}] to [{this.Verb.Package}]...").ConfigureAwait(false); await msixSdkWrapper.UnpackPackage(this.Verb.Package, this.Verb.Directory).ConfigureAwait(false); await this.Console.WriteSuccess($"Package has been unpacked to [{this.Verb.Directory}]."); return(0); } catch (SdkException e) { Logger.Error(e); await this.Console.WriteError(e.Message); return(e.ExitCode); } catch (Exception e) { Logger.Error(e); await this.Console.WriteError(e.Message); return(1); } }
private static string GetVersion(string sdkFile) { var path = MsixSdkWrapper.GetSdkPath(sdkFile); if (!File.Exists(path)) { return(null); } return(FileVersionInfo.GetVersionInfo(path).ProductVersion); }
public async Task<string> GetSubjectFromDeviceGuardSigning(string dgssTokenPath, CancellationToken cancellationToken = default) { Logger.Info("Getting certificate subject for Device Guard signing..."); var tempFilePath = Path.Combine(Path.GetTempPath(), "msix-hero-" + Guid.NewGuid().ToString("N") + ".cat"); try { var name = typeof(DeviceGuardHelper).Assembly.GetManifestResourceNames().First(n => n.EndsWith("MSIXHeroTest.cat")); using (var manifestResourceStream = typeof(DeviceGuardHelper).Assembly.GetManifestResourceStream(name)) { if (manifestResourceStream == null) { throw new InvalidOperationException("Cannot extract temporary file."); } Logger.Debug($"Creating temporary file path {tempFilePath}"); using (var fileStream = File.Create(tempFilePath)) { manifestResourceStream.Seek(0L, SeekOrigin.Begin); await manifestResourceStream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false); } } var sdk = new MsixSdkWrapper(); Logger.Debug($"Signing temporary file path {tempFilePath}"); await sdk.SignPackageWithDeviceGuard(new[] {tempFilePath}, "SHA256", dgssTokenPath, null, cancellationToken).ConfigureAwait(false); using (var fromSignedFile = X509Certificate.CreateFromSignedFile(tempFilePath)) { Logger.Info($"Certificate subject is {tempFilePath}"); return fromSignedFile.Subject; } } catch (Exception e) { Logger.Error("Could not read subject from Device Guard certificate.", e); throw; } finally { if (File.Exists(tempFilePath)) { Logger.Debug($"Removing {tempFilePath}"); ExceptionGuard.Guard(() => File.Delete(tempFilePath)); } } }
public async Task SignPackageWithPfx( string package, bool updatePublisher, string pfxPath, SecureString password, string timestampUrl = null, IncreaseVersionMethod increaseVersion = IncreaseVersionMethod.None, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { Logger.Info("Signing package {0} using PFX {1}.", package, pfxPath); if (!File.Exists(pfxPath)) { throw new FileNotFoundException($"File {pfxPath} does not exit."); } Logger.Debug("Analyzing given certificate..."); var x509 = new X509Certificate2(await File.ReadAllBytesAsync(pfxPath, cancellationToken).ConfigureAwait(false), password); var localCopy = await this.PreparePackageForSigning(package, updatePublisher, increaseVersion, x509, cancellationToken).ConfigureAwait(false); try { cancellationToken.ThrowIfCancellationRequested(); string type; if (x509.SignatureAlgorithm.FriendlyName.EndsWith("rsa", StringComparison.OrdinalIgnoreCase)) { type = x509.SignatureAlgorithm.FriendlyName.Substring(0, x509.SignatureAlgorithm.FriendlyName.Length - 3).ToUpperInvariant(); } else { throw new NotSupportedException($"Signature algorithm {x509.SignatureAlgorithm.FriendlyName} is not supported."); } var openTextPassword = new System.Net.NetworkCredential(string.Empty, password).Password; Logger.Debug("Signing package {0} with algorithm {1}.", localCopy, x509.SignatureAlgorithm.FriendlyName); var sdk = new MsixSdkWrapper(); progress?.Report(new ProgressData(25, "Signing...")); await sdk.SignPackageWithPfx(new[] { localCopy }, type, pfxPath, openTextPassword, timestampUrl, cancellationToken).ConfigureAwait(false); progress?.Report(new ProgressData(75, "Signing...")); await Task.Delay(500, cancellationToken).ConfigureAwait(false); Logger.Debug("Moving {0} to {1}.", localCopy, package); File.Copy(localCopy, package, true); progress?.Report(new ProgressData(95, "Signing...")); } finally { try { if (File.Exists(localCopy)) { File.Delete(localCopy); } } catch (Exception e) { Logger.Warn(e, "Clean-up of a temporary file {0} failed.", localCopy); } } }
public async Task SignPackageWithDeviceGuard(string package, bool updatePublisher, DeviceGuardConfig config, string timestampUrl = null, IncreaseVersionMethod increaseVersion = IncreaseVersionMethod.None, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { Logger.Info("Signing package {0} using Device Guard for {1}.", package, config.Subject); var dgssTokenPath = await new DgssTokenCreator().CreateDeviceGuardJsonTokenFile(config, cancellationToken); try { var publisherName = config.Subject; if (publisherName == null) { var dgh = new DeviceGuardHelper(); publisherName = await dgh.GetSubjectFromDeviceGuardSigning(dgssTokenPath, cancellationToken).ConfigureAwait(false); } var localCopy = await this.PreparePackageForSigning(package, updatePublisher, increaseVersion, publisherName, cancellationToken).ConfigureAwait(false); try { cancellationToken.ThrowIfCancellationRequested(); var sdk = new MsixSdkWrapper(); progress?.Report(new ProgressData(25, "Signing with Device Guard...")); await sdk.SignPackageWithDeviceGuard(new[] { localCopy }, "SHA256", dgssTokenPath, timestampUrl, cancellationToken).ConfigureAwait(false); progress?.Report(new ProgressData(75, "Signing with Device Guard...")); await Task.Delay(500, cancellationToken).ConfigureAwait(false); Logger.Debug("Moving {0} to {1}.", localCopy, package); File.Copy(localCopy, package, true); progress?.Report(new ProgressData(95, "Signing with Device Guard...")); } finally { try { if (File.Exists(localCopy)) { File.Delete(localCopy); } } catch (Exception e) { Logger.Warn(e, "Clean-up of a temporary file {0} failed.", localCopy); } } } finally { if (File.Exists(dgssTokenPath)) { ExceptionGuard.Guard(() => File.Delete(dgssTokenPath)); } } }
public async Task SignPackageWithInstalled( string package, bool updatePublisher, PersonalCertificate certificate, string timestampUrl = null, IncreaseVersionMethod increaseVersion = IncreaseVersionMethod.None, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } Logger.Info("Signing package {0} using personal certificate {1}.", package, certificate.Subject); StoreLocation loc; switch (certificate.StoreType) { case CertificateStoreType.User: loc = StoreLocation.CurrentUser; break; case CertificateStoreType.Machine: loc = StoreLocation.LocalMachine; break; default: throw new ArgumentOutOfRangeException(); } using var store = new X509Store(StoreName.My, loc); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); var x509 = store.Certificates.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, false); if (x509.Count < 1) { throw new ArgumentException("Certificate could not be located in the store."); } var isForCodeSigning = x509[0].Extensions.OfType <X509KeyUsageExtension>().Any(ke => ke.KeyUsages.HasFlag(X509KeyUsageFlags.DigitalSignature)); if (!isForCodeSigning) { throw new ArgumentException("Selected certificate is not for code-signing."); } if (!x509[0].HasPrivateKey) { throw new ArgumentException("Selected certificate does not contain a private key."); } var localCopy = await this.PreparePackageForSigning( package, updatePublisher, increaseVersion, x509[0], cancellationToken).ConfigureAwait(false); try { cancellationToken.ThrowIfCancellationRequested(); string type; if (x509[0].SignatureAlgorithm.FriendlyName.EndsWith("rsa", StringComparison.OrdinalIgnoreCase)) { type = x509[0].SignatureAlgorithm.FriendlyName.Substring(0, x509[0].SignatureAlgorithm.FriendlyName.Length - 3).ToUpperInvariant(); } else { throw new NotSupportedException($"Signature algorithm {x509[0].SignatureAlgorithm.FriendlyName} is not supported."); } Logger.Debug("Signing package {0} with algorithm {1}.", localCopy, x509[0].SignatureAlgorithm.FriendlyName); var sdk = new MsixSdkWrapper(); progress?.Report(new ProgressData(25, "Signing...")); await sdk.SignPackageWithPersonal(new[] { localCopy }, type, certificate.Thumbprint, certificate.StoreType == CertificateStoreType.Machine, timestampUrl, cancellationToken).ConfigureAwait(false); progress?.Report(new ProgressData(75, "Signing...")); await Task.Delay(500, cancellationToken).ConfigureAwait(false); Logger.Debug("Moving {0} to {1}.", localCopy, package); File.Copy(localCopy, package, true); progress?.Report(new ProgressData(95, "Signing...")); } finally { try { if (File.Exists(localCopy)) { File.Delete(localCopy); } } catch (Exception e) { Logger.Warn(e, "Clean-up of a temporary file {0} failed.", localCopy); } } }