Skip to content

Commit

Permalink
Support arbitrary blob signing (#283)
Browse files Browse the repository at this point in the history
Support Arbitrary Blob Signing
---------

Signed-off-by: rgnote <[email protected]>
  • Loading branch information
rgnote authored Feb 26, 2024
1 parent f52bc09 commit f2d8f8f
Show file tree
Hide file tree
Showing 8 changed files with 368 additions and 134 deletions.
4 changes: 4 additions & 0 deletions media/blob-signature-specification.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
22 changes: 20 additions & 2 deletions specs/signature-envelope-cose.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This specification implements the [Notary Project signature specification](signa
CBOR Object Signing and Encryption (COSE). COSE ([RFC8152](https://datatracker.ietf.org/doc/html/rfc8152)) is a CBOR based envelope format for digital signatures over any type of payload (e.g. CBOR, JSON, binary).
Notary Project specifically supports [COSE_Sign1_Tagged](https://datatracker.ietf.org/doc/html/rfc8152#section-4.2) as a signature envelope.

## Storage
## OCI Signature Storage

A COSE signature envelope will be stored in an OCI registry as a blob, and referenced in the signature manifest as a layer blob with `mediaType` of `"application/cose"`.

Expand Down Expand Up @@ -36,12 +36,15 @@ Signature Manifest Example
}
}
```
## Blob Signature Storage

For detached signatures associated with arbitrary blobs, a COSE signature envelope will be stored on the file system as a binary file with `cose` as the file extension.

## COSE Payload

The COSE envelope contains the [Notary Project signature Payload](./signature-specification.md#payload).

Example of the Notary Project signature payload:
Example of the Notary Project OCI signature payload:

```jsonc
{
Expand All @@ -56,6 +59,21 @@ Example of the Notary Project signature payload:
}
```

Example of the Notary Project blob signature payload:

```jsonc
{
"targetArtifact": {
"mediaType": "application/octet-stream",
"digest": "sha256:2f3a23b6373afb134ddcd864be8e037e34a662d090d33ee849471ff73c873345",
"size": 1024,
"annotations": {
"io.wabbit-networks.buildId": "123" // user defined metadata
}
}
}
```

## Protected Header

The COSE envelope for the Notary Project signature uses the following header parameters:
Expand Down
23 changes: 21 additions & 2 deletions specs/signature-envelope-jws.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This specification implements the [Notary Project signature specification](./signature-specification.md) using JSON Web Signature (JWS). JWS ([RFC7515](https://datatracker.ietf.org/doc/html/rfc7515)) is a JSON based envelope format for digital signatures over any type of payload (e.g. JSON, binary). JWS is the Notary Project supported signature format and specifically uses the *JWS JSON Serialization* representation.

## Storage
## OCI Signature Storage

A JWS signature envelope will be stored in an OCI registry as a layer, and referenced in the signature manifest as a layer blob with `mediaType` of `"application/jose+json"`.

Expand Down Expand Up @@ -35,11 +35,15 @@ Signature Manifest Example
}
```

## Blob Signature Storage

For detached signatures associated with blobs, a JWS signature envelope will be stored on the file system with `jws` as the file extension.

## JWS Payload

The JWS envelope contains the [Notary Project signature payload](./signature-specification.md#payload).

Example of the Notary Project signature payload
Example of the Notary Project OCI signature payload

```jsonc
{
Expand All @@ -54,6 +58,21 @@ Example of the Notary Project signature payload
}
```

Example of the Notary Project blob signature payload:

```jsonc
{
"targetArtifact": {
"mediaType": "application/octet-stream",
"digest": "sha256:2f3a23b6373afb134ddcd864be8e037e34a662d090d33ee849471ff73c873345",
"size": 1024,
"annotations": {
"io.wabbit-networks.buildId": "123" // user defined metadata
}
}
}
```

## Protected Headers

The JWS envelope for the Notary Project signature uses following headers
Expand Down
210 changes: 132 additions & 78 deletions specs/signature-specification.md

Large diffs are not rendered by default.

56 changes: 50 additions & 6 deletions specs/signing-and-verification-workflow.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Signing and Verification Workflow

This document describes the workflow of signing and verifying OCI artifacts.
This document describes workflows for signing and verifying OCI artifacts and arbitrary blobs.

## Signing workflow
## OCI artifact signing workflow

The user wants to sign an OCI artifact and push the signature to a repository.

Expand All @@ -27,7 +27,7 @@ The user wants to sign an OCI artifact and push the signature to a repository.

The user pushes the OCI artifact to the repository before the signature generation process as the signature reference must exist for the signature push to succeed.

## Verification workflow
## OCI artifact verification workflow

The user wants to pull an OCI artifact only if they are signed by a trusted publisher and the signature is valid.

Expand All @@ -41,7 +41,7 @@ The user wants to pull an OCI artifact only if they are signed by a trusted publ

### Verification Steps

1. **Should implementations of this specification verify the signature? :** Depending upon [trust-policy](./trust-store-trust-policy.md#trust-policy) configuration, determine whether implementations of this specification need to verify the signature or not.
1. **Should implementations of this specification verify the signature? :** Depending upon [trust-policy](./trust-store-trust-policy.md#oci-trust-policy) configuration, determine whether implementations of this specification need to verify the signature or not.
If signature verification should be skipped for the given artifact, skip the below steps and directly jump to step 4.
1. **Get signature artifact descriptors:** Using the [OCI Distribution Referrers API](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers) download the Notary Project signature manifest descriptors.
The `artifactType` parameter is set to the Notary Project signature's artifact type `application/vnd.cncf.notary.signature`.
Expand All @@ -64,9 +64,53 @@ The user wants to pull an OCI artifact only if they are signed by a trusted publ
1. Verify the signature envelope using trust-store and trust-policy as mentioned in [signature evaluation](./trust-store-trust-policy.md#signature-evaluation) section.
1. If the signature verification fails, skip the below steps and move to the next signature artifact descriptor(step 3.1).
If all signature artifact descriptors have already been processed, fail the signature verification and exit.
1. If signature verification succeeds, compare the digest derived from the given OCI artifact reference with the signed digest present in the signature envelope's payload.
If digests are equal, signature verification is considered successful.
1. If signature verification succeeds, compare the digest derived from the given OCI artifact reference with the signed digest present in the signature envelope's payload. Also, if there are any user-defined/supplied custom annotations, match them as well.
If digests and custom annotations are equal, signature verification is considered successful.
Otherwise, move to the next signature artifact descriptor(step 3.1).
If all signature artifact descriptors have already been processed, fail the signature verification and exit.
1. **Get OCI artifact:** Using the verified digest, download the OCI artifact.
This step is not in the purview of Notary Project.

## Blob signing workflow

The user wants to sign an arbitrary blob with a detached signature.

### Signing Prerequisites

- User has access to the signing certificate and private key or a remote signing service through a notation plug-in.

### Signing Steps

1. **Generate signature:** Using notation CLI or any other compliant signing tool, sign the blob. The signing tool should follow the following guideline.
1. Construct the blob payload as defined in [`signature specification`](./signature-specification.md#payload)
1. Verify that the signing certificate is valid and satisfies [certificate requirements](./signature-specification.md#certificate-requirements).
1. Verify that the signing algorithm satisfies [algorithm requirements](./signature-specification.md#signature-algorithm-requirements).
1. Generate signature.
1. Generate signature using a signature format specified in [supported signature envelopes](./signature-specification.md#supported-signature-envelopes). Also, as part of this step, the user-defined/supplied custom attributes should be added to the annotations of the signature payload.
1. If the user wants to timestamp the signature, obtain an [RFC-3161](https://datatracker.ietf.org/doc/html/rfc3161.html) compliant timestamp for the signature generated in the previous step. Otherwise, continue to the next step.
1. Verify that the timestamp signing certificate satisfies [certificate requirements](./signature-specification.md#certificate-requirements).
1. Verify that the timestamp signing algorithm satisfies [algorithm requirements](./signature-specification.md#signature-algorithm-requirements).
1. Embed timestamp to the signature envelope.
1. **Save the signature envelope:** Save the signature envelope generated in the previous step to a file. File extension should be the original blob file name plus `.sig.jws` for JWS signatures and `.sig.cose` for COSE signatures.

## Arbitrary blob verification workflow

The user wants to consume an arbitrary blob only if it was signed by a trusted publisher and the signature associated with the blob is valid.

### Verification Prerequisites

- User has the blob that they want to consume, along with its detached signature.
- User has configured [trust store and trust policy](./trust-store-trust-policy.md) required for signature verification.

### Verification Steps

1. **Should implementations of this specification verify the signature? :** Depending upon [trust-policy](./trust-store-trust-policy.md#blob-trust-policy) configuration, determine whether implementations of this specification need to verify the signature or not.
If signature verification should be skipped for the given blob, skip the below steps.
1. **Verify the detached signature:**
1. Parse and validate the signature envelope using the detached signature's file extension as the envelope type.
1. Verify the signature envelope using trust-store and trust-policy as mentioned in [signature evaluation](./trust-store-trust-policy.md#signature-evaluation) section.
1. If the signature verification fails, exit.
1. Calculate the blob's size and verify that it matches the size present in `targetArtifact.size`. Fail signature verification if there is a mismatch.
1. If provided by the user, verify blob's media type to the one present in `targetArtifact.mediaType`. Fail signature verification if there is a mismatch.
1. Calculate the digest of the blob using the digest algorithm deduced from signing certificate's public key (see [Algorithm Selection](./signature-specification.md#algorithm-selection)) and match it with the digest specified at `targetArtifact.digest`. Fail signature verification if there is a mismatch.
1. If there any user-defined/supplied custom annotations, match them against the ones present in `targetArtifact.annotations`. If they match, signature verification is considered successful.
2 changes: 1 addition & 1 deletion specs/signing-scheme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Similarly, a signing authority (SA) will need to demonstrate signing keys were o

* A signature envelope can only specify one Signing Scheme
* When Notary Project supports an additional Signing Scheme
* Existing signed artifacts MUST be resigned if they need to be verified using the new signing scheme defined verification process.
* Existing signed artifacts MUST be re-signed if they need to be verified using the new signing scheme defined verification process.
* Existing clients used by verifying entity MUST be updated to newer versions that support verifying signatures that use the new signing scheme, otherwise the signatures with newer signing schemes which are unknown to existing clients will fail signature verification. Signatures that use older signing schemes which are known to existing clients will continue to verify correctly.
* The language of the [Notary Project verification policy](./trust-store-trust-policy.md) in *trustpolicy.json* MAY have breaking changes to support newer concepts/configuration elements introduced by the new signing scheme.
The breaking changes are addressed by introducing new major version in the versioned *trustpolicy.json* .
Expand Down
Loading

0 comments on commit f2d8f8f

Please sign in to comment.