2022-02-26 04:14:55 +00:00
|
|
|
package crypto
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/pem"
|
|
|
|
"errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewRSAKey to generate new RSA Key if env is not set
|
2022-02-26 12:44:43 +00:00
|
|
|
// returns key instance, private key string, public key string, jwk string, error
|
|
|
|
func NewRSAKey(algo, keyID string) (*rsa.PrivateKey, string, string, string, error) {
|
2022-02-26 04:14:55 +00:00
|
|
|
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
|
|
if err != nil {
|
2022-02-26 12:44:43 +00:00
|
|
|
return nil, "", "", "", err
|
2022-02-26 04:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
privateKey, publicKey, err := AsRSAStr(key, &key.PublicKey)
|
|
|
|
if err != nil {
|
2022-02-26 12:44:43 +00:00
|
|
|
return nil, "", "", "", err
|
2022-02-26 04:14:55 +00:00
|
|
|
}
|
|
|
|
|
2022-02-26 12:44:43 +00:00
|
|
|
jwkPublicKey, err := GetPubJWK(algo, keyID, &key.PublicKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, "", "", "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return key, privateKey, publicKey, string(jwkPublicKey), err
|
2022-02-26 04:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// IsRSA checks if given string is valid RSA algo
|
|
|
|
func IsRSA(algo string) bool {
|
|
|
|
switch algo {
|
|
|
|
case "RS256", "RS384", "RS512":
|
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExportRsaPrivateKeyAsPemStr to get RSA private key as pem string
|
|
|
|
func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string {
|
|
|
|
privkeyBytes := x509.MarshalPKCS1PrivateKey(privkey)
|
|
|
|
privkeyPem := pem.EncodeToMemory(
|
|
|
|
&pem.Block{
|
|
|
|
Type: "RSA PRIVATE KEY",
|
|
|
|
Bytes: privkeyBytes,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return string(privkeyPem)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExportRsaPublicKeyAsPemStr to get RSA public key as pem string
|
2022-02-26 12:44:43 +00:00
|
|
|
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) string {
|
|
|
|
pubkeyBytes := x509.MarshalPKCS1PublicKey(pubkey)
|
2022-02-26 04:14:55 +00:00
|
|
|
pubkeyPem := pem.EncodeToMemory(
|
|
|
|
&pem.Block{
|
|
|
|
Type: "RSA PUBLIC KEY",
|
|
|
|
Bytes: pubkeyBytes,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2022-02-26 12:44:43 +00:00
|
|
|
return string(pubkeyPem)
|
2022-02-26 04:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ParseRsaPrivateKeyFromPemStr to parse RSA private key from pem string
|
|
|
|
func ParseRsaPrivateKeyFromPemStr(privPEM string) (*rsa.PrivateKey, error) {
|
|
|
|
block, _ := pem.Decode([]byte(privPEM))
|
|
|
|
if block == nil {
|
|
|
|
return nil, errors.New("failed to parse PEM block containing the key")
|
|
|
|
}
|
|
|
|
|
|
|
|
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return priv, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ParseRsaPublicKeyFromPemStr to parse RSA public key from pem string
|
|
|
|
func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) {
|
|
|
|
block, _ := pem.Decode([]byte(pubPEM))
|
|
|
|
if block == nil {
|
|
|
|
return nil, errors.New("failed to parse PEM block containing the key")
|
|
|
|
}
|
|
|
|
|
2022-02-26 12:44:43 +00:00
|
|
|
pub, err := x509.ParsePKCS1PublicKey(block.Bytes)
|
2022-02-26 04:14:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-02-26 12:44:43 +00:00
|
|
|
return pub, nil
|
2022-02-26 04:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
2022-02-26 12:44:43 +00:00
|
|
|
pubPem := ExportRsaPublicKeyAsPemStr(publickKey)
|
2022-02-26 04:14:55 +00:00
|
|
|
|
|
|
|
// Import the keys from pem string
|
|
|
|
privParsed, err := ParseRsaPrivateKeyFromPemStr(privPem)
|
|
|
|
if err != nil {
|
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
pubParsed, err := ParseRsaPublicKeyFromPemStr(pubPem)
|
|
|
|
if err != nil {
|
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Export the newly imported keys
|
|
|
|
privParsedPem := ExportRsaPrivateKeyAsPemStr(privParsed)
|
2022-02-26 12:44:43 +00:00
|
|
|
pubParsedPem := ExportRsaPublicKeyAsPemStr(pubParsed)
|
2022-02-26 04:14:55 +00:00
|
|
|
|
|
|
|
return privParsedPem, pubParsedPem, nil
|
|
|
|
}
|