예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
        /// <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));
        }
예제 #5
0
        /// <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));
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
		/// <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;
        }
예제 #9
0
		/// <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);
		}
예제 #10
0
        /// <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));
        }
예제 #11
0
		/// <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);
		}
예제 #12
0
		/// <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);
        }