Skip to content

Commit

Permalink
Support Get Method OCSP Request.
Browse files Browse the repository at this point in the history
  • Loading branch information
yuxki committed Oct 16, 2023
1 parent c56f93e commit 39bfbd3
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 11 deletions.
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ linters-settings:
desc: Should be replaced by standard lib errors package
funlen:
lines: 120
statements: 120

linters:
enable-all: true
Expand Down
33 changes: 29 additions & 4 deletions cache_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package dyocsp

import (
"crypto"
"encoding/base64"
"errors"
"fmt"
"io"
"net/http"
"path"
"reflect"
"time"

Expand All @@ -17,12 +20,22 @@ import (
"golang.org/x/crypto/ocsp"
)

func handleNotallowedMethod(h http.Handler) http.Handler {
const GETMethodMaxRequestSize = 255

func handleHTTPMethod(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
switch r.Method {
case http.MethodPost:
case http.MethodGet:
if r.ContentLength > int64(GETMethodMaxRequestSize) {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
default:
w.WriteHeader(http.StatusMethodNotAllowed)
return
}

h.ServeHTTP(w, r)
})
}
Expand Down Expand Up @@ -118,7 +131,7 @@ func NewCacheHandler(
handler.logger = &log.Logger
}

chain = chain.Append(handleNotallowedMethod)
chain = chain.Append(handleHTTPMethod)
chain = chain.Append(handleOverMaxRequestBytes(handler.maxRequestBytes))

return chain.Then(handler)
Expand Down Expand Up @@ -164,6 +177,8 @@ func addSuccessOCSPResHeader(w http.ResponseWriter, cache *cache.ResponseCache,
w.Header().Add("ETag", cache.SHA1HashHexString())
}

var ErrUnexpectedHTTPMethod = errors.New("unexpected HTTP method")

// ServeHTTP handles an OCSP request with following steps.
// - Verify that the request is in the correct form of an OCSP request.
// If the request is Malformed, it sends ocsp.MalformedRequestErrorResponse.
Expand All @@ -175,7 +190,17 @@ func addSuccessOCSPResHeader(w http.ResponseWriter, cache *cache.ResponseCache,
// This Handler add headers Headers introduced in RFC5019.
// (https://www.rfc-editor.org/rfc/rfc5019#section-5)
func (c CacheHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
var body []byte
var err error

switch r.Method {
case http.MethodGet:
body, err = base64.StdEncoding.DecodeString(path.Base(r.URL.Path))
case http.MethodPost:
body, err = io.ReadAll(r.Body)
default:
err = ErrUnexpectedHTTPMethod
}
if err != nil {
return
}
Expand Down
75 changes: 68 additions & 7 deletions cache_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package dyocsp

import (
"bytes"
"encoding/base64"
"io"
"math/big"
"net"
"net/http"
stduri "net/url"
"reflect"
"regexp"
"strconv"
Expand Down Expand Up @@ -107,6 +109,9 @@ func TestCacheHandler_ServeHTTP_Methods(t *testing.T) {
if method == http.MethodPost {
code = http.StatusOK
}
if method == http.MethodGet {
code = http.StatusOK
}
if res.StatusCode != code {
t.Errorf("Method %s Expected status code is %d but got: %d", method, code, res.StatusCode)
}
Expand Down Expand Up @@ -297,7 +302,42 @@ func testHTTPResContent(t *testing.T, responder *Responder, res *http.Response,
}
}

func testHandler(t *testing.T, port string, handler http.Handler, responder *Responder) *http.Response {
func testHandlerWithGETMethod(t *testing.T, port string, handler http.Handler, responder *Responder) *http.Response {
t.Helper()

s, url := testCreateServer(t, port, handler)

go func() {
err := s.ListenAndServe()
if err != nil {
log.Printf("Server listening error: %s", err.Error())
}
}()

testServerRunning(t, url)

var opts *ocsp.RequestOptions
rawReq, err := ocsp.CreateRequest(responder.rCert, responder.issuerCert, opts)
if err != nil {
t.Fatal(err)
}

base64Req := base64.StdEncoding.EncodeToString(rawReq)

url, err = stduri.JoinPath(url, base64Req)
if err != nil {
t.Fatal(err)
}

res, err := http.Get(url)
if err != nil {
t.Fatal(err)
}

return res
}

func testHandlerWithPOSTMethod(t *testing.T, port string, handler http.Handler, responder *Responder) *http.Response {
t.Helper()

s, url := testCreateServer(t, port, handler)
Expand Down Expand Up @@ -326,7 +366,28 @@ func testHandler(t *testing.T, port string, handler http.Handler, responder *Res
return res
}

func TestCacheHandler_ServeHTTP_ResponseSuccess(t *testing.T) {
func TestCacheHandler_ServeHTTP_GET_ResponseSuccess(t *testing.T) {
t.Parallel()

responder := testCreateDelegatedResponder(t)
resCache := testCreateDummyCache(t, responder, 500)
cacheStore := cache.NewResponseCacheStore()
cacheStore.Update([]cache.ResponseCache{resCache})

handler := NewCacheHandler(
cacheStore.NewReadOnlyCacheStore(), responder, alice.New(),
WithMaxRequestBytes(512), WithMaxAge(256),
)

res := testHandlerWithGETMethod(t, "8090", handler, responder)
defer res.Body.Close()

template := resCache.Template()
testHTTPResHeader(t, res.Header, &template)
testHTTPResContent(t, responder, res, resCache)
}

func TestCacheHandler_ServeHTTP_POST_ResponseSuccess(t *testing.T) {
t.Parallel()

responder := testCreateDelegatedResponder(t)
Expand All @@ -339,7 +400,7 @@ func TestCacheHandler_ServeHTTP_ResponseSuccess(t *testing.T) {
WithMaxRequestBytes(512), WithMaxAge(256),
)

res := testHandler(t, "8090", handler, responder)
res := testHandlerWithPOSTMethod(t, "8090", handler, responder)
defer res.Body.Close()

template := resCache.Template()
Expand All @@ -357,7 +418,7 @@ func TestCacheHandler_ServeHTTP_ResponseFailed_DiffIssuer(t *testing.T) {
WithMaxRequestBytes(512), WithMaxAge(256),
)

res := testHandler(t, "8085", handler, responder)
res := testHandlerWithPOSTMethod(t, "8085", handler, responder)
defer res.Body.Close()

ocspRes, err := io.ReadAll(res.Body)
Expand All @@ -380,7 +441,7 @@ func TestCacheHandler_ServeHTTP_ResponseFailed_SerialNotMatched(t *testing.T) {
WithMaxRequestBytes(512), WithMaxAge(256),
)

res := testHandler(t, "8086", handler, responder)
res := testHandlerWithPOSTMethod(t, "8086", handler, responder)
defer res.Body.Close()

ocspRes, err := io.ReadAll(res.Body)
Expand All @@ -407,7 +468,7 @@ func TestCacheHandler_ServeHTTP_NowIsOverNextUpdate(t *testing.T) {
WithMaxRequestBytes(512), WithMaxAge(256),
)

res := testHandler(t, "8087", handler, responder)
res := testHandlerWithPOSTMethod(t, "8087", handler, responder)
defer res.Body.Close()

ocspRes, err := io.ReadAll(res.Body)
Expand Down Expand Up @@ -436,7 +497,7 @@ func TestCacheHandler_ServeHTTP_MaxAgeOverNextUpdate(t *testing.T) {
WithMaxRequestBytes(512), WithMaxAge(256),
)

res := testHandler(t, "8088", handler, responder)
res := testHandlerWithPOSTMethod(t, "8088", handler, responder)
defer res.Body.Close()

cc := res.Header.Get("Cache-Control")
Expand Down

0 comments on commit 39bfbd3

Please sign in to comment.