/* Copyright 2022 CAcert Inc. SPDX-License-Identifier: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package ocspsource import ( "bytes" "crypto" "crypto/rand" "crypto/x509" "crypto/x509/pkix" "encoding/base64" "io" "io/ioutil" "math/big" "net/http" "net/http/httptest" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "code.cacert.org/cacert/goocsp/pkg/ocsp" ) type OcspSourceTestSuite struct { suite.Suite RootKey crypto.Signer IntermediateKey crypto.Signer RootResponderKey crypto.Signer IntermediateResponderKey crypto.Signer RootCertificate *x509.Certificate IntermediateCertificate *x509.Certificate RootResponderCertificate *x509.Certificate IntermediaResponderCertificate *x509.Certificate Server *httptest.Server responder http.Handler RootIssuer *CertificateIssuer IntermediateIssuer *CertificateIssuer } type OcspTestHandler struct { suite *OcspSourceTestSuite } func (o *OcspTestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) { mux := http.NewServeMux() mux.HandleFunc("/crl/", o.suite.crlHandler) mux.HandleFunc("/ocsp", o.suite.ocspHandler) mux.ServeHTTP(writer, request) } func (suite *OcspSourceTestSuite) crlHandler(_ http.ResponseWriter, _ *http.Request) { panic("implement me") } func (suite *OcspSourceTestSuite) ocspHandler(writer http.ResponseWriter, request *http.Request) { suite.responder.ServeHTTP(writer, request) } func (suite *OcspSourceTestSuite) SetupSuite() { suite.RootKey = suite.deserializeKey(idxRootKey) testHandler := &OcspTestHandler{suite} suite.Server = httptest.NewServer(testHandler) baseURL := suite.Server.URL var ( startDate, endDate time.Time template *x509.Certificate serial *big.Int ) const ( organizationalUnit = "CA Ops" organization = "Test CA" ) serial = suite.newRandomSerial() rootSubject := pkix.Name{ CommonName: "Root CA", Organization: []string{organization}, OrganizationalUnit: []string{organizationalUnit}, } startDate = time.Now().AddDate(-2, 0, 0) endDate = startDate.AddDate(30, 0, 0) template = &x509.Certificate{ PublicKey: suite.RootKey.Public(), SerialNumber: serial, Issuer: rootSubject, Subject: rootSubject, NotBefore: startDate, NotAfter: endDate, KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, IsCA: true, MaxPathLen: 3, CRLDistributionPoints: []string{baseURL + "/crl/root.crl"}, } suite.RootCertificate = suite.signCertificate( template, template, suite.RootKey.Public(), suite.RootKey, ) suite.IntermediateKey = suite.deserializeKey(idxIntermediaryKey) startDate = time.Now().AddDate(-1, 0, 0) endDate = startDate.AddDate(5, 0, 0) serial = suite.newRandomSerial() intermediateSubject := pkix.Name{ CommonName: "Intermediate CA", Organization: []string{organization}, OrganizationalUnit: []string{organizationalUnit}, } template = &x509.Certificate{ PublicKey: suite.IntermediateKey.Public(), SerialNumber: serial, Issuer: rootSubject, Subject: intermediateSubject, NotBefore: startDate, NotAfter: endDate, KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, IsCA: true, MaxPathLen: 2, OCSPServer: []string{baseURL + "/ocsp"}, CRLDistributionPoints: []string{baseURL + "/crl/intermediate.crl"}, } suite.IntermediateCertificate = suite.signCertificate( template, suite.RootCertificate, suite.IntermediateKey.Public(), suite.RootKey, ) suite.RootResponderKey = suite.deserializeKey(idxRootOcspKey) startDate = time.Now().Add(-24 * time.Hour) endDate = startDate.AddDate(0, 6, 0) serial = suite.newRandomSerial() rootResponderSubject := pkix.Name{ CommonName: "Root CA OCSP Responder", Organization: []string{organization}, OrganizationalUnit: []string{organizationalUnit}, } template = &x509.Certificate{ PublicKey: suite.RootResponderKey.Public(), SerialNumber: serial, Issuer: rootSubject, Subject: rootResponderSubject, NotBefore: startDate, NotAfter: endDate, KeyUsage: x509.KeyUsageDigitalSignature, IsCA: false, MaxPathLen: 0, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageOCSPSigning}, OCSPServer: []string{baseURL + "/ocsp"}, CRLDistributionPoints: []string{baseURL + "/crl/root.crl"}, } suite.RootResponderCertificate = suite.signCertificate( template, suite.RootCertificate, suite.RootResponderKey.Public(), suite.RootKey, ) suite.IntermediateResponderKey = suite.deserializeKey(idxIntermediaryOcspKey) startDate = time.Now().Add(-24 * time.Hour) endDate = startDate.AddDate(0, 6, 0) serial = suite.newRandomSerial() intermediateResponderSubject := pkix.Name{ CommonName: "Intermediate CA OCSP Responder", Organization: []string{organization}, OrganizationalUnit: []string{organizationalUnit}, } template = &x509.Certificate{ PublicKey: suite.IntermediateResponderKey.Public(), SerialNumber: serial, Issuer: intermediateSubject, Subject: intermediateResponderSubject, NotBefore: startDate, NotAfter: endDate, KeyUsage: x509.KeyUsageDigitalSignature, IsCA: false, MaxPathLen: 0, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageOCSPSigning}, OCSPServer: []string{baseURL + "/ocsp"}, CRLDistributionPoints: []string{baseURL + "/crl/intermediate.crl"}, } suite.IntermediaResponderCertificate = suite.signCertificate( template, suite.IntermediateCertificate, suite.IntermediateResponderKey.Public(), suite.IntermediateKey, ) } type testCertDB struct { content map[string]*ocsp.Response } func newTestCertDB() *testCertDB { return &testCertDB{content: make(map[string]*ocsp.Response)} } func (t testCertDB) LookupResponseTemplate(serial *big.Int) *ocsp.Response { serialText := serial.Text(16) if response, ok := t.content[serialText]; ok { return response } response := &ocsp.Response{ Status: ocsp.Revoked, SerialNumber: serial, } return response } func (t testCertDB) UpdateCertificate(update *CertificateUpdate) { t.content[update.Serial.Text(16)] = &ocsp.Response{ Status: update.Status, SerialNumber: update.Serial, RevokedAt: update.RevokedAt, RevocationReason: update.RevocationReason, } } func (suite *OcspSourceTestSuite) SetupTest() { var err error suite.RootIssuer = NewIssuer( suite.RootCertificate, suite.RootResponderCertificate, suite.RootResponderKey, newTestCertDB(), ) if err != nil { suite.FailNow("could not create root issuer: %v", err) } suite.IntermediateIssuer = NewIssuer( suite.IntermediateCertificate, suite.IntermediaResponderCertificate, suite.IntermediateResponderKey, newTestCertDB(), ) if err != nil { suite.FailNow("could not create intermediate issuer: %v", err) } source, err := NewSource(WithIssuer(suite.RootIssuer), WithIssuer(suite.IntermediateIssuer)) if err != nil { suite.FailNow("could not create ocsp source: %v", err) } suite.responder = ocsp.NewResponder(source, nil) } func (suite *OcspSourceTestSuite) TearDownSuite() { suite.Server.Close() } func (suite *OcspSourceTestSuite) newRandomSerial() *big.Int { serial, err := rand.Int(rand.Reader, big.NewInt(1<<62-1)) if err != nil { suite.FailNow("could not generate random serial number: %v", err) } return serial } func (suite *OcspSourceTestSuite) deserializeKey(index int) crypto.Signer { var ( //nolint:lll pkcs8Keys = []string{ `MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC0sI1pZMtN8MyKE2uO8Jx7nythIzQ6QtG07Tj+CwjdsTlrLYOjtmXl5NHaElAFcCdknX5TT/P+z+uBwbFUQbTsp0Z9Dd/SX4M5VXHFyPDFHLfBdAcRO/ECy7JxbntDBdS5skpDZzsFFDUXrKtAZoAUtRn8DsrHWoSDKpoMvkT5dRyJEv6AJGhV8853PGBWH59hcPqXYts/mYOPpfGcQ9JvePKTc2+Xp+OOYm0pG8D+tpDwLu5qy0NXjgRRUS1Gs2chpV4M+cvYEU0bfZ6j5ZzaaiqWHdKlRJxL9dHArI4Lx0A4r6lTbTbkheDqndYa4i+Nxcp7FxiJEsgahCfHmdRinY+9YpFaxT3v2925y+UWCW3CYD93iumbD1XwAwrVt5ipUpW00P5Dm0A623S0WPw2sN9dCKruQtj1rDHudi8lYw3hwpQu/mEJ5rvLDnq/yINFRnQTbRGvyjiVgppIwgNzC393nPXxy7MVkKvlxLqoXtkEtZHf37rT8mjsQFLV9o4U+rKl9Bw3MiuufEu3aL7UMZ7Y1VwRBEgpQVW1sN2ycpm6mR9UMRNUMQZlF5PcODKN1rSn0G49xiUTTHfzdql1xzmh37iuFXMju071ZLAOweHNZp6E61p6PyiPhlmoWToX/UpMsCjEqLmGv8odAZnvAn+dWsg+B0pkJn4qYGwOWQIDAQABAoICAQCFYwBBmYLr2qNkGsoAD2e1at8fKlnX2JPuuGCmSYcWAUqd8E+Jf5DhkXXJQlOIcC7ke89RuWgp51u3wkEiLg9d1G6YyrE8H/5DSOxgUeJL4NNWIE1HT7Svl6f3TNP5ukg7fX6NG5vaN/ypqXISbJiIsNip1lGjsRK5sa1fUuagMPAL0NXHyxiquvzj0NJdQaLqz/ht4TBxVuZkGOCvtvGWEPciGsl6bxnxdn+XJUHnxuZgKIUgmUTxUYmmbgK6ep3bnLQ9Z/ovWzZM4QNHgq20H0Oo5gMmteubt7BMSBXkZAbo0eRyDeHD+YD8MeBooCjyw9yh2X7nUdIeoQistMavdoyqCpp+3ppDTE4aXEDXEGvjlDrRyoxMu+IYTrONDICT1H+0UDyxHBMpMXslC5WiqqPaXaiE3APxQJlTViOSYfi1AIfn6XTMDDX7xrIFryAn3/YRU3BvGEQRPdAp/PioCl1pwYrGUPzN9dpngCTlJMaGNq689paQ7cqft/+WTi/0d2znrZvfjTD8ebtMi3JRvN6gWNGdipUZylcxk+3xFZwijDf4aiFQTDEWB9/ztDILU8umVdx3Pg+95/7H7/dGb27hmgGPdKhcL7LdHc0R/l1AVSI+ktkyVW4WuFgDtdxvfXaG9ueYIumHVETgGyezwMjhWr4jXanmdHti2ckoAQKCAQEA8KUNYVMxCFvHFqlu39tS8uhUuW/QlmZJntalbqJSDFMcfjVYIxWH/t0lmoNcql4gp+PizG9yPZEr1/hM6xfVBONdZRZkLYfgfpL4eIxeR3yKog/THyYY8ePpl9kMO985dV/iPGGttXPAy4KLF4/PAgR+yXTbQS6IGZK+m0ND4OfkNb1jL6FhyiyQQMoOzqaiixziVCctD28IFAj8X9/G1Lei/LkrZsTh2nUxrPQijuwoYjhd/mZkRiUXGRrqydniRRU0u5SEgTciriwaNp1KEMCJH2+tqddEU1OCd6I9fzs7d0M+6I3WVypZXq1o/zLQszuUSjTeHvDO+HPMwQC6QQKCAQEAwDghREsLkh9hvCi42DXE8aKClXwfEErk26ptGM0IKp4Vs/PyV8JUvb4sfYRz0XEz5gY5cFkwGJ8na9Jn6WlZhkJFPgjDrP1eUOM1XNvWcFaCFisjneV65wue2QgZuLFKGdSM2l08V2vkAYupe/ndWqbfuOiHX9uFtlwmTrq0csmr5Nj88xFsBCee3RZQn1mBWAXnZTGjvQqMuSMBr9Erqq6YVtsueQVOWS82dZPKO7YySaFWniN3ENe6YGEehlXsfwC21fAr6q0m383ZoaB5aIOhhZZSZIAy5tslXTSygkioyMt9t8fkYOq1FbKInpCb7Qg1qbvf8L78wKVjKXZeGQKCAQEAgJq0m96pxZ3GuAW0i03a9pXTMYbgIoBnt8tefdGhp5SDFa/MenN3Sm1FO14Yl7PWH+NZwYeNtflvROwdr0X9Qa+AqhVdVDfZcct5nnLlr66PKCzs1yi1DBCRNeV49EZHnsKvVTWeb+p8jkYlr2Hbb2iXmXIp+puzgHc8Bh3cmMVU4KNl7n6AlFtcfEN/xlCnbVDyY6bMHgNofcyPk200BVpecFFFMJbnXKhk89lE3ry2mEcndF2kGRiZT4FjGJyon+LFW7nzVlrw3cQT/jvw6SL8JSC53pp8mUt33heGZghxrzrw07d5ZPvs5vwlsLynbCHbDg1S55YqBf1c34hUAQKCAQAYvKB7W3UHvwYi4tK28GSB/Dn15t1QiXLeWhZkJK6yXVnJqNE9PgMN0BWFqbAF+h2FsrNdo/yujnzSQWeiAC7HOmwSyan07z5eBn9tjdUQ6/EdzTtuLIQei75Li+FThW1V2aauy2Tikz3qfQC4tbUo32TXNQWG7odMqps7coeaZh26+7nBxjIybq7hIOgLOceNfmUC/tplj6AAi2LCL5cBBisQsnBOnsIwdAT8KKLUAGSEWUD+ZO4Dut9/W8BD5Xbj+UGOUrQ0JUhlcOZbCH3XV2lH+cpsqJrkXrt2PTvjzFn8TUPGjPD1D/9x5WHzlgSbAn11dHojT1DTsfUK9vKxAoIBAEraanpXIJqzjt5wj8z8/OjbXFXOdH3njKe2ntwPCrzU9qN4yv2/a9GEqhnBHZp4s1kznM5hCoEG3TROOKmgp4iDyq/hFKx61wZQAOdHOjCuxvOr+TXSUYJ5lW41BkjZUhm+gWO5WK1nsstaGbOUBQkbOF41zAzUvyt3klaXRaoSJL2XmcVm0VHkpO9IDFIgJNXQpEWV+uiQcghp1K1KPm9sII18g0i0KeI8LllbcmrSvC5kZcv2r9XIKz7h6qvSWYS3wzBKZxeZgCMlMAbg5RNTn72qFvPtXdJBymRvRebxuwrsMhkwvtyxk8T8ym/fKHSJuHaLt46c+r4QjO4alY0`, `MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC0Fi/9aWs4cezbKPZv8D2gXCvD/B/8tqCq3i+9gFcMGj9etBBXtxd0k4TIIbC+y3bbI5bo3AM0RPLsqeGEBnb0V+tfJ211xJaVqOMnUfKrRXjzUiENcO/qGfueh1pMV9KJ+ZUcbm+FQrTRnDShfZlcUZwyGxy6pCxGfQTHMdCSAA5XDj3gmRQxSJvYfZK7hIE9dmNG/yi+rw6Qoh+jGTROiuihY4Bi/w+KczWX74Y6N7vPEH5DTfxuNQxYzMsYBF3Pq+nNpwhB1Ntq7YPpFco8T4zzmh0RHIAGILxBjhcPvtnbSPF4BQATtquj/l2K30CelLCO5h9kPB+r73+di0Nk/d0TBat1PSTVfdZntreb8HhzZ2aSTtXTuNMk4zx0UeoTXKYDsSY9wJY1r5+Sy8XbBYUQJnDgut/ZmKEByV3fkqlJkKvyP/6RKKWAtq6uwZQcbQsEIhSn+V8rP4j20NkASL+KvETsIjr+sb/j8udiynshWML8lrcNVeeMxaYTpzpgUsX8FX58pE3u366zy2PMvYw94baeaxVwSjhXXQr1yDq6NEsqlx0FnWU5DCQWgO3WzRwu0cp0juxLuyPssEuPBz9yBMRKOnc2Own1+vO6q4h56dCR0QI1RuEobIXB/O89fA4dhAjYeBD4bjk3EkNYME1RQDQ+oZxDTbPx2PZ3XQIDAQABAoICAH1MCqvIUx98tI1vnLcZcedG+fRsUV0lO/hmitTQnMAA6yJbKhu9egZUNUiBmFXHfrTNuEvf+CK/7j0XnZ6cWNt86HjWF+SemR8b2KAc9jiQJ60z8WdGssYwuc784ajIWeZBzqtvcwxG80P76OqLVs7SwVhjYMPDQkLw7Qgi8rkCbPfJIuhH2bLIkBY6mIL7mGhJHJ3jHlg9uGaNRnHWMXyMTXssncFDMW7k5d8Gel+7M2LIWPE/K2kKY8LNCml1cEfzlsLNeoNDND7bbrIXxRPdTXaYPa0QJUseL5103TrJUQ6vW8JjyD/vEtERQ8hBuNYdIhLqreCxrF+WTTYyFPrc6UPXE55XTSr78cTZNe5w/u1eYwz/n24J6o6CLjp9XwY+Xb5dmm60TpjqDZl5NmQPvpIgH53l0wxLWg5C2QvKPRo1gBv/LHun2bflZG9eZ+mktYNkfcu4OsZZ86ry7/3tx2UUZaesmVZ8mDhAY2593DfJVQvGEJuOmzLfg4gRTRCAneAjORewLYGh2bRUW0CFrU284cxdFNZkdh3SO0ekpC95EgF2FeKFMI9nxcL+DtR9wTGFmzth9rzPXacGCoEI6a3eZvCXbBqOG0FrRM9KmuabVADiPUm4iFLTKDw6iPPiFZyIu+hpo+f4Seb80VgYLhDhjACmUuBqzzZtxVFJAoIBAQDBJso4sc2ZwWXQrnYnEhvKpaCw3y02/CX3v81j5v/JBO728MZ3KRZaHDzz2ZaTIY2GRRWl/wt6kdWegMlIwK+HHOBQGJXe4qwz+OkqMacN4vkc8cJbhohc9VA/UGJ+1jt2XQTD8oBUGk+5Lyh0YEeS9V2xequz19rXrNToi5vlbrVJL4um7h1wccJy50+07gGCE1AGUSQ4aaV9oTWXiUcsTvC6AYtltUKwsE3pJAilTAfuW4QD65aXux6Z7+bRjDmZAUJvYnDA8F2fPrYt7Ly3abX2cAO+2zGe7jHLURnge1r9ITZA+s2eV01FkJBDE+HsLoaTX39TwIDHn5mq8sdLAoIBAQDurx3IOoOoIS+lFvYoydlxfDFUJzEoQ5mDRSv4ql+Bgmld1jl9txBBC1oo+sA71NvuPZ8Ki9O3TLwcrJdVca9EzEP1dGryYaQ7genkkDoGC9eM31QFoWyYCBXKHychYseHeMBFFmdvk9Zn8uBjTN67i0HMMoPebzeHI/6ZgVLjk3KjXzZ/YJ93vcGlGAWzOXU3X/uISQGFBpyb2wSqRWholcOtPAhE9ToH/G4MdTsqjCJFyaSUPcmrOu337KbpcIxO0kZmRhwAfXtMS/njj88T35v0CUYvLWGPwFOBCofTH5+Od/RUfYY7g1X0lNk11cY6NF32XKgdhaqTMk55Bcr3AoIBADeCAEd+wYlYTPxFxuq/h4EbTCzIVmQg3oBufIYjUorgghQxabfA9Q18Y//oHh+2Wselfu0veIsG8g8VD8N6rHb103jxN9DP75EYDVn03v9cpR6uU56d8P5V+XPYlBXDV19SqBXv0PVagmLDrKqVKLyRCxYAHOwYMmoc3yrdRDYRNMQNh+K3N3qjFrCSzRM/+ur4xdyq4O/dXJPYCmC8MNoI7aFm5Dqcdsf0Qs+nbVyjlvvnDO9bevGr8sVmbjz2QW85L3B3J9Qqv50OFqjoCevj00k5M7pbn8z+wwydCAS9Lo7kRoUyDnlcuXYub2b3hcusKzybCyp0fg3gTfcUwjUCggEBALRNnt7ZrQj+AMLiZJONX3BGE/FxJcY3wqiSQVQ4R6tKu5PCN23LM0EfdT1NppfMBVOkQxcxZ36pPdUfX7aRCYicEZ5DEmME9Y5qZihd9ycIHQ1yy0LxnVn/iY5FGEc1GmsxAXVvJjX4ZNfjdjQtJnhgCxVY95q5QyYYP8TwF5CImunlDAMPF4fZ1YWEbxHjjrOFEzrxg29c/kMSISULB4Mx1z5vAgQth2fu/ab1i/tpHp6/Y08Emep6urc1kyT2+1azq7Cot5B7Of/5yMxpn1Fw8ptXwifzTSbNb4ckUFRhKCP0Y6LLq/IbFXyMUMVFNthTJMPtXKXoimFleDgd8yMCggEBAKc+Ro5kkEE7vIEOTkMZ88/X9eTRV7qk5FVEpllyGBDOYkrPP25UaS0I1CbXtqWMTqBz40tXcdAN69sHru6MlF5zioEcl51QYJUcrY9/4M5Rv/xIA5dWeuJ42Ly1A89U+Zzx+lTjuwgQR+R6Y8AyjHhkYF76JSEoFkCb28+uIsERHhCay7pevOLZYLbeHdANCtXceId80Yvh36+9/qzKoV4eTE6O8LWj1cDudc+vGAb97DCCeGi5vbh3XBf1Xzp88MnsnGFzC6azCrjr9TLW3/p66OESSmm1y1qnMwcq/h/9Bh9SjhFTab9ftOS9bO3pcvTygheHAywO212BOZ+I8h0`, `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`, `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`, `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`, `MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQCi/gLhii/iYFL + S1N2/h4MT + 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`, `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`, `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`, `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`, `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`, } ) assert.Less(suite.T(), index, len(pkcs8Keys)) keyBytes, err := base64.RawStdEncoding.DecodeString(pkcs8Keys[index]) if err != nil { suite.FailNow("could not decode private key DER bytes: %v", err) } pkcs8PrivateKey, err := x509.ParsePKCS8PrivateKey(keyBytes) if err != nil { suite.FailNow("could not parse private key: %v", err) } key, ok := pkcs8PrivateKey.(crypto.Signer) if !ok { suite.FailNow("could not use private key as crypto.Signer") } return key } func (suite *OcspSourceTestSuite) signCertificate( template, parent *x509.Certificate, public crypto.PublicKey, private crypto.Signer, ) *x509.Certificate { rootBytes, err := x509.CreateCertificate(rand.Reader, template, parent, public, private) if err != nil { suite.FailNow("could not sign test root certificate %v", err) } certificate, err := x509.ParseCertificate(rootBytes) if err != nil { suite.FailNow("could not parse generated root certificate: %v", err) } return certificate } func (suite *OcspSourceTestSuite) TestCertificateInIndexTxt() { const duration90days = 90 * 24 * time.Hour serial := suite.newRandomSerial() start := time.Now().Add(-1 * time.Hour) end := start.Add(duration90days) key := suite.deserializeKey(idxEndpointKey1) template := &x509.Certificate{ PublicKey: key.Public(), SerialNumber: serial, Issuer: suite.IntermediateCertificate.Subject, Subject: pkix.Name{ CommonName: "test.example.org", Organization: []string{"Test Company"}, Locality: []string{"Acme Town"}, }, NotBefore: start, NotAfter: end, KeyUsage: x509.KeyUsageDataEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, OCSPServer: suite.IntermediateCertificate.OCSPServer, } cert := suite.signCertificate( template, suite.IntermediateCertificate, key.Public(), suite.IntermediateKey, ) suite.IntermediateIssuer.UpdateCert(&CertificateUpdate{ Serial: serial, Status: ocsp.Good, NotAfter: end, }) ocspClient := http.DefaultClient request, err := ocsp.CreateRequest(cert, suite.IntermediateCertificate, nil) if err != nil { suite.FailNow("could not create OCSP request: %v", err) } response, err := ocspClient.Post( suite.IntermediateCertificate.OCSPServer[0], "application/ocsp-request", bytes.NewReader(request), ) if err != nil { suite.FailNow("could not retrieve response: %v", err) } defer func() { _ = response.Body.Close() }() assert.Equal(suite.T(), 200, response.StatusCode) responseData, err := io.ReadAll(response.Body) if err != nil { suite.FailNow("could not read data from OCSP response: %v", err) } tempFile, _ := ioutil.TempFile("", "ocspresponse-*.der") _, _ = io.Copy(tempFile, bytes.NewReader(responseData)) data, err := ocsp.ParseResponse(responseData, suite.IntermediateCertificate) if err != nil { suite.FailNow("could not parse OCSP response: %v", err) } assert.Equal(suite.T(), serial, data.SerialNumber) assert.Equal(suite.T(), ocsp.Good, data.Status) } func TestOcspSourceTestSuite(t *testing.T) { suite.Run(t, new(OcspSourceTestSuite)) } const ( idxRootKey int = iota idxIntermediaryKey idxRootOcspKey idxIntermediaryOcspKey idxEndpointKey1 // idxEndpointKey2 // idxEndpointKey3 )