<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc rfcedstyle="yes"?>
<?rfc subcompact="no"?>
<?rfc symrefs="yes"?>
<?rfc comments="yes" ?>
<?rfc inline="yes" ?>

<rfc ipr="trust200902" category="info" docName='draft-ietf-jmap-smime-sender-extensions-03'>
  <front>
    <title abbrev="JMAP extension for S/MIME">
      JMAP extension for S/MIME signing and encryption
    </title>
    <author initials="A." surname="Melnikov" fullname="Alexey Melnikov">
      <organization>Isode Ltd</organization>
      <address>
        <postal>
          <street>14 Castle Mews</street>
          <city>Hampton</city>
          <region>Middlesex</region>
          <code>TW12 2NP</code>
          <country>UK</country>
        </postal>
        <email>Alexey.Melnikov@isode.com</email>
      </address>
    </author>
      
    <date year="2023" />
    
    <keyword>JMAP</keyword>
    <keyword>S/MIME</keyword>

    <abstract>

    <t>
    This document specifies an extension to JMAP for sending S/MIME signed and S/MIME encrypted messages<!--, and automatic decryption of received S/MIME messages-->.
    </t>
	
    </abstract>
    
  </front>
  <middle>

    <section title="Introduction">

        <t>
        <xref target="RFC8621"/> is a JSON based application protocol for synchronising email data
        between a client and a server.

<!--
   JMAP [RFC8620] is a generic protocol for synchronising
   data, such as mail, calendars or contacts, between a client and a
   server.  It is optimised for mobile and web environments, and aims to
   provide a consistent interface to different data types.
   [RFC8621] builds on top of JMAP and defines how to perform
   email synchronization.
-->
        </t>
      
        <t>
        This document describes an extension to JMAP for sending S/MIME signed and encrypted messages
        <!--, and automatic decryption of received S/MIME messages-->.
        It allows JMAP server to <!--access (preconfigured) user's signing and encryption keys, and-->
        sign/encrypt messages on user's behalf.
        </t>

    </section>
    
    <section title="Conventions Used in This Document">
      
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
	    "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in
	    this document are to be interpreted as described in
	    <xref target="RFC2119"/>.</t>

    </section>

    <section title="Addition to the capabilities object">

      <t>
        The capabilities object is returned as part of the standard JMAP
        Session object; see the JMAP spec.  Servers supporting _this_
        specification MUST add a property called
        "urn:ietf:params:jmap:smime-advanced" to the capabilities object.
      </t>

      <t>
        <!--/////This might change in the future if S/MIME signing/encrypting/decrypting is added:-->
        The value of this property is an empty object in both the JMAP
        session _capabilities_ property and an account's
        _accountCapabilities_ property.
      </t>

    </section>

    <section title="Extension to Email/set for S/MIME signing and/or encryption" anchor="smime">

      <!--The following assumes that messages created signed/encrypted, when they are created and uploaded.
      I.e. this operation is not deferred till later Send. Is this the right model?-->

      <t>
        <xref target="RFC8621"/> defines Email/set method for creating new email messages.
        This document defines the following additional request arguments that can be used to
        create S/MIME signed and/or encrypted messages:<vspace/>

        <list style="bullets">

          <t>
            smimeSign: "Boolean" (default: false). If included and has the value "true", this requests the JMAP server
            to create an S/MIME signed message from the message constructed according to other specified arguments (the "original message").
            This is done by encapsulating the original message either inside application/pkcs7-mime <xref target="RFC8551"/> or 
            multipart/signed <xref target="RFC1847"/> container. (smimeSignOpaque argument (see below) controls which of the two mechanisms is used.)
            The signature's private key/certificate is associated with the email address in
            the Sender header field, if present; otherwise, it is associated with the email address
            in the From header field, if present.<vspace/>

            If multiple addresses are present in one of these header
            fields, or there is more than one Sender/From header field, the
            server SHOULD reject the Email/set as invalid with the "invalidEmail" error code; otherwise,
            it MUST take the first address in the last Sender/From header field.
            
            If JMAP account is not authorized to sign message as the selected sender (as above), it SHOULD return "signedSenderNotAllowed" error code.
          </t>

          <t>
            smimeEncrypt: "Boolean" (default: false). If included and has the value "true", this requests the JMAP server
            to create an S/MIME encrypted message from the constructed message.
            This is done by encapsulating the message inside application/pkcs7-mime <xref target="RFC8551"/> media type.
            The message MUST be encrypted to the sender and all To/Cc/Bcc recipients.
            This extension assumes that there is some kind of per user or organizational addressbook,
            that can be used to lookup public keys of recipients. If lookup of a particular public key fails,
            or results in an expired or revoked certificate, the Email/set operation MUST fail with the "validEncryptionKeyNotFound" error code.
          </t>

          <t>
            smimeHeaderProtect: "Boolean" (default: true). If has the value "true", this requests the JMAP server
            to use S/MIME header protection as specified in <xref target="draft-ietf-lamps-header-protection"/>
            when at least one of smimeEncrypt/smimeSign is true.
          </t>
          
          <t>
            smimeSignOpaque: "Boolean" (default: true). If has the value "true", this requests the JMAP server
            to use application/pkcs7-mime media type for S/MIME signing, otherwise multipart/signed media type.
          </t>

        </list>
      </t>

      <t>
      If both "smimeSign" and "smimeEncrypt" are set to true, the message is first signed and then the signed version is encrypted (in that order).
      </t>

      <t>
        <!--///Use <aside>?-->
        (Note that this extension doesn't allow management of private keys/certificates.
        How private keys are managed or configured for a particular user is out of scope for this document.)
      </t>

      <!--///For decryption: should we return blobIds for decrypted body parts and let clients use Email/parse on them?-->

      <figure title="Example 1:">
        <preamble>
        </preamble>
