Skip to content

Commit 5c40fa7

Browse files
authored
Use JWKS for Attestation Token Vetification (intel#9)
* Use JWKS for Attestation Token Vetification * Incorporated review comments * Incorporated review comments
1 parent 35903a1 commit 5c40fa7

File tree

4 files changed

+78
-19
lines changed

4 files changed

+78
-19
lines changed

go-client/go.mod

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
module github.com/intel/amber-client/go-client
22

3-
go 1.18
3+
go 1.19
44

55
require (
66
github.com/golang-jwt/jwt/v4 v4.4.2
77
github.com/google/uuid v1.3.0
8+
github.com/lestrrat-go/jwx/v2 v2.0.8
89
github.com/pkg/errors v0.9.1
910
github.com/stretchr/testify v1.8.1
1011
)
1112

1213
require (
1314
github.com/davecgh/go-spew v1.1.1 // indirect
15+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
16+
github.com/goccy/go-json v0.9.11 // indirect
17+
github.com/lestrrat-go/blackmagic v1.0.1 // indirect
18+
github.com/lestrrat-go/httpcc v1.0.1 // indirect
19+
github.com/lestrrat-go/httprc v1.0.4 // indirect
20+
github.com/lestrrat-go/iter v1.0.2 // indirect
21+
github.com/lestrrat-go/option v1.0.0 // indirect
1422
github.com/pmezard/go-difflib v1.0.0 // indirect
1523
github.com/stretchr/objx v0.5.0 // indirect
24+
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f // indirect
1625
gopkg.in/yaml.v3 v3.0.1 // indirect
1726
)

go-client/go.sum

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
22
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
33
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
5+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=
6+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc=
7+
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
8+
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
49
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
510
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
611
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
712
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
13+
github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
14+
github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
15+
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
16+
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
17+
github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8=
18+
github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
19+
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
20+
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
21+
github.com/lestrrat-go/jwx/v2 v2.0.8 h1:jCFT8oc0hEDVjgUgsBy1F9cbjsjAVZSXNi7JaU9HR/Q=
22+
github.com/lestrrat-go/jwx/v2 v2.0.8/go.mod h1:zLxnyv9rTlEvOUHbc48FAfIL8iYu2hHvIRaTFGc8mT0=
23+
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
24+
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
825
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
926
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
1027
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -13,10 +30,20 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
1330
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
1431
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
1532
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
33+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1634
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1735
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
1836
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
1937
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
38+
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f h1:OeJjE6G4dgCY4PIXvIRQbE8+RX+uXZyGhUy/ksMGJoc=
39+
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
40+
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
41+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
42+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
43+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
44+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
45+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
46+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
2047
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2148
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2249
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

go-client/token.go

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,15 @@ package client
77

88
import (
99
"bytes"
10-
"crypto"
11-
"crypto/rsa"
12-
"crypto/x509"
1310
"encoding/json"
14-
"encoding/pem"
1511
"fmt"
1612
"io/ioutil"
1713
"net/http"
1814
"net/url"
1915

2016
"github.com/golang-jwt/jwt/v4"
2117
"github.com/google/uuid"
18+
"github.com/lestrrat-go/jwx/v2/jwk"
2219
"github.com/pkg/errors"
2320
)
2421

@@ -86,6 +83,20 @@ func (client *amberClient) GetToken(nonce *Nonce, policyIds []uuid.UUID, evidenc
8683
func (client *amberClient) VerifyToken(token string) (*jwt.Token, error) {
8784

8885
parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
86+
87+
var kid string
88+
89+
keyIDValue, keyIDExists := token.Header["kid"]
90+
if !keyIDExists {
91+
return nil, errors.New("kid field missing in token header")
92+
} else {
93+
var ok bool
94+
kid, ok = keyIDValue.(string)
95+
if !ok {
96+
return nil, errors.Errorf("kid field in jwt header is not valid : %v", kid)
97+
}
98+
}
99+
89100
jkuValue, jkuExists := token.Header["jku"]
90101
if !jkuExists {
91102
return nil, errors.New("jku field missing in token header")
@@ -106,39 +117,38 @@ func (client *amberClient) VerifyToken(token string) (*jwt.Token, error) {
106117
}
107118

108119
var headers = map[string]string{
109-
headerAccept: "application/x-pem-file",
120+
headerAccept: "application/json",
110121
}
111122

112-
var key crypto.PublicKey
123+
var pubKey interface{}
113124
processResponse := func(resp *http.Response) error {
114-
tokenSignCert, err := ioutil.ReadAll(resp.Body)
125+
jwks, err := ioutil.ReadAll(resp.Body)
115126
if err != nil {
116127
return errors.Errorf("Failed to read body from %s: %s", tokenSignCertUrl, err)
117128
}
118129

119-
block, _ := pem.Decode(tokenSignCert)
120-
if block == nil {
121-
return errors.New("Unable to decode pem bytes")
122-
}
123-
124-
cert, err := x509.ParseCertificate(block.Bytes)
130+
jwkSet, err := jwk.Parse(jwks)
125131
if err != nil {
126-
return errors.Wrap(err, "Failed to parse certificate")
132+
return errors.New("Unable to unmarshal response into a JWT Key Set")
127133
}
128134

129-
var ok bool
130-
if key, ok = cert.PublicKey.(*rsa.PublicKey); !ok {
131-
return errors.New("Certificate has invalid public key")
135+
jwkKey, found := jwkSet.LookupKeyID(kid)
136+
if !found {
137+
return errors.New("Could not find Key matching the key id")
132138
}
133139

140+
err = jwkKey.Raw(&pubKey)
141+
if err != nil {
142+
return errors.New("Failed to extract Public Key from Certificate")
143+
}
134144
return nil
135145
}
136146

137147
if err := doRequest(client.cfg.TlsCfg, newRequest, nil, headers, processResponse); err != nil {
138148
return nil, err
139149
}
140150

141-
return key, nil
151+
return pubKey, nil
142152
})
143153
if err != nil {
144154
return nil, errors.Wrap(err, "Failed to parse jwt token")

0 commit comments

Comments
 (0)