internal PgpSecretKey( SecretKeyPacket secret, PgpPublicKey pub) { this.secret = secret; this.pub = pub; }
public string SignText(string strMessage, ulong lSignatureKeyID, string strPassphrase) { SignaturePacket spSign = new SignaturePacket(); strMessage = Radix64.TrimMessage(strMessage); TransportableSecretKey tskKey = skrKeyRing.Find(lSignatureKeyID); SecretKeyPacket skpKey = tskKey.FindKey(AsymActions.Sign); spSign.HashAlgorithm = HashAlgorithms.SHA1; spSign.Format = PacketFormats.New; spSign.KeyID = skpKey.PublicKey.KeyID; spSign.TimeCreated = DateTime.Now; spSign.SignatureAlgorithm = skpKey.PublicKey.Algorithm; spSign.SignatureType = SignatureTypes.TextSignature; spSign.Version = SignaturePacketVersionNumbers.v4; byte[] bMessage = System.Text.Encoding.UTF8.GetBytes(strMessage); spSign.Sign(bMessage, skpKey, strPassphrase); byte[] bSignature = spSign.Generate(); string strSignature = Radix64.Encode(bSignature, true); string strFinal = Armor.WrapCleartextSignature(strMessage, strSignature); return(strFinal); }
/// <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(IPgpSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { var rawKeyData = key.ExtractKeyData(oldPassPhrase); var s2KUsage = key.SecretPacket.S2KUsage; byte[] iv = null; S2k s2K = null; byte[] keyData; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { s2KUsage = SecretKeyPacket.UsageNone; if (key.SecretPacket.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); var 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) { throw; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } } SecretKeyPacket secret; if (key.SecretPacket is SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } else { secret = new SecretKeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } return(new PgpSecretKey(secret, key.PublicKey)); }
public void SignKeyBindingSignature(PublicKeyPacket pkpPrimaryKey, SecretKeyPacket skpPrimaryKey, string strPassphrase) { byte[] bSubKey = new byte[pkpSubkey.Body.Length + 3]; bSubKey[0] = 0x99; bSubKey[1] = (byte)((pkpSubkey.Body.Length >> 8) & 0xFF); bSubKey[2] = (byte)(pkpSubkey.Body.Length & 0xFF); Array.Copy(pkpSubkey.Body, 0, bSubKey, 3, pkpSubkey.Body.Length); byte[] bPrimaryKey = new byte[pkpPrimaryKey.Body.Length + 3]; bPrimaryKey[0] = 0x99; bPrimaryKey[1] = (byte)((pkpPrimaryKey.Body.Length >> 8) & 0xFF); bPrimaryKey[2] = (byte)(pkpPrimaryKey.Body.Length & 0xFF); Array.Copy(pkpPrimaryKey.Body, 0, bPrimaryKey, 3, pkpPrimaryKey.Body.Length); byte[] bData = new byte[bPrimaryKey.Length + bSubKey.Length]; Array.Copy(bSubKey, 0, bData, 0, bSubKey.Length); Array.Copy(bPrimaryKey, 0, bData, bSubKey.Length, bPrimaryKey.Length); SignaturePacket spKeyBindingSig = new SignaturePacket(); spKeyBindingSig.Version = SignaturePacketVersionNumbers.v4; spKeyBindingSig.HashAlgorithm = HashAlgorithms.SHA1; spKeyBindingSig.KeyID = pkpPrimaryKey.KeyID; spKeyBindingSig.SignatureType = SignatureTypes.SubkeyBindingSignature; spKeyBindingSig.Sign(bData, skpPrimaryKey, strPassphrase); this.KeyBindingSignature = spKeyBindingSig; }
/// <summary> /// Creates a new Certification for the UserID. /// </summary> /// <param name="spSignature">A signaturepacket that has been /// prepared for being signed. Things like signature subpackets /// MUST already be in place. Only the signature type is /// automatically set to UserIDCertification.</param> /// <param name="skpKey">A secret key that is used to signed the /// certification.</param> /// <param name="strPassphrase">The passphrase that fits to the /// given secret key packet.</param> /// <param name="pkpKey">The public key to which the userid that /// is to be signed belongs.</param> public void Sign(SignaturePacket spSignature, SecretKeyPacket skpKey, string strPassphrase, PublicKeyPacket pkpKey) { if (spSignature.Version == SignaturePacketVersionNumbers.v4) { byte[] bKey = new byte[pkpKey.Body.Length + 3]; bKey[0] = 0x99; bKey[1] = (byte)((pkpKey.Body.Length >> 8) & 0xFF); bKey[2] = (byte)(pkpKey.Body.Length & 0xFF); Array.Copy(pkpKey.Body, 0, bKey, 3, pkpKey.Body.Length); byte[] bUserID = new byte[UserID.Body.Length + 5]; bUserID[0] = 0xb4; bUserID[1] = (byte)((UserID.Body.Length >> 24) & 0xFF); bUserID[2] = (byte)((UserID.Body.Length >> 16) & 0xFF); bUserID[3] = (byte)((UserID.Body.Length >> 8) & 0xFF); bUserID[4] = (byte)(UserID.Body.Length & 0xFF); Array.Copy(UserID.Body, 0, bUserID, 5, UserID.Body.Length); byte[] bData = new byte[bUserID.Length + bKey.Length]; Array.Copy(bKey, 0, bData, 0, bKey.Length); Array.Copy(bUserID, 0, bData, bKey.Length, bUserID.Length); spSignature.SignatureType = SignatureTypes.UserIDSignature; spSignature.Sign(bData, skpKey, strPassphrase); this.alCertificates.Add(spSignature); } else { throw new System.NotImplementedException("Only v4 signatures are supported so far!"); } }
/// <summary> /// Finds a key /// </summary> /// <param name="lKeyID"the key to be found></param> /// <returns>the found key</returns> public TransportableSecretKey Find(ulong lKeyID) { IEnumerator ieKeys = SecretKeys.GetEnumerator(); while (ieKeys.MoveNext()) { TransportableSecretKey tskKey = (TransportableSecretKey)ieKeys.Current; if (tskKey.PrimaryKey.PublicKey.KeyID == lKeyID) { return(tskKey); } IEnumerator ieSubkeys = tskKey.SubKeys.GetEnumerator(); while (ieSubkeys.MoveNext()) { if (!(ieSubkeys.Current is SecretKeyPacket)) { throw new Exception("Expected a secret key packet, but did not find one."); } SecretKeyPacket skpKey = (SecretKeyPacket)ieSubkeys.Current; if (skpKey.PublicKey.KeyID == lKeyID) { return(tskKey); } } } return(null); }
public PgpSecretKeyRing(IPacketReader packetReader) { this.keys = new List <PgpSecretKey>(); this.extraPubKeys = new List <PgpPublicKey>(); PacketTag initialTag = packetReader.NextPacketTag(); if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey) { throw new PgpUnexpectedPacketException(); } SecretKeyPacket secret = (SecretKeyPacket)packetReader.ReadContainedPacket(); keys.Add(new PgpSecretKey(packetReader, secret, subKey: false)); // Read subkeys while (packetReader.NextPacketTag() == PacketTag.SecretSubkey || packetReader.NextPacketTag() == PacketTag.PublicSubkey) { if (packetReader.NextPacketTag() == PacketTag.SecretSubkey) { SecretSubkeyPacket sub = (SecretSubkeyPacket)packetReader.ReadContainedPacket(); keys.Add(new PgpSecretKey(packetReader, sub, subKey: true)); } else { PublicSubkeyPacket sub = (PublicSubkeyPacket)packetReader.ReadContainedPacket(); extraPubKeys.Add(new PgpPublicKey(packetReader, sub, subKey: true)); } } }
public static string ClearTextSign(string strMessage, SecretKeyRing skrKeyRing) { SignaturePacket spSign = new SignaturePacket(); strMessage = Radix64.TrimMessage(strMessage); QueryPassphrase qpPassphrase = new QueryPassphrase(); qpPassphrase.ShowMyDialog(skrKeyRing); string strPassphrase = qpPassphrase.Passphrase; TransportableSecretKey tskKey = qpPassphrase.SelectedKey; SecretKeyPacket skpKey = tskKey.FindKey(AsymActions.Sign); Working wWorking = new Working(); wWorking.Show(); spSign.HashAlgorithm = HashAlgorithms.SHA1; spSign.Format = PacketFormats.New; wWorking.Progress(10); SignatureSubPacket sspCreator = new SignatureSubPacket(); sspCreator.Type = SignatureSubPacketTypes.IssuerKeyID; sspCreator.KeyID = skpKey.PublicKey.KeyID; SignatureSubPacket sspCreationTime = new SignatureSubPacket(); sspCreationTime.Type = SignatureSubPacketTypes.SignatureCreationTime; sspCreationTime.TimeCreated = DateTime.Now; spSign.HashedSubPackets = new SignatureSubPacket[2]; spSign.HashedSubPackets[0] = sspCreator; spSign.HashedSubPackets[1] = sspCreationTime; wWorking.Progress(20); //spSign.KeyID = skpKey.PublicKey.KeyID; //spSign.TimeCreated = DateTime.Now; spSign.SignatureAlgorithm = skpKey.PublicKey.Algorithm; spSign.SignatureType = SignatureTypes.TextSignature; spSign.Version = SignaturePacketVersionNumbers.v4; wWorking.Progress(10); byte[] bMessage = System.Text.Encoding.UTF8.GetBytes(strMessage); spSign.Sign(bMessage, skpKey, strPassphrase); wWorking.Progress(40); byte[] bSignature = spSign.Generate(); string strSignature = Radix64.Encode(bSignature, true); wWorking.Progress(20); string strFinal = Armor.WrapCleartextSignature(strMessage, strSignature); wWorking.Hide(); return(strFinal); }
/** * Construct a PgpSecretKey using the passed in private key and public key. This constructor will not add any * certifications but assumes that pubKey already has what is required. * * @param privKey the private key component. * @param pubKey the public key component. * @param checksumCalculator a calculator for the private key checksum * @param isMasterKey true if the key is a master key, false otherwise. * @param keyEncryptor an encryptor for the key if required (null otherwise). * @throws PgpException if there is an issue creating the secret key packet. */ public PgpSecretKey( PgpPrivateKey privKey, PgpPublicKey pubKey, bool isMasterKey, IPbeSecretKeyEncryptor keyEncryptor) { this.pub = pubKey; this.secret = buildSecretKeyPacket(isMasterKey, privKey, pubKey, keyEncryptor); }
/// <summary> /// Generates the transportable secret key out of the properties /// in this. /// </summary> /// <returns>Returns a byte array containing the openpgp encoded /// representation of the transportable secret key.</returns> /// <remarks> /// Generates the transportable secret key out of the properties /// in this. /// </remarks> public byte[] Generate() { if (alUserIDs.Count == 0) { throw new Exception("A transportable secret key must have at least one userid assigned to the primary key!"); } byte[] bSecretKey = skpPrimaryKey.Generate(); byte[] bUserIDs = new byte[0]; byte[] bSubkeys = new byte[0]; IEnumerator ieUserIDs = alUserIDs.GetEnumerator(); while (ieUserIDs.MoveNext()) { if (!(ieUserIDs.Current is UserIDPacket)) { continue; } UserIDPacket uipID = (UserIDPacket)ieUserIDs.Current; byte[] bUserID = uipID.Generate(); byte[] bOldUserIDs = new byte[bUserIDs.Length]; bUserIDs.CopyTo(bOldUserIDs, 0); bUserIDs = new byte[bOldUserIDs.Length + bUserID.Length]; bOldUserIDs.CopyTo(bUserIDs, 0); bUserID.CopyTo(bUserIDs, bOldUserIDs.Length); } IEnumerator ieSubkeys = alSubkeys.GetEnumerator(); while (ieSubkeys.MoveNext()) { if (!(ieSubkeys.Current is SecretKeyPacket)) { continue; } SecretKeyPacket skpSubkey = (SecretKeyPacket)ieSubkeys.Current; byte[] bSubkey = skpSubkey.Generate(); byte[] bOldSubkeys = new byte[bSubkeys.Length]; bSubkeys.CopyTo(bOldSubkeys, 0); bSubkeys = new byte[bOldSubkeys.Length + bSubkey.Length]; bOldSubkeys.CopyTo(bSubkeys, 0); bSubkey.CopyTo(bSubkeys, bOldSubkeys.Length); } byte[] bReturn = new byte[bSecretKey.Length + bUserIDs.Length + bSubkeys.Length]; bSecretKey.CopyTo(bReturn, 0); bUserIDs.CopyTo(bReturn, bSecretKey.Length); bSubkeys.CopyTo(bReturn, bSecretKey.Length + bUserIDs.Length); return(bReturn); }
void cmdParse_Click(Object sender, System.EventArgs e) { Packet[] pKeys = Packet.ParsePackets(txtBase64Key.Text); string strKeys = ""; for (int i = 0; i < pKeys.Length; i++) { /* As soon as all Packets are implemented, replace * this by a simple pKeys[i].ToString(); * For now we need all the ifs */ if (pKeys[i] is PublicKeyPacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is UserIDPacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is SignaturePacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is SymmetricallyEncryptedDataPacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is AsymSessionKeyPacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is SymSessionKeyPacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is LiteralDataPacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is CompressedDataPacket) { strKeys += pKeys[i].ToString(); } else if (pKeys[i] is SecretKeyPacket) { QueryPassphrase queryPassphrase = new QueryPassphrase(); queryPassphrase.ShowMyDialog(); string strPassphrase = queryPassphrase.Passphrase; SecretKeyPacket skpPacket = (SecretKeyPacket)pKeys[i]; skpPacket.GetDecryptedKeyMaterial(strPassphrase); strKeys += pKeys[i].ToString(); } } this.txtKeyProperties.Lines = strKeys.Split('\n'); }
/// <summary>Copy constructor - subkey.</summary> private PgpSecretKey( SecretKeyPacket secret, TrustPacket trust, ArrayList subSigs, PgpPublicKey pub) { this.secret = secret; this.trust = trust; this.subSigs = subSigs; this.pub = pub; }
/// <summary> /// Secret key operation. Signs biHash with the keydata /// in the given secret key packet. /// </summary> /// <param name="biHash">The hash value of a message that is about to /// be signed</param> /// <param name="skpKey">The secret key packet with the key /// material for the signature</param> /// <param name="strPassphrase">The passphrase for the /// keymaterial</param> /// <returns>The signed hash as array of biginteger. Only return[0] /// contains a value: the signed hash.</returns> /// <remarks>No remarks</remarks> public override BigInteger[] Sign(BigInteger biHash, SecretKeyPacket skpKey, string strPassphrase) { //Signing and encrypting is just the same BigInteger[] biHashArray = { biHash }; BigInteger biSignature = Decrypt(biHashArray, skpKey, strPassphrase); BigInteger[] biReturn = new BigInteger[1]; biReturn[0] = biSignature; return(biReturn); }
internal PgpSecretKey( SecretKeyPacket secret, TrustPacket trust, IDigest sha, ArrayList subSigs) { this.secret = secret; this.trust = trust; this.subSigs = subSigs; this.pub = new PgpPublicKey(secret.PublicKeyPacket, trust, subSigs); }
/// <summary> /// Return a copy of the passed in secret key, encrypted using a new password /// and the passed in algorithm. /// </summary> /// <remarks> /// Allows the caller to handle the encoding of the passphrase to bytes. /// </remarks> /// <param name="key">The PgpSecretKey to be copied.</param> /// <param name="rawOldPassPhrase">The current password for the key.</param> /// <param name="rawNewPassPhrase">The new password for the key.</param> public static PgpSecretKey CopyWithNewPassword( PgpSecretKey key, ReadOnlySpan <byte> rawOldPassPhrase, ReadOnlySpan <byte> rawNewPassPhrase) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (key.IsPrivateKeyEmpty) { throw new PgpException("no private key in this SecretKey - public key present only."); } byte[] rawKeyData = CryptoPool.Rent(key.keyPacket.KeyBytes.Length - key.keyPacket.PublicKeyLength + 0x20); try { S2kBasedEncryption.DecryptSecretKey( rawOldPassPhrase, key.keyPacket.KeyBytes.AsSpan(key.keyPacket.PublicKeyLength), rawKeyData, out int rawKeySize, key.keyPacket.Version); // Use the default S2K parameters var s2kParameters = new S2kParameters(); var newKeyData = new byte[S2kBasedEncryption.GetEncryptedLength(s2kParameters, rawKeySize, key.keyPacket.Version) + key.keyPacket.PublicKeyLength]; key.keyPacket.KeyBytes.AsSpan(0, key.keyPacket.PublicKeyLength).CopyTo(newKeyData); S2kBasedEncryption.EncryptSecretKey( rawNewPassPhrase, s2kParameters, rawKeyData.AsSpan(0, rawKeySize), newKeyData.AsSpan(key.keyPacket.PublicKeyLength), key.keyPacket.Version); SecretKeyPacket newKeyPacket; if (key.keyPacket is SecretSubkeyPacket) { newKeyPacket = new SecretSubkeyPacket(key.Algorithm, key.CreationTime, newKeyData); } else { newKeyPacket = new SecretKeyPacket(key.Algorithm, key.CreationTime, newKeyData); } return(new PgpSecretKey(newKeyPacket, key)); } finally { CryptoPool.Return(rawKeyData); } }
internal static PgpSecretKey DoCopyWithNewPassword(PgpSecretKey key, byte[] rawOldPassPhrase, byte[] rawNewPassPhrase, bool clearPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { if (key.IsPrivateKeyEmpty) { throw new PgpException("no private key in this SecretKey - public key present only."); } byte[] array = key.ExtractKeyData(rawOldPassPhrase, clearPassPhrase); int num = key.secret.S2kUsage; byte[] iv = null; S2k s2k = null; PublicKeyPacket publicKeyPacket = key.secret.PublicKeyPacket; byte[] array2; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { num = 0; if (key.secret.S2kUsage == 254) { array2 = new byte[array.Length - 18]; global::System.Array.Copy((global::System.Array)array, 0, (global::System.Array)array2, 0, array2.Length - 2); byte[] array3 = Checksum(useSha1: false, array2, array2.Length - 2); array2[array2.Length - 2] = array3[0]; array2[array2.Length - 1] = array3[1]; } else { array2 = array; } } else { if (num == 0) { num = 255; } try { array2 = ((publicKeyPacket.Version < 4) ? EncryptKeyDataV3(array, newEncAlgorithm, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv) : EncryptKeyDataV4(array, newEncAlgorithm, HashAlgorithmTag.Sha1, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv)); } catch (PgpException ex) { throw ex; } catch (global::System.Exception exception) { throw new PgpException("Exception encrypting key", exception); } } SecretKeyPacket secretKeyPacket = ((!(key.secret is SecretSubkeyPacket)) ? new SecretKeyPacket(publicKeyPacket, newEncAlgorithm, num, s2k, iv, array2) : new SecretSubkeyPacket(publicKeyPacket, newEncAlgorithm, num, s2k, iv, array2)); return(new PgpSecretKey(secretKeyPacket, key.pub)); }
public static TransportableSecretKey[] SplitKeys(string strRadix64) { ArrayList alKeys = new ArrayList(); Packet[] pPackets = Packet.ParsePackets(strRadix64); byte[] bOneKey = new byte[0]; for (int i = 0; i < pPackets.Length; i++) { if (pPackets[i] is PublicKeyPacket) { SecretKeyPacket skpKey = (SecretKeyPacket)pPackets[i]; if ((skpKey.Content == ContentTypes.SecretKey) && (bOneKey.Length > 10)) { TransportableSecretKey tskKey = new TransportableSecretKey(Radix64.Encode(bOneKey, true)); alKeys.Add(tskKey); bOneKey = new byte[0]; } } byte[] bPacket = pPackets[i].Generate(); byte[] bTmpKey = new byte[bOneKey.Length]; bOneKey.CopyTo(bTmpKey, 0); bOneKey = new byte[bOneKey.Length + bPacket.Length]; Array.Copy(bTmpKey, 0, bOneKey, 0, bTmpKey.Length); Array.Copy(bPacket, 0, bOneKey, bTmpKey.Length, bPacket.Length); } if (bOneKey.Length > 10) { TransportableSecretKey tskKey = new TransportableSecretKey(Radix64.Encode(bOneKey, true)); alKeys.Add(tskKey); } TransportableSecretKey[] tskKeys = new TransportableSecretKey[alKeys.Count]; int iCount = 0; IEnumerator ieKeys = alKeys.GetEnumerator(); while (ieKeys.MoveNext()) { if (!(ieKeys.Current is TransportableSecretKey)) { continue; } tskKeys[iCount++] = (TransportableSecretKey)ieKeys.Current; } return(tskKeys); }
private DSA_Secret_Key ParseSecretKey(SecretKeyPacket skpKey, string strPassphrase) { DSA_Secret_Key dskKey = new DSA_Secret_Key(); dskKey.p = skpKey.PublicKey.KeyMaterial[0]; dskKey.q = skpKey.PublicKey.KeyMaterial[1]; dskKey.g = skpKey.PublicKey.KeyMaterial[2]; dskKey.y = skpKey.PublicKey.KeyMaterial[3]; BigInteger[] biSecretKeyMaterial = skpKey.GetDecryptedKeyMaterial(strPassphrase); dskKey.x = biSecretKeyMaterial[0]; return(dskKey); }
private RSA_Secret_Key ParseSecretKey(SecretKeyPacket skpKey, string strPassphrase) { RSA_Secret_Key rskKey = new RSA_Secret_Key(); rskKey.n = skpKey.PublicKey.KeyMaterial[0]; rskKey.e = skpKey.PublicKey.KeyMaterial[1]; BigInteger[] biSecretKeyMaterial = skpKey.GetDecryptedKeyMaterial(strPassphrase); rskKey.d = biSecretKeyMaterial[0]; rskKey.p = biSecretKeyMaterial[1]; rskKey.q = biSecretKeyMaterial[2]; rskKey.u = biSecretKeyMaterial[3]; return(rskKey); }
/// <summary>Copy constructor - master key.</summary> private PgpSecretKey( SecretKeyPacket secret, TrustPacket trust, ArrayList keySigs, ArrayList ids, ArrayList idTrusts, ArrayList idSigs, PgpPublicKey pub) { this.secret = secret; this.trust = trust; this.keySigs = keySigs; this.ids = ids; this.idTrusts = idTrusts; this.idSigs = idSigs; this.pub = pub; }
internal PgpSecretKey( SecretKeyPacket secret, TrustPacket trust, IDigest sha, ArrayList keySigs, ArrayList ids, ArrayList idTrusts, ArrayList idSigs) { this.secret = secret; this.trust = trust; this.keySigs = keySigs; this.ids = ids; this.idTrusts = idTrusts; this.idSigs = idSigs; this.pub = new PgpPublicKey(secret.PublicKeyPacket, trust, keySigs, ids, idTrusts, idSigs); }
} //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown public PgpSecretKeyRing(Stream inputStream) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) keys = Platform.CreateArrayList(); extraPubKeys = Platform.CreateArrayList(); BcpgInputStream bcpgInputStream = BcpgInputStream.Wrap(inputStream); PacketTag packetTag = bcpgInputStream.NextPacketTag(); if (packetTag != PacketTag.SecretKey && packetTag != PacketTag.SecretSubkey) { int num = (int)packetTag; throw new IOException("secret key ring doesn't start with secret key tag: tag 0x" + num.ToString("X")); } SecretKeyPacket secretKeyPacket = (SecretKeyPacket)bcpgInputStream.ReadPacket(); while (bcpgInputStream.NextPacketTag() == PacketTag.Experimental2) { bcpgInputStream.ReadPacket(); } TrustPacket trustPk = PgpKeyRing.ReadOptionalTrustPacket(bcpgInputStream); global::System.Collections.IList keySigs = PgpKeyRing.ReadSignaturesAndTrust(bcpgInputStream); PgpKeyRing.ReadUserIDs(bcpgInputStream, out var ids, out var idTrusts, out var idSigs); keys.Add((object)new PgpSecretKey(secretKeyPacket, new PgpPublicKey(secretKeyPacket.PublicKeyPacket, trustPk, keySigs, ids, idTrusts, idSigs))); while (bcpgInputStream.NextPacketTag() == PacketTag.SecretSubkey || bcpgInputStream.NextPacketTag() == PacketTag.PublicSubkey) { if (bcpgInputStream.NextPacketTag() == PacketTag.SecretSubkey) { SecretSubkeyPacket secretSubkeyPacket = (SecretSubkeyPacket)bcpgInputStream.ReadPacket(); while (bcpgInputStream.NextPacketTag() == PacketTag.Experimental2) { bcpgInputStream.ReadPacket(); } TrustPacket trustPk2 = PgpKeyRing.ReadOptionalTrustPacket(bcpgInputStream); global::System.Collections.IList sigs = PgpKeyRing.ReadSignaturesAndTrust(bcpgInputStream); keys.Add((object)new PgpSecretKey(secretSubkeyPacket, new PgpPublicKey(secretSubkeyPacket.PublicKeyPacket, trustPk2, sigs))); } else { PublicSubkeyPacket publicPk = (PublicSubkeyPacket)bcpgInputStream.ReadPacket(); TrustPacket trustPk3 = PgpKeyRing.ReadOptionalTrustPacket(bcpgInputStream); global::System.Collections.IList sigs2 = PgpKeyRing.ReadSignaturesAndTrust(bcpgInputStream); extraPubKeys.Add((object)new PgpPublicKey(publicPk, trustPk3, sigs2)); } } }
public PgpSecretKeyRing(Stream inputStream) { keys = Platform.CreateArrayList(); extraPubKeys = Platform.CreateArrayList(); BcpgInputStream bcpgInputStream = BcpgInputStream.Wrap(inputStream); PacketTag packetTag = bcpgInputStream.NextPacketTag(); if (packetTag != PacketTag.SecretKey && packetTag != PacketTag.SecretSubkey) { int num = (int)packetTag; throw new IOException("secret key ring doesn't start with secret key tag: tag 0x" + num.ToString("X")); } SecretKeyPacket secretKeyPacket = (SecretKeyPacket)bcpgInputStream.ReadPacket(); while (bcpgInputStream.NextPacketTag() == PacketTag.Experimental2) { bcpgInputStream.ReadPacket(); } TrustPacket trustPk = PgpKeyRing.ReadOptionalTrustPacket(bcpgInputStream); IList keySigs = PgpKeyRing.ReadSignaturesAndTrust(bcpgInputStream); PgpKeyRing.ReadUserIDs(bcpgInputStream, out IList ids, out IList idTrusts, out IList idSigs); keys.Add(new PgpSecretKey(secretKeyPacket, new PgpPublicKey(secretKeyPacket.PublicKeyPacket, trustPk, keySigs, ids, idTrusts, idSigs))); while (bcpgInputStream.NextPacketTag() == PacketTag.SecretSubkey || bcpgInputStream.NextPacketTag() == PacketTag.PublicSubkey) { if (bcpgInputStream.NextPacketTag() == PacketTag.SecretSubkey) { SecretSubkeyPacket secretSubkeyPacket = (SecretSubkeyPacket)bcpgInputStream.ReadPacket(); while (bcpgInputStream.NextPacketTag() == PacketTag.Experimental2) { bcpgInputStream.ReadPacket(); } TrustPacket trustPk2 = PgpKeyRing.ReadOptionalTrustPacket(bcpgInputStream); IList sigs = PgpKeyRing.ReadSignaturesAndTrust(bcpgInputStream); keys.Add(new PgpSecretKey(secretSubkeyPacket, new PgpPublicKey(secretSubkeyPacket.PublicKeyPacket, trustPk2, sigs))); } else { PublicSubkeyPacket publicPk = (PublicSubkeyPacket)bcpgInputStream.ReadPacket(); TrustPacket trustPk3 = PgpKeyRing.ReadOptionalTrustPacket(bcpgInputStream); IList sigs2 = PgpKeyRing.ReadSignaturesAndTrust(bcpgInputStream); extraPubKeys.Add(new PgpPublicKey(publicPk, trustPk3, sigs2)); } } }
/// <summary> /// Parses the radix64 encoded representation of a transportable secret /// key given as an argument to populate the parameters of this. /// </summary> /// <param name="strRadix64">Radix64 representation of an transportable /// secret key</param> /// <exception cref="System.ArgumentException">Throws an /// ArgumentException if the radix64 string given as a parameter is /// not an transportable secret key.</exception> /// <remarks>No remarks</remarks> public void Parse(string strRadix64) { Packet[] pPackets = Packet.ParsePackets(strRadix64); int nCurrentPacket = 0; int nUserIDCounter = 0; try { // First we expect a PublicKeyPacket if (!(pPackets[0] is SecretKeyPacket)) { throw(new ArgumentException("The given packet is not in the required transportable secret key format!")); } this.PrimaryKey = (SecretKeyPacket)pPackets[nCurrentPacket++]; // Next we expect one or more userid packets while ((nCurrentPacket < pPackets.Length) && (pPackets[nCurrentPacket] is UserIDPacket)) { UserIDPacket uipUserID = (UserIDPacket)pPackets[nCurrentPacket++]; this.UserIDs.Add(uipUserID); nUserIDCounter++; } // we want at least 1 userid packet. if (nUserIDCounter == 0) { throw(new ArgumentException("The given packet is not in the required transportable secret key format!")); } // Finally we have zero or more subkeys while ((nCurrentPacket < pPackets.Length) && (pPackets[nCurrentPacket] is SecretKeyPacket)) { SecretKeyPacket skpSubKey = (SecretKeyPacket)pPackets[nCurrentPacket++]; this.SubKeys.Add(skpSubKey); } } catch (System.IndexOutOfRangeException) { if (nUserIDCounter == 0) { throw(new ArgumentException("The given packet is not in the required transportable secret key format!")); } } }
public void SignKeyBindingSignature(PublicKeyPacket pkpPrimaryKey, SecretKeyPacket skpPrimaryKey, string strPassphrase, DateTime expirationTime, bool revocable) { byte[] bSubKey = new byte[pkpSubkey.Body.Length + 3]; bSubKey[0] = 0x99; bSubKey[1] = (byte)((pkpSubkey.Body.Length >> 8) & 0xFF); bSubKey[2] = (byte)(pkpSubkey.Body.Length & 0xFF); Array.Copy(pkpSubkey.Body, 0, bSubKey, 3, pkpSubkey.Body.Length); byte[] bPrimaryKey = new byte[pkpPrimaryKey.Body.Length + 3]; bPrimaryKey[0] = 0x99; bPrimaryKey[1] = (byte)((pkpPrimaryKey.Body.Length >> 8) & 0xFF); bPrimaryKey[2] = (byte)(pkpPrimaryKey.Body.Length & 0xFF); Array.Copy(pkpPrimaryKey.Body, 0, bPrimaryKey, 3, pkpPrimaryKey.Body.Length); byte[] bData = new byte[bPrimaryKey.Length + bSubKey.Length]; Array.Copy(bPrimaryKey, 0, bData, 0, bPrimaryKey.Length); Array.Copy(bSubKey, 0, bData, bPrimaryKey.Length, bSubKey.Length); SignaturePacket spKeyBindingSig = new SignaturePacket(); spKeyBindingSig.Version = SignaturePacketVersionNumbers.v4; spKeyBindingSig.HashAlgorithm = HashAlgorithms.SHA1; spKeyBindingSig.KeyID = pkpPrimaryKey.KeyID; spKeyBindingSig.SignatureType = SignatureTypes.SubkeyBindingSignature; if (expirationTime.Ticks != 0) { SignatureSubPacket sspExpiration = new SignatureSubPacket(); sspExpiration.Type = SignatureSubPacketTypes.KeyExpirationTime; sspExpiration.KeyExpirationTime = new DateTime(expirationTime.Ticks + (new DateTime(1970, 1, 2)).Ticks - pkpPrimaryKey.TimeCreated.Ticks); spKeyBindingSig.AddSubPacket(sspExpiration, true); } if (!revocable) { SignatureSubPacket sspRevocable = new SignatureSubPacket(); sspRevocable.Type = SignatureSubPacketTypes.Revocable; sspRevocable.Revocable = revocable; spKeyBindingSig.AddSubPacket(sspRevocable, true); } spKeyBindingSig.Sign(bData, skpPrimaryKey, strPassphrase); this.KeyBindingSignature = spKeyBindingSig; }
/// <summary> /// Secret key operation. Decrypts biCipher with the keydata /// in the given secret key packet. /// </summary> /// <param name="biCipher">The ciphertext that is about to /// be decrypted</param> /// <param name="skpKey">The secret key packet with the key /// material for the decryption</param> /// <param name="strPassphrase">The passphrase for the /// keymaterial</param> /// <returns>The decrypted ciphertext.</returns> /// <remarks>No remarks.</remarks> public override BigInteger Decrypt(BigInteger[] biCipher, SecretKeyPacket skpKey, string strPassphrase) { RSA_Secret_Key skey = new RSA_Secret_Key(); skey = ParseSecretKey(skpKey, strPassphrase); //check if someone mangled with the key if (!CheckKey(skey)) { throw(new Exception("This key does not fullfill the requirements of a valid RSA key. Please check if someone messed with your keys!")); } if ((skey.d == 0) || (skey.n == 0)) { throw new System.ArgumentException("This is not a valid secret key"); } BigInteger biPlain = biCipher[0].modPow(skey.d, skey.n); return(biPlain); }
private SignedMessage SignMessage(LiteralMessage lmToBeSigned, ulong lSignatureKeyID, string strPassphrase) { TransportableSecretKey tskKey = skrKeyRing.Find(lSignatureKeyID); SignedMessage smMessage = new SignedMessage(); smMessage.MessageSigned = lmToBeSigned; SignaturePacket spPacket = new SignaturePacket(); spPacket.Version = SignaturePacketVersionNumbers.v3; SecretKeyPacket skpKey = tskKey.FindKey(AsymActions.Sign); spPacket.KeyID = skpKey.PublicKey.KeyID; spPacket.HashAlgorithm = HashAlgorithms.SHA1; spPacket.SignatureAlgorithm = skpKey.PublicKey.Algorithm; spPacket.TimeCreated = DateTime.Now; spPacket.SignatureType = SignatureTypes.TextSignature; spPacket.Sign(lmToBeSigned.Binary, skpKey, strPassphrase); smMessage.Signature = spPacket; return(smMessage); }
/// <summary> /// Finds a subkey (or the primary key) with the given keyid /// and returns it. Returns null if the the fitting key has /// not been found. /// </summary> /// <remarks>No remarks.</remarks> /// <param name="lKeyID">The keyid to be sought in the transportable /// secret key.</param> /// <returns>The subkey (or the primary key) with the given keyid. /// Null if the the fitting key has not been found.</returns> public SecretKeyPacket FindKey(ulong lKeyID) { if (skpPrimaryKey.PublicKey.KeyID == lKeyID) { return(skpPrimaryKey); } IEnumerator ieSubkeys = alSubkeys.GetEnumerator(); while (ieSubkeys.MoveNext()) { SecretKeyPacket skpKey = (SecretKeyPacket)ieSubkeys.Current; if (skpKey.PublicKey.KeyID == lKeyID) { return(skpKey); } } return(null); }
/// <summary>Create a subkey</summary> internal PgpSecretKey( PgpKeyPair keyPair, TrustPacket trust, ArrayList subSigs, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSHA1, SecureRandom rand) : this(keyPair, encAlgorithm, passPhrase, useSHA1, rand) { this.secret = new SecretSubkeyPacket( secret.PublicKeyPacket, secret.EncAlgorithm, secret.S2kUsage, secret.S2k, secret.GetIV(), secret.GetSecretKeyData()); this.trust = trust; this.subSigs = subSigs; this.pub = new PgpPublicKey(keyPair.PublicKey, trust, subSigs); }
public void AddUserID(ulong lKeyID, string strName, string strEmail, string strPassphrase) { TransportableSecretKey tskKey = skrKeyRing.Find(lKeyID); TransportablePublicKey tpkKey = pkrKeyRing.Find(lKeyID, false); CertifiedUserID cuiUID = new CertifiedUserID(); UserIDPacket uipUID = new UserIDPacket(); uipUID.UserID = strName.Trim() + " <" + strEmail.Trim() + ">"; cuiUID.UserID = uipUID; SecretKeyPacket skpSignatureKey = tskKey.FindKey(AsymActions.Sign); SignaturePacket spSelfSig = new SignaturePacket(); spSelfSig.Version = SignaturePacketVersionNumbers.v4; spSelfSig.HashAlgorithm = HashAlgorithms.SHA1; spSelfSig.KeyID = skpSignatureKey.PublicKey.KeyID; spSelfSig.TimeCreated = DateTime.Now; cuiUID.Certificates = new System.Collections.ArrayList(); cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, tpkKey.PrimaryKey); tpkKey.Certifications.Add(cuiUID); tskKey.UserIDs.Add(uipUID); }
internal static PgpSecretKey DoCopyWithNewPassword( PgpSecretKey key, byte[] rawOldPassPhrase, byte[] rawNewPassPhrase, bool clearPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { if (key.IsPrivateKeyEmpty) throw new PgpException("no private key in this SecretKey - public key present only."); byte[] rawKeyData = key.ExtractKeyData(rawOldPassPhrase, clearPassPhrase); int s2kUsage = key.secret.S2kUsage; byte[] iv = null; S2k s2k = null; byte[] keyData; PublicKeyPacket pubKeyPacket = key.secret.PublicKeyPacket; 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 { if (s2kUsage == SecretKeyPacket.UsageNone) { s2kUsage = SecretKeyPacket.UsageChecksum; } try { if (pubKeyPacket.Version >= 4) { keyData = EncryptKeyDataV4(rawKeyData, newEncAlgorithm, HashAlgorithmTag.Sha1, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv); } else { keyData = EncryptKeyDataV3(rawKeyData, newEncAlgorithm, rawNewPassPhrase, clearPassPhrase, 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(pubKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); } else { secret = new SecretKeyPacket(pubKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); } return new PgpSecretKey(secret, key.pub); }
/// <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 { IBufferedCipher c; try { string cName = PgpUtilities.GetSymmetricCipherName(newEncAlgorithm); c = CipherUtilities.GetCipher(cName + "/CFB/NoPadding"); } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } iv = new byte[8]; rand.NextBytes(iv); s2k = new S2k(HashAlgorithmTag.Sha1, iv, 0x60); try { KeyParameter sKey = PgpUtilities.MakeKeyFromPassPhrase(newEncAlgorithm, s2k, newPassPhrase); iv = new byte[c.GetBlockSize()]; rand.NextBytes(iv); c.Init(true, new ParametersWithIV(sKey, iv)); keyData = c.DoFinal(rawKeyData); } 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); } if (key.subSigs == null) { return new PgpSecretKey(secret, key.trust, key.keySigs, key.ids, key.idTrusts, key.idSigs, key.pub); } return new PgpSecretKey(secret, key.trust, key.subSigs, key.pub); }
internal PgpSecretKey( SecretKeyPacket secret, TrustPacket trust, ArrayList keySigs, ArrayList ids, ArrayList idTrusts, ArrayList idSigs) { this.secret = secret; this.trust = trust; this.keySigs = keySigs; this.ids = ids; this.idTrusts = idTrusts; this.idSigs = idSigs; this.pub = new PgpPublicKey(secret.PublicKeyPacket, trust, keySigs, ids, idTrusts, idSigs); }
internal PgpSecretKey( SecretKeyPacket secret, TrustPacket trust, ArrayList subSigs) { this.secret = secret; this.trust = trust; this.subSigs = subSigs; this.pub = new PgpPublicKey(secret.PublicKeyPacket, trust, subSigs); }
internal PgpSecretKey( PgpPrivateKey privKey, PgpPublicKey pubKey, SymmetricKeyAlgorithmTag encAlgorithm, byte[] rawPassPhrase, bool clearPassPhrase, bool useSha1, SecureRandom rand, bool isMasterKey) { BcpgObject secKey; this.pub = pubKey; switch (pubKey.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: case PublicKeyAlgorithmTag.RsaGeneral: RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters) privKey.Key; secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q); break; case PublicKeyAlgorithmTag.Dsa: DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters) privKey.Key; secKey = new DsaSecretBcpgKey(dsK.X); break; case PublicKeyAlgorithmTag.ECDH: case PublicKeyAlgorithmTag.ECDsa: ECPrivateKeyParameters ecK = (ECPrivateKeyParameters)privKey.Key; secKey = new ECSecretBcpgKey(ecK.D); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters) privKey.Key; secKey = new ElGamalSecretBcpgKey(esK.X); break; default: throw new PgpException("unknown key class"); } try { MemoryStream bOut = new MemoryStream(); BcpgOutputStream pOut = new BcpgOutputStream(bOut); pOut.WriteObject(secKey); byte[] keyData = bOut.ToArray(); byte[] checksumData = Checksum(useSha1, keyData, keyData.Length); keyData = Arrays.Concatenate(keyData, checksumData); if (encAlgorithm == SymmetricKeyAlgorithmTag.Null) { if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, keyData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, keyData); } } else { S2k s2k; byte[] iv; byte[] encData; if (pub.Version >= 4) { encData = EncryptKeyDataV4(keyData, encAlgorithm, HashAlgorithmTag.Sha1, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv); } else { encData = EncryptKeyDataV3(keyData, encAlgorithm, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv); } int s2kUsage = useSha1 ? SecretKeyPacket.UsageSha1 : SecretKeyPacket.UsageChecksum; if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } } } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } }
internal PgpSecretKey( PgpKeyPair keyPair, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSHA1, SecureRandom rand) { PublicKeyPacket pubPk = keyPair.PublicKey.publicPk; BcpgObject secKey; switch (keyPair.PublicKey.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: case PublicKeyAlgorithmTag.RsaGeneral: RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters) keyPair.PrivateKey.Key; secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q); break; case PublicKeyAlgorithmTag.Dsa: DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters) keyPair.PrivateKey.Key; secKey = new DsaSecretBcpgKey(dsK.X); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters) keyPair.PrivateKey.Key; secKey = new ElGamalSecretBcpgKey(esK.X); break; default: throw new PgpException("unknown key class"); } string cName = PgpUtilities.GetSymmetricCipherName(encAlgorithm); IBufferedCipher c = null; if (cName != null) { try { c = CipherUtilities.GetCipher(cName + "/CFB/NoPadding"); } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } } try { MemoryStream bOut = new MemoryStream(); BcpgOutputStream pOut = new BcpgOutputStream(bOut); pOut.WriteObject(secKey); byte[] keyData = bOut.ToArray(); byte[] checksumBytes = Checksum(useSHA1, keyData, keyData.Length); pOut.Write(checksumBytes); byte[] bOutData = bOut.ToArray(); if (c != null) { byte[] iv = new byte[8]; rand.NextBytes(iv); S2k s2k = new S2k(HashAlgorithmTag.Sha1, iv, 0x60); KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase(encAlgorithm, s2k, passPhrase); iv = new byte[c.GetBlockSize()]; rand.NextBytes(iv); c.Init(true, new ParametersWithIV(key, iv)); byte[] encData = c.DoFinal(bOutData); int usage = useSHA1 ? SecretKeyPacket.UsageSha1 : SecretKeyPacket.UsageChecksum; this.secret = new SecretKeyPacket(pubPk, encAlgorithm, usage, s2k, iv, encData); } else { this.secret = new SecretKeyPacket(pubPk, encAlgorithm, null, null, bOutData); } this.trust = null; } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } this.keySigs = new ArrayList(); }
/// <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(IPgpSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { var rawKeyData = key.ExtractKeyData(oldPassPhrase); var s2KUsage = key.SecretPacket.S2KUsage; byte[] iv = null; S2k s2K = null; byte[] keyData; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { s2KUsage = SecretKeyPacket.UsageNone; if (key.SecretPacket.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); var 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) { throw; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } } SecretKeyPacket secret; if (key.SecretPacket is SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } else { secret = new SecretKeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } return new PgpSecretKey(secret, key.PublicKey); }
public void SignKeyBindingSignature(PublicKeyPacket pkpPrimaryKey, SecretKeyPacket skpPrimaryKey, string strPassphrase, DateTime expirationTime, bool revocable) { byte[] bSubKey = new byte[pkpSubkey.Body.Length + 3]; bSubKey[0] = 0x99; bSubKey[1] = (byte)((pkpSubkey.Body.Length >> 8) & 0xFF); bSubKey[2] = (byte)(pkpSubkey.Body.Length & 0xFF); Array.Copy(pkpSubkey.Body, 0, bSubKey, 3, pkpSubkey.Body.Length); byte[] bPrimaryKey = new byte[pkpPrimaryKey.Body.Length + 3]; bPrimaryKey[0] = 0x99; bPrimaryKey[1] = (byte)((pkpPrimaryKey.Body.Length >> 8) & 0xFF); bPrimaryKey[2] = (byte)(pkpPrimaryKey.Body.Length & 0xFF); Array.Copy(pkpPrimaryKey.Body, 0, bPrimaryKey, 3, pkpPrimaryKey.Body.Length); byte[] bData = new byte[bPrimaryKey.Length + bSubKey.Length]; Array.Copy(bPrimaryKey, 0, bData, 0, bPrimaryKey.Length); Array.Copy(bSubKey, 0, bData, bPrimaryKey.Length, bSubKey.Length); SignaturePacket spKeyBindingSig = new SignaturePacket(); spKeyBindingSig.Version = SignaturePacketVersionNumbers.v4; spKeyBindingSig.HashAlgorithm = HashAlgorithms.SHA1; spKeyBindingSig.KeyID = pkpPrimaryKey.KeyID; spKeyBindingSig.SignatureType = SignatureTypes.SubkeyBindingSignature; if(expirationTime.Ticks != 0) { SignatureSubPacket sspExpiration = new SignatureSubPacket(); sspExpiration.Type = SignatureSubPacketTypes.KeyExpirationTime; sspExpiration.KeyExpirationTime = new DateTime(expirationTime.Ticks + (new DateTime(1970,1,2)).Ticks - pkpPrimaryKey.TimeCreated.Ticks); spKeyBindingSig.AddSubPacket(sspExpiration, true); } if(!revocable) { SignatureSubPacket sspRevocable = new SignatureSubPacket(); sspRevocable.Type = SignatureSubPacketTypes.Revocable; sspRevocable.Revocable = revocable; spKeyBindingSig.AddSubPacket(sspRevocable, true); } spKeyBindingSig.Sign(bData, skpPrimaryKey, strPassphrase); this.KeyBindingSignature = spKeyBindingSig; }