/// <summary>Replace the passed the public key on the passed in secret key.</summary> /// <param name="secretKey">Secret key to change.</param> /// <param name="publicKey">New public key.</param> /// <returns>A new secret key.</returns> /// <exception cref="ArgumentException">If KeyId's do not match.</exception> public static PgpSecretKey ReplacePublicKey( PgpSecretKey secretKey, PgpPublicKey publicKey) { if (publicKey.KeyId != secretKey.KeyId) { throw new ArgumentException("KeyId's do not match"); } return(new PgpSecretKey(secretKey.secret, publicKey)); }
/// <summary>Return the PGP secret key associated with the given key id.</summary> /// <param name="keyId">The ID of the secret key to return.</param> public PgpSecretKey GetSecretKey( long keyId) { foreach (PgpSecretKeyRing secRing in GetKeyRings()) { PgpSecretKey sec = secRing.GetSecretKey(keyId); if (sec != null) { return(sec); } } return(null); }
/// <summary> /// Replace the public key set on the secret ring with the corresponding key off the public ring. /// </summary> /// <param name="secretRing">Secret ring to be changed.</param> /// <param name="publicRing">Public ring containing the new public key set.</param> public static PgpSecretKeyRing ReplacePublicKeys( PgpSecretKeyRing secretRing, PgpPublicKeyRing publicRing) { IList newList = Platform.CreateArrayList(secretRing.keys.Count); foreach (PgpSecretKey sk in secretRing.keys) { PgpPublicKey pk = publicRing.GetPublicKey(sk.KeyId); newList.Add(PgpSecretKey.ReplacePublicKey(sk, pk)); } return(new PgpSecretKeyRing(newList)); }
/// <summary> /// Return a copy of the passed in secret key ring, with the master key and sub keys encrypted /// using a new password and the passed in algorithm. /// </summary> /// <param name="ring">The <c>PgpSecretKeyRing</c> to be copied.</param> /// <param name="oldPassPhrase">The current password for key.</param> /// <param name="newPassPhrase">The new password for the key.</param> /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param> /// <param name="rand">Source of randomness.</param> public static PgpSecretKeyRing CopyWithNewPassword( PgpSecretKeyRing ring, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { IList newKeys = Platform.CreateArrayList(ring.keys.Count); foreach (PgpSecretKey secretKey in ring.GetSecretKeys()) { newKeys.Add(PgpSecretKey.CopyWithNewPassword(secretKey, oldPassPhrase, newPassPhrase, newEncAlgorithm, rand)); } return(new PgpSecretKeyRing(newKeys, ring.extraPubKeys)); }
/// <summary> /// Returns a new key ring with the secret key passed in either added or /// replacing an existing one with the same key ID. /// </summary> /// <param name="secRing">The secret key ring to be modified.</param> /// <param name="secKey">The secret key to be inserted.</param> /// <returns>A new <c>PgpSecretKeyRing</c></returns> public static PgpSecretKeyRing InsertSecretKey( PgpSecretKeyRing secRing, PgpSecretKey secKey) { IList keys = Platform.CreateArrayList(secRing.keys); bool found = false; bool masterFound = false; for (int i = 0; i != keys.Count; i++) { PgpSecretKey key = (PgpSecretKey)keys[i]; if (key.KeyId == secKey.KeyId) { found = true; keys[i] = secKey; } if (key.IsMasterKey) { masterFound = true; } } if (!found) { if (secKey.IsMasterKey) { if (masterFound) { throw new ArgumentException("cannot add a master key to a ring that already has one"); } keys.Insert(0, secKey); } else { keys.Add(secKey); } } return(new PgpSecretKeyRing(keys, secRing.extraPubKeys)); }
/// <summary>Returns a new key ring with the secret key passed in removed from the key ring.</summary> /// <param name="secRing">The secret key ring to be modified.</param> /// <param name="secKey">The secret key to be removed.</param> /// <returns>A new <c>PgpSecretKeyRing</c>, or null if secKey is not found.</returns> public static PgpSecretKeyRing RemoveSecretKey( PgpSecretKeyRing secRing, PgpSecretKey secKey) { IList keys = Platform.CreateArrayList(secRing.keys); bool found = false; for (int i = 0; i < keys.Count; i++) { PgpSecretKey key = (PgpSecretKey)keys[i]; if (key.KeyId == secKey.KeyId) { found = true; keys.RemoveAt(i); } } return(found ? new PgpSecretKeyRing(keys, secRing.extraPubKeys) : null); }
/// <summary>Return the secret key ring which contains the key referred to by keyId</summary> /// <param name="keyId">The ID of the secret key</param> public PgpSecretKeyRing GetSecretKeyRing( long keyId) { long id = keyId; if (secretRings.Contains(id)) { return((PgpSecretKeyRing)secretRings[id]); } foreach (PgpSecretKeyRing secretRing in GetKeyRings()) { PgpSecretKey secret = secretRing.GetSecretKey(keyId); if (secret != null) { return(secretRing); } } return(null); }
/// <summary>Returns a new key ring with the secret key passed in removed from the key ring.</summary> /// <param name="secRing">The secret key ring to be modified.</param> /// <param name="secKey">The secret key to be removed.</param> /// <returns>A new <c>PgpSecretKeyRing</c>, or null if secKey is not found.</returns> public static PgpSecretKeyRing RemoveSecretKey( PgpSecretKeyRing secRing, PgpSecretKey secKey) { IList keys = Platform.CreateArrayList(secRing.keys); bool found = false; for (int i = 0; i < keys.Count; i++) { PgpSecretKey key = (PgpSecretKey)keys[i]; if (key.KeyId == secKey.KeyId) { found = true; keys.RemoveAt(i); } } return found ? new PgpSecretKeyRing(keys, secRing.extraPubKeys) : null; }
/// <summary> /// Returns a new key ring with the secret key passed in either added or /// replacing an existing one with the same key ID. /// </summary> /// <param name="secRing">The secret key ring to be modified.</param> /// <param name="secKey">The secret key to be inserted.</param> /// <returns>A new <c>PgpSecretKeyRing</c></returns> public static PgpSecretKeyRing InsertSecretKey( PgpSecretKeyRing secRing, PgpSecretKey secKey) { IList keys = Platform.CreateArrayList(secRing.keys); bool found = false; bool masterFound = false; for (int i = 0; i != keys.Count; i++) { PgpSecretKey key = (PgpSecretKey) keys[i]; if (key.KeyId == secKey.KeyId) { found = true; keys[i] = secKey; } if (key.IsMasterKey) { masterFound = true; } } if (!found) { if (secKey.IsMasterKey) { if (masterFound) throw new ArgumentException("cannot add a master key to a ring that already has one"); keys.Insert(0, secKey); } else { keys.Add(secKey); } } return new PgpSecretKeyRing(keys, secRing.extraPubKeys); }
/// <summary> /// Return a copy of the passed in secret key, encrypted using a new password /// and the passed in algorithm. /// </summary> /// <param name="key">The PgpSecretKey to be copied.</param> /// <param name="oldPassPhrase">The current password for the key.</param> /// <param name="newPassPhrase">The new password for the key.</param> /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param> /// <param name="rand">Source of randomness.</param> public static PgpSecretKey CopyWithNewPassword( PgpSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { byte[] rawKeyData = key.ExtractKeyData(oldPassPhrase); int s2kUsage = key.secret.S2kUsage; byte[] iv = null; S2k s2k = null; byte[] keyData; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { s2kUsage = SecretKeyPacket.UsageNone; if (key.secret.S2kUsage == SecretKeyPacket.UsageSha1) // SHA-1 hash, need to rewrite Checksum { keyData = new byte[rawKeyData.Length - 18]; Array.Copy(rawKeyData, 0, keyData, 0, keyData.Length - 2); byte[] check = Checksum(false, keyData, keyData.Length - 2); keyData[keyData.Length - 2] = check[0]; keyData[keyData.Length - 1] = check[1]; } else { keyData = rawKeyData; } } else { try { keyData = EncryptKeyData(rawKeyData, newEncAlgorithm, newPassPhrase, rand, out s2k, out iv); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } } SecretKeyPacket secret; if (key.secret is SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.secret.PublicKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); } else { secret = new SecretKeyPacket(key.secret.PublicKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); } return(new PgpSecretKey(secret, key.pub)); }
/// <summary>Replace the passed the public key on the passed in secret key.</summary> /// <param name="secretKey">Secret key to change.</param> /// <param name="publicKey">New public key.</param> /// <returns>A new secret key.</returns> /// <exception cref="ArgumentException">If KeyId's do not match.</exception> public static PgpSecretKey ReplacePublicKey( PgpSecretKey secretKey, PgpPublicKey publicKey) { if (publicKey.KeyId != secretKey.KeyId) throw new ArgumentException("KeyId's do not match"); return new PgpSecretKey(secretKey.secret, publicKey); }
/// <summary> /// Return a copy of the passed in secret key, encrypted using a new password /// and the passed in algorithm. /// </summary> /// <param name="key">The PgpSecretKey to be copied.</param> /// <param name="oldPassPhrase">The current password for the key.</param> /// <param name="newPassPhrase">The new password for the key.</param> /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param> /// <param name="rand">Source of randomness.</param> public static PgpSecretKey CopyWithNewPassword( PgpSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { byte[] rawKeyData = key.ExtractKeyData(oldPassPhrase); int s2kUsage = key.secret.S2kUsage; byte[] iv = null; S2k s2k = null; byte[] keyData; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { s2kUsage = SecretKeyPacket.UsageNone; if (key.secret.S2kUsage == SecretKeyPacket.UsageSha1) // SHA-1 hash, need to rewrite Checksum { keyData = new byte[rawKeyData.Length - 18]; Array.Copy(rawKeyData, 0, keyData, 0, keyData.Length - 2); byte[] check = Checksum(false, keyData, keyData.Length - 2); keyData[keyData.Length - 2] = check[0]; keyData[keyData.Length - 1] = check[1]; } else { keyData = rawKeyData; } } else { try { keyData = EncryptKeyData(rawKeyData, newEncAlgorithm, newPassPhrase, rand, out s2k, out iv); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } } SecretKeyPacket secret; if (key.secret is SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.secret.PublicKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); } else { secret = new SecretKeyPacket(key.secret.PublicKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); } return new PgpSecretKey(secret, key.pub); }