112 lines
2.6 KiB
Go
112 lines
2.6 KiB
Go
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), "=")
|
|
}
|