/// <summary> /// Main constructor. /// </summary> /// <param name="KeyID"> /// A <see cref="System.String"/>, the primary key ID. /// </param> /// <param name="SignKey"> /// A <see cref="System.String"/>, the signing key ID. /// </param> /// <param name="SignDate"> /// A <see cref="System.String"/>, the signature date (seconds from Epoch) /// </param> public Signature(string KeyID, string SignKey, string SignDate) { // sig:::17:F4B4B0CC797EBFAB:1223678701::::Enrico Zini <*****@*****.**>:10x: // Console.WriteLine(String.Format("Key: {0} - SignKey: {1} - SignDate: {2}", KeyID, Key, Date)); GPG gpg = new GPG(KeyID, Commands.List); gpg.Exec(); foreach (string line in gpg.Output.Split('\n')) { RecordType tag = Utils.GetRecordType(Utils.GetField(line, 0)); if (tag == RecordType.Signature) { string key = Utils.GetField(line, 4); string date = Utils.GetField(line, 5); if ((key == SignKey) && (date == SignDate)) { this._algorithm = Utils.GetAlgorithm(Convert.ToInt32(Utils.GetField(line, 3))); this._user = Utils.ParseUsername(Utils.GetField(line, 9)); this._signingKey = SignKey; this._signingDate = SignDate; // TODO: also parse the "10x" above? The docs give very poor info: /* * 11. Field: Signature class. This is a 2 digit hexnumber followed by * either the letter 'x' for an exportable signature or the * letter 'l' for a local-only signature. * The class byte of an revocation key is also given here, * 'x' and 'l' ist used the same way. */ } } } }
/// <summary> /// Main constructor. /// </summary> /// <param name="KeyID"> /// A <see cref="System.String"/>, the parent key ID. /// </param> /// <param name="Hash"> /// A <see cref="System.String"/>, an unique identifier provided by gpg. /// </param> /// <param name="Type"> /// A <see cref="RecordType"/>, RecordType.UserId or RecordType.UserAttribute /// are the only two currently supported. /// </param> public UID(string KeyID, string Hash, RecordType Type) { this._keyid = KeyID; // TODO: Disabled: far too slow: // Keyset foreach: 00:00:13.6448860 // while, without: // Keyset foreach: 00:00:03.9610520 // this._sigs = GetSignatures(KeyID, Hash); GPG gpg = new GPG(KeyID, Commands.List); gpg.Exec(); foreach (string line in gpg.Output.Split('\n')) { RecordType tag = Utils.GetRecordType(Utils.GetField(line, 0)); // if it's what we're looking for... if (tag == Type) { // the hashes match... string hash = Utils.GetField(line, 7); if (hash.ToUpper() == Hash.ToUpper()) { ParseLine(line); } } } }
/// <summary> /// Returns an armored version of the secret part of KeyID. /// </summary> /// <param name="KeyID"> /// A <see cref="System.String"/> /// </param> /// <returns> /// A <see cref="System.String"/>, the armored version of the secret key. /// </returns> public static string GetSecretKey(string KeyID) { GPG me = new GPG(KeyID, Commands.ExportSecretKey); me.Armor = true; me.Exec(); return(me.Output); }
/// <summary> /// Main constructor. /// </summary> /// <param name="KeyID"> /// A <see cref="System.String"/>, the exact key ID (8 or 16 chars, /// with or without preceding 0x / 0X). /// </param> public Keyset(string KeyID) { // Remove the 0{x,X} from the KeyID. KeyID = KeyID.Replace("0x", "").Replace("0X", ""); if ((KeyID.Length != 8) && (KeyID.Length != 16)) { throw new GPGException(String.Format("invalid KeyID ({0}) to build Keyset object.", KeyID)); } KeyID = "0x" + KeyID; GPG gpg = new GPG(KeyID, Commands.List); gpg.Exec(); string[] output = gpg.Output.Split('\n'); this._subkeys = new ArrayList(); DateTime start = DateTime.Now; foreach (string line in output) { string tag = Utils.GetField(line, 0); // TODO: what else a keyset can contain? // Store the public primary key. if (Utils.GetRecordType(tag) == RecordType.PublicKey) { // The line is in the form: // pub:u:1024:17:E6AA90171392B174:1138786427:::u:::scaESCA: DateTime kstart = DateTime.Now; this._primaryKey = new Key(Utils.GetField(line, 4)); Console.WriteLine("PrimaryKey: " + DateTime.Now.Subtract(kstart).ToString()); } // Store the subkey. else if (Utils.GetRecordType(tag) == RecordType.Subkey) { // The line is in the form: // sub:u:4096:1:BB45ABF7A71D5481:1203325654::::::e: DateTime kstart = DateTime.Now; this._subkeys.Add(new Key(Utils.GetField(line, 4))); Console.WriteLine("SubKey: " + DateTime.Now.Subtract(kstart).ToString()); } } Console.WriteLine("Keyset foreach: " + DateTime.Now.Subtract(start).ToString()); }
/// <summary> /// Get signatures on the specified UID/UAT /// </summary> /// <param name="KeyID"> /// A <see cref="System.String"/>, the primary Key ID. /// </param> /// <param name="UIDHash"> /// A <see cref="System.String"/>, the hash of this UID. See /// <see cref="OpenPGP.UID.Hash"/>. /// </param> /// <returns> /// A <see cref="ArrayList"/> of <see cref="OpenPGP.Signature"/> objects. /// </returns> public static ArrayList GetSignatures(string KeyID, string UIDHash) { ArrayList sigs = new ArrayList(); GPG gpg = new GPG(KeyID, Commands.List); gpg.Exec(); bool isMyUid = false; foreach (string line in gpg.Output.Split('\n')) { RecordType tag = Utils.GetRecordType(Utils.GetField(line, 0)); // let's look for our UID. if ( (tag == RecordType.UserAttribute) || (tag == RecordType.UserId) ) { // the hashes match... string hash = Utils.GetField(line, 7); if (hash.ToUpper() == UIDHash.ToUpper()) { isMyUid = true; } else { isMyUid = false; } } // we are looking for signatures... else if (tag == RecordType.Signature) { if (isMyUid) { string signKey = Utils.GetField(line, 4); string signDate = Utils.GetField(line, 5); sigs.Add(new Signature(KeyID, signKey, signDate)); } } } return(sigs); }
/// <summary> /// Returns a list of available secret keys from <paramref name="SecretKeyring"/>. /// </summary> /// <param name="SecretKeyring"> /// A <see cref="System.String"/> /// </param> /// <returns> /// A <see cref="ArrayList"/> /// </returns> public static ArrayList GetAvailableSecretKeys(string SecretKeyring) { ArrayList mySecretKeys = new ArrayList(); GPG me = new GPG(); me.Command = Commands.ListSecretKeys; me.SecretKeyring = SecretKeyring; me.Exec(); string[] output = me.Output.Split('\n'); foreach (string line in output) { if (Utils.GetRecordType(Utils.GetField(line, 0)) == RecordType.SecretKey) { mySecretKeys.Add(Utils.GetField(line, 4)); } else { continue; } } return(mySecretKeys); }
/// <summary> /// Get the Fingerprint for the specified key. /// </summary> /// <param name="KeyID"> /// A <see cref="System.String"/>, the Key ID to work on. /// </param> /// <returns> /// A <see cref="System.String"/>, the Fingerprint of the specified Key. /// </returns> public static string GetFingerprint(string KeyID) { // The fingerprint is returned in the form: // fpr:::::::::2BABC6254E66E7B8450AC3E1E6AA90171392B174: GPG gpg = new GPG(KeyID, Commands.List); gpg.Exec(); bool isMyKey = false; foreach (string line in gpg.Output.Split('\n')) { RecordType tag = Utils.GetRecordType(Utils.GetField(line, 0)); if ( (tag == RecordType.PublicKey) || (tag == RecordType.Subkey) ) { if (Utils.GetField(line, 4).Contains(KeyID.ToUpper())) { // It is our key. isMyKey = true; } else { isMyKey = false; } } else { if (isMyKey && (tag == RecordType.Fingerprint)) { return(Utils.GetField(line, 9)); } } } throw new GPGException(gpg.Error); }
/// <summary> /// Main constructor. /// </summary> /// <param name="KeyID"> /// A <see cref="System.String"/>, the exact key ID (8 or 16 chars, /// with or without preceding 0x / 0X). /// </param> public Key(string KeyID) { KeyID = KeyID.Replace("0x", "").Replace("0X", ""); if ((KeyID.Length != 8) && (KeyID.Length != 16)) { throw new GPGException(String.Format("invalid KeyID ({0}) to build Key object.", KeyID)); } GPG gpg = new GPG("0x" + KeyID, Commands.List); gpg.Exec(); this._uids = new ArrayList(); this._uats = new ArrayList(); ArrayList tmp_uids = new ArrayList(); ArrayList tmp_uats = new ArrayList(); bool isMyKey = false; foreach (string line in gpg.Output.Split('\n')) { RecordType tag = Utils.GetRecordType(Utils.GetField(line, 0)); if ((tag == RecordType.PublicKey) || (tag == RecordType.Subkey)) { if (Utils.GetField(line, 4).ToUpper().Contains(KeyID.ToUpper())) { ParseLine(line); UpdateFields(); isMyKey = true; } else { isMyKey = false; } } // We have some "data" for our key, grab it. // Example data: // uat:u::::2008-01-04::4E2CB61790C019A48949A0124DC9F6CD00AE5E28::1 6727: // uid:u::::2008-01-02::71F3098861D9F69E3C427819AE3F615378EE8009::Hanska <*****@*****.**>: // uid:u::::2006-02-01::64E94BC187C9B38AD5070B2327C4211970D90639::David Paleino <*****@*****.**>: // uid:r::::::6A12CAA95C42D93D4A2AD83E85793C9120BCC585::David Paleino <*****@*****.**>: // uid:u::::2007-12-30::9CE39242A56CA074C46D5EB842C0AF1B9493EFFA::David Paleino (Alioth account) <*****@*****.**>: else if ((tag == RecordType.UserAttribute) || (tag == RecordType.UserId)) { if (isMyKey) { if (tag == RecordType.UserId) { tmp_uids.Add(Utils.GetField(line, 7)); } else if (tag == RecordType.UserAttribute) { tmp_uats.Add(Utils.GetField(line, 7)); } } } } foreach (string hash in tmp_uids) { this._uids.Add(new UID(KeyID, hash, RecordType.UserId)); } foreach (string hash in tmp_uats) { this._uats.Add(new UID(KeyID, hash, RecordType.UserAttribute)); } }