1
0
Fork 0
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.

245 lines
5.9 KiB
Go

package rtls
import (
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"net"
"testing"
"time"
)
func Test_GenerateCACert(t *testing.T) {
// generate a new CA certificate
certPEM, keyPEM, err := GenerateCACert(pkix.Name{CommonName: "rqlite.io"}, time.Hour, 2048)
if err != nil {
t.Fatal(err)
}
// decode the certificate and private key
cert, _ := pem.Decode(certPEM)
if cert == nil {
t.Fatal("failed to decode certificate")
}
key, _ := pem.Decode(keyPEM)
if err != nil {
t.Fatal("failed to decode key")
}
// parse the certificate and private key
certParsed, err := x509.ParseCertificate(cert.Bytes)
if err != nil {
t.Fatal(err)
}
keyParsed, err := x509.ParsePKCS1PrivateKey(key.Bytes)
if err != nil {
t.Fatal(err)
}
// verify the certificate and private key
if certParsed.Subject.CommonName != "rqlite.io" {
t.Fatal("certificate subject is not correct")
}
if !certParsed.IsCA {
t.Fatal("certificate is not a CA")
}
if certParsed.PublicKey.(*rsa.PublicKey).N.Cmp(keyParsed.N) != 0 {
t.Fatal("certificate and private key do not match")
}
}
func Test_GenerateCASignedCert(t *testing.T) {
caCert, caKey := mustGenerateCACert(pkix.Name{CommonName: "ca.rqlite"})
// generate a new certificate signed by the CA
certPEM, keyPEM, err := GenerateCert(pkix.Name{CommonName: "test"}, 365*24*time.Hour, 2048, caCert, caKey)
if err != nil {
t.Fatal(err)
}
cert, _ := pem.Decode(certPEM)
if cert == nil {
panic("failed to decode certificate")
}
key, _ := pem.Decode(keyPEM)
if key == nil {
panic("failed to decode key")
}
// parse the certificate and private key
parsedCert, err := x509.ParseCertificate(cert.Bytes)
if err != nil {
t.Fatal(err)
}
_, err = x509.ParsePKCS1PrivateKey(key.Bytes)
if err != nil {
t.Fatal(err)
}
// verify the certificate is signed by the CA
if err := parsedCert.CheckSignatureFrom(caCert); err != nil {
t.Fatal(err)
}
if parsedCert.NotBefore.After(time.Now()) {
t.Fatal("certificate is not valid yet")
}
if parsedCert.NotAfter.Before(time.Now()) {
t.Fatal("certificate is expired")
}
if parsedCert.Subject.CommonName != "test" {
t.Fatal("certificate has incorrect subject")
}
expUsage := x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature
if parsedCert.KeyUsage != expUsage {
t.Fatalf("certificate has incorrect key usage, exp %v, got %v", expUsage, parsedCert.KeyUsage)
}
if len(parsedCert.ExtKeyUsage) != 2 ||
parsedCert.ExtKeyUsage[0] != x509.ExtKeyUsageServerAuth ||
parsedCert.ExtKeyUsage[1] != x509.ExtKeyUsageClientAuth {
t.Fatal("certificate has incorrect extended key usage")
}
if parsedCert.IsCA {
t.Fatal("certificate has incorrect basic constraints")
}
}
func Test_GenerateCASignedCertIPSAN(t *testing.T) {
caCert, caKey := mustGenerateCACert(pkix.Name{CommonName: "ca.rqlite"})
// generate a new certificate signed by the CA
certPEM, keyPEM, err := GenerateCertIPSAN(pkix.Name{CommonName: "rqlite"}, 365*24*time.Hour, 2048, caCert, caKey, net.ParseIP("127.0.0.1"))
if err != nil {
t.Fatal(err)
}
cert, _ := pem.Decode(certPEM)
if cert == nil {
t.Fatal("failed to decode certificate")
}
key, _ := pem.Decode(keyPEM)
if keyPEM == nil {
t.Fatal("failed to decode key")
}
// parse the certificate and private key
parsedCert, err := x509.ParseCertificate(cert.Bytes)
if err != nil {
t.Fatal(err)
}
_, err = x509.ParsePKCS1PrivateKey(key.Bytes)
if err != nil {
t.Fatal(err)
}
// verify the certificate is signed by the CA
if err := parsedCert.CheckSignatureFrom(caCert); err != nil {
t.Fatal(err)
}
if parsedCert.NotBefore.After(time.Now()) {
t.Fatal("certificate is not valid yet")
}
if parsedCert.NotAfter.Before(time.Now()) {
t.Fatal("certificate is expired")
}
if parsedCert.Subject.CommonName != "rqlite" {
t.Fatal("certificate has incorrect subject")
}
expUsage := x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature
if parsedCert.KeyUsage != expUsage {
t.Fatalf("certificate has incorrect key usage, exp %v, got %v", expUsage, parsedCert.KeyUsage)
}
if len(parsedCert.ExtKeyUsage) != 2 ||
parsedCert.ExtKeyUsage[0] != x509.ExtKeyUsageServerAuth ||
parsedCert.ExtKeyUsage[1] != x509.ExtKeyUsageClientAuth {
t.Fatal("certificate has incorrect extended key usage")
}
if len(parsedCert.IPAddresses) != 1 || !parsedCert.IPAddresses[0].Equal(net.ParseIP("127.0.0.1")) {
t.Fatal("certificate has incorrect IP SAN")
}
}
func Test_GenerateSelfSignedCert(t *testing.T) {
certPEM, keyPEM, err := GenerateSelfSignedCert(pkix.Name{CommonName: "rqlite"}, 365*24*time.Hour, 2048)
if err != nil {
t.Fatal(err)
}
// decode the certificate and private key
certBlock, _ := pem.Decode(certPEM)
if certBlock == nil {
t.Fatal("failed to decode certificate PEM")
}
keyBlock, _ := pem.Decode(keyPEM)
if keyBlock == nil {
t.Fatal("failed to decode private key PEM")
}
// parse the certificate and private key
cert, err := x509.ParseCertificate(certBlock.Bytes)
if err != nil {
t.Fatal(err)
}
key, err := x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
if err != nil {
t.Fatal(err)
}
// verify the certificate
if err := cert.CheckSignatureFrom(cert); err != nil {
t.Fatal(err)
}
// verify the private key
if err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil {
t.Fatal(err)
}
if err := key.Validate(); err != nil {
t.Fatal(err)
}
}
// mustGenerateCACert generates a new CA certificate and private key.
func mustGenerateCACert(name pkix.Name) (*x509.Certificate, *rsa.PrivateKey) {
certPEM, keyPEM, err := GenerateCACert(name, time.Hour, 2048)
if err != nil {
panic(err)
}
cert, _ := pem.Decode(certPEM)
if cert == nil {
panic("failed to decode certificate")
}
key, _ := pem.Decode(keyPEM)
if key == nil {
panic("failed to decode key")
}
parsedCert, err := x509.ParseCertificate(cert.Bytes)
if err != nil {
panic(err)
}
parsedKey, err := x509.ParsePKCS1PrivateKey(key.Bytes)
if err != nil {
panic(err)
}
return parsedCert, parsedKey
}