Skip to content

Commit

Permalink
Added a test for the crypto signer with an ECDSA key pair
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfeidau committed Aug 29, 2024
1 parent 0971b8e commit 6880862
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
5 changes: 5 additions & 0 deletions signature/fixtures/crypto_signer/P256/private.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MHcCAQEEIKG2wc1cI8aGVw4f1GhMfGbhMiDZAE1NeNAyil63wbXPoAoGCCqGSM49
AwEHoUQDQgAETbursv8d9C1Fa/89/d2FqSo2sw/zeke9F0IWiOKGJuuXENVcp8U5
FfxStK9sKVH4tPMCpVNPNr1pMa/3NFVlLA==
-----END PRIVATE KEY-----
4 changes: 4 additions & 0 deletions signature/fixtures/crypto_signer/P256/public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETbursv8d9C1Fa/89/d2FqSo2sw/z
eke9F0IWiOKGJuuXENVcp8U5FfxStK9sKVH4tPMCpVNPNr1pMa/3NFVlLA==
-----END PUBLIC KEY-----
125 changes: 125 additions & 0 deletions signature/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ package signature

import (
"context"
"crypto"
"crypto/ecdsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io"
"math/rand"
"os"
"path"
Expand Down Expand Up @@ -134,6 +139,126 @@ func TestSignVerify(t *testing.T) {
}
}

var _ crypto.Signer = MockCryptoSigner{}

type MockCryptoSigner struct {
privateKey crypto.PrivateKey
publickKey crypto.PublicKey
}

func (m MockCryptoSigner) Public() crypto.PublicKey { return m.publickKey }

func (m MockCryptoSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
return ecdsa.SignASN1(rand, m.privateKey.(*ecdsa.PrivateKey), digest)
}

func (m MockCryptoSigner) Algorithm() jwa.KeyAlgorithm {
return jwa.ES256
}

func TestSignVerifyCryptoSigner(t *testing.T) {

t.Parallel()
ctx := context.Background()

step := &pipeline.CommandStep{
Command: "llamas",
Plugins: pipeline.Plugins{
{
Source: "some-plugin#v1.0.0",
Config: nil,
},
{
Source: "another-plugin#v3.4.5",
Config: map[string]any{"llama": "Kuzco"},
},
},
Env: map[string]string{
"CONTEXT": "cats",
"DEPLOY": "0",
},
}
// The pipeline-level env that the agent uploads:
signEnv := map[string]string{
"DEPLOY": "1",
}

// The backend combines the pipeline and step envs, providing a new env:
verifyEnv := map[string]string{
"CONTEXT": "cats",
"DEPLOY": "0",
"MISC": "llama drama",
}

stepWithInvariants := &CommandStepWithInvariants{
CommandStep: *step,
RepositoryURL: "fake-repo",
}

cases := []struct {
name string
alg jwa.SignatureAlgorithm
expectedSignature string
}{
{
name: "should sign using crypto.Signer",
alg: jwa.ES256,
expectedSignature: "eyJhbGciOiJFUzI1NiJ9..Op5KSww95n5s1b9jz0Me5UGqUQPcHzEIFvkWTB_yEv6qEDnnFUO1XsC5592fQoAcB0VnPnHaK31iSiCypREIdA",
},
}

wd, err := os.Getwd()
if err != nil {
t.Fatalf("os.Getwd() error = %v", err)
}

privateKeyPath := path.Join(wd, "fixtures", "crypto_signer", "P256", "private.pem")
pemPrivateKey, err := os.ReadFile(privateKeyPath)
if err != nil {
t.Fatalf("os.ReadFile(%q) error = %v", privateKeyPath, err)
}

block, _ := pem.Decode([]byte(pemPrivateKey))
x509Encoded := block.Bytes
privateKey, _ := x509.ParseECPrivateKey(x509Encoded)

publicKeyPath := path.Join(wd, "fixtures", "crypto_signer", "P256", "public.pem")
pemPublicKey, err := os.ReadFile(publicKeyPath)
if err != nil {
t.Fatalf("os.ReadFile(%q) error = %v", publicKeyPath, err)
}

blockPub, _ := pem.Decode([]byte(pemPublicKey))
x509EncodedPub := blockPub.Bytes
genericPublicKey, _ := x509.ParsePKIXPublicKey(x509EncodedPub)
publicKey := genericPublicKey.(*ecdsa.PublicKey)

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

sKey := MockCryptoSigner{
privateKey: privateKey,
publickKey: publicKey,
}

sig, err := Sign(ctx, sKey, stepWithInvariants, WithEnv(signEnv))
if err != nil {
t.Fatalf("Sign(ctx, sKey, %v, WithEnv(%v)) error = %v", stepWithInvariants, signEnv, err)
}

if sig.Algorithm != tc.alg.String() {
t.Errorf("Signature.Algorithm = %v, want %v", sig.Algorithm, tc.alg)
}

if err := Verify(ctx, sig, sKey, stepWithInvariants, WithEnv(verifyEnv)); err != nil {
t.Errorf("Verify(ctx, %v, verifier, %v, WithEnv(%v)) = %v", sig, stepWithInvariants, verifyEnv, err)
}

})
}
}

type testFields map[string]any

func (m testFields) SignedFields() (map[string]any, error) { return m, nil }
Expand Down

0 comments on commit 6880862

Please sign in to comment.