<artwork>
  <![CDATA[
      [[ "Email/set", {
        "accountId": "ue150411c",
        "create": {
          "k192": {
            "mailboxIds": {
              "2ea1ca41b38e": true
            },
            "keywords": {
              "$seen": true,
              "$draft": true
            },
            "from": [{
              "name": "Joe Bloggs",
              "email": "joe@example.com"
            }],
            "subject": "World domination",
            "receivedAt": "2021-07-07T01:03:11Z",
            "sentAt": "2021-07-10T11:03:11+10:00",
            "smimeSign": true,
            "smimeEncrypt": true,
            "bodyStructure": {
              "type": "text/plain",
              "partId": "bd48",
              "header:Content-Language": "en"
            },
            "bodyValues": {
              "bd48": {
                "value": "I have the most brilliant plan.  Let me tell
                  you all about it.",
                "isTruncated": false
              }
            }
          }
        }
      }, "0" ]]

This will result in the following response:

      [[ "Email/set", {
        "accountId": "ue150411c",
        "oldState": "780823",
        "newState": "780839",
        "created": {
          "k192": {
            "id": "Mf40b5f831efa7233b9eb1c7f",
            "blobId": "Gf40b5f831efa7233b9eb1c7f8f97d84eeeee64f7",
            "threadId": "Td957e72e89f516dc",
            "size": 5096
          }
        },
        ...
      }, "0" ]]
]]></artwork>
        <postamble>
        </postamble>
      </figure>
    </section>

    <section title="Extension to Email/get for S/MIME decryption" anchor="smime-decrypt">

      <t>
        <xref target="RFC8621"/> defines Email/get method for retrieving information about email messages.
        This document defines the following additional request arguments of the "bodyProperties" object that can be used to
        facilitate decryption of S/MIME encrypted messages:<vspace/>

        <list style="bullets">

          <t>
            smimeBlobId: "Id|null".

            The id representing the raw octets of the decrypted contents of the part.
            When processing this request argument, the server first removes
            the Content-Transfer-Encoding (see then "blobId" request argument in RFC 8621).
            If the Content-Transfer-Encoding is supported by the server,
            the content is then S/MIME decrypted.
            The resulting Id can be used in Email/parse method to import the decrypted message.

            If the body part is not encrypted, the returned smimeBlobId attribute has
            the same value as the "blobId" attribute.
          </t>

        </list>
      </t>

      <!--///For decryption: should we also extend Email/query to be able to search for encrypted attachments?-->

      <figure title="Example 2:">
        <preamble>
        </preamble>
