| package jose |
| |
| import ( |
| "encoding/base64" |
| "encoding/json" |
| "fmt" |
| "strings" |
| ) |
| |
| const ( |
| HeaderMediaType = "typ" |
| HeaderKeyAlgorithm = "alg" |
| HeaderKeyID = "kid" |
| ) |
| |
| const ( |
| // Encryption Algorithm Header Parameter Values for JWS |
| // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-6 |
| AlgHS256 = "HS256" |
| AlgHS384 = "HS384" |
| AlgHS512 = "HS512" |
| AlgRS256 = "RS256" |
| AlgRS384 = "RS384" |
| AlgRS512 = "RS512" |
| AlgES256 = "ES256" |
| AlgES384 = "ES384" |
| AlgES512 = "ES512" |
| AlgPS256 = "PS256" |
| AlgPS384 = "PS384" |
| AlgPS512 = "PS512" |
| AlgNone = "none" |
| ) |
| |
| const ( |
| // Algorithm Header Parameter Values for JWE |
| // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-4.1 |
| AlgRSA15 = "RSA1_5" |
| AlgRSAOAEP = "RSA-OAEP" |
| AlgRSAOAEP256 = "RSA-OAEP-256" |
| AlgA128KW = "A128KW" |
| AlgA192KW = "A192KW" |
| AlgA256KW = "A256KW" |
| AlgDir = "dir" |
| AlgECDHES = "ECDH-ES" |
| AlgECDHESA128KW = "ECDH-ES+A128KW" |
| AlgECDHESA192KW = "ECDH-ES+A192KW" |
| AlgECDHESA256KW = "ECDH-ES+A256KW" |
| AlgA128GCMKW = "A128GCMKW" |
| AlgA192GCMKW = "A192GCMKW" |
| AlgA256GCMKW = "A256GCMKW" |
| AlgPBES2HS256A128KW = "PBES2-HS256+A128KW" |
| AlgPBES2HS384A192KW = "PBES2-HS384+A192KW" |
| AlgPBES2HS512A256KW = "PBES2-HS512+A256KW" |
| ) |
| |
| const ( |
| // Encryption Algorithm Header Parameter Values for JWE |
| // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-22 |
| EncA128CBCHS256 = "A128CBC-HS256" |
| EncA128CBCHS384 = "A128CBC-HS384" |
| EncA256CBCHS512 = "A256CBC-HS512" |
| EncA128GCM = "A128GCM" |
| EncA192GCM = "A192GCM" |
| EncA256GCM = "A256GCM" |
| ) |
| |
| type JOSEHeader map[string]string |
| |
| func (j JOSEHeader) Validate() error { |
| if _, exists := j[HeaderKeyAlgorithm]; !exists { |
| return fmt.Errorf("header missing %q parameter", HeaderKeyAlgorithm) |
| } |
| |
| return nil |
| } |
| |
| func decodeHeader(seg string) (JOSEHeader, error) { |
| b, err := decodeSegment(seg) |
| if err != nil { |
| return nil, err |
| } |
| |
| var h JOSEHeader |
| err = json.Unmarshal(b, &h) |
| if err != nil { |
| return nil, err |
| } |
| |
| return h, nil |
| } |
| |
| func encodeHeader(h JOSEHeader) (string, error) { |
| b, err := json.Marshal(h) |
| if err != nil { |
| return "", err |
| } |
| |
| return encodeSegment(b), nil |
| } |
| |
| // Decode JWT specific base64url encoding with padding stripped |
| func decodeSegment(seg string) ([]byte, error) { |
| if l := len(seg) % 4; l != 0 { |
| seg += strings.Repeat("=", 4-l) |
| } |
| return base64.URLEncoding.DecodeString(seg) |
| } |
| |
| // Encode JWT specific base64url encoding with padding stripped |
| func encodeSegment(seg []byte) string { |
| return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=") |
| } |