153 lines
2.7 KiB
Go
153 lines
2.7 KiB
Go
package key
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"io"
|
|
"time"
|
|
|
|
"github.com/coreos/go-oidc/jose"
|
|
)
|
|
|
|
func NewPublicKey(jwk jose.JWK) *PublicKey {
|
|
return &PublicKey{jwk: jwk}
|
|
}
|
|
|
|
type PublicKey struct {
|
|
jwk jose.JWK
|
|
}
|
|
|
|
func (k *PublicKey) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(&k.jwk)
|
|
}
|
|
|
|
func (k *PublicKey) UnmarshalJSON(data []byte) error {
|
|
var jwk jose.JWK
|
|
if err := json.Unmarshal(data, &jwk); err != nil {
|
|
return err
|
|
}
|
|
k.jwk = jwk
|
|
return nil
|
|
}
|
|
|
|
func (k *PublicKey) ID() string {
|
|
return k.jwk.ID
|
|
}
|
|
|
|
func (k *PublicKey) Verifier() (jose.Verifier, error) {
|
|
return jose.NewVerifierRSA(k.jwk)
|
|
}
|
|
|
|
type PrivateKey struct {
|
|
KeyID string
|
|
PrivateKey *rsa.PrivateKey
|
|
}
|
|
|
|
func (k *PrivateKey) ID() string {
|
|
return k.KeyID
|
|
}
|
|
|
|
func (k *PrivateKey) Signer() jose.Signer {
|
|
return jose.NewSignerRSA(k.ID(), *k.PrivateKey)
|
|
}
|
|
|
|
func (k *PrivateKey) JWK() jose.JWK {
|
|
return jose.JWK{
|
|
ID: k.KeyID,
|
|
Type: "RSA",
|
|
Alg: "RS256",
|
|
Use: "sig",
|
|
Exponent: k.PrivateKey.PublicKey.E,
|
|
Modulus: k.PrivateKey.PublicKey.N,
|
|
}
|
|
}
|
|
|
|
type KeySet interface {
|
|
ExpiresAt() time.Time
|
|
}
|
|
|
|
type PublicKeySet struct {
|
|
keys []PublicKey
|
|
index map[string]*PublicKey
|
|
expiresAt time.Time
|
|
}
|
|
|
|
func NewPublicKeySet(jwks []jose.JWK, exp time.Time) *PublicKeySet {
|
|
keys := make([]PublicKey, len(jwks))
|
|
index := make(map[string]*PublicKey)
|
|
for i, jwk := range jwks {
|
|
keys[i] = *NewPublicKey(jwk)
|
|
index[keys[i].ID()] = &keys[i]
|
|
}
|
|
return &PublicKeySet{
|
|
keys: keys,
|
|
index: index,
|
|
expiresAt: exp,
|
|
}
|
|
}
|
|
|
|
func (s *PublicKeySet) ExpiresAt() time.Time {
|
|
return s.expiresAt
|
|
}
|
|
|
|
func (s *PublicKeySet) Keys() []PublicKey {
|
|
return s.keys
|
|
}
|
|
|
|
func (s *PublicKeySet) Key(id string) *PublicKey {
|
|
return s.index[id]
|
|
}
|
|
|
|
type PrivateKeySet struct {
|
|
keys []*PrivateKey
|
|
ActiveKeyID string
|
|
expiresAt time.Time
|
|
}
|
|
|
|
func NewPrivateKeySet(keys []*PrivateKey, exp time.Time) *PrivateKeySet {
|
|
return &PrivateKeySet{
|
|
keys: keys,
|
|
ActiveKeyID: keys[0].ID(),
|
|
expiresAt: exp.UTC(),
|
|
}
|
|
}
|
|
|
|
func (s *PrivateKeySet) Keys() []*PrivateKey {
|
|
return s.keys
|
|
}
|
|
|
|
func (s *PrivateKeySet) ExpiresAt() time.Time {
|
|
return s.expiresAt
|
|
}
|
|
|
|
func (s *PrivateKeySet) Active() *PrivateKey {
|
|
for i, k := range s.keys {
|
|
if k.ID() == s.ActiveKeyID {
|
|
return s.keys[i]
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type GeneratePrivateKeyFunc func() (*PrivateKey, error)
|
|
|
|
func GeneratePrivateKey() (*PrivateKey, error) {
|
|
pk, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
keyID := make([]byte, 20)
|
|
if _, err := io.ReadFull(rand.Reader, keyID); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
k := PrivateKey{
|
|
KeyID: hex.EncodeToString(keyID),
|
|
PrivateKey: pk,
|
|
}
|
|
|
|
return &k, nil
|
|
}
|