1 files changed, 170 insertions, 0 deletions
diff --git a/Crypto/src/bcpg/SecretKeyPacket.cs b/Crypto/src/bcpg/SecretKeyPacket.cs
new file mode 100644
index 000000000..d9ceab4f1
--- /dev/null
+++ b/Crypto/src/bcpg/SecretKeyPacket.cs
@@ -0,0 +1,170 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Bcpg
+{
+ /// <remarks>Basic packet for a PGP secret key.</remarks>
+ public class SecretKeyPacket
+ : ContainedPacket //, PublicKeyAlgorithmTag
+ {
+ public const int UsageNone = 0x00;
+ public const int UsageChecksum = 0xff;
+ public const int UsageSha1 = 0xfe;
+
+ private PublicKeyPacket pubKeyPacket;
+ private readonly byte[] secKeyData;
+ private int s2kUsage;
+ private SymmetricKeyAlgorithmTag encAlgorithm;
+ private S2k s2k;
+ private byte[] iv;
+
+ internal SecretKeyPacket(
+ BcpgInputStream bcpgIn)
+ {
+ if (this is SecretSubkeyPacket)
+ {
+ pubKeyPacket = new PublicSubkeyPacket(bcpgIn);
+ }
+ else
+ {
+ pubKeyPacket = new PublicKeyPacket(bcpgIn);
+ }
+
+ s2kUsage = bcpgIn.ReadByte();
+
+ if (s2kUsage == UsageChecksum || s2kUsage == UsageSha1)
+ {
+ encAlgorithm = (SymmetricKeyAlgorithmTag) bcpgIn.ReadByte();
+ s2k = new S2k(bcpgIn);
+ }
+ else
+ {
+ encAlgorithm = (SymmetricKeyAlgorithmTag) s2kUsage;
+ }
+
+ if (!(s2k != null && s2k.Type == S2k.GnuDummyS2K && s2k.ProtectionMode == 0x01))
+ {
+ if (s2kUsage != 0)
+ {
+ if (((int) encAlgorithm) < 7)
+ {
+ iv = new byte[8];
+ }
+ else
+ {
+ iv = new byte[16];
+ }
+ bcpgIn.ReadFully(iv);
+ }
+ }
+
+ secKeyData = bcpgIn.ReadAll();
+ }
+
+ public SecretKeyPacket(
+ PublicKeyPacket pubKeyPacket,
+ SymmetricKeyAlgorithmTag encAlgorithm,
+ S2k s2k,
+ byte[] iv,
+ byte[] secKeyData)
+ {
+ this.pubKeyPacket = pubKeyPacket;
+ this.encAlgorithm = encAlgorithm;
+
+ if (encAlgorithm != SymmetricKeyAlgorithmTag.Null)
+ {
+ this.s2kUsage = UsageChecksum;
+ }
+ else
+ {
+ this.s2kUsage = UsageNone;
+ }
+
+ this.s2k = s2k;
+ this.iv = Arrays.Clone(iv);
+ this.secKeyData = secKeyData;
+ }
+
+ public SecretKeyPacket(
+ PublicKeyPacket pubKeyPacket,
+ SymmetricKeyAlgorithmTag encAlgorithm,
+ int s2kUsage,
+ S2k s2k,
+ byte[] iv,
+ byte[] secKeyData)
+ {
+ this.pubKeyPacket = pubKeyPacket;
+ this.encAlgorithm = encAlgorithm;
+ this.s2kUsage = s2kUsage;
+ this.s2k = s2k;
+ this.iv = Arrays.Clone(iv);
+ this.secKeyData = secKeyData;
+ }
+
+ public SymmetricKeyAlgorithmTag EncAlgorithm
+ {
+ get { return encAlgorithm; }
+ }
+
+ public int S2kUsage
+ {
+ get { return s2kUsage; }
+ }
+
+ public byte[] GetIV()
+ {
+ return Arrays.Clone(iv);
+ }
+
+ public S2k S2k
+ {
+ get { return s2k; }
+ }
+
+ public PublicKeyPacket PublicKeyPacket
+ {
+ get { return pubKeyPacket; }
+ }
+
+ public byte[] GetSecretKeyData()
+ {
+ return secKeyData;
+ }
+
+ public byte[] GetEncodedContents()
+ {
+ MemoryStream bOut = new MemoryStream();
+ BcpgOutputStream pOut = new BcpgOutputStream(bOut);
+
+ pOut.Write(pubKeyPacket.GetEncodedContents());
+
+ pOut.WriteByte((byte) s2kUsage);
+
+ if (s2kUsage == UsageChecksum || s2kUsage == UsageSha1)
+ {
+ pOut.WriteByte((byte) encAlgorithm);
+ pOut.WriteObject(s2k);
+ }
+
+ if (iv != null)
+ {
+ pOut.Write(iv);
+ }
+
+ if (secKeyData != null && secKeyData.Length > 0)
+ {
+ pOut.Write(secKeyData);
+ }
+
+ return bOut.ToArray();
+ }
+
+ public override void Encode(
+ BcpgOutputStream bcpgOut)
+ {
+ bcpgOut.WritePacket(PacketTag.SecretKey, GetEncodedContents(), true);
+ }
+ }
+}
|