// VerifyWithJKU verifies the JWS message using a remote JWK // file represented in the url. func VerifyWithJKU(buf []byte, jwkurl string) ([]byte, error) { key, err := jwk.FetchHTTP(jwkurl) if err != nil { return nil, err } return VerifyWithJWK(buf, key) }
func ExampleJWK() { set, err := jwk.FetchHTTP("https://foobar.domain/jwk.json") if err != nil { log.Printf("failed to parse JWK: %s", err) return } // If you KNOW you have exactly one key, you can just // use set.Keys[0] keys := set.LookupKeyID("mykey") if len(keys) == 0 { log.Printf("failed to lookup key: %s", err) return } key, err := keys[0].Materialize() if err != nil { log.Printf("failed to create public key: %s", err) return } // Use key for jws.Verify() or whatever _ = key }
func doJWK() int { c := JWKConfig{} flag.StringVar(&c.JWKLocation, "jwk", "", "JWK location, either a local file or a URL") flag.Parse() var key *jwk.Set if c.JWKLocation == "" { fmt.Printf("-jwk must be specified\n") return 1 } if u, err := url.Parse(c.JWKLocation); err == nil && (u.Scheme == "http" || u.Scheme == "https") { var err error key, err = jwk.FetchHTTP(c.JWKLocation) if err != nil { log.Printf("Failed to fetch remote JWK: %s", err) return 0 } } else { var err error key, err = jwk.FetchFile(c.JWKLocation) if err != nil { log.Printf("Failed to fetch remote JWK: %s", err) return 0 } } keybuf, err := json.MarshalIndent(key, "", " ") if err != nil { log.Printf("Failed to marshal JWK: %s", err) return 0 } log.Printf("=== JWK ===") for _, l := range bytes.Split(keybuf, []byte{'\n'}) { log.Printf("%s", l) } // TODO make it flexible pubkey, err := (key.Keys[0]).(*jwk.RsaPublicKey).PublicKey() if err != nil { log.Printf("Failed to get public key from JWK: %s", err) return 0 } var payload io.Reader if c.Payload == "" { payload = os.Stdin } else { f, err := os.Open(c.Payload) if err != nil { log.Printf("Failed to open file '%s': %s", c.Payload, err) return 1 } payload = f defer f.Close() } buf, err := ioutil.ReadAll(payload) if err != nil { log.Printf("Failed to read payload: %s", err) return 0 } message, err := jws.Parse(buf) if err != nil { log.Printf("Failed to parse JWS: %s", err) return 0 } log.Printf("=== Payload ===") // See if this is JSON. if it is, display it nicely m := map[string]interface{}{} if err := json.Unmarshal(message.Payload, &m); err == nil { payloadbuf, err := json.MarshalIndent(m, "", " ") if err != nil { log.Printf("Failed to marshal payload: %s", err) return 0 } for _, l := range bytes.Split(payloadbuf, []byte{'\n'}) { log.Printf("%s", l) } } else { log.Printf("%s", message.Payload) } for i, sig := range message.Signatures { log.Printf("=== Signature %d ===", i) sigbuf, err := json.MarshalIndent(sig, "", " ") if err != nil { log.Printf("ERROR: Failed to marshal signature %d as JSON: %s", i, err) return 0 } for _, l := range bytes.Split(sigbuf, []byte{'\n'}) { log.Printf("%s", l) } v, err := jws.NewRsaVerify(sig.ProtectedHeader.Algorithm, pubkey) if err != nil { log.Printf("ERROR: Failed to create verifier: %s", err) continue } if err := v.Verify(message); err == nil { log.Printf("=== Verified with signature %d! ===", i) } } return 1 }