Skip to content

Commit 00a19ed

Browse files
committed
auth: Avoid abort() if len(secret) is not 32 bytes
Before OpenSIPS 3.2, the "secret" modparam supported random-length strings, to be hashed into an MD5 computation when generating the nonce. Starting with 3.2 and the new AES-CBC based nonce generation algorithm, the "secret" has been restricted to 32-bytes only, however OpenSIPS would assert() -> abort() on startup without displaying any helper error if the user supplied a different-length secret. Many thanks to @thuroc for an accurate report on the assert() issue! Fixes #3043
1 parent d4b03b7 commit 00a19ed

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

lib/digest_auth/dauth_nonce.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,13 @@
3939

4040
#include "dauth_nonce.h"
4141

42-
#define RAND_SECRET_LEN 32
4342
/*
4443
* Length of nonce string in bytes
4544
*/
4645
#define NONCE_LEN 44
4746

4847
_Static_assert((NONCE_LEN * 6) % 8 == 0, "NONCE_LEN should not be padded");
49-
_Static_assert((NONCE_LEN * 6) / 8 >= RAND_SECRET_LEN, "NONCE_LEN is too small");
48+
_Static_assert((NONCE_LEN * 6) / 8 >= AUTH_SECRET_LEN, "NONCE_LEN is too small");
5049

