You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
6.8 KiB
Go
196 lines
6.8 KiB
Go
2 years ago
|
package rtls
|
||
2 years ago
|
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
"crypto/rsa"
|
||
|
"crypto/x509"
|
||
|
"crypto/x509/pkix"
|
||
|
"encoding/pem"
|
||
|
"math/big"
|
||
2 years ago
|
"net"
|
||
2 years ago
|
"time"
|
||
|
)
|
||
|
|
||
2 years ago
|
// GenerateCACert generates a new CA certificate and returns the cert and key as PEM-encoded bytes.
|
||
2 years ago
|
func GenerateCACert(subject pkix.Name, validFor time.Duration, keySize int) ([]byte, []byte, error) {
|
||
2 years ago
|
// generate a new private key
|
||
|
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// generate a new certificate
|
||
|
template := x509.Certificate{
|
||
|
SerialNumber: big.NewInt(1),
|
||
|
Subject: subject,
|
||
|
NotBefore: time.Now(),
|
||
|
NotAfter: time.Now().Add(validFor),
|
||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||
2 years ago
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||
2 years ago
|
IsCA: true,
|
||
|
BasicConstraintsValid: true,
|
||
|
}
|
||
|
|
||
|
// generate a new certificate
|
||
|
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// encode the certificate and private key
|
||
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})
|
||
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||
|
|
||
|
return certPEM, keyPEM, nil
|
||
|
}
|
||
|
|
||
2 years ago
|
// GenerateCert generates a new x509 certificate and returns the cert and key as PEM-encoded bytes.
|
||
|
// The function should take in a subject, a validity period, and a key size. It should optionally
|
||
|
// take in a parent certificate and key. If a parent certificate and key are provided, the new
|
||
2 years ago
|
// certificate should be signed by the parent. If no parent certificate and key are provided,
|
||
|
// the new certificate should be self-signed.
|
||
|
func GenerateCert(subject pkix.Name, validFor time.Duration, keySize int, parent *x509.Certificate, parentKey interface{}) ([]byte, []byte, error) {
|
||
|
// generate a new private key
|
||
|
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// generate a new certificate
|
||
|
template := x509.Certificate{
|
||
|
SerialNumber: big.NewInt(1),
|
||
|
Subject: subject,
|
||
|
NotBefore: time.Now(),
|
||
|
NotAfter: time.Now().Add(validFor),
|
||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||
2 years ago
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||
2 years ago
|
}
|
||
|
|
||
2 years ago
|
signerCert := parent
|
||
|
signerKey := parentKey
|
||
|
if signerCert == nil {
|
||
|
signerCert = &template
|
||
|
signerKey = key
|
||
|
}
|
||
|
cert, err := x509.CreateCertificate(rand.Reader, &template, signerCert, &key.PublicKey, signerKey)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// encode the certificate and private key
|
||
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})
|
||
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||
|
|
||
|
return certPEM, keyPEM, nil
|
||
|
}
|
||
|
|
||
|
func GenerateCertIPSAN(subject pkix.Name, validFor time.Duration, keySize int, parent *x509.Certificate, parentKey interface{}, san net.IP) ([]byte, []byte, error) {
|
||
|
// generate a new private key
|
||
|
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// generate a new certificate
|
||
|
template := x509.Certificate{
|
||
|
SerialNumber: big.NewInt(1),
|
||
|
Subject: subject,
|
||
|
NotBefore: time.Now(),
|
||
|
NotAfter: time.Now().Add(validFor),
|
||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||
2 years ago
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||
2 years ago
|
}
|
||
|
|
||
2 years ago
|
// generate cert template for new certificate suitable for client verification
|
||
|
|
||
2 years ago
|
// Add IP SAN to the certificate
|
||
|
template.IPAddresses = append(template.IPAddresses, san)
|
||
|
|
||
2 years ago
|
signerCert := parent
|
||
|
signerKey := parentKey
|
||
|
if signerCert == nil {
|
||
|
signerCert = &template
|
||
|
signerKey = key
|
||
|
}
|
||
|
cert, err := x509.CreateCertificate(rand.Reader, &template, signerCert, &key.PublicKey, signerKey)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// encode the certificate and private key
|
||
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})
|
||
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||
|
|
||
|
return certPEM, keyPEM, nil
|
||
|
}
|
||
2 years ago
|
|
||
|
// GenerateSelfSignedCert generates a new self-signed certificate and
|
||
|
// returns the cert and key as PEM-encoded bytes.
|
||
|
func GenerateSelfSignedCert(subject pkix.Name, validFor time.Duration, keySize int) ([]byte, []byte, error) {
|
||
|
// generate a new private key
|
||
|
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// generate a new certificate
|
||
|
template := x509.Certificate{
|
||
|
SerialNumber: big.NewInt(1),
|
||
|
Subject: subject,
|
||
|
NotBefore: time.Now(),
|
||
|
NotAfter: time.Now().Add(validFor),
|
||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||
|
IsCA: true,
|
||
|
BasicConstraintsValid: true,
|
||
|
}
|
||
|
|
||
|
// Add IP SAN to the certificate
|
||
|
//template.IPAddresses = append(template.IPAddresses, net.ParseIP("127.0.0.1"))
|
||
|
|
||
|
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// encode the certificate and private key
|
||
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})
|
||
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||
|
|
||
|
return certPEM, keyPEM, nil
|
||
|
}
|
||
|
|
||
|
// GenerateSelfSignedCertIPSAN generates a new self-signed certificate and
|
||
|
// returns the cert and key as PEM-encoded bytes.
|
||
|
func GenerateSelfSignedCertIPSAN(subject pkix.Name, validFor time.Duration, keySize int, san net.IP) ([]byte, []byte, error) {
|
||
|
// generate a new private key
|
||
|
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// generate a new certificate
|
||
|
template := x509.Certificate{
|
||
|
SerialNumber: big.NewInt(1),
|
||
|
Subject: subject,
|
||
|
NotBefore: time.Now(),
|
||
|
NotAfter: time.Now().Add(validFor),
|
||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||
|
IsCA: true,
|
||
|
BasicConstraintsValid: true,
|
||
|
}
|
||
|
template.IPAddresses = append(template.IPAddresses, san)
|
||
|
|
||
|
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
// encode the certificate and private key
|
||
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})
|
||
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||
|
|
||
|
return certPEM, keyPEM, nil
|
||
|
}
|