Skip to content

Comments

S/MIME signing (WIP)#3979

Merged
tomholub merged 24 commits intomasterfrom
issue-2970-signing-smime
Oct 6, 2021
Merged

S/MIME signing (WIP)#3979
tomholub merged 24 commits intomasterfrom
issue-2970-signing-smime

Conversation

@rrrooommmaaa
Copy link
Contributor

@rrrooommmaaa rrrooommmaaa commented Sep 14, 2021

This PR supports sending Signed S/MIME messages

Tasks:

  • encrypt/decrypt PKCS#7 message
  • support for armored PKCS#7
  • support for PKCS#7-encrypted drafts
  • send simple-text S/MIME message without attachments

close #2970


Tests (delete all except exactly one):

  • Tests added or updated

To be filled by reviewers

I have reviewed that this PR... (tick whichever items you personally focused on during this review):

  • addresses the issue it closes (if any)
  • code is readable and understandable
  • is accompanied with tests, or tests are not needed
  • is free of vulnerabilities
  • is documented clearly and usefully, or doesn't need documentation

@rrrooommmaaa
Copy link
Contributor Author

@tomholub a simple-text S/MIME was successfully generated, also S/MIME drafts (encrypted) are supported in this PR.
Which features of the task list should I implement in this PR and which to postpone? (The PR becomes quite big).

@tomholub
Copy link
Collaborator

Ok to merge limited functionality, for smaller PR.

The ultimate goal is to support signed+encrypted S/MIME, which is what one of our customer needs and has been asking for. That can also be in separate PR.

add authenticated attributes to PKCS#7 message

does this mean the actual signing? Or something else?

send simple text with attachments

can be a separate issue for the future

send richtext?

can be a separate issue for the future

signed and encrypted?

This is the most important. Could also be tackled separately.

@rrrooommmaaa
Copy link
Contributor Author

rrrooommmaaa commented Sep 28, 2021

add authenticated attributes to PKCS#7 message

does this mean the actual signing? Or something else?

Well, according to docs, it is possible for SignerInfo to have some optional signed attributes, listed here: https://datatracker.ietf.org/doc/html/rfc5652#section-11

From what I understood, we can omit all of these signed attributes (and Thundertbird successfully verified the signature without them).
However, if we require at least one (e.g. "Signing Time"), we MUST include "Content Type" and "Message Digest".
As said in https://datatracker.ietf.org/doc/html/rfc5652#section-5.6 ... If the SignedData signerInfo includes
signedAttributes

So, as far as my understanding goes, the question is whether we need Signing Time

@rrrooommmaaa
Copy link
Contributor Author

rrrooommmaaa commented Sep 28, 2021

They are quite easy to add. Not sure if necessary. The forge library shows this example

      authenticatedAttributes: [{
        type: forge.pki.oids.contentType,
        value: forge.pki.oids.data
      }, {
        type: forge.pki.oids.messageDigest
        // value will be auto-populated at signing time
      }, {
        type: forge.pki.oids.signingTime
        // value will be auto-populated at signing time
        //value: new Date('2050-01-01T00:00:00Z')
      }]

forge.pki.oids.data is a constant 1.2.840.113549.1.7.1, other values are placeholders to be filled by the forge library itself.
Took time to figure out.
Guessed you (or the client) had a position on whether this is required.

@tomholub
Copy link
Collaborator

Please file the above two comments in a separate issue. We'll deliver to customer without it. If they need it, they will know (their recipient system will reject the message). Then we'd add it at that point. Otherwise, we'd add it whenever we have spare time in the future (2023? :-) )

Copy link
Collaborator

@tomholub tomholub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a serious effort - very happy to see this.

let smimePubs = pubs.filter(pub => pub.pubkey.type === 'x509');
if (pgpPubs.length && smimePubs.length) {
// get rid of some of my keys to resolve the conflict
// todo: how would it work with drafts?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drafts could be enabled only when we have at least one OpenPGP private key? Then make them OpenPGP?

In general, it's ok to explicitly disable functionality when user only imports S/MIME private key and nothing else. It's not a scenario we are designing for, even if it's allowed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented drafts for S/MIME because there were errors popping up when testing S/MIME user (without OpenPGP keys) editing a message (although "experimental"). I will disable such drafts completely, if you like.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it already works, no need to disable it. If you needed to spend a bunch of other work, then can disable as a way to save time

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it works. I even added a test that loads an ecnrypted PKCS#7 draft. Was also planning on adding a test that saves a PKCS#7 draft, but will skip it, if you wish so.

@rrrooommmaaa rrrooommmaaa marked this pull request as ready for review October 6, 2021 09:04
@rrrooommmaaa rrrooommmaaa requested a review from tomholub October 6, 2021 09:04
@rrrooommmaaa
Copy link
Contributor Author

rrrooommmaaa commented Oct 6, 2021

Oh perhaps need to add a test to send an S/MIME signed message when passphrase is not cached.

Copy link
Collaborator

@tomholub tomholub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm starting to feel like we are writing some sort of an S/MIME library here. It may be worth to one day extract this functionality, including their own tests, and make an actual library from it that uses forge as dependency and get it security-reviewed. Then we'd import this s/mime library into our project. Either that, or contribute the improvements back to forge. Because these S/MIME operations are getting quite dense: ideally the browser extension code would work at a higher level of abstraction.

For now, it's more convenient to keep it in this codebase, for flexibility as you develop and add major S/MIME functionality. But once that mostly settles, it would be better to extract it into a library.

Comment on lines +95 to +97
if (p7.type !== '1.2.840.113549.1.7.3') {
throw new Error('Not implemented');
}
Copy link
Collaborator

@tomholub tomholub Oct 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add comment regarding what this means? 1.2.840.113549.1.7.3 and also what is the regular type, and why is 1.2.840.113549.1.7.3 different from whatever the regular type is.

@tomholub
Copy link
Collaborator

tomholub commented Oct 6, 2021

I'll merge this, then you can address the misisng test and a comment afterwards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

allow signing of outgoing s/mime emails

2 participants