mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00
security: switch from RSA-2048 to ECDSA-P256 for agent certs and update certificate config and handling
This commit is contained in:
parent
f45f3fba79
commit
36ceba3ae7
1 changed files with 72 additions and 22 deletions
|
@ -2,7 +2,6 @@ package agent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
|
@ -12,20 +11,37 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CertsDNSName = "godoxy.agent"
|
CertsDNSName = "godoxy.agent"
|
||||||
KeySize = 2048
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func toPEMPair(certDER []byte, key *rsa.PrivateKey) *PEMPair {
|
func toPEMPair(certDER []byte, key *ecdsa.PrivateKey) *PEMPair {
|
||||||
|
marshaledKey, err := marshalECPrivateKey(key)
|
||||||
|
if err != nil {
|
||||||
|
// This is a critical internal error during PEM encoding of a newly generated key.
|
||||||
|
// Panicking is acceptable here as it indicates a fundamental issue.
|
||||||
|
panic(fmt.Sprintf("failed to marshal EC private key for PEM encoding: %v", err))
|
||||||
|
}
|
||||||
return &PEMPair{
|
return &PEMPair{
|
||||||
Cert: pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}),
|
Cert: pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}),
|
||||||
Key: pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}),
|
Key: pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: marshaledKey}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func marshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
|
||||||
|
derBytes, err := x509.MarshalECPrivateKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to marshal EC private key: %w", err)
|
||||||
|
}
|
||||||
|
return derBytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
func b64Encode(data []byte) string {
|
func b64Encode(data []byte) string {
|
||||||
return base64.StdEncoding.EncodeToString(data)
|
return base64.StdEncoding.EncodeToString(data)
|
||||||
}
|
}
|
||||||
|
@ -63,10 +79,23 @@ func (p *PEMPair) ToTLSCert() (*tls.Certificate, error) {
|
||||||
return &cert, err
|
return &cert, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newSerialNumber() (*big.Int, error) {
|
||||||
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) // 128-bit random number
|
||||||
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate serial number: %w", err)
|
||||||
|
}
|
||||||
|
return serialNumber, nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewAgent() (ca, srv, client *PEMPair, err error) {
|
func NewAgent() (ca, srv, client *PEMPair, err error) {
|
||||||
|
caSerialNumber, err := newSerialNumber()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
// Create the CA's certificate
|
// Create the CA's certificate
|
||||||
caTemplate := &x509.Certificate{
|
caTemplate := &x509.Certificate{
|
||||||
SerialNumber: big.NewInt(1),
|
SerialNumber: caSerialNumber,
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
Organization: []string{"GoDoxy"},
|
Organization: []string{"GoDoxy"},
|
||||||
CommonName: CertsDNSName,
|
CommonName: CertsDNSName,
|
||||||
|
@ -76,9 +105,12 @@ func NewAgent() (ca, srv, client *PEMPair, err error) {
|
||||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
IsCA: true,
|
IsCA: true,
|
||||||
|
MaxPathLen: 0,
|
||||||
|
MaxPathLenZero: true,
|
||||||
|
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||||
}
|
}
|
||||||
|
|
||||||
caKey, err := rsa.GenerateKey(rand.Reader, KeySize)
|
caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -91,20 +123,29 @@ func NewAgent() (ca, srv, client *PEMPair, err error) {
|
||||||
ca = toPEMPair(caDER, caKey)
|
ca = toPEMPair(caDER, caKey)
|
||||||
|
|
||||||
// Generate a new private key for the server certificate
|
// Generate a new private key for the server certificate
|
||||||
serverKey, err := rsa.GenerateKey(rand.Reader, KeySize)
|
serverKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverSerialNumber, err := newSerialNumber()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
srvTemplate := &x509.Certificate{
|
srvTemplate := &x509.Certificate{
|
||||||
SerialNumber: big.NewInt(2),
|
SerialNumber: serverSerialNumber,
|
||||||
Issuer: caTemplate.Subject,
|
Issuer: caTemplate.Subject,
|
||||||
Subject: caTemplate.Subject,
|
Subject: pkix.Name{
|
||||||
DNSNames: []string{CertsDNSName},
|
Organization: caTemplate.Subject.Organization,
|
||||||
NotBefore: time.Now(),
|
OrganizationalUnit: []string{"Server"},
|
||||||
NotAfter: time.Now().AddDate(1000, 0, 0), // Add validity period
|
CommonName: CertsDNSName,
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
},
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
DNSNames: []string{CertsDNSName},
|
||||||
|
NotBefore: time.Now(),
|
||||||
|
NotAfter: time.Now().AddDate(1000, 0, 0), // Add validity period
|
||||||
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||||
}
|
}
|
||||||
|
|
||||||
srvCertDER, err := x509.CreateCertificate(rand.Reader, srvTemplate, caTemplate, &serverKey.PublicKey, caKey)
|
srvCertDER, err := x509.CreateCertificate(rand.Reader, srvTemplate, caTemplate, &serverKey.PublicKey, caKey)
|
||||||
|
@ -114,20 +155,29 @@ func NewAgent() (ca, srv, client *PEMPair, err error) {
|
||||||
|
|
||||||
srv = toPEMPair(srvCertDER, serverKey)
|
srv = toPEMPair(srvCertDER, serverKey)
|
||||||
|
|
||||||
clientKey, err := rsa.GenerateKey(rand.Reader, KeySize)
|
clientKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientSerialNumber, err := newSerialNumber()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
clientTemplate := &x509.Certificate{
|
clientTemplate := &x509.Certificate{
|
||||||
SerialNumber: big.NewInt(3),
|
SerialNumber: clientSerialNumber,
|
||||||
Issuer: caTemplate.Subject,
|
Issuer: caTemplate.Subject,
|
||||||
Subject: caTemplate.Subject,
|
Subject: pkix.Name{
|
||||||
DNSNames: []string{CertsDNSName},
|
Organization: caTemplate.Subject.Organization,
|
||||||
NotBefore: time.Now(),
|
OrganizationalUnit: []string{"Client"},
|
||||||
NotAfter: time.Now().AddDate(1000, 0, 0),
|
CommonName: CertsDNSName,
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
},
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
DNSNames: []string{CertsDNSName},
|
||||||
|
NotBefore: time.Now(),
|
||||||
|
NotAfter: time.Now().AddDate(1000, 0, 0),
|
||||||
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||||
}
|
}
|
||||||
clientCertDER, err := x509.CreateCertificate(rand.Reader, clientTemplate, caTemplate, &clientKey.PublicKey, caKey)
|
clientCertDER, err := x509.CreateCertificate(rand.Reader, clientTemplate, caTemplate, &clientKey.PublicKey, caKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue