Files
releases/internal/jwx/jws/verify/rsa.go
T
Anders Eknert e43ef0a979 Use any in place of interface{} (#7566)
Earlier this evening I tried to run the Go
[modernize](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize)
analyzer on OPA. That didn't go as planned:

- https://github.com/golang/go/issues/73661
- https://github.com/golang/go/issues/73663

While we wait for that to be fixed, I figured an old-fashioned
search-and-replace across the repo may work for at least the
`interface{}` to `any` conversion. That should help make it easier
to see the other fixes as applied by the modernize tool once it has
had those issues resolved.

Signed-off-by: Anders Eknert <anders@styra.com>
2025-05-12 13:57:48 +02:00

89 lines
2.0 KiB
Go

package verify
import (
"crypto"
"crypto/rsa"
"errors"
"fmt"
"github.com/open-policy-agent/opa/internal/jwx/jwa"
)
var rsaVerifyFuncs = map[jwa.SignatureAlgorithm]rsaVerifyFunc{}
func init() {
algs := map[jwa.SignatureAlgorithm]struct {
Hash crypto.Hash
VerifyFunc func(crypto.Hash) rsaVerifyFunc
}{
jwa.RS256: {
Hash: crypto.SHA256,
VerifyFunc: makeVerifyPKCS1v15,
},
jwa.RS384: {
Hash: crypto.SHA384,
VerifyFunc: makeVerifyPKCS1v15,
},
jwa.RS512: {
Hash: crypto.SHA512,
VerifyFunc: makeVerifyPKCS1v15,
},
jwa.PS256: {
Hash: crypto.SHA256,
VerifyFunc: makeVerifyPSS,
},
jwa.PS384: {
Hash: crypto.SHA384,
VerifyFunc: makeVerifyPSS,
},
jwa.PS512: {
Hash: crypto.SHA512,
VerifyFunc: makeVerifyPSS,
},
}
for alg, item := range algs {
rsaVerifyFuncs[alg] = item.VerifyFunc(item.Hash)
}
}
func makeVerifyPKCS1v15(hash crypto.Hash) rsaVerifyFunc {
return rsaVerifyFunc(func(payload, signature []byte, key *rsa.PublicKey) error {
h := hash.New()
h.Write(payload)
return rsa.VerifyPKCS1v15(key, hash, h.Sum(nil), signature)
})
}
func makeVerifyPSS(hash crypto.Hash) rsaVerifyFunc {
return rsaVerifyFunc(func(payload, signature []byte, key *rsa.PublicKey) error {
h := hash.New()
h.Write(payload)
return rsa.VerifyPSS(key, hash, h.Sum(nil), signature, nil)
})
}
func newRSA(alg jwa.SignatureAlgorithm) (*RSAVerifier, error) {
verifyfn, ok := rsaVerifyFuncs[alg]
if !ok {
return nil, fmt.Errorf(`unsupported algorithm while trying to create RSA verifier: %s`, alg)
}
return &RSAVerifier{
verify: verifyfn,
}, nil
}
// Verify checks if a JWS is valid.
func (v RSAVerifier) Verify(payload, signature []byte, key any) error {
if key == nil {
return errors.New(`missing public key while verifying payload`)
}
rsaKey, ok := key.(*rsa.PublicKey)
if !ok {
return fmt.Errorf(`invalid key type %T. *rsa.PublicKey is required`, key)
}
return v.verify(payload, signature, rsaKey)
}