Skip to content

Commit 1932842

Browse files
committed
Add check_certificate and check_jwk_without_password
1 parent 2944159 commit 1932842

10 files changed

Lines changed: 95 additions & 16 deletions

File tree

integration/certificate_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ func TestCertificateSignCommand(t *testing.T) {
5151

5252
return nil
5353
},
54+
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
55+
"check_certificate": checkCertificate,
56+
},
5457
})
5558

5659
testscript.Run(t, testscript.Params{
@@ -117,3 +120,13 @@ func TestCertificateFingerprintCommand(t *testing.T) {
117120
},
118121
})
119122
}
123+
124+
func checkCertificate(ts *testscript.TestScript, neg bool, args []string) {
125+
contents := ts.ReadFile("stdout") // directly reads from stdout of the previously executed command
126+
bundle, err := pemutil.ParseCertificateBundle([]byte(contents))
127+
ts.Check(err)
128+
129+
if len(bundle) != 1 {
130+
ts.Fatalf("expected 1 certificate; got %d", len(bundle))
131+
}
132+
}

integration/crypto_test.go

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ func TestCryptoJWKCreateRSACommand(t *testing.T) {
4646
return os.WriteFile(filepath.Join(e.Cd, "password.txt"), []byte("password"), 0600)
4747
},
4848
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
49-
"check_jwk": checkKeyPair,
49+
"check_jwk": checkKeyPair,
50+
"check_jwk_without_password": checkKeyPairWithoutPassword,
5051
},
5152
})
5253
}
@@ -58,7 +59,8 @@ func TestCryptoJWKCreateECCommand(t *testing.T) {
5859
return os.WriteFile(filepath.Join(e.Cd, "password.txt"), []byte("password"), 0600)
5960
},
6061
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
61-
"check_jwk": checkKeyPair,
62+
"check_jwk": checkKeyPair,
63+
"check_jwk_without_password": checkKeyPairWithoutPassword,
6264
},
6365
})
6466
}
@@ -70,7 +72,8 @@ func TestCryptoJWKCreateOKPCommand(t *testing.T) {
7072
return os.WriteFile(filepath.Join(e.Cd, "password.txt"), []byte("password"), 0600)
7173
},
7274
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
73-
"check_jwk": checkKeyPair,
75+
"check_jwk": checkKeyPair,
76+
"check_jwk_without_password": checkKeyPairWithoutPassword,
7477
},
7578
})
7679
}
@@ -82,7 +85,8 @@ func TestCryptoJWKCreateOctCommand(t *testing.T) {
8285
return os.WriteFile(filepath.Join(e.Cd, "password.txt"), []byte("password"), 0600)
8386
},
8487
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
85-
"check_jwk": checkKeyPair,
88+
"check_jwk": checkKeyPair,
89+
"check_jwk_without_password": checkKeyPairWithoutPassword,
8690
},
8791
})
8892
}
@@ -311,16 +315,10 @@ func TestCryptoHelp(t *testing.T) {
311315
})
312316
}
313317

