package signing_test import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "math/big" "testing" "time" "git.cacert.org/cacert-gosigner/pkg/x509/signing" "github.com/stretchr/testify/assert" ) type testRepo struct { certs map[string]x509.Certificate } func (r *testRepo) StoreCertificate(certificate *x509.Certificate) error { r.certs[certificate.SerialNumber.Text(16)] = *certificate return nil } type testSigner struct { t *testing.T key crypto.PrivateKey certificate *x509.Certificate } func newTestSignerResponse(certificate *x509.Certificate) *signing.SignerResponse { return &signing.SignerResponse{Certificate: certificate} } func randomSerial(t *testing.T) *big.Int { t.Helper() serial, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) if err != nil { t.Fatalf("could not generate random serial number: %v", err) } return serial } func (s *testSigner) SignCertificate(request *signing.SignerRequest) (*signing.SignerResponse, error) { startDate := time.Now().Add(-1 * time.Minute) template := &x509.Certificate{ Subject: request.SubjectDN, SerialNumber: randomSerial(s.t), EmailAddresses: request.Emails, NotBefore: startDate, NotAfter: startDate.Add(request.Duration), KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageEmailProtection}, SignatureAlgorithm: request.SignatureAlgorithm, } certBytes, err := x509.CreateCertificate(rand.Reader, template, s.certificate, request.CSR.PublicKey, s.key) if err != nil { return nil, err } certificate, err := x509.ParseCertificate(certBytes) if err != nil { return nil, err } return newTestSignerResponse(certificate), nil } func TestSigning(t *testing.T) { testRepository := testRepo{certs: make(map[string]x509.Certificate)} testSigner := newTestSigner(t) s := signing.NewX509Signing(testSigner, &testRepository) csrKey, err := rsa.GenerateKey(rand.Reader, 3072) if err != nil { t.Errorf("could not generate key pair") } csrTemplate := &x509.CertificateRequest{PublicKey: csrKey.Public()} csrBytes, err := x509.CreateCertificateRequest(rand.Reader, csrTemplate, csrKey) if err != nil { t.Error(err) } testRequest := signing.NewRequestSignature(csrBytes, "Test Subject", []string{"test@example.org"}, nil, 365*24*time.Hour, x509.SHA384WithRSA) signed, err := s.Sign(testRequest) if err != nil { t.Error(err) } cert := signed.Certificate() assert.Contains(t, testRepository.certs, cert.SerialNumber.Text(16)) assert.Equal(t, cert.Subject.CommonName, "Test Subject") assert.Contains(t, cert.EmailAddresses, "test@example.org") } func newTestSigner(t *testing.T) *testSigner { t.Helper() caKey, err := rsa.GenerateKey(rand.Reader, 3072) if err != nil { t.Fatalf("could not generate key pair: %v", err) } caTemplate := &x509.Certificate{Subject: pkix.Name{CommonName: "Test CA"}, SerialNumber: randomSerial(t)} certificateBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, caKey.Public(), caKey) if err != nil { t.Fatalf("could not self-sign CA certificate: %v", err) } caCertificate, err := x509.ParseCertificate(certificateBytes) if err != nil { t.Fatalf("could not create test CA certificate: %v", err) } return &testSigner{key: caKey, certificate: caCertificate, t: t} }