insert_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. package certadd
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "crypto/x509/pkix"
  8. "encoding/hex"
  9. "encoding/json"
  10. "encoding/pem"
  11. "io/ioutil"
  12. "math/big"
  13. "net/http"
  14. "net/http/httptest"
  15. "testing"
  16. "time"
  17. "github.com/cloudflare/cfssl/certdb"
  18. "github.com/cloudflare/cfssl/certdb/sql"
  19. "github.com/cloudflare/cfssl/certdb/testdb"
  20. "github.com/cloudflare/cfssl/ocsp"
  21. "encoding/base64"
  22. stdocsp "golang.org/x/crypto/ocsp"
  23. )
  24. func prepDB() (certdb.Accessor, error) {
  25. db := testdb.SQLiteDB("../../certdb/testdb/certstore_development.db")
  26. dbAccessor := sql.NewAccessor(db)
  27. return dbAccessor, nil
  28. }
  29. func makeRequest(t *testing.T, dbAccessor certdb.Accessor, signer ocsp.Signer, req map[string]interface{}) (resp *http.Response, body []byte) {
  30. ts := httptest.NewServer(NewHandler(dbAccessor, signer))
  31. defer ts.Close()
  32. blob, err := json.Marshal(req)
  33. if err != nil {
  34. t.Fatal(err)
  35. }
  36. resp, err = http.Post(ts.URL, "application/json", bytes.NewReader(blob))
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. body, err = ioutil.ReadAll(resp.Body)
  41. if err != nil {
  42. t.Fatal(err)
  43. }
  44. return
  45. }
  46. func makeCertificate() (serialNumber *big.Int, cert *x509.Certificate, pemBytes []byte, signer ocsp.Signer, err error) {
  47. privKey, err := rsa.GenerateKey(rand.Reader, 2048)
  48. if err != nil {
  49. return
  50. }
  51. serialNumberRange := new(big.Int).Lsh(big.NewInt(1), 128)
  52. serialNumber, err = rand.Int(rand.Reader, serialNumberRange)
  53. if err != nil {
  54. return
  55. }
  56. template := x509.Certificate{
  57. SerialNumber: serialNumber,
  58. Subject: pkix.Name{
  59. Organization: []string{"Cornell CS 5152"},
  60. },
  61. AuthorityKeyId: []byte{42, 42, 42, 42},
  62. }
  63. cert = &template
  64. issuerSerial, err := rand.Int(rand.Reader, serialNumberRange)
  65. if err != nil {
  66. return
  67. }
  68. responderSerial, err := rand.Int(rand.Reader, serialNumberRange)
  69. if err != nil {
  70. return
  71. }
  72. // Generate a CA certificate
  73. issuerTemplate := x509.Certificate{
  74. SerialNumber: issuerSerial,
  75. Subject: pkix.Name{
  76. Organization: []string{"Cornell CS 5152"},
  77. },
  78. AuthorityKeyId: []byte{42, 42, 42, 42},
  79. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
  80. IsCA: true,
  81. BasicConstraintsValid: true,
  82. }
  83. issuerBytes, err := x509.CreateCertificate(rand.Reader, &issuerTemplate, &issuerTemplate, &privKey.PublicKey, privKey)
  84. if err != nil {
  85. return
  86. }
  87. issuer, err := x509.ParseCertificate(issuerBytes)
  88. if err != nil {
  89. return
  90. }
  91. responderTemplate := x509.Certificate{
  92. SerialNumber: responderSerial,
  93. Subject: pkix.Name{
  94. Organization: []string{"Cornell CS 5152 Responder"},
  95. },
  96. AuthorityKeyId: []byte{42, 42, 42, 43},
  97. }
  98. responderBytes, err := x509.CreateCertificate(rand.Reader, &responderTemplate, &responderTemplate, &privKey.PublicKey, privKey)
  99. if err != nil {
  100. return
  101. }
  102. responder, err := x509.ParseCertificate(responderBytes)
  103. if err != nil {
  104. return
  105. }
  106. signer, err = ocsp.NewSigner(issuer, responder, privKey, time.Hour)
  107. if err != nil {
  108. return
  109. }
  110. derBytes, err := x509.CreateCertificate(rand.Reader, &template, issuer, &privKey.PublicKey, privKey)
  111. if err != nil {
  112. return
  113. }
  114. pemBytes = pem.EncodeToMemory(&pem.Block{
  115. Type: "CERTIFICATE",
  116. Bytes: derBytes,
  117. })
  118. return
  119. }
  120. func TestInsertValidCertificate(t *testing.T) {
  121. dbAccessor, err := prepDB()
  122. if err != nil {
  123. t.Fatal(err)
  124. }
  125. serialNumber, cert, pemBytes, signer, err := makeCertificate()
  126. if err != nil {
  127. t.Fatal(err)
  128. }
  129. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  130. "serial_number": serialNumber.Text(16),
  131. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  132. "status": "good",
  133. "pem": string(pemBytes),
  134. })
  135. if resp.StatusCode != http.StatusOK {
  136. t.Fatal("Expected HTTP OK, got", resp.StatusCode, string(body))
  137. }
  138. var response map[string]interface{}
  139. if err = json.Unmarshal(body, &response); err != nil {
  140. t.Fatal("Could not parse response: ", err)
  141. }
  142. responseResult := response["result"].(map[string]interface{})
  143. encodedOcsp := responseResult["ocsp_response"].(string)
  144. rawOcsp, err := base64.StdEncoding.DecodeString(encodedOcsp)
  145. if err != nil {
  146. t.Fatal("Could not base64 decode response: ", err)
  147. }
  148. returnedOcsp, err := stdocsp.ParseResponse(rawOcsp, nil)
  149. if err != nil {
  150. t.Fatal("Could not parse returned OCSP response", err)
  151. }
  152. ocsps, err := dbAccessor.GetOCSP(serialNumber.Text(16), hex.EncodeToString(cert.AuthorityKeyId))
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. if len(ocsps) != 1 {
  157. t.Fatal("Expected 1 OCSP record to be inserted, but found ", len(ocsps))
  158. }
  159. parsedOcsp, err := stdocsp.ParseResponse([]byte(ocsps[0].Body), nil)
  160. if err != nil {
  161. t.Fatal(err)
  162. }
  163. if parsedOcsp.SerialNumber.Cmp(returnedOcsp.SerialNumber) != 0 {
  164. t.Fatal("The returned and inserted OCSP response have different serial numbers: got ", returnedOcsp.SerialNumber, " but decoded ", parsedOcsp.SerialNumber)
  165. }
  166. if parsedOcsp.SerialNumber.Cmp(serialNumber) != 0 {
  167. t.Fatal("Got the wrong serial number: expected", serialNumber, "but got", parsedOcsp.SerialNumber)
  168. }
  169. if parsedOcsp.Status != stdocsp.Good {
  170. t.Fatal("Expected OCSP response status to be ", stdocsp.Good,
  171. " but found ", parsedOcsp.Status)
  172. }
  173. }
  174. func TestInsertMissingSerial(t *testing.T) {
  175. dbAccessor, err := prepDB()
  176. if err != nil {
  177. t.Fatal(err)
  178. }
  179. _, cert, pemBytes, signer, err := makeCertificate()
  180. if err != nil {
  181. t.Fatal(err)
  182. }
  183. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  184. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  185. "status": "good",
  186. "pem": string(pemBytes),
  187. })
  188. if resp.StatusCode != http.StatusBadRequest {
  189. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  190. }
  191. }
  192. func TestInsertMissingAKI(t *testing.T) {
  193. dbAccessor, err := prepDB()
  194. if err != nil {
  195. t.Fatal(err)
  196. }
  197. serialNumber, _, pemBytes, signer, err := makeCertificate()
  198. if err != nil {
  199. t.Fatal(err)
  200. }
  201. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  202. "serial_number": serialNumber.Text(16),
  203. "status": "good",
  204. "pem": string(pemBytes),
  205. })
  206. if resp.StatusCode != http.StatusBadRequest {
  207. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  208. }
  209. }
  210. func TestInsertMissingPEM(t *testing.T) {
  211. dbAccessor, err := prepDB()
  212. if err != nil {
  213. t.Fatal(err)
  214. }
  215. serialNumber, cert, _, signer, err := makeCertificate()
  216. if err != nil {
  217. t.Fatal(err)
  218. }
  219. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  220. "serial_number": serialNumber.Text(16),
  221. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  222. "status": "good",
  223. })
  224. if resp.StatusCode != http.StatusBadRequest {
  225. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  226. }
  227. }
  228. func TestInsertInvalidSerial(t *testing.T) {
  229. dbAccessor, err := prepDB()
  230. if err != nil {
  231. t.Fatal(err)
  232. }
  233. _, cert, pemBytes, signer, err := makeCertificate()
  234. if err != nil {
  235. t.Fatal(err)
  236. }
  237. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  238. "serial_number": "this is not a serial number",
  239. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  240. "status": "good",
  241. "pem": string(pemBytes),
  242. })
  243. if resp.StatusCode != http.StatusBadRequest {
  244. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  245. }
  246. }
  247. func TestInsertInvalidAKI(t *testing.T) {
  248. dbAccessor, err := prepDB()
  249. if err != nil {
  250. t.Fatal(err)
  251. }
  252. serialNumber, _, pemBytes, signer, err := makeCertificate()
  253. if err != nil {
  254. t.Fatal(err)
  255. }
  256. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  257. "serial_number": serialNumber.Text(16),
  258. "authority_key_identifier": "this is not an AKI",
  259. "status": "good",
  260. "pem": string(pemBytes),
  261. })
  262. if resp.StatusCode != http.StatusBadRequest {
  263. t.Fatal("Expected HTTP Bad Request, got", resp.StatusCode, string(body))
  264. }
  265. }
  266. func TestInsertInvalidStatus(t *testing.T) {
  267. dbAccessor, err := prepDB()
  268. if err != nil {
  269. t.Fatal(err)
  270. }
  271. serialNumber, cert, pemBytes, signer, err := makeCertificate()
  272. if err != nil {
  273. t.Fatal(err)
  274. }
  275. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  276. "serial_number": serialNumber.Text(16),
  277. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  278. "status": "invalid",
  279. "pem": string(pemBytes),
  280. })
  281. if resp.StatusCode != http.StatusBadRequest {
  282. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  283. }
  284. }
  285. func TestInsertInvalidPEM(t *testing.T) {
  286. dbAccessor, err := prepDB()
  287. if err != nil {
  288. t.Fatal(err)
  289. }
  290. serialNumber, cert, _, signer, err := makeCertificate()
  291. if err != nil {
  292. t.Fatal(err)
  293. }
  294. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  295. "serial_number": serialNumber.Text(16),
  296. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  297. "status": "good",
  298. "pem": "this is not a PEM certificate",
  299. })
  300. if resp.StatusCode != http.StatusBadRequest {
  301. t.Fatal("Expected HTTP Bad Request, got", resp.StatusCode, string(body))
  302. }
  303. }
  304. func TestInsertWrongSerial(t *testing.T) {
  305. dbAccessor, err := prepDB()
  306. if err != nil {
  307. t.Fatal(err)
  308. }
  309. _, cert, pemBytes, signer, err := makeCertificate()
  310. if err != nil {
  311. t.Fatal(err)
  312. }
  313. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  314. "serial_number": big.NewInt(1).Text(16),
  315. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  316. "status": "good",
  317. "pem": string(pemBytes),
  318. })
  319. if resp.StatusCode != http.StatusBadRequest {
  320. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  321. }
  322. }
  323. func TestInsertWrongAKI(t *testing.T) {
  324. dbAccessor, err := prepDB()
  325. if err != nil {
  326. t.Fatal(err)
  327. }
  328. serialNumber, _, pemBytes, signer, err := makeCertificate()
  329. if err != nil {
  330. t.Fatal(err)
  331. }
  332. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  333. "serial_number": serialNumber.Text(16),
  334. "authority_key_identifier": hex.EncodeToString([]byte{7, 7}),
  335. "status": "good",
  336. "pem": string(pemBytes),
  337. })
  338. if resp.StatusCode != http.StatusBadRequest {
  339. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  340. }
  341. }
  342. func TestInsertRevokedCertificate(t *testing.T) {
  343. dbAccessor, err := prepDB()
  344. if err != nil {
  345. t.Fatal(err)
  346. }
  347. serialNumber, cert, pemBytes, signer, err := makeCertificate()
  348. if err != nil {
  349. t.Fatal(err)
  350. }
  351. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  352. "serial_number": serialNumber.Text(16),
  353. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  354. "status": "revoked",
  355. "pem": string(pemBytes),
  356. "revoked_at": time.Now(),
  357. })
  358. if resp.StatusCode != http.StatusOK {
  359. t.Fatal("Expected HTTP OK", resp.StatusCode, string(body))
  360. }
  361. ocsps, err := dbAccessor.GetOCSP(serialNumber.Text(16), hex.EncodeToString(cert.AuthorityKeyId))
  362. if err != nil {
  363. t.Fatal(err)
  364. }
  365. if len(ocsps) != 1 {
  366. t.Fatal("Expected 1 OCSP record to be inserted, but found ", len(ocsps))
  367. }
  368. response, err := stdocsp.ParseResponse([]byte(ocsps[0].Body), nil)
  369. if err != nil {
  370. t.Fatal(err)
  371. }
  372. if response.Status != stdocsp.Revoked {
  373. t.Fatal("Expected OCSP response status to be ", stdocsp.Revoked,
  374. " but found ", response.Status)
  375. }
  376. }
  377. func TestInsertRevokedCertificateWithoutTime(t *testing.T) {
  378. dbAccessor, err := prepDB()
  379. if err != nil {
  380. t.Fatal(err)
  381. }
  382. serialNumber, cert, pemBytes, signer, err := makeCertificate()
  383. if err != nil {
  384. t.Fatal(err)
  385. }
  386. resp, body := makeRequest(t, dbAccessor, signer, map[string]interface{}{
  387. "serial_number": serialNumber.Text(16),
  388. "authority_key_identifier": hex.EncodeToString(cert.AuthorityKeyId),
  389. "status": "revoked",
  390. "pem": string(pemBytes),
  391. // Omit RevokedAt
  392. })
  393. if resp.StatusCode != http.StatusBadRequest {
  394. t.Fatal("Expected HTTP Bad Request", resp.StatusCode, string(body))
  395. }
  396. }