示例#1
0
        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;
            }
        }
示例#2
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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));
                }
            }
        }
示例#8
0
        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);
            }
        }