/// <summary> /// Loads a keyring file /// </summary> /// <param name="strPath">The keyring file location</param> public void Load(string strPath) { this.strLoadingPath = strPath; System.IO.StreamReader srInput = new StreamReader(strPath); string strKeys = srInput.ReadToEnd(); srInput.Close(); this.PublicKeys = new ArrayList(); ArmorTypes atType = new ArmorTypes(); string strKey = Armor.RemoveArmor(strKeys, ref atType, ref strKeys); while (strKey.Length > 0) { TransportablePublicKey[] tpkKeys = TransportablePublicKey.SplitKeys(strKey); foreach (TransportablePublicKey tpkKey in tpkKeys) { this.Add(tpkKey); } strKey = Armor.RemoveArmor(strKeys, ref atType, ref strKeys); } this.bIsUpdated = false; }
/// <summary> /// Verifies a key user id certificetion revocation status /// </summary> /// <param name="keyID">the key to verify</param> /// <param name="userID">the user id to verify</param> /// <param name="certifierKeyID">the key that issued the certification</param> /// <returns>the revocation status of the user id</returns> public bool isRevoked(ulong keyID, string userID, ulong certifierKeyID) { TransportablePublicKey tpkKey = this.Find(keyID, true); if (tpkKey == null) { return(false); } bool found = false; CertifiedUserID toBeVerified = null; foreach (CertifiedUserID cui in tpkKey.Certifications) { if (cui.UserID.UserID == userID) { found = true; toBeVerified = cui; break; } } if (!found) { throw new Exception("UserId not found among Key certificates"); } toBeVerified.Validate(tpkKey.PrimaryKey, this); foreach (SignaturePacket sign in toBeVerified.Certificates) { if (sign.SignatureType == SignatureTypes.CertificationRevocationSignature && sign.KeyID == certifierKeyID && sign.SignatureStatus == SignatureStatusTypes.Valid && sign.isRevocable()) { return(true); } } return(false); }
/// <summary> /// Finds a local or remote key given its fingerprint /// </summary> /// <param name="fingerprint">fingerprint</param> /// <returns>a public key</returns> public TransportablePublicKey FindPublicKey(string fingerprint) { IEnumerator ieKeys = this.PublicKeys.GetEnumerator(); while (ieKeys.MoveNext()) { if (!(ieKeys.Current is TransportablePublicKey)) { continue; } TransportablePublicKey key = ((TransportablePublicKey)ieKeys.Current); if (key.PrimaryKey.Fingerprint.ToString() == fingerprint) { return(key); } } ldapKeyFinder.KeyFinder kf = new ldapKeyFinder.KeyFinder(); string remoteKey = kf.MyLDAPSearch(SharpPrivacyLibrary.LdapKeyServer, SharpPrivacyLibrary.LdapPort, "pgpkey", "(pgpsignerid=" + fingerprint + ")"); if (remoteKey != null) { ArmorTypes atType = new ArmorTypes(); string strKey = Armor.RemoveArmor(remoteKey, ref atType, ref remoteKey); if (strKey.Length > 0) { TransportablePublicKey tpkKey = new TransportablePublicKey(strKey); AddPublicKey(tpkKey); return(tpkKey); } } return(null); }
public void EncryptFile(string strPath, string strOutput, ulong[] lTargetKeyIDs) { TransportablePublicKey[] tpkSelectedKeys = new TransportablePublicKey[lTargetKeyIDs.Length]; for (int i = 0; i < lTargetKeyIDs.Length; i++) { tpkSelectedKeys[i] = pkrKeyRing.Find(lTargetKeyIDs[i], true); } System.IO.FileStream fsFile = new FileStream(strPath, FileMode.Open); BinaryReader brReader = new BinaryReader(fsFile); byte[] bFileContent = brReader.ReadBytes((int)fsFile.Length); brReader.Close(); fsFile.Close(); LiteralMessage lmMessage = new LiteralMessage(DataFormatTypes.Binary); lmMessage.Binary = bFileContent; lmMessage.TimeCreated = DateTime.Now; int iLastBackslash = strPath.LastIndexOf("\\"); lmMessage.Filename = strPath.Substring(iLastBackslash + 1, strPath.Length - iLastBackslash - 1); byte[] bReturn = EncryptMessage(lmMessage, lTargetKeyIDs); FileStream fsOut = new FileStream(strOutput, FileMode.CreateNew); BinaryWriter bwWrite = new BinaryWriter(fsOut); bwWrite.Write(bReturn); bwWrite.Close(); fsOut.Close(); }
public string GetPublicKey(ulong lKeyID) { TransportablePublicKey tpkKey = pkrKeyRing.Find(lKeyID, true); byte[] bKey = tpkKey.Generate(); return(Armor.WrapPublicKey(bKey)); }
private ESKSequence CreateESKSequence(TransportablePublicKey[] tpkKeys, AsymActions aaAction, SymAlgorithms saAlgo, byte[] bSymKey) { ESKSequence esksReturn = new ESKSequence(); for (int i = 0; i < tpkKeys.Length; i++) { TransportablePublicKey tpkKey = tpkKeys[i]; PublicKeyPacket pkpKey = tpkKey.FindKey(aaAction); if (pkpKey == null) { throw new Exception("Could not find subkey fitting to the selected action. Concerned Key: " + tpkKey.PrimaryUserID); } AsymSessionKeyPacket skpKey = new AsymSessionKeyPacket(); skpKey.KeyID = pkpKey.KeyID; skpKey.PublicAlgorithm = pkpKey.Algorithm; skpKey.SymmetricAlgorithm = saAlgo; skpKey.SessionKey = bSymKey; skpKey.EncryptSessionKey(pkpKey); esksReturn.AddAsymSessionKey(skpKey); } return(esksReturn); }
private static ESKSequence CreateESKSequence(ArrayList alKeys, AsymActions aaAction, SymAlgorithms saAlgo, byte[] bSymKey) { IEnumerator ieKeys = alKeys.GetEnumerator(); ESKSequence esksReturn = new ESKSequence(); while (ieKeys.MoveNext()) { TransportablePublicKey tpkKey = (TransportablePublicKey)ieKeys.Current; PublicKeyPacket pkpKey = tpkKey.FindKey(aaAction); if (pkpKey == null) { throw new Exception("Could not find subkey fitting to the selected action. Concerned Key: " + tpkKey.PrimaryUserID); } AsymSessionKeyPacket skpKey = new AsymSessionKeyPacket(); skpKey.KeyID = pkpKey.KeyID; skpKey.PublicAlgorithm = pkpKey.Algorithm; skpKey.SymmetricAlgorithm = saAlgo; skpKey.SessionKey = bSymKey; skpKey.EncryptSessionKey(pkpKey); esksReturn.AddAsymSessionKey(skpKey); } return(esksReturn); }
/// <summary> /// Add a key to the keyring /// </summary> /// <param name="tspk">the key to be added</param> public void AddPublicKey(TransportablePublicKey tspk) { if (tspk != null) { if (this.Find(tspk.PrimaryKey.KeyID, false) == null) { this.Add(tspk); } } }
/// <summary> /// Saves a key to a location /// </summary> /// <param name="strPath">file path</param> /// <param name="KeyID">key to save</param> public void Save(string strPath, ulong KeyID) { System.IO.StreamWriter swOutput = new StreamWriter(strPath); try { TransportablePublicKey tpkKey = this.Find(KeyID, false); byte[] bKey = tpkKey.Generate(); string strKey = Armor.WrapPublicKey(bKey); swOutput.Write(strKey); } catch (Exception e) { throw new Exception("Error while trying to save a public key: " + e.Message); } swOutput.Close(); this.bIsUpdated = false; }
public void LoadKey(string Key) { this.PublicKeys = new ArrayList(); ArmorTypes atType = new ArmorTypes(); //string strKey = Armor.RemoveArmor(Key, ref atType, ref Key); //while (strKey.Length > 0) //{ TransportablePublicKey tpkKey = new TransportablePublicKey(Key); this.PublicKeys.Add(tpkKey); //strKey = Armor.RemoveArmor(Key, ref atType, ref Key); //} this.bIsUpdated = false; }
private byte[] EncryptMessage(Message mToBeEncrypted, ulong[] lTargetKeyIDs) { CompressedMessage cmMessage = new CompressedMessage(); cmMessage.Compress(mToBeEncrypted); TransportablePublicKey[] tpkSelectedKeys = new TransportablePublicKey[lTargetKeyIDs.Length]; for (int i = 0; i < lTargetKeyIDs.Length; i++) { tpkSelectedKeys[i] = pkrKeyRing.Find(lTargetKeyIDs[i], true); } SymAlgorithms saAlgo = GetSymAlgorithmPreferences(tpkSelectedKeys); SymmetricallyEncryptedDataPacket sedpEncrypted = new SymmetricallyEncryptedDataPacket(); SymmetricAlgorithm saEncrypt = CipherHelper.CreateSymAlgorithm(saAlgo); saEncrypt.Mode = CipherMode.OpenPGP_CFB; saEncrypt.GenerateKey(); byte[] bKey = saEncrypt.Key; ESKSequence esksKeys = new ESKSequence(); esksKeys = CreateESKSequence(tpkSelectedKeys, AsymActions.Encrypt, saAlgo, bKey); ICryptoTransform ictEncryptor = saEncrypt.CreateEncryptor(); byte[] bMessage = cmMessage.GetEncoded(); byte[] bOutput = new byte[bMessage.Length]; ictEncryptor.TransformBlock(bMessage, 0, bMessage.Length, ref bOutput, 0); bKey.Initialize(); int iOutLength = (saEncrypt.BlockSize >> 3) + 2 + bMessage.Length; sedpEncrypted.Body = new byte[iOutLength]; Array.Copy(bOutput, 0, sedpEncrypted.Body, 0, iOutLength); byte[] bESK = esksKeys.GetEncoded(); byte[] bEncrypted = sedpEncrypted.Generate(); byte[] bReturn = new byte[bESK.Length + bEncrypted.Length]; bESK.CopyTo(bReturn, 0); bEncrypted.CopyTo(bReturn, bESK.Length); return(bReturn); }
/// <summary> /// Find a list of keys which contains the result of the query done using userID as argument. /// </summary> /// <param name="userID">User ID contained in the keys to list</param> /// <returns>a list of keys</returns> public ArrayList FindPublicKeysByID(string userID) { ArrayList pkList = new ArrayList(); IEnumerator ieKeys = this.PublicKeys.GetEnumerator(); while (ieKeys.MoveNext()) { if (!(ieKeys.Current is TransportablePublicKey)) { continue; } TransportablePublicKey key = ((TransportablePublicKey)ieKeys.Current); if (key.PrimaryUserID.IndexOf(userID) >= 0) { pkList.Add(key); } } return(pkList); }
public string GetPublicKeysProperties() { string strReturn = "<PublicKeyRing>"; IEnumerator ieKeys = pkrKeyRing.PublicKeys.GetEnumerator(); while (ieKeys.MoveNext()) { if (!(ieKeys.Current is TransportablePublicKey)) { continue; } TransportablePublicKey tpkKey = (TransportablePublicKey)ieKeys.Current; strReturn += "\n" + GetPublicKeyProperties(tpkKey.PrimaryKey.KeyID); } return(strReturn + "</PublicKeyRing>"); }
/// <summary> /// Finds a Key given a keyid. Performs a remote LDAP search if specified. /// </summary> /// <param name="lKeyID">Key to find</param> /// <param name="remote">LDAP search</param> /// <returns>a key</returns> public TransportablePublicKey Find(ulong lKeyID, bool remote) { IEnumerator ieKeys = alPublicKeys.GetEnumerator(); while (ieKeys.MoveNext()) { TransportablePublicKey tpkKey = (TransportablePublicKey)ieKeys.Current; if (tpkKey.PrimaryKey.KeyID == lKeyID) { return(tpkKey); } IEnumerator ieSubkeys = tpkKey.SubKeys.GetEnumerator(); while (ieSubkeys.MoveNext()) { CertifiedPublicSubkey cpsSubkey = (CertifiedPublicSubkey)ieSubkeys.Current; if (cpsSubkey.Subkey.KeyID == lKeyID) { return(tpkKey); } } } if (remote) { ldapKeyFinder.KeyFinder kf = new ldapKeyFinder.KeyFinder(); string key = kf.MyLDAPSearch(SharpPrivacyLibrary.LdapKeyServer, SharpPrivacyLibrary.LdapPort, "pgpkey", "(pgpsignerid=" + lKeyID.ToString("X") + ")"); if (key != null) { ArmorTypes atType = new ArmorTypes(); string strKey = Armor.RemoveArmor(key, ref atType, ref key); if (strKey.Length > 0) { TransportablePublicKey tpkKey = new TransportablePublicKey(strKey); AddPublicKey(tpkKey); return(tpkKey); } } } return(null); }
public void Save(string strPath) { System.IO.StreamWriter swOutput = new StreamWriter(strPath); IEnumerator ieKeys = this.PublicKeys.GetEnumerator(); while (ieKeys.MoveNext()) { if (ieKeys.Current is TransportablePublicKey) { try { TransportablePublicKey tpkKey = (TransportablePublicKey)ieKeys.Current; byte[] bKey = tpkKey.Generate(); string strKey = Armor.WrapPublicKey(bKey); swOutput.Write(strKey); } catch (Exception e) { MessageBox.Show("Error while trying to save a public key: " + e.Message, "Error...", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } swOutput.Close(); this.bIsUpdated = false; }
public TransportablePublicKey Find(ulong lKeyID) { IEnumerator ieKeys = alPublicKeys.GetEnumerator(); while (ieKeys.MoveNext()) { TransportablePublicKey tpkKey = (TransportablePublicKey)ieKeys.Current; if (tpkKey.PrimaryKey.KeyID == lKeyID) { return(tpkKey); } IEnumerator ieSubkeys = tpkKey.SubKeys.GetEnumerator(); while (ieSubkeys.MoveNext()) { CertifiedPublicSubkey cpsSubkey = (CertifiedPublicSubkey)ieSubkeys.Current; if (cpsSubkey.Subkey.KeyID == lKeyID) { return(tpkKey); } } } return(null); }
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 Delete(TransportablePublicKey tpkKey) { bIsUpdated = true; alPublicKeys.Remove(tpkKey); }
/// <summary> /// Private method to add a key doing checks /// </summary> /// <param name="tpkKey">the key to be saved</param> private void Add(TransportablePublicKey tpkKey) { bIsUpdated = true; TransportablePublicKey local = null; if ((local = this.Find(tpkKey.PrimaryKey.KeyID, false)) == null) { alPublicKeys.Add(tpkKey); } else { TransportablePublicKey joinKey = new TransportablePublicKey(); joinKey.PrimaryKey = local.PrimaryKey; //Revocations ArrayList toBeAdded = new ArrayList(); toBeAdded.AddRange(local.RevocationSignatures); toBeAdded.AddRange(tpkKey.RevocationSignatures); foreach (SignaturePacket localpacket in local.RevocationSignatures) { foreach (SignaturePacket packet in tpkKey.RevocationSignatures) { if (localpacket.Body == packet.Body && localpacket.Header == packet.Header) { toBeAdded.Remove(packet); continue; } } } joinKey.RevocationSignatures = toBeAdded; //Revokers toBeAdded = new ArrayList(); toBeAdded.AddRange(local.RevocationKeys); toBeAdded.AddRange(tpkKey.RevocationKeys); foreach (SignaturePacket localpacket in local.RevocationKeys) { foreach (SignaturePacket packet in tpkKey.RevocationKeys) { if (localpacket.Body == packet.Body && localpacket.Header == packet.Header) { toBeAdded.Remove(packet); continue; } } } joinKey.RevocationKeys = toBeAdded; //CERTIFICATES toBeAdded = new ArrayList(); toBeAdded.AddRange(local.Certifications); toBeAdded.AddRange(tpkKey.Certifications); foreach (CertifiedUserID localpacket in local.Certifications) { foreach (CertifiedUserID packet in tpkKey.Certifications) { if (localpacket.UserID == packet.UserID) { ArrayList certificatesToBeAdded = new ArrayList(); certificatesToBeAdded.AddRange(localpacket.Certificates); certificatesToBeAdded.AddRange(packet.Certificates); foreach (SignaturePacket signatureLocal in localpacket.Certificates) { foreach (SignaturePacket signature in localpacket.Certificates) { if (signatureLocal.Header == signature.Header && signatureLocal.Body == signature.Body) { certificatesToBeAdded.Remove(signature); continue; } } } localpacket.Certificates = certificatesToBeAdded; toBeAdded.Remove(packet); continue; } } } joinKey.Certifications = toBeAdded; //SUBKEYS toBeAdded = new ArrayList(); toBeAdded.AddRange(local.SubKeys); toBeAdded.AddRange(tpkKey.SubKeys); foreach (CertifiedPublicSubkey localpacket in local.SubKeys) { foreach (CertifiedPublicSubkey packet in tpkKey.SubKeys) { if (localpacket.Subkey.KeyID == packet.Subkey.KeyID) { toBeAdded.Remove(packet); if (localpacket.KeyBindingSignature == null) { localpacket.KeyBindingSignature = packet.KeyBindingSignature; } if (localpacket.RevocationSignature == null) { localpacket.RevocationSignature = packet.RevocationSignature; } continue; } } } joinKey.SubKeys = toBeAdded; alPublicKeys.Remove(local); alPublicKeys.Add(joinKey); } }
private SymAlgorithms GetSymAlgorithmPreferences(TransportablePublicKey[] tpkKeys) { bool bCAST5 = true; bool bAES256 = true; bool bAES192 = true; bool bAES128 = true; for (int i = 0; i < tpkKeys.Length; i++) { TransportablePublicKey tpkKey = tpkKeys[i]; ulong lKeyID = tpkKey.PrimaryKey.KeyID; IEnumerator ieCerts = tpkKey.Certifications.GetEnumerator(); while (ieCerts.MoveNext()) { if (!(ieCerts.Current is CertifiedUserID)) { continue; } CertifiedUserID cuiID = (CertifiedUserID)ieCerts.Current; IEnumerator ieSigs = cuiID.Certificates.GetEnumerator(); while (ieSigs.MoveNext()) { if (!(ieSigs.Current is SignaturePacket)) { continue; } SignaturePacket spSig = (SignaturePacket)ieSigs.Current; if ((spSig.Version == SignaturePacketVersionNumbers.v4) && (spSig.KeyID == lKeyID)) { try { bool bTmpCAST5 = false; bool bTmpAES256 = false; bool bTmpAES192 = false; bool bTmpAES128 = false; SymAlgorithms[] saThisKey = spSig.FindPreferedSymAlgorithms(); for (int j = 0; j < saThisKey.Length; j++) { if (saThisKey[j] == SymAlgorithms.AES128) { bTmpAES128 = true; } else if (saThisKey[j] == SymAlgorithms.AES192) { bTmpAES192 = true; } else if (saThisKey[j] == SymAlgorithms.AES256) { bTmpAES256 = true; } else if (saThisKey[j] == SymAlgorithms.CAST5) { bTmpCAST5 = true; } } if (!bTmpCAST5) { bCAST5 = false; } if (!bTmpAES256) { bAES256 = false; } if (!bTmpAES192) { bAES192 = false; } if (!bTmpAES128) { bAES128 = false; } } catch (InvalidOperationException) {} } } } } if (bAES256) { return(SymAlgorithms.AES256); } if (bAES192) { return(SymAlgorithms.AES192); } if (bAES128) { return(SymAlgorithms.AES128); } if (bCAST5) { return(SymAlgorithms.CAST5); } return(SymAlgorithms.Triple_DES); }
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") { } }
public void SignKey(ulong lSignedKeyID, ulong lSigningKeyID, string strUserID, int nIntroducerDepth, bool bIsExportable, int nType, string strPassphrase) { TransportableSecretKey tskKey = skrKeyRing.Find(lSigningKeyID); SecretKeyPacket skpSignatureKey = tskKey.FindKey(AsymActions.Sign); TransportablePublicKey tpkKey = pkrKeyRing.Find(lSignedKeyID, false); SignaturePacket spCertificate = new SignaturePacket(); spCertificate.SignatureType = (SignatureTypes)nType; spCertificate.Version = SignaturePacketVersionNumbers.v4; spCertificate.HashAlgorithm = HashAlgorithms.SHA1; spCertificate.KeyID = skpSignatureKey.PublicKey.KeyID; spCertificate.TimeCreated = DateTime.Now; CertifiedUserID cuiID = null; IEnumerator ieUserIDs = tpkKey.Certifications.GetEnumerator(); while (ieUserIDs.MoveNext()) { if (!(ieUserIDs.Current is CertifiedUserID)) { continue; } CertifiedUserID cuiThisID = (CertifiedUserID)ieUserIDs.Current; if (cuiThisID.ToString() == strUserID) { cuiID = cuiThisID; } } if (cuiID == null) { throw new Exception("UserID could not be found!"); } if (bIsExportable == false) { SignatureSubPacket sspNotExportable = new SignatureSubPacket(); sspNotExportable.Type = SignatureSubPacketTypes.ExportableSignature; sspNotExportable.ExportableSignature = false; spCertificate.AddSubPacket(sspNotExportable, true); } if (nIntroducerDepth > 0) { SignatureSubPacket sspTrust = new SignatureSubPacket(); sspTrust.Type = SignatureSubPacketTypes.TrustSignature; sspTrust.TrustLevel = (byte)nIntroducerDepth; sspTrust.TrustAmount = 120; spCertificate.AddSubPacket(sspTrust, true); } cuiID.Sign(spCertificate, skpSignatureKey, strPassphrase, tpkKey.PrimaryKey); tpkKey.Certifications.Remove(cuiID); tpkKey.Certifications.Add(cuiID); pkrKeyRing.Delete(lSignedKeyID); pkrKeyRing.AddPublicKey(tpkKey); pkrKeyRing.Save(); }
public string GetPublicKeyProperties(ulong lKeyID) { TransportablePublicKey tpkKey = pkrKeyRing.Find(lKeyID, false); XmlDocument xmlDoc = new XmlDocument(); XmlElement xmlPublicKey = xmlDoc.CreateElement("PublicKey"); xmlPublicKey.SetAttribute("keyid", "0x" + tpkKey.PrimaryKey.KeyID.ToString("x")); xmlPublicKey.SetAttribute("fingerprint", tpkKey.PrimaryKey.Fingerprint.ToString(16)); xmlPublicKey.SetAttribute("created", tpkKey.PrimaryKey.TimeCreated.Ticks.ToString()); try { xmlPublicKey.SetAttribute("expiration", tpkKey.KeyExpirationTime.Ticks.ToString()); } catch (System.Exception) { xmlPublicKey.SetAttribute("expiration", "never"); } xmlPublicKey.SetAttribute("size", tpkKey.PrimaryKey.KeyMaterial[0].bitCount().ToString()); xmlPublicKey.SetAttribute("algorithm", tpkKey.PrimaryKey.Algorithm.ToString()); XmlElement xmlUserIDs = xmlDoc.CreateElement("UserIDs"); XmlElement xmlUserID; IEnumerator ieUserIDs = tpkKey.Certifications.GetEnumerator(); while (ieUserIDs.MoveNext()) { if (!(ieUserIDs.Current is CertifiedUserID)) { continue; } CertifiedUserID cuiUID = (CertifiedUserID)ieUserIDs.Current; cuiUID.Validate(tpkKey.PrimaryKey, pkrKeyRing); xmlUserID = xmlDoc.CreateElement("UserID"); xmlUserID.SetAttribute("name", cuiUID.UserID.UserID); string strPrimary = "false"; if (tpkKey.PrimaryUserID == cuiUID.UserID.UserID) { strPrimary = "true"; } xmlUserID.SetAttribute("primary", strPrimary); DateTime dtTimeCreated = DateTime.Now; XmlElement xmlSignature; IEnumerator ieSignatures = cuiUID.Certificates.GetEnumerator(); while (ieSignatures.MoveNext()) { if (!(ieSignatures.Current is SignaturePacket)) { continue; } SignaturePacket spSignature = (SignaturePacket)ieSignatures.Current; xmlSignature = xmlDoc.CreateElement("Signature"); xmlSignature.SetAttribute("keyid", "0x" + spSignature.KeyID.ToString("x")); xmlSignature.SetAttribute("created", spSignature.TimeCreated.Ticks.ToString()); string strExpiration = ""; try { strExpiration = spSignature.FindExpirationTime().Ticks.ToString(); } catch (InvalidOperationException) { strExpiration = "never"; } xmlSignature.SetAttribute("expiration", strExpiration); xmlSignature.SetAttribute("signaturestatus", spSignature.SignatureStatus.ToString()); string strCreator = ""; try { TransportablePublicKey tpkSignatureKey = pkrKeyRing.Find(spSignature.KeyID, false); strCreator = tpkSignatureKey.PrimaryUserID; } catch (Exception) { strCreator = "0x" + spSignature.KeyID.ToString("x"); } xmlSignature.SetAttribute("creator", strCreator); xmlSignature.SetAttribute("algorithm", spSignature.SignatureAlgorithm.ToString()); if (spSignature.KeyID == tpkKey.PrimaryKey.KeyID) { dtTimeCreated = spSignature.TimeCreated; } xmlUserID.AppendChild(xmlSignature); } xmlUserID.SetAttribute("created", dtTimeCreated.Ticks.ToString()); xmlUserIDs.AppendChild(xmlUserID); } xmlPublicKey.AppendChild(xmlUserIDs); XmlElement xmlSubkeys = xmlDoc.CreateElement("Subkeys"); XmlElement xmlSubkey; IEnumerator ieSubkeys = tpkKey.SubKeys.GetEnumerator(); while (ieSubkeys.MoveNext()) { if (!(ieSubkeys.Current is CertifiedPublicSubkey)) { continue; } CertifiedPublicSubkey cpsSubkey = (CertifiedPublicSubkey)ieSubkeys.Current; xmlSubkey = xmlDoc.CreateElement("Subkey"); xmlSubkey.SetAttribute("keyid", "0x" + cpsSubkey.Subkey.KeyID.ToString("x")); xmlSubkey.SetAttribute("fingerprint", cpsSubkey.Subkey.Fingerprint.ToString(16)); xmlSubkey.SetAttribute("created", cpsSubkey.Subkey.TimeCreated.Ticks.ToString()); string strExpiration = ""; try { strExpiration = cpsSubkey.KeyBindingSignature.FindExpirationTime().Ticks.ToString(); } catch (InvalidOperationException) { strExpiration = "never"; } xmlSubkey.SetAttribute("expiration", strExpiration); xmlSubkey.SetAttribute("size", cpsSubkey.Subkey.KeyMaterial[0].bitCount().ToString()); xmlSubkey.SetAttribute("algorithm", cpsSubkey.Subkey.Algorithm.ToString()); xmlSubkeys.AppendChild(xmlSubkey); } xmlPublicKey.AppendChild(xmlSubkeys); xmlDoc.AppendChild(xmlPublicKey); return(xmlDoc.OuterXml); }
public void AddKey(string strKey) { bool bNotImported = false; bool bError = false; string strRest = ""; ArmorTypes atType = new ArmorTypes(); do { strKey = Armor.RemoveArmor(strKey, ref atType, ref strRest); if (atType == ArmorTypes.PrivateKeyBlock) { try { TransportableSecretKey[] tskKeys = TransportableSecretKey.SplitKeys(strKey); for (int i = 0; i < tskKeys.Length; i++) { TransportableSecretKey tskKey = tskKeys[i]; TransportableSecretKey tskTestKey = skrKeyRing.Find(tskKey.PrimaryKey.PublicKey.KeyID); if (tskTestKey != null) { bNotImported = true; continue; } skrKeyRing.AddSecretKey(tskKey); } } catch (Exception) { bError = true; } } else if (atType == ArmorTypes.PublicKeyBlock) { try { TransportablePublicKey[] tpkKeys = TransportablePublicKey.SplitKeys(strKey); for (int i = 0; i < tpkKeys.Length; i++) { TransportablePublicKey tpkKey = tpkKeys[i]; TransportablePublicKey tpkTestKey = pkrKeyRing.Find(tpkKey.PrimaryKey.KeyID, true); if (tpkTestKey != null) { bNotImported = true; continue; } pkrKeyRing.AddPublicKey(tpkKey); } } catch (Exception) { bError = true; } } strKey = strRest; } while (strKey.Length > 0); pkrKeyRing.Save(); skrKeyRing.Save(); if (bError) { throw new Exception("Some keys could not be imported, because there were errors!"); } if (bNotImported) { throw new Exception("Some keys could not be imported, because they were already in your keyring!"); } }
/// <summary> /// Verifies key signatures /// </summary> /// <param name="tpkKey">the key to be verified</param> /// <returns> /// list of invalid signatures or objects containing invalid signatures: /// SignaturePacket /// CertifiedUserID /// CertifiedPublicSubkey /// </returns> private ArrayList verifySignatures(TransportablePublicKey tpkKey) { ArrayList signaturesNotOK = new ArrayList(); //Verify Revocation Signatures foreach (SignaturePacket revocation in tpkKey.RevocationSignatures) { if (revocation.KeyID == tpkKey.PrimaryKey.KeyID) { PublicKeyPacket pkpKey = tpkKey.FindKey(revocation.KeyID); byte[] key = new byte[tpkKey.PrimaryKey.Length]; tpkKey.PrimaryKey.Header.CopyTo(key, 0); tpkKey.PrimaryKey.Body.CopyTo(key, tpkKey.PrimaryKey.Header.Length); if (pkpKey == null) { revocation.SignatureStatus = SignatureStatusTypes.Signing_Key_Not_Available; signaturesNotOK.Add(revocation); } else { revocation.Verify(key, pkpKey); if (revocation.SignatureStatus == SignatureStatusTypes.Invalid || revocation.SignatureStatus == SignatureStatusTypes.Not_Verified || revocation.SignatureStatus == SignatureStatusTypes.Signing_Key_Not_Available) { signaturesNotOK.Add(revocation); } } } else { TransportablePublicKey revtpkKey = this.Find(revocation.KeyID, true); if (revtpkKey != null) { foreach (SignaturePacket spPacket in tpkKey.RevocationKeys) { foreach (BigInteger revoker in spPacket.FindRevokerKeys()) { if (revoker.ToString() == revtpkKey.PrimaryKey.Fingerprint.ToString()) { PublicKeyPacket pkpKey = revtpkKey.PrimaryKey; byte[] key = new byte[tpkKey.PrimaryKey.Length]; tpkKey.PrimaryKey.Header.CopyTo(key, 0); tpkKey.PrimaryKey.Body.CopyTo(key, tpkKey.PrimaryKey.Header.Length); revocation.Verify(key, pkpKey); if (revocation.SignatureStatus == SignatureStatusTypes.Invalid || revocation.SignatureStatus == SignatureStatusTypes.Not_Verified || revocation.SignatureStatus == SignatureStatusTypes.Signing_Key_Not_Available) { signaturesNotOK.Add(revocation); } } } } } else { revocation.SignatureStatus = SignatureStatusTypes.Signing_Key_Not_Available; signaturesNotOK.Add(revocation); } } } //Verify UserID foreach (CertifiedUserID userId in tpkKey.Certifications) { userId.Validate(tpkKey.PrimaryKey, this); if (userId.CertificationValidityStatus == CertifiedUserID.ValidityStatus.Invalid || userId.CertificationValidityStatus == CertifiedUserID.ValidityStatus.NotYetValidated || userId.CertificationValidityStatus == CertifiedUserID.ValidityStatus.ValidationKeyUnavailable) { foreach (SignaturePacket sp in userId.Certificates) { if (sp.SignatureStatus != SignatureStatusTypes.Valid) { signaturesNotOK.Add(sp); } } } } foreach (CertifiedPublicSubkey cps in tpkKey.SubKeys) { if (cps.KeyBindingSignature == null) { signaturesNotOK.Add(cps); } else { cps.VerifyKeyBindingSignature(tpkKey.PrimaryKey); if (cps.KeyBindingSignature.SignatureStatus == SignatureStatusTypes.Invalid || cps.KeyBindingSignature.SignatureStatus == SignatureStatusTypes.Not_Verified || cps.KeyBindingSignature.SignatureStatus == SignatureStatusTypes.Signing_Key_Not_Available) { signaturesNotOK.Add(cps.KeyBindingSignature); } } //Verify Subkey Revocation Signature SignaturePacket revocation = cps.RevocationSignature; if (revocation != null) { if (revocation.KeyID == tpkKey.PrimaryKey.KeyID) { byte[] subkey = new byte[cps.Subkey.Length]; cps.Subkey.Header.CopyTo(subkey, 0); cps.Subkey.Body.CopyTo(subkey, cps.Subkey.Header.Length); subkey[0] = 0x99; byte[] mainkey = new byte[tpkKey.PrimaryKey.Length]; tpkKey.PrimaryKey.Header.CopyTo(mainkey, 0); tpkKey.PrimaryKey.Body.CopyTo(mainkey, tpkKey.PrimaryKey.Header.Length); byte[] key = new byte[subkey.Length + mainkey.Length]; mainkey.CopyTo(key, 0); subkey.CopyTo(key, mainkey.Length); revocation.Verify(key, tpkKey.PrimaryKey); if (revocation.SignatureStatus == SignatureStatusTypes.Invalid || revocation.SignatureStatus == SignatureStatusTypes.Not_Verified || revocation.SignatureStatus == SignatureStatusTypes.Signing_Key_Not_Available) { signaturesNotOK.Add(revocation); } } else { TransportablePublicKey revtpkKey = this.Find(revocation.KeyID, true); if (revtpkKey != null) { foreach (SignaturePacket spPacket in tpkKey.RevocationKeys) { foreach (BigInteger revoker in spPacket.FindRevokerKeys()) { if (revoker.ToString() == revtpkKey.PrimaryKey.Fingerprint.ToString()) { byte[] subkey = new byte[cps.Subkey.Length]; cps.Subkey.Header.CopyTo(subkey, 0); cps.Subkey.Body.CopyTo(subkey, cps.Subkey.Header.Length); subkey[0] = 0x99; byte[] mainkey = new byte[revtpkKey.PrimaryKey.Length]; tpkKey.PrimaryKey.Header.CopyTo(mainkey, 0); tpkKey.PrimaryKey.Body.CopyTo(mainkey, revtpkKey.PrimaryKey.Header.Length); byte[] key = new byte[subkey.Length + mainkey.Length]; mainkey.CopyTo(key, 0); subkey.CopyTo(key, mainkey.Length); revocation.Verify(key, revtpkKey.PrimaryKey); if (revocation.SignatureStatus == SignatureStatusTypes.Invalid || revocation.SignatureStatus == SignatureStatusTypes.Not_Verified || revocation.SignatureStatus == SignatureStatusTypes.Signing_Key_Not_Available) { signaturesNotOK.Add(revocation); } } } } } else { signaturesNotOK.Add(revocation); } } } } return(signaturesNotOK); }
/// <summary> /// Verifies the revocation status of a key /// </summary> /// <param name="KeyID">the key to verify</param> /// <returns>the revocation status of the key</returns> public bool isRevoked(ulong KeyID) { TransportablePublicKey tpkKey = this.Find(KeyID, true); if (tpkKey == null) { return(false); } if (tpkKey.PrimaryKey.KeyID == KeyID) { ArrayList nvsigatures = this.verifySignatures(tpkKey); foreach (SignaturePacket sp in tpkKey.PrimaryUserIDCert.Certificates) { if (sp.SignatureType == SignatureTypes.UserIDSignature || sp.SignatureType == SignatureTypes.UserIDSignature_CasualVerification || sp.SignatureType == SignatureTypes.UserIDSignature_NoVerification || sp.SignatureType == SignatureTypes.UserIDSignature_PositivVerification) { if (!sp.isRevocable()) { return(false); } } } if (tpkKey.RevocationSignatures == null || tpkKey.RevocationSignatures.Count == 0) { return(false); } else { foreach (SignaturePacket revocation in tpkKey.RevocationSignatures) { if (revocation.KeyID == tpkKey.PrimaryKey.KeyID) { PublicKeyPacket pkpKey = tpkKey.FindKey(revocation.KeyID); byte[] key = new byte[tpkKey.PrimaryKey.Length]; tpkKey.PrimaryKey.Header.CopyTo(key, 0); tpkKey.PrimaryKey.Body.CopyTo(key, tpkKey.PrimaryKey.Header.Length); revocation.Verify(key, pkpKey); if (revocation.SignatureStatus == SignatureStatusTypes.Valid) { return(true); } else if (revocation.SignatureStatus == SignatureStatusTypes.Invalid) { continue; } else { continue; } } else { TransportablePublicKey revtpkKey = this.Find(revocation.KeyID, true); if (revtpkKey == null) { return(false); } foreach (SignaturePacket spPacket in tpkKey.RevocationKeys) { foreach (BigInteger revoker in spPacket.FindRevokerKeys()) { if (revoker.ToString() == revtpkKey.PrimaryKey.Fingerprint.ToString()) { PublicKeyPacket pkpKey = revtpkKey.PrimaryKey; byte[] key = new byte[tpkKey.PrimaryKey.Length]; tpkKey.PrimaryKey.Header.CopyTo(key, 0); tpkKey.PrimaryKey.Body.CopyTo(key, tpkKey.PrimaryKey.Header.Length); revocation.Verify(key, pkpKey); if (revocation.SignatureStatus == SignatureStatusTypes.Valid) { return(true); } else if (revocation.SignatureStatus == SignatureStatusTypes.Invalid) { continue; } else { continue; } } } } } } } } else { ArrayList signaturesNotOK = this.verifySignatures(tpkKey); foreach (CertifiedPublicSubkey cps in tpkKey.SubKeys) { if (cps.Subkey.KeyID == KeyID) { if (cps.RevocationSignature != null && !signaturesNotOK.Contains(cps.RevocationSignature) && cps.KeyBindingSignature.isRevocable()) { ulong issuer = cps.RevocationSignature.KeyID; if (issuer == tpkKey.PrimaryKey.KeyID) { return(true); } else { foreach (SignaturePacket spPacket in tpkKey.RevocationKeys) { foreach (BigInteger revoker in spPacket.FindRevokerKeys()) { if (revoker == this.Find(issuer, true).PrimaryKey.Fingerprint) { return(true); } } } } } } } } return(false); }
public void Add(TransportablePublicKey tpkKey) { bIsUpdated = true; alPublicKeys.Add(tpkKey); }