Skip to content

Commit

Permalink
feat: add local sign/verification for OCI layout directory (notarypro…
Browse files Browse the repository at this point in the history
  • Loading branch information
Two-Hearts authored Apr 19, 2023
1 parent 5cf34ac commit cd1a135
Show file tree
Hide file tree
Showing 29 changed files with 586 additions and 204 deletions.
2 changes: 1 addition & 1 deletion dir/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// file, err := dir.ConfigFS().Open(dir.PathTrustPolicy)
//
// - Get the path of trustpolicy.json:
// path, err := dir.ConfigFS().SysPath(dir.trustpolicy)
// path, err := dir.ConfigFS().SysPath(dir.PathTrustPolicy)
//
// - Set custom configurations directory:
// dir.UserConfigDir = '/path/to/configurations/'
Expand Down
4 changes: 2 additions & 2 deletions example_localSign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func Example_localSign() {
// signature mediaTypes are supported.
exampleSignatureMediaType := cose.MediaTypeEnvelope

// exampleSignOptions is an example of notation.SignOptions.
exampleSignOptions := notation.SignOptions{
// exampleSignOptions is an example of notation.SignerSignOptions.
exampleSignOptions := notation.SignerSignOptions{
SignatureMediaType: exampleSignatureMediaType,
SigningAgent: "example signing agent",
}
Expand Down
4 changes: 2 additions & 2 deletions example_localVerify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func Example_localVerify() {
// exampleSignatureEnvelope is a valid signature envelope.
exampleSignatureEnvelope := generateExampleSignatureEnvelope()

// exampleVerifyOptions is an example of notation.VerifyOptions
exampleVerifyOptions := notation.VerifyOptions{
// exampleVerifyOptions is an example of notation.VerifierVerifyOptions
exampleVerifyOptions := notation.VerifierVerifyOptions{
ArtifactReference: exampleArtifactReference,
SignatureMediaType: exampleSignatureMediaType,
}
Expand Down
6 changes: 3 additions & 3 deletions example_remoteSign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ func Example_remoteSign() {
exampleRepo := registry.NewRepository(remoteRepo)

// exampleSignOptions is an example of notation.SignOptions.
exampleSignOptions := notation.RemoteSignOptions{
SignOptions: notation.SignOptions{
ArtifactReference: exampleArtifactReference,
exampleSignOptions := notation.SignOptions{
SignerSignOptions: notation.SignerSignOptions{
SignatureMediaType: exampleSignatureMediaType,
},
ArtifactReference: exampleArtifactReference,
}

// remote sign core process
Expand Down
6 changes: 3 additions & 3 deletions example_remoteVerify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ func Example_remoteVerify() {
}
exampleRepo := registry.NewRepository(remoteRepo)

// exampleRemoteVerifyOptions is an example of notation.RemoteVerifyOptions.
exampleRemoteVerifyOptions := notation.RemoteVerifyOptions{
// exampleVerifyOptions is an example of notation.VerifyOptions.
exampleVerifyOptions := notation.VerifyOptions{
ArtifactReference: exampleArtifactReference,
MaxSignatureAttempts: 50,
}

// remote verify core process
// upon successful verification, the target OCI artifact manifest descriptor
// and signature verification outcome are returned.
targetDesc, _, err := notation.Verify(context.Background(), exampleVerifier, exampleRepo, exampleRemoteVerifyOptions)
targetDesc, _, err := notation.Verify(context.Background(), exampleVerifier, exampleRepo, exampleVerifyOptions)
if err != nil {
panic(err) // Handle error
}
Expand Down
20 changes: 19 additions & 1 deletion internal/envelope/envelope.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package envelope

import (
"errors"
"fmt"
"time"

"github.com/notaryproject/notation-core-go/signature"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

// MediaTypePayloadV1 is the supported content type for signature's payload.
const MediaTypePayloadV1 = "application/vnd.cncf.notary.payload.v1+json"
const (
MediaTypePayloadV1 = "application/vnd.cncf.notary.payload.v1+json"
AnnotationX509ChainThumbprint = "io.cncf.notary.x509chain.thumbprint#S256"
)

// Payload describes the content that gets signed.
type Payload struct {
Expand All @@ -35,3 +40,16 @@ func SanitizeTargetArtifact(targetArtifact ocispec.Descriptor) ocispec.Descripto
Annotations: targetArtifact.Annotations,
}
}

// SigningTime returns the signing time of a signature envelope blob
func SigningTime(signerInfo *signature.SignerInfo) (time.Time, error) {
// sanity check
if signerInfo == nil {
return time.Time{}, errors.New("failed to generate annotations: signerInfo cannot be nil")
}
signingTime := signerInfo.SignedAttributes.SigningTime
if signingTime.IsZero() {
return time.Time{}, errors.New("signing time is missing")
}
return signingTime.UTC(), nil
}
21 changes: 21 additions & 0 deletions internal/envelope/envelope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package envelope
import (
"errors"
"testing"
"time"

"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation-core-go/signature/cose"
Expand Down Expand Up @@ -85,6 +86,26 @@ func TestValidatePayloadContentType(t *testing.T) {
}
}

func TestSigningTime(t *testing.T) {
testTime, err := time.Parse(time.RFC3339, "2023-03-14T04:45:22Z")
if err != nil {
t.Fatal("failed to generate time")
}
signerInfo := signature.SignerInfo{
SignedAttributes: signature.SignedAttributes{
SigningTime: testTime,
},
}
signingTime, err := SigningTime(&signerInfo)
if err != nil {
t.Fatalf("failed to get signing time from signature: %v", err)
}
expectedSigningTime := "2023-03-14T04:45:22Z"
if signingTime.Format(time.RFC3339) != expectedSigningTime {
t.Fatalf("expected signing time: %q, got: %q", expectedSigningTime, signingTime.Format(time.RFC3339))
}
}

func isErrEqual(wanted, got error) bool {
if wanted == nil && got == nil {
return true
Expand Down
Binary file added internal/testdata/cose_signature.sig
Binary file not shown.
1 change: 1 addition & 0 deletions internal/testdata/jws_signature.sig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"payload":"eyJ0YXJnZXRBcnRpZmFjdCI6eyJkaWdlc3QiOiJzaGEyNTY6MTlkYmQyZTQ4ZTkyMTQyNmVlOGFjZTRkYzg5MmVkZmIyZWNkYzFkMWE3MmQ1NDE2YzgzNjcwYzMwYWNlY2VmMCIsIm1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5vY2kuaW1hZ2UubWFuaWZlc3QudjEranNvbiIsInNpemUiOjQ4MX19","protected":"eyJhbGciOiJQUzI1NiIsImNyaXQiOlsiaW8uY25jZi5ub3Rhcnkuc2lnbmluZ1NjaGVtZSJdLCJjdHkiOiJhcHBsaWNhdGlvbi92bmQuY25jZi5ub3RhcnkucGF5bG9hZC52MStqc29uIiwiaW8uY25jZi5ub3Rhcnkuc2lnbmluZ1NjaGVtZSI6Im5vdGFyeS54NTA5IiwiaW8uY25jZi5ub3Rhcnkuc2lnbmluZ1RpbWUiOiIyMDIzLTAzLTE0VDE2OjEwOjAyKzA4OjAwIn0","header":{"x5c":["MIIDQDCCAiigAwIBAgIBUTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxDzANBgNVBAoTBk5vdGFyeTEPMA0GA1UEAxMGYWxwaW5lMCAXDTAwMDgyOTEzNTAwMFoYDzIxMjMwODI5MTM1MDAwWjBOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxDzANBgNVBAoTBk5vdGFyeTEPMA0GA1UEAxMGYWxwaW5lMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAocg3qEsyNDDLfB8OHD4dhi+M1NPK1Asy5NX84c+gvacZuoPLTwmpOfm6nPt7GPPB9G7S6xxhFNbRxTYfYUjK+kaCj38XjBRf5lGewbSJKVkxQ82/axU70ceSW3JpazrageN9JUTZ/Jfi4MfnipITwcmMoiij8eGrHskjyVyZbJd0WMMKRDWVhLPUiPMVWt/4d7YtZItzacaQKtXmXgsTCTWpIols3gftNYjrQoMsUelUdD8vOAWN9J28/SyC+uSh/K1KfyUlbqufn4di8DEBxntP5wnXYbJL1jtjsUgExAVjQxT1zI59X36m3t3YKqCQh1cud02L5onObY6zj57N6QIDAQABoycwJTAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAC8AjBLy7EsRpi6oguCdFSb6nRGjvF17N+b6mDb3sARnB8T1pxvzTT26ya+AyWR+jjodEwbMIS+13lV+9qT2LwqlbOUNY519Pa2GRRY72JjeowWI3iKkKaMzfZUB7lRTGXdEuZApLbTO/3JVcR9ffu00N1UaAP9YGElSt4JDJYA9M+d/Qto+HiIsE0Kj+jdnwIYovPPOlryKOLfFb/r1GEq7n63xFZz83iyWNaZdsJ5N3YHxdOpkbBbCalOEBDJTjQKqeAYBLoANNU0OBslmqHCSBTEnhbqJHN6QKyF09ScOl5LwM1QsTl0UY5siGLAfj/jSf9OH9VLTPHOS8/N0Ka4="],"io.cncf.notary.signingAgent":"Notation/1.0.0"},"signature":"eac34SOR2yT0jJcqu2Kd_3TxOBLhRU06RW1ue39Yg_VJeB2v0hYMy-Ufb-q1edcmh9S6LwXX9yRe4xeWaH-rjO_34q3e3nhSYV2dMUx78uQs2Np_6QhdEr0RZwZw9Vw0Jxr-FuMD7gBGdIQlJKbA7HHzBV9B0Gyy6I_SWnQuXtoOBEsFVFHJrT6UeZd2LrUcNRtqvkwjP0Hydx1RwPJMiGHu-K2sCBMeZuRRMhOqDyC9ArqapcnHgu0Cemoiur1zADm2MdUBvqkUsfc6Ogh9gknfDEpO4z66Kogt4zA7hqCl2d_nKKY4rIIIsrGUDZ0C3d7eWLP_YRordU6Mbs2ozg"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:572996c3caeacea40b947911a9dda21516c082b5a64af30048a02a6f5eb956d4",
"size": 1035
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:63b65145d645c1250c391b2d16ebe53b3747c295ca8ba2fcb6b0cf064a4dc21c",
"size": 3374446
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"architecture":"amd64","config":{"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/bash"],"ArgsEscaped":true,"OnBuild":null},"created":"2023-02-11T04:46:42.558343068Z","history":[{"created":"2023-02-11T04:46:42.449083344Z","created_by":"/bin/sh -c #(nop) ADD file:40887ab7c06977737e63c215c9bd297c0c74de8d12d16ebdf1c3d40ac392f62d in / "},{"created":"2023-02-11T04:46:42.558343068Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true},{"created":"2023-02-11T04:46:42.558343068Z","created_by":"CMD [\"/bin/bash\"]","comment":"buildkit.dockerfile.v0","empty_layer":true}],"moby.buildkit.buildinfo.v1":"eyJmcm9udGVuZCI6ImRvY2tlcmZpbGUudjAiLCJzb3VyY2VzIjpbeyJ0eXBlIjoiZG9ja2VyLWltYWdlIiwicmVmIjoiZG9ja2VyLmlvL2xpYnJhcnkvYWxwaW5lOmxhdGVzdCIsInBpbiI6InNoYTI1Njo2OTY2NWQwMmNiMzIxOTJlNTJlMDc2NDRkNzZiYzZmMjVhYmViNTQxMGVkYzFjN2E4MWExMGJhM2YwZWZiOTBhIn1dfQ==","os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:7cd52847ad775a5ddc4b58326cf884beee34544296402c6292ed76474c686d39"]}}
Binary file not shown.
19 changes: 19 additions & 0 deletions internal/testdata/oci-layout/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:19dbd2e48e921426ee8ace4dc892edfb2ecdc1d1a72d5416c83670c30acecef0",
"size": 481,
"annotations": {
"io.containerd.image.name": "docker.io/library/alpine:v2",
"org.opencontainers.image.created": "2023-03-13T02:31:43Z",
"org.opencontainers.image.ref.name": "v2"
},
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
]
}
9 changes: 9 additions & 0 deletions internal/testdata/oci-layout/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"Config": "blobs/sha256/572996c3caeacea40b947911a9dda21516c082b5a64af30048a02a6f5eb956d4",
"RepoTags": null,
"Layers": [
"blobs/sha256/63b65145d645c1250c391b2d16ebe53b3747c295ca8ba2fcb6b0cf064a4dc21c"
]
}
]
1 change: 1 addition & 0 deletions internal/testdata/oci-layout/oci-layout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"imageLayoutVersion":"1.0.0"}
Loading

0 comments on commit cd1a135

Please sign in to comment.