]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: Add OCSP request helper function
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Tue, 20 Dec 2022 10:11:05 +0000 (11:11 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Wed, 21 Dec 2022 10:21:07 +0000 (11:21 +0100)
This function creates the url and body that will be used to build a
proper OCSP request for a given certid (following section A.1 of
RFC6960).

include/haproxy/ssl_sock.h
include/haproxy/tools.h
src/ssl_sock.c

index b71eb3a2f57d1cb6c569a7758e41f84d86012957..1c48c1474f429f04219f382d7535f78cacf584d2 100644 (file)
@@ -88,6 +88,8 @@ unsigned int ssl_sock_get_verify_result(struct connection *conn);
 #if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
 int ssl_sock_update_ocsp_response(struct buffer *ocsp_response, char **err);
 int ssl_ocsp_get_uri_from_cert(X509 *cert, struct buffer *out, char **err);
+int ssl_ocsp_create_request_details(const OCSP_CERTID *certid, struct buffer *req_url,
+                                    struct buffer *req_body, char **err);
 #endif
 #if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
 int ssl_sock_update_tlskey_ref(struct tls_keys_ref *ref,
index b2133b827c465efedfbf983b2158ceb474b9418f..fb9a019fd8e6aaa696878b63c8724816d9c7f916 100644 (file)
@@ -406,6 +406,7 @@ int addr_is_local(const struct netns_entry *ns,
  * The input string must also be zero-terminated.
  */
 extern const char hextab[];
+extern long query_encode_map[];
 char *encode_string(char *start, char *stop,
                    const char escape, const long *map,
                    const char *string);
index 69ae3e9db3560004a7e57eb5e40f9e1427a87dce..c9de25028122282f7db39ae5afae37a52199ed33 100644 (file)
@@ -1174,6 +1174,80 @@ end:
        return ret;
 }
 
+/*
+ * Create the url and request body that make a proper OCSP request for the
+ * <certid>. The <req_url> parameter should already hold the OCSP URI that was
+ * extracted from the corresponding certificate. Depending on the size of the
+ * certid we will either append data to the <req_url> to create a proper URL
+ * that will be sent with a GET command, or the <req_body> will be constructed
+ * in case of a POST.
+ * Returns 0 in case of success.
+ */
+int ssl_ocsp_create_request_details(const OCSP_CERTID *certid, struct buffer *req_url,
+                                    struct buffer *req_body, char **err)
+{
+       int errcode = -1;
+       OCSP_REQUEST *ocsp;
+       struct buffer *bin_request = get_trash_chunk();
+       unsigned char *outbuf = (unsigned char*)b_orig(bin_request);
+
+       ocsp = OCSP_REQUEST_new();
+       if (ocsp == NULL) {
+               memprintf(err, "%sCan't create OCSP_REQUEST\n", *err ? *err : "");
+               goto end;
+       }
+
+       if (OCSP_request_add0_id(ocsp, (OCSP_CERTID*)certid) == NULL) {
+               memprintf(err, "%sOCSP_request_add0_id() error\n", *err ? *err : "");
+               goto end;
+       }
+
+       bin_request->data = i2d_OCSP_REQUEST(ocsp, &outbuf);
+       if (b_data(bin_request) <= 0) {
+               memprintf(err, "%si2d_OCSP_REQUEST() error\n", *err ? *err : "");
+               goto end;
+       }
+
+       errcode = 0;
+
+       /* HTTP based OCSP requests can use either the GET or the POST method to
+        * submit their requests. To enable HTTP caching, small requests (that
+        * after encoding are less than 255 bytes), MAY be submitted using GET.
+        * If HTTP caching is not important, or the request is greater than 255
+        * bytes, the request SHOULD be submitted using POST.
+        */
+       if (b_data(bin_request)+b_data(req_url) < 0xff) {
+               struct buffer *b64buf = get_trash_chunk();
+               char *ret = NULL;
+               int base64_ret = 0;
+
+               chunk_strcat(req_url, "/");
+
+               base64_ret = a2base64(b_orig(bin_request), b_data(bin_request),
+                                     b_orig(b64buf), b_size(b64buf));
+
+               if (base64_ret < 0) {
+                       memprintf(err, "%sa2base64() error\n", *err ? *err : "");
+               }
+
+               b64buf->data = base64_ret;
+
+               ret = encode_chunk((char*)b_stop(req_url), b_orig(req_url)+b_size(req_url), '%',
+                                  query_encode_map, b64buf);
+               if (ret && *ret == '\0') {
+                       req_url->data = ret-b_orig(req_url);
+               }
+       }
+       else {
+               chunk_cpy(req_body, bin_request);
+       }
+
+end:
+       OCSP_REQUEST_free(ocsp);
+
+       return errcode;
+}
+
 #endif /* defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP */
 
 /*