Skip to content

Commit 4d012a6

Browse files
committed
stir_shaken: Migrate to WolfSSL-compatible cryptography
While stir_shaken only uses the "libcrypto" part of OpenSSL, the fact that the OpenSSL runtime can be shared across multiple modules (e.g. with proto_wss doing TLS connections) may induce unexpected crashes in the stir_shaken crypto workflows. This commit makes stir_shaken compatible with WolfSSL too, to become the new default crypto library, but *without* losing OpenSSL compatibility. To revert to OpenSSL based crypto, add this to Makefile.conf: DEFS+= -DSTIR_SHAKEN_OPENSSL
1 parent b1482d8 commit 4d012a6

4 files changed

Lines changed: 111 additions & 35 deletions

File tree

modules/stir_shaken/Makefile

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,31 @@
33

44
include ../../Makefile.defs
55

6+
auto_gen=
7+
NAME=stir_shaken.so
8+
9+
ifneq ($(STIR_SHAKEN_OPENSSL),)
610
USE_ONLY_CRYPTO=true
711
include ../../Makefile.openssl
12+
else
13+
# Prefer system wolfSSL. If unavailable, fallback to the local tls_wolfssl
14+
# include/lib paths under LOCALBASE.
15+
ifeq ($(CROSS_COMPILE),)
16+
SS_WOLFSSL_BUILDER := $(shell \
17+
if pkg-config --exists wolfssl; then \
18+
echo 'pkg-config wolfssl'; \
19+
fi)
20+
endif
821

9-
auto_gen=
10-
NAME=stir_shaken.so
22+
ifneq ($(SS_WOLFSSL_BUILDER),)
23+
DEFS += $(shell $(SS_WOLFSSL_BUILDER) --cflags) -DOPENSSL_EXTRA
24+
LIBS += $(shell $(SS_WOLFSSL_BUILDER) --libs) -lm
25+
else
26+
DEFS += -I$(LOCALBASE)/include -I$(LOCALBASE)/ssl/include -DOPENSSL_EXTRA
27+
LIBS += -L$(LOCALBASE)/lib -L$(LOCALBASE)/ssl/lib \
28+
-L$(LOCALBASE)/lib64 -L$(LOCALBASE)/ssl/lib64 \
29+
-lwolfssl -lm
30+
endif
31+
endif
1132

1233
include ../../Makefile.modules

modules/stir_shaken/README

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Chapter 1. Admin Guide
9797

9898
The following libraries or applications must be installed
9999
before running OpenSIPS with this module loaded:
100-
* openssl (libssl).
100+
* wolfssl (libwolfssl).
101101

102102
1.3. Exported Parameters
103103

modules/stir_shaken/doc/stir_shaken_admin.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<itemizedlist>
3333
<listitem>
3434
<para>
35-
<emphasis>openssl (libssl)</emphasis>.
35+
<emphasis>wolfssl (libwolfssl)</emphasis>.
3636
</para>
3737
</listitem>
3838
</itemizedlist>

modules/stir_shaken/stir_shaken.c

Lines changed: 86 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,26 @@
3737
#define _GNU_SOURCE
3838
#include <time.h>
3939

40+
#ifdef STIR_SHAKEN_OPENSSL
4041
#include <openssl/x509.h>
42+
#else
43+
#include <wolfssl/options.h>
44+
#include <wolfssl/openssl/x509.h>
45+
#endif
46+
4147

4248
#undef _GNU_SOURCE
4349

50+
#ifdef STIR_SHAKEN_OPENSSL
4451
#include <openssl/x509v3.h>
4552
#include <openssl/pem.h>
4653
#include <openssl/err.h>
54+
#else
55+
#include <wolfssl/openssl/x509v3.h>
56+
#include <wolfssl/openssl/pem.h>
57+
#include <wolfssl/openssl/err.h>
58+
#endif
59+
4760
#include <stdlib.h>
4861

