diff options
author | William Lallemand <wlallemand@haproxy.org> | 2021-08-21 23:16:06 +0200 |
---|---|---|
committer | William Lallemand <wlallemand@haproxy.org> | 2021-08-21 23:44:02 +0200 |
commit | 44d862d8d403ebb41dd20246ab7ba7df0285a73d (patch) | |
tree | da9fd4619bb1ce18cc9a5fcffdfa82c280fa78ac | |
parent | fff1e583aa86551f88b95bbe7ca9960304d1632d (diff) | |
download | haproxy-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.h | 2 | ||||
-rw-r--r-- | src/ssl_utils.c | 84 |
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; + +} |