Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions internal/cryptotest/asset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Package cryptotest provides cryptographic asset fixtures for tests.
package cryptotest

import (
"strings"

"github.com/aquasecurity/trivy/pkg/crypto"
)

// Option customizes an Asset fixture.
type Option func(*crypto.Asset)

// WithMutate applies mutate after constructing a complete Asset fixture.
func WithMutate(mutate func(*crypto.Asset)) Option {
return mutate
}

// CertificateAsset returns a valid certificate asset.
func CertificateAsset(opts ...Option) crypto.Asset {
asset := crypto.Asset{
Kind: crypto.KindCertificate,
Identity: crypto.Identity{
Method: crypto.MethodSHA256,
Value: strings.Repeat("a", 64),
},
Name: "example.test",
FilePath: "/etc/example.pem",
Certificate: &crypto.Certificate{
Subject: "CN=example.test",
Issuer: "CN=Example Test CA",
SerialNumber: "1",
Format: crypto.CertificateFormatX509,
},
}
return applyOptions(asset, opts)
}

// PublicKeyAsset returns a valid public key asset.
func PublicKeyAsset(opts ...Option) crypto.Asset {
asset := crypto.Asset{
Kind: crypto.KindKey,
KeyType: crypto.KeyTypePublic,
Identity: crypto.Identity{
Method: crypto.MethodSPKISHA256,
Value: strings.Repeat("b", 64),
},
FilePath: "/etc/example-public.pem",
Key: &crypto.Key{
Size: 2048,
Format: crypto.KeyFormatPKIX,
Encoding: crypto.EncodingPEM,
},
}
return applyOptions(asset, opts)
}

// PrivateKeyAsset returns a valid private key asset.
func PrivateKeyAsset(opts ...Option) crypto.Asset {
asset := PublicKeyAsset()
asset.KeyType = crypto.KeyTypePrivate
asset.FilePath = "/etc/example-private.pem"
asset.Key.Format = crypto.KeyFormatPKCS8
return applyOptions(asset, opts)
}

// EncryptedPrivateKeyAsset returns a valid encrypted private key asset.
func EncryptedPrivateKeyAsset(opts ...Option) crypto.Asset {
asset := PrivateKeyAsset()
asset.Identity.Method = crypto.MethodEncryptedPKCS8SHA256
asset.FilePath = "/etc/example-encrypted-private.pem"
asset.Key.Encrypted = true
return applyOptions(asset, opts)
}

// AlgorithmAsset returns a valid algorithm asset.
func AlgorithmAsset(opts ...Option) crypto.Asset {
asset := crypto.Asset{
Kind: crypto.KindAlgorithm,
Identity: crypto.Identity{
Method: crypto.MethodOID,
Value: "1.2.840.113549.1.1.1",
},
Name: "RSA",
FilePath: "/etc/example-algorithm.pem",
Algorithm: &crypto.Algorithm{
Family: "RSA",
Primitive: crypto.PrimitivePKE,
},
}
return applyOptions(asset, opts)
}

func applyOptions(asset crypto.Asset, opts []Option) crypto.Asset {
for _, opt := range opts {
opt(&asset)
}
return asset
}
76 changes: 76 additions & 0 deletions internal/cryptotest/asset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package cryptotest_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/aquasecurity/trivy/internal/cryptotest"
"github.com/aquasecurity/trivy/pkg/crypto"
)

func TestAssets(t *testing.T) {
t.Parallel()

tests := []struct {
name string
asset func(...cryptotest.Option) crypto.Asset
mutate func(*crypto.Asset)
}{
{
name: "certificate",
asset: cryptotest.CertificateAsset,
mutate: func(asset *crypto.Asset) {
asset.Certificate.Subject = "changed"
},
},
{
name: "public key",
asset: cryptotest.PublicKeyAsset,
mutate: func(asset *crypto.Asset) {
asset.Key.Size = 4096
},
},
{
name: "private key",
asset: cryptotest.PrivateKeyAsset,
mutate: func(asset *crypto.Asset) {
asset.Key.Size = 4096
},
},
{
name: "encrypted private key",
asset: cryptotest.EncryptedPrivateKeyAsset,
mutate: func(asset *crypto.Asset) {
asset.Key.Size = 4096
},
},
{
name: "algorithm",
asset: cryptotest.AlgorithmAsset,
mutate: func(asset *crypto.Asset) {
asset.Algorithm.Family = "changed"
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

first := tt.asset()
second := tt.asset()
require.NoError(t, first.Validate())
require.NoError(t, second.Validate())
assert.NotEmpty(t, first.FilePath)
assert.Equal(t, first, second)

mutated := tt.asset(cryptotest.WithMutate(tt.mutate))
assert.NotEqual(t, first, mutated)

tt.mutate(&first)
assert.NotEqual(t, first, second)
})
}
}
33 changes: 33 additions & 0 deletions internal/cryptotest/descriptor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cryptotest

import "github.com/aquasecurity/trivy/pkg/crypto"

// CertificateDescriptor returns the descriptor of CertificateAsset.
func CertificateDescriptor() crypto.Descriptor {
asset := CertificateAsset()
return asset.Descriptor()
}

// PublicKeyDescriptor returns the descriptor of PublicKeyAsset.
func PublicKeyDescriptor() crypto.Descriptor {
asset := PublicKeyAsset()
return asset.Descriptor()
}

// PrivateKeyDescriptor returns the descriptor of PrivateKeyAsset.
func PrivateKeyDescriptor() crypto.Descriptor {
asset := PrivateKeyAsset()
return asset.Descriptor()
}

// EncryptedPrivateKeyDescriptor returns the descriptor of EncryptedPrivateKeyAsset.
func EncryptedPrivateKeyDescriptor() crypto.Descriptor {
asset := EncryptedPrivateKeyAsset()
return asset.Descriptor()
}

// AlgorithmDescriptor returns the descriptor of AlgorithmAsset.
func AlgorithmDescriptor() crypto.Descriptor {
asset := AlgorithmAsset()
return asset.Descriptor()
}
19 changes: 19 additions & 0 deletions pkg/crypto/algorithm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package crypto

// Primitive identifies the cryptographic primitive provided by an algorithm.
type Primitive string

const (
// PrimitiveUnknown identifies an algorithm with an unknown primitive.
PrimitiveUnknown Primitive = "unknown"
// PrimitiveSignature identifies a digital signature algorithm.
PrimitiveSignature Primitive = "signature"
// PrimitivePKE identifies a public-key encryption algorithm.
PrimitivePKE Primitive = "pke"
)

// Algorithm contains algorithm-specific metadata.
type Algorithm struct {
Family string `json:",omitempty"`
Primitive Primitive `json:",omitempty"`
}
Loading