Comments (8)
Yes, I implemented it as a list because it needs to be flexible when parsing.
from mimekit.
I'm actually surprised anyone even looked at the RFC to comment on my design. In my experience looking at other MIME parsers (in .NET or otherwise), I don't think any of the authors ever bothered even looking up what RFCs were relevant, never mind actually reading them.
So when you opened this issue, I must say, I was surprised.
I don't think I've ever gotten a message from someone with multiple mailboxes in the Sender: header, so it may be safe to make it a MailboxAddress (as opposed to an InternetAddress, which can be a group).
Since the raw header value will be preserved, I might just do that...
from mimekit.
Well, I think your original answer is a fair response for someone implementing a framework. I do like the whole strict in what you send and liberal in what you accept. From an API standpoint it would be nice to match the expectation of normal from the RFC, as long as - like you said - it doesn't affect the ability to access the original header. Honestly I don't fully understand the differences between internetaddress, group, and mailbox yet. My code is just grabbing MailboxAddress and casting to System.Net.MailAddress so I can separate the local part and the domain part.
I ended up reading quite a few RFC because I'm trying to implement NHIN Direct and they have plenty of references. The Direct project has guidance for using S/MIME to authenticate clinical messages between doctors. They're clear that they want to validate the subjects of the signing and encryption certificates with the sender's and recipients' addresses.They tried to qualify what they want done with the following statement:
http://wiki.directproject.org/Applicability+Statement+for+Secure+Health+Transport+Working+Version
STAs MUST perform encryption/decryption and verification functions on the basis of the actual sender(s)
and receiver(s) of the message (i.e., those who are or would be listed in an SMTP RCPT FROM (sic) and
MAIL TO (sic) commands).
I think they meant MAIL FROM and RCPT TO. I don't know what they think that clears up, but MAIL FROM requires there to only be 1 sender mailbox, even if the From header in DATA has multiple senders, and in the case where From has multiple addresses, Sender is required to identify the source mailbox (presumably this is identified by the SMTP MAIL FROM command that originated the message). I think that's the intention of Sender by both Direct Project and RFC-5322 anyway.
In my case, I get to just reject mail that's not compliant with the RFC (single From or single Sender). If there's anything I find that I can contribute back through my use of the API I'll submit some pulls.
On an unrelated note - I haven't had a chance to review your parsing code, but you get a thumbs up from me for caring about performance and spending the time to write C# using pointers. And so far everything has just worked.
from mimekit.
Interesting about the NHIN Direct requirements. I wonder if they realize that the RFC*822 headers don't have to match what the client uses for the MAIL FROM and RCPT TO commands to SMTP. But I guess that doesn't matter so long as the receiving client verifies the digital signatures by matching against the Sender/From headers.
If you need to match against the To/Cc recipients when the message was encrypted, I'll have to implement an API to return a list of who the S/MIME encryption recipients were... which means I'll have to rethink my Decrypt() APIs a bit.
If you don't need this and I'm misunderstanding what is required, let me know so I don't waste time on this :-)
As far as performance... yea, MimeKit is 25x faster than OpenPOP.NET's parser (which is the fastest I could find of the open source .NET parsers), 65x faster than MIMER and 75x faster than SharpMimeTools (which is fairly representative of most of the other .NET parsers out there). They all seem to like to use TextReader and string.Split() with bits of Regex thrown in for slowness. I guess most .NET developers have never heard of tokenizers? Anyway, let's not get me started on this rant :-)
I've got some blog posts on the performance aspect of MimeKit if you are interested:
http://jeffreystedfast.blogspot.com/2013/09/optimization-tips-tricks-used-by.html (part 1)
http://jeffreystedfast.blogspot.com/2013/10/optimization-tips-tricks-used-by.html (part 2)
Sadly, I haven't yet found a way to make MimeKit as fast a my C parser (my C parser is about 1.5x faster than MimeKit). Although, considering that my C parser is noticeably faster than most other C MIME parsers out there... that puts MimeKit in some pretty respectable territory.
from mimekit.
You are right. I will need access to the recipients after the envelope is parsed so that I can ensure each address in the header has a certificate whose subject matches the address based on their rules.
Ideally the certificate that is returned with the recipient would have the private key loaded. At that point I can choose to decrypt the content per-recipient.
from mimekit.
I've changed things so that MimeMessage.Sender is now a MailboxAddress instead of an InternetAdressList.
Ideally the certificate that is returned with the recipient would have the private key loaded. At that point I can choose to decrypt the content per-recipient.
You don't need to do that. You only need to decrypt for one of the recipients - once it is decrypted, it's decrypted. What you probably really want is just a list of recipient certificates that the mime part was encrypted for so that you can use those certificates to try and map them back to the individual email addresses in the To/Cc headers.
from mimekit.
Well I need to at least ensure I have access to the private key for the recipient's certificate. If I have the public key only, then I shouldn't be able to send or receive mail for that recipient.
One option for Decrypt() is to return a DecryptedMessage object that includes all the information available from CmsEnvelopedDataParser. This let's me verify the content encryption algorithm, the recipient certificates and keys, and then lazily load the content if the recipient trust works out. If you don't need any of that detail, you can just go straight to Content and get the decrypted MimeEntity.
public class DecryptedMessage
{
public EncryptionAlgorithm? Algorithm { get; set; }
public IList<SecureMimeRecipient> Recipients { get; set; }
private MimeEntity _content = null;
public MimeEntity Content
{
get { return _content ?? (_content = LoadContent()); }
protected set { _content = value; }
}
...
}
public class SecureMimeRecipient
{
public RecipientInformation Recipient { get; set; }
public X509Certificate Certificate { get; set; }
public AsymmetricKeyParameter PrivateKey { get; set; }
}
from mimekit.
MimeMessage.Sender in the latest version works well for all the messages I have tested it with
from mimekit.
Related Issues (20)
- Potentially false 'Illegal characters in header field name' error
- Suppressing Automatic Replies HOT 13
- Question: Speed up loading of mimemessage from stream HOT 6
- NullReferenceException in BouncyCastleSecureMimeContext
- How To wright Long filenames in "Content-Disposition: attachment; filename" in one line with out the file being writen to a new line HOT 1
- TNEF File Truncated HOT 5
- Support for custom location of certificates store. HOT 1
- Restrictive license reference found HOT 2
- .Accept() return a 500 error when the Html Body format is invalid (missing tag, etc.) HOT 1
- Problem with usage itselv HOT 1
- Problem in getting the name of the attached file HOT 3
- HtmlKit manipulates the attribute value when they contain HTML special entities HOT 1
- Attachment encoding wrong HOT 2
- MimeUtils ParseMessageId function not working as expected HOT 4
- Empty `HtmlBody` for some Apple Mail messages (sent from iOS) HOT 2
- VS 2022 Preview .Net 8 Maui iOS Archive Fails HOT 9
- Mail can't be opened and would not show attachments HOT 7
- How to load a MimeMessage from an IFormFile ? HOT 2
- System.Security.Cryptography vs Org.BouncyCastle.Crypto HOT 1
- Question: Is this fixable with MimeKit HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mimekit.