#endif
};
+/*
+ * In OpenSSL 3.0.0, the biggest verify error code's value is 94 and on the
+ * latest 1.1.1 it already reaches 79 so we need to size the ca/crt-ignore-err
+ * arrays accordingly. If the max error code increases, the arrays might need to
+ * be resized.
+ */
+#define SSL_MAX_VFY_ERROR_CODE 94
+#define IGNERR_BF_SIZE ((SSL_MAX_VFY_ERROR_CODE >> 6) + 1)
+
/* "bind" line settings */
struct bind_conf {
#ifdef USE_OPENSSL
struct ssl_bind_conf ssl_conf; /* ssl conf for ctx setting */
- unsigned long long ca_ignerr; /* ignored verify errors in handshake if depth > 0 */
- unsigned long long crt_ignerr; /* ignored verify errors in handshake if depth == 0 */
+ unsigned long long ca_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth > 0 */
+ unsigned long long crt_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth == 0 */
void *initial_ctx; /* SSL context for initial negotiation */
void *default_ctx; /* SSL context of first/default certificate */
struct ckch_inst *default_inst;
#define SSL_SOCK_SEND_UNLIMITED 0x00000004
#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
-/* bits 0xFFFF0000 are reserved to store verify errors */
+/* bits 0xFFFFFF00 are reserved to store verify errors.
+ * The CA en CRT error codes will be stored on 7 bits each
+ * (since the max verify error code does not exceed 127)
+ * and the CA error depth will be stored on 4 bits.
+ */
/* Verify errors macros */
-#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
-#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
-#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
+#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 127) ? 127 : e) << (8))
+#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (7+8))
+#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 127) ? 127 : e) << (4+7+8))
-#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
-#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
-#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
+#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (8)) & 127)
+#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (7+8)) & 15)
+#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+7+8)) & 127)
/* ssl_methods flags for ssl options */
#define MC_SSL_O_ALL 0x0000
SSL *ssl_sock_get_ssl_object(struct connection *conn);
+static inline int cert_ignerr_bitfield_get(const unsigned long long *bitfield, int bit_index)
+{
+ int byte_index = bit_index >> 6;
+ int val = 0;
+
+ if (byte_index < IGNERR_BF_SIZE)
+ val = bitfield[byte_index] & (1 << (bit_index & 0x3F));
+
+ return val != 0;
+}
+
+static inline void cert_ignerr_bitfield_set(unsigned long long *bitfield, int bit_index)
+{
+ int byte_index = bit_index >> 6;
+
+ if (byte_index < IGNERR_BF_SIZE)
+ bitfield[byte_index] |= (1 << (bit_index & 0x3F));
+}
+
+static inline void cert_ignerr_bitfield_set_all(unsigned long long *bitfield)
+{
+ memset(bitfield, -1, IGNERR_BF_SIZE*sizeof(*bitfield));
+}
#endif /* USE_OPENSSL */
#endif /* _HAPROXY_SSL_SOCK_H */
{
int code;
char *p = args[cur_arg + 1];
- unsigned long long *ignerr = &conf->crt_ignerr;
+ unsigned long long *ignerr = conf->crt_ignerr_bitfield;
if (!*p) {
memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
}
if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
- ignerr = &conf->ca_ignerr;
+ ignerr = conf->ca_ignerr_bitfield;
if (strcmp(p, "all") == 0) {
- *ignerr = ~0ULL;
+ cert_ignerr_bitfield_set_all(ignerr);
return 0;
}
while (p) {
code = atoi(p);
- if ((code <= 0) || (code > 63)) {
- memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
- args[cur_arg], code, args[cur_arg + 1]);
+ if ((code <= 0) || (code > SSL_MAX_VFY_ERROR_CODE)) {
+ memprintf(err, "'%s' : ID '%d' out of range (1..%d) in error IDs list '%s'",
+ args[cur_arg], code, SSL_MAX_VFY_ERROR_CODE, args[cur_arg + 1]);
return ERR_ALERT | ERR_FATAL;
}
- *ignerr |= 1ULL << code;
+ cert_ignerr_bitfield_set(ignerr, code);
p = strchr(p, ',');
if (p)
p++;
ctx->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
}
- if (err < 64 && bind_conf->ca_ignerr & (1ULL << err))
+ if (err <= SSL_MAX_VFY_ERROR_CODE &&
+ cert_ignerr_bitfield_get(__objt_listener(conn->target)->bind_conf->ca_ignerr_bitfield, err))
goto err_ignored;
/* TODO: for QUIC connection, this error code is lost */
ctx->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
/* check if certificate error needs to be ignored */
- if (err < 64 && bind_conf->crt_ignerr & (1ULL << err))
+ if (err <= SSL_MAX_VFY_ERROR_CODE &&
+ cert_ignerr_bitfield_get(__objt_listener(conn->target)->bind_conf->crt_ignerr_bitfield, err))
goto err_ignored;
/* TODO: for QUIC connection, this error code is lost */