in capi/capi.go [76:196]
func verify(resp http.ResponseWriter, req *http.Request) {
var response string
var responseCode = http.StatusOK
defer func() {
if err := recover(); err != nil {
responseCode = http.StatusBadGateway
response = fmt.Sprintf("a fatal error has occured\n%s", err)
}
switch responseCode {
case http.StatusBadGateway:
log.Fatal(string(response))
case http.StatusBadRequest:
log.Error(responseCode)
}
resp.WriteHeader(responseCode)
_, err := fmt.Fprintln(resp, string(response))
if err != nil {
// Oh my, perhaps the client hung up.
log.WithField("response", string(response)).
WithError(err).
Fatal("failed to respond to the remote client")
// This may or may not prove to be useful.
// Leave it on debug because this can be incredibly noisy.
dump, err := httputil.DumpRequest(req, false)
switch err == nil {
case true:
log.WithField("wireRepresentation", dump).Debug()
default:
log.WithError(err).Fatal()
}
}
}()
dump, err := httputil.DumpRequest(req, false)
if err != nil {
responseCode = http.StatusBadGateway
response = "a fatal internal error occurred, " + err.Error()
return
}
log.WithField("Request", string(dump)).Info("Received request")
log.Info(req.URL.RawQuery)
query, err := url.ParseQuery(req.URL.RawQuery)
log.Info(req.ParseForm())
if err != nil {
responseCode = http.StatusBadRequest
response = "malformed query string, " + err.Error()
return
}
s, ok := query["subject"]
if !ok {
responseCode = http.StatusBadRequest
response = "'subject' query parameter is required"
return
}
if len(s) == 0 {
responseCode = http.StatusBadRequest
response = "'subject' query parameter may not be empty"
return
}
subject := s[0]
rawRoot, err := ioutil.ReadAll(req.Body)
if err != nil {
responseCode = http.StatusBadRequest
response = "failed to read request body, " + err.Error()
return
}
e, ok := query["expect"]
interpretation := service.None
log.Info(e)
if ok {
if len(e) == 0 {
responseCode = http.StatusBadRequest
response = "'expect' query parameter may not be empty"
return
}
switch strings.ToLower(e[0]) {
case "valid":
interpretation = service.Valid
case "expired":
interpretation = service.Expired
case "revoked":
interpretation = service.Revoked
}
}
log.Info("Expectation is " + strconv.Itoa(int(interpretation)))
if err := req.Body.Close(); err != nil {
responseCode = http.StatusBadGateway
response = "failed to close the request body, " + err.Error()
return
}
if len(rawRoot) == 0 {
responseCode = http.StatusBadRequest
response = "The PEM of the provided trust anchor cannot be empty."
}
rootPEM, err := certificateUtils.NormalizePEM(rawRoot)
if err != nil {
responseCode = http.StatusBadRequest
response = "failed to format the provided PEM"
return
}
log.Info(string(rootPEM))
block, _ := pem.Decode(rootPEM)
if block == nil {
responseCode = http.StatusBadRequest
response = "failed to decode the provided PEM"
return
}
root, err := x509.ParseCertificate(block.Bytes)
if err != nil {
responseCode = http.StatusBadRequest
response = "Bad root PEM, " + err.Error()
return
}
result := test(subject, root, interpretation)
switch r, err := json.MarshalIndent(result, "", " "); err != nil {
case true:
responseCode = http.StatusBadGateway
response = "a fatal error occurred when serializing the response, " + err.Error()
case false:
response = string(r)
}
}