2024-08-12 14:49:52 -05:00
package attestation_test
2024-08-05 11:24:28 -05:00
import (
2024-09-19 14:59:54 -05:00
"path/filepath"
2024-08-05 11:24:28 -05:00
"strings"
"testing"
2024-09-02 16:17:50 +01:00
"github.com/docker/attest"
"github.com/docker/attest/attestation"
2024-08-05 11:24:28 -05:00
"github.com/docker/attest/internal/test"
2024-09-02 16:17:50 +01:00
"github.com/docker/attest/oci"
"github.com/docker/attest/policy"
2024-08-05 16:50:40 -05:00
v1 "github.com/google/go-containerregistry/pkg/v1"
2024-08-05 11:24:28 -05:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestAttestationFromOCILayout ( t * testing . T ) {
ctx , signer := test . Setup ( t )
outputLayout := test . CreateTempDir ( t , "" , "attest-oci-layout" )
2024-08-05 16:50:40 -05:00
invalidPlatform := & v1 . Platform {
Architecture : "invalid" ,
OS : "invalid" ,
}
2024-08-05 11:24:28 -05:00
opts := & attestation . SigningOptions { }
2024-09-02 16:17:50 +01:00
attIdx , err := oci . IndexFromPath ( test . UnsignedTestImage ( ".." ) )
2024-08-05 11:24:28 -05:00
require . NoError ( t , err )
signedManifests , err := attest . SignStatements ( ctx , attIdx . Index , signer , opts )
require . NoError ( t , err )
signedIndex := attIdx . Index
signedIndex , err = attestation . UpdateIndexImages ( signedIndex , signedManifests )
require . NoError ( t , err )
spec , err := oci . ParseImageSpec ( oci . LocalPrefix + outputLayout )
require . NoError ( t , err )
2024-09-19 14:59:54 -05:00
err = oci . SaveIndex ( ctx , [ ] * oci . ImageSpec { spec } , signedIndex , "docker.io/library/test-image:test" )
2024-08-05 11:24:28 -05:00
require . NoError ( t , err )
2024-08-05 16:50:40 -05:00
testCases := [ ] struct {
name string
platform * v1 . Platform
errorStr string
} {
{ name : "nominal" , platform : spec . Platform } ,
{ name : "invalid platform" , platform : invalidPlatform , errorStr : "platform not found in index" } ,
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
spec := & oci . ImageSpec {
Type : oci . OCI ,
Identifier : outputLayout ,
Platform : tc . platform ,
}
resolver , err := policy . CreateImageDetailsResolver ( spec )
if tc . errorStr != "" {
require . Error ( t , err )
assert . Contains ( t , err . Error ( ) , tc . errorStr )
return
}
require . NoError ( t , err )
desc , err := resolver . ImageDescriptor ( ctx )
require . NoError ( t , err )
digest := desc . Digest . String ( )
assert . True ( t , strings . Contains ( digest , "sha256:" ) )
} )
}
2024-08-05 11:24:28 -05:00
}
2024-09-19 14:59:54 -05:00
func TestSubjectNameAnnotations ( t * testing . T ) {
testCases := [ ] struct {
name string
ociLayoutPath string
errorStr string
} {
{ name : "oci annotation" , ociLayoutPath : test . UnsignedTestImage ( ".." ) } ,
{ name : "containerd annotation" , ociLayoutPath : filepath . Join ( ".." , "test" , "testdata" , "containerd-subject-layout" ) } ,
2024-09-19 15:31:37 -05:00
{ name : "missing subject name" , ociLayoutPath : filepath . Join ( ".." , "test" , "testdata" , "missing-subject-layout" ) , errorStr : "failed to find subject name in annotations" } ,
2024-09-19 14:59:54 -05:00
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
2024-09-19 15:31:37 -05:00
spec , err := oci . ParseImageSpec ( oci . LocalPrefix + tc . ociLayoutPath , oci . WithPlatform ( "linux/arm64" ) )
2024-09-19 14:59:54 -05:00
require . NoError ( t , err )
_ , err = policy . CreateImageDetailsResolver ( spec )
if tc . errorStr != "" {
require . Error ( t , err )
assert . Contains ( t , err . Error ( ) , tc . errorStr )
return
}
require . NoError ( t , err )
} )
}
}