/// <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);
        }
        /// <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!"));
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        public void GenerateKey(string strName, string strEmail, string strKeyType, int iKeySize, long lExpiration, string strPassphrase)
        {
            if (strKeyType == "ElGamal/DSA")
            {
                System.Security.Cryptography.RandomNumberGenerator rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();

                // let's first create the encryption key
                BigInteger[][] biEncryptionKey = GenerateEncryptionKey(iKeySize);

                // now the signature key
                BigInteger[][] biSignatureKey = GenerateSignatureKey();

                PublicKeyPacket pkpSignatureKey = new PublicKeyPacket(false);
                pkpSignatureKey.Algorithm   = AsymAlgorithms.DSA;
                pkpSignatureKey.KeyMaterial = biSignatureKey[0];
                pkpSignatureKey.TimeCreated = DateTime.Now;
                pkpSignatureKey.Version     = PublicKeyPacketVersionNumbers.v4;

                SecretKeyPacket skpSignatureKey = new SecretKeyPacket(false);
                skpSignatureKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
                skpSignatureKey.PublicKey            = pkpSignatureKey;
                skpSignatureKey.InitialVector        = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
                rngRand.GetBytes(skpSignatureKey.InitialVector);
                skpSignatureKey.EncryptKeyMaterial(biSignatureKey[1], strPassphrase);
                skpSignatureKey.PublicKey = pkpSignatureKey;

                PublicKeyPacket pkpEncryptionKey = new PublicKeyPacket(true);
                pkpEncryptionKey.Algorithm   = AsymAlgorithms.ElGamal_Encrypt_Only;
                pkpEncryptionKey.KeyMaterial = biEncryptionKey[0];
                pkpEncryptionKey.TimeCreated = DateTime.Now;
                pkpEncryptionKey.Version     = PublicKeyPacketVersionNumbers.v4;

                SecretKeyPacket skpEncryptionKey = new SecretKeyPacket(true);
                skpEncryptionKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
                skpEncryptionKey.PublicKey            = pkpEncryptionKey;
                skpEncryptionKey.InitialVector        = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
                rngRand.GetBytes(skpEncryptionKey.InitialVector);
                skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
                skpEncryptionKey.PublicKey = pkpEncryptionKey;

                CertifiedUserID cuiUID = new CertifiedUserID();
                UserIDPacket    uipUID = new UserIDPacket();
                uipUID.UserID = strName.Trim() + " <" + strEmail.Trim() + ">";
                cuiUID.UserID = uipUID;
                SignaturePacket spSelfSig = new SignaturePacket();
                spSelfSig.Version       = SignaturePacketVersionNumbers.v4;
                spSelfSig.HashAlgorithm = HashAlgorithms.SHA1;
                spSelfSig.KeyID         = pkpSignatureKey.KeyID;
                spSelfSig.TimeCreated   = DateTime.Now;
                SignatureSubPacket sspPrimaryUserID = new SignatureSubPacket();
                sspPrimaryUserID.Type          = SignatureSubPacketTypes.PrimaryUserID;
                sspPrimaryUserID.PrimaryUserID = true;
                spSelfSig.AddSubPacket(sspPrimaryUserID, true);
                SignatureSubPacket sspPreferedSymAlgos = new SignatureSubPacket();
                sspPreferedSymAlgos.Type             = SignatureSubPacketTypes.PreferedSymmetricAlgorithms;
                sspPreferedSymAlgos.PreferedSymAlgos = new SymAlgorithms[] { SymAlgorithms.AES256, SymAlgorithms.AES192, SymAlgorithms.AES256, SymAlgorithms.CAST5, SymAlgorithms.Triple_DES };
                spSelfSig.AddSubPacket(sspPreferedSymAlgos, true);
                SignatureSubPacket sspPreferedHashAlgos = new SignatureSubPacket();
                sspPreferedHashAlgos.Type = SignatureSubPacketTypes.PreferedHashAlgorithms;
                sspPreferedHashAlgos.PreferedHashAlgos = new HashAlgorithms[] { HashAlgorithms.SHA1 };
                spSelfSig.AddSubPacket(sspPreferedHashAlgos, true);
                if (lExpiration != 0)
                {
                    SignatureSubPacket sspExpiration = new SignatureSubPacket();
                    sspExpiration.Type = SignatureSubPacketTypes.SignatureExpirationTime;
                    sspExpiration.SignatureExpirationTime = new DateTime(lExpiration);
                    spSelfSig.AddSubPacket(sspExpiration, true);
                }
                cuiUID.Certificates = new System.Collections.ArrayList();
                cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, pkpSignatureKey);

                CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
                cpsEncryptionKey.Subkey = pkpEncryptionKey;
                cpsEncryptionKey.SignKeyBindingSignature(pkpSignatureKey, skpSignatureKey, strPassphrase, new DateTime(lExpiration), true);

                TransportablePublicKey tpkPublicKey = new TransportablePublicKey();
                tpkPublicKey.PrimaryKey = pkpSignatureKey;
                tpkPublicKey.SubKeys.Add(cpsEncryptionKey);
                tpkPublicKey.Certifications.Add(cuiUID);

                TransportableSecretKey tskSecretKey = new TransportableSecretKey();
                tskSecretKey.PrimaryKey = skpSignatureKey;
                tskSecretKey.SubKeys.Add(skpEncryptionKey);
                tskSecretKey.UserIDs.Add(uipUID);

                this.pkrKeyRing.AddPublicKey(tpkPublicKey);
                this.skrKeyRing.AddSecretKey(tskSecretKey);
                pkrKeyRing.Save();
                skrKeyRing.Save();

                // it's an RSA key
            }
            else if (strKeyType == "RSA")
            {
            }
        }
