/// <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.Fingerprint.SequenceEqual(fingerprint))); } catch (FormatException) {} catch (InvalidOperationException) {} try { return(secretKeys.First(x => x.UserID.ContainsIgnoreCase(keySpecifier))); } catch { throw new KeyNotFoundException(Resources.UnableToFindSecretKey); } }
/// <summary> /// Parses information about a signature from a console line. /// </summary> /// <param name="line">The console line containing the signature information.</param> /// <returns>The parsed signature representation; <c>null</c> if <paramref name="line"/> did not contain any signature information.</returns> /// <exception cref="FormatException"><paramref name="line"/> contains incorrectly formatted signature information.</exception> private static OpenPgpSignature?ParseSignatureLine(string line) { const int signatureTypeIndex = 1, fingerprintIndex = 2, timestampIndex = 4, keyIDIndex = 2, errorCodeIndex = 7; var signatureParts = line.Split(' '); if (signatureParts.Length < signatureTypeIndex + 1) { return(null); } switch (signatureParts[signatureTypeIndex]) { case "VALIDSIG": if (signatureParts.Length != 12) { throw new FormatException("Incorrect number of columns in VALIDSIG line."); } var fingerprint = OpenPgpUtils.ParseFingerprint(signatureParts[fingerprintIndex]); return(new ValidSignature( keyID: OpenPgpUtils.FingerprintToKeyID(fingerprint), fingerprint: fingerprint, timestamp: new UnixTime(long.Parse(signatureParts[timestampIndex])))); case "BADSIG": if (signatureParts.Length < 3) { throw new FormatException("Incorrect number of columns in BADSIG line."); } return(new BadSignature(OpenPgpUtils.ParseKeyID(signatureParts[keyIDIndex]))); case "ERRSIG": if (signatureParts.Length != 8) { throw new FormatException("Incorrect number of columns in ERRSIG line."); } return(int.Parse(signatureParts[errorCodeIndex]) switch { 9 => new MissingKeySignature(OpenPgpUtils.ParseKeyID(signatureParts[keyIDIndex])), _ => new ErrorSignature(OpenPgpUtils.ParseKeyID(signatureParts[keyIDIndex])) });