private string FindPrimaryUserID() { string strReturn = ""; int nUserIDCounter = 0; IEnumerator ieCertificates = this.alCertifications.GetEnumerator(); while (ieCertificates.MoveNext()) { if (!(ieCertificates.Current is CertifiedUserID)) { continue; } nUserIDCounter++; CertifiedUserID cuiID = (CertifiedUserID)ieCertificates.Current; IEnumerator ieSignatures = cuiID.Certificates.GetEnumerator(); while (ieSignatures.MoveNext()) { if (!(ieSignatures.Current is SignaturePacket)) { continue; } SignaturePacket spCertificate = (SignaturePacket)ieSignatures.Current; // look only at selfsignatures if (spCertificate.KeyID != this.PrimaryKey.KeyID) { continue; } if (nUserIDCounter == 1) { strReturn = cuiID.UserID.UserID; } for (int i = 0; i < spCertificate.UnhashedSubPackets.Length; i++) { if ((spCertificate.UnhashedSubPackets[i].Type == SignatureSubPacketTypes.PrimaryUserID) && (spCertificate.UnhashedSubPackets[i].PrimaryUserID)) { strReturn = cuiID.UserID.UserID; } } for (int i = 0; i < spCertificate.HashedSubPackets.Length; i++) { if ((spCertificate.HashedSubPackets[i].Type == SignatureSubPacketTypes.PrimaryUserID) && (spCertificate.HashedSubPackets[i].PrimaryUserID)) { strReturn = cuiID.UserID.UserID; } } } } return(strReturn); }
public override bool Equals(object o) { if (o is CertifiedUserID) { CertifiedUserID cuiComp = (CertifiedUserID)o; if (cuiComp.UserID.UserID == this.UserID.UserID) { return(true); } } return(false); }
private DateTime FindExpirationDate() { IEnumerator ieCertificates = this.alCertifications.GetEnumerator(); while (ieCertificates.MoveNext()) { if (!(ieCertificates.Current is CertifiedUserID)) { continue; } CertifiedUserID cuiID = (CertifiedUserID)ieCertificates.Current; IEnumerator ieSignatures = cuiID.Certificates.GetEnumerator(); while (ieSignatures.MoveNext()) { if (!(ieSignatures.Current is SignaturePacket)) { continue; } SignaturePacket spCertificate = (SignaturePacket)ieSignatures.Current; // look only at selfsignatures if (spCertificate.KeyID != this.PrimaryKey.KeyID) { continue; } for (int i = 0; i < spCertificate.HashedSubPackets.Length; i++) { if (spCertificate.HashedSubPackets[i].Type == SignatureSubPacketTypes.KeyExpirationTime) { return(spCertificate.HashedSubPackets[i].KeyExpirationTime); } } } } throw new Exception("never"); }
public SymAlgorithms[] FindPreferedAlgorithms() { IEnumerator ieCertificates = this.alCertifications.GetEnumerator(); while (ieCertificates.MoveNext()) { if (!(ieCertificates.Current is CertifiedUserID)) { continue; } CertifiedUserID cuiID = (CertifiedUserID)ieCertificates.Current; IEnumerator ieSignatures = cuiID.Certificates.GetEnumerator(); while (ieSignatures.MoveNext()) { if (!(ieSignatures.Current is SignaturePacket)) { continue; } SignaturePacket spCertificate = (SignaturePacket)ieSignatures.Current; // look only at selfsignatures if (spCertificate.KeyID != this.PrimaryKey.KeyID) { continue; } try { SymAlgorithms[] saReturn = spCertificate.FindPreferedSymAlgorithms(); return(saReturn); } catch (Exception) {} } } throw new Exception("none found!"); }
/// <summary> /// Returns a string representation of the transportable public key. /// </summary> /// <remarks>No remarks</remarks> /// <returns>Returns a string representation of the transportable /// public key.</returns> public override string ToString() { string strReturn = ""; strReturn += "Abstract:\r\n"; strReturn += "Number of Certificates: " + this.Certifications.Count + "\r\n"; strReturn += "\r\n\r\n\r\nPublic Key Packet: \r\n"; strReturn += this.PrimaryKey.ToString() + "\r\n\r\n"; IEnumerator ieLoop = this.Certifications.GetEnumerator(); while (ieLoop.MoveNext()) { if (ieLoop.Current is CertifiedUserID) { CertifiedUserID cuiUserID = (CertifiedUserID)ieLoop.Current; strReturn += cuiUserID.ToString(); } } return(strReturn); }
/// <summary> /// Revokes a key certified userID /// </summary> /// <param name="KeyID">key containing the certified user id</param> /// <param name="cuidTobeSigned">certified user id to be revoked</param> /// <param name="skpKeySigner">revoker secret key</param> /// <param name="strPassphrase">revoker passphrase</param> /// <param name="exportable">exportable revocation</param> public void RevokeKeyCertificate(ulong KeyID, CertifiedUserID cuidTobeSigned, TransportableSecretKey skpKeySigner, string strPassphrase, bool exportable) { TransportablePublicKey tspKey = this.PublicRing.Find(KeyID,false); if(tspKey == null) throw new Exception("Public Key not found"); bool found = false; CertifiedUserID toBeVerified = null; foreach(CertifiedUserID cui in tspKey.Certifications) { if(cui==cuidTobeSigned) { found=true; toBeVerified = cui; break; } } if (!found) throw new Exception("UserId not found among Key certificates"); found = false; foreach(SignaturePacket sign in toBeVerified.Certificates) { if(sign.KeyID == skpKeySigner.PrimaryKey.PublicKey.KeyID && sign.isRevocable()) found = true; } if (!found) throw new Exception("UserId not certified by this private key or not revocable"); SignaturePacket spSig = new SignaturePacket(); spSig.Version = SignaturePacketVersionNumbers.v4; spSig.HashAlgorithm = HashAlgorithms.SHA1; spSig.KeyID = skpKeySigner.PrimaryKey.PublicKey.KeyID; spSig.TimeCreated = DateTime.Now; SignatureSubPacket sspExportableSignature = new SignatureSubPacket(); sspExportableSignature.Type = SignatureSubPacketTypes.ExportableSignature; sspExportableSignature.ExportableSignature = exportable; spSig.AddSubPacket(sspExportableSignature, false); cuidTobeSigned.Revoke(spSig, skpKeySigner.PrimaryKey, strPassphrase, tspKey.PrimaryKey); }
/// <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> /// Changes the primary user id of a public key /// </summary> /// <param name="newPUID">the certified user id to se as primary</param> /// <param name="KeyID">the keyID to execute the operation for</param> /// <param name="strPassphrase"></param> public void changePrimaryUserID(CertifiedUserID newPUID, ulong KeyID, string strPassphrase) { TransportablePublicKey tpkKey = this.PublicRing.Find(KeyID,false); TransportableSecretKey tskKey = this.SecretRing.Find(KeyID); if (tpkKey!=null && tskKey!=null) { CertifiedUserID oldPUID = tpkKey.PrimaryUserIDCert; if (oldPUID!=newPUID) { bool updated = false; for (int k = 0; k < oldPUID.Certificates.Count; k++) { SignaturePacket sp = (SignaturePacket)oldPUID.Certificates[k]; if(sp.SignatureType == SignatureTypes.UserIDSignature || sp.SignatureType == SignatureTypes.UserIDSignature_CasualVerification || sp.SignatureType == SignatureTypes.UserIDSignature_NoVerification || sp.SignatureType == SignatureTypes.UserIDSignature_PositivVerification) { foreach (SignatureSubPacket ssp in sp.HashedSubPackets) { if(ssp.Type == SignatureSubPacketTypes.PrimaryUserID) { ssp.PrimaryUserID = false; updated = true; } } if (!updated) { foreach(SignatureSubPacket ssp in sp.UnhashedSubPackets) { if(ssp.Type == SignatureSubPacketTypes.PrimaryUserID) { ssp.PrimaryUserID = false; updated = true; } } } if (updated) { oldPUID.Certificates.Remove(sp); oldPUID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey); break; } } } updated = false; for (int k = 0; k < oldPUID.Certificates.Count; k++) { SignaturePacket sp = (SignaturePacket)newPUID.Certificates[k]; if (sp.SignatureType == SignatureTypes.UserIDSignature || sp.SignatureType == SignatureTypes.UserIDSignature_CasualVerification || sp.SignatureType == SignatureTypes.UserIDSignature_NoVerification || sp.SignatureType == SignatureTypes.UserIDSignature_PositivVerification) { foreach(SignatureSubPacket ssp in sp.HashedSubPackets) { if(ssp.Type == SignatureSubPacketTypes.PrimaryUserID) { ssp.PrimaryUserID = true; updated = true; } } if (!updated) { foreach (SignatureSubPacket ssp in sp.UnhashedSubPackets) { if (ssp.Type == SignatureSubPacketTypes.PrimaryUserID) { ssp.PrimaryUserID = true; updated = true; } } } if (updated) { newPUID.Certificates.Remove(sp); newPUID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey); break; } if (!updated) { SignatureSubPacket sspPrimaryUserID = new SignatureSubPacket(); sspPrimaryUserID.Type = SignatureSubPacketTypes.PrimaryUserID; sspPrimaryUserID.PrimaryUserID = true; sp.AddSubPacket(sspPrimaryUserID,true); newPUID.Certificates.Remove(sp); newPUID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey); break; } } } } } }
/// <summary> /// Adds a userID to the specified key /// </summary> /// <param name="userID">user id to be added</param> /// <param name="email">user email address</param> /// <param name="infos">xml encoded user infos</param> /// <param name="strPassphrase">passphrase of the secret key we want to add the user id to</param> /// <param name="KeyID">keyID of the key we want to add the userID to</param> /// <param name="isRevocable">is a revocable keyID</param> public void AddUserID(string userID, string email, string infos, string strPassphrase, ulong KeyID, bool isRevocable) { TransportablePublicKey tpkKey = this.PublicRing.Find(KeyID,false); TransportableSecretKey tskKey = this.SecretRing.Find(KeyID); if (tpkKey != null && tskKey != null) { CertifiedUserID cuiUID = new CertifiedUserID(); UserIDPacket uipUID = new UserIDPacket(); uipUID.UserID = userID.Trim() + " <" + email.Trim() + ">"; cuiUID.UserID = uipUID; SecretKeyPacket skpSignatureKey = tskKey.FindKey(AsymActions.Sign); SignaturePacket spSelfSig = new SignaturePacket(); if (infos != null) { SignatureSubPacket sspNotation = new SignatureSubPacket(); sspNotation.Type = SignatureSubPacketTypes.NotationData; sspNotation.NotationName = "PersonalData"; sspNotation.NotationValue = infos; spSelfSig.AddSubPacket(sspNotation,false); } if (!isRevocable) { SignatureSubPacket sspRevocable = new SignatureSubPacket(); sspRevocable.Type = SignatureSubPacketTypes.Revocable; sspRevocable.Revocable = isRevocable; spSelfSig.AddSubPacket(sspRevocable, true); } SignatureSubPacket sspPrimaryUID = new SignatureSubPacket(); sspPrimaryUID.Type = SignatureSubPacketTypes.PrimaryUserID; sspPrimaryUID.Revocable = false; spSelfSig.AddSubPacket(sspPrimaryUID, true); 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); return; } throw new Exception("Keys not found"); }
/// <summary> /// Signs a key /// </summary> /// <param name="tspKey">key to be signed</param> /// <param name="cuidTobeSigned">user id to be signed</param> /// <param name="skpKeySigner">signer private key</param> /// <param name="strPassphrase">signer passphrase</param> /// <param name="exportable">exportable signature</param> /// <param name="expirationTime">expiration time (new DateTime(0) == never)</param> /// <param name="isRevocable"></param> public void SignKey(TransportablePublicKey tspKey, CertifiedUserID cuidTobeSigned, TransportableSecretKey skpKeySigner, string strPassphrase, bool exportable, DateTime expirationTime, bool isRevocable) { SignaturePacket spSig = new SignaturePacket(); spSig.Version = SignaturePacketVersionNumbers.v4; spSig.HashAlgorithm = HashAlgorithms.SHA1; spSig.KeyID = skpKeySigner.PrimaryKey.PublicKey.KeyID; spSig.TimeCreated = DateTime.Now; SignatureSubPacket sspExportableSignature = new SignatureSubPacket(); sspExportableSignature.Type = SignatureSubPacketTypes.ExportableSignature; sspExportableSignature.ExportableSignature = exportable; spSig.AddSubPacket(sspExportableSignature, false); if (!isRevocable) { SignatureSubPacket sspRevocable = new SignatureSubPacket(); sspRevocable.Type = SignatureSubPacketTypes.Revocable; sspRevocable.Revocable = isRevocable; spSig.AddSubPacket(sspRevocable, true); } if (expirationTime.Ticks != 0) { SignatureSubPacket sspExpiration = new SignatureSubPacket(); sspExpiration.Type = SignatureSubPacketTypes.KeyExpirationTime; sspExpiration.KeyExpirationTime = new DateTime(expirationTime.Ticks + (new DateTime(1970,1,2)).Ticks - tspKey.PrimaryKey.TimeCreated.Ticks); spSig.AddSubPacket(sspExpiration, true); } cuidTobeSigned.Sign(spSig, skpKeySigner.PrimaryKey, strPassphrase, tspKey.PrimaryKey); }
/// <summary> /// Sets the trust level and amount for a specified userID in a key /// </summary> /// <param name="userIdKeyId">KeyID of the key containing the userID which this set the trust of</param> /// <param name="userID">UserID whose trust has to be set</param> /// <param name="KeyID">Signer (Truster) keyID</param> /// <param name="strPassphrase">passphrase of the signer</param> /// <param name="trustLevel">trust level</param> /// <param name="trustAmount">trust amount</param> public void setUserIDTrust(ulong userIdKeyId, CertifiedUserID userID, ulong KeyID, string strPassphrase, int trustLevel, int trustAmount) { TransportablePublicKey tpkKey = this.PublicRing.Find(userIdKeyId,false); TransportableSecretKey tskKey = this.SecretRing.Find(KeyID); bool updated = false; if (tpkKey!=null && tskKey!=null) { ArrayList cert = new ArrayList(userID.Certificates); for (int k = 0; k < cert.Count; k++) { updated = false; SignaturePacket sp = (SignaturePacket)cert[k]; if ((sp.SignatureType == SignatureTypes.UserIDSignature || sp.SignatureType == SignatureTypes.UserIDSignature_CasualVerification || sp.SignatureType == SignatureTypes.UserIDSignature_NoVerification || sp.SignatureType == SignatureTypes.UserIDSignature_PositivVerification) && sp.KeyID == KeyID) { foreach (SignatureSubPacket ssp in sp.HashedSubPackets) { if(ssp.Type == SignatureSubPacketTypes.TrustSignature) { ssp.TrustLevel = (byte)(trustLevel & 0xFF); ssp.TrustAmount = (byte)(trustAmount & 0xFF); updated = true; } } if (!updated) { foreach (SignatureSubPacket ssp in sp.UnhashedSubPackets) { if (ssp.Type == SignatureSubPacketTypes.TrustSignature) { ssp.TrustLevel = (byte)(trustLevel & 0xFF); ssp.TrustAmount = (byte)(trustAmount & 0xFF); updated = true; } } } if(updated) { userID.Certificates.Remove(sp); userID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey); updated = true; } else { SignatureSubPacket sspTrust = new SignatureSubPacket(); sspTrust.Type = SignatureSubPacketTypes.TrustSignature; sspTrust.TrustAmount = (byte)(trustAmount & 0xFF); sspTrust.TrustLevel = (byte)(trustLevel & 0xFF); sp.AddSubPacket(sspTrust, false); userID.Certificates.Remove(sp); userID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey); updated = true; } } } } if (!updated) throw new Exception("User id not certified by this Key. You cannot set Trust."); }
/// <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 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); }
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> /// 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); }