4962
#include "../../dprint.h"
@@ -141,7 +154,7 @@ static int e164_max_length = 15;
141154

142155
static int require_date_hdr = 1;
143156

144-
static int tn_authlist_nid;
157+
static ASN1_OBJECT *tn_authlist_obj;
145158

146159
static int parsed_ctx_idx =-1;
147160

@@ -254,6 +267,15 @@ static int verify_callback(int ok, X509_STORE_CTX *ctx)
254267
return ok;
255268
}
256269

270+
static int ss_store_set_default_paths(X509_STORE *x509_store)
271+
{
272+
#ifdef WOLFSSL_VERSION
273+
return wolfSSL_X509_STORE_set_default_paths(x509_store);
274+
#else
275+
return X509_STORE_set_default_paths(x509_store);
276+
#endif
277+
}
278+
257279
// called during mod_init
258280
static int init_cert_validation(void)
259281
{
@@ -269,7 +291,7 @@ static int init_cert_validation(void)
269291
LM_ERR("Failed to load trusted CAs\n");
270292
return -1;
271293
}
272-
if (X509_STORE_set_default_paths(store) != 1) {
294+
if (ss_store_set_default_paths(store) != 1) {
273295
LM_ERR("Failed to load the system-wide CA certificates\n");
274296
return -1;
275297
}
@@ -321,7 +343,7 @@ static int init_cert_ca_reload(void)
321343
LM_ERR("Failed to load trusted CAs\n");
322344
return -4;
323345
}
324-
if (X509_STORE_set_default_paths(store) != 1) {
346+
if (ss_store_set_default_paths(store) != 1) {
325347
LM_ERR("Failed to load the system-wide CA certificates\n");
326348
return -5;
327349
}
@@ -381,10 +403,9 @@ static void parsed_ctx_free(void *param)
381403

382404
static int mod_init(void)
383405
{
384-
tn_authlist_nid = OBJ_create(TN_AUTH_LIST_OID,
385-
TN_AUTH_LIST_SN, TN_AUTH_LIST_LN);
386-
if (tn_authlist_nid == NID_undef) {
387-
LM_ERR("Failed to create new openssl object\n");
406+
tn_authlist_obj = OBJ_txt2obj(TN_AUTH_LIST_OID, 1);
407+
if (!tn_authlist_obj) {
408+
LM_ERR("Failed to create TNAuthList object identifier\n");
388409
return -1;
389410
}
390411

@@ -397,6 +418,9 @@ static int mod_init(void)
397418
}
398419

399420
static void mod_destroy(void) {
421+
if (tn_authlist_obj)
422+
ASN1_OBJECT_free(tn_authlist_obj);
423+
400424
#if OPENSSL_VERSION_NUMBER < 0x10100000L
401425
OBJ_cleanup();
402426
#endif
@@ -574,8 +598,8 @@ static int add_disengagement_token(struct sip_msg *msg, str *token)
574598

575599
static int check_cert_validity(time_t *timestamp, X509 *cert)
576600
{
577-
ASN1_STRING *notBeforeSt;
578-
ASN1_STRING *notAfterSt;
601+
const ASN1_TIME *notBeforeSt;
602+
const ASN1_TIME *notAfterSt;
579603

580604
notBeforeSt = X509_get_notBefore(cert);
581605
notAfterSt = X509_get_notAfter(cert);
@@ -591,6 +615,24 @@ static int check_cert_validity(time_t *timestamp, X509 *cert)
591615
return 0;
592616
}
593617

618+
static int ss_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
619+
{
620+
int bnlen, padlen;
621+
622+
bnlen = BN_num_bytes(a);
623+
624+
if (tolen < bnlen)
625+
return -1;
626+
627+
padlen = tolen - bnlen;
628+
memset(to, 0, padlen);
629+
630+
if (BN_bn2bin(a, to + padlen) == 0)
631+
return -1;
632+
633+
return tolen;
634+
}
635+
594636
static char *build_pport_hdr_json(str *cr_url)
595637
{
596638
char *json_str;
@@ -865,26 +907,7 @@ static int get_dest_tn_from_msg(struct sip_msg *msg, str *dest_tn)
865907
return 0;
866908
}
867909

868-
/* compatibility function for openssl versions lower than 1.1.0 */
869910
#if OPENSSL_VERSION_NUMBER < 0x10100000L
870-
int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
871-
{
872-
int bnlen, padlen;
873-
874-
bnlen = BN_num_bytes(a);
875-
876-
if (tolen < bnlen)
877-
return -1;
878-
879-
padlen = tolen - bnlen;
880-
memset(to, 0, padlen);
881-
882-
if (BN_bn2bin(a, to + padlen) == 0)
883-
return -1;
884-
885-
return tolen;
886-
}
887-
888911
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
889912
{
890913
*pr = sig->r;
@@ -958,12 +981,12 @@ static str *build_identity_hf(EVP_PKEY *pkey,
958981
der_sig_buf.s = NULL;
959982

960983
ECDSA_SIG_get0(sig, &r, &s);
961-
len = BN_bn2binpad(r, raw_sig_buf, R_S_INT_LEN);
984+
len = ss_bn2binpad(r, raw_sig_buf, R_S_INT_LEN);
962985
if (len < 0 || len != R_S_INT_LEN) {
963986
LM_ERR("Failed to convert R integer into binay represantation\n");
964987
goto error;
965988
}
966-
len = BN_bn2binpad(s, raw_sig_buf + R_S_INT_LEN,
989+
len = ss_bn2binpad(s, raw_sig_buf + R_S_INT_LEN,
967990
R_S_INT_LEN);
968991
if (len < 0 || len != R_S_INT_LEN) {
969992
LM_ERR("Failed to convert S integer into binay represantation\n");
@@ -1692,10 +1715,42 @@ static int check_passport_claims(struct parsed_identity *parsed)
16921715
static int validate_certificate(X509 *cert, STACK_OF(X509) *certchain)
16931716
{
16941717
X509_STORE_CTX *verify_ctx;
1718+
X509_EXTENSION *ext;
1719+
ASN1_OBJECT *ext_obj;
1720+
char ext_oid[128];
1721+
int ext_count, i, has_tn_authlist = 0;
16951722
int rc;
16961723

16971724
/* check the TN Authorization list extension */
1698-
if (X509_get_ext_by_NID(cert, tn_authlist_nid, -1) == -1) {
1725+
if (tn_authlist_obj &&
1726+
X509_get_ext_by_OBJ(cert, tn_authlist_obj, -1) != -1) {
1727+
has_tn_authlist = 1;
1728+
} else {
1729+
/*
1730+
* WolfSSL may fail object-based lookup for this custom OID.
1731+
* Fallback to direct OID-string matching over all extensions.
1732+
*/
1733+
ext_count = X509_get_ext_count(cert);
1734+
for (i = 0; i < ext_count; i++) {
1735+
ext = X509_get_ext(cert, i);
1736+
if (!ext)
1737+
continue;
1738+
1739+
ext_obj = X509_EXTENSION_get_object(ext);
1740+
if (!ext_obj)
1741+
continue;
1742+
1743+
if (OBJ_obj2txt(ext_oid, sizeof(ext_oid), ext_obj, 1) <= 0)
1744+
continue;
1745+
1746+
if (strcmp(ext_oid, TN_AUTH_LIST_OID) == 0) {
1747+
has_tn_authlist = 1;
1748+
break;
1749+
}
1750+
}
1751+
}
1752+
1753+
if (!has_tn_authlist) {
16991754
LM_INFO("The certificate is missing the TnAuthList extension\n");
17001755
return -8;
17011756
}

0 commit comments

Comments
 (0)