forked from Mirrors/oauth2
jws: add EncodeWithSigner function.
This permits controlling the mechanism for signing the token; for instance, one can use EncodeWithSigner in an App Engine app to use the App Identity API to perform the signing (you don't have direct access to the private key there). An alternate would be to replace Encode with EncodeWithSigner, and add a little wrapper type that turns a *rsa.PrivateKey into a Signer. That's probably what I'd do if this were being written from scratch, but I wasn't keen on breaking existing code. Change-Id: Id48f5dfa15c179832e613268d4a4098b96648f9a Reviewed-on: https://go-review.googlesource.com/16711 Reviewed-by: Burcu Dogan <jbd@google.com> Run-TryBot: David Symonds <dsymonds@golang.org> Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
parent
038cb4adce
commit
e347d2238c
25
jws/jws.go
25
jws/jws.go
|
@ -119,8 +119,11 @@ func Decode(payload string) (*ClaimSet, error) {
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode encodes a signed JWS with provided header and claim set.
|
// Signer returns a signature for the given data.
|
||||||
func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, error) {
|
type Signer func(data []byte) (sig []byte, err error)
|
||||||
|
|
||||||
|
// EncodeWithSigner encodes a header and claim set with the provided signer.
|
||||||
|
func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) {
|
||||||
head, err := header.encode()
|
head, err := header.encode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -130,14 +133,22 @@ func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, err
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
ss := fmt.Sprintf("%s.%s", head, cs)
|
ss := fmt.Sprintf("%s.%s", head, cs)
|
||||||
h := sha256.New()
|
sig, err := sg([]byte(ss))
|
||||||
h.Write([]byte(ss))
|
|
||||||
b, err := rsa.SignPKCS1v15(rand.Reader, signature, crypto.SHA256, h.Sum(nil))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
sig := base64Encode(b)
|
return fmt.Sprintf("%s.%s", ss, base64Encode(sig)), nil
|
||||||
return fmt.Sprintf("%s.%s", ss, sig), nil
|
}
|
||||||
|
|
||||||
|
// Encode encodes a signed JWS with provided header and claim set.
|
||||||
|
// This invokes EncodeWithSigner using crypto/rsa.SignPKCS1v15 with the given RSA private key.
|
||||||
|
func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) {
|
||||||
|
sg := func(data []byte) (sig []byte, err error) {
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write([]byte(data))
|
||||||
|
return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil))
|
||||||
|
}
|
||||||
|
return EncodeWithSigner(header, c, sg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// base64Encode returns and Base64url encoded version of the input string with any
|
// base64Encode returns and Base64url encoded version of the input string with any
|
||||||
|
|
Loading…
Reference in New Issue