Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 167 additions & 63 deletions IETF-OCM.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ Share Creation Notification from an unknown Sending Party is received

Whereas the precise syntax of the Invite Message and the Invite
Acceptance Gesture will differ between implementations, the Invite
Acceptance Request SHOULD be a HTTP POST request:
Acceptance Request MUST be a HTTP POST request:

* to the `/invite-accepted` path in the Invite Sender OCM Server's OCM
API
Expand All @@ -376,7 +376,12 @@ Acceptance Request SHOULD be a HTTP POST request:
- REQUIRED: `name` - Human-readable name of the Invite Receiver, as a
suggestion for display in the Invite Sender's address book
* using TLS
* using httpsig [RFC9421]

When HTTP Message Signatures are available, the Invite Acceptance
Request MUST be signed and verified as described in [HTTP Message
Signatures](#http-message-signatures). As the Invite flow establishes
the trust that later exchanges rely on, implementations SHOULD NOT use
it unless signing is available.

The Invite Receiver OCM Server SHOULD apply its own policies for
trusting the Invite Sender OCM Server before making the Invite
Expand Down Expand Up @@ -429,10 +434,11 @@ A 403 response status means the Invite Receiver OCM Server is not
trusted to accept this Invite.
A 409 response status means the Invite was already accepted.

The Invite Sender OCM Server SHOULD verify the HTTP Signature on the
Invite Acceptance Request and apply its own policies for trusting the
Invite Receiver OCM Server before processing the Invite Acceptance
Request and sending the Invite Acceptance Response.
Before processing the Invite Acceptance Request and sending the Invite
Acceptance Response, the Invite Sender OCM Server SHOULD apply its own
policies for trusting the Invite Receiver OCM Server. Any HTTP
Signature on the request is verified as described in [HTTP Message
Signatures](#http-message-signatures).

As with the `userID` in the Invite Acceptance Request, the one in the
Response also doesn't need to be human-memorable, doesn't need to match
Expand Down Expand Up @@ -760,6 +766,108 @@ contain the following information about its OCM API:
provide this URL as well.
Example: `"https://cloud.example.org/ocm/token"`.

# HTTP Message Signatures

A number of OCM API requests are signed "using httpsig [RFC9421]", as
described in the respective sections. This section specifies the
normative requirements for producing and verifying those signatures.
Appendix B contains a complete example.

Public keys for signature verification are published in the format
specified by [RFC7517] at the signer's `/.well-known/jwks.json`
endpoint, if the `http-sig` capability is included in the
[Discovery](#ocm-api-discovery) response.

## Applicability

Support for HTTP Message Signatures is negotiated through the
`http-sig` capability in the [Discovery](#ocm-api-discovery) response.
The following rules let deployments adopt signing incrementally while
remaining interoperable:

* A Server that implements HTTP Message Signatures MUST use them when
interacting with another Server that advertises the `http-sig`
capability.
* Such a Server MAY nonetheless continue to interact, without signing,
with a Server that does not advertise the `http-sig` capability, for
backwards compatibility.
* A Server that implements HTTP Message Signatures MUST verify any
signature present on a request it receives, as specified below.
* A Server MAY accept an unsigned request from a Server that does not
advertise the `http-sig` capability; a Server that advertises the
`must-use-http-sig` criterion MUST reject unsigned requests.
* A Server that does not implement HTTP Message Signatures operates
without them.

Because the [Invite Acceptance
Request](#invite-acceptance-request-details) and [Request for a
Share](#request-for-a-share) establish the trust that later exchanges
rely on, implementations SHOULD NOT use those features unless HTTP
Message Signatures are available.

## Signing Requirements

A signed request MUST cover at least the following Signature-Input
components:

* "@method" - HTTP method
* "@target-uri" - full request URI (scheme, authority,
path, query)
* "content-digest" - [RFC9530] digest of the body
Comment thread
mickenordin marked this conversation as resolved.
* "content-length" - message size

The Signature-Input parameters MUST include `created`. Freshness and
replay protection are anchored on `created` (see Verification
Requirements).

A signed request SHOULD additionally cover the `date` component when a
`Date` header is present.

The `content-digest` component binds the request body to the signature,
protecting it against modification in transit. Its value MUST use a
hash algorithm from the IANA "Hash Algorithms for HTTP Digest Fields"
registry [IANA-DIGEST-ALG]; implementations MUST support `sha-256`.

A request signed in the context of OCM MUST carry the signature
parameter `tag="ocm"` (see Section 2.3 of [RFC9421]). Unlike the
signature label, which is a dictionary key that is not covered by the
signature and MAY be rewritten in transit, the `tag` parameter is part
of the signature base and is therefore integrity-protected.

A request MUST include one and only one signature carrying
`tag="ocm"`. The signature label MAY be any value; it is not
significant to OCM processing.

The signature MUST use an asymmetric algorithm from the IANA "HTTP
Signature Algorithms" registry [IANA-SIG-ALG]; `ed25519` [RFC8032] is
RECOMMENDED. A symmetric algorithm, such as the HMAC-based
`hmac-sha256`, MUST NOT be used, as the Receiving Server would not be
able to verify the signature without prior access to the shared secret.

## Verification Requirements

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

adding a short mention of Accept-Signature (Section 5.1 of RFC 9421) as a wayn for verifier to state which parameters they require and support seems relevant in this section

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Is this needed since we have the http-sig capability in the discovery, already negotiating this? Do you know if it is usually is used by software libraries to prepare signatures, or if it would be redundant in this context given our discovery mechanism?


Verifiers MUST reject signatures that omit any of the mandatory
components listed under Signing Requirements or the `created`
parameter, and MUST reject signatures whose `created` value is more
than a small implementation-defined skew tolerance in the future, or
older than the verifier's freshness window.

A `Content-Digest` header value carrying multiple algorithms MUST have
every recognised digest match the body; a single match alongside a
recognised mismatch MUST be treated as an integrity failure.

Verifiers MUST identify the OCM signature by its `tag="ocm"`
parameter, examining the parameters of each member of the
`Signature-Input` field and disregarding the dictionary labels.
Verifiers MUST verify only that signature. If more than one signature
carries `tag="ocm"`, the entire message MUST be rejected. A request
that carries no signature with `tag="ocm"` is unsigned and is handled
as described in Applicability (accepted only at the receiver's
discretion, or rejected when the receiver advertises
`must-use-http-sig`). Signatures without `tag="ocm"` MAY coexist (e.g.
proxy-attached signatures) but verifiers MUST NOT process them as part
of OCM signature processing.

# Share Creation Notification

To create a Share, the Sending Server SHOULD make a HTTP POST request
Expand Down Expand Up @@ -1098,15 +1206,22 @@ notification that this happened.
# Request for a Share

If the Receiving Party knows of a resource that has not yet
been shared, the Receiving Party MAY make an HTTP POST request
been shared, the Receiving Party MAY request that it be shared.
Such a Request for a Share MUST be an HTTP POST request

* to the `/request-share` path in the Sending Server's OCM API
* using `application/json` as the `Content-Type` HTTP request
header
* its request body containing a JSON document representing an
object with the fields as described below
* using TLS
* using httpsig [RFC9421]

When HTTP Message Signatures are available, the Request for a Share
MUST be signed and verified as described in [HTTP Message
Signatures](#http-message-signatures). As requesting access to a
restricted resource relies on authenticating the requester,
implementations SHOULD NOT use this feature unless signing is
available.

## Fields

Expand All @@ -1120,6 +1235,10 @@ been shared, the Receiving Party MAY make an HTTP POST request
A unique identifier for the resource.
Example: 1234567890abcdef or https://cloud.example.org/files/data.txt

Any HTTP Signature on the Request for a Share is verified as described
in [HTTP Message Signatures](#http-message-signatures) before the
Sending Server acts on it.

After receiving a request for a Share, the Sending Party MAY
send a Share Creation Notification to the Receiving Party
using the OCM address in the shareWith field.
Expand Down Expand Up @@ -1283,11 +1402,12 @@ Content-Type: application/x-www-form-urlencoded
Digest: SHA-256=ok6mQ3WZzKc8nb7s/Jt2yY1uK7d2n8Zq7dhl3Q0s1xk=
Content-Length: 101
Signature-Input:
ocm=("@method" "@target-uri" "content-digest" "date");
sig1=("@method" "@target-uri" "content-digest" "date");
created=1730815200;
keyid="receiver.example.org#key1";
alg="ed25519"
Signature: ocm=:bM2sV2a4oM8pWc4Q8r9Zb8bQ7a2vH1kR9xT0yJ3uE4wO5lV6bZ1cP
alg="ed25519";
tag="ocm"
Signature: sig1=:bM2sV2a4oM8pWc4Q8r9Zb8bQ7a2vH1kR9xT0yJ3uE4wO5lV6bZ1cP
2rN3qD4tR5hC=:

grant_type=authorization_code&
Expand Down Expand Up @@ -1699,7 +1819,9 @@ discovery service.

It is RECOMMENDED to use signed messages, "httpsig" [RFC9421], to
verify that an OCM server is the server you expect it to be, and SHOULD
be done unless you have a niche use case.
be done unless you have a niche use case. Where signatures are used,
they MUST follow the requirements in
[HTTP Message Signatures](#http-message-signatures).

## Legacy shared secrets

Expand All @@ -1726,6 +1848,12 @@ author, version, name of work, or endorsement information.

## Normative References

[IANA-DIGEST-ALG] IANA, "[Hash Algorithms for HTTP Digest Fields](
https://www.iana.org/assignments/http-digest-hash-alg/http-digest-hash-alg.xhtml)".

[IANA-SIG-ALG] IANA, "[HTTP Signature Algorithms](
https://www.iana.org/assignments/http-message-signature/http-message-signature.xhtml#signature-algorithms)".

[RFC2119] Bradner, S. "[Key words for use in RFCs to Indicate
Requirement Levels](https://datatracker.ietf.org/doc/html/rfc2119)",
March 1997.
Expand Down Expand Up @@ -1777,13 +1905,13 @@ https://datatracker.ietf.org/doc/html/rfc9553), May 2024"

## Informative References

[OCM-IP] Nordin, M., Lo Presti, G., and Baghbani, M. "[Open
Cloud Mesh Integration
[OCM-IP] Nordin, M., Lo Presti, G., and Baghbani, M. "[Open Cloud Mesh
Integration
Protocol](https://datatracker.ietf.org/doc/draft-nordin-ocm-integration-protocol/)",
Work in Progress, Internet-Draft.

[OCM-MLS] Nordin, M., Lo Presti, G., and Baghbani, M. "[Federated
Groups in Open Cloud Mesh using Messaging Layer
[OCM-MLS] Nordin, M., Lo Presti, G., and Baghbani, M. "[Federated Groups
in Open Cloud Mesh using Messaging Layer
Security](https://datatracker.ietf.org/doc/draft-nordin-ocm-mls-federated-groups/)",
Work in Progress, Internet-Draft.

Expand Down Expand Up @@ -1879,71 +2007,47 @@ breaks in @signature-params for display purposes only):
"content-length" "date");
created=[timestamp];
keyid="sender.example.org#key1";
alg="ed25519"
alg="ed25519";
tag="ocm"
</sourcecode>

Sign this base using for example Ed25519 ([RFC8032]) to produce the
signature, using the `ocm` label, and then add headers (line breaks
for display purposes only):
signature, and then add headers (line breaks for display purposes
only). Note that the dictionary label (`sig1` below) is arbitrary; the
signature is marked as belonging to OCM by its `tag="ocm"` parameter,
which is part of the signature base above:

<sourcecode type="http">
Content-Digest: sha-256=:[digest-value]:
Content-Length: [body-length]
Date: [date]
Signature-Input: ocm=("@method" "@target-uri" "content-digest"
Signature-Input: sig1=("@method" "@target-uri" "content-digest"
"content-length" "date");
created=[timestamp];
keyid="sender.example.org#key1";
alg="ed25519"
Signature: ocm=:[signature-value]=:
alg="ed25519";
tag="ocm"
Signature: sig1=:[signature-value]=:
</sourcecode>

A signed request MUST cover at least the following Signature-Input
components:

- "@method" - HTTP method
- "@target-uri" - full request URI (scheme, authority,
path, query)
- "content-digest" - [RFC9530] digest of the body
- "content-length" - bound message size
- "date" - bound clock time

The Signature-Input parameters MUST include `created`. Verifiers MUST
reject signatures that omit any of the above components or the `created`
parameter, and MUST reject signatures whose `created` value is more than
a small implementation-defined skew tolerance in the future, or older
than the verifier's freshness window.

A `Content-Digest` header value carrying multiple algorithms MUST have
every recognised digest match the body; a single match alongside a
recognised mismatch MUST be treated as an integrity failure.

A request signed in the context of OCM MUST include one and only one
signature with the label `ocm` in its Signature and Signature-Input
headers.

A symmetric signing algorithm MUST NOT be used to sign the
request, as the Receiving Server would not be able to verify the
signature without having access to the shared secret in advance.
The covered components, the `created` parameter, the single `ocm`
tag, and the prohibition on symmetric algorithms shown here are
normative; see [HTTP Message Signatures](#http-message-signatures) for
the full requirements.

## Verifying a Signature (Receiver)

Verifiers MUST locate the ocm-labeled entry and verify only that one.
If multiple `ocm` signatures are present, the entire message MUST be
rejected. Verifiers MUST reject requests for which no ocm-labeled entry
is present. Other labels MAY coexist (e.g. proxy-attached signatures)
but verifiers MUST NOT process them as part of OCM signature
processing.


To verify an incoming signed request:
The normative verification requirements are specified in
[HTTP Message Signatures](#http-message-signatures). The following
illustrates the procedure to verify an incoming signed request:

1. Extract the provider domain from the `sender` field in the
request body
2. Fetch the public key from
`https://<provider-domain>/.well-known/jwks.json`
3. Locate the unique signature with the label `ocm` in the
`Signature-Input` header
3. Locate the unique signature carrying the `tag="ocm"` parameter in
the `Signature-Input` header, disregarding its dictionary label
(here `sig1`)
4. Extract `keyid` from `Signature-Input` header and find the key
matching the `kid` value in the [RFC7517] response
5. Reconstruct the signature base from the request using the
Expand Down Expand Up @@ -2437,9 +2541,9 @@ Peter Szegedi, Ron Trompert, Benedikt Wegmann and Jonathan Xu.

We would also like to thank Ishank Arora, Gianmaria Del Monte,
Jörn Friedrich Dreyer, Richard Freitag, Hugo González Labrador,
Matthias Kraus, Maxence Lange, Lovisa Lugnegård, Sandro Mesterheide,
Antoon Prins and Björn Schießle for their direct contributions
to the specification.
Matthias Kraus, Maxence Lange, Lovisa Lugnegård, Thibault Meunier,
Sandro Mesterheide, Antoon Prins and Björn Schießle for their direct
contributions to the specification.

Over the years many more people have been involved in the development
of OCM. We would like to thank all of them for their contributions,
Expand Down
Loading