summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Lallemand <wlallemand@haproxy.org>2021-08-21 23:16:06 +0200
committerWilliam Lallemand <wlallemand@haproxy.org>2021-08-21 23:44:02 +0200
commit44d862d8d403ebb41dd20246ab7ba7df0285a73d (patch)
treeda9fd4619bb1ce18cc9a5fcffdfa82c280fa78ac
parentfff1e583aa86551f88b95bbe7ca9960304d1632d (diff)
downloadhaproxy-44d862d8d403ebb41dd20246ab7ba7df0285a73d.tar.gz
MINOR: ssl: add an openssl version string parser
openssl_version_parser() parse a string in the OpenSSL version format which is documented here: https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_VERSION_NUMBER.html The function returns an unsigned int that could be used for comparing openssl versions.
-rw-r--r--include/haproxy/ssl_utils.h2
-rw-r--r--src/ssl_utils.c84
2 files changed, 85 insertions, 1 deletions
diff --git a/include/haproxy/ssl_utils.h b/include/haproxy/ssl_utils.h
index 28c5a8472..9851e8a36 100644
--- a/include/haproxy/ssl_utils.h
+++ b/include/haproxy/ssl_utils.h
@@ -38,8 +38,8 @@ int ssl_sock_get_dn_entry(X509_NAME *a, const struct buffer *entry, int pos,
struct buffer *out);
int ssl_sock_get_dn_formatted(X509_NAME *a, const struct buffer *format, struct buffer *out);
int ssl_sock_get_dn_oneline(X509_NAME *a, struct buffer *out);
-
X509* ssl_sock_get_peer_certificate(SSL *ssl);
+unsigned int openssl_version_parser(const char *version);
#endif /* _HAPROXY_SSL_UTILS_H */
#endif /* USE_OPENSSL */
diff --git a/src/ssl_utils.c b/src/ssl_utils.c
index ce17e9553..20dcdb90c 100644
--- a/src/ssl_utils.c
+++ b/src/ssl_utils.c
@@ -315,3 +315,87 @@ X509* ssl_sock_get_peer_certificate(SSL *ssl)
return cert;
}
+
+/*
+ * Take an OpenSSL version in text format and return a numeric openssl version
+ * Return 0 if it failed to parse the version
+ *
+ * https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_VERSION_NUMBER.html
+ *
+ * MNNFFPPS: major minor fix patch status
+ *
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.
+ *
+ * for example
+ *
+ * 0x0090821f 0.9.8zh
+ * 0x1000215f 1.0.2u
+ * 0x30000000 3.0.0-alpha17
+ * 0x30000002 3.0.0-beta2
+ * 0x3000000e 3.0.0-beta14
+ * 0x3000000f 3.0.0
+ */
+unsigned int openssl_version_parser(const char *version)
+{
+ unsigned int numversion;
+ unsigned int major = 0, minor = 0, fix = 0, patch = 0, status = 0;
+ char *p, *end;
+
+ p = (char *)version;
+
+ if (!p || !*p)
+ return 0;
+
+ major = strtol(p, &end, 10);
+ if (*end != '.' || major > 0xf)
+ goto error;
+ p = end + 1;
+
+ minor = strtol(p, &end, 10);
+ if (*end != '.' || minor > 0xff)
+ goto error;
+ p = end + 1;
+
+ fix = strtol(p, &end, 10);
+ if (fix > 0xff)
+ goto error;
+ p = end;
+
+ if (!*p) {
+ /* end of the string, that's a release */
+ status = 0xf;
+ } else if (*p == '-') {
+ /* after the hyphen, only the beta will increment the status
+ * counter, all others versions will be considered as "dev" and
+ * does not increment anything */
+ p++;
+
+ if (!strncmp(p, "beta", 4)) {
+ p += 4;
+ if (p) {
+ status = strtol(p, &end, 10);
+ if (status > 14)
+ goto error;
+ }
+ }
+ } else {
+ /* that's a patch release */
+ patch = 1;
+
+ /* add the value of each letter */
+ while (*p) {
+ patch += (*p & ~0x20) - 'A';
+ p++;
+ }
+ status = 0xf;
+ }
+
+end:
+ numversion = ((major & 0xf) << 28) | ((minor & 0xff) << 20) | ((fix & 0xff) << 12) | ((patch & 0xff) << 4) | (status & 0xf);
+ return numversion;
+
+error:
+ return 0;
+
+}