Skip to content

Commit 389fa2e

Browse files
committed
test: unit tests for the signer
Signed-off-by: Pierre-Henri Symoneaux <[email protected]>
1 parent 952666c commit 389fa2e

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

Diff for: sign_test.go

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package okms
2+
3+
import (
4+
"context"
5+
"crypto"
6+
"crypto/ecdsa"
7+
"crypto/elliptic"
8+
"crypto/rand"
9+
"crypto/rsa"
10+
"encoding/base64"
11+
"strings"
12+
"testing"
13+
14+
"github.com/google/uuid"
15+
"github.com/ovh/okms-sdk-go/mocks"
16+
"github.com/ovh/okms-sdk-go/types"
17+
"github.com/stretchr/testify/mock"
18+
"github.com/stretchr/testify/require"
19+
)
20+
21+
func TestSigner_RSA(t *testing.T) {
22+
api := mocks.NewAPIMock(t)
23+
client := Client{api}
24+
keyId := uuid.New()
25+
format := types.Jwk
26+
27+
pKey, err := rsa.GenerateKey(rand.Reader, 2048)
28+
require.NoError(t, err)
29+
30+
jwk, err := types.NewJsonWebKey(pKey, []types.CryptographicUsages{types.Sign, types.Verify}, keyId.String())
31+
require.NoError(t, err)
32+
33+
api.EXPECT().GetServiceKey(mock.Anything, keyId, &format).
34+
Return(&types.GetServiceKeyResponse{
35+
Attributes: &map[string]interface{}{"state": "active"},
36+
Keys: &[]types.JsonWebKey{jwk},
37+
}, nil).
38+
Once()
39+
40+
signer, err := client.NewSigner(context.Background(), keyId)
41+
require.NoError(t, err)
42+
require.Equal(t, pKey.Public(), signer.Public())
43+
44+
tcs := []struct {
45+
alg types.DigitalSignatureAlgorithms
46+
hash crypto.SignerOpts
47+
}{
48+
{alg: types.RS256, hash: crypto.SHA256},
49+
{alg: types.RS384, hash: crypto.SHA384},
50+
{alg: types.RS512, hash: crypto.SHA512},
51+
{alg: types.PS256, hash: &rsa.PSSOptions{Hash: crypto.SHA256}},
52+
{alg: types.PS384, hash: &rsa.PSSOptions{Hash: crypto.SHA384}},
53+
{alg: types.PS512, hash: &rsa.PSSOptions{Hash: crypto.SHA512}},
54+
}
55+
56+
for _, tc := range tcs {
57+
t.Run(string(tc.alg), func(t *testing.T) {
58+
hf := tc.hash.HashFunc().New()
59+
hf.Write([]byte("the message"))
60+
digest := hf.Sum(nil)
61+
62+
var rawsig []byte
63+
var err error
64+
if strings.HasPrefix(string(tc.alg), "RS") {
65+
rawsig, err = rsa.SignPKCS1v15(rand.Reader, pKey, tc.hash.HashFunc(), digest)
66+
} else {
67+
rawsig, err = rsa.SignPSS(rand.Reader, pKey, tc.hash.HashFunc(), digest, tc.hash.(*rsa.PSSOptions))
68+
}
69+
require.NoError(t, err)
70+
71+
api.EXPECT().Sign(mock.Anything, keyId, tc.alg, true, mock.Anything).
72+
Return(base64.StdEncoding.EncodeToString(rawsig), nil).
73+
Once()
74+
sig, err := signer.Sign(rand.Reader, digest, tc.hash)
75+
require.NoError(t, err)
76+
require.Equal(t, rawsig, sig)
77+
})
78+
}
79+
}
80+
81+
func TestSigner_ECDSA(t *testing.T) {
82+
api := mocks.NewAPIMock(t)
83+
client := Client{api}
84+
keyId := uuid.New()
85+
format := types.Jwk
86+
87+
pKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
88+
require.NoError(t, err)
89+
90+
jwk, err := types.NewJsonWebKey(pKey, []types.CryptographicUsages{types.Sign, types.Verify}, keyId.String())
91+
require.NoError(t, err)
92+
93+
api.EXPECT().GetServiceKey(mock.Anything, keyId, &format).
94+
Return(&types.GetServiceKeyResponse{
95+
Attributes: &map[string]interface{}{"state": "active"},
96+
Keys: &[]types.JsonWebKey{jwk},
97+
}, nil).
98+
Once()
99+
100+
signer, err := client.NewSigner(context.Background(), keyId)
101+
require.NoError(t, err)
102+
require.Equal(t, pKey.Public(), signer.Public())
103+
104+
tcs := []struct {
105+
alg types.DigitalSignatureAlgorithms
106+
hash crypto.SignerOpts
107+
}{
108+
{alg: types.ES256, hash: crypto.SHA256},
109+
{alg: types.ES384, hash: crypto.SHA384},
110+
{alg: types.ES512, hash: crypto.SHA512},
111+
}
112+
113+
for _, tc := range tcs {
114+
t.Run(string(tc.alg), func(t *testing.T) {
115+
hf := tc.hash.HashFunc().New()
116+
hf.Write([]byte("the message"))
117+
digest := hf.Sum(nil)
118+
119+
r, s, err := ecdsa.Sign(rand.Reader, pKey, digest)
120+
require.NoError(t, err)
121+
rawsig := r.Bytes()
122+
rawsig = append(rawsig, s.Bytes()...)
123+
124+
api.EXPECT().Sign(mock.Anything, keyId, tc.alg, true, digest).
125+
Return(base64.StdEncoding.EncodeToString(rawsig), nil).
126+
Once()
127+
128+
sig, err := signer.Sign(rand.Reader, digest, tc.hash)
129+
require.NoError(t, err)
130+
require.True(t, ecdsa.VerifyASN1(&pKey.PublicKey, digest, sig))
131+
})
132+
}
133+
}

0 commit comments

Comments
 (0)