happyDomain/rsa.go

80 lines
1.7 KiB
Go
Raw Normal View History

2024-10-04 17:18:57 +00:00
package main
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io"
"log"
"os"
)
func generateOrRetrieveRSAKeys(name string, size int) (io.Reader, []byte, error) {
var pemprvkey bytes.Buffer
var prvKey *rsa.PrivateKey
fd, err := os.Open(name + ".pem")
if os.IsNotExist(err) {
log.Println("Private RSA key not found, generating a new one")
fd, err = os.Create(name + ".pem")
if err != nil {
return nil, nil, fmt.Errorf("unable to open the file for writing: %w", err)
}
defer fd.Close()
prvKey, err = rsa.GenerateKey(rand.Reader, size)
if err != nil {
return nil, nil, err
}
pkcs1prvkey := x509.MarshalPKCS1PrivateKey(prvKey)
var tmpprvkey bytes.Buffer
w := io.MultiWriter(&tmpprvkey, &pemprvkey)
err = pem.Encode(w, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: pkcs1prvkey})
if err != nil {
return nil, nil, err
}
// Save it!
_, err = tmpprvkey.WriteTo(fd)
if err != nil {
return nil, nil, err
}
} else if err != nil {
return nil, nil, err
} else {
defer fd.Close()
var tmpprvkey bytes.Buffer
io.Copy(io.MultiWriter(&tmpprvkey, &pemprvkey), fd)
decodedpem, _ := pem.Decode(tmpprvkey.Bytes())
if decodedpem == nil {
return nil, nil, fmt.Errorf("unable to decode PEM data")
} else if decodedpem.Type != "RSA PRIVATE KEY" {
return nil, nil, fmt.Errorf("not the expected PEM type: %s intead of RSA PRIVATE KEY", decodedpem.Type)
}
prvKey, err = x509.ParsePKCS1PrivateKey(decodedpem.Bytes)
}
pubkey := prvKey.Public()
pkixpub, err := x509.MarshalPKIXPublicKey(pubkey.(*rsa.PublicKey))
if err != nil {
return nil, nil, err
}
pempubkey := pem.EncodeToMemory(
&pem.Block{
Type: "PUBLIC KEY",
Bytes: pkixpub,
},
)
return &pemprvkey, pempubkey, nil
}