Previous commits introduces a new way to generate all X.509 certificates needed for testing. This commit reuses the same method for auth tests. This has two benefits: 1) The new code generates certificates with Subject Alternative Name which means we can use it on systems with Go 1.15 (Fedora 33, RHEL 8.4). 2) The new code generates much saner certificates.
187 lines
3.9 KiB
Go
187 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
)
|
|
|
|
const (
|
|
opensslConfig = "/usr/share/tests/osbuild-composer/x509/openssl.cnf"
|
|
osbuildCAExt = "osbuild_ca_ext"
|
|
osbuildClientExt = "osbuild_client_ext"
|
|
)
|
|
|
|
type certificateKeyPair struct {
|
|
baseDir string
|
|
}
|
|
|
|
func (ckp certificateKeyPair) remove() {
|
|
err := os.RemoveAll(ckp.baseDir)
|
|
if err != nil {
|
|
log.Printf("cannot delete the certificate key pair: %v", err)
|
|
}
|
|
}
|
|
|
|
func (ckp certificateKeyPair) certificate() string {
|
|
return path.Join(ckp.baseDir, "crt")
|
|
}
|
|
|
|
func (ckp certificateKeyPair) key() string {
|
|
return path.Join(ckp.baseDir, "key")
|
|
}
|
|
|
|
func newSelfSignedCertificateKeyPair(subj string) (*certificateKeyPair, error) {
|
|
dir, err := ioutil.TempDir("", "osbuild-auth-tests-")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot create a temporary directory for the certificate: %v", err)
|
|
}
|
|
|
|
ckp := certificateKeyPair{baseDir: dir}
|
|
|
|
cmd := exec.Command(
|
|
"openssl", "req", "-nodes", "-x509",
|
|
"-subj", subj,
|
|
"-out", ckp.certificate(),
|
|
"-keyout", ckp.key(),
|
|
)
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot generate a self-signed certificate: %v", err)
|
|
}
|
|
|
|
return &ckp, nil
|
|
}
|
|
|
|
type ca struct {
|
|
BaseDir string
|
|
}
|
|
|
|
func (c ca) remove() {
|
|
err := os.RemoveAll(c.BaseDir)
|
|
if err != nil {
|
|
log.Printf("cannot delete the ca: %v", err)
|
|
}
|
|
}
|
|
|
|
func (c ca) certificate() string {
|
|
return path.Join(c.BaseDir, "ca.cert.pem")
|
|
}
|
|
|
|
func (c ca) key() string {
|
|
return path.Join(c.BaseDir, "private", "ca.key.pem")
|
|
}
|
|
|
|
func newCA(subj string) (*ca, error) {
|
|
baseDir, err := ioutil.TempDir("", "osbuild-auth-tests-ca")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot create a temporary dir for a new CA: %v", err)
|
|
}
|
|
|
|
err = os.Mkdir(path.Join(baseDir, "certs"), 0700)
|
|
if err != nil {
|
|
innerErr := os.RemoveAll(baseDir)
|
|
if innerErr != nil {
|
|
log.Print(innerErr)
|
|
}
|
|
return nil, fmt.Errorf("cannot create certs dir for the new CA: %v", err)
|
|
}
|
|
|
|
err = os.Mkdir(path.Join(baseDir, "private"), 0700)
|
|
if err != nil {
|
|
innerErr := os.RemoveAll(baseDir)
|
|
if innerErr != nil {
|
|
log.Print(innerErr)
|
|
}
|
|
return nil, fmt.Errorf("cannot create private dir for the new CA: %v", err)
|
|
}
|
|
|
|
f, err := os.Create(path.Join(baseDir, "index.txt"))
|
|
if err != nil {
|
|
innerErr := os.RemoveAll(baseDir)
|
|
if innerErr != nil {
|
|
log.Print(innerErr)
|
|
}
|
|
return nil, fmt.Errorf("cannot create index file for the new CA: %v", err)
|
|
}
|
|
f.Close()
|
|
|
|
c := ca{
|
|
BaseDir: baseDir,
|
|
}
|
|
|
|
cmd := exec.Command(
|
|
"openssl", "req",
|
|
"-config", opensslConfig,
|
|
"-new", "-nodes", "-x509", "-extensions", osbuildCAExt,
|
|
"-subj", subj,
|
|
"-keyout", c.key(),
|
|
"-out", c.certificate(),
|
|
)
|
|
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
innerErr := os.RemoveAll(baseDir)
|
|
if innerErr != nil {
|
|
log.Print(innerErr)
|
|
}
|
|
return nil, fmt.Errorf("cannot create the CA: %v", err)
|
|
}
|
|
|
|
return &c, nil
|
|
}
|
|
|
|
func (c ca) newCertificateKeyPair(subj, extensions, addext string) (*certificateKeyPair, error) {
|
|
dir, err := ioutil.TempDir("", "osbuild-auth-tests-")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot create a temporary directory for the certificate: %v", err)
|
|
}
|
|
|
|
ckp := certificateKeyPair{baseDir: dir}
|
|
certificateRequest := path.Join(dir, "csr")
|
|
|
|
args := []string{
|
|
"req", "-new", "-nodes",
|
|
"-subj", subj,
|
|
"-keyout", ckp.key(),
|
|
"-out", certificateRequest,
|
|
"-config", opensslConfig,
|
|
}
|
|
|
|
if addext != "" {
|
|
args = append(args, "-addext", addext)
|
|
}
|
|
|
|
cmd := exec.Command(
|
|
"openssl",
|
|
args...,
|
|
)
|
|
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot generate a private key and a certificate request: %v", err)
|
|
}
|
|
|
|
defer os.Remove(certificateRequest)
|
|
|
|
cmd = exec.Command(
|
|
"openssl", "ca",
|
|
"-batch",
|
|
"-config", opensslConfig,
|
|
"-extensions", extensions,
|
|
"-in", certificateRequest,
|
|
"-out", ckp.certificate(),
|
|
)
|
|
// this command must be run in the CA base directory
|
|
cmd.Dir = c.BaseDir
|
|
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot sign the certificate: %v", err)
|
|
}
|
|
|
|
return &ckp, nil
|
|
}
|