Skip to content

Commit

Permalink
Remove signed HTTP request support (#5137)
Browse files Browse the repository at this point in the history
  • Loading branch information
achamayou authored Apr 19, 2023
1 parent defca11 commit 5b1c504
Show file tree
Hide file tree
Showing 51 changed files with 155 additions and 2,092 deletions.
3 changes: 1 addition & 2 deletions .daily_canary
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
--- ___
(- -) (o o) | Y & +-
( V ) z O z O +---=---'
/--x-m- /--m-m---xXx--/--yY-----

/--x-m- /--m-m---xXx--/--yY-----
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Removed

- Support for HTTP request signing has been removed (#5137). Governance requests must use COSE Sign1 signing instead, see [documentation](https://microsoft.github.io/CCF/main/use_apps/issue_commands.html#cose-sign1) for details.
- Removed experimental 2tx reconfiguration mode, and the associated "reconfiguration_type" config option (#5179).

## [4.0.0-rc1]
Expand Down
15 changes: 0 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -512,21 +512,6 @@ if(BUILD_TESTS)
${CMAKE_CURRENT_SOURCE_DIR}/src/node/rpc/test/tx_status_test.cpp
)

add_unit_test(
proposal_id_test ${CMAKE_CURRENT_SOURCE_DIR}/src/js/wrap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/node/rpc/test/proposal_id_test.cpp
)
target_link_libraries(
proposal_id_test
PRIVATE ${CMAKE_THREAD_LIBS_INIT}
http_parser.host
sss.host
ccf_endpoints.host
ccfcrypto.host
quickjs.host
ccf_kv.host
)

add_unit_test(
node_frontend_test ${CMAKE_CURRENT_SOURCE_DIR}/src/js/wrap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/node/rpc/test/node_frontend_test.cpp
Expand Down
1 change: 0 additions & 1 deletion cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ set(CCF_ENDPOINTS_SOURCES
${CCF_DIR}/src/endpoints/authentication/cert_auth.cpp
${CCF_DIR}/src/endpoints/authentication/empty_auth.cpp
${CCF_DIR}/src/endpoints/authentication/jwt_auth.cpp
${CCF_DIR}/src/endpoints/authentication/sig_auth.cpp
${CCF_DIR}/src/enclave/enclave_time.cpp
${CCF_DIR}/src/indexing/strategies/seqnos_by_key_bucketed.cpp
${CCF_DIR}/src/indexing/strategies/seqnos_by_key_in_memory.cpp
Expand Down
7 changes: 0 additions & 7 deletions doc/build_apps/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ Policies
.. doxygenvariable:: ccf::user_cert_auth_policy
:project: CCF

.. doxygenvariable:: ccf::user_signature_auth_policy
:project: CCF

.. doxygenvariable:: ccf::jwt_auth_policy
:project: CCF

Expand All @@ -77,10 +74,6 @@ Identities
:project: CCF
:members:

.. doxygenstruct:: ccf::UserSignatureAuthnIdentity
:project: CCF
:members:

Supporting Types
----------------

Expand Down
2 changes: 0 additions & 2 deletions doc/build_apps/js_app_bundle.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ Each endpoint object contains the following information:
is executed. An empty list indicates an unauthenticated endpoint which can be called by anyone. Possible entries are:

- ``"user_cert"``
- ``"user_signature"``
- ``"member_cert"``
- ``"member_signature"``
- ``"jwt"``
- ``"no_auth"``

Expand Down
28 changes: 0 additions & 28 deletions doc/governance/accept_recovery.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,6 @@ A member proposes to recover the network and other members can vote on the propo
"state": "Accepted"
}
Or alternatively, with the old signature method:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/proposals --cacert service_cert.pem --signing-key member1_privk.pem --signing-cert member1_cert.pem --data-binary @transition_service_to_open.json -H "content-type: application/json"
{
"ballot_count": 0,
"proposal_id": "1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377",
"proposer_id": "d5d7d5fed6f839028456641ad5c3df18ce963bd329bd8a21df16ccdbdbba1eb1",
"state": "Open"
}
$ scurl.sh https://<ccf-node-address>/gov/proposals/1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377/ballots --cacert service_cert.pem --signing-key member2_privk.pem --signing-cert member2_cert.pem --data-binary @vote_accept.json -H "content-type: application/json"
{
"ballot_count": 1,
"proposal_id": "1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377",
"proposer_id": "d5d7d5fed6f839028456641ad5c3df18ce963bd329bd8a21df16ccdbdbba1eb1",
"state": "Open"
}
$ scurl.sh https://<ccf-node-address>/gov/proposals/1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377/ballots --cacert service_cert.pem --signing-key member3_privk.pem --signing-cert member3_cert.pem --data-binary @vote_accept.json -H "content-type: application/json"
{
"ballot_count": 2,
"proposal_id": "1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377",
"proposer_id": "d5d7d5fed6f839028456641ad5c3df18ce963bd329bd8a21df16ccdbdbba1eb1",
"state": "Accepted"
}
Once the proposal to recover the network has passed under the rules of the :term:`Constitution`, the recovered service is ready for members to submit their recovery shares.

Note that the ``transition_service_to_open`` proposal takes two parameters: the previous and the next service identity (x509 certificates in PEM format). This is to ensure that the correct network is recovered and to facilitate auditing, as well as to avoid forks. The previous service identity is used to validate the snapshot the recovery node is started from; CCF will refuse to start from a snapshot where the signing node certificate is not endorsed by the previous service identity. Since both identities are recorded on the ledger with the proposal, it is always clear at which point the identity changed.
Expand Down
9 changes: 1 addition & 8 deletions doc/governance/adding_member.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,14 @@ First, the new member should update and retrieve the latest state digest via the
}
Then, the new member should sign the state digest returned by the :http:POST:`/gov/ack/update_state_digest` via the :http:POST:`/gov/ack` endpoint, using either the ``ccf_cose_sign1`` or ``scurl.sh`` utilities:
Then, the new member should sign the state digest returned by the :http:POST:`/gov/ack/update_state_digest` via the :http:POST:`/gov/ack` endpoint, using the ``ccf_cose_sign1`` utility:

.. code-block:: bash
$ ccf_cose_sign1 --ccf-gov-msg-type ack --ccf-gov-msg-created_at `date -Is` --signing-key new_member_privk.pem --signing-cert new_member_cert.pem --content request.json | \
curl https://<ccf-node-address>/gov/ack --cacert service_cert.pem --data-binary @- -H "content-type: application/cose"
true
Or alternatively:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/ack --cacert service_cert.pem --signing-key new_member_privk.pem --signing-cert new_member_cert.pem --header "Content-Type: application/json" --data-binary @request.json
true
Once the command completes, the new member becomes active and can take part in governance operations (e.g. creating a new proposal or voting for an existing one). You can verify the activation of the member at `/gov/members`.

.. code-block:: bash
Expand Down
56 changes: 0 additions & 56 deletions doc/governance/common_member_operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,34 +80,6 @@ To limit the scope of key compromise, members of the consortium can refresh the
"state": "Accepted"
}
Or alternatively, with the old signature method:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/proposals --cacert service_cert.pem --signing-key member1_privk.pem --signing-cert member1_cert.pem --data-binary @trigger_ledger_rekey.json -H "content-type: application/json"
{
"ballot_count": 0,
"proposal_id": "2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Open"
}
$ scurl.sh https://<ccf-node-address>/gov/proposals/2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e/ballots --cacert service_cert.pem --signing-key member2_privk.pem --signing-cert member2_cert.pem --data-binary @vote_accept_1.json -H "content-type: application/json"
{
"ballot_count": 1,
"proposal_id": "2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Open"
}
$ scurl.sh https://<ccf-node-address>/gov/proposals/2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e/ballots --cacert service_cert.pem --signing-key member3_privk --signing-cert member3_cert.pem --data-binary @vote_accept_1.json -H "content-type: application/json"
{
"ballot_count": 2,
"proposal_id": "2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Accepted"
}
Once the proposal is accepted (``"state": "Accepted"``) it is immediately enacted. All subsequent transactions will be encrypted with a fresh new ledger encryption key.

Updating Recovery Threshold
Expand Down Expand Up @@ -162,34 +134,6 @@ The number of member shares required to restore the private ledger (``recovery_t
"state": "Accepted"
}
Or alternatively, with the old signature method:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/proposals --cacert service_cert.pem --signing-key member1_privk.pem --signing-cert member1_cert.pem --data-binary @set_recovery_threshold.json -H "content-type: application/json"
{
"ballot_count": 0,
"proposal_id": "b9c08b3861395eca904d913427dcb436136e277cf4712eb14e9e9cddf9d231a8",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Open"
}
$ scurl.sh https://<ccf-node-address>/gov/proposals/b9c08b3861395eca904d913427dcb436136e277cf4712eb14e9e9cddf9d231a8/ballots --cacert service_cert.pem --signing-key member2_privk.pem --signing-cert member2_cert.pem --data-binary @vote_accept_1.json -H "content-type: application/json"
{
"ballot_count": 1,
"proposal_id": "b9c08b3861395eca904d913427dcb436136e277cf4712eb14e9e9cddf9d231a8",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Open"
}
$ scurl.sh https://<ccf-node-address>/gov/proposals/b9c08b3861395eca904d913427dcb436136e277cf4712eb14e9e9cddf9d231a8/ballots --cacert service_cert.pem --signing-key member3_privk.pem --signing-cert member3_cert.pem --data-binary @vote_accept_1.json -H "content-type: application/json"
{
"ballot_count": 2,
"proposal_id": "b9c08b3861395eca904d913427dcb436136e277cf4712eb14e9e9cddf9d231a8",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Accepted"
}
.. note:: The new recovery threshold has to be in the range between 1 and the current number of active recovery members.

Renewing Node Certificate
Expand Down
43 changes: 3 additions & 40 deletions doc/governance/hsm_keys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,45 +117,6 @@ Like ``ccf_cose_sign1``, the output can be sent directly to the service via curl
"state": "Open"
}
HTTP Signing
~~~~~~~~~~~~

