thinner wrapping, add exp to jwk
This commit is contained in:
parent
517865f334
commit
84b07108b6
37
keypairs.go
37
keypairs.go
|
@ -19,8 +19,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var EInvalidPrivateKey = errors.New("PrivateKey must be of type rsa.PrivateKey or ecdsa.PrivateKey")
|
var EInvalidPrivateKey = errors.New("PrivateKey must be of type *rsa.PrivateKey or *ecdsa.PrivateKey")
|
||||||
var EInvalidPublicKey = errors.New("PublicKey must be of type rsa.PublicKey or ecdsa.PublicKey")
|
var EInvalidPublicKey = errors.New("PublicKey must be of type *rsa.PublicKey or *ecdsa.PublicKey")
|
||||||
var EParsePrivateKey = errors.New("PrivateKey bytes could not be parsed as PEM or DER (PKCS8, SEC1, or PKCS1) or JWK")
|
var EParsePrivateKey = errors.New("PrivateKey bytes could not be parsed as PEM or DER (PKCS8, SEC1, or PKCS1) or JWK")
|
||||||
var EParseJWK = errors.New("JWK is missing required base64-encoded JSON fields")
|
var EParseJWK = errors.New("JWK is missing required base64-encoded JSON fields")
|
||||||
var EInvalidKeyType = errors.New("The JWK's 'kty' must be either 'RSA' or 'EC'")
|
var EInvalidKeyType = errors.New("The JWK's 'kty' must be either 'RSA' or 'EC'")
|
||||||
|
@ -60,15 +60,22 @@ func (p *ECPublicKey) Thumbprint() string {
|
||||||
func (p *ECPublicKey) Key() crypto.PublicKey {
|
func (p *ECPublicKey) Key() crypto.PublicKey {
|
||||||
return p.PublicKey
|
return p.PublicKey
|
||||||
}
|
}
|
||||||
|
func (p *ECPublicKey) ExpireAt(t time.Time) {
|
||||||
|
p.Expiry = t
|
||||||
|
}
|
||||||
|
|
||||||
func (p *RSAPublicKey) Thumbprint() string {
|
func (p *RSAPublicKey) Thumbprint() string {
|
||||||
return ThumbprintUntypedPublicKey(p.PublicKey)
|
return ThumbprintUntypedPublicKey(p.PublicKey)
|
||||||
}
|
}
|
||||||
func (p *RSAPublicKey) Key() crypto.PublicKey {
|
func (p *RSAPublicKey) Key() crypto.PublicKey {
|
||||||
return p.PublicKey
|
return p.PublicKey
|
||||||
}
|
}
|
||||||
|
func (p *RSAPublicKey) ExpireAt(t time.Time) {
|
||||||
|
p.Expiry = t
|
||||||
|
}
|
||||||
|
|
||||||
// TypesafePublicKey wraps a crypto.PublicKey to make it typesafe.
|
// TypesafePublicKey wraps a crypto.PublicKey to make it typesafe.
|
||||||
func NewPublicKey(pub crypto.PublicKey, exp time.Time, kid ...string) PublicKey {
|
func NewPublicKey(pub crypto.PublicKey, kid ...string) PublicKey {
|
||||||
var k PublicKey
|
var k PublicKey
|
||||||
switch p := pub.(type) {
|
switch p := pub.(type) {
|
||||||
case *ecdsa.PublicKey:
|
case *ecdsa.PublicKey:
|
||||||
|
@ -80,7 +87,6 @@ func NewPublicKey(pub crypto.PublicKey, exp time.Time, kid ...string) PublicKey
|
||||||
} else {
|
} else {
|
||||||
eckey.KID = k.Thumbprint()
|
eckey.KID = k.Thumbprint()
|
||||||
}
|
}
|
||||||
eckey.Expiry = exp
|
|
||||||
k = eckey
|
k = eckey
|
||||||
case *rsa.PublicKey:
|
case *rsa.PublicKey:
|
||||||
rsakey := &RSAPublicKey{
|
rsakey := &RSAPublicKey{
|
||||||
|
@ -91,7 +97,6 @@ func NewPublicKey(pub crypto.PublicKey, exp time.Time, kid ...string) PublicKey
|
||||||
} else {
|
} else {
|
||||||
rsakey.KID = k.Thumbprint()
|
rsakey.KID = k.Thumbprint()
|
||||||
}
|
}
|
||||||
rsakey.Expiry = exp
|
|
||||||
k = rsakey
|
k = rsakey
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PrivateKey:
|
||||||
panic(errors.New(EDevSwapPrivatePublic))
|
panic(errors.New(EDevSwapPrivatePublic))
|
||||||
|
@ -108,13 +113,13 @@ func NewPublicKey(pub crypto.PublicKey, exp time.Time, kid ...string) PublicKey
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalJWKPublicKey(key PublicKey) []byte {
|
func MarshalJWKPublicKey(key PublicKey, exp ...time.Time) []byte {
|
||||||
// thumbprint keys are alphabetically sorted and only include the necessary public parts
|
// thumbprint keys are alphabetically sorted and only include the necessary public parts
|
||||||
switch k := key.Key().(type) {
|
switch k := key.Key().(type) {
|
||||||
case *rsa.PublicKey:
|
case *rsa.PublicKey:
|
||||||
return MarshalRSAPublicKey(k)
|
return MarshalRSAPublicKey(k, exp...)
|
||||||
case *ecdsa.PublicKey:
|
case *ecdsa.PublicKey:
|
||||||
return MarshalECPublicKey(k)
|
return MarshalECPublicKey(k, exp...)
|
||||||
case *dsa.PublicKey:
|
case *dsa.PublicKey:
|
||||||
panic(EInvalidPublicKey)
|
panic(EInvalidPublicKey)
|
||||||
default:
|
default:
|
||||||
|
@ -139,12 +144,16 @@ func ThumbprintUntypedPublicKey(pub crypto.PublicKey) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalECPublicKey(k *ecdsa.PublicKey) []byte {
|
func MarshalECPublicKey(k *ecdsa.PublicKey, exp ...time.Time) []byte {
|
||||||
thumb := ThumbprintECPublicKey(k)
|
thumb := ThumbprintECPublicKey(k)
|
||||||
crv := k.Curve.Params().Name
|
crv := k.Curve.Params().Name
|
||||||
x := base64.RawURLEncoding.EncodeToString(k.X.Bytes())
|
x := base64.RawURLEncoding.EncodeToString(k.X.Bytes())
|
||||||
y := base64.RawURLEncoding.EncodeToString(k.Y.Bytes())
|
y := base64.RawURLEncoding.EncodeToString(k.Y.Bytes())
|
||||||
return []byte(fmt.Sprintf(`{"kid":%q,"crv":%q,"kty":"EC","x":%q,"y":%q}`, thumb, crv, x, y))
|
expstr := ""
|
||||||
|
if 0 != len(exp) {
|
||||||
|
expstr = fmt.Sprintf(`"exp":%q,`, exp[0].Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
return []byte(fmt.Sprintf(`{"kid":%q,%s"crv":%q,"kty":"EC","x":%q,"y":%q}`, expstr, thumb, crv, x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalECPublicKeyWithoutKeyID(k *ecdsa.PublicKey) []byte {
|
func MarshalECPublicKeyWithoutKeyID(k *ecdsa.PublicKey) []byte {
|
||||||
|
@ -160,11 +169,15 @@ func ThumbprintECPublicKey(k *ecdsa.PublicKey) string {
|
||||||
return base64.RawURLEncoding.EncodeToString(sha[:])
|
return base64.RawURLEncoding.EncodeToString(sha[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalRSAPublicKey(p *rsa.PublicKey) []byte {
|
func MarshalRSAPublicKey(p *rsa.PublicKey, exp ...time.Time) []byte {
|
||||||
thumb := ThumbprintRSAPublicKey(p)
|
thumb := ThumbprintRSAPublicKey(p)
|
||||||
e := base64.RawURLEncoding.EncodeToString(big.NewInt(int64(p.E)).Bytes())
|
e := base64.RawURLEncoding.EncodeToString(big.NewInt(int64(p.E)).Bytes())
|
||||||
n := base64.RawURLEncoding.EncodeToString(p.N.Bytes())
|
n := base64.RawURLEncoding.EncodeToString(p.N.Bytes())
|
||||||
return []byte(fmt.Sprintf(`{"kid":%q,"e":%q,"kty":"RSA","n":%q}`, thumb, e, n))
|
expstr := ""
|
||||||
|
if 0 != len(exp) {
|
||||||
|
expstr = fmt.Sprintf(`"exp":%q,`, exp[0].Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
return []byte(fmt.Sprintf(`{"kid":%q,%s"e":%q,"kty":"RSA","n":%q}`, expstr, thumb, e, n))
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalRSAPublicKeyWithoutKeyID(p *rsa.PublicKey) []byte {
|
func MarshalRSAPublicKeyWithoutKeyID(p *rsa.PublicKey) []byte {
|
||||||
|
|
Loading…
Reference in New Issue