예제 #1
0
        /// <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>If the public key has been revoked, it is ignored
        /// and NOT found by this function!!!</remarks>
        /// <param name="lKeyID">The keyid to be sought in the transportable
        /// public 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 PublicKeyPacket FindKey(ulong lKeyID)
        {
            if (pkpPrimaryKey.KeyID == lKeyID)
            {
                return(pkpPrimaryKey);
            }

            IEnumerator ieSubkeys = alSubkeys.GetEnumerator();

            while (ieSubkeys.MoveNext())
            {
                CertifiedPublicSubkey cpsKey = (CertifiedPublicSubkey)ieSubkeys.Current;

                // The subkey has been revoced
                if (cpsKey.RevocationSignature != null)
                {
                    continue;
                }

                PublicKeyPacket pkpKey = cpsKey.Subkey;
                if (pkpKey.KeyID == lKeyID)
                {
                    return(pkpKey);
                }
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        /// Generates a subkey for the specified primary key pair
        /// </summary>
        /// <param name="iKeySize">size of the subkey</param>
        /// <param name="strPassphrase">passphrase for the primar secret key</param>
        /// <param name="PrimaryKeyID">primary key pair keyID</param>
        /// <param name="expirationTime">expiration time for the subkey (new DateTime(0) == never)</param>
        /// <param name="isRevocableSubkey">is revocable?</param>
        public void GenerateSubkey(int iKeySize, string strPassphrase, ulong PrimaryKeyID, DateTime expirationTime, bool isRevocableSubkey)
        {
            if (iKeySize % 1024 != 0)
                throw new Exception("Keysize must be a 1024 multiple");
            TransportablePublicKey tpkKey = this.PublicRing.Find(PrimaryKeyID,false);
            TransportableSecretKey tskKey = this.SecretRing.Find(PrimaryKeyID);
            System.Security.Cryptography.RandomNumberGenerator rngRand;

            BigInteger[][] biEncryptionKey = GenerateElGamalEncryptionKey(iKeySize);

            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 = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpEncryptionKey.InitialVector);
            skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
            skpEncryptionKey.PublicKey = pkpEncryptionKey;

            CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
            cpsEncryptionKey.Subkey = pkpEncryptionKey;
            cpsEncryptionKey.SignKeyBindingSignature(tpkKey.PrimaryKey, tskKey.PrimaryKey, strPassphrase, expirationTime, isRevocableSubkey);

            tpkKey.SubKeys.Add(cpsEncryptionKey);
            this.PublicRing.AddPublicKey(tpkKey);

            tskKey.SubKeys.Add(skpEncryptionKey);
            this.SecretRing.AddSecretKey(tskKey);
        }
예제 #3
0
        /// <summary>
        /// Generate a key pair
        /// </summary>
        /// <param name="iKeySize">Encription key size</param>
        /// <param name="strPassphrase">passhrase for the key pair</param>
        /// <param name="userID">primary user id</param>
        /// <param name="email">user email</param>
        /// <param name="notation">xml encoded user info</param>
        /// <param name="expirationTime">expiration date of the primary key (new DateTime(0) == never)</param>
        /// <param name="keyType">1: RSA/DSA   0:Elgamal/DSA(DEFAULT)</param>
        /// <param name="isRevocableKey">revocable?</param>
        /// <param name="isRevocableSubkey">revocable subkey?</param>
        public void GenerateKey(int iKeySize, string strPassphrase, string userID, string email, string notation, DateTime expirationTime, int keyType, bool isRevocableKey, bool isRevocableSubkey)
        {
            if(iKeySize % 1024 != 0)
                throw new Exception("Keysize must be a 1024 multiple");

            System.Security.Cryptography.RandomNumberGenerator rngRand;

            // let's first create the encryption key
            BigInteger[][] biEncryptionKey;
            if (keyType == 1) {
                // it's a RSA/DSA key
                biEncryptionKey = GenerateRSAEncryptionKey(iKeySize);
            } else {
                // it's an elgamal/DSA key DEFAULF
                biEncryptionKey = GenerateElGamalEncryptionKey(iKeySize);
            }

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

            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 = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpSignatureKey.InitialVector);
            skpSignatureKey.EncryptKeyMaterial(biSignatureKey[1], strPassphrase);
            skpSignatureKey.PublicKey = pkpSignatureKey;

            PublicKeyPacket pkpEncryptionKey = new PublicKeyPacket(true);
            if (keyType == 0) {
                // it's an elgamal/DSA key
                pkpEncryptionKey.Algorithm = AsymAlgorithms.ElGamal_Encrypt_Only;
            } else if (keyType == 1) {
                // it's a RSA/DSA key
                pkpEncryptionKey.Algorithm = AsymAlgorithms.RSA_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 = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpEncryptionKey.InitialVector);
            skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
            skpEncryptionKey.PublicKey = pkpEncryptionKey;

            CertifiedUserID cuiUID = new CertifiedUserID();
            UserIDPacket uipUID = new UserIDPacket();
            uipUID.UserID = userID.Trim() + " <" + email.Trim() + ">";
            cuiUID.UserID = uipUID;
            SignaturePacket spSelfSig = new SignaturePacket();
            if (notation != null) {
                SignatureSubPacket sspNotation = new SignatureSubPacket();
                sspNotation.Type = SignatureSubPacketTypes.NotationData;
                sspNotation.NotationName = "PersonalData";
                sspNotation.NotationValue = notation;
                spSelfSig.AddSubPacket(sspNotation,false);
            }
            if (expirationTime.Ticks != 0) {
                SignatureSubPacket sspExpiration = new SignatureSubPacket();
                sspExpiration.Type = SignatureSubPacketTypes.KeyExpirationTime;
                sspExpiration.KeyExpirationTime = new DateTime(expirationTime.Ticks + (new DateTime(1970,1,2)).Ticks - pkpEncryptionKey.TimeCreated.Ticks);
                spSelfSig.AddSubPacket(sspExpiration, true);
            }
            if (!isRevocableKey) {
                SignatureSubPacket sspRevocable = new SignatureSubPacket();
                sspRevocable.Type = SignatureSubPacketTypes.Revocable;
                sspRevocable.Revocable = isRevocableKey;
                spSelfSig.AddSubPacket(sspRevocable, true);
            }
            SignatureSubPacket sspPrimaryUID = new SignatureSubPacket();
            sspPrimaryUID.Type = SignatureSubPacketTypes.PrimaryUserID;
            sspPrimaryUID.Revocable = true;
            spSelfSig.AddSubPacket(sspPrimaryUID, true);

            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);

            cuiUID.Certificates = new System.Collections.ArrayList();
            cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, pkpSignatureKey);

            CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
            cpsEncryptionKey.Subkey = pkpEncryptionKey;
            cpsEncryptionKey.SignKeyBindingSignature(pkpSignatureKey, skpSignatureKey, strPassphrase, expirationTime, isRevocableSubkey);

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

            this.PublicRing.AddPublicKey(tpkPublicKey);

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

            this.SecretRing.AddSecretKey(tskSecretKey);
        }
        /// <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 (packet 0 should have been public key packet)!"));

                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) {
                        this.RevocationSignatures.Add(spRevocation);
                    } else if(spRevocation.SignatureType == SignatureTypes.KeySignature) {
                        this.RevocationKeys.Add(spRevocation);
                    } else
                        throw(new ArgumentException("The given packet is not in the required transportable public key format (expected zero or more revocation signatures, was: " + spRevocation.SignatureType + ")!"));
                }

                // 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) &&
                            (spCertificate.SignatureType != SignatureTypes.CertificationRevocationSignature)) {
                            throw(new ArgumentException("The given packet is not in the required transportable public key format (expected zero or more Signatures/Certificates)!"));
                        }
                        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 (there was no UserIDPacket)!"));
                }

                // 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;

                    while ((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;
                        }
                    }
                    if (nCurrentPacket < pPackets.Length) {
                        if (!(pPackets[nCurrentPacket] is PublicKeyPacket)) {
                            throw(new ArgumentException("The given packet is not in the required transportable public key format (expected public subkey packet)!"));
                        }
                    }
                    /*
                    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 (no userid packet found)!"));
                }
            }
        }
예제 #5
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") {

            }
        }
예제 #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 (packet 0 should have been public key packet)!"));
                }

                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)
                    {
                        this.RevocationSignatures.Add(spRevocation);
                    }
                    else if (spRevocation.SignatureType == SignatureTypes.KeySignature)
                    {
                        this.RevocationKeys.Add(spRevocation);
                    }
                    else
                    {
                        throw(new ArgumentException("The given packet is not in the required transportable public key format (expected zero or more revocation signatures, was: " + spRevocation.SignatureType + ")!"));
                    }
                }

                // 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) &&
                            (spCertificate.SignatureType != SignatureTypes.CertificationRevocationSignature))
                        {
                            throw(new ArgumentException("The given packet is not in the required transportable public key format (expected zero or more Signatures/Certificates)!"));
                        }
                        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 (there was no UserIDPacket)!"));
                }

                // 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;

                    while ((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;
                        }
                    }
                    if (nCurrentPacket < pPackets.Length)
                    {
                        if (!(pPackets[nCurrentPacket] is PublicKeyPacket))
                        {
                            throw(new ArgumentException("The given packet is not in the required transportable public key format (expected public subkey packet)!"));
                        }
                    }

                    /*
                     * 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 (no userid packet found)!"));
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Finds a subkey (or the primary key) that fits to the given
        /// requirements (meaning it must be supposed to be used for
        /// the given action, which can be either signing or encryption).
        /// If more than just one keys fullfill the requirements, the one
        /// with the newer creationdate is used.
        /// </summary>
        /// <remarks>No remarks</remarks>
        /// <param name="aaAction">The action (signing or encrypting) for
        /// which the key should be used</param>
        /// <returns>Returns a public key packet fullfilling the given
        /// requirements (the action) or null, if it did not find such
        /// a key.</returns>
        public PublicKeyPacket FindKey(AsymActions aaAction)
        {
            DateTime        dtCandidateTime = DateTime.Now;
            PublicKeyPacket pkpCandidate    = new PublicKeyPacket();
            bool            bFound          = false;

            // First check the primary Key
            if (aaAction == AsymActions.Encrypt)
            {
                if (pkpPrimaryKey.Algorithm == AsymAlgorithms.ElGama_Encrypt_Sign ||
                    pkpPrimaryKey.Algorithm == AsymAlgorithms.ElGamal_Encrypt_Only ||
                    pkpPrimaryKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Only ||
                    pkpPrimaryKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Sign)
                {
                    dtCandidateTime = pkpPrimaryKey.TimeCreated;
                    bFound          = true;
                    pkpCandidate    = pkpPrimaryKey;
                }
            }
            else if (aaAction == AsymActions.Sign)
            {
                if (pkpPrimaryKey.Algorithm == AsymAlgorithms.ElGama_Encrypt_Sign ||
                    pkpPrimaryKey.Algorithm == AsymAlgorithms.DSA ||
                    pkpPrimaryKey.Algorithm == AsymAlgorithms.RSA_Sign_Only ||
                    pkpPrimaryKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Sign)
                {
                    dtCandidateTime = pkpPrimaryKey.TimeCreated;
                    bFound          = true;
                    pkpCandidate    = pkpPrimaryKey;
                }
            }

            // Now check the subkeys
            IEnumerator ieSubkeys = alSubkeys.GetEnumerator();

            while (ieSubkeys.MoveNext())
            {
                CertifiedPublicSubkey cpsKey = (CertifiedPublicSubkey)ieSubkeys.Current;

                // The subkey has been revoced
                if (cpsKey.RevocationSignature != null)
                {
                    continue;
                }

                PublicKeyPacket pkpKey = cpsKey.Subkey;
                if (aaAction == AsymActions.Encrypt)
                {
                    if (pkpKey.Algorithm == AsymAlgorithms.ElGama_Encrypt_Sign ||
                        pkpKey.Algorithm == AsymAlgorithms.ElGamal_Encrypt_Only ||
                        pkpKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Only ||
                        pkpKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Sign)
                    {
                        if ((bFound && dtCandidateTime < pkpKey.TimeCreated) || (!bFound))
                        {
                            dtCandidateTime = pkpKey.TimeCreated;
                            bFound          = true;
                            pkpCandidate    = pkpKey;
                        }
                    }
                }
                else if (aaAction == AsymActions.Sign)
                {
                    if (pkpKey.Algorithm == AsymAlgorithms.ElGama_Encrypt_Sign ||
                        pkpKey.Algorithm == AsymAlgorithms.DSA ||
                        pkpKey.Algorithm == AsymAlgorithms.RSA_Sign_Only ||
                        pkpKey.Algorithm == AsymAlgorithms.RSA_Encrypt_Sign)
                    {
                        if ((bFound && dtCandidateTime < pkpKey.TimeCreated) || (!bFound))
                        {
                            dtCandidateTime = pkpKey.TimeCreated;
                            bFound          = true;
                            pkpCandidate    = pkpKey;
                        }
                    }
                }
            }

            if (bFound)
            {
                return(pkpCandidate);
            }

            return(null);
        }
예제 #8
0
        /// <summary>
        /// Generates the transportable public key out of the properties
        /// in this.
        /// </summary>
        /// <remarks>No remarks</remarks>
        /// <returns>Returns a byte array containing the openpgp encoded
        /// representation of the transportable public key.</returns>
        public byte[] Generate()
        {
            byte[] bPrimaryKey = this.PrimaryKey.Generate();

            //Revocation signatures
            int         iLength       = 0;
            IEnumerator ieRevocations = this.RevocationSignatures.GetEnumerator();

            while (ieRevocations.MoveNext())
            {
                if (ieRevocations.Current is SignaturePacket)
                {
                    iLength += ((SignaturePacket)ieRevocations.Current).Generate().Length;
                }
            }
            byte[] bRevocations = new byte[iLength];
            ieRevocations = this.RevocationSignatures.GetEnumerator();
            int iPosition = 0;

            while (ieRevocations.MoveNext())
            {
                if (ieRevocations.Current is SignaturePacket)
                {
                    byte[] bRev = ((SignaturePacket)ieRevocations.Current).Generate();
                    Array.Copy(bRev, 0, bRevocations, iPosition, bRev.Length);
                    iPosition += bRev.Length;
                }
            }

            // Revoker keys
            iLength = 0;
            IEnumerator ieRevoker = this.RevocationKeys.GetEnumerator();

            while (ieRevoker.MoveNext())
            {
                if (ieRevoker.Current is SignaturePacket)
                {
                    iLength += ((SignaturePacket)ieRevoker.Current).Generate().Length;
                }
            }

            byte[] bRevoker = new byte[iLength];
            ieRevoker = this.RevocationKeys.GetEnumerator();
            iPosition = 0;
            while (ieRevoker.MoveNext())
            {
                if (ieRevoker.Current is SignaturePacket)
                {
                    byte[] bRev = ((SignaturePacket)ieRevoker.Current).Generate();
                    Array.Copy(bRev, 0, bRevoker, iPosition, bRev.Length);
                    iPosition += bRev.Length;
                }
            }

            //Certificates
            iLength = 0;
            IEnumerator ieCertificates = this.Certifications.GetEnumerator();

            while (ieCertificates.MoveNext())
            {
                if (ieCertificates.Current is CertifiedUserID)
                {
                    CertifiedUserID cuiID = (CertifiedUserID)ieCertificates.Current;
                    iLength += cuiID.Generate().Length;
                }
            }
            byte[] bCertificates = new byte[iLength];
            iPosition      = 0;
            ieCertificates = this.Certifications.GetEnumerator();
            while (ieCertificates.MoveNext())
            {
                if (ieCertificates.Current is CertifiedUserID)
                {
                    CertifiedUserID cuiID = (CertifiedUserID)ieCertificates.Current;
                    byte[]          bCert = cuiID.Generate();
                    Array.Copy(bCert, 0, bCertificates, iPosition, bCert.Length);
                    iPosition += bCert.Length;
                }
            }

            //SubKeys
            iLength = 0;
            IEnumerator ieSubkeys = this.SubKeys.GetEnumerator();

            while (ieSubkeys.MoveNext())
            {
                if (ieSubkeys.Current is CertifiedPublicSubkey)
                {
                    CertifiedPublicSubkey cpsKey = (CertifiedPublicSubkey)ieSubkeys.Current;
                    iLength += cpsKey.Generate().Length;
                }
            }
            byte[] bSubkeys = new byte[iLength];
            iPosition = 0;
            ieSubkeys = this.SubKeys.GetEnumerator();
            while (ieSubkeys.MoveNext())
            {
                if (ieSubkeys.Current is CertifiedPublicSubkey)
                {
                    CertifiedPublicSubkey cpsKey = (CertifiedPublicSubkey)ieSubkeys.Current;
                    byte[] bKey = cpsKey.Generate();
                    Array.Copy(bKey, 0, bSubkeys, iPosition, bKey.Length);
                    iPosition += bKey.Length;
                }
            }

            byte[] bData = new byte[bPrimaryKey.Length + bRevocations.Length +
                                    bRevoker.Length + bCertificates.Length + bSubkeys.Length];
            iPosition = 0;
            Array.Copy(bPrimaryKey, bData, bPrimaryKey.Length);
            iPosition = bPrimaryKey.Length;
            Array.Copy(bRevocations, 0, bData, iPosition, bRevocations.Length);
            iPosition += bRevocations.Length;
            Array.Copy(bRevoker, 0, bData, iPosition, bRevoker.Length);
            iPosition += bRevoker.Length;
            Array.Copy(bCertificates, 0, bData, iPosition, bCertificates.Length);
            iPosition += bCertificates.Length;
            Array.Copy(bSubkeys, 0, bData, iPosition, bSubkeys.Length);

            return(bData);
        }