/// <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); }
/// <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); }
/// <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)!")); } } }
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") { } }
/// <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)!")); } } }
/// <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); }
/// <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); }