github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/x509/revocation/google/google_test.go (about) 1 package google_test 2 3 import ( 4 "io/ioutil" 5 "net/http" 6 "net/http/httptest" 7 "os" 8 "strings" 9 "testing" 10 11 "github.com/zmap/zcrypto/x509" 12 "github.com/zmap/zcrypto/x509/revocation/google" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 // obtained from https://firefox.settings.services.mozilla.com/v1/buckets/blocklists/collections/certificates/records 19 const crlset_location = `./testdata/test_crlset` 20 const VERSION = "4619" 21 22 const revoked_intermediate = ` 23 -----BEGIN CERTIFICATE----- 24 MIIHVTCCBT2gAwIBAgIIEOqAPvgqxt8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE 25 BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h 26 cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xMzAyMjAxMDAzMTdaFw0zMDEy 27 MzEwNTA1NDJaMIGNMQswCQYDVQQGEwJFUzEeMBwGA1UEChMVRmlybWFwcm9mZXNp 28 b25hbCBTLkEuMRowGAYDVQQLExFTZWN1cml0eSBTZXJ2aWNlczESMBAGA1UEBRMJ 29 QTYyNjM0MDY4MS4wLAYDVQQDEyVBQyBGaXJtYXByb2Zlc2lvbmFsIC0gSU5GUkFF 30 U1RSVUNUVVJBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuqX7V9RP 31 HmZ/SpGlhXSfREEtOiiRS8SdJC1QuOB2EYLiFEeL2QFZHIRP4HBm+CbLZ7ts+GLD 32 5XOGWa84Q9BgRI2HXF4E9PeCQh+ejtnnpDRQlx/cIkX5zt750xXfjArifVS4IUHR 33 fiyfZmNuyn3qqB5O/nz1K/YelKSZtbjc00qlwXU4sfrZRFJgm0PD6oxJqLoU8VVE 34 jBzdbVWsG9KEc91gG0u5UJZyLWGJP2f7I/zrki2WOf9SPfrA01viYw2PSe/81Z7O 35 tADKy076N6Z8ky4HaS1aNsqxx/LTylUh+9O0ccGKSQSpO87LFbrKNilGvIRQYzrj 36 ItUawGsF0KuUEwIDAQABo4IC8jCCAu4wdAYIKwYBBQUHAQEEaDBmMDYGCCsGAQUF 37 BzAChipodHRwOi8vY3JsLmZpcm1hcHJvZmVzaW9uYWwuY29tL2Nhcm9vdC5jcnQw 38 LAYIKwYBBQUHMAGGIGh0dHA6Ly9vY3NwLmZpcm1hcHJvZmVzaW9uYWwuY29tMB0G 39 A1UdDgQWBBRiFau1swh5pYf+gNki8I78jxH9eTASBgNVHRMBAf8ECDAGAQH/AgEA 40 MB8GA1UdIwQYMBaAFGXN66s1HgA+ftV0wBy0c0cOGmQvMIIB0gYDVR0gBIIByTCC 41 AcUwggHBBgorBgEEAeZ5CgoBMIIBsTAvBggrBgEFBQcCARYjaHR0cDovL3d3dy5m 42 aXJtYXByb2Zlc2lvbmFsLmNvbS9jcHMwggF8BggrBgEFBQcCAjCCAW4eggFqAEMA 43 ZQByAHQAaQBmAGkAYwBhAGQAbwAgAGQAZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAA 44 ZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAuACAAQwBvAG4AcwB1AGwA 45 dABlACAAbABhAHMAIABjAG8AbgBkAGkAYwBpAG8AbgBlAHMAIABkAGUAIAB1AHMA 46 bwAgAGUAbgAgAC8AIABDAGUAcgB0AGkAZgBpAGMAYQB0AGkAbwBuACAAQQB1AHQA 47 aABvAHIAaQB0AHkAIABjAGUAcgB0AGkAZgBpAGMAYQB0AGUALgAgAFMAZQBlACAA 48 dABlAHIAbQBzACAAYQBuAGQAIABjAG8AbgBkAGkAdABpAG8AbgBzACAAYQB0ACAA 49 IABoAHQAdABwADoALwAvAHcAdwB3AC4AZgBpAHIAbQBhAHAAcgBvAGYAZQBzAGkA 50 bwBuAGEAbAAuAGMAbwBtAC8AYwBwAHMwPAYDVR0fBDUwMzAxoC+gLYYraHR0cHM6 51 Ly9jcmwuZmlybWFwcm9mZXNpb25hbC5jb20vZnByb290LmNybDAOBgNVHQ8BAf8E 52 BAMCAQYwDQYJKoZIhvcNAQEFBQADggIBAGRD/ej1VKQGfWiBwL8I6plyFfvplmwO 53 +N7EpzUifUgn2sDHiL2L2V5nQdN2lLL5tI83JimPKybrHbv9EwSGPsTOgY+8HWCA 54 iaq9dLKVHRK93/FvI+Wj63X6pvx5YDiT2Kq7RuXQFx8AG+acwMa7WHaeravzAiSd 55 pak4qW5KlZ54RxiTNtFGwuEGpHc7wakdWSH3hUYfXNLz8JC9DmNqG8ZxAf3Z8AJq 56 vIeH4NRPkZ6//QG5JzPowb8eNG2v84ZYQStIAsHa0sVdq9o/zK9x2isv4Y+5GAw4 57 bnfq14G23Zh1oFS2T6la7W+AR3OGhP8Y6Xt+TFhn10yfE4TrFGNr20akj2TddsMj 58 SAatoB2gE3f7wTFsrXdJn0aJ/18KdlqV0NNuHrs/ZOIhnt7qswZVQfeQHHUQpwOp 59 CJrveDbSDZz3Kmo0afJtkcyAnZEPdFdyq8YgqfSqyJs6PJuemsj2ipai0gWO/3f8 60 EcApsll70fMRVXfOObBcO+hEO1tN0etNLlT5mlulpbMpkJ6hRgcHmVqogw1YJhmL 61 /E03f6Lw8aaCT9yDunE66bFZ/gwNky0V9PvCQni4GmGSKqcM2hFPux6FIWOOokBE 62 bicOgqIPCJodWamv++aE/6VKV6Th5gyYBJQ5Pjb6BRxpXtCVAVrev9ZIFcmYn6LX 63 wp6ggHtX2lGF 64 -----END CERTIFICATE----- 65 ` 66 67 const PARENT_SPKI_HASH = `3b0d73b4be4a854adc3e51d7ef9fa48aefbb2cdd824d67bdc7d7d09a2abc2d43` 68 69 func parseCertPEM(t *testing.T) (revoked *x509.Certificate) { 70 certPool := x509.NewCertPool() 71 ok := certPool.AppendCertsFromPEM([]byte(revoked_intermediate)) 72 if !ok { 73 t.Fail() 74 } 75 revoked = certPool.Certificates()[0] 76 return 77 } 78 79 func loadRevokedList(t *testing.T) (crlset *google.CRLSet) { 80 crlSetFile, err := os.Open(crlset_location) 81 if err != nil { 82 t.Error(err.Error()) 83 } 84 defer crlSetFile.Close() 85 86 crlSetBytes, err := ioutil.ReadAll(crlSetFile) 87 if err != nil { 88 t.Error(err.Error()) 89 } 90 91 crlset, err = google.Parse(crlSetBytes, VERSION) 92 if err != nil { 93 t.Error(err.Error()) 94 } 95 return 96 } 97 98 // Parses a static, stored version of an issued CRLSet - to prevent 99 // unexpected breakage with tests, use this instead of a live 100 // fetch when possible 101 func TestParse(t *testing.T) { 102 loadRevokedList(t) 103 } 104 105 func TestParse6375(t *testing.T) { 106 raw, err := ioutil.ReadFile("testdata/crl-set-6375") 107 if err != nil { 108 t.Error(err.Error()) 109 } 110 111 set, err := google.Parse(raw, "6375") 112 if err != nil { 113 t.Error(err.Error()) 114 } 115 if "6375" != set.Version { 116 t.Fail() 117 } 118 } 119 120 // just tests that there are no major complaints when live fetching, 121 // don't actually use this in case google removes our testing intermediate 122 // cert from the revocation list 123 func TestFetchRemote(t *testing.T) { 124 list, err := google.FetchAndParse() 125 if list == nil || err != nil { 126 t.Fail() 127 } 128 } 129 130 func TestCheck(t *testing.T) { 131 revoked := parseCertPEM(t) 132 crlset := loadRevokedList(t) 133 134 entry := crlset.Check(revoked, PARENT_SPKI_HASH) 135 if entry == nil { // this should provide an entry, since cert is revoked and in the provided sst file 136 t.Fail() 137 } 138 if entry.SerialNumber.Cmp(revoked.SerialNumber) != 0 { 139 t.Fail() 140 } 141 } 142 143 func TestFetch(t *testing.T) { 144 bytes, err := ioutil.ReadFile("testdata/APm1SaUzZaPllaSDuZS5yng") 145 require.NoError(t, err) 146 147 versionResponse := `xml version="1.0" encoding="UTF-8"?> 148 <gupdate xmlns="http://www.google.com/update2/response" protocol="2.0" server="prod"> 149 <daystart elapsed_days="5134" elapsed_seconds="36004"/> 150 <app appid="hfnkpimlhhgieaddgfemjhofmfblmnib" cohort="1:jcl:" cohortname="Auto" status="ok"> 151 <updatecheck codebase="http://dl.google.com/APm1SaUzZaPllaSDuZS5yng" 152 fp="1.dfee9fe7c749d1d15c6e8118bfe5281a0263474de2037516a525c3a885afe763" hash="LSXbDXGMp13JH5whBObmE4X7qCE=" hash_sha256="dfee9fe7c749d1d15c6e8118bfe5281a0263474de2037516a525c3a885afe763" size="24898" status="ok" version="6376"/> 153 </app> 154 </gupdate>` 155 156 h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 157 w.WriteHeader(http.StatusOK) 158 159 if r.RequestURI == "/APm1SaUzZaPllaSDuZS5yng" { 160 w.Write(bytes) 161 } else { 162 w.Write([]byte(versionResponse)) 163 } 164 }) 165 server := httptest.NewServer(h) 166 defer server.Close() 167 168 versionResponse = strings.Replace(versionResponse, 169 "http://dl.google.com/APm1SaUzZaPllaSDuZS5yng", 170 server.URL+"/APm1SaUzZaPllaSDuZS5yng", 1) 171 172 p := google.NewProvider(server.URL) 173 set, err := p.FetchAndParse() 174 require.NoError(t, err) 175 assert.Equal(t, 6376, set.Sequence) 176 }