package jwa import ( "errors" "fmt" "strconv" ) // SignatureAlgorithm represents the various signature algorithms as described in https://tools.ietf.org/html/rfc7518#section-3.1 type SignatureAlgorithm string var signatureAlg = map[string]struct{}{"ES256": {}, "ES384": {}, "ES512": {}, "HS256": {}, "HS384": {}, "HS512": {}, "PS256": {}, "PS384": {}, "PS512": {}, "RS256": {}, "RS384": {}, "RS512": {}, "none": {}} // Supported values for SignatureAlgorithm const ( ES256 SignatureAlgorithm = "ES256" // ECDSA using P-256 and SHA-256 ES384 SignatureAlgorithm = "ES384" // ECDSA using P-384 and SHA-384 ES512 SignatureAlgorithm = "ES512" // ECDSA using P-521 and SHA-512 HS256 SignatureAlgorithm = "HS256" // HMAC using SHA-256 HS384 SignatureAlgorithm = "HS384" // HMAC using SHA-384 HS512 SignatureAlgorithm = "HS512" // HMAC using SHA-512 NoSignature SignatureAlgorithm = "none" PS256 SignatureAlgorithm = "PS256" // RSASSA-PSS using SHA256 and MGF1-SHA256 PS384 SignatureAlgorithm = "PS384" // RSASSA-PSS using SHA384 and MGF1-SHA384 PS512 SignatureAlgorithm = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512 RS256 SignatureAlgorithm = "RS256" // RSASSA-PKCS-v1.5 using SHA-256 RS384 SignatureAlgorithm = "RS384" // RSASSA-PKCS-v1.5 using SHA-384 RS512 SignatureAlgorithm = "RS512" // RSASSA-PKCS-v1.5 using SHA-512 NoValue SignatureAlgorithm = "" // No value is different from none Unsupported SignatureAlgorithm = "unsupported" ) // Accept is used when conversion from values given by // outside sources (such as JSON payloads) is required func (signature *SignatureAlgorithm) Accept(value interface{}) error { var tmp SignatureAlgorithm switch x := value.(type) { case string: tmp = SignatureAlgorithm(x) case SignatureAlgorithm: tmp = x default: return fmt.Errorf("invalid type for jwa.SignatureAlgorithm: %T", value) } _, ok := signatureAlg[tmp.String()] if !ok { return errors.New("unknown signature algorithm") } *signature = tmp return nil } // String returns the string representation of a SignatureAlgorithm func (signature SignatureAlgorithm) String() string { return string(signature) } // UnmarshalJSON unmarshals and checks data as Signature Algorithm func (signature *SignatureAlgorithm) UnmarshalJSON(data []byte) error { var quote byte = '"' var quoted string if data[0] == quote { var err error quoted, err = strconv.Unquote(string(data)) if err != nil { return fmt.Errorf("failed to process signature algorithm: %w", err) } } else { quoted = string(data) } _, ok := signatureAlg[quoted] if !ok { *signature = Unsupported return nil } *signature = SignatureAlgorithm(quoted) return nil }