/// <summary> /// Creates a new feed editing form. /// </summary> /// <param name="feedEditing">The feed to open on start up.</param> /// <param name="openPgp">The OpenPGP-compatible system used to create signatures.</param> public MainForm([NotNull] FeedEditing feedEditing, [NotNull] IOpenPgp openPgp) { InitializeComponent(); _openPgp = openPgp; FeedEditing = feedEditing; }
/// <summary> /// Creates an <see cref="IFeedCache"/> instance that uses the default cache location in the user profile. /// </summary> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> /// <exception cref="IOException">A problem occurred while creating a directory.</exception> /// <exception cref="UnauthorizedAccessException">Creating a directory is not permitted.</exception> public static IFeedCache CreateDefault(IOpenPgp openPgp) { var cache = new DiskFeedCache(Locations.GetCacheDirPath("0install.net", machineWide: false, resource: "interfaces"), openPgp); // Note: Recreate memory-caching layer for each call to prevent long-running caches from getting out of sync with disk because of changes made by other processes return new MemoryFeedCache(cache); }
public SecurityPage([NotNull] FeedBuilder feedBuilder, [NotNull] IOpenPgp openPgp) { InitializeComponent(); _feedBuilder = feedBuilder; _openPgp = openPgp; }
/// <summary> /// Returns a specific secret key in the keyring. /// </summary> /// <param name="openPgp">The <see cref="IOpenPgp"/> implementation.</param> /// <param name="keyIDContainer">An object containing the key ID that identifies the keypair.</param> /// <exception cref="KeyNotFoundException">The specified key could not be found on the system.</exception> /// <seealso cref="IOpenPgp.Sign"/> /// <seealso cref="IOpenPgp.ExportKey"/> public static OpenPgpSecretKey GetSecretKey(this IOpenPgp openPgp, IKeyIDContainer keyIDContainer) { #region Sanity checks if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } if (keyIDContainer == null) { throw new ArgumentNullException(nameof(keyIDContainer)); } #endregion var secretKeys = openPgp.ListSecretKeys().ToList(); if (secretKeys.Count == 0) { throw new KeyNotFoundException(Resources.UnableToFindSecretKey); } try { return(secretKeys.First(x => x.KeyID == keyIDContainer.KeyID)); } catch (InvalidOperationException) { throw new KeyNotFoundException(Resources.UnableToFindSecretKey); } }
/// <summary> /// Determines which signatures a feed is signed with. /// </summary> /// <param name="openPgp">The OpenPGP-compatible system used to validate the signatures.</param> /// <param name="feedData">The feed data containing an embedded signature.</param> /// <returns>A list of signatures found, both valid and invalid.</returns> /// <exception cref="IOException">The OpenPGP implementation could not be launched.</exception> /// <exception cref="SignatureException">The signature data could not be handled.</exception> public static IEnumerable <OpenPgpSignature> GetSignatures([NotNull] IOpenPgp openPgp, [NotNull] byte[] feedData) { #region Sanity checks if (openPgp == null) { throw new ArgumentNullException("openPgp"); } if (feedData == null) { throw new ArgumentNullException("feedData"); } #endregion if (feedData.Length == 0) { return(Enumerable.Empty <OpenPgpSignature>()); } int signatureStartIndex = GetSignatureStartIndex(feedData); if (signatureStartIndex == -1) { return(Enumerable.Empty <OpenPgpSignature>()); } return(openPgp.Verify( IsolateFeed(feedData, signatureStartIndex), IsolateAndDecodeSignature(feedData, signatureStartIndex))); }
/// <summary> /// Creates an <see cref="IFeedCache"/> instance that uses the default cache location in the user profile. /// </summary> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> /// <exception cref="IOException">A problem occurred while creating a directory.</exception> /// <exception cref="UnauthorizedAccessException">Creating a directory is not permitted.</exception> public static IFeedCache CreateDefault(IOpenPgp openPgp) { var cache = new DiskFeedCache(Locations.GetCacheDirPath("0install.net", machineWide: false, resource: "interfaces"), openPgp); // Note: Recreate memory-caching layer for each call to prevent long-running caches from getting out of sync with disk because of changes made by other processes return(new MemoryFeedCache(cache)); }
/// <summary> /// Creates a new trust manager. /// </summary> /// <param name="config">User settings controlling network behaviour, solving, etc.</param> /// <param name="openPgp">The OpenPGP-compatible system used to validate the signatures.</param> /// <param name="feedCache">Provides access to a cache of <see cref="Feed"/>s that were downloaded via HTTP(S).</param> /// <param name="handler">A callback object used when the the user needs to be asked questions.</param> public TrustManager([NotNull] Config config, [NotNull] IOpenPgp openPgp, [NotNull] IFeedCache feedCache, [NotNull] ITaskHandler handler) { #region Sanity checks if (config == null) { throw new ArgumentNullException("config"); } if (openPgp == null) { throw new ArgumentNullException("openPgp"); } if (feedCache == null) { throw new ArgumentNullException("feedCache"); } if (handler == null) { throw new ArgumentNullException("handler"); } #endregion _config = config; _openPgp = openPgp; _feedCache = feedCache; _handler = handler; }
/// <summary> /// Creates a new trust manager. /// </summary> /// <param name="config">User settings controlling network behaviour, solving, etc.</param> /// <param name="openPgp">The OpenPGP-compatible system used to validate the signatures.</param> /// <param name="trustDB">A database of OpenPGP signature fingerprints the users trusts to sign <see cref="Feed"/>s coming from specific domains.</param> /// <param name="feedCache">Provides access to a cache of <see cref="Feed"/>s that were downloaded via HTTP(S).</param> /// <param name="handler">A callback object used when the the user needs to be asked questions.</param> public TrustManager([NotNull] Config config, [NotNull] IOpenPgp openPgp, [NotNull] TrustDB trustDB, [NotNull] IFeedCache feedCache, [NotNull] ITaskHandler handler) { #region Sanity checks if (config == null) { throw new ArgumentNullException(nameof(config)); } if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } if (trustDB == null) { throw new ArgumentNullException(nameof(trustDB)); } if (feedCache == null) { throw new ArgumentNullException(nameof(feedCache)); } if (handler == null) { throw new ArgumentNullException(nameof(handler)); } #endregion _config = config; _openPgp = openPgp; _trustDB = trustDB; _feedCache = feedCache; _handler = handler; }
public static SignedFeed Run([NotNull] IOpenPgp openPgp, [CanBeNull] IWin32Window owner = null) { using (var wizard = new NewFeedWizard(openPgp)) { wizard.ShowDialog(owner); return(wizard._signedFeed); } }
/// <summary> /// Creates a new trust manager. /// </summary> /// <param name="config">User settings controlling network behaviour, solving, etc.</param> /// <param name="openPgp">The OpenPGP-compatible system used to validate the signatures.</param> /// <param name="trustDB">A database of OpenPGP signature fingerprints the users trusts to sign <see cref="Feed"/>s coming from specific domains.</param> /// <param name="feedCache">Provides access to a cache of <see cref="Feed"/>s that were downloaded via HTTP(S).</param> /// <param name="handler">A callback object used when the the user needs to be asked questions.</param> public TrustManager(Config config, IOpenPgp openPgp, TrustDB trustDB, IFeedCache feedCache, ITaskHandler handler) { _config = config ?? throw new ArgumentNullException(nameof(config)); _openPgp = openPgp ?? throw new ArgumentNullException(nameof(openPgp)); _trustDB = trustDB ?? throw new ArgumentNullException(nameof(trustDB)); _feedCache = feedCache ?? throw new ArgumentNullException(nameof(feedCache)); _handler = handler ?? throw new ArgumentNullException(nameof(handler)); }
private NewFeedWizard(IOpenPgp openPgp) { InitializeComponent(); // Pages var downloadPage = new DownloadPage(_feedBuilder, _installerCapture); var archiveExtractPage = new ArchiveExtractPage(_feedBuilder); var entryPointPage = new EntryPointPage(_feedBuilder); var installerCaptureStartPage = new InstallerCaptureStartPage(_installerCapture, _feedBuilder); var installerCaptureDiffPage = new InstallerCaptureDiffPage(_installerCapture, _feedBuilder); var installerCollectFilesPage = new InstallerCollectFilesPage(_installerCapture); var installerAltDownloadPage = new DownloadPage(_feedBuilder, _installerCapture); var installerExtractPage = new ArchiveExtractPage(_feedBuilder, _installerCapture); var installerEntryPointPage = new EntryPointPage(_feedBuilder); var detailsPage = new DetailsPage(_feedBuilder); var iconPage = new IconPage(_feedBuilder); var securityPage = new SecurityPage(_feedBuilder, openPgp); var donePage = new DonePage(); // Flows downloadPage.AsArchive += () => PushPage(archiveExtractPage); downloadPage.AsSingleFile += () => { _feedBuilder.GenerateCommands(); PushPage(detailsPage); }; downloadPage.AsInstaller += () => PushPage(installerCaptureStartPage); archiveExtractPage.Next += () => PushPage(entryPointPage); entryPointPage.Next += () => { _feedBuilder.GenerateCommands(); PushPage(detailsPage); }; installerCaptureStartPage.Next += () => PushPage(installerCaptureDiffPage); installerCaptureStartPage.Skip += () => PushPage(archiveExtractPage); installerCaptureDiffPage.AsArchive += () => PushPage(installerExtractPage); installerCaptureDiffPage.AltSource += () => PushPage(installerCollectFilesPage); installerCollectFilesPage.Next += () => PushPage(installerEntryPointPage); installerCollectFilesPage.ExistingArchive += () => PushPage(installerAltDownloadPage); installerAltDownloadPage.AsArchive += () => PushPage(installerExtractPage); installerExtractPage.Next += () => PushPage(installerEntryPointPage); installerEntryPointPage.Next += () => { _installerCapture.CaptureSession.Finish(); PushPage(detailsPage); }; detailsPage.Next += () => PushPage(iconPage); iconPage.Next += () => PushPage(securityPage); securityPage.Next += () => PushPage(donePage); donePage.Finish += () => { _signedFeed = _feedBuilder.Build(); Close(); }; // Start PushPage(downloadPage); }
/// <summary> /// Creates a new disk-based cache. /// </summary> /// <param name="path">A fully qualified directory path.</param> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> public DiskFeedCache([NotNull] string path, [NotNull] IOpenPgp openPgp) { #region Sanity checks if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); if (openPgp == null) throw new ArgumentNullException("openPgp"); #endregion DirectoryPath = path; _openPgp = openPgp; }
/// <summary> /// Creates a new welcome form. /// </summary> /// <param name="openPgp">The OpenPGP-compatible system used to create signatures.</param> public WelcomeForm([NotNull] IOpenPgp openPgp) { #region Sanity checks if (openPgp == null) throw new ArgumentNullException(nameof(openPgp)); #endregion InitializeComponent(); _openPgp = openPgp; }
/// <summary> /// Creates a new welcome form. /// </summary> /// <param name="openPgp">The OpenPGP-compatible system used to create signatures.</param> public WelcomeForm([NotNull] IOpenPgp openPgp) { #region Sanity checks if (openPgp == null) { throw new ArgumentNullException("openPgp"); } #endregion InitializeComponent(); _openPgp = openPgp; }
/// <summary> /// Returns a specific secret key in the keyring. /// </summary> /// <param name="openPgp">The <see cref="IOpenPgp"/> implementation.</param> /// <param name="keySpecifier">The key ID, fingerprint or any part of a user ID that identifies the keypair; <c>null</c> to use the default key.</param> /// <exception cref="KeyNotFoundException">The specified key could not be found on the system.</exception> /// <seealso cref="IOpenPgp.Sign"/> /// <seealso cref="IOpenPgp.ExportKey"/> public static OpenPgpSecretKey GetSecretKey(this IOpenPgp openPgp, string?keySpecifier = null) { #region Sanity checks if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } #endregion var secretKeys = openPgp.ListSecretKeys().ToList(); if (secretKeys.Count == 0) { throw new KeyNotFoundException(Resources.UnableToFindSecretKey); } if (string.IsNullOrEmpty(keySpecifier)) { return(secretKeys[0]); } try { long keyID = OpenPgpUtils.ParseKeyID(keySpecifier); return(secretKeys.First(x => x.KeyID == keyID)); } catch (FormatException) {} catch (InvalidOperationException) {} try { var fingerprint = OpenPgpUtils.ParseFingerprint(keySpecifier); return(secretKeys.First(x => x.GetFingerprint().SequenceEqual(fingerprint))); } catch (FormatException) {} catch (InvalidOperationException) {} try { return(secretKeys.First(x => x.UserID.ContainsIgnoreCase(keySpecifier))); } catch { throw new KeyNotFoundException(Resources.UnableToFindSecretKey); } }
/// <summary> /// Creates a new welcome form. /// </summary> /// <param name="openPgp">The OpenPGP-compatible system used to create signatures.</param> public WelcomeForm(IOpenPgp openPgp) { #region Sanity checks if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } #endregion InitializeComponent(); _openPgp = openPgp; labelVersion.Text = @"v" + AppInfo.CurrentLibrary.Version; }
/// <summary> /// Creates a new disk-based cache. /// </summary> /// <param name="path">A fully qualified directory path.</param> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> public DiskFeedCache([NotNull] string path, [NotNull] IOpenPgp openPgp) { #region Sanity checks if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } if (openPgp == null) { throw new ArgumentNullException("openPgp"); } #endregion DirectoryPath = path; _openPgp = openPgp; }
/// <summary> /// Creates a new trust manager. /// </summary> /// <param name="config">User settings controlling network behaviour, solving, etc.</param> /// <param name="openPgp">The OpenPGP-compatible system used to validate the signatures.</param> /// <param name="trustDB">A database of OpenPGP signature fingerprints the users trusts to sign <see cref="Feed"/>s coming from specific domains.</param> /// <param name="feedCache">Provides access to a cache of <see cref="Feed"/>s that were downloaded via HTTP(S).</param> /// <param name="handler">A callback object used when the the user needs to be asked questions.</param> public TrustManager([NotNull] Config config, [NotNull] IOpenPgp openPgp, [NotNull] TrustDB trustDB, [NotNull] IFeedCache feedCache, [NotNull] ITaskHandler handler) { #region Sanity checks if (config == null) throw new ArgumentNullException("config"); if (openPgp == null) throw new ArgumentNullException("openPgp"); if (trustDB == null) throw new ArgumentNullException("trustDB"); if (feedCache == null) throw new ArgumentNullException("feedCache"); if (handler == null) throw new ArgumentNullException("handler"); #endregion _config = config; _openPgp = openPgp; _trustDB = trustDB; _feedCache = feedCache; _handler = handler; }
/// <summary> /// Exports all feeds listed in a <see cref="Selections"/> document along with any OpenPGP public key files required for validation. /// </summary> /// <param name="feedCache">Used to get local feed files.</param> /// <param name="openPgp">Used to get export keys feeds were signed with.</param> /// <exception cref="UnauthorizedAccessException">The file could not be read or written.</exception> /// <exception cref="UnauthorizedAccessException">Write access to the directory is not permitted.</exception> /// <exception cref="IOException">A feed or GnuPG could not be read from the cache.</exception> public void ExportFeeds(IFeedCache feedCache, IOpenPgp openPgp) { #region Sanity checks if (feedCache == null) { throw new ArgumentNullException(nameof(feedCache)); } if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } #endregion string contentDir = Path.Combine(_destination, "content"); Directory.CreateDirectory(contentDir); var feedUris = _selections.Implementations .SelectMany(x => new [] { x.InterfaceUri, x.FromFeed }) .WhereNotNull().Distinct().ToList(); foreach (var feedUri in feedUris) { string filePath = Path.Combine(contentDir, feedUri.PrettyEscape()); if (!filePath.EndsWith(".xml")) { filePath += ".xml"; } string?path = feedCache.GetPath(feedUri); if (path != null) { Log.Info("Exporting feed " + feedUri.ToStringRfc()); File.Copy(path, filePath, overwrite: true); } } foreach (var signature in feedUris.SelectMany(feedCache.GetSignatures).OfType <ValidSignature>().Distinct()) { Log.Info("Exporting GPG key " + signature.FormatKeyID()); openPgp.DeployPublicKey(signature, contentDir); } }
/// <summary> /// Exports an OpenPGP public key to a key file. /// </summary> /// <param name="openPgp">The OpenPGP-compatible system used to manage keys.</param> /// <param name="keyID">The key ID to get the public key for.</param> /// <param name="path">The directory to write the key file to.</param> /// <exception cref="UnauthorizedAccessException">The file could not be read or written.</exception> /// <exception cref="UnauthorizedAccessException">Write access to the directory is not permitted.</exception> /// <exception cref="IOException">The specified <paramref name="keyID"/> could not be found on the system.</exception> public static void DeployPublicKey([NotNull] this IOpenPgp openPgp, [NotNull] IKeyIDContainer keyID, [NotNull] string path) { #region Sanity checks if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } if (keyID == null) { throw new ArgumentNullException(nameof(keyID)); } if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } #endregion File.WriteAllText( path: Path.Combine(path, keyID.FormatKeyID() + ".gpg"), contents: openPgp.ExportKey(keyID), encoding: Encoding.ASCII); }
/// <summary> /// Determines the key used to sign a feed or catalog file. Only uses the first signature if more than one is present. /// </summary> /// <param name="path">The feed or catalog file to check for signatures.</param> /// <param name="openPgp">The OpenPGP-compatible system used to validate the signatures.</param> /// <returns>The key used to sign the file; <c>null</c> if the file was not signed.</returns> /// <exception cref="FileNotFoundException">The file file could not be found.</exception> /// <exception cref="IOException">The file could not be read.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the file is not permitted.</exception> public static OpenPgpSecretKey?GetKey(string path, IOpenPgp openPgp) { #region Sanity checks if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } #endregion try { var signature = StoreFeedUtils.GetSignatures(openPgp, File.ReadAllBytes(path)) .OfType <ValidSignature>() .FirstOrDefault(); if (signature == null) { return(null); } return(openPgp.GetSecretKey(signature)); } #region Error handling catch (KeyNotFoundException) { Log.Info(Resources.SecretKeyNotInKeyring); return(null); } catch (SignatureException ex) { // Unable to parse the signature Log.Error(ex); return(null); } #endregion }
/// <summary> /// Determines which signatures a feed is signed with. /// </summary> /// <param name="openPgp">The OpenPGP-compatible system used to validate the signatures.</param> /// <param name="feedData">The feed data containing an embedded signature.</param> /// <returns>A list of signatures found, both valid and invalid.</returns> /// <exception cref="SignatureException">There is no valid signature data embedded in the <paramref name="feedData"/>.</exception> public static IEnumerable <OpenPgpSignature> GetSignatures(IOpenPgp openPgp, byte[] feedData) { #region Sanity checks if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } if (feedData == null) { throw new ArgumentNullException(nameof(feedData)); } #endregion if (feedData.Length == 0) { return(Enumerable.Empty <OpenPgpSignature>()); } int signatureStartIndex = GetSignatureStartIndex(feedData); if (signatureStartIndex == -1) { return(Enumerable.Empty <OpenPgpSignature>()); } var data = IsolateFeed(feedData, signatureStartIndex); var signature = IsolateAndDecodeSignature(feedData, signatureStartIndex); try { return(openPgp.Verify(data, signature)); } #region Error handling catch (InvalidDataException ex) { throw new SignatureException(Resources.InvalidSignature, ex); } #endregion }
public static OpenPgpSecretKey GetKey([NotNull] string path, [NotNull] IOpenPgp openPgp) { #region Sanity checks if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } if (openPgp == null) { throw new ArgumentNullException("openPgp"); } #endregion try { var signatures = Store.Feeds.FeedUtils.GetSignatures(openPgp, File.ReadAllBytes(path)); foreach (var signature in signatures.OfType <ValidSignature>()) { return(openPgp.GetSecretKey(signature.Fingerprint)); } } #region Error handling catch (KeyNotFoundException) { Log.Info(Resources.SecretKeyNotInKeyring); } catch (SignatureException ex) { // Unable to parse the signature Log.Error(ex); } #endregion return(null); }
/// <summary> /// Runs the wizard. /// </summary> /// <param name="openPgp">Used to get a list of <see cref="OpenPgpSecretKey"/>s.</param> /// <param name="owner">The parent window the displayed window is modal to; can be <c>null</c>.</param> /// <returns>The feed generated by the wizard; <c>null</c> if the user canceled.</returns> public static SignedFeed?Run(IOpenPgp openPgp, IWin32Window?owner = null) { using var wizard = new NewFeedWizard(openPgp); wizard.ShowDialog(owner); return(wizard._signedFeed); }
/// <summary> /// Creates a new disk-based cache. /// </summary> /// <param name="path">A fully qualified directory path.</param> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> public FeedCache(string path, IOpenPgp openPgp) { Path = path ?? throw new ArgumentNullException(nameof(path)); _openPgp = openPgp ?? throw new ArgumentNullException(nameof(openPgp)); }
/// <summary> /// Creates a new disk-based cache. /// </summary> /// <param name="directoryPath">A fully qualified directory path.</param> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> public DiskFeedCache(string directoryPath, IOpenPgp openPgp) { DirectoryPath = directoryPath ?? throw new ArgumentNullException(nameof(directoryPath)); _openPgp = openPgp ?? throw new ArgumentNullException(nameof(openPgp)); }
private NewFeedWizard(IOpenPgp openPgp) { _openPgp = openPgp; InitializeComponent(); }
/// <summary> /// Creates an <see cref="IFeedCache"/> instance that uses the default cache location in the user profile. /// </summary> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> /// <exception cref="IOException">A problem occurred while creating a directory.</exception> /// <exception cref="UnauthorizedAccessException">Creating a directory is not permitted.</exception> public static IFeedCache CreateDefault(IOpenPgp openPgp) { return(new DiskFeedCache(Locations.GetCacheDirPath("0install.net", machineWide: false, resource: "interfaces"), openPgp)); }
/// <summary> /// Creates an <see cref="IFeedCache"/> instance that uses the default cache location in the user profile. /// </summary> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> /// <exception cref="IOException">A problem occurred while creating a directory.</exception> /// <exception cref="UnauthorizedAccessException">Creating a directory is not permitted.</exception> public static IFeedCache Default(IOpenPgp openPgp) => new DiskFeedCache(DefaultDirectoryPath, openPgp);
/// <summary> /// Creates a new signed feed. /// </summary> /// <param name="feed">The wrapped <see cref="Feed"/>.</param> /// <param name="secretKey">The secret key used to sign the <see cref="Feed"/>; <c>null</c> for no signature.</param> /// <param name="openPgp">The OpenPGP-compatible system used to create the signatures; <c>null</c> for default.</param> public SignedFeed(Feed feed, OpenPgpSecretKey?secretKey = null, IOpenPgp?openPgp = null) { Feed = feed ?? throw new ArgumentNullException(nameof(feed)); SecretKey = secretKey; _openPgp = openPgp ?? OpenPgp.Signing(); }
/// <summary> /// Creates an <see cref="IFeedCache"/> instance that uses the default cache location in the user profile. /// </summary> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> /// <exception cref="IOException">A problem occurred while creating a directory.</exception> /// <exception cref="UnauthorizedAccessException">Creating a directory is not permitted.</exception> public static IFeedCache CreateDefault(IOpenPgp openPgp) { return new DiskFeedCache(Locations.GetCacheDirPath("0install.net", machineWide: false, resource: "interfaces"), openPgp); }
/// <summary> /// Creates a new signed catalog. /// </summary> /// <param name="catalog">The wrapped <see cref="Catalog"/>.</param> /// <param name="secretKey">The secret key used to sign the <see cref="Catalog"/>; <c>null</c> for no signature.</param> /// <param name="openPgp">The OpenPGP-compatible system used to create the signatures; <c>null</c> for default.</param> public SignedCatalog(Catalog catalog, OpenPgpSecretKey?secretKey, IOpenPgp?openPgp = null) { Catalog = catalog ?? throw new ArgumentNullException(nameof(catalog)); SecretKey = secretKey; _openPgp = openPgp ?? OpenPgp.Signing(); }
/// <summary> /// Adds a Base64 signature to a feed or catalog stream. /// </summary> /// <param name="stream">The feed or catalog to sign.</param> /// <param name="secretKey">The secret key to use for signing the file.</param> /// <param name="passphrase">The passphrase to use to unlock the key.</param> /// <param name="openPgp">The OpenPGP-compatible system used to create signatures.</param> /// <exception cref="IOException">The OpenPGP implementation could not be launched or the file could not be read or written.</exception> /// <exception cref="WrongPassphraseException">Passphrase was incorrect.</exception> /// <remarks> /// The file is not parsed before signing; invalid XML files are signed as well. /// The existing file must end with a line break. /// Old signatures are not removed. /// </remarks> public static void SignFeed([NotNull] Stream stream, [NotNull] OpenPgpSecretKey secretKey, string passphrase, [NotNull] IOpenPgp openPgp) { #region Sanity checks if (stream == null) { throw new ArgumentNullException("stream"); } if (secretKey == null) { throw new ArgumentNullException("secretKey"); } if (openPgp == null) { throw new ArgumentNullException("openPgp"); } #endregion // Calculate the signature in-memory string signature = openPgp.DetachSign(stream, secretKey.Fingerprint, passphrase); // Add the signature to the end of the file var writer = new StreamWriter(stream, encoding: Store.Feeds.FeedUtils.Encoding) { NewLine = "\n" }; writer.Write(Store.Feeds.FeedUtils.SignatureBlockStart); writer.WriteLine(signature); writer.Write(Store.Feeds.FeedUtils.SignatureBlockEnd); writer.Flush(); }
/// <summary> /// Adds a Base64 signature to a feed or catalog stream. /// </summary> /// <param name="stream">The feed or catalog to sign.</param> /// <param name="secretKey">The secret key to use for signing the file.</param> /// <param name="passphrase">The passphrase to use to unlock the key.</param> /// <param name="openPgp">The OpenPGP-compatible system used to create signatures.</param> /// <exception cref="IOException">The file could not be read or written.</exception> /// <exception cref="UnauthorizedAccessException">Read or write access to the file is not permitted.</exception> /// <exception cref="KeyNotFoundException">The specified <paramref name="secretKey"/> could not be found on the system.</exception> /// <exception cref="WrongPassphraseException"><paramref name="passphrase"/> was incorrect.</exception> /// <remarks> /// The file is not parsed before signing; invalid XML files are signed as well. /// The existing file must end with a line break. /// Old signatures are not removed. /// </remarks> public static void SignFeed(Stream stream, OpenPgpSecretKey secretKey, string?passphrase, IOpenPgp openPgp) { #region Sanity checks if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (secretKey == null) { throw new ArgumentNullException(nameof(secretKey)); } if (openPgp == null) { throw new ArgumentNullException(nameof(openPgp)); } #endregion // Calculate the signature in-memory var signature = openPgp.Sign(stream.ReadAll(), secretKey, passphrase); // Add the signature to the end of the file var writer = new StreamWriter(stream, EncodingUtils.Utf8) { NewLine = "\n" }; writer.Write(StoreFeedUtils.SignatureBlockStart); writer.WriteLine(Convert.ToBase64String(signature)); writer.Write(StoreFeedUtils.SignatureBlockEnd); writer.Flush(); }
/// <summary> /// Creates an <see cref="IFeedCache"/> instance that uses the default cache location in the user profile. /// </summary> /// <param name="openPgp">Provides access to an encryption/signature system compatible with the OpenPGP standard.</param> public static IFeedCache Default(IOpenPgp openPgp) => new FeedCache(DefaultPath, openPgp);