public async Task <DeviceGuardConfig> SignIn(CancellationToken cancellationToken) { var factory = new MsixHeroClientFactory(); string refreshToken = null; EventHandler <string> gotRefreshToken = (sender, s) => { refreshToken = s; }; try { factory.GotRefreshToken += gotRefreshToken; var clientApp = PublicClientApplicationBuilder.Create("4dd963fd-7400-4ce3-bc90-0bed2b65820d") .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient") .WithHttpClientFactory(factory) .Build(); await clientApp.GetAccountsAsync().ConfigureAwait(true); var result = await clientApp.AcquireTokenInteractive(Scope).WithPrompt(Prompt.ForceLogin).ExecuteAsync(cancellationToken).ConfigureAwait(false); var tokens = new DeviceGuardConfig(result.AccessToken, refreshToken); return(tokens); } finally { factory.GotRefreshToken -= gotRefreshToken; } }
private async Task <int> SignDeviceGuard(DeviceGuardConfig cfg, string timestamp, bool updatePublisherName) { try { foreach (var path in this.Verb.FilePath) { await this.Console.WriteInfo($"Signing '{path}' with Device Guard..."); await this.signingManager.SignPackageWithDeviceGuard(path, updatePublisherName, cfg, timestamp, this.Verb.IncreaseVersion).ConfigureAwait(false); await this.Console.WriteSuccess("Package signed successfully!").ConfigureAwait(false); await this.Console.ShowCertSummary(signingManager, path); } return(0); } catch (SdkException e) { Logger.Error(e); await this.Console.WriteError($"Signing failed with error code 0x{e.ExitCode:X}: {e.Message}"); return(e.ExitCode); } catch (Exception e) { Logger.Error(e); await this.Console.WriteError($"Signing failed: {e.Message}"); return(10); } }
public static DeviceGuardConfig FromConfiguration(this DeviceGuardConfiguration configuration) { var tokens = new DeviceGuardConfig(); var crypto = new Crypto(); tokens.AccessToken = FromSecureString(crypto.Unprotect(configuration.EncodedAccessToken)); tokens.RefreshToken = FromSecureString(crypto.Unprotect(configuration.EncodedRefreshToken)); tokens.Subject = configuration.Subject; return(tokens); }
public async Task SignPackageWithDeviceGuard(string package, bool updatePublisher, DeviceGuardConfig config, string timestampUrl = null, IncreaseVersionMethod increaseVersion = IncreaseVersionMethod.None, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { var manager = await this.managerFactory.GetProxyFor(SelfElevationLevel.AsInvoker, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await manager.SignPackageWithDeviceGuard(package, updatePublisher, config, timestampUrl, increaseVersion, cancellationToken, progress).ConfigureAwait(false); }
public SecureString CreateDeviceGuardJsonToken(DeviceGuardConfig tokens, CancellationToken cancellationToken = default) { var secureString = new SecureString(); var jsonObject = new JObject(); jsonObject["access_token"] = tokens.AccessToken; jsonObject["refresh_token"] = tokens.RefreshToken; foreach (var c in jsonObject.ToString(Formatting.Indented)) { secureString.AppendChar(c); } return(secureString); }
public async Task <string> CreateDeviceGuardJsonTokenFile(DeviceGuardConfig tokens, CancellationToken cancellationToken = default) { var tmpFile = Path.Combine(Path.GetTempPath(), "msixhero-dg-" + Guid.NewGuid().ToString("N").Substring(0, 12) + ".json"); using (var text = File.Create(tmpFile)) { var jsonObject = new JObject(); jsonObject["access_token"] = tokens.AccessToken; jsonObject["refresh_token"] = tokens.RefreshToken; using (var streamWriter = new StreamWriter(text)) { cancellationToken.ThrowIfCancellationRequested(); await streamWriter.WriteAsync(jsonObject.ToString(Formatting.Indented)).ConfigureAwait(false); } } return(tmpFile); }
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 SignToolWrapper(); progress?.Report(new ProgressData(25, "Signing with Device Guard...")); timestampUrl = await this.GetTimeStampUrl(timestampUrl).ConfigureAwait(false); 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 override async Task <int> Execute() { var checkCmd = await this.AssertCorrectCommandLine().ConfigureAwait(false); if (checkCmd != 0) { return(checkCmd); } var config = await configurationService.GetCurrentConfigurationAsync().ConfigureAwait(false); if (config.Signing?.Source == CertificateSource.Unknown) { // workaround for some migration issues if (!string.IsNullOrEmpty(config.Signing.PfxPath)) { config.Signing.Source = CertificateSource.Pfx; } else if (!string.IsNullOrEmpty(config.Signing.Thumbprint)) { config.Signing.Source = CertificateSource.Personal; } else { await this.Console.WriteError("In order to sign with CLI without any extra signing parameters, configure your signature in MSIX Hero settings.").ConfigureAwait(false); return(1); } } if (this.Verb.ThumbPrint != null) { return(await this.SignStore( this.Verb.ThumbPrint, this.Verb.TimeStampUrl ?? config.Signing?.TimeStampServer, !this.Verb.NoPublisherUpdate).ConfigureAwait(false)); } if (this.Verb.PfxFilePath != null) { return(await this.SignPfx( this.Verb.PfxFilePath, this.Verb.PfxPassword, this.Verb.TimeStampUrl ?? config.Signing?.TimeStampServer, !this.Verb.NoPublisherUpdate).ConfigureAwait(false)); } if (this.Verb.DeviceGuardInteractive) { return(await this.SignDeviceGuardInteractive( this.Verb.TimeStampUrl ?? config.Signing?.TimeStampServer, !this.Verb.NoPublisherUpdate).ConfigureAwait(false)); } if (this.Verb.DeviceGuardFile != null) { var json = JObject.Parse(await File.ReadAllTextAsync(this.Verb.DeviceGuardFile).ConfigureAwait(false)); var cfg = new DeviceGuardConfig { AccessToken = json["access_token"]?.Value <string>(), RefreshToken = json["access_token"]?.Value <string>(), Subject = this.Verb.DeviceGuardSubject }; if (cfg.Subject == null && !this.Verb.NoPublisherUpdate) { await this.Console.WriteInfo("Determining publisher name from Device Guard Signing certificate...").ConfigureAwait(false); cfg.Subject = await this.DeviceGuardHelper.GetSubjectFromDeviceGuardSigning(cfg.AccessToken, cfg.RefreshToken); await this.Console.WriteSuccess("New publisher name is " + cfg.Subject).ConfigureAwait(false); } return(await this.SignDeviceGuard( cfg, this.Verb.TimeStampUrl ?? config.Signing?.TimeStampServer, !this.Verb.NoPublisherUpdate).ConfigureAwait(false)); } await this.Console.WriteInfo("Using current MSIX Hero signing options...").ConfigureAwait(false); switch (config?.Signing?.Source) { case CertificateSource.Pfx: string password = null; if (!string.IsNullOrEmpty(config.Signing?.EncodedPassword)) { var crypto = new Crypto(); try { password = crypto.DecryptString(config.Signing.EncodedPassword, "$%!!ASddahs55839AA___ąółęńśSdcvv"); } catch (Exception) { Logger.Error("Could not use the configured password. Decryption of the string from settings failed."); await this.Console.WriteError("Could not use the configured password. Decryption of the string from settings failed.").ConfigureAwait(false); return(10); } } return(await this.SignPfx( config.Signing.PfxPath.Resolved, password, this.Verb.TimeStampUrl ?? config.Signing?.TimeStampServer, !this.Verb.NoPublisherUpdate).ConfigureAwait(false)); case CertificateSource.Personal: return(await this.SignStore( config.Signing.Thumbprint, this.Verb.TimeStampUrl ?? config.Signing?.TimeStampServer, !this.Verb.NoPublisherUpdate)); case CertificateSource.DeviceGuard: if (config.Signing.DeviceGuard == null) { Logger.Error("Device Guard has not been configured yet."); await this.Console.WriteError("Device Guard has not been configured yet.").ConfigureAwait(false); return(10); } return(await this.SignDeviceGuard( config.Signing.DeviceGuard.FromConfiguration(), this.Verb.TimeStampUrl ?? config.Signing?.TimeStampServer, !this.Verb.NoPublisherUpdate)); default: Logger.Error("No certificate has been provided, and no default certificate has been configured in MSIX Hero settings."); await this.Console.WriteError("No certificate has been provided, and no default certificate has been configured in MSIX Hero settings.").ConfigureAwait(false); return(10); } }