<artwork>
        <![CDATA[
    [[ "Email/get", {
        "ids": [ "f123u986" ],
        "properties": [ "threadId", "mailboxIds", "from", "subject",
          "receivedAt", "htmlBody" ],
        "bodyProperties": [ "partId", "smimeBlobId", "size", "type" ]
      }, "#1" ]]
      
This will result in the following response:

    [[ "Email/get", {
     "accountId": "abc",
     "state": "41234123231",
     "list": [
       {
         "id": "f123u986",
         "threadId": "cb1314a",
         "mailboxIds": { "da123c": true },
         "from": [{ "name": "Mice Ace", "email": "mike@example.com" }],
         "subject": "Dinner on Saturday?",
         "receivedAt": "2023-03-09T14:12:00Z",
         
         "htmlBody": [{
           "partId": "1",
           "smimeBlobId": "B841623871",
           "size": 120537,
           "type": "text/html"
         }]
       }
     ]
   }, "#1" ]]      

]]></artwork>
        <postamble>
        </postamble>
      </figure>

    </section>

    <section title="IANA Considerations">

      <section title='JMAP capability registration for "smime-advanced"'>

        <t>
          IANA is requested to register the "smime" JMAP Capability as follows:
        </t>

        <t>
          Capability Name: "urn:ietf:params:jmap:smime-advanced"
        </t>

        <t>
          Specification document: this document
        </t>

        <t>
          Intended use: common
        </t>

        <t>
          Change Controller: IETF
        </t>

        <t>
          Security and privacy considerations: this document, <xref target="seccons"/>
        </t>

      </section>
      
      <section title='JMAP Error Codes Registry Updates'>

        <section title='signedSenderNotAllowed error code'>
          
          <t>
          JMAP Error Code: signedSenderNotAllowed
          </t>

          <t>
          Intended use: common
          </t>

          <t>
          Change controller: IETF
          </t>

          <t>
          Reference: This document, <xref target="smime"/>
          </t>

          <t>
          Description: JMAP account is not authorized to S/MIME sign message as
          the specified sender.
          </t>
        
        </section>

        <section title='validEncryptionKeyNotFound error code'>
          <t>
          JMAP Error Code: validEncryptionKeyNotFound
          </t>

          <t>
          Intended use: common
          </t>

          <t>
          Change controller: IETF
          </t>

          <t>
          Reference: This document, <xref target="smime"/>
          </t>

          <t>
          Description: S/MIME encrypted message can't be generated because
          no valid certificate (non expired and non revoked) can be found
          for one of recipients.
          </t>
        </section>

      </section>
  
    </section>

    <section title="Security Considerations" anchor="seccons">

      <t>This JMAP extension assumes trust between the user and the JMAP server for purposes of signing and encrypting messages on user's behalf.
      <!--This might break "end-to-end encrypted" guarantee that might be expected from use of S/MIME.-->
      </t>
      
      <t>This JMAP extension also relies on access to user's (or organization's) addressbook which contain up-to-date certificates for recipients.
      </t>

      <t>This JMAP extension doesn't support management of user's private keys and corresponding certificates.</t>

      <!--
      <t>TBD. Server that lies?</t>
      -->

    </section>
    
  </middle>
  <back>
    <references title="Normative References">
      <?rfc include="reference.RFC.1847"?> <!-- Multipart/signed and multipart/encrypted -->
      <?rfc include="reference.RFC.2119"?> <!-- Keywords -->
      <?rfc include="reference.RFC.8550"?> <!-- S/MIME Certificate Handling -->
      <?rfc include="reference.RFC.8551"?> <!-- S/MIME Message Format -->
      <?rfc include="reference.RFC.8620"?> <!-- JMAP Core -->
      <?rfc include="reference.RFC.8621"?> <!-- JMAP Mail -->

      <reference anchor="draft-ietf-lamps-header-protection" target="https://datatracker.ietf.org/doc/html/draft-ietf-lamps-header-protection-13">
        <front>
          <title>Header Protection for Cryptographically Protected E-mail</title>
          <author fullname="Daniel Kahn Gillmor" initials="D. K." surname="Gillmor">
            <organization>American Civil Liberties Union</organization>
          </author>
          <author fullname="Bernie Hoeneisen" initials="B." surname="Hoeneisen">
            <organization>pEp Foundation</organization>
          </author>
          <author fullname="Alexey Melnikov" initials="A." surname="Melnikov">
            <organization>Isode Ltd</organization>
          </author>
          <date day="10" month="March" year="2023"/>
          <abstract>
            <t>S/MIME version 3.1 introduced a mechanism to provide end-to-end cryptographic protection of e-mail message headers. However, few implementations generate messages using this mechanism, and several legacy implementations have revealed rendering or security issues when handling such a message. This document updates the S/MIME specification to offer a different mechanism that provides the same cryptographic protections but with fewer downsides when handled by legacy clients. The header protection schemes described here are also applicable to messages with PGP/MIME cryptographic protections. Furthermore, this document offers more explicit guidance for clients when generating or handling e-mail messages with cryptographic protection of message headers.</t>
          </abstract>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-lamps-header-protection-13"/>
      </reference>

    </references>

<!--    
    <references title="Informative References">
    </references>
-->

<!--
    <section title="Acknowledgements">
	
      <t>Thank you to Steve Kille and David Wilson for suggestions, comments and corrections on this document.</t>

      <t>David Wilson came up with the idea of defining a new Content-Type header field parameter to distinguish
      forwarded messages from inner header field protection constructs.</t>
      
    </section>
-->    
    
  </back>
</rfc>
