Skip to content

Commit

Permalink
Compatiility with LibreSSL
Browse files Browse the repository at this point in the history
limitations as of LibreSSL version 3.4.2:

uacme: --must-staple doesn't work. This is because LibreSSL does not
support NID_tlsfeature and therefore it can't add the necessary
extension to the certificate request.

ualpn: doesn't work at all and probably never will. This is because
the TLS implementation of LibreSSL is completely different.
  • Loading branch information
ndilieto committed Jan 12, 2022
1 parent 8d2356b commit 32546c7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 10 deletions.
15 changes: 14 additions & 1 deletion configure.ac
Expand Up @@ -278,6 +278,12 @@ if test "x$OPT_OPENSSL" != "xno"; then
AC_SUBST(USE_OPENSSL, [1])
USE_OPENSSL="yes"],
[AC_MSG_ERROR([openssl check failed])])
AC_MSG_CHECKING([if OpenSSL is really LibreSSL])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([#include <openssl/crypto.h>
int main() {return LIBRESSL_VERSION_NUMBER;}])],
LIBRESSL=yes
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
fi
fi
AM_CONDITIONAL(ENABLE_READFILE, test "x$USE_OPENSSL" != "xyes")
Expand Down Expand Up @@ -305,12 +311,19 @@ if test "x$OPT_MBEDTLS" != "xno"; then
fi
fi

OPT_UALPN=yes
if test "x$LIBRESSL" = "xyes"; then
OPT_UALPN=no
else
OPT_UALPN=yes
fi
AC_ARG_WITH(ualpn,
[AS_HELP_STRING([--with-ualpn], [enable ualpn])
AS_HELP_STRING([--without-ualpn], [disable ualpn])], OPT_UALPN=$withval)

if test "x$OPT_UALPN" != "xno"; then
if test "x$LIBRESSL" = "xyes"; then
AC_MSG_ERROR([ualpn is not compatible with LibreSSL])
fi
AM_PROG_AR
AC_CHECK_HEADERS([netinet/tcp.h], [],
AC_MSG_ERROR([ualpn requires netinet/tcp.h]))
Expand Down
45 changes: 36 additions & 9 deletions crypto.c
Expand Up @@ -32,6 +32,7 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "base64.h"
Expand Down Expand Up @@ -544,18 +545,21 @@ static bool rsa_params(privkey_t key, char **m, char **e)
}
#elif defined(USE_OPENSSL)
unsigned char *data = NULL;
const BIGNUM *bm = NULL;
const BIGNUM *be = NULL;
RSA *rsa = EVP_PKEY_get0_RSA(key);
if (!rsa) {
openssl_error("rsa_params");
goto out;
}
r = BN_num_bytes(RSA_get0_n(rsa));
RSA_get0_key(rsa, &bm, &be, NULL);
r = BN_num_bytes(bm);
data = calloc(1, r);
if (!data) {
warn("rsa_params: calloc failed");
goto out;
}
if (BN_bn2bin(RSA_get0_n(rsa), data) != r) {
if (BN_bn2bin(bm, data) != r) {
openssl_error("rsa_params");
goto out;
}
Expand All @@ -565,13 +569,13 @@ static bool rsa_params(privkey_t key, char **m, char **e)
goto out;
}
free(data);
r = BN_num_bytes(RSA_get0_e(rsa));
r = BN_num_bytes(be);
data = calloc(1, r);
if (!data) {
warn("rsa_params: calloc failed");
goto out;
}
if (BN_bn2bin(RSA_get0_e(rsa), data) != r) {
if (BN_bn2bin(be, data) != r) {
openssl_error("rsa_params");
goto out;
}
Expand Down Expand Up @@ -1230,26 +1234,29 @@ bool ec_decode(size_t hash_size, unsigned char **sig, size_t *sig_size)
#endif
#elif defined(USE_OPENSSL)
const unsigned char *p = *sig;
const BIGNUM *br = NULL;
const BIGNUM *bs = NULL;
ECDSA_SIG *s = d2i_ECDSA_SIG(NULL, &p, *sig_size);
if (!s) {
openssl_error("ec_decode");
return false;
}
ECDSA_SIG_get0(s, &br, &bs);
unsigned char *tmp = calloc(1, 2*hash_size);
if (!tmp) {
warn("ec_decode: calloc failed");
ECDSA_SIG_free(s);
return false;
}
r = BN_num_bytes(ECDSA_SIG_get0_r(s));
r = BN_num_bytes(br);
unsigned char *data = calloc(1, r);
if (!data) {
warn("ec_decode: calloc failed");
ECDSA_SIG_free(s);
free(tmp);
return false;
}
if (BN_bn2bin(ECDSA_SIG_get0_r(s), data) != r) {
if (BN_bn2bin(br, data) != r) {
openssl_error("ec_decode");
ECDSA_SIG_free(s);
free(data);
Expand All @@ -1262,15 +1269,15 @@ bool ec_decode(size_t hash_size, unsigned char **sig, size_t *sig_size)
memcpy(tmp + hash_size - r, data, r);
free(data);

r = BN_num_bytes(ECDSA_SIG_get0_s(s));
r = BN_num_bytes(bs);
data = calloc(1, r);
if (!data) {
warn("ec_decode: calloc failed");
ECDSA_SIG_free(s);
free(tmp);
return false;
}
if (BN_bn2bin(ECDSA_SIG_get0_s(s), data) != r) {
if (BN_bn2bin(bs, data) != r) {
openssl_error("ec_decode");
ECDSA_SIG_free(s);
free(data);
Expand Down Expand Up @@ -2283,6 +2290,11 @@ char *csr_gen(char * const *names, bool status_req, privkey_t key)
}
sk_X509_EXTENSION_push(exts, ext);
if (status_req) {
#if defined(LIBRESSL_VERSION_NUMBER)
warnx("csr_gen: -m, --must-staple is not supported by LibreSSL "
"- consider recompiling with OpenSSL");
goto out;
#endif
ext = X509V3_EXT_conf_nid(NULL, NULL, NID_tlsfeature,
"status_request");
if (!ext) {
Expand Down Expand Up @@ -4254,9 +4266,24 @@ bool cert_valid(const char *certfile, char * const *names, int validity,
int ncrt = cert_load(crt, 2, "%s", certfile);
if (ncrt <= 0)
goto out;
int days_left, sec;
int days_left;
const ASN1_TIME *tm = X509_get0_notAfter(crt[0]);
#if defined(LIBRESSL_VERSION_NUMBER)
struct tm tcrt;
if (tm && ASN1_time_parse((const char *)tm->data, tm->length, &tcrt,
tm->type) != -1) {
time_t now = time(NULL);
struct tm *tnow = gmtime(&now);
if (!tnow) {
warnx("cert_valid: gmtime overflow");
goto out;
}
days_left = difftime(mktime(&tcrt), mktime(tnow))/(3600*24);
} else {
#else
int sec;
if (!tm || !ASN1_TIME_diff(&days_left, &sec, NULL, tm)) {
#endif
warnx("cert_valid: invalid expiration time format in %s", certfile);
goto out;
}
Expand Down

2 comments on commit 32546c7

@vaygr
Copy link

@vaygr vaygr commented on 32546c7 Jul 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ndilieto this still fails with:

crypto.c:2353:47: error: ‘NID_tlsfeature’ undeclared (first use in this function)
crypto.c:2353:47: note: each undeclared identifier is reported only once for each function it appears in

missing #else pragma?

@ndilieto
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 63a70a9

Please sign in to comment.