2021-11-02 07:43:52 +00:00
|
|
|
package jwk
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2021-12-04 07:55:00 +00:00
|
|
|
"io"
|
2021-11-03 17:41:03 +00:00
|
|
|
"mercan.dev/dumb-jose/internal/publickey"
|
2021-11-02 07:43:52 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type PublicKeyHeader interface{}
|
|
|
|
|
|
|
|
type JWK struct {
|
|
|
|
KeyID string `json:"kid"`
|
|
|
|
KeyType string `json:"kty"`
|
|
|
|
Algorithm string `json:"alg"`
|
|
|
|
UseCase string `json:"use"`
|
|
|
|
PublicKey crypto.PublicKey `json:"-"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type jwkHeader struct {
|
|
|
|
Keys []json.RawMessage `json:"keys"`
|
|
|
|
}
|
|
|
|
|
2021-12-04 07:55:00 +00:00
|
|
|
func ParseKeysFromSet(r io.Reader) ([]JWK, error) {
|
|
|
|
dec := json.NewDecoder(r)
|
|
|
|
|
2021-11-02 07:43:52 +00:00
|
|
|
keys := jwkHeader{}
|
|
|
|
|
2021-12-04 07:55:00 +00:00
|
|
|
err := dec.Decode(&keys)
|
2021-11-02 07:43:52 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var set []JWK
|
|
|
|
|
|
|
|
for _, key := range keys.Keys {
|
|
|
|
var jwk JWK
|
|
|
|
err := json.Unmarshal(key, &jwk)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if jwk.UseCase != "sig" {
|
|
|
|
return nil, fmt.Errorf("Non-signing use case %s", jwk.UseCase)
|
|
|
|
}
|
|
|
|
|
|
|
|
switch jwk.Algorithm {
|
|
|
|
case "ES256", "ES384", "ES512":
|
|
|
|
if jwk.KeyType != "EC" {
|
|
|
|
return nil, fmt.Errorf("Insuitable key type %s for algorithm %s", jwk.KeyType, jwk.Algorithm)
|
|
|
|
}
|
|
|
|
|
2021-11-03 17:41:03 +00:00
|
|
|
jwk.PublicKey, err = publickey.ParseECDSAPublicKey(key)
|
2021-11-02 07:43:52 +00:00
|
|
|
case "RS256", "RS384", "RS512", "PS256", "PS384", "PS512":
|
|
|
|
if jwk.KeyType != "RSA" {
|
|
|
|
return nil, fmt.Errorf("Insuitable key type %s for algorithm %s", jwk.KeyType, jwk.Algorithm)
|
|
|
|
}
|
|
|
|
|
2021-11-03 17:41:03 +00:00
|
|
|
jwk.PublicKey, err = publickey.ParseRSAPublicKey(key)
|
2021-11-02 07:43:52 +00:00
|
|
|
case "EdDSA":
|
|
|
|
if jwk.KeyType != "OKP" {
|
|
|
|
return nil, fmt.Errorf("Insuitable key type %s for algorithm %s", jwk.KeyType, jwk.Algorithm)
|
|
|
|
}
|
|
|
|
|
2021-11-03 17:41:03 +00:00
|
|
|
jwk.PublicKey, err = publickey.ParseEdDSAPublicKey(key)
|
2021-11-02 07:43:52 +00:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("Invalid/Unsupported JWK Algorithm %s", jwk.Algorithm)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
set = append(set, jwk)
|
|
|
|
}
|
|
|
|
|
|
|
|
return set, nil
|
|
|
|
}
|