예제 #5
0
        public string GetSecretKeyProperties(ulong lKeyID)
        {
            TransportableSecretKey tskKey = skrKeyRing.Find(lKeyID);
            SecretKeyPacket        skpKey = tskKey.PrimaryKey;

            XmlDocument xmlDoc = new XmlDocument();

            XmlElement xmlSecretKey = xmlDoc.CreateElement("SecretKey");

            xmlSecretKey.SetAttribute("keyid", "0x" + skpKey.PublicKey.KeyID.ToString("x"));
            xmlSecretKey.SetAttribute("fingerprint", skpKey.PublicKey.Fingerprint.ToString(16));
            xmlSecretKey.SetAttribute("size", skpKey.PublicKey.KeyMaterial[0].bitCount().ToString());
            xmlSecretKey.SetAttribute("algorithm", skpKey.PublicKey.Algorithm.ToString());
            xmlSecretKey.SetAttribute("timecreated", skpKey.PublicKey.TimeCreated.Ticks.ToString());

            XmlElement xmlUserIDs = xmlDoc.CreateElement("UserIDs");

            XmlElement  xmlUserID;
            IEnumerator ieUserIDs = tskKey.UserIDs.GetEnumerator();

            while (ieUserIDs.MoveNext())
            {
                if (!(ieUserIDs.Current is UserIDPacket))
                {
                    continue;
                }

                UserIDPacket uipUID = (UserIDPacket)ieUserIDs.Current;
                xmlUserID = xmlDoc.CreateElement("UserID");
                xmlUserID.SetAttribute("name", uipUID.UserID);

                xmlUserIDs.AppendChild(xmlUserID);
            }

            xmlSecretKey.AppendChild(xmlUserIDs);

            XmlElement xmlSubkeys = xmlDoc.CreateElement("Subkeys");

            XmlElement  xmlSubkey;
            IEnumerator ieSubkeys = tskKey.SubKeys.GetEnumerator();

            while (ieSubkeys.MoveNext())
            {
                if (!(ieSubkeys.Current is SecretKeyPacket))
                {
                    continue;
                }

                SecretKeyPacket skpSubkey = (SecretKeyPacket)ieSubkeys.Current;
                xmlSubkey = xmlDoc.CreateElement("Subkey");
                xmlSubkey.SetAttribute("keyid", "0x" + skpSubkey.PublicKey.KeyID.ToString("x"));
                xmlSubkey.SetAttribute("fingerprint", skpSubkey.PublicKey.Fingerprint.ToString(16));
                xmlSubkey.SetAttribute("size", skpSubkey.PublicKey.KeyMaterial[0].bitCount().ToString());
                xmlSubkey.SetAttribute("algorithm", skpSubkey.PublicKey.Algorithm.ToString());


                xmlSubkeys.AppendChild(xmlSubkey);
            }

            xmlSecretKey.AppendChild(xmlSubkeys);

            xmlDoc.AppendChild(xmlSecretKey);

            return(xmlDoc.OuterXml);
        }
