diff --git a/cmd/ocsp-updater/main.go b/cmd/ocsp-updater/main.go index 5a70ad570..1f62bdad1 100644 --- a/cmd/ocsp-updater/main.go +++ b/cmd/ocsp-updater/main.go @@ -1,6 +1,7 @@ package main import ( + "crypto/md5" "crypto/sha256" "crypto/tls" "crypto/x509" @@ -199,6 +200,21 @@ func newUpdater( return &updater, nil } +func reverseBytes(b []byte) []byte { + for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 { + b[i], b[j] = b[j], b[i] + } + return b +} + +func generatePOSTURL(der []byte, ocspServer string) string { + // Generate POST url, format is the URL that was POST'd to with a query string with + // the parameter 'body-mdy' and the value of the first two uint32s in little endian + // order in hex of the MD5 hash of the OCSP request body. + hash := md5.Sum(der) + return fmt.Sprintf("%s?body-mdy=%x%x", ocspServer, reverseBytes(hash[0:4]), reverseBytes(hash[4:8])) +} + // sendPurge should only be called as a Goroutine as it will block until the purge // request is successful func (updater *OCSPUpdater) sendPurge(der []byte) { @@ -214,18 +230,18 @@ func (updater *OCSPUpdater) sendPurge(der []byte) { return } - // Create a GET style OCSP url for each endpoint in cert.OCSPServer (still waiting - // on word from Akamai on how to properly purge cached POST requests, for now just - // do GET) + // Create a GET and special Akamai POST style OCSP url for each endpoint in cert.OCSPServer urls := []string{} for _, ocspServer := range cert.OCSPServer { if !strings.HasSuffix(ocspServer, "/") { ocspServer += "/" } + // Generate GET url urls = append( urls, fmt.Sprintf("%s%s", ocspServer, url.QueryEscape(base64.StdEncoding.EncodeToString(req))), ) + urls = append(urls, generatePOSTURL(der, ocspServer)) } err = updater.ccu.Purge(urls) diff --git a/cmd/ocsp-updater/main_test.go b/cmd/ocsp-updater/main_test.go index c251a38ad..798586ab6 100644 --- a/cmd/ocsp-updater/main_test.go +++ b/cmd/ocsp-updater/main_test.go @@ -851,3 +851,17 @@ func TestMissingLogs(t *testing.T) { } } } + +func TestReverseBytes(t *testing.T) { + a := []byte{0, 1, 2, 3} + test.AssertDeepEquals(t, reverseBytes(a), []byte{3, 2, 1, 0}) +} + +func TestGeneratePOSTURL(t *testing.T) { + der := []byte{0} + test.AssertEquals( + t, + generatePOSTURL(der, "ocsp.invalid/"), + "ocsp.invalid/?body-mdy=ad85b89389a00dfe", + ) +}