ocspstapling_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package ocspstapling
  2. import (
  3. "bytes"
  4. "crypto"
  5. "crypto/rand"
  6. "crypto/rsa"
  7. "crypto/x509"
  8. "crypto/x509/pkix"
  9. "encoding/base64"
  10. "math/big"
  11. "os"
  12. "testing"
  13. "github.com/cloudflare/cfssl/certdb"
  14. "github.com/cloudflare/cfssl/certdb/sql"
  15. "github.com/cloudflare/cfssl/certdb/testdb"
  16. "github.com/cloudflare/cfssl/helpers"
  17. ct "github.com/google/certificate-transparency-go"
  18. "golang.org/x/crypto/ocsp"
  19. )
  20. func TestStapleSCTList(t *testing.T) {
  21. t.Skip("broken relating to https://github.com/cloudflare/cfssl/issues/1230")
  22. // issuer is a CA certificate.
  23. issuer, issuerPrivKey, err := makeCert(nil)
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. // responderCert is a certificate for which to make an OCSP response.
  28. responderCert, _, err := makeCert(issuer)
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. template := ocsp.Response{
  33. SerialNumber: responderCert.SerialNumber,
  34. IssuerHash: crypto.SHA256,
  35. Status: ocsp.Good,
  36. }
  37. // respDER is an OCSP response to be added to the database.
  38. respDER, err := ocsp.CreateResponse(issuer, responderCert, template, issuerPrivKey)
  39. if err != nil {
  40. t.Fatal(err)
  41. }
  42. // testDB is an empty DB of OCSP responses.
  43. pwd, err := os.Getwd()
  44. if err != nil {
  45. t.Fatal(err)
  46. }
  47. dbPath := pwd + "/../testdb/certstore_development.db"
  48. testDB := sql.NewAccessor(testdb.SQLiteDB(dbPath))
  49. // Next, we store the OCSP response in the DB.
  50. respSN := responderCert.SerialNumber.Text(16)
  51. testDB.InsertOCSP(certdb.OCSPRecord{
  52. Serial: respSN,
  53. Body: base64.StdEncoding.EncodeToString(respDER),
  54. AKI: "Cornell CS 5152",
  55. })
  56. var zeroSCT ct.SignedCertificateTimestamp
  57. err = StapleSCTList(testDB, respSN, "Cornell CS 5152", []ct.SignedCertificateTimestamp{zeroSCT},
  58. responderCert, issuer, issuerPrivKey)
  59. if err != nil {
  60. t.Fatal(err)
  61. }
  62. // Lastly, we verify that the SCT was inserted.
  63. recs, err := testDB.GetOCSP(respSN, "Cornell CS 5152")
  64. if err != nil {
  65. t.Fatal(err)
  66. }
  67. if len(recs) == 0 {
  68. t.Fatal("SCT could not be retrieved from DB:", zeroSCT)
  69. }
  70. respDER, err = base64.StdEncoding.DecodeString(recs[0].Body)
  71. if err != nil {
  72. t.Fatal(err)
  73. }
  74. response, err := ocsp.ParseResponse(respDER, issuer)
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. scts, err := helpers.SCTListFromOCSPResponse(response)
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. if len(scts) == 0 {
  83. t.Fatal("No SCTs in OCSP response:", response)
  84. }
  85. // Here, we check the equivalence of the SCT we inserted with the SCT
  86. // returned by SCTListFromOCSPResponse.
  87. // sctEquals returns true if all fields of both SCTs are equivalent.
  88. sctEquals := func(sctA, sctB ct.SignedCertificateTimestamp) bool {
  89. if sctA.SCTVersion == sctB.SCTVersion &&
  90. sctA.LogID == sctB.LogID &&
  91. sctA.Timestamp == sctB.Timestamp &&
  92. bytes.Equal(sctA.Extensions, sctB.Extensions) &&
  93. sctA.Signature.Algorithm == sctB.Signature.Algorithm &&
  94. bytes.Equal(sctA.Signature.Signature, sctA.Signature.Signature) {
  95. return true
  96. }
  97. return false
  98. }
  99. if !sctEquals(scts[0], zeroSCT) {
  100. t.Fatal("SCTs do not match:", "\nGot --", scts[0], "\nExpected --", zeroSCT)
  101. }
  102. }
  103. // serialCounter stores the next serial number to be issued by nextSN.
  104. var serialCounter int64
  105. // nextSN returns a new big.Int for creating x509 certificates.
  106. func nextSN() *big.Int {
  107. i := big.NewInt(serialCounter)
  108. serialCounter++
  109. return i
  110. }
  111. // makeCert returns a new x509 certificate with the given issuer certificate.
  112. // If issuer is nil, the certificate is self-signed.
  113. func makeCert(issuer *x509.Certificate) (*x509.Certificate, crypto.Signer, error) {
  114. // Create a new private key
  115. privKey, err := rsa.GenerateKey(rand.Reader, 1024)
  116. if err != nil {
  117. return nil, nil, err
  118. }
  119. template := x509.Certificate{
  120. SerialNumber: nextSN(),
  121. Subject: pkix.Name{
  122. Organization: []string{"Cornell CS 5152"},
  123. },
  124. AuthorityKeyId: []byte{42, 42, 42, 42},
  125. }
  126. if issuer == nil { // the cert is self-signed
  127. issuer = &template
  128. }
  129. der, err := x509.CreateCertificate(rand.Reader, &template, issuer, privKey.Public(), privKey)
  130. if err != nil {
  131. return nil, nil, err
  132. }
  133. cert, err := x509.ParseCertificate(der)
  134. if err != nil {
  135. return nil, nil, err
  136. }
  137. return cert, privKey, nil
  138. }