From 91294b97cb5b8e7ce81edb25b6cbc1c4d87bfb51 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Fri, 13 Jun 2025 22:32:42 +0000 Subject: [PATCH 1/3] Fix PublicKey extraction from JWK Signed-off-by: Dionna Glaze --- corim/signer.go | 59 +++++++++++++++++++++++++++++++++++-------------- go.mod | 21 +++++++++--------- go.sum | 36 +++++++++++++++--------------- 3 files changed, 72 insertions(+), 44 deletions(-) diff --git a/corim/signer.go b/corim/signer.go index cf971292..39bd7f50 100644 --- a/corim/signer.go +++ b/corim/signer.go @@ -12,7 +12,7 @@ import ( "fmt" "reflect" - "github.com/lestrrat-go/jwx/v2/jwk" + "github.com/lestrrat-go/jwx/v3/jwk" "github.com/veraison/corim/comid" "github.com/veraison/corim/encoding" "github.com/veraison/corim/extensions" @@ -114,7 +114,7 @@ func (o Signer) MarshalJSON() ([]byte, error) { const noAlg = cose.Algorithm(-65537) -func getAlgAndKeyFromJWK(j []byte) (cose.Algorithm, crypto.Signer, error) { +func getAlgAndKeyFromJWK(j []byte) (cose.Algorithm, any, error) { var ( err error k jwk.Key @@ -127,31 +127,47 @@ func getAlgAndKeyFromJWK(j []byte) (cose.Algorithm, crypto.Signer, error) { return noAlg, nil, err } - var key crypto.Signer + var key any - err = k.Raw(&key) + err = jwk.Export(k, &key) if err != nil { return noAlg, nil, err } - switch v := key.(type) { - case *ecdsa.PrivateKey: - alg = ellipticCurveToAlg(v.Curve) + fromCurve := func(c elliptic.Curve) (cose.Algorithm, any, error) { + alg = ellipticCurveToAlg(c) if alg == noAlg { return noAlg, nil, fmt.Errorf("unknown elliptic curve %v", crv) } - case ed25519.PrivateKey: - alg = cose.AlgorithmEd25519 - case *rsa.PrivateKey: + return alg, key, nil + } + isRsa := func() (cose.Algorithm, any, error) { alg = rsaJWKToAlg(k) if alg == noAlg { - return noAlg, nil, fmt.Errorf("unknown RSA algorithm %q", k.Algorithm().String()) + name := "unnamed" + if jalg, ok := k.Algorithm(); ok { + name = jalg.String() + } + return noAlg, nil, fmt.Errorf("unknown RSA algorithm %q", name) } + return alg, key, nil + } + switch v := key.(type) { + case *ecdsa.PrivateKey: + return fromCurve(v.Curve) + case *ecdsa.PublicKey: + return fromCurve(v.Curve) + case ed25519.PrivateKey: + return cose.AlgorithmEd25519, key, nil + case ed25519.PublicKey: + return cose.AlgorithmEd25519, key, nil + case *rsa.PrivateKey: + return isRsa() + case *rsa.PublicKey: + return isRsa() default: return noAlg, nil, fmt.Errorf("unknown private key type %v", reflect.TypeOf(key)) } - - return alg, key, nil } func ellipticCurveToAlg(c elliptic.Curve) cose.Algorithm { @@ -168,7 +184,11 @@ func ellipticCurveToAlg(c elliptic.Curve) cose.Algorithm { } func rsaJWKToAlg(k jwk.Key) cose.Algorithm { - switch k.Algorithm().String() { + alg, ok := k.Algorithm() + if !ok { + return noAlg + } + switch alg.String() { case "PS256": return cose.AlgorithmPS256 case "PS384": @@ -185,8 +205,12 @@ func NewSignerFromJWK(j []byte) (cose.Signer, error) { if err != nil { return nil, err } + signer, isSigner := key.(crypto.Signer) + if !isSigner { + return nil, fmt.Errorf("jwk did not contain a private key") + } - return cose.NewSigner(alg, key) + return cose.NewSigner(alg, signer) } func NewPublicKeyFromJWK(j []byte) (crypto.PublicKey, error) { @@ -194,6 +218,9 @@ func NewPublicKeyFromJWK(j []byte) (crypto.PublicKey, error) { if err != nil { return nil, err } + if signer, isSigner := key.(crypto.Signer); isSigner { + return signer.Public(), nil + } - return key.Public(), nil + return key, nil } diff --git a/go.mod b/go.mod index cce1748c..1800607f 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,15 @@ module github.com/veraison/corim -go 1.22.0 +go 1.23.0 + +toolchain go1.24.2 require ( github.com/fxamacker/cbor/v2 v2.5.0 github.com/google/uuid v1.3.0 - github.com/lestrrat-go/jwx/v2 v2.0.21 + github.com/lestrrat-go/jwx/v3 v3.0.6 github.com/spf13/cast v1.4.1 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/veraison/eat v0.0.0-20210331113810-3da8a4dd42ff github.com/veraison/go-cose v1.2.1 github.com/veraison/swid v1.1.1-0.20230911094910-8ffdd07a22ca @@ -15,19 +17,18 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/kr/pretty v0.2.0 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/blackmagic v1.0.4 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc v1.0.5 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/httprc/v3 v3.0.0 // indirect github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lestrrat-go/option/v2 v2.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.33.0 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2aaa8ae4..df05d7f2 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,14 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/fxamacker/cbor/v2 v2.3.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= @@ -16,18 +16,18 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA= +github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/httprc v1.0.5 h1:bsTfiH8xaKOJPrg1R+E3iE/AWZr/x0Phj9PBTG/OLUk= -github.com/lestrrat-go/httprc v1.0.5/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx/v2 v2.0.21 h1:jAPKupy4uHgrHFEdjVjNkUgoBKtVDgrQPB/h55FHrR0= -github.com/lestrrat-go/jwx/v2 v2.0.21/go.mod h1:09mLW8zto6bWL9GbwnqAli+ArLf+5M33QLQPDggkUWM= +github.com/lestrrat-go/httprc/v3 v3.0.0 h1:nZUx/zFg5uc2rhlu1L1DidGr5Sj02JbXvGSpnY4LMrc= +github.com/lestrrat-go/httprc/v3 v3.0.0/go.mod h1:k2U1QIiyVqAKtkffbg+cUmsyiPGQsb9aAfNQiNFuQ9Q= +github.com/lestrrat-go/jwx/v3 v3.0.6 h1:aWM4fQxCncasWolc67qfv6YKo53QBcW6cee2CmT35Qg= +github.com/lestrrat-go/jwx/v3 v3.0.6/go.mod h1:7bi1u/M8ZoyDH4UCTcIMO8l42ETaO4ULYckKRkEWe8Y= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= +github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= @@ -38,8 +38,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/veraison/eat v0.0.0-20210331113810-3da8a4dd42ff h1:r6I2eJL/z8dp5flsQIKHMeDjyV6UO8If3MaVBLvTjF4= github.com/veraison/eat v0.0.0-20210331113810-3da8a4dd42ff/go.mod h1:+kxt8iuFiVvKRs2VQ1Ho7bbAScXAB/kHFFuP5Biw19I= github.com/veraison/go-cose v1.2.1 h1:Gj4x20D0YP79J2+cK3anjGEMwIkg2xX+TKVVGUXwNAc= @@ -48,10 +48,10 @@ github.com/veraison/swid v1.1.1-0.20230911094910-8ffdd07a22ca h1:osmCKwWO/xM68Kz github.com/veraison/swid v1.1.1-0.20230911094910-8ffdd07a22ca/go.mod h1:d5jt76uMNbTfQ+f2qU4Lt8RvWOTsv6PFgstIM1QdMH0= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 9a864400aad55945595ae63e7f14a6e09a2d6102 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Tue, 17 Jun 2025 17:33:20 +0000 Subject: [PATCH 2/3] Split switch of private keys and public keys The linter does not appear to like that ecdsa.PrivateKey contains an unnamed ecdsa.PublicKey. Signed-off-by: Dionna Glaze --- corim/signer.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/corim/signer.go b/corim/signer.go index 39bd7f50..1410c364 100644 --- a/corim/signer.go +++ b/corim/signer.go @@ -152,21 +152,29 @@ func getAlgAndKeyFromJWK(j []byte) (cose.Algorithm, any, error) { } return alg, key, nil } + // Private and public need to be in separate switches due to tooling failure when + // a private key type extends the public key type. switch v := key.(type) { case *ecdsa.PrivateKey: return fromCurve(v.Curve) - case *ecdsa.PublicKey: - return fromCurve(v.Curve) case ed25519.PrivateKey: return cose.AlgorithmEd25519, key, nil - case ed25519.PublicKey: - return cose.AlgorithmEd25519, key, nil case *rsa.PrivateKey: return isRsa() + default: + err = fmt.Errorf("unknown private key type %v", reflect.TypeOf(key)) + alg = noAlg + } + switch v := key.(type) { + case *ecdsa.PublicKey: + return fromCurve(v.Curve) + case ed25519.PublicKey: + return cose.AlgorithmEd25519, key, nil case *rsa.PublicKey: return isRsa() default: - return noAlg, nil, fmt.Errorf("unknown private key type %v", reflect.TypeOf(key)) + err = errors.Join(err, fmt.Errorf("unknown public key type %v", reflect.TypeOf(key))) + return noAlg, nil, err } } From 7627b0df75860445d1f5e00dc756650d54845297 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Tue, 17 Jun 2025 19:01:48 +0000 Subject: [PATCH 3/3] Remove broken unnecessary typecheck lint. Signed-off-by: Dionna Glaze --- .golangci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 51cc9e70..507c5593 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -51,7 +51,6 @@ linters: - misspell - revive - staticcheck - - typecheck - unconvert - unused