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"));
                await 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}");
                    await using var fileStream = File.Create(tempFilePath);
                    manifestResourceStream.Seek(0L, SeekOrigin.Begin);
                    await manifestResourceStream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
                }

                var sdk = new SignToolWrapper();
                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));
                }
            }
        }
예제 #2
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)
        {
            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));
                }
            }
        }