314-
// checkKeyPair checks that the public/private key pair is valid. It performs
315-
// the following checks:
316-
//
317-
// - Read and parse the JWK public key, validating it's a valid public key
318-
// - Read and parse the JWK private key, validating it's a valid private key
319-
// - Compare the public and private key SHA-1 thumbprints to verify they match
320-
// - The type of the key that was created
321-
// - For RSA keys, the key size is the expected size
322-
// - For EC keys, the key curve is the expected curve
323-
func checkKeyPair(ts *testscript.TestScript, neg bool, args []string) {
318+
// checkKeyPair checks that the public/private key pair provided as filenames in
319+
// the first and second argument is valid. It always uses the password "password".
320+
// Other validations are delegated to the checkKeyDetails function.
321+
func checkKeyPair(ts *testscript.TestScript, _ bool, args []string) {
324322
if len(args) < 4 {
325323
ts.Fatalf("expected at least 4 arguments, got %d", len(args))
326324
}
@@ -330,6 +328,35 @@ func checkKeyPair(ts *testscript.TestScript, neg bool, args []string) {
330328
priv, err := jose.ParseKey([]byte(ts.ReadFile(args[1])), jose.WithPassword([]byte("password")))
331329
ts.Check(err)
332330

331+
checkKeyDetails(ts, pub, priv, args)
332+
}
333+
334+
// checkKeyPair checks that the public/private key pair provided as filenames in
335+
// the first and second argument is valid. It assumes no password is set on the file.
336+
// Other validations are delegated to the checkKeyDetails function.
337+
func checkKeyPairWithoutPassword(ts *testscript.TestScript, _ bool, args []string) {
338+
if len(args) < 4 {
339+
ts.Fatalf("expected at least 4 arguments, got %d", len(args))
340+
}
341+
342+
pub, err := jose.ParseKey([]byte(ts.ReadFile(args[0])))
343+
ts.Check(err)
344+
priv, err := jose.ParseKey([]byte(ts.ReadFile(args[1])))
345+
ts.Check(err)
346+
347+
checkKeyDetails(ts, pub, priv, args)
348+
}
349+
350+
// checkKeyDetails checks that the public/private key pair is valid. It performs
351+
// the following checks:
352+
//
353+
// - Compare the public and private key SHA-1 thumbprints to verify they match
354+
// - The type of the key that was created
355+
// - For RSA keys, the key size is the expected size, and using the expected algorithm
356+
// - For EC keys, the key curve is the expected curve, and using the expected algorithm
357+
// - For OKP keys, the key curve is the expected curve, and using the expected algorithm
358+
// - For oct keys, the key parts are of the expected type, and using the expected algorithm
359+
func checkKeyDetails(ts *testscript.TestScript, pub, priv *jose.JSONWebKey, args []string) {
333360
keyType := strings.ToUpper(args[2])
334361
if keyType == "OCT" {
335362
if _, ok := pub.Key.([]byte); !ok {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
exec step certificate sign test.csr cacert.pem cakey.pem
2-
stdout '-----BEGIN CERTIFICATE-----'
2+
check_certificate

integration/testdata/crypto/jwk-create-ec.txtar

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,13 @@ stderr 'alg ''ES384'' is not compatible with kty ''EC'' and crv ''P-256'''
5656
# EC P256 size fails
5757
! exec step crypto jwk create --password-file password.txt --kty EC --crv P-256 --alg ES256 --size 2048 fail.pub fail.priv
5858
stderr 'flag ''--size'' is incompatible with ''--kty EC'''
59+
60+
61+
# EC P256 without password
62+
exec step crypto jwk create --no-password --insecure --kty EC ec-no-pass.pub ec-no-pass.priv
63+
check_jwk_without_password ec-no-pass.pub ec-no-pass.priv ECDSA P-256
64+
65+
66+
# EC P256 without password without insecure fails
67+
! exec step crypto jwk create --no-password --kty EC fail.pub fail.priv
68+
stderr 'flag ''--no-password'' requires the ''--insecure'' flag'

integration/testdata/crypto/jwk-create-oct.txtar

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,13 @@ stderr 'alg ''RS256'' is not compatible with kty ''oct'''
8686
# oct with curve fails
8787
! exec step crypto jwk create --password-file password.txt --kty oct --alg HS256 --size 32 --curve P-256 fail.pub fail.priv
8888
stderr 'flag ''--crv'' is incompatible with ''--kty oct'''
89+
90+
91+
# oct without password
92+
exec step crypto jwk create --no-password --insecure --kty oct oct-no-pass.pub oct-no-pass.priv
93+
check_jwk_without_password oct-no-pass.pub oct-no-pass.priv oct HS256
94+
95+
96+
# oct without password without insecure fails
97+
! exec step crypto jwk create --no-password --kty oct fail.pub fail.priv
98+
stderr 'flag ''--no-password'' requires the ''--insecure'' flag'

integration/testdata/crypto/jwk-create-okp.txtar

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,13 @@ stderr 'flag ''--size'' is incompatible with ''--kty OKP'''
3131
# bad key type
3232
! exec step crypto jwk create --password-file password.txt --kty okp fail.pub fail.priv
3333
stderr 'invalid value ''okp'' for flag ''--kty''; options are EC, RSA, OKP, or oct'
34+
35+
36+
# OKP without password
37+
exec step crypto jwk create --no-password --insecure --kty OKP okp-no-pass.pub okp-no-pass.priv
38+
check_jwk_without_password okp-no-pass.pub okp-no-pass.priv OKP Ed25519
39+
40+
41+
# OKP without password without insecure fails
42+
! exec step crypto jwk create --no-password --kty OKP fail.pub fail.priv
43+
stderr 'flag ''--no-password'' requires the ''--insecure'' flag'

integration/testdata/crypto/jwk-create-rsa.txtar

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,13 @@ check_jwk kid.pub kid.priv RSA 2048 PS512
116116
# RSA 2048, with curve
117117
! exec step crypto jwk create --password-file password.txt --kty RSA --size 2048 --alg RS256 --crv P-256 fail.pub fail.priv
118118
stderr 'flag ''--crv'' is incompatible with ''--kty RSA'''
119+
120+
121+
# OKP without password
122+
exec step crypto jwk create --no-password --insecure --kty RSA rsa-no-pass.pub rsa-no-pass.priv
123+
check_jwk_without_password rsa-no-pass.pub rsa-no-pass.priv RSA 2048 RS256
124+
125+
126+
# OKP without password without insecure fails
127+
! exec step crypto jwk create --no-password --kty RSA fail.pub fail.priv
128+
stderr 'flag ''--no-password'' requires the ''--insecure'' flag'

integration/testdata/crypto/jwt-sign.txtar

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ exec step crypto jwt sign -key p256.pem -iss TestIssuer -aud TestAudience -sub T
88
stdout 'eyJhbGciOiJFUzI1NiIsImtpZCI6Ii1pZ1pNalRCdkhFRG02bjkxQkgwT0k4ZUhqQko2b0I3UlpIZFA0RE81U0EiLCJ0eXAiOiJKV1QifQ'
99

1010

11-
1211
# P-256 sign fails with JSON public key
1312
! exec step crypto jwt sign -key p256.pub.json -iss TestIssuer -aud TestAudience -sub TestSubject -nbf $NBF -iat $IAT -exp $EXP
1413
stderr 'cannot use a public key for signing'

0 commit comments

Comments
 (0)