/* * Only encrypts the given MimeEntity. */ private MultipartEncrypted EncryptEntity(Node entityNode, MimeEntity entity) { // Retrieving node that declares encryption settings for us. var encryptionNode = entityNode ["encrypt"]; // Retrieving MailboxAddresses to encrypt message for. var receivers = GetReceiversMailboxAddress(encryptionNode); // Creating our Gnu Privacy Guard context. // Notice, no password necessary when doing encryption, since we're only using public certificates. using (var ctx = new GnuPrivacyContext()) { // Encrypting content of email and returning to caller. var retVal = MultipartEncrypted.Encrypt( ctx, receivers, entity); // Setting preamble and epilogue AFTER encryption, to give opportunity to give hints to receiver. retVal.Preamble = entityNode.GetChildValue <string> ("preamble", _context, null); retVal.Epilogue = entityNode.GetChildValue <string> ("epilogue", _context, null); // Returning encrypted Multipart. return(retVal); } }
/* * Processes an encrypted Multipart. */ private void ProcessEncryptedMultipart(MultipartEncrypted encryptedMultipart, Node entityNode) { try { // Creating cryptographic context. using (var ctx = new GnuPrivacyContext()) { // Associating our KeyPasswordMapper collection with GnuPG CryptographyContext. ctx.Passwords = _passwords; // Decrypting entity, making sure we retrieve signatures at the same time, if there are any. DigitalSignatureCollection signatures; var decryptedMultipart = encryptedMultipart.Decrypt(ctx, out signatures); // Making sure caller gets notified of which private key was used for decrypting encrypted multipart. entityNode.Add("decryption-key", ctx.LastUsedUserId); // Adding signatures. ProcessSignatures(entityNode, signatures); // Parsing decrypted result. ProcessEntity(decryptedMultipart, entityNode); } } catch (Exception err) { // Couldn't decrypt Multipart, returning raw encrypted content. entityNode.Add("processing-message", err.Message); foreach (var idxEntity in encryptedMultipart) { ProcessEntity(idxEntity, entityNode); } } }
/* * Only signs the given MimeEntity */ private MultipartSigned SignEntity( Node entityNode, MimeEntity entity) { // Retrieving signature node to use for signing operation var signatureNode = entityNode ["signature"]; // Getting signature email as provided by caller var signatureAddress = GetSignatureMailboxAddress(signatureNode); // Figuring out signature Digest Algorithm to use for signature, defaulting to Sha256 var algo = signatureNode.GetChildValue("digest-algorithm", _context, DigestAlgorithm.Sha256); // Creating our Gnu Privacy Guard context using (var ctx = new GnuPrivacyContext()) { // Setting password to retrieve signing certificate from GnuPG context ctx.Password = signatureAddress.Item1; // Signing content of email and returning to caller return(MultipartSigned.Create( ctx, signatureAddress.Item2, algo, entity)); } }
/* * Processes a signed Multipart. */ private void ProcessSignedMultipart(MultipartSigned signedMultipart, Node entityNode) { // Creating cryptographic context. using (var ctx = new GnuPrivacyContext()) { // Adding signatures. ProcessSignatures(entityNode, signedMultipart.Verify(ctx)); // Looping through all entities in Multipart, processing recursively. foreach (var idxEntity in signedMultipart) { ProcessEntity(idxEntity, entityNode); } } }
/* * Iterates all public keys in all keyrings in GnuPrivacyContext, and invokes given delegate for every key matching filter condition. */ internal static void MatchingPublicKeys(ApplicationContext context, Node args, MatchingPublicKeysDelegate functor, bool write) { // House cleaning. using (new ArgsRemover(args, true)) { // Storing all filter given by caller in list, to avoid destroying enumeration iterator, due to modifying collection in caller's callback. var filters = XUtil.Iterate <string> (context, args).Where(ix => ix != null).ToList(); // Creating new GnuPG context. using (var ctx = new GnuPrivacyContext(write)) { // Iterating all secret keyrings. foreach (PgpPublicKeyRing idxRing in ctx.PublicKeyRingBundle.GetKeyRings()) { // Iterating all keys in currently iterated secret keyring. foreach (PgpPublicKey idxPublicKey in idxRing.GetPublicKeys()) { // Verifying that this is a normal plain public key. // Notice, we only return keys with at least one User ID. if (!idxPublicKey.GetUserIds().GetEnumerator().MoveNext()) { continue; // Probably just a signature for another key, or something. } // Checking if caller provided filters, and if not, yielding "everything". if (filters.Count == 0) { // No filters provided, matching everything. functor(idxPublicKey); } else { // Iterating all filters given by caller. foreach (var idxFilter in filters) { // Checking if current filter is a match. if (IsMatch(idxPublicKey, idxFilter)) { // Invoking callback supplied by caller, and breaking current filter enumeration, to avoid adding key twice. functor(idxPublicKey); break; } } } } } } } }
/* * Iterates all public keys in all keyrings in GnuPrivacyContext, and invokes given delegate for every key matching filter condition. */ internal static void MatchingPublicKeys(ApplicationContext context, Node args, MatchingPublicKeysDelegate functor) { // House cleaning. using (new ArgsRemover(args, true)) { // Storing all filter given by caller in list, to avoid destroying enumeration iterator, due to modifying collection in caller's callback. var filters = XUtil.Iterate <string> (context, args).Where(ix => ix != null).ToList(); // Creating new GnuPG context. using (var ctx = new GnuPrivacyContext()) { // Iterating all secret keyrings. foreach (PgpPublicKeyRing idxRing in ctx.PublicKeyRingBundle.GetKeyRings()) { // Iterating all keys in currently iterated secret keyring. foreach (PgpPublicKey idxPublicKey in idxRing.GetPublicKeys()) { // Checking if caller provided filters, and if not, yielding "everything". if (filters.Count == 0) { // No filters provided, matching everything. functor(idxPublicKey); } else { // Iterating all filters given by caller. foreach (var idxFilter in filters) { // Checking if current filter is a match. if (IsMatch(idxPublicKey, idxFilter)) { // Invoking callback supplied by caller, and breaking current filter enumeration, to avoid adding key twice. functor(idxPublicKey); break; } } } } } } } }
/* * Signs and encrypts the given MimeEntity. */ private MultipartEncrypted SignAndEncryptEntity( Node entityNode, MimeEntity entity) { // Retrieving [sign] and [encrypt] nodes. var signatureNode = entityNode ["sign"]; var encryptionNode = entityNode ["encrypt"]; // Getting signature email as provided by caller. var signatureAddress = GetSignatureMailboxAddress(signatureNode); // Retrieving MailboxAddresses to encrypt message for. var receivers = GetReceiversMailboxAddress(encryptionNode); // Figuring out signature Digest Algorithm to use for signature, defaulting to Sha256. var algo = signatureNode.GetChildValue("digest-algorithm", _context, DigestAlgorithm.Sha256); // Creating our Gnu Privacy Guard context. using (var ctx = new GnuPrivacyContext()) { // Setting password to retrieve signing certificate from GnuPG context. ctx.Password = signatureAddress.Item1; // Signing and Encrypting content of email. var retVal = MultipartEncrypted.SignAndEncrypt( ctx, signatureAddress.Item2, algo, receivers, entity); // Setting preamble and epilogue AFTER encryption, to give opportunity to give receiver hints. retVal.Preamble = entityNode.GetChildValue <string> ("preamble", _context, null); retVal.Epilogue = entityNode.GetChildValue <string> ("epilogue", _context, null); // Returning encrypted Multipart. return(retVal); } }