5150
struct nonce_context_priv {
5251
struct nonce_context pub;
@@ -65,10 +64,10 @@ struct nonce_payload {
6564
uint64_t expires_usec:20;
6665
} __attribute__((__packed__));
6766

68-
_Static_assert(sizeof(struct nonce_payload) <= RAND_SECRET_LEN / 2,
67+
_Static_assert(sizeof(struct nonce_payload) <= AUTH_SECRET_LEN / 2,
6968
"struct nonce_payload is too big");
70-
_Static_assert(RAND_SECRET_LEN % sizeof(uint64_t) == 0,
71-
"RAND_SECRET_LEN is not multiple of sizeof(uint64_t)");
69+
_Static_assert(AUTH_SECRET_LEN % sizeof(uint64_t) == 0,
70+
"AUTH_SECRET_LEN is not multiple of sizeof(uint64_t)");
7271

7372
static int Base64Encode(const str_const *message, char* b64buffer);
7473
static int Base64Decode(const str_const *b64message, unsigned char* obuffer);
@@ -98,16 +97,16 @@ int calc_nonce(const struct nonce_context *pub, char* _nonce,
9897
const struct nonce_params *npp)
9998
{
10099
struct nonce_context_priv *self = (typeof(self))pub;
101-
unsigned char ebin[RAND_SECRET_LEN + 1];
100+
unsigned char ebin[AUTH_SECRET_LEN + 1];
102101
int rc, elen;
103-
unsigned char dbin[RAND_SECRET_LEN], *bp;
102+
unsigned char dbin[AUTH_SECRET_LEN], *bp;
104103
unsigned char *riv = dbin;
105104

106-
rc = RAND_bytes(riv, RAND_SECRET_LEN / 2);
105+
rc = RAND_bytes(riv, AUTH_SECRET_LEN / 2);
107106
if (rc != 1)
108107
return -1;
109108

110-
bp = dbin + RAND_SECRET_LEN / 2;
109+
bp = dbin + AUTH_SECRET_LEN / 2;
111110
struct nonce_payload npl;
112111
memset(&npl, 0, sizeof(npl));
113112
npl.expires_sec = npp->expires.tv_sec;
@@ -119,8 +118,8 @@ int calc_nonce(const struct nonce_context *pub, char* _nonce,
119118
bp += sizeof(npl);
120119
memset(bp, 0, sizeof(dbin) - (bp - dbin));
121120

122-
bp = dbin + RAND_SECRET_LEN / 2;
123-
xor_bufs(bp, bp, dbin, RAND_SECRET_LEN / 2);
121+
bp = dbin + AUTH_SECRET_LEN / 2;
122+
xor_bufs(bp, bp, dbin, AUTH_SECRET_LEN / 2);
124123

125124
elen = 0;
126125
rc = EVP_EncryptUpdate(self->ectx, ebin, &elen, dbin, sizeof(dbin));
@@ -140,10 +139,10 @@ int decr_nonce(const struct nonce_context *pub, const str_const * _n,
140139
struct nonce_params *npp)
141140
{
142141
struct nonce_context_priv *self = (typeof(self))pub;
143-
unsigned char bin[RAND_SECRET_LEN + 1];
142+
unsigned char bin[AUTH_SECRET_LEN + 1];
144143
const unsigned char *bp;
145144
unsigned char *wbp;
146-
unsigned char dbin[RAND_SECRET_LEN];
145+
unsigned char dbin[AUTH_SECRET_LEN];
147146
int rc;
148147

149148
if (_n->len != NONCE_LEN)
@@ -153,12 +152,12 @@ int decr_nonce(const struct nonce_context *pub, const str_const * _n,
153152
return -1;
154153
int dlen = 0;
155154
bp = (const unsigned char *)bin;
156-
rc = EVP_DecryptUpdate(self->dctx, dbin, &dlen, bp, RAND_SECRET_LEN);
155+
rc = EVP_DecryptUpdate(self->dctx, dbin, &dlen, bp, AUTH_SECRET_LEN);
157156
if (rc != 1 || dlen != sizeof(dbin))
158157
return -1;
159158

160-
wbp = dbin + RAND_SECRET_LEN / 2;
161-
xor_bufs(wbp, wbp, dbin, RAND_SECRET_LEN / 2);
159+
wbp = dbin + AUTH_SECRET_LEN / 2;
160+
xor_bufs(wbp, wbp, dbin, AUTH_SECRET_LEN / 2);
162161

163162
bp = (const unsigned char *)wbp;
164163
struct nonce_payload npl;
@@ -208,21 +207,21 @@ int generate_random_secret(struct nonce_context *pub)
208207
struct nonce_context_priv *self = (typeof(self))pub;
209208
int rc;
210209

211-
self->sec_rand = (char*)pkg_malloc(RAND_SECRET_LEN);
210+
self->sec_rand = (char*)pkg_malloc(AUTH_SECRET_LEN);
212211
if (!self->sec_rand) {
213212
LM_ERR("no pkg memory left\n");
214213
goto e0;
215214
}
216215

217216
/* the generator is seeded from the core */
218-
rc = RAND_bytes((unsigned char *)self->sec_rand, RAND_SECRET_LEN);
217+
rc = RAND_bytes((unsigned char *)self->sec_rand, AUTH_SECRET_LEN);
219218
if(rc != 1) {
220219
LM_ERR("RAND_bytes() failed, error = %lu\n", ERR_get_error());
221220
goto e1;
222221
}
223222

224223
pub->secret.s = self->sec_rand;
225-
pub->secret.len = RAND_SECRET_LEN;
224+
pub->secret.len = AUTH_SECRET_LEN;
226225

227226
/*LM_DBG("Generated secret: '%.*s'\n", pub->secret.len, pub->secret.s); */
228227

@@ -347,5 +346,5 @@ static int Base64Decode(const str_const *b64message, unsigned char* obuffer)
347346

348347
rval = EVP_DecodeBlock(obuffer, (const unsigned char *)b64message->s,
349348
b64message->len);
350-
return (rval == (RAND_SECRET_LEN + 1)) ? 0 : -1;
349+
return (rval == (AUTH_SECRET_LEN + 1)) ? 0 : -1;
351350
}

lib/digest_auth/dauth_nonce.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "../../str.h"
2828
#include <time.h>
2929

30+
#define AUTH_SECRET_LEN 32
31+
3032
struct nonce_context {
3133
str_const secret; /* secret phrase used to generate nonce */
3234
int nonce_len;

modules/auth/auth_mod.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,13 @@ static int mod_init(void)
229229
/* Otherwise use the parameter's value */
230230
ncp->secret.s = sec_param;
231231
ncp->secret.len = strlen(sec_param);
232+
233+
if (ncp->secret.len != AUTH_SECRET_LEN) {
234+
LM_ERR("bad secret length, must be exactly 32 bytes"
235+
" (256-bit AES key), given: %d (changed in OpenSIPS 3.2+)\n",
236+
ncp->secret.len);
237+
return -1;
238+
}
232239
}
233240

234241
if (dauth_noncer_init(ncp) < 0) {

0 commit comments

Comments
 (0)