r509-ocsp-responder 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/README.md +77 -0
  2. data/Rakefile +38 -0
  3. data/doc/R509.html +115 -0
  4. data/doc/R509/Ocsp.html +130 -0
  5. data/doc/R509/Ocsp/Helper.html +126 -0
  6. data/doc/R509/Ocsp/Helper/RequestChecker.html +739 -0
  7. data/doc/R509/Ocsp/Helper/ResponseSigner.html +583 -0
  8. data/doc/R509/Ocsp/Responder.html +129 -0
  9. data/doc/R509/Ocsp/Responder/OcspConfig.html +289 -0
  10. data/doc/R509/Ocsp/Responder/Server.html +128 -0
  11. data/doc/R509/Ocsp/Responder/StatusError.html +134 -0
  12. data/doc/R509/Ocsp/Signer.html +584 -0
  13. data/doc/_index.html +197 -0
  14. data/doc/class_list.html +53 -0
  15. data/doc/css/common.css +1 -0
  16. data/doc/css/full_list.css +57 -0
  17. data/doc/css/style.css +328 -0
  18. data/doc/file.README.html +156 -0
  19. data/doc/file_list.html +55 -0
  20. data/doc/frames.html +28 -0
  21. data/doc/index.html +156 -0
  22. data/doc/js/app.js +214 -0
  23. data/doc/js/full_list.js +173 -0
  24. data/doc/js/jquery.js +4 -0
  25. data/doc/method_list.html +164 -0
  26. data/doc/top-level-namespace.html +112 -0
  27. data/lib/r509/ocsp/responder/ocsp-config.rb +35 -0
  28. data/lib/r509/ocsp/responder/server.rb +169 -0
  29. data/lib/r509/ocsp/responder/version.rb +7 -0
  30. data/lib/r509/ocsp/signer.rb +244 -0
  31. data/spec/fixtures.rb +196 -0
  32. data/spec/fixtures/cert1.pem +24 -0
  33. data/spec/fixtures/config_test_various.yaml +46 -0
  34. data/spec/fixtures/ocsptest.r509.local.pem +27 -0
  35. data/spec/fixtures/second_ca.cer +26 -0
  36. data/spec/fixtures/second_ca.key +27 -0
  37. data/spec/fixtures/stca.pem +22 -0
  38. data/spec/fixtures/stca_ocsp_request.der +0 -0
  39. data/spec/fixtures/stca_ocsp_response.der +0 -0
  40. data/spec/fixtures/test_ca.cer +22 -0
  41. data/spec/fixtures/test_ca.key +28 -0
  42. data/spec/fixtures/test_ca_ocsp.cer +26 -0
  43. data/spec/fixtures/test_ca_ocsp.key +27 -0
  44. data/spec/fixtures/test_ca_ocsp_chain.txt +48 -0
  45. data/spec/fixtures/test_ca_request.der +0 -0
  46. data/spec/fixtures/test_ca_response.der +0 -0
  47. data/spec/fixtures/test_ca_subroot.cer +25 -0
  48. data/spec/fixtures/test_ca_subroot.key +27 -0
  49. data/spec/fixtures/test_ca_subroot_ocsp.cer +25 -0
  50. data/spec/fixtures/test_ca_subroot_ocsp.key +27 -0
  51. data/spec/fixtures/test_config.yaml +17 -0
  52. data/spec/server_spec.rb +400 -0
  53. data/spec/signer_spec.rb +275 -0
  54. data/spec/spec_helper.rb +18 -0
  55. metadata +259 -0
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEAvVuPqX19dbEXF1ciXNF7BQpwwiNK96GkvmMIn/sCp6N+xXor
3
+ VqWX0KA6hcXWPt8BPwiRy7BwhBqrfMBXW9fFi0dGJaVB9h5dJarPBDxbMEDMhrod
4
+ ExnG2NsXN+sA9YQpE3I6UX9H3z5VMPYwJFtt5U8tGQ63Me6IbTFqn69VsYbts76S
5
+ 3xxG2FV1ibWCQg/g7HtxKL4kBH0mxkvWST5CEiBT0EoTgFLSKiuML8Vcd3qXe5vU
6
+ MKgo+vmXDXoymYvCGOefSbIDLoWvh5MCvr28OgD8q2izMVY7YRpCxbSslxGPAoB+
7
+ WIFC7VtXN+EESmjZ8XCMf3J3Gns1Ych/7/LXIQIDAQABAoIBAHfVsSY/P52y0/02
8
+ bI23GJaJE/EYqsHqbzr5q6SrEvQKeRj6huDP7TLfpAmyuTKSqNQ+VR5F6/7+bdaG
9
+ VwLNm7vYAGGkowjiEGrdHSP+GmuAJq+AqxPCdWAZzyjZNYMq/1/KI3QeC9sRNJLG
10
+ ypLHtdWv9Mdt06vq3DXWVzb1nFK7DOKwCmR8qIhsGpBRBuztzHups2joQa4RTihC
11
+ 7hmdGz2VLFR0J9xphLV57W/ObJuxTD3sqL3HrsDkfv6Poi6iS1GBFtDUuxrFtUv/
12
+ K1Yao02gkXD32Mq5M38uTyBK7nEhS1V7cvP0iHPdLgan9bsrOREXyVV+u0gr2IN1
13
+ wKvyYs0CgYEA7HiL3JdOwlxzWznHLRPOd07cOnwkq5eauqmT2nzxtqL3InSFmNtL
14
+ 1hMfIRA2wejo/Q1Ezi7d7RCHsSHBfCGag7L/NdVnIiHAErbVf+LofvjL2C9LShKB
15
+ u4DxPsb7hcj3I9qaHoc0zotxjAkg38sdr2sfP7EMc5k+asPb9MA/bX8CgYEAzP7z
16
+ J4c+CkUhUg1xynZswjxvvC3oMhbC2vVsuKt/ZMwFolpDvVJNcrFOFkqikaGDLcPB
17
+ Dg2WxxZdujnfXBWjTI8M7pfhD1u2OW99yQsWxnWOc1C4n4OjPH0/sn9IEAjlmTpc
18
+ 5NYZB6dAARGRTEJN8srNGm59z0S6jLyciuErS18CgYBk8lz6cVk83YydMAAX/TGR
19
+ ewfGq8JXwiNadhPZHKdvCQipG8cAZvVr0MPkMHC/vLbhd+2ceyNgFUNn2XoojIvS
20
+ lvIdwBkD2BaPpp9jtbD8qycSBbaFS3s4WSYjX3x2M0FVe/d4+s0PMzXoyujOwH3O
21
+ qdMwNFuVaaDcoPnf9MXe7wKBgH9OpbsaplDCddr7NnvB5/EIj2uSJu1UbVaFrCtT
22
+ dh4nBii5XfApOKfNrOzzFNrULx8wvqf3kHe7UCHi5u/NEEjvXdyevcpH7nbk4n0E
23
+ QfSl9P1wV/fYTHu4XOKBYUN0AwKR2DbVL14tY/ZF7rIpSzdI8u9DRyZ9TE0ypRUq
24
+ mTSJAoGAOkzZ2D/nQyIz9mHOKmDoXWbFgZ32rqTzqfS07cq5vtt2Ol2MTRXY386Q
25
+ kW1AyHf0hz8SQe3+An4K6uMpGkZ6dzEOXhsw1+fwU9jFb+qucRuhTVlyVWDVtkf6
26
+ NRg6ZlSfTi3KxmaSsY7X/t9DfWmud8MXTm3cUqI0VdljQmAT85A=
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,48 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDjzCCAnegAwIBAgIJAP/ZxwuHN9GUMA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNV
3
+ BAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEYMBYG
4
+ A1UECgwPUnVieSBDQSBQcm9qZWN0MRAwDgYDVQQDDAdUZXN0IENBMB4XDTExMDIy
5
+ MDIwNDkxMloXDTMwMDQyMTIwNDkxMlowXjELMAkGA1UEBhMCVVMxETAPBgNVBAgM
6
+ CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRgwFgYDVQQKDA9SdWJ5IENBIFBy
7
+ b2plY3QxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
8
+ ggEKAoIBAQCot8/z3jxARkwyRk0csM84dlWs91W95wPpunx3P3otqUxCJaOAyQl/
9
+ uY8deg0xDmsime2JQ6aG6m76y3LfT4J1tlkhtmiGKhNJir1kgL8sL0wTXYXvwZEw
10
+ qEEYD5mKi7Na9eo4R0ydqd9KAquVIhKywXvV1+Y4RDTx+f1WXmMCBaYZ76/rXmIe
11
+ oE0avriRiihOtlgto+VNJw7VRnvq+cEd81BT62wRk1fG1lcpCqTEfEtKEI6PqqZh
12
+ E2f+6lNmhZZ3Tj7NeNgYQLd4q+L1y030Vj4onpAIJrwfQq3dxTmrLDqnN2WOFsbo
13
+ 0qGh3s4yqUaOYd2wIBgCp7fEf5X/yh53AgMBAAGjUDBOMB0GA1UdDgQWBBR5dbuE
14
+ Osss3noJvjEbQ7wcKk1TWDAfBgNVHSMEGDAWgBR5dbuEOsss3noJvjEbQ7wcKk1T
15
+ WDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAp/Fh+WWjN7x/SZzMm
16
+ H1INAS4loufHXzkqI+3bClAzlhzpBVbY7dHwD6H8oKh06EtppbN0Bw3iqXSRyoNd
17
+ +lDXccPij5dCuTFQ97DOrv7kGlhiM95XVkx4mvnd+i6jKwgOpllgDE/nKOwC42bq
18
+ lIikcp7XLQUPt7amyX9UeJ8lxQ/niSkT868ls2IZQkF3XEhCi+5VlefEoaiMQZmD
19
+ RyEd/vlsSnpXI5LLpkFq+NFGvgdI7+UADNIyDplyivD4VyQ6+zisX3r1ojroa6Y+
20
+ WyXxLx+AVJVnGjngr2fDKr4ggsYWlJEs8lJ0r90jliYrSPA6rIldTbs3k9AbUp8G
21
+ kS6X
22
+ -----END CERTIFICATE-----
23
+ -----BEGIN CERTIFICATE-----
24
+ MIIEaDCCA1CgAwIBAgIVAOpjrhBj/knK4IwIzIpSmDxdBlOYMA0GCSqGSIb3DQEB
25
+ BQUAMF4xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwH
26
+ Q2hpY2FnbzEYMBYGA1UECgwPUnVieSBDQSBQcm9qZWN0MRAwDgYDVQQDDAdUZXN0
27
+ IENBMB4XDTExMTIxNjA5NTg1NloXDTEyMTIxNTA5NTg1NlowGzEZMBcGA1UEAwwQ
28
+ cjUwOSBPQ1NQIFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
29
+ ALVK9XwIRznpBNC7Ltqqq4RSrkGdRZzt3fI2MrJVYAz1fc+kZ8IfsmEiZxGgRuQ2
30
+ 83TNF70IsSR6a3oiPUKuywqDbKBaXNDMzhLJKvT1bHsIfkBQ//IYKtN9JCBLzs92
31
+ vcsV5hZOhTs0WDyKvmjdX3Xh8vKtMoX1pfSjuXQuTpzTiQW/LDlfnDy5Cf668D1K
32
+ JsaEd8Nd4xncpWTj806WyODAkkqEaIvJJ014itqy9Tjo+m9TxGmRrY6SaBJRQGGe
33
+ Z6e0s6eccYuGrdFyElXc2M5kWkKirTmCSPGGokx9vw8v1EcdvNFlW2pug31RFWt9
34
+ sZ5P6XVkMykwjJwMyPm93dMCAwEAAaOCAV4wggFaMAwGA1UdEwEB/wQCMAAwHQYD
35
+ VR0OBBYEFCgE62q6is5xpdlkkPU1zy93piH2MAsGA1UdDwQEAwIHgDCBkAYDVR0j
36
+ BIGIMIGFgBR5dbuEOsss3noJvjEbQ7wcKk1TWKFipGAwXjELMAkGA1UEBhMCVVMx
37
+ ETAPBgNVBAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRgwFgYDVQQKDA9S
38
+ dWJ5IENBIFByb2plY3QxEDAOBgNVBAMMB1Rlc3QgQ0GCCQD/2ccLhzfRlDATBgNV
39
+ HSUEDDAKBggrBgEFBQcDCTAOBgNVHSAEBzAFMAMGAQAwMgYDVR0fBCswKTAnoCWg
40
+ I4YhaHR0cDovL2NybC5kb21haW4uY29tL3Rlc3RfY2EuY3JsMDIGCCsGAQUFBwEB
41
+ BCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AuZG9tYWluLmNvbTANBgkqhkiG
42
+ 9w0BAQUFAAOCAQEADNAMfwzRpx8UoWe1i/qivAIPJtP2zlop0eIwSy9ocAoAfcHF
43
+ wVsdBzIb74amm4z/+y7j4x8ZAY2d4hosdDH05OKnGVHUT0ASzYjh0zDgOItObk2L
44
+ XrMykW2GCNGTOlt1C/FfKVkBMDQz7Pi8fXmHsI4N1A0krTEVgVwKVLn0TrrLZ6OP
45
+ 0vsj9nqSPYJ4eLsIE3gp4RBLJWGtLWtlkIwKLU/ZhpKo7VcvoZU8zDjHJR/HO9uD
46
+ T3vlekoEc5rlWk9Uobh9Sz/pFb/r/ErOkXBnka1XunJQBOLe6wj1T2v/B0zMv6RG
47
+ Tpd0n0zKik4a7nBH82jxg78kRLUfjbhFZienKA==
48
+ -----END CERTIFICATE-----
@@ -0,0 +1,25 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEJjCCAw6gAwIBAgIVALxHSa9L48ZH3q9EANuGMICYOmRpMA0GCSqGSIb3DQEB
3
+ BQUAMF4xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwH
4
+ Q2hpY2FnbzEYMBYGA1UECgwPUnVieSBDQSBQcm9qZWN0MRAwDgYDVQQDDAdUZXN0
5
+ IENBMB4XDTEyMDEwNjExNTQxOVoXDTMyMDEwMTE3NTQxOVowLjELMAkGA1UEBhMC
6
+ VVMxHzAdBgNVBAMMFnI1MDkgQXJiaXRyYXJ5IFN1YnJvb3QwggEiMA0GCSqGSIb3
7
+ DQEBAQUAA4IBDwAwggEKAoIBAQC6s6E0RHPdC/g6ZVe/4bRka2FndjqCwxiuTpaq
8
+ FQwf8/etXyCuz0ZADs04WaqCtIs+uUoXh+jSBg0BVC0rc1pCoQIraq9M3ZJ1umu/
9
+ i96Ohhjbk1ygJW3U1+vdxWuowk4H51/pLbNUIy/fntSTE1vSbVo1rviK/SFXpHT3
10
+ PaPjIX4IjLpnW12+h1zH5P9yLoIZ/NN+s64rW21JX3y/gFG4DW9d0LxMKbI5Nixv
11
+ bn+1mpLCcPn+pO4i/8o8AXs/FsoKing32m23k7+8rz2IWKZWcVoLe4/x+j00zzjv
12
+ eXAvvoXBomYgftsj83tCQ5vOFznVoZJROfqKtcRwFpDaQosBAgMBAAGjggEJMIIB
13
+ BTASBgNVHRMBAf8ECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUtsRD
14
+ bNCYQJnEYNRxJAcAcPZ6JWowgZAGA1UdIwSBiDCBhYAUeXW7hDrLLN56Cb4xG0O8
15
+ HCpNU1ihYqRgMF4xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4G
16
+ A1UEBwwHQ2hpY2FnbzEYMBYGA1UECgwPUnVieSBDQSBQcm9qZWN0MRAwDgYDVQQD
17
+ DAdUZXN0IENBggkA/9nHC4c30ZQwMAYIKwYBBQUHAQEEJDAiMCAGCCsGAQUFBzAB
18
+ hhRodHRwOi8vb2NzcC5yNTA5Lm9yZzANBgkqhkiG9w0BAQUFAAOCAQEAAV6ub5mP
19
+ xLYV8Zpu6WhG1JvM8PKEUzPv5jR3Bzm0MG9ISlT9soVO2LxcRoRUMscTzvPLIIj/
20
+ R24fMjJMzewu/BmYVcJJ9aG1z5Zdlczjz+Jm8P40V1x6iMn/MZrDc4Yx00TIkzT0
21
+ b2w6GvPjS6RZwybTr6d1bj8EB0Urbuk7a/FL3hOi5wQ4AWh+RqW8mWjvjs1ElKE5
22
+ hpIb2fjC3JnifZAo/sD2xV8Y3Vasqb2uUGYZ3+HZFTbF+WQ6OZHVHlv0xB1yYTid
23
+ 4melkAZEPf5OblurgioGu0b9nSHGdrCrk84nKdNN3w5rFOPo/dyaO5wcYIpcpC6f
24
+ Hs6C1rY6pPOImw==
25
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEAurOhNERz3Qv4OmVXv+G0ZGthZ3Y6gsMYrk6WqhUMH/P3rV8g
3
+ rs9GQA7NOFmqgrSLPrlKF4fo0gYNAVQtK3NaQqECK2qvTN2Sdbprv4vejoYY25Nc
4
+ oCVt1Nfr3cVrqMJOB+df6S2zVCMv357UkxNb0m1aNa74iv0hV6R09z2j4yF+CIy6
5
+ Z1tdvodcx+T/ci6CGfzTfrOuK1ttSV98v4BRuA1vXdC8TCmyOTYsb25/tZqSwnD5
6
+ /qTuIv/KPAF7PxbKCop4N9ptt5O/vK89iFimVnFaC3uP8fo9NM8473lwL76FwaJm
7
+ IH7bI/N7QkObzhc51aGSUTn6irXEcBaQ2kKLAQIDAQABAoIBAGjoMGenIxeM90EQ
8
+ 2tq132AhukyhcUUyjPa8sAoH45U8x+oCLuIrE8VAy+2i7J2fBzMKeGh6dMc2oS4i
9
+ 93KX0Zroz8hHnRLq2bYPNyYdWMPq86LFzeEqxuk3HpCxssnTzHbCevESPdbEIs1b
10
+ eQTfdtPpoCvUElI+4/JUNWkLmMAxhlnQjAVIIB4RsjUugn4h2VZIj5tx7L9at06C
11
+ TPz10xA6v+uIxtYE1Ijr0LB0LjV7FIttfHbq/6SoNaRCGYz1m0VN6CJ/cN6tBMAj
12
+ EKwpnfD1kr0T1N+Y27lnLEW+xSg8DfQIchaKc3dJFr8Sx+WbpajSKEywtfl4wpTV
13
+ iwT/ZDECgYEA6dqXr038bf29womMh9Qds2YMUt5SI+SjA9DHxcvodCzyG5dvchpY
14
+ 0V8RXPWJsVV9ECWbGr8T0ZPPXo3EFR8JyOUBDnDgDE0SlhFo4lNlRLHYFsUPrjgf
15
+ 6IHhCTtkZtdOr7ObZe4mOjo3K2tQcN7e4uArIFqNP5tUc48hcNhO410CgYEAzGHo
16
+ oOsj7xBBO+3ohIsXgXXlNqcAnCBkUYVC9HIBi+atWUddpsXrXF+YVMn3Kw8nEZnE
17
+ /KUINnwn+NyInmSEmgRuWo6Uv+dxa8I7H51LkjtmhhIFkMTxXewTLdrWkX1M/9dp
18
+ RwrkGHN3vTYPi4/PT18FIw/MZ6pH9ly4M1Kqj/UCgYBUAC4eTWAQTmX8XBY7sCjf
19
+ CRgCKFPPCtC3jSZFWYJtQLvSx2nDzcz7oC+Hebd1GKUsyKVXTS2cSYDikP/PKnAE
20
+ VqYzfr4sDP9RIn3PVm945n0daLnCNezYQtcHzuq4ujxMhrKaQZo/riulEA48DQJ4
21
+ 8lbrbztvjqceP1qew0RLDQKBgGBqy/imFSShcXTZLjjg+SzMtl5K+IGu0kSW7lgt
22
+ NEeQgjS88xRLCFZijpVpVd4NXuvxs7lQDYjOl3jSaOz4FIooDvtPiiLiB2LDlWq7
23
+ pLwOo7YZ6GA8WHVrejzGoTSvfNSxBWxLWgGi71jmmPzI0g7qj5zTxiUdcqdpZEhp
24
+ 9ibFAoGAPMEI59/eCmSZPIZ7acs//4HI0QTo6856KZj4bqlowdeZf/D7uyCpn7UX
25
+ 904L4tAVwLKddqmDXbReS/ObsNs4v1FsdgnTySR59PYmW67S/CMzyN0T9Ld4xtOe
26
+ R/khjaviCkqAmPzDRx8+OZmbzNJtb0s6hJIQS73lcj84kuprSio=
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,25 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEPzCCAyegAwIBAgIVAPVJ8f7HkMe36qArq2sTN1abDCjWMA0GCSqGSIb3DQEB
3
+ BQUAMC4xCzAJBgNVBAYTAlVTMR8wHQYDVQQDDBZyNTA5IEFyYml0cmFyeSBTdWJy
4
+ b290MB4XDTEyMDEwNjEzMDgzNFoXDTMyMDEwMTE5MDgzNFowaDELMAkGA1UEBhMC
5
+ VVMxETAPBgNVBAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMREwDwYDVQQK
6
+ DAhyNTA5IExMQzEhMB8GA1UEAwwYcjUwOSBTdWJyb290IE9DU1AgU2lnbmVyMIIB
7
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuOPd0oz5t/GJyB94jTXyALy7
8
+ tD2F3FgIIkMx+0zWwxytd7OMWmYGnxxSjx/kC1VbLnB254llbWVf6aZO13sNgXTb
9
+ tXtWcHBSIfje1IAFW85+UHuQ3L/cv/JoFxFL0r0L/MPO0zwMTBa68TVTS6LhvjNY
10
+ 8mK0Oot6i/m/Hh7LXK6ynYxqqacAdK6PKMKsGG1ywDwrGNvjLpH3qmzTkqTkF+8o
11
+ J2B5kgIAMVEfgiK46zFtIMe6tcDT7n5KJ2NwG3GVwRnrTgnuBqpp8/hukAEdLT/L
12
+ yD0DShA5HWljJQGj8JlWe+x2k68kMHN4fgNfBoE97wjFCdeolKSHUP6yDn3+wQID
13
+ AQABo4IBGDCCARQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCTAd
14
+ BgNVHQ4EFgQU0sNGTKxh+UEPYyBk1Wi3Uisq4gkwgZwGA1UdIwSBlDCBkYAUtsRD
15
+ bNCYQJnEYNRxJAcAcPZ6JWqhYqRgMF4xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhJ
16
+ bGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEYMBYGA1UECgwPUnVieSBDQSBQcm9q
17
+ ZWN0MRAwDgYDVQQDDAdUZXN0IENBghUAvEdJr0vjxkfer0QA24YwgJg6ZGkwMQYI
18
+ KwYBBQUHAQEEJTAjMCEGCCsGAQUFBzABhhVodHRwOi8vb2NzcC5yNTA5Lm9yZy8w
19
+ DQYJKoZIhvcNAQEFBQADggEBALOUPqx9blxSYAvor/H1ITWz0huj+WPvGdPQABGn
20
+ nu16V7Jak3EposqXY9ObKteWzdiLvo41O4mVAviBhdKYexo/LLlEa5cP6/lRQ2yC
21
+ TR5MKYTVIaaSuxCTxwM4AF2XFaRs2AnxcpPKQjCkxe6fT0lPwuQbBdQqjtRl39CR
22
+ +2muSQlqpCz4KTPivTOCyOizIrhnxhMjcSr1zxpEPsCbJO0Bd/8PPHPER3MMXmYb
23
+ Ci3HVRWqDczVniy3tmKh20rEWZPUmJNiLaGLdD5Ug39YhGMn9fkT+x8+UxIeaNZW
24
+ 2JtcNoOp9v5e7EOcxJp2doHq3+FCOii3LwHlwk2XMAeKYKo=
25
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpAIBAAKCAQEAuOPd0oz5t/GJyB94jTXyALy7tD2F3FgIIkMx+0zWwxytd7OM
3
+ WmYGnxxSjx/kC1VbLnB254llbWVf6aZO13sNgXTbtXtWcHBSIfje1IAFW85+UHuQ
4
+ 3L/cv/JoFxFL0r0L/MPO0zwMTBa68TVTS6LhvjNY8mK0Oot6i/m/Hh7LXK6ynYxq
5
+ qacAdK6PKMKsGG1ywDwrGNvjLpH3qmzTkqTkF+8oJ2B5kgIAMVEfgiK46zFtIMe6
6
+ tcDT7n5KJ2NwG3GVwRnrTgnuBqpp8/hukAEdLT/LyD0DShA5HWljJQGj8JlWe+x2
7
+ k68kMHN4fgNfBoE97wjFCdeolKSHUP6yDn3+wQIDAQABAoIBAEql1X2Y5Ynav2JJ
8
+ Mobw7NBXYwGWhWE9Oat7rcZkc6E7Bt55Y4VsA+hhqwOWQKBCyhmp1pgM5SKR93OC
9
+ bfqZ+A34fGx9a5zh/Icyz+TD+2XhrSYZfZdi72GgIV6O4SoooZpgBDVM3TorQzb3
10
+ 7LVxAeulF5hlOZcZkVTKdNtYW4sDXa0zthSLhCladQjRSV2znuNN1ZRocQhNRMv6
11
+ 4MgOVon2S22HkxFHz0yT6NImp6Ns3Qvjoej1MAcuhMhcHFFvhHvn1GUF4Ur6A6JP
12
+ Rbr2Z6h0hUmKqVX02kEgYhJduy3btVr+QGKDZBD43vzFZ74ZQsLbK9mXZFU0eOe9
13
+ dWglZ0ECgYEA5i2saggVyHbOm+WbE5FvUwVrkdokM9lUeK6QY+mWN0xJ8uTUwplR
14
+ iXw4gr7Jcl5D8SoNm6EFGzQh4ZVkZw8v0CpO18sA3gTBVLMPl8EijUzUNk6MIKUL
15
+ h37O0Wr6hnpFsuTwFZgwmuBc4KYY9eNVhzURjDD+bbvNx+9krYLuU3UCgYEAzaGX
16
+ StD/d8ypcAmzl0x4BeN7QbkHRtYC5MqPfkycmegypJAIXIV9kVRGznj4+Q2Zne9e
17
+ E1llS41KJHgi04LL34/wunSAPGNTLEbhQObSxZppDTFmZhouN4CMEIUMrETXHDri
18
+ Qy0SMLmnD3LxmpnGvMMyQICU1BfLvIPxvUh3kJ0CgYATohWwvZvOC4Q3+++sTZ1n
19
+ QXEZcbfgzErOOGWMgCIV+WXdV/Nl3dn8liHj1Q4tuSima2XZvnRHC71QFoQH3l2/
20
+ rbwn3+LlDRbIeLV9xjWCQ+ld8Hk3V5ySJBjT+AICcm97gNeRn/eVXknNx50dbBSh
21
+ gb9La+pnxbsZsKuvuRlG+QKBgQC8U8ByXxN6LtEHsXrvmLNcAUmDmehWMe8Yh4QA
22
+ Ej5insyy9s8RnZixH1RyCU1NG+2TPgUVB4zEMzSyTezndiUuLXA19Dj2Fam5JXlr
23
+ rXtgStjnolS8MkIdxveAsbo3lBzG2A8dowvD4GRmu8kW5Lulach+VsT3sot/rgAa
24
+ cWI/6QKBgQCWL6c25xjU71n+ZQfXt1nLes1Z06bs25oOJnY6cKwXn41o4Z+FAaEG
25
+ +XSpGDHed5lO/WqolSMF1BGAVgZU6x7YK0iBDbRia5bVs3KAs0p7vEO2vIKNx58A
26
+ UuuAb6igKKOLzM7L7vzNwQr4QyuSUTL0cgOlVT6RVR1F6tlkXd2wdw==
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,17 @@
1
+ copy_nonce: true
2
+ cache_headers: true
3
+ max_cache_age: 60
4
+ certificate_authorities: {
5
+ test_ca: {
6
+ ca_cert: {
7
+ cert: "spec/fixtures/test_ca.cer",
8
+ key: "spec/fixtures/test_ca.key"
9
+ }
10
+ },
11
+ second_ca: {
12
+ ca_cert: {
13
+ cert: "spec/fixtures/second_ca.cer",
14
+ key: "spec/fixtures/second_ca.key"
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,400 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'time'
3
+
4
+
5
+ describe R509::Ocsp::Responder::Server do
6
+ before :all do
7
+ @test_ca_cert = OpenSSL::X509::Certificate.new(File.read(Pathname.new(__FILE__).dirname + "fixtures/test_ca.cer"))
8
+ @second_ca_cert = OpenSSL::X509::Certificate.new(File.read(Pathname.new(__FILE__).dirname + "fixtures/second_ca.cer"))
9
+ end
10
+
11
+ before :each do
12
+ # clear the dependo before each test
13
+ Dependo::Registry.clear
14
+ Dependo::Registry[:log] = Logger.new(nil)
15
+
16
+ # we always want to mock with a new redis
17
+ @redis = double("redis")
18
+ Dependo::Registry[:redis] = @redis
19
+
20
+ # and we want to mock the stats recorder
21
+ @stats = double("stats")
22
+ Dependo::Registry[:stats] = @stats
23
+
24
+ # default value for :copy_nonce is false (can override on a per-test basis)
25
+ Dependo::Registry[:copy_nonce] = false
26
+
27
+ # default value for :cache_headers is false (can override on a per-test basis)
28
+ Dependo::Registry[:cache_headers] = false
29
+
30
+ # default value for :max_cache_age is nil (can override on a per-test basis)
31
+ Dependo::Registry[:max_cache_age] = nil
32
+
33
+ # read the config.yaml
34
+ @config_pool = R509::Config::CaConfigPool.from_yaml("certificate_authorities", File.read(File.dirname(__FILE__)+"/fixtures/test_config.yaml"))
35
+ end
36
+
37
+ def app
38
+ # this is executed after the code in each test, so if we change something in the dependo registry, it'll show up here (we will set :copy_nonce in some tests)
39
+ Dependo::Registry[:ocsp_signer] = R509::Ocsp::Signer.new(
40
+ :configs => @config_pool,
41
+ :validity_checker => R509::Validity::Redis::Checker.new(Dependo::Registry[:redis]),
42
+ :copy_nonce => Dependo::Registry[:copy_nonce]
43
+ )
44
+ @app ||= R509::Ocsp::Responder::Server
45
+ end
46
+
47
+ it "should return unauthorized on a GET which does not match any configured CA" do
48
+ get '/MFEwTzBNMEswSTAJBgUrDgMCGgUABBQ1mI4Ww4R5LZiQ295pj4OF%2F44yyAQUyk7dWyc1Kdn27sPlU%2B%2BkwBmWHa8CEFqb7H4xpqYH6ed2G0%2BPMG4%3D'
49
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
50
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_UNAUTHORIZED
51
+ last_response.content_type.should == "application/ocsp-response"
52
+ last_response.should be_ok
53
+ end
54
+
55
+ it "should return a valid (UNKNOWN) response on a GET request from the test_ca CA" do
56
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({})
57
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "UNKNOWN")
58
+
59
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D'
60
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
61
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
62
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
63
+ ocsp_response.basic.status[0][0].serial.should == 1051177536915098490149656742929223623669143613238
64
+ ocsp_response.verify(@test_ca_cert).should == true
65
+ last_response.content_type.should == "application/ocsp-response"
66
+ last_response.should be_ok
67
+ end
68
+
69
+ it "should return a valid (REVOKED) response on a GET request from the test_ca CA" do
70
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({"status" => R509::Validity::REVOKED})
71
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "REVOKED")
72
+
73
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D'
74
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
75
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
76
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_REVOKED
77
+ ocsp_response.basic.status[0][0].serial.should == 1051177536915098490149656742929223623669143613238
78
+ ocsp_response.verify(@test_ca_cert).should == true
79
+ last_response.content_type.should == "application/ocsp-response"
80
+ last_response.should be_ok
81
+ end
82
+
83
+ it "should return a valid (VALID) response on a GET request from the test_ca CA" do
84
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({"status" => R509::Validity::VALID})
85
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "VALID")
86
+
87
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D'
88
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
89
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
90
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_GOOD
91
+ ocsp_response.basic.status[0][0].serial.should == 1051177536915098490149656742929223623669143613238
92
+ ocsp_response.verify(@test_ca_cert).should == true
93
+ last_response.content_type.should == "application/ocsp-response"
94
+ last_response.should be_ok
95
+ end
96
+
97
+ it "should return a valid (VALID) response on a GET request with extra leading slashes from the test_ca CA" do
98
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({"status" => R509::Validity::VALID})
99
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "VALID")
100
+
101
+ get '/%2F%2FMFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D'
102
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
103
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
104
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_GOOD
105
+ ocsp_response.basic.status[0][0].serial.should == 1051177536915098490149656742929223623669143613238
106
+ ocsp_response.verify(@test_ca_cert).should == true
107
+ last_response.content_type.should == "application/ocsp-response"
108
+ last_response.should be_ok
109
+ end
110
+
111
+ it "should return a valid (VALID) response on a GET request from a second configured CA (second_ca)" do
112
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA:773553085290984246110251380739025914079776985795").and_return({"status" => R509::Validity::VALID})
113
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA", "773553085290984246110251380739025914079776985795", "VALID")
114
+
115
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBT1kOLWHXbHiKP3sVPVxVziq%2FMqIwQUP8ezIf8yhMLgHnccSKJLQdhDaVkCFQCHf1HsjUAACwcp3qQL4IxclfXSww%3D%3D'
116
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
117
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
118
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_GOOD
119
+ ocsp_response.basic.status[0][0].serial.should == 773553085290984246110251380739025914079776985795
120
+ ocsp_response.verify(@test_ca_cert).should == false
121
+ ocsp_response.verify(@second_ca_cert).should == true
122
+ last_response.content_type.should == "application/ocsp-response"
123
+ last_response.should be_ok
124
+ end
125
+
126
+ it "should return unauthorized on a POST which does not match any configured CA" do
127
+ der = Base64.decode64(URI.decode("MFEwTzBNMEswSTAJBgUrDgMCGgUABBQ1mI4Ww4R5LZiQ295pj4OF%2F44yyAQUyk7dWyc1Kdn27sPlU%2B%2BkwBmWHa8CEFqb7H4xpqYH6ed2G0%2BPMG4%3D"))
128
+ post '/', der, "CONTENT_TYPE" => "application/ocsp-request"
129
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
130
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_UNAUTHORIZED
131
+ last_response.content_type.should == "application/ocsp-response"
132
+ last_response.should be_ok
133
+ end
134
+
135
+ it "should return a valid (UNKNOWN) response on a POST request from the test_ca CA" do
136
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({})
137
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "UNKNOWN")
138
+
139
+ der = Base64.decode64(URI.decode("MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D"))
140
+ post '/', der, "CONTENT_TYPE" => "application/ocsp-request"
141
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
142
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
143
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
144
+ ocsp_response.basic.status[0][0].serial.should == 1051177536915098490149656742929223623669143613238
145
+ ocsp_response.verify(@test_ca_cert).should == true
146
+ last_response.content_type.should == "application/ocsp-response"
147
+ last_response.should be_ok
148
+ end
149
+
150
+ it "should return a valid (REVOKED) response on a POST request from the test_ca CA" do
151
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({"status" => R509::Validity::REVOKED})
152
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "REVOKED")
153
+
154
+ der = Base64.decode64(URI.decode("MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D"))
155
+ post '/', der, "CONTENT_TYPE" => "application/ocsp-request"
156
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
157
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
158
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_REVOKED
159
+ ocsp_response.basic.status[0][0].serial.should == 1051177536915098490149656742929223623669143613238
160
+ ocsp_response.verify(@test_ca_cert).should == true
161
+ last_response.content_type.should == "application/ocsp-response"
162
+ last_response.should be_ok
163
+ end
164
+
165
+ it "should return a valid (VALID) response on a POST request from the test_ca CA" do
166
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({"status" => R509::Validity::VALID})
167
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "VALID")
168
+
169
+ der = Base64.decode64(URI.decode("MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D"))
170
+ post '/', der, "CONTENT_TYPE" => "application/ocsp-request"
171
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
172
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
173
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_GOOD
174
+ ocsp_response.basic.status[0][0].serial.should == 1051177536915098490149656742929223623669143613238
175
+ ocsp_response.verify(@test_ca_cert).should == true
176
+ last_response.content_type.should == "application/ocsp-response"
177
+ last_response.should be_ok
178
+ end
179
+
180
+ it "should return a valid (VALID) response on a POST request from a second configured CA (second_ca)" do
181
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA:773553085290984246110251380739025914079776985795").and_return({"status" => R509::Validity::VALID})
182
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA", "773553085290984246110251380739025914079776985795", "VALID")
183
+
184
+ der = Base64.decode64(URI.decode("MFYwVDBSMFAwTjAJBgUrDgMCGgUABBT1kOLWHXbHiKP3sVPVxVziq%2FMqIwQUP8ezIf8yhMLgHnccSKJLQdhDaVkCFQCHf1HsjUAACwcp3qQL4IxclfXSww%3D%3D"))
185
+ post '/', der, "CONTENT_TYPE" => "application/ocsp-request"
186
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
187
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
188
+ ocsp_response.basic.status[0][1].should == OpenSSL::OCSP::V_CERTSTATUS_GOOD
189
+ ocsp_response.basic.status[0][0].serial.should == 773553085290984246110251380739025914079776985795
190
+ ocsp_response.verify(@test_ca_cert).should == false
191
+ ocsp_response.verify(@second_ca_cert).should == true
192
+ last_response.content_type.should == "application/ocsp-response"
193
+ last_response.should be_ok
194
+ end
195
+
196
+ it "should return 200 OK when querying status and redis is available" do
197
+ @redis.should_receive(:ping).and_return("PONG")
198
+ get '/status'
199
+ last_response.should be_ok
200
+ end
201
+
202
+ it "should return 500 DOWN when querying status with redis unavailable" do
203
+ @redis.should_receive(:ping).and_raise(StandardError)
204
+ get '/status'
205
+ last_response.should_not be_ok
206
+ last_response.body.should == "Down"
207
+ end
208
+
209
+ it "a malformed request should return a proper OCSP response (GET)" do
210
+ get '/Msdfsfsdf'
211
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
212
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_MALFORMEDREQUEST
213
+ last_response.content_type.should == "application/ocsp-response"
214
+ last_response.should be_ok
215
+ end
216
+
217
+ it "a malformed request should return a proper OCSP response (POST)" do
218
+ post '/', 'Mdskfsdf', "CONTENT_TYPE" => "application/ocsp-request"
219
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
220
+ ocsp_response.status.should == OpenSSL::OCSP::RESPONSE_STATUS_MALFORMEDREQUEST
221
+ last_response.content_type.should == "application/ocsp-response"
222
+ last_response.should be_ok
223
+ end
224
+
225
+ it "copies nonce when copy_nonce is true" do
226
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:872625873161273451176241581705670534707360122361").and_return({"status" => R509::Validity::VALID})
227
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "872625873161273451176241581705670534707360122361", "VALID")
228
+
229
+ # set to true for this test (this works because the app doesn't get set up until after this code)
230
+ Dependo::Registry[:copy_nonce] = true
231
+
232
+ get '/MHsweTBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQCY2eXAtMNzVS33fF0PHrUSjklF%2BaIjMCEwHwYJKwYBBQUHMAECBBIEEDTJniOQonxCRmmHAHCVstw%3D'
233
+ request = OpenSSL::OCSP::Request.new(Base64.decode64("MHsweTBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQCY2eXAtMNzVS33fF0PHrUSjklF+aIjMCEwHwYJKwYBBQUHMAECBBIEEDTJniOQonxCRmmHAHCVstw="))
234
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
235
+ request.check_nonce(ocsp_response.basic).should == R509::Ocsp::Request::Nonce::PRESENT_AND_EQUAL
236
+
237
+ end
238
+
239
+ it "doesn't copy nonce when copy_nonce is false" do
240
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:872625873161273451176241581705670534707360122361").and_return({"status" => R509::Validity::VALID})
241
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "872625873161273451176241581705670534707360122361", "VALID")
242
+
243
+ # set to false for this test (this works because the app doesn't get set up until after this code)
244
+ Dependo::Registry[:copy_nonce] = false
245
+
246
+ get '/MHsweTBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQCY2eXAtMNzVS33fF0PHrUSjklF%2BaIjMCEwHwYJKwYBBQUHMAECBBIEEDTJniOQonxCRmmHAHCVstw%3D'
247
+ request = OpenSSL::OCSP::Request.new(Base64.decode64("MHsweTBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQCY2eXAtMNzVS33fF0PHrUSjklF+aIjMCEwHwYJKwYBBQUHMAECBBIEEDTJniOQonxCRmmHAHCVstw="))
248
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
249
+ request.check_nonce(ocsp_response.basic).should == R509::Ocsp::Request::Nonce::REQUEST_ONLY
250
+ end
251
+
252
+ it "returns caching headers for GET when cache_headers is true and no nonce is present" do
253
+ Dependo::Registry[:cache_headers] = true
254
+
255
+ now = Time.now
256
+ Time.stub!(:now).and_return(now)
257
+
258
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA:773553085290984246110251380739025914079776985795").and_return({"status" => R509::Validity::VALID})
259
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA", "773553085290984246110251380739025914079776985795", "VALID")
260
+
261
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBT1kOLWHXbHiKP3sVPVxVziq%2FMqIwQUP8ezIf8yhMLgHnccSKJLQdhDaVkCFQCHf1HsjUAACwcp3qQL4IxclfXSww%3D%3D'
262
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
263
+ last_response.headers.size.should == 6
264
+ last_response.headers["Last-Modified"].should == Time.now.httpdate
265
+ last_response.headers["ETag"].should == OpenSSL::Digest::SHA1.new(ocsp_response.to_der).to_s
266
+ last_response.headers["Expires"].should == ocsp_response.basic.status[0][5].httpdate
267
+ max_age = ocsp_response.basic.status[0][5] - now
268
+ last_response.headers["Cache-Control"].should == "max-age=#{max_age.to_i}, public, no-transform, must-revalidate"
269
+ end
270
+
271
+ it "returns no caching headers for GET when cache_headers is false and no nonce is present" do
272
+ Dependo::Registry[:cache_headers] = false
273
+
274
+ now = Time.now
275
+ Time.stub!(:now).and_return(now)
276
+
277
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA:773553085290984246110251380739025914079776985795").and_return({"status" => R509::Validity::VALID})
278
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA", "773553085290984246110251380739025914079776985795", "VALID")
279
+
280
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBT1kOLWHXbHiKP3sVPVxVziq%2FMqIwQUP8ezIf8yhMLgHnccSKJLQdhDaVkCFQCHf1HsjUAACwcp3qQL4IxclfXSww%3D%3D'
281
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
282
+ last_response.headers.size.should == 2
283
+ end
284
+
285
+ it "returns no caching headers for GET when cache_headers is true and a nonce is present" do
286
+ Dependo::Registry[:cache_headers] = true
287
+
288
+ now = Time.now
289
+ Time.stub!(:now).and_return(now)
290
+
291
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:872625873161273451176241581705670534707360122361").and_return({"status" => R509::Validity::VALID})
292
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "872625873161273451176241581705670534707360122361", "VALID")
293
+
294
+ get '/MHsweTBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQCY2eXAtMNzVS33fF0PHrUSjklF%2BaIjMCEwHwYJKwYBBQUHMAECBBIEEDTJniOQonxCRmmHAHCVstw%3D'
295
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
296
+ last_response.headers.size.should == 2
297
+ end
298
+
299
+ it "returns no caching headers for GET when cache_headers is false and a nonce is present" do
300
+ Dependo::Registry[:cache_headers] = false
301
+
302
+ now = Time.now
303
+ Time.stub!(:now).and_return(now)
304
+
305
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:872625873161273451176241581705670534707360122361").and_return({"status" => R509::Validity::VALID})
306
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "872625873161273451176241581705670534707360122361", "VALID")
307
+
308
+ get '/MHsweTBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQCY2eXAtMNzVS33fF0PHrUSjklF%2BaIjMCEwHwYJKwYBBQUHMAECBBIEEDTJniOQonxCRmmHAHCVstw%3D'
309
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
310
+ last_response.headers.size.should == 2
311
+ end
312
+
313
+ it "returns custom max_cache_age when it's set properly" do
314
+ Dependo::Registry[:cache_headers] = true
315
+ Dependo::Registry[:max_cache_age] = 600
316
+
317
+ now = Time.now
318
+ Time.stub!(:now).and_return(now)
319
+
320
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA:773553085290984246110251380739025914079776985795").and_return({"status" => R509::Validity::VALID})
321
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA", "773553085290984246110251380739025914079776985795", "VALID")
322
+
323
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBT1kOLWHXbHiKP3sVPVxVziq%2FMqIwQUP8ezIf8yhMLgHnccSKJLQdhDaVkCFQCHf1HsjUAACwcp3qQL4IxclfXSww%3D%3D'
324
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
325
+ last_response.headers.size.should == 6
326
+ last_response.headers["Last-Modified"].should == now.httpdate
327
+ last_response.headers["ETag"].should == OpenSSL::Digest::SHA1.new(ocsp_response.to_der).to_s
328
+ last_response.headers["Expires"].should == ocsp_response.basic.status[0][5].httpdate
329
+ last_response.headers["Cache-Control"].should == "max-age=600, public, no-transform, must-revalidate"
330
+ end
331
+
332
+ it "returns default max_cache_age if custom age is too large" do
333
+ Dependo::Registry[:cache_headers] = true
334
+ Dependo::Registry[:max_cache_age] = 950000
335
+
336
+ now = Time.now
337
+ Time.stub!(:now).and_return(now)
338
+
339
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA:773553085290984246110251380739025914079776985795").and_return({"status" => R509::Validity::VALID})
340
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA", "773553085290984246110251380739025914079776985795", "VALID")
341
+
342
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBT1kOLWHXbHiKP3sVPVxVziq%2FMqIwQUP8ezIf8yhMLgHnccSKJLQdhDaVkCFQCHf1HsjUAACwcp3qQL4IxclfXSww%3D%3D'
343
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
344
+ last_response.headers.size.should == 6
345
+ last_response.headers["Last-Modified"].should == now.httpdate
346
+ last_response.headers["ETag"].should == OpenSSL::Digest::SHA1.new(ocsp_response.to_der).to_s
347
+ last_response.headers["Expires"].should == ocsp_response.basic.status[0][5].httpdate
348
+ max_age = ocsp_response.basic.status[0][5] - now
349
+ last_response.headers["Cache-Control"].should == "max-age=#{max_age.to_i}, public, no-transform, must-revalidate"
350
+ end
351
+
352
+ it "returns no caching headers for GET when cache_headers is false" do
353
+ Dependo::Registry[:cache_headers] = false
354
+
355
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA:773553085290984246110251380739025914079776985795").and_return({"status" => R509::Validity::VALID})
356
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=R509, Ltd/CN=R509 Secondary Test CA", "773553085290984246110251380739025914079776985795", "VALID")
357
+
358
+ get '/MFYwVDBSMFAwTjAJBgUrDgMCGgUABBT1kOLWHXbHiKP3sVPVxVziq%2FMqIwQUP8ezIf8yhMLgHnccSKJLQdhDaVkCFQCHf1HsjUAACwcp3qQL4IxclfXSww%3D%3D'
359
+ last_response.content_type.should == "application/ocsp-response"
360
+ last_response.headers.size.should == 2
361
+ last_response.should be_ok
362
+ end
363
+
364
+ it "returns no caching headers for POST when cache_headers is true" do
365
+ Dependo::Registry[:cache_headers] = true
366
+
367
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({"status" => R509::Validity::VALID})
368
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "VALID")
369
+
370
+ der = Base64.decode64(URI.decode("MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D"))
371
+ post '/', der, "CONTENT_TYPE" => "application/ocsp-request"
372
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
373
+ last_response.content_type.should == "application/ocsp-response"
374
+ last_response.headers.size.should == 2
375
+ last_response.should be_ok
376
+ end
377
+
378
+ it "returns no caching headers for POST when cache_headers is false" do
379
+ Dependo::Registry[:cache_headers] = false
380
+
381
+ @redis.should_receive(:hgetall).with("cert:/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA:1051177536915098490149656742929223623669143613238").and_return({"status" => R509::Validity::VALID})
382
+ @stats.should_receive(:record).with("/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA", "1051177536915098490149656742929223623669143613238", "VALID")
383
+
384
+ der = Base64.decode64(URI.decode("MFYwVDBSMFAwTjAJBgUrDgMCGgUABBQ4ykaMB0SN9IGWx21tTHBRnmCnvQQUeXW7hDrLLN56Cb4xG0O8HCpNU1gCFQC4IG5U4zC4RYb4VQ%2B2f0zCoFCvNg%3D%3D"))
385
+ post '/', der, "CONTENT_TYPE" => "application/ocsp-request"
386
+ ocsp_response = R509::Ocsp::Response.parse(last_response.body)
387
+ last_response.content_type.should == "application/ocsp-response"
388
+ last_response.headers.size.should == 2
389
+ last_response.should be_ok
390
+ end
391
+
392
+ it "should reload and print config when receiving a SIGUSR2" do
393
+ config = double("config")
394
+ stub_const("R509::Ocsp::Responder::OcspConfig",config)
395
+ #R509::Ocsp::Responder::OcspConfig = double("config")
396
+ R509::Ocsp::Responder::OcspConfig.should_receive(:load_config)
397
+ R509::Ocsp::Responder::OcspConfig.should_receive(:print_config)
398
+ Process.kill :USR2, Process.pid
399
+ end
400
+ end