certinfo_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package certinfo
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "crypto/x509/pkix"
  8. "encoding/pem"
  9. "math/big"
  10. "strings"
  11. "testing"
  12. "time"
  13. "github.com/cloudflare/cfssl/certdb"
  14. "github.com/cloudflare/cfssl/certdb/sql"
  15. "github.com/cloudflare/cfssl/certdb/testdb"
  16. )
  17. const (
  18. sqliteDBFile = "../certdb/testdb/certstore_development.db"
  19. fakeAKI = "fake_aki"
  20. testSerial = 1337
  21. )
  22. func TestParseSerialNumber(t *testing.T) {
  23. db := testdb.SQLiteDB(sqliteDBFile)
  24. accessor := sql.NewAccessor(db)
  25. certificate, err := createCertificate()
  26. if err != nil {
  27. t.Logf("could not create certificate: %s", err.Error())
  28. t.FailNow()
  29. }
  30. err = accessor.InsertCertificate(
  31. certdb.CertificateRecord{
  32. Serial: big.NewInt(testSerial).String(),
  33. AKI: fakeAKI,
  34. PEM: certificate,
  35. },
  36. )
  37. if err != nil {
  38. t.Log(err.Error())
  39. t.FailNow()
  40. }
  41. cases := []struct {
  42. description string
  43. serial string
  44. aki string
  45. errorShouldContain string
  46. }{
  47. {
  48. description: "no certificate found - wrong serial",
  49. serial: "1",
  50. aki: fakeAKI,
  51. errorShouldContain: "no certificate found",
  52. },
  53. {
  54. description: "no certificate found - wrong AKI",
  55. serial: "123456789",
  56. aki: "1",
  57. errorShouldContain: "no certificate found",
  58. },
  59. {
  60. description: "certificate found",
  61. serial: big.NewInt(testSerial).String(),
  62. aki: fakeAKI,
  63. },
  64. }
  65. for _, tc := range cases {
  66. t.Run(tc.description, func(t *testing.T) {
  67. cert, err := ParseSerialNumber(tc.serial, tc.aki, accessor)
  68. if tc.errorShouldContain != "" {
  69. if cert != nil {
  70. t.Error("no certificate should be returned if error occurs")
  71. }
  72. if err == nil {
  73. t.Error("err expected to not be nil")
  74. return
  75. }
  76. if !strings.Contains(err.Error(), tc.errorShouldContain) {
  77. t.Errorf("expected error to contain '%s' but was '%s'", tc.errorShouldContain, err.Error())
  78. }
  79. return
  80. }
  81. if err != nil {
  82. t.Errorf("expected error to be nil but got '%s'", err.Error())
  83. return
  84. }
  85. if cert.SerialNumber != tc.serial {
  86. t.Errorf("returned certificate doesn't match the serial queried for")
  87. }
  88. })
  89. }
  90. }
  91. func createCertificate() (string, error) {
  92. key, err := rsa.GenerateKey(rand.Reader, 2048)
  93. if err != nil {
  94. return "", err
  95. }
  96. cert := &x509.Certificate{
  97. SerialNumber: big.NewInt(testSerial),
  98. Subject: pkix.Name{
  99. Country: []string{"SE"},
  100. Organization: []string{"CFSSL Unit Testing"},
  101. },
  102. NotBefore: time.Now(),
  103. NotAfter: time.Now().AddDate(1, 0, 0),
  104. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
  105. KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
  106. BasicConstraintsValid: true,
  107. }
  108. certificate, err := x509.CreateCertificate(rand.Reader, cert, cert, &key.PublicKey, key)
  109. if err != nil {
  110. return "", err
  111. }
  112. return certificateToPEMBlock(certificate)
  113. }
  114. func certificateToPEMBlock(cert []byte) (string, error) {
  115. buf := &bytes.Buffer{}
  116. err := pem.Encode(buf, &pem.Block{
  117. Type: "CERTIFICATE",
  118. Bytes: cert,
  119. })
  120. if err != nil {
  121. return "", err
  122. }
  123. return buf.String(), nil
  124. }