Server-side OCSP stapling support.

This is a simpler implementation than OpenSSL's, lacking responder IDs
and request extensions support. This mirrors the client implementation
already present.

Change-Id: I54592b60e0a708bfb003d491c9250401403c9e69
Reviewed-on: https://boringssl-review.googlesource.com/5700
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/tool/server.cc b/tool/server.cc
index 164d6a5..69994bc 100644
--- a/tool/server.cc
+++ b/tool/server.cc
@@ -35,10 +35,52 @@
       "Private-key file to use (default is server.pem)",
     },
     {
+      "-ocsp-response", kOptionalArgument,
+      "OCSP response file to send",
+    },
+    {
      "", kOptionalArgument, "",
     },
 };
 
+static bool LoadOCSPResponse(SSL_CTX *ctx, const char *filename) {
+  void *data = NULL;
+  bool ret = false;
+  long length;
+
+  FILE *f = fopen(filename, "rb");
+
+  if (f == NULL ||
+      fseek(f, 0, SEEK_END) != 0) {
+    goto out;
+  }
+
+  length = ftell(f);
+  if (length < 0) {
+    goto out;
+  }
+
+  data = malloc(length);
+  if (data == NULL) {
+    goto out;
+  }
+  rewind(f);
+
+  fread(data, 1, length, f);
+  if (ferror(f) != 0 ||
+      !SSL_CTX_set_ocsp_response(ctx, (uint8_t*)data, length)) {
+    goto out;
+  }
+
+  ret = true;
+out:
+  if (f != NULL) {
+      fclose(f);
+  }
+  free(data);
+  return ret;
+}
+
 bool Server(const std::vector<std::string> &args) {
   if (!InitSocketLibrary()) {
     return false;
@@ -74,6 +116,12 @@
     return false;
   }
 
+  if (args_map.count("-ocsp-response") != 0 &&
+      !LoadOCSPResponse(ctx, args_map["-ocsp-response"].c_str())) {
+    fprintf(stderr, "Failed to load OCSP response: %s\n", args_map["-ocsp-response"].c_str());
+    return false;
+  }
+
   int sock = -1;
   if (!Accept(&sock, args_map["-accept"])) {
     return false;