oasis-tcs / openc2-oc2ls

OASIS OpenC2 TC: GitHub repository used to propose and track changes to the OpenC2 Language Specification as new working draft level revisions are created and the associated CSDs mature
https://github.com/oasis-tcs/openc2-oc2ls
Other
15 stars 19 forks source link

Multiple responses and Messages #353

Closed davaya closed 2 years ago

davaya commented 4 years ago

1) the Actuator Profile subcommittee needs to identify the source of multiple responses to a command: "An issue for some environment is determining which actuator responded if an orchestrator receives three responses that appear similar (200 ok)."

2) Plugfest Issue 11 (https://github.com/oasis-tcs/openc2-usecases/blob/master/Cybercom-Plugfest/Plugfest-Outcomes.md#issue-11-content-balance-between-https-headers-and-openc2-message-content) identified a desire to include message element information in the JSON body of HTTP commands and responses.

These two issues are related and have the same solution - the Language Specification can define an OpenC2-Message structure containing the message elements listed in Section 3.2, and the HTTP transfer spec can create a new Content-Type to carry that structure:

OpenC2-Message = Record {
    1 content         Content,                  // Message body as specified by msg_type (the ID/Name of Content)
    2 request_id      String optional,          // A unique identifier created by Producer and copied by Consumer into responses
    3 created         Date-Time optional,       // Creation date/time of the content
    4 from            String optional,          // Authenticated identifier of the creator of / authority for a request
    5 to              ArrayOf(String) optional  // Authenticated identifier(s) of the authorized recipient(s) of a message
}

Content = Choice {
    1 request         OpenC2-Command,           // The initiator of a two-way message exchange.
    2 response        OpenC2-Response,          // A response linked to a request in a two-way message exchange.
    3 notification    OpenC2-Notification       // A (one-way) message that is not a request or response.  (Placeholder)
}

The sender of each response to an OpenC2 command includes its identifier in the message "from" field, allowing responses from different actuators to be identified.

Vasileios-Mavroeidis commented 4 years ago

+1

That way we also reduce the work for mapping OpenC2 message elements to transfer protocol headers

jmbrule commented 4 years ago

I like the approach described by davaya. This is actually quite a departure from where we are now, but suspect that the notification message type to be quite useful.
May I suggest that we make this a topic on the next LSC and if we can get general consensus, then move it into the next revision of the spec?

Vasileios-Mavroeidis commented 4 years ago

It should also be discussed on the next IC-SC as it is one of the points @dlemire60 indicated for moving forward with the transports.

dlemire60 commented 4 years ago

I am in favor of this change and think that the self-complete message should be our default.

However, it would be good if we could include some approach to addressing Plug Fest issue #1, Authentication, concurrently with PF issue #11 and in a transfer protocol-agnostic way. The suggestion for issue #1 offered in the Plug Fest issues focuses on the HTTPS Transfer Spec, but it would be better to have a general solution that is transfer protocol-agnostic and provides authentication when a Command message traverses a path encompassing more than one transfer protocol.

John-Mark Gurney had suggested this JSON Signature Format as a solution to the authentication need. It has the advantage of being a good fit to our needs ("a JSF signature is intended to be an integral part of a JSON object with message centric systems ... as the primary target"), at least for JSON serialization, and the disadvantage of not being under the auspices of any formal standards body.

dmg2 commented 4 years ago

I am very much in favor of this change in light of the recent plugfest events. As vaselios mentioned it has the potential to reduce the work of mapping transport headers but also allows us to continue to be transport agnostic for transport types that do not support custom headers or contain mapabale headers at all. We recently had this issue with mqtt 3.1

dmg2 commented 4 years ago

In reference to issue #362,it would be helpful to have a "OpenC2-Message" include a field "signature" which can hold both a message digest and the public certificate of the sender.

davaya commented 4 years ago

I support defining an appropriate signature field.

The data covered by the message digest would have to be specified (Content only, Content plus the content type (request/response/notification), or the entire Message including headers but excluding the signature header. As would a canonical form of that data (presumably verbose JSON with Record fields in the defined order, Map fields sorted by name or ID, all whitespace outside of strings stripped, etc).

sparrell commented 3 years ago

please include some JSON examples

dmg2 commented 3 years ago

I did create an example in my signature document that is relevant here. I am including it as a use-case I worked on. That said, take it with a grain of salt because it was based on this very preliminary version of the payload structure, I am unsure if the original poster planned to modify it: https://github.com/dmg2/OpenC2-Signatures (notice I added content_type, which was not necessarily the original posters intent, and may not be needed, again it was just a usecase)

davaya commented 3 years ago

I plan to submit a pull request to update section 3.2 of the language spec to define a Message structure. This version adds a "body" field that allows new specifications to define or reference new types of message content.

OpenC2-Message = Map
    1 body            Body                      // Message body
    2 request_id      String optional           // A unique identifier created by Producer and copied by Consumer into responses
    3 created         Date-Time optional        // Creation date/time of the content
    4 from            String optional           // Authenticated identifier of the creator of / authority for a request
    5 to              ArrayOf(String) optional  // Authenticated identifier(s) of the authorized recipient(s) of a message

Body = Choice                                   // Registry of message content formats
   1 openc2           OpenC2-Content            // request, response, or notification defined in OpenC2 Language Spec
   2 xyz              XYZ-Content               // (example of how a future specification would add new content - not included in PR)

OpenC2-Content = Choice
    1 request         OpenC2-Command            // The initiator of a two-way message exchange.
    2 response        OpenC2-Response           // A response linked to a request in a two-way message exchange.
    3 notification    OpenC2-Notification       // A one-way message that is not a request or response.  (Placeholder)

The message signature example modified to use this structure removes the "content-type" header, replaces "content" with "body" as the reserved name for the field that isn't a header, and adds "openc2" to specify the content type. As an example, a future version of the OpenC2 language spec might define a structure containing a list of commands. That structure is different from a single OpenC2-Command and would need a new property name such as "bundle", but it wouldn't supersede the current OpenC2-Command specified by the "openc2" property name.

{
    "request_id": "95ad511c-3339-4111-9c47-9156c47d37d3",
    "created": 1595268027000,
    "from": "Producer1@example.com",
    "to": ["consumer1@example.com", "consumer2@example.com", "consumer3@example.com"],
    "body": {
        "openc2": {
            "request": {
                "action": "deny",
                "target": {
                    "file": {
                        "hashes": {
                            "sha256": "22fe72a34f006ea67d26bb7004e2b6941b5c3953d43ae7ec24d41b1a928a6973"
                        }
                    }
                }
            }
        }
    }
}

An equivalent structure would enclose the headers in a "headers" property, removing the need for for a reserved name for a "content" or "body" field mixed in with the real headers. This seems both more logical and more obvious to document. Comments?

OpenC2-Message = Record
   1 headers  Headers
   2 body     Body
{
    "headers": {
        "request_id": "95ad511c-3339-4111-9c47-9156c47d37d3",
        "created": 1595268027000,
        "from": "Producer1@example.com",
        "to": ["consumer1@example.com", "consumer2@example.com", "consumer3@example.com"]
    },
    "body": {
        "openc2": {
            "request": {
                "action": "deny",
                "target": {
                    "file": {
                        "hashes": {
                            "sha256": "22fe72a34f006ea67d26bb7004e2b6941b5c3953d43ae7ec24d41b1a928a6973"
                        }
                    }
                }
            }
        }
    }
}
davaya commented 2 years ago

Need to create a "Signature" issue referencing Danny's comment . Since the Message structure has been created, this issue can be closed.

dlemire60 commented 2 years ago

There is a signature issue: #362. I don't think there's a corresponding PR. But there is language describing a signature solution that can be turned into a PR.

EDIT: @dmg2 has a thorough write up here: https://github.com/dmg2/OpenC2-Signatures

dlemire60 commented 2 years ago

Discussed in triage; PR #370 addressed the message structure issue. Issue #362 is where signatures will be address. This issue is candidate for closure.