The ``scurl.sh`` script can be used with the ``--print-digest-to-sign`` option to print the SHA384 to be signed as well as the required headers for HTTP signatures (following the `draft-cavage-http-signatures-12 <https://tools.ietf.org/html/draft-cavage-http-signatures-12>`_ scheme):

.. code-block:: bash
# First, retrieve the hash to be signed
$ scurl.sh https://<ccf-node-address>/gov/<endpoint> -X [GET|POST] --signing-cert $IDENTITY_CERT_NAME.pem --print-digest-to-sign
Hash to sign: <hash_to_sign> # To be signed by AKV
Request headers:
-H 'Digest: SHA-256=...'
-H 'Authorization: Signature keyId="...",algorithm="hs2019",headers="(request-target) digest content-length",signature="<insert_base64_signature_here>"' # Replace signature with AKV signature here
-H 'content-length: 0'
# Then, retrieve the kid url for the identity key
$ export IDENTITY_AKV_KID=$(az keyvault key show --vault-name $VAULT_NAME --name $IDENTITY_CERT_NAME --query key.kid --output tsv)
# Then, sign the request hash to be signed (as output by scurl.sh --print-digest-to-sign)
$ export base64url_signature=$(curl -s -X POST $IDENTITY_AKV_KID/sign?api-version=7.1 --data '{alg: "ES384", "value": "<hash_to_sign>"}' -H "Authorization: Bearer ${AZ_TOKEN}" -H "Content-Type: application/json" | jq -r .value)
.. note:: The signatures returned by AKV are returned as a `JWS signature <https://tools.ietf.org/html/rfc7518#section-3.4>`_ and encoded in `base64url <https://tools.ietf.org/html/rfc4648#section-5>`_ format and are not directly compatible with the signatures supported by CCF.

