package signing_test import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "math/big" rand2 "math/rand" "testing" "time" "git.cacert.org/cacert-gosigner/x509/signing" "github.com/stretchr/testify/assert" ) type testRepo struct { certs map[string]x509.Certificate } func (r *testRepo) StoreCertificate(c *signing.CertificateSigned) error { cert := c.Certificate() r.certs[cert.SerialNumber.Text(16)] = *cert return nil } type testSigner struct { key crypto.PrivateKey certificate *x509.Certificate } type testSignerResponse struct { certificate *x509.Certificate } func (t testSignerResponse) Certificate() *x509.Certificate { return t.certificate } func newTestSignerResponse(certificate *x509.Certificate) *testSignerResponse { return &testSignerResponse{certificate: certificate} } func (s *testSigner) SignCertificate(request *signing.SignerRequest) (signing.SignerResponse, error) { startDate := time.Now().Add(-1 * time.Minute) template := &x509.Certificate{ Subject: request.SubjectDN(), SerialNumber: big.NewInt(rand2.Int63()), 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) { rand2.Seed(time.Now().UnixMilli()) 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: big.NewInt(rand2.Int63())} 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} }