feat: add well-known jwks.json endpoint

This commit is contained in:
Lakhan Samani
2022-02-26 18:14:43 +05:30
parent ad46210112
commit 145091dce1
13 changed files with 156 additions and 58 deletions

29
server/crypto/common.go Normal file
View File

@@ -0,0 +1,29 @@
package crypto
import (
"crypto/x509"
"gopkg.in/square/go-jose.v2"
)
// GetPubJWK returns JWK for given keys
func GetPubJWK(algo, keyID string, publicKey interface{}) (string, error) {
jwk := &jose.JSONWebKeySet{
Keys: []jose.JSONWebKey{
{
Algorithm: algo,
Key: publicKey,
Use: "sig",
KeyID: keyID,
Certificates: []*x509.Certificate{},
CertificateThumbprintSHA1: []uint8{},
CertificateThumbprintSHA256: []uint8{},
},
},
}
jwkPublicKey, err := jwk.Keys[0].MarshalJSON()
if err != nil {
return "", err
}
return string(jwkPublicKey), nil
}

View File

@@ -10,18 +10,24 @@ import (
)
// NewECDSAKey to generate new ECDSA Key if env is not set
func NewECDSAKey() (*ecdsa.PrivateKey, string, string, error) {
// returns key instance, private key string, public key string, jwk string, error
func NewECDSAKey(algo, keyID string) (*ecdsa.PrivateKey, string, string, string, error) {
key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
return nil, "", "", err
return nil, "", "", "", err
}
privateKey, publicKey, err := AsECDSAStr(key, &key.PublicKey)
if err != nil {
return nil, "", "", err
return nil, "", "", "", err
}
return key, privateKey, publicKey, err
jwkPublicKey, err := GetPubJWK(algo, keyID, &key.PublicKey)
if err != nil {
return nil, "", "", "", err
}
return key, privateKey, publicKey, string(jwkPublicKey), err
}
// IsECDSA checks if given string is valid ECDSA algo

View File

@@ -1,11 +1,18 @@
package crypto
import "github.com/google/uuid"
import (
"github.com/google/uuid"
)
// NewHMAC key returns new key that can be used to ecnrypt data using HMAC algo
func NewHMACKey() string {
// returns key, string, error
func NewHMACKey(algo, keyID string) (string, string, error) {
key := uuid.New().String()
return key
jwkPublicKey, err := GetPubJWK(algo, keyID, []byte(key))
if err != nil {
return "", "", err
}
return key, string(jwkPublicKey), nil
}
// IsHMACValid checks if given string is valid HMCA algo

View File

@@ -9,18 +9,24 @@ import (
)
// NewRSAKey to generate new RSA Key if env is not set
func NewRSAKey() (*rsa.PrivateKey, string, string, error) {
// returns key instance, private key string, public key string, jwk string, error
func NewRSAKey(algo, keyID string) (*rsa.PrivateKey, string, string, string, error) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, "", "", err
return nil, "", "", "", err
}
privateKey, publicKey, err := AsRSAStr(key, &key.PublicKey)
if err != nil {
return nil, "", "", err
return nil, "", "", "", err
}
return key, privateKey, publicKey, err
jwkPublicKey, err := GetPubJWK(algo, keyID, &key.PublicKey)
if err != nil {
return nil, "", "", "", err
}
return key, privateKey, publicKey, string(jwkPublicKey), err
}
// IsRSA checks if given string is valid RSA algo
@@ -46,11 +52,8 @@ func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string {
}
// ExportRsaPublicKeyAsPemStr to get RSA public key as pem string
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
pubkeyBytes, err := x509.MarshalPKIXPublicKey(pubkey)
if err != nil {
return "", err
}
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) string {
pubkeyBytes := x509.MarshalPKCS1PublicKey(pubkey)
pubkeyPem := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PUBLIC KEY",
@@ -58,7 +61,7 @@ func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
},
)
return string(pubkeyPem), nil
return string(pubkeyPem)
}
// ParseRsaPrivateKeyFromPemStr to parse RSA private key from pem string
@@ -83,28 +86,19 @@ func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) {
return nil, errors.New("failed to parse PEM block containing the key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
pub, err := x509.ParsePKCS1PublicKey(block.Bytes)
if err != nil {
return nil, err
}
switch pub := pub.(type) {
case *rsa.PublicKey:
return pub, nil
default:
break // fall through
}
return nil, errors.New("Key type is not RSA")
return pub, nil
}
// AsRSAStr returns private, public key string or error
func AsRSAStr(privateKey *rsa.PrivateKey, publickKey *rsa.PublicKey) (string, string, error) {
// Export the keys to pem string
privPem := ExportRsaPrivateKeyAsPemStr(privateKey)
pubPem, err := ExportRsaPublicKeyAsPemStr(publickKey)
if err != nil {
return "", "", err
}
pubPem := ExportRsaPublicKeyAsPemStr(publickKey)
// Import the keys from pem string
privParsed, err := ParseRsaPrivateKeyFromPemStr(privPem)
@@ -118,10 +112,7 @@ func AsRSAStr(privateKey *rsa.PrivateKey, publickKey *rsa.PublicKey) (string, st
// Export the newly imported keys
privParsedPem := ExportRsaPrivateKeyAsPemStr(privParsed)
pubParsedPem, err := ExportRsaPublicKeyAsPemStr(pubParsed)
if err != nil {
return "", "", err
}
pubParsedPem := ExportRsaPublicKeyAsPemStr(pubParsed)
return privParsedPem, pubParsedPem, nil
}