Here's a full example for both private and public pem files:
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"io/ioutil"
"log"
)
func RSAConfigSetup(rsaPrivateKeyLocation, privatePassphrase, rsaPublicKeyLocation string) (*rsa.PrivateKey, error) {
if rsaPrivateKeyLocation == "" {
log.Println("No RSA Key given, generating temp one")
return GenRSA(4096)
}
priv, err := ioutil.ReadFile(rsaPrivateKeyLocation)
if err != nil {
log.Println("No RSA private key found, generating temp one")
return GenRSA(4096)
}
privPem, _ := pem.Decode(priv)
if privPem.Type != "RSA PRIVATE KEY" {
log.Println("RSA private key is of the wrong type", privPem.Type)
}
if x509.IsEncryptedPEMBlock(privPem) && privatePassphrase == "" {
log.Println("Passphrase is required to open private pem file")
return GenRSA(4096)
}
var privPemBytes []byte
if privatePassphrase != "" {
privPemBytes, err = x509.DecryptPEMBlock(privPem, []byte(privatePassphrase))
} else {
privPemBytes = privPem.Bytes
}
var parsedKey interface{}
//PKCS1
if parsedKey, err = x509.ParsePKCS1PrivateKey(privPemBytes); err != nil {
//If what you are sitting on is a PKCS#8 encoded key
if parsedKey, err = x509.ParsePKCS8PrivateKey(privPemBytes); err != nil { // note this returns type `interface{}`
log.Println("Unable to parse RSA private key, generating a temp one", err)
return GenRSA(4096)
}
}
var privateKey *rsa.PrivateKey
var ok bool
privateKey, ok = parsedKey.(*rsa.PrivateKey)
if !ok {
log.Println("Unable to parse RSA private key, generating a temp one", err)
return GenRSA(4096)
}
pub, err := ioutil.ReadFile(rsaPublicKeyLocation)
if err != nil {
log.Println("No RSA public key found, generating temp one")
return GenRSA(4096)
}
pubPem, _ := pem.Decode(pub)
if pubPem == nil {
log.Println("Use `ssh-keygen -f id_rsa.pub -e -m pem > id_rsa.pem` to generate the pem encoding of your RSA public key - rsa public key not in pem format")
return GenRSA(4096)
}
if pubPem.Type != "RSA PUBLIC KEY" {
log.Println("RSA public key is of the wrong type", pubPem.Type)
return GenRSA(4096)
}
if parsedKey, err = x509.ParsePKIXPublicKey(pubPem.Bytes); err != nil {
log.Println("Unable to parse RSA public key, generating a temp one", err)
return GenRSA(4096)
}
var pubKey *rsa.PublicKey
if pubKey, ok = parsedKey.(*rsa.PublicKey); !ok {
log.Println("Unable to parse RSA public key, generating a temp one", err)
return GenRSA(4096)
}
privateKey.PublicKey = *pubKey
return privateKey, nil
}
// GenRSA returns a new RSA key of bits length
func GenRSA(bits int) (*rsa.PrivateKey, error) {
key, err := rsa.GenerateKey(rand.Reader, bits)
return key, err
}