mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
testlib: Add GenerateCert function
This patch moves the GenerateCert function from the smtpsrv tests to the common testlib, so it can be used by other tests in the future.
This commit is contained in:
@@ -1,16 +1,10 @@
|
|||||||
package smtpsrv
|
package smtpsrv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/pem"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
|
||||||
"net"
|
"net"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"os"
|
"os"
|
||||||
@@ -516,75 +510,6 @@ func BenchmarkManyEmailsParallel(b *testing.B) {
|
|||||||
// === Test environment ===
|
// === Test environment ===
|
||||||
//
|
//
|
||||||
|
|
||||||
// generateCert generates a new, INSECURE self-signed certificate and writes
|
|
||||||
// it to a pair of (cert.pem, key.pem) files to the given path.
|
|
||||||
// Note the certificate is only useful for testing purposes.
|
|
||||||
func generateCert(path string) error {
|
|
||||||
tmpl := x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(1234),
|
|
||||||
Subject: pkix.Name{
|
|
||||||
Organization: []string{"chasquid_test.go"},
|
|
||||||
},
|
|
||||||
|
|
||||||
DNSNames: []string{"localhost"},
|
|
||||||
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
|
|
||||||
|
|
||||||
NotBefore: time.Now(),
|
|
||||||
NotAfter: time.Now().Add(30 * time.Minute),
|
|
||||||
|
|
||||||
KeyUsage: x509.KeyUsageKeyEncipherment |
|
|
||||||
x509.KeyUsageDigitalSignature |
|
|
||||||
x509.KeyUsageCertSign,
|
|
||||||
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
IsCA: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
priv, err := rsa.GenerateKey(rand.Reader, 1024)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
derBytes, err := x509.CreateCertificate(
|
|
||||||
rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a global config for convenience.
|
|
||||||
srvCert, err := x509.ParseCertificate(derBytes)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
rootCAs := x509.NewCertPool()
|
|
||||||
rootCAs.AddCert(srvCert)
|
|
||||||
tlsConfig = &tls.Config{
|
|
||||||
ServerName: "localhost",
|
|
||||||
RootCAs: rootCAs,
|
|
||||||
}
|
|
||||||
|
|
||||||
certOut, err := os.Create(path + "/cert.pem")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer certOut.Close()
|
|
||||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
|
||||||
|
|
||||||
keyOut, err := os.OpenFile(
|
|
||||||
path+"/key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer keyOut.Close()
|
|
||||||
|
|
||||||
block := &pem.Block{
|
|
||||||
Type: "RSA PRIVATE KEY",
|
|
||||||
Bytes: x509.MarshalPKCS1PrivateKey(priv),
|
|
||||||
}
|
|
||||||
pem.Encode(keyOut, block)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// waitForServer waits 5 seconds for the server to start, and returns an error
|
// waitForServer waits 5 seconds for the server to start, and returns an error
|
||||||
// if it fails to do so.
|
// if it fails to do so.
|
||||||
// It does this by repeatedly connecting to the address until it either
|
// It does this by repeatedly connecting to the address until it either
|
||||||
@@ -650,7 +575,7 @@ func realMain(m *testing.M) int {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
err = generateCert(tmpDir)
|
tlsConfig, err = testlib.GenerateCert(tmpDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to generate cert for testing: %v\n", err)
|
fmt.Printf("Failed to generate cert for testing: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -2,7 +2,14 @@
|
|||||||
package testlib
|
package testlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/pem"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -129,3 +136,76 @@ func (c dumbCourier) Deliver(from string, to string, data []byte) (error, bool)
|
|||||||
|
|
||||||
// DumbCourier always succeeds delivery, and ignores everything.
|
// DumbCourier always succeeds delivery, and ignores everything.
|
||||||
var DumbCourier = dumbCourier{}
|
var DumbCourier = dumbCourier{}
|
||||||
|
|
||||||
|
// generateCert generates a new, INSECURE self-signed certificate and writes
|
||||||
|
// it to a pair of (cert.pem, key.pem) files to the given path.
|
||||||
|
// Note the certificate is only useful for testing purposes.
|
||||||
|
func GenerateCert(path string) (*tls.Config, error) {
|
||||||
|
tmpl := x509.Certificate{
|
||||||
|
SerialNumber: big.NewInt(1234),
|
||||||
|
Subject: pkix.Name{
|
||||||
|
Organization: []string{"chasquid_test.go"},
|
||||||
|
},
|
||||||
|
|
||||||
|
DNSNames: []string{"localhost"},
|
||||||
|
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
|
||||||
|
|
||||||
|
NotBefore: time.Now(),
|
||||||
|
NotAfter: time.Now().Add(30 * time.Minute),
|
||||||
|
|
||||||
|
KeyUsage: x509.KeyUsageKeyEncipherment |
|
||||||
|
x509.KeyUsageDigitalSignature |
|
||||||
|
x509.KeyUsageCertSign,
|
||||||
|
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
IsCA: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
derBytes, err := x509.CreateCertificate(
|
||||||
|
rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a global config for convenience.
|
||||||
|
srvCert, err := x509.ParseCertificate(derBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rootCAs := x509.NewCertPool()
|
||||||
|
rootCAs.AddCert(srvCert)
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
ServerName: "localhost",
|
||||||
|
RootCAs: rootCAs,
|
||||||
|
}
|
||||||
|
|
||||||
|
certOut, err := os.Create(path + "/cert.pem")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer certOut.Close()
|
||||||
|
err = pem.Encode(certOut,
|
||||||
|
&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyOut, err := os.OpenFile(
|
||||||
|
path+"/key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer keyOut.Close()
|
||||||
|
|
||||||
|
block := &pem.Block{
|
||||||
|
Type: "RSA PRIVATE KEY",
|
||||||
|
Bytes: x509.MarshalPKCS1PrivateKey(priv),
|
||||||
|
}
|
||||||
|
err = pem.Encode(keyOut, block)
|
||||||
|
return tlsConfig, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,3 +96,25 @@ func TestWaitFor(t *testing.T) {
|
|||||||
t.Errorf("WaitFor(false) worked")
|
t.Errorf("WaitFor(false) worked")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGenerateCert(t *testing.T) {
|
||||||
|
dir := MustTempDir(t)
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
conf, err := GenerateCert(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("GenerateCert returned error: %v", err)
|
||||||
|
}
|
||||||
|
if conf.ServerName != "localhost" {
|
||||||
|
t.Errorf("Config server name %q != localhost", conf.ServerName)
|
||||||
|
}
|
||||||
|
if conf.RootCAs == nil {
|
||||||
|
t.Errorf("Config had an empty RootCAs pool")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateCertBadDir(t *testing.T) {
|
||||||
|
conf, err := GenerateCert("/doesnotexist/")
|
||||||
|
if err == nil || conf != nil {
|
||||||
|
t.Fatalf("GenerateCert returned non-error: %v / %v", conf, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user