########################### GSSAPI Sealing API Proposal ########################### .. warning:: This is a work in progress, largely intended to solicit the opinion of interested parties. Introduction ############ `GSSAPI `_ is a standard for secure communications between two parties. Notably, it has become the de-facto standard portable API for `Kerberos `_, so much so that "GSSAPI" often implies "Kerberos" despite the existence of things like `SPKM `_ and `LIPKEY `_. GSSAPI is, at its core, an online client/server ("initiator" and "acceptor" in its terminology) architecture. The basic flow of communication is to initiate a "context" (and have that context be accepted) before messages may be passed within that context, using, optionally, confidentiality and integrity mechanisms provided by the underlying cryptographic mechanism. That is, Alice may establish a context for secure communication with Bob, and another for Carol, and so on. (Other things are possible, including delegation of identity or rights and replay detection on the stream of messages, but these are not germane to this document.) However, GSSAPI has no intrinsic mechanism for *asynchronous* communication with another party; there is no mechanism, Alice having established a context with Bob (and, optionally, Carol), for Alice (or Bob) to **seal** or **box** a message such that it can be passed to Carol, who can then forward it to Bob in a *verifiable*, *confidential* way. Bob should be able to verify that * Alice sealed this message, * Bob was indeed the intended recipient, * (optionally) that Carol was the intended relaying party, * (optionally) that the message was sealed recently, and * (optionally) that the message has not been replayed by Carol (or another agent). Neither Carol nor any other agent should be able to learn anything about the message body (except an approximation of its length) or the identities of Alice, Bob, or Carol from the message itself. Another way to think about the intended use of sealing is that Alice may wish to allow Carol to prove to Bob that Alice and Carol are in communication and to reliably prove Alice's opinions of that communication to Bob. For intuition, imagine Alice as something akin to a Kerberos TGS, having active contexts with both Bob and Carol; Alice's sealing of a message for Carol to give to Bob is akin to granting a service ticket. The key is that the sealed message carries the identities of its originator (Alice) and relaying party (Carol) and may only be unsealed by its recipient (Bob). API Calls ######### * ``GSS_Wrap2`` (as performed by Alice): * Inputs: * ``recipient_context_handle`` ``CONTEXT HANDLE`` (with Bob), * ``relaying_context_handle`` ``CONTEXT HANDLE`` (with Carol, optional), * ``freshness_stamp`` ``INTEGER``, * ``input_message`` ``OCTET STRING`` * Outputs: * ``major_status`` ``INTEGER``, * ``minor_status`` ``INTEGER``, * ``output_message`` ``OCTET STRING`` -- caller to release with ``GSS_Release_buffer()`` The ``freshness_stamp`` parameter is one of ``GSS_WRAP_FRESH_TIMESERIAL``, ``GSS_WRAP_FRESH_TIMEONLY``, or ``GSS_WRAP_FRESH_NONE``. The existing ``GSS_Wrap`` call is equivalent to ``GSS_Wrap2`` with ``relaying_context_handle = NULL`` and ``freshness_stamp = GSS_WRAP_FRESH_NONE``, and a call to ``GSS_Wrap2`` satisfying these conditions may not fail unless the equivalent call to ``GSS_Wrap`` would. * ``GSS_Unwrap2`` (as performed by Bob): * Inputs: * ``context_handle`` ``CONTEXT HANDLE`` (with Carol), * ``req_freshness`` ``INTEGER``, * ``input_message`` ``OCTET STRING`` (from Carol, originally produced by Alice) * Outputs: * ``major_status`` ``INTEGER``, * ``minor_status`` ``INTEGER``, * ``output_message`` ``OCTET STRING`` -- caller to release with ``GSS_Release_buffer()`` * ``cred_name`` ``INTERNAL NAME`` -- caller to release with ``GSS_Release_name()`` * ``is_relayer`` ``INTEGER`` ``is_relayer`` indicates whether the remote credential of ``context_handle`` is the same credential as the remote credential of the ``relaying_context_handle`` given to ``GSS_Wrap2``. Possible values are * ``GSS_WRAP_ISRELAY_POSITIVE``, indicating explicit confirmation; * ``GSS_WRAP_ISRELAY_NEGATIVE``, indicating explicit denial; or * ``GSS_WRAP_ISRELAY_UNSPECIFIED``, indicating that no ``relaying_context_handle`` was given to ``GSS_Wrap2``. If ``GSS_Unwrap2`` is successful, ``output_message`` must match the ``input_message`` used in the call to ``GSS_Wrap2`` to produce the ``input_message`` fed to ``GSS_Unwrap2`` and ``cred_name`` must describe Alice. (In particular, ``cred_name`` should be equal to the name that would be obtained as the remote half of Bob's half of Alice's ``recipient_context_handle``.) Note that ``GSS_Unwrap2`` is a superset of ``GSS_Unwrap``. If the ``input_message`` to ``GSS_Unwrap2`` was produced with ``GSS_Wrap`` or with an equivalent ``GSS_Wrap2`` call, ``cred_name`` must be NULL and ``is_relayer`` must be ``GSS_WRAP_ISRELAY_UNSPECIFIED``.