The :ccf_repo:`jws_to_der.py </doc/governance/jws_to_der.py>` Python script can be used to convert a JWS signature generated by AKV to a DER signature compatible with CCF:

.. code-block:: bash
$ pip install pyasn1
$ export ccf_signature=$(python3.8 jws_to_der.py $base64url_signature)
Finally, the signed HTTP request can be issued, using the request headers printed by ``scurl.sh --print-digest-to-sign``:

.. code-block:: bash
$ curl https://<ccf-node-address>/gov/<endpoint> -X [GET|POST] --cert $IDENTITY_CERT_NAME.pem \
-H 'Digest: SHA-256=...' \
-H 'Authorization: Signature keyId="...",algorithm="hs2019",headers="(request-target) digest content-length",signature="$ccf_signature"' \
-H 'content-length: <content-length>'
Recovery Share Decryption
-------------------------

Expand All @@ -168,4 +129,6 @@ The retrieved encrypted recovery share can be decrypted with the encryption key
$ az keyvault key decrypt --vault-name $VAULT_NAME --name $ENCRYPTION_KEY_NAME --algorithm RSA-OAEP-256 --value <base64_encrypted_share>
# Outputs base64 decrypted share
The decrypted recovery share can then be submitted to the CCF recovered service (see :ref:`governance/accept_recovery:Submitting Recovery Shares`).
The decrypted recovery share can then be submitted to the CCF recovered service (see :ref:`governance/accept_recovery:Submitting Recovery Shares`).

