mirror of https://github.com/poanetwork/gecko.git
75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
package staking
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"math/big"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
// GenerateStakingKeyCert generates a self-signed TLS key/cert pair to use in staking
|
|
// The key and files will be placed at [keyPath] and [certPath], respectively
|
|
// If there is already a file at [keyPath], returns nil
|
|
func GenerateStakingKeyCert(keyPath, certPath string) error {
|
|
// If there is already a file at [keyPath], do nothing
|
|
if _, err := os.Stat(keyPath); !os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
|
|
// Create key to sign cert with
|
|
key, err := rsa.GenerateKey(rand.Reader, 4096)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't generate rsa key: %w", err)
|
|
}
|
|
|
|
// Create self-signed staking cert
|
|
certTemplate := &x509.Certificate{
|
|
SerialNumber: big.NewInt(0),
|
|
NotBefore: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC),
|
|
NotAfter: time.Now().AddDate(100, 0, 0),
|
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment,
|
|
BasicConstraintsValid: true,
|
|
}
|
|
certBytes, err := x509.CreateCertificate(rand.Reader, certTemplate, certTemplate, &key.PublicKey, key)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't create certificate: %w", err)
|
|
}
|
|
|
|
// Write cert to disk
|
|
if err := os.MkdirAll(filepath.Dir(certPath), 0755); err != nil {
|
|
return fmt.Errorf("couldn't create path for key/cert: %w", err)
|
|
}
|
|
certOut, err := os.Create(certPath)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't create cert file: %w", err)
|
|
}
|
|
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes}); err != nil {
|
|
return fmt.Errorf("couldn't write cert file: %w", err)
|
|
}
|
|
if err := certOut.Close(); err != nil {
|
|
return fmt.Errorf("couldn't close cert file: %w", err)
|
|
}
|
|
|
|
// Write key to disk
|
|
keyOut, err := os.Create(keyPath)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't create key file: %w", err)
|
|
}
|
|
privBytes, err := x509.MarshalPKCS8PrivateKey(key)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't marshal private key: %w", err)
|
|
}
|
|
if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
|
|
return fmt.Errorf("couldn't write private key: %w", err)
|
|
}
|
|
if err := keyOut.Close(); err != nil {
|
|
return fmt.Errorf("couldn't close key file: %w", err)
|
|
}
|
|
return nil
|
|
}
|