1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package test
18
19 import (
20 "context"
21 "crypto/x509"
22 "encoding/pem"
23 "net/http/httptest"
24 "path"
25 "path/filepath"
26 "testing"
27 "time"
28
29 "github.com/secure-systems-lab/go-securesystemslib/encrypted"
30 "github.com/sigstore/cosign/v2/cmd/cosign/cli/options"
31 "github.com/sigstore/cosign/v2/cmd/cosign/cli/sign"
32 cliverify "github.com/sigstore/cosign/v2/cmd/cosign/cli/verify"
33 "github.com/sigstore/cosign/v2/pkg/cosign"
34 tsaclient "github.com/sigstore/timestamp-authority/pkg/client"
35 tsaserver "github.com/sigstore/timestamp-authority/pkg/server"
36 "github.com/spf13/viper"
37 )
38
39 func TestTSAMTLS(t *testing.T) {
40 repo, stop := reg(t)
41 defer stop()
42 td := t.TempDir()
43
44 imgName := path.Join(repo, "cosign-tsa-mtls-e2e")
45
46 _, _, cleanup := mkimage(t, imgName)
47 defer cleanup()
48
49 pemRootRef, pemLeafRef, pemKeyRef := generateSigningKeys(t, td)
50
51
52 timestampCACert, timestampServerCert, timestampServerKey, timestampClientCert, timestampClientKey := generateMTLSKeys(t, td)
53 timestampServerURL, timestampChainFile, tsaCleanup := setUpTSAServerWithTLS(t, td, timestampCACert, timestampServerKey, timestampServerCert)
54 t.Cleanup(tsaCleanup)
55
56 ko := options.KeyOpts{
57 KeyRef: pemKeyRef,
58 PassFunc: passFunc,
59 TSAServerURL: timestampServerURL,
60 TSAClientCACert: timestampCACert,
61 TSAClientCert: timestampClientCert,
62 TSAClientKey: timestampClientKey,
63 TSAServerName: "server.example.com",
64 }
65 so := options.SignOptions{
66 Upload: true,
67 TlogUpload: false,
68 Cert: pemLeafRef,
69 CertChain: pemRootRef,
70 }
71 must(sign.SignCmd(ro, ko, so, []string{imgName}), t)
72
73 verifyCmd := cliverify.VerifyCommand{
74 IgnoreTlog: true,
75 IgnoreSCT: true,
76 CheckClaims: true,
77 CertChain: pemRootRef,
78 TSACertChainPath: timestampChainFile,
79 CertVerifyOptions: options.CertVerifyOptions{
80 CertIdentityRegexp: ".*",
81 CertOidcIssuerRegexp: ".*",
82 },
83 }
84 must(verifyCmd.Exec(context.Background(), []string{imgName}), t)
85 }
86
87 func TestSignBlobTSAMTLS(t *testing.T) {
88 td := t.TempDir()
89 blob := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
90 blobPath := mkfile(blob, td, t)
91 timestampPath := filepath.Join(td, "timestamp.txt")
92 bundlePath := filepath.Join(td, "cosign.bundle")
93
94 _, privKey, pubKey := keypair(t, td)
95
96
97 timestampCACert, timestampServerCert, timestampServerKey, timestampClientCert, timestampClientKey := generateMTLSKeys(t, td)
98 timestampServerURL, timestampChainFile, tsaCleanup := setUpTSAServerWithTLS(t, td, timestampCACert, timestampServerKey, timestampServerCert)
99 t.Cleanup(tsaCleanup)
100
101 signingKO := options.KeyOpts{
102 KeyRef: privKey,
103 PassFunc: passFunc,
104 TSAServerURL: timestampServerURL,
105 TSAClientCACert: timestampCACert,
106 TSAClientCert: timestampClientCert,
107 TSAClientKey: timestampClientKey,
108 TSAServerName: "server.example.com",
109 RFC3161TimestampPath: timestampPath,
110 BundlePath: bundlePath,
111 }
112 sig, err := sign.SignBlobCmd(ro, signingKO, blobPath, true, "", "", false)
113 must(err, t)
114
115 verifyKO := options.KeyOpts{
116 KeyRef: pubKey,
117 TSACertChainPath: timestampChainFile,
118 RFC3161TimestampPath: timestampPath,
119 BundlePath: bundlePath,
120 }
121
122 verifyCmd := cliverify.VerifyBlobCmd{
123 KeyOpts: verifyKO,
124 SigRef: string(sig),
125 CertVerifyOptions: options.CertVerifyOptions{
126 CertIdentityRegexp: ".*",
127 CertOidcIssuerRegexp: ".*",
128 },
129 IgnoreTlog: true,
130 }
131 must(verifyCmd.Exec(context.Background(), blobPath), t)
132 }
133
134 func generateSigningKeys(t *testing.T, td string) (string, string, string) {
135 rootCert, rootKey, _ := GenerateRootCa()
136 pemRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCert.Raw})
137 pemRootRef := mkfile(string(pemRoot), td, t)
138
139 leafCert, privKey, _ := GenerateLeafCert("xyz@nosuchprovider.com", "oidc-issuer", rootCert, rootKey)
140 pemLeaf := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: leafCert.Raw})
141 pemLeafRef := mkfile(string(pemLeaf), td, t)
142
143 x509Encoded, _ := x509.MarshalPKCS8PrivateKey(privKey)
144 encBytes, _ := encrypted.Encrypt(x509Encoded, keyPass)
145 keyPem := pem.EncodeToMemory(&pem.Block{
146 Type: cosign.CosignPrivateKeyPemType,
147 Bytes: encBytes})
148 pemKeyRef := mkfile(string(keyPem), td, t)
149
150 return pemRootRef, pemLeafRef, pemKeyRef
151 }
152
153 func generateMTLSKeys(t *testing.T, td string) (string, string, string, string, string) {
154 rootCert, rootKey, _ := GenerateRootCa()
155 pemRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCert.Raw})
156 pemRootRef := mkfile(string(pemRoot), td, t)
157
158 serverLeafCert, serverPrivKey, _ := GenerateLeafCertWithSubjectAlternateNames([]string{"server.example.com"}, nil, nil, nil, "oidc-issuer", rootCert, rootKey)
159 serverPemLeaf := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: serverLeafCert.Raw})
160 serverPemLeafRef := mkfile(string(serverPemLeaf), td, t)
161 serverX509Encoded, _ := x509.MarshalPKCS8PrivateKey(serverPrivKey)
162 serverKeyPem := pem.EncodeToMemory(&pem.Block{
163 Type: cosign.ECPrivateKeyPemType,
164 Bytes: serverX509Encoded})
165 serverPemKeyRef := mkfile(string(serverKeyPem), td, t)
166
167 clientLeafCert, clientPrivKey, _ := GenerateLeafCert("tsa-mtls-client", "oidc-issuer", rootCert, rootKey)
168 clientPemLeaf := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: clientLeafCert.Raw})
169 clientPemLeafRef := mkfile(string(clientPemLeaf), td, t)
170 clientX509Encoded, _ := x509.MarshalPKCS8PrivateKey(clientPrivKey)
171 clientKeyPem := pem.EncodeToMemory(&pem.Block{
172 Type: cosign.ECPrivateKeyPemType,
173 Bytes: clientX509Encoded})
174 clientPemKeyRef := mkfile(string(clientKeyPem), td, t)
175 return pemRootRef, serverPemLeafRef, serverPemKeyRef, clientPemLeafRef, clientPemKeyRef
176 }
177
178 func setUpTSAServerWithTLS(t *testing.T, td, timestampCACert, timestampServerKey, timestampServerCert string) (string, string, func()) {
179 viper.Set("timestamp-signer", "memory")
180 viper.Set("timestamp-signer-hash", "sha256")
181 viper.Set("disable-ntp-monitoring", true)
182 viper.Set("tls-host", "0.0.0.0")
183 viper.Set("tls-port", 3000)
184 viper.Set("tls-ca", timestampCACert)
185 viper.Set("tls-key", timestampServerKey)
186 viper.Set("tls-certificate", timestampServerCert)
187 tsaAPIServer := tsaserver.NewRestAPIServer("localhost", 3000, []string{"https"}, false, 10*time.Second, 10*time.Second)
188 tsaServer := httptest.NewServer(tsaAPIServer.GetHandler())
189 tsaClient, err := tsaclient.GetTimestampClient(tsaServer.URL)
190 must(err, t)
191 tsaChain, err := tsaClient.Timestamp.GetTimestampCertChain(nil)
192 must(err, t)
193 timestampServerURL := tsaServer.URL + "/api/v1/timestamp"
194 timestampChainFile := mkfile(tsaChain.Payload, td, t)
195 return timestampServerURL, timestampChainFile, tsaServer.Close
196 }
197
View as plain text