.. warning:: HTTP request signing could be used in previous versions of CCF, but has been removed as of 4.0, in favour of COSE Sign1.
53 changes: 0 additions & 53 deletions doc/governance/open_network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,6 @@ Then, the certificates of trusted users should be registered in CCF via the memb
"state": "Open"
}
Or alternatively, with the old signature method:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/proposals --cacert service_cert.pem --signing-key member0_privk.pem --signing-cert member0_cert.pem --data-binary @set_user.json -H "content-type: application/json"
{
"ballot_count": 0,
"proposal_id": "f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Open"
}
Other members are then allowed to vote for the proposal, using the proposal id returned to the proposer member. They may submit an unconditional approval, or their vote may query the current state and the proposed actions. These votes `must` be signed.

.. code-block:: bash
Expand All @@ -68,23 +56,6 @@ Other members are then allowed to vote for the proposal, using the proposal id r
"state": "Open"
}
Or alternatively, with the old signature method:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/proposals/f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253/ballots --cacert service_cert.pem --signing-key member1_privk.pem --signing-cert member1_cert.pem --data-binary @vote_accept.json -H "content-type: application/json"
{
"ballot_count": 1,
"proposal_id": "f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Open"
}
$ cat vote_conditional.json
{
"ballot": "export function vote (proposal, proposerId) { return proposerId == \"2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0\" }"
}
.. code-block:: bash
$ ccf_cose_sign1 --ccf-gov-msg-type ballot --ccf-gov-msg-created_at `date -Is` --ccf-gov-msg-proposal_id f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253 --signing-key member0_privk.pem --signing-cert member0_cert.pem --content vote_conditional.json | \
Expand All @@ -96,18 +67,6 @@ Or alternatively, with the old signature method:
"state": "Accepted"
}
Or alternatively, with the old signature method:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/proposals/f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253/ballots --cacert service_cert.pem --signing-key member2_privk.pem --signing-cert member2_cert.pem --data-binary @vote_conditional.json -H "content-type: application/json"
{
"ballot_count": 2,
"proposal_id": "f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Accepted"
}
The user is successfully added once the proposal has received enough votes under the rules of the :term:`Constitution` (indicated by the response body showing a transition to state ``Accepted``).

The user can then make user RPCs.
Expand Down Expand Up @@ -193,18 +152,6 @@ Once users are added to the opening network, members should create a proposal to
"state": "Open"
}
Or alternatively, with the old signature method:

.. code-block:: bash
$ scurl.sh https://<ccf-node-address>/gov/proposals --cacert service_cert.pem --signing-key member0_privk.pem --signing-cert member0_cert.pem --data-binary @transition_service_to_open.json -H "content-type: application/json"
{
"ballot_count": 0,
"proposal_id": "77374e16de0b2d61f58aec84d01e6218205d19c9401d2df127d893ce62576b81",
"proposer_id": "2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0",
"state": "Open"
}
Other members are then able to vote for the proposal using the returned proposal id.

Once the proposal has received enough votes under the rules of the :term:`Constitution` (ie. ballots which evaluate to ``true``), the network is opened to users. It is only then that users are able to execute transactions on the business logic defined by the enclave file (``enclave.file`` configuration entry).
Loading

0 comments on commit 5b1c504

Please sign in to comment.