예제 #6
0
        /// <summary>
        /// Parses the radix64 encoded representation of a transportable public
        /// key given as an argument to populate the parameters of this.
        /// </summary>
        /// <remarks>No remarks</remarks>
        /// <param name="strRadix64">Radix64 representation of an transportable
        /// public key</param>
        /// <exception cref="System.ArgumentException">Throws an
        /// ArgumentException if the radix64 string given as a parameter is
        /// not an transportable public key.</exception>
        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 PublicKeyPacket))
                {
                    throw(new ArgumentException("The given packet is not in the required transportable public key format!"));
                }
                this.PrimaryKey = (PublicKeyPacket)pPackets[nCurrentPacket++];

                // Next we expect zero or more revocation signatures
                while ((nCurrentPacket < pPackets.Length) && (pPackets[nCurrentPacket] is SignaturePacket))
                {
                    SignaturePacket spRevocation = (SignaturePacket)pPackets[nCurrentPacket++];
                    if (spRevocation.SignatureType != SignatureTypes.KeyRevocationSignature)
                    {
                        throw(new ArgumentException("The given packet is not in the required transportable public key format!"));
                    }
                    this.RevocationSignatures.Add(spRevocation);
                }

                // Next in queue must be one or more UserID Packets
                while ((nCurrentPacket < pPackets.Length) && (pPackets[nCurrentPacket] is UserIDPacket))
                {
                    nUserIDCounter++;
                    CertifiedUserID cuiUserID = new CertifiedUserID();
                    UserIDPacket    uipUserID = (UserIDPacket)pPackets[nCurrentPacket++];
                    cuiUserID.UserID = uipUserID;

                    // For every UserIDPacket we expect zero or more Signatures (Certificates)
                    while ((nCurrentPacket < pPackets.Length) && (pPackets[nCurrentPacket] is SignaturePacket))
                    {
                        SignaturePacket spCertificate = (SignaturePacket)pPackets[nCurrentPacket++];
                        if ((spCertificate.SignatureType != SignatureTypes.UserIDSignature) &&
                            (spCertificate.SignatureType != SignatureTypes.UserIDSignature_CasualVerification) &&
                            (spCertificate.SignatureType != SignatureTypes.UserIDSignature_NoVerification) &&
                            (spCertificate.SignatureType != SignatureTypes.UserIDSignature_PositivVerification))
                        {
                            throw(new ArgumentException("The given packet is not in the required transportable public key format!"));
                        }
                        cuiUserID.Certificates.Add(spCertificate);
                    }
                    this.Certifications.Add(cuiUserID);
                }

                // There was no UserIDPacket. This is fatal!!!
                if (nUserIDCounter == 0)
                {
                    throw(new ArgumentException("The given packet is not in the required transportable public key format!"));
                }

                // Finally we have zero or more subkeys
                while ((nCurrentPacket < pPackets.Length) && (pPackets[nCurrentPacket] is PublicKeyPacket))
                {
                    PublicKeyPacket       pkpSubKey = (PublicKeyPacket)pPackets[nCurrentPacket++];
                    CertifiedPublicSubkey cpsSubKey = new CertifiedPublicSubkey();
                    cpsSubKey.Subkey = pkpSubKey;

                    if ((nCurrentPacket < pPackets.Length) && (pPackets[nCurrentPacket] is SignaturePacket))
                    {
                        SignaturePacket spKeySignature = (SignaturePacket)pPackets[nCurrentPacket++];
                        if (spKeySignature.SignatureType == SignatureTypes.SubkeyBindingSignature)
                        {
                            cpsSubKey.KeyBindingSignature = spKeySignature;
                        }
                        else if (spKeySignature.SignatureType == SignatureTypes.SubkeyRevocationSignature)
                        {
                            cpsSubKey.RevocationSignature = spKeySignature;
                        }
                    }
                    else
                    {
                        throw(new ArgumentException("The given packet is not in the required transportable public key format!"));
                    }
                    if (nCurrentPacket < pPackets.Length)
                    {
                        if (pPackets[nCurrentPacket] is SignaturePacket)
                        {
                            SignaturePacket spSubkeyRev = (SignaturePacket)pPackets[nCurrentPacket++];
                            cpsSubKey.RevocationSignature = spSubkeyRev;
                        }
                    }
                    this.SubKeys.Add(cpsSubKey);
                }
            } catch (System.IndexOutOfRangeException) {
                if (nUserIDCounter == 0)
                {
                    throw(new ArgumentException("The given packet is not in the required transportable public key format!"));
                }
            }
        }
        /// <summary>
        /// Parses a single packet out of the given binary
        /// data. Even if there are more than one packets in the byte
        /// array, only the first packet is returned.
        /// </summary>
        /// <param name="bBinaryData">A byte array containing a set
        /// of OpenPGP packets</param>
        /// <returns>Returns an single OpenPGP packets</returns>
        /// <remarks>No remarks</remarks>
        public virtual Packet ParsePacket(byte[] bBinaryData)
        {
            Packet pReturnPacket = new Packet();

            if ((bBinaryData[0] & 0xC0) == 0xC0)
            {
                pfFormat = PacketFormats.New;
            }
            else if ((bBinaryData[0] & 0xC0) == 0x80)
            {
                pfFormat = PacketFormats.Old;
            }
            else
            {
                throw(new ArgumentException("This is not a valid OpenPGP Packet"));
            }


            if (pfFormat == PacketFormats.New)
            {
                int iBinaryDataPos = 2;
                ctContent = (ContentTypes)(bBinaryData[0] & 0x3F);
                lLength   = bBinaryData[1];
                bBody     = new byte[0];
                int iHeaderLength = 1;
                //partial body lengths
                while ((lLength > 223) && (lLength < 255))
                {
                    iHeaderLength++;
                    int lPartialBody = 1 << ((int)(lLength & 0x1F));
                    int lOldLength   = 0;
                    if (bBody.Length > 0)
                    {
                        byte[] bOldBody = new byte[bBody.Length];
                        bBody.CopyTo(bOldBody, 0);
                        bBody = new byte[bOldBody.Length + lPartialBody];
                        bOldBody.CopyTo(bBody, 0);
                        lOldLength = bBody.Length;
                    }
                    else
                    {
                        bBody = new byte[lPartialBody];
                    }
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, lOldLength, lPartialBody);
                    lLength         = bBinaryData[iBinaryDataPos + lPartialBody];
                    iBinaryDataPos += lPartialBody;
                }                 //partial bodies must end with a normal header!
                if (lLength < 192)
                {
                    iHeaderLength++;
                    bHeader = new byte[iHeaderLength];
                    if (bBody.Length == 0)
                    {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 2);
                        iBinaryDataPos = 1;
                    }
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos + 1, bBody, bBody.Length - (int)lLength, (int)lLength);
                }
                else if ((lLength > 191) && (lLength < 224))
                {
                    iHeaderLength += 2;
                    bHeader        = new byte[iHeaderLength];
                    if (bBody.Length == 0)
                    {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 3);
                        iBinaryDataPos = 1;
                    }
                    lLength = ((bBinaryData[iBinaryDataPos++] - 192) << 8) + bBinaryData[iBinaryDataPos++] + 192;
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - (int)lLength, (int)lLength);
                }
                else if (lLength == 255)
                {
                    iHeaderLength += 5;
                    bHeader        = new byte[iHeaderLength];
                    if (bBody.Length == 0)
                    {
                        Array.Copy(bBinaryData, 0, bHeader, 0, 6);
                    }
                    lLength = (bBinaryData[iBinaryDataPos++] << 24) ^ (bBinaryData[iBinaryDataPos++] << 16) ^
                              (bBinaryData[iBinaryDataPos++] << 8) ^ bBinaryData[iBinaryDataPos++];
                    byte[] bOldBody = new byte[bBody.Length];
                    bBody.CopyTo(bOldBody, 0);
                    bBody = new byte[bOldBody.Length + lLength];
                    bOldBody.CopyTo(bBody, 0);
                    Array.Copy(bBinaryData, iBinaryDataPos, bBody, bBody.Length - (int)lLength, (int)lLength);
                }
            }
            else
            {
                ctContent = (ContentTypes)((bBinaryData[0] & 0x3C) >> 2);
                switch (bBinaryData[0] & 0x03)
                {
                case 0:
                    lLength = bBinaryData[1];
                    bHeader = new byte[2];
                    break;

                case 1:
                    lLength = (bBinaryData[1] << 8) ^ (bBinaryData[2]);
                    bHeader = new byte[3];
                    break;

                case 2:
                    lLength = (bBinaryData[1] << 16) ^ (bBinaryData[2] << 8) ^
                              (bBinaryData[3]);
                    bHeader = new byte[4];
                    break;

                case 3:
                    throw new System.NotSupportedException("Packets of indetermined length are not supported due to security considerations!");

                default:
                    throw new System.ApplicationException("This is not a valid Packet!");
                }
                bBody = new byte[lLength];
                Array.Copy(bBinaryData, 0, bHeader, 0, bHeader.Length);
                Array.Copy(bBinaryData, bHeader.Length, bBody, 0, (int)lLength);
            }

            this.bIsUpdated = false;
            switch (ctContent)
            {
            case ContentTypes.AsymSessionKey:
                pReturnPacket = new AsymSessionKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Compressed:
                pReturnPacket = new CompressedDataPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.LiteralData:
                pReturnPacket = new LiteralDataPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Marker:
                pReturnPacket = new Packet(this);
                //We can savly ignore Marker packets!
                //MessageBox.Show("This is a marker packet. It is not yet supported.");
                break;

            case ContentTypes.OnePassSignature:
                pReturnPacket = new OnePassSignaturePacket(this);
                //System.Windows.Forms.MessageBox.Show("This is a One Pass Signature Packet. It is not yet supported");
                break;

            //Content is Public Key Packet
            case ContentTypes.PublicKey:
                pReturnPacket = new PublicKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            //Content is Public Subkey Packet. Same format as Public Key Packet
            case ContentTypes.PublicSubkey:
                pReturnPacket = new PublicKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SecretKey:
                pReturnPacket = new SecretKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SecretSubkey:
                pReturnPacket = new SecretKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Signature:
                pReturnPacket = new SignaturePacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SymEncrypted:
                pReturnPacket = new SymmetricallyEncryptedDataPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.SymSessionKey:
                pReturnPacket = new SymSessionKeyPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            case ContentTypes.Trust:
                pReturnPacket = new Packet(this);
                // TODO - Remove the messagebox
                //System.Windows.Forms.MessageBox.Show("This is a Trust Packet. It is not yet supported");
                break;

            case ContentTypes.UserID:
                pReturnPacket = new UserIDPacket(this);
                pReturnPacket = pReturnPacket.ParsePacket(bBody);
                break;

            default:
                pReturnPacket = new Packet(this);
                // TODO - Remove the messagebox
                System.Windows.Forms.MessageBox.Show("Sorry, but this is a packet I don't know about!");
                break;
            }

            pReturnPacket.bIsUpdated = false;
            return(pReturnPacket);
        }