Merge commit from fork

Fix registry token authentication bug
This commit is contained in:
Milos Gajdos 2025-02-10 19:50:35 -08:00 committed by GitHub
commit 5ea9aa028d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 6 deletions

View File

@ -212,18 +212,18 @@ func verifyCertChain(header jose.Header, roots *x509.CertPool) (signingKey crypt
return
}
func verifyJWK(header jose.Header, verifyOpts VerifyOptions) (signingKey crypto.PublicKey, err error) {
func verifyJWK(header jose.Header, verifyOpts VerifyOptions) (crypto.PublicKey, error) {
jwk := header.JSONWebKey
signingKey = jwk.Key
// Check to see if the key includes a certificate chain.
if len(jwk.Certificates) == 0 {
// The JWK should be one of the trusted root keys.
if _, trusted := verifyOpts.TrustedKeys[jwk.KeyID]; !trusted {
key, trusted := verifyOpts.TrustedKeys[jwk.KeyID]
if !trusted {
return nil, errors.New("untrusted JWK with no certificate chain")
}
// The JWK is one of the trusted keys.
return
return key, nil
}
opts := x509.VerifyOptions{
@ -245,9 +245,8 @@ func verifyJWK(header jose.Header, verifyOpts VerifyOptions) (signingKey crypto.
if err != nil {
return nil, err
}
signingKey = getCertPubKey(chains)
return
return getCertPubKey(chains), nil
}
func getCertPubKey(chains [][]*x509.Certificate) crypto.PublicKey {

View File

@ -646,3 +646,57 @@ func TestNewAccessControllerPemBlock(t *testing.T) {
t.Fatal("accessController has the wrong number of certificates")
}
}
// This test makes sure the untrusted key can not be used in token verification.
func TestVerifyJWKWithTrustedKey(t *testing.T) {
// Generate a test key pair
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
pubKey := privKey.Public()
// Create a JWK with no certificates
jwk := &jose.JSONWebKey{
Key: privKey,
KeyID: "test-key-id",
Use: "sig",
Algorithm: string(jose.ES256),
}
// Create verify options with our public key as trusted
verifyOpts := VerifyOptions{
TrustedKeys: map[string]crypto.PublicKey{
"test-key-id": pubKey,
},
}
// Create test header
header := jose.Header{
JSONWebKey: jwk,
}
// Test the verifyJWK function
returnedKey, err := verifyJWK(header, verifyOpts)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
// Verify the returned key matches our trusted key
if returnedKey != pubKey {
t.Error("Returned key does not match the trusted key")
}
// Test with untrusted key
verifyOpts.TrustedKeys = map[string]crypto.PublicKey{
"different-key-id": pubKey,
}
_, err = verifyJWK(header, verifyOpts)
if err == nil {
t.Error("Expected error for untrusted key, got none")
}
if err.Error() != "untrusted JWK with no certificate chain" {
t.Errorf("Expected 'untrusted JWK with no certificate chain' error, got: %v", err)
}
}