Coverage Report

Created: 2025-12-31 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl30/ssl/tls_srp.c
Line
Count
Source
1
/*
2
 * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright (c) 2004, EdelKey Project. All Rights Reserved.
4
 *
5
 * Licensed under the Apache License 2.0 (the "License").  You may not use
6
 * this file except in compliance with the License.  You can obtain a copy
7
 * in the file LICENSE in the source distribution or at
8
 * https://www.openssl.org/source/license.html
9
 *
10
 * Originally written by Christophe Renou and Peter Sylvester,
11
 * for the EdelKey project.
12
 */
13
14
/*
15
 * We need to use the SRP deprecated APIs in order to implement the SSL SRP
16
 * APIs - which are themselves deprecated.
17
 */
18
#define OPENSSL_SUPPRESS_DEPRECATED
19
20
#include <openssl/crypto.h>
21
#include <openssl/rand.h>
22
#include <openssl/err.h>
23
#include "ssl_local.h"
24
25
#ifndef OPENSSL_NO_SRP
26
#include <openssl/srp.h>
27
28
/*
29
 * The public API SSL_CTX_SRP_CTX_free() is deprecated so we use
30
 * ssl_ctx_srp_ctx_free_intern() internally.
31
 */
32
int ssl_ctx_srp_ctx_free_intern(SSL_CTX *ctx)
33
163k
{
34
163k
    if (ctx == NULL)
35
0
        return 0;
36
163k
    OPENSSL_free(ctx->srp_ctx.login);
37
163k
    OPENSSL_free(ctx->srp_ctx.info);
38
163k
    BN_free(ctx->srp_ctx.N);
39
163k
    BN_free(ctx->srp_ctx.g);
40
163k
    BN_free(ctx->srp_ctx.s);
41
163k
    BN_free(ctx->srp_ctx.B);
42
163k
    BN_free(ctx->srp_ctx.A);
43
163k
    BN_free(ctx->srp_ctx.a);
44
163k
    BN_free(ctx->srp_ctx.b);
45
163k
    BN_free(ctx->srp_ctx.v);
46
163k
    memset(&ctx->srp_ctx, 0, sizeof(ctx->srp_ctx));
47
163k
    ctx->srp_ctx.strength = SRP_MINIMAL_N;
48
163k
    return 1;
49
163k
}
50
51
int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx)
52
0
{
53
0
    return ssl_ctx_srp_ctx_free_intern(ctx);
54
0
}
55
56
/*
57
 * The public API SSL_SRP_CTX_free() is deprecated so we use
58
 * ssl_srp_ctx_free_intern() internally.
59
 */
60
int ssl_srp_ctx_free_intern(SSL *s)
61
163k
{
62
163k
    if (s == NULL)
63
0
        return 0;
64
163k
    OPENSSL_free(s->srp_ctx.login);
65
163k
    OPENSSL_free(s->srp_ctx.info);
66
163k
    BN_free(s->srp_ctx.N);
67
163k
    BN_free(s->srp_ctx.g);
68
163k
    BN_free(s->srp_ctx.s);
69
163k
    BN_free(s->srp_ctx.B);
70
163k
    BN_free(s->srp_ctx.A);
71
163k
    BN_free(s->srp_ctx.a);
72
163k
    BN_free(s->srp_ctx.b);
73
163k
    BN_free(s->srp_ctx.v);
74
163k
    memset(&s->srp_ctx, 0, sizeof(s->srp_ctx));
75
163k
    s->srp_ctx.strength = SRP_MINIMAL_N;
76
163k
    return 1;
77
163k
}
78
79
int SSL_SRP_CTX_free(SSL *s)
80
0
{
81
0
    return ssl_srp_ctx_free_intern(s);
82
0
}
83
84
/*
85
 * The public API SSL_SRP_CTX_init() is deprecated so we use
86
 * ssl_srp_ctx_init_intern() internally.
87
 */
88
int ssl_srp_ctx_init_intern(SSL *s)
89
163k
{
90
163k
    SSL_CTX *ctx;
91
92
163k
    if ((s == NULL) || ((ctx = s->ctx) == NULL))
93
0
        return 0;
94
95
163k
    memset(&s->srp_ctx, 0, sizeof(s->srp_ctx));
96
97
163k
    s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
98
    /* set client Hello login callback */
99
163k
    s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
100
    /* set SRP N/g param callback for verification */
101
163k
    s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
102
    /* set SRP client passwd callback */
103
163k
    s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
104
105
163k
    s->srp_ctx.strength = ctx->srp_ctx.strength;
106
107
163k
    if (((ctx->srp_ctx.N != NULL) && ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || ((ctx->srp_ctx.g != NULL) && ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || ((ctx->srp_ctx.s != NULL) && ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || ((ctx->srp_ctx.B != NULL) && ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || ((ctx->srp_ctx.A != NULL) && ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || ((ctx->srp_ctx.a != NULL) && ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || ((ctx->srp_ctx.v != NULL) && ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || ((ctx->srp_ctx.b != NULL) && ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) {
108
0
        ERR_raise(ERR_LIB_SSL, ERR_R_BN_LIB);
109
0
        goto err;
110
0
    }
111
163k
    if ((ctx->srp_ctx.login != NULL) && ((s->srp_ctx.login = OPENSSL_strdup(ctx->srp_ctx.login)) == NULL)) {
112
0
        ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
113
0
        goto err;
114
0
    }
115
163k
    if ((ctx->srp_ctx.info != NULL) && ((s->srp_ctx.info = OPENSSL_strdup(ctx->srp_ctx.info)) == NULL)) {
116
0
        ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
117
0
        goto err;
118
0
    }
119
163k
    s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
120
121
163k
    return 1;
122
0
err:
123
0
    OPENSSL_free(s->srp_ctx.login);
124
0
    OPENSSL_free(s->srp_ctx.info);
125
0
    BN_free(s->srp_ctx.N);
126
0
    BN_free(s->srp_ctx.g);
127
0
    BN_free(s->srp_ctx.s);
128
0
    BN_free(s->srp_ctx.B);
129
0
    BN_free(s->srp_ctx.A);
130
0
    BN_free(s->srp_ctx.a);
131
0
    BN_free(s->srp_ctx.b);
132
0
    BN_free(s->srp_ctx.v);
133
0
    memset(&s->srp_ctx, 0, sizeof(s->srp_ctx));
134
0
    return 0;
135
163k
}
136
137
int SSL_SRP_CTX_init(SSL *s)
138
0
{
139
0
    return ssl_srp_ctx_init_intern(s);
140
0
}
141
142
/*
143
 * The public API SSL_CTX_SRP_CTX_init() is deprecated so we use
144
 * ssl_ctx_srp_ctx_init_intern() internally.
145
 */
146
int ssl_ctx_srp_ctx_init_intern(SSL_CTX *ctx)
147
163k
{
148
163k
    if (ctx == NULL)
149
0
        return 0;
150
151
163k
    memset(&ctx->srp_ctx, 0, sizeof(ctx->srp_ctx));
152
163k
    ctx->srp_ctx.strength = SRP_MINIMAL_N;
153
154
163k
    return 1;
155
163k
}
156
157
int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx)
158
0
{
159
0
    return ssl_ctx_srp_ctx_init_intern(ctx);
160
0
}
161
162
/* server side */
163
/*
164
 * The public API SSL_srp_server_param_with_username() is deprecated so we use
165
 * ssl_srp_server_param_with_username_intern() internally.
166
 */
167
int ssl_srp_server_param_with_username_intern(SSL *s, int *ad)
168
0
{
169
0
    unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
170
0
    int al;
171
172
0
    *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
173
0
    if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && ((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg)) != SSL_ERROR_NONE))
174
0
        return al;
175
176
0
    *ad = SSL_AD_INTERNAL_ERROR;
177
0
    if ((s->srp_ctx.N == NULL) || (s->srp_ctx.g == NULL) || (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL))
178
0
        return SSL3_AL_FATAL;
179
180
0
    if (RAND_priv_bytes_ex(s->ctx->libctx, b, sizeof(b), 0) <= 0)
181
0
        return SSL3_AL_FATAL;
182
0
    s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL);
183
0
    OPENSSL_cleanse(b, sizeof(b));
184
185
    /* Calculate:  B = (kv + g^b) % N  */
186
187
0
    return ((s->srp_ctx.B = SRP_Calc_B_ex(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g,
188
0
                 s->srp_ctx.v, s->ctx->libctx, s->ctx->propq))
189
0
               != NULL)
190
0
        ? SSL_ERROR_NONE
191
0
        : SSL3_AL_FATAL;
192
0
}
193
194
int SSL_srp_server_param_with_username(SSL *s, int *ad)
195
0
{
196
0
    return ssl_srp_server_param_with_username_intern(s, ad);
197
0
}
198
199
/*
200
 * If the server just has the raw password, make up a verifier entry on the
201
 * fly
202
 */
203
int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
204
    const char *grp)
205
0
{
206
0
    SRP_gN *GN = SRP_get_default_gN(grp);
207
0
    if (GN == NULL)
208
0
        return -1;
209
0
    s->srp_ctx.N = BN_dup(GN->N);
210
0
    s->srp_ctx.g = BN_dup(GN->g);
211
0
    BN_clear_free(s->srp_ctx.v);
212
0
    s->srp_ctx.v = NULL;
213
0
    BN_clear_free(s->srp_ctx.s);
214
0
    s->srp_ctx.s = NULL;
215
0
    if (!SRP_create_verifier_BN_ex(user, pass, &s->srp_ctx.s, &s->srp_ctx.v,
216
0
            s->srp_ctx.N, s->srp_ctx.g, s->ctx->libctx,
217
0
            s->ctx->propq))
218
0
        return -1;
219
220
0
    return 1;
221
0
}
222
223
int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
224
    BIGNUM *sa, BIGNUM *v, char *info)
225
0
{
226
0
    if (N != NULL) {
227
0
        if (s->srp_ctx.N != NULL) {
228
0
            if (!BN_copy(s->srp_ctx.N, N)) {
229
0
                BN_free(s->srp_ctx.N);
230
0
                s->srp_ctx.N = NULL;
231
0
            }
232
0
        } else
233
0
            s->srp_ctx.N = BN_dup(N);
234
0
    }
235
0
    if (g != NULL) {
236
0
        if (s->srp_ctx.g != NULL) {
237
0
            if (!BN_copy(s->srp_ctx.g, g)) {
238
0
                BN_free(s->srp_ctx.g);
239
0
                s->srp_ctx.g = NULL;
240
0
            }
241
0
        } else
242
0
            s->srp_ctx.g = BN_dup(g);
243
0
    }
244
0
    if (sa != NULL) {
245
0
        if (s->srp_ctx.s != NULL) {
246
0
            if (!BN_copy(s->srp_ctx.s, sa)) {
247
0
                BN_free(s->srp_ctx.s);
248
0
                s->srp_ctx.s = NULL;
249
0
            }
250
0
        } else
251
0
            s->srp_ctx.s = BN_dup(sa);
252
0
    }
253
0
    if (v != NULL) {
254
0
        if (s->srp_ctx.v != NULL) {
255
0
            if (!BN_copy(s->srp_ctx.v, v)) {
256
0
                BN_free(s->srp_ctx.v);
257
0
                s->srp_ctx.v = NULL;
258
0
            }
259
0
        } else
260
0
            s->srp_ctx.v = BN_dup(v);
261
0
    }
262
0
    if (info != NULL) {
263
0
        if (s->srp_ctx.info)
264
0
            OPENSSL_free(s->srp_ctx.info);
265
0
        if ((s->srp_ctx.info = OPENSSL_strdup(info)) == NULL)
266
0
            return -1;
267
0
    }
268
269
0
    if (!(s->srp_ctx.N) || !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v))
270
0
        return -1;
271
272
0
    return 1;
273
0
}
274
275
int srp_generate_server_master_secret(SSL *s)
276
0
{
277
0
    BIGNUM *K = NULL, *u = NULL;
278
0
    int ret = 0, tmp_len = 0;
279
0
    unsigned char *tmp = NULL;
280
281
0
    if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N))
282
0
        goto err;
283
0
    if ((u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N,
284
0
             s->ctx->libctx, s->ctx->propq))
285
0
        == NULL)
286
0
        goto err;
287
0
    if ((K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b,
288
0
             s->srp_ctx.N))
289
0
        == NULL)
290
0
        goto err;
291
292
0
    tmp_len = BN_num_bytes(K);
293
0
    if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) {
294
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
295
0
        goto err;
296
0
    }
297
0
    BN_bn2bin(K, tmp);
298
    /* Calls SSLfatal() as required */
299
0
    ret = ssl_generate_master_secret(s, tmp, tmp_len, 1);
300
0
err:
301
0
    BN_clear_free(K);
302
0
    BN_clear_free(u);
303
0
    return ret;
304
0
}
305
306
/* client side */
307
int srp_generate_client_master_secret(SSL *s)
308
0
{
309
0
    BIGNUM *x = NULL, *u = NULL, *K = NULL;
310
0
    int ret = 0, tmp_len = 0;
311
0
    char *passwd = NULL;
312
0
    unsigned char *tmp = NULL;
313
314
    /*
315
     * Checks if b % n == 0
316
     */
317
0
    if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0
318
0
        || (u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N,
319
0
                s->ctx->libctx, s->ctx->propq))
320
0
            == NULL
321
0
        || s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) {
322
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
323
0
        goto err;
324
0
    }
325
0
    if ((passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s,
326
0
             s->srp_ctx.SRP_cb_arg))
327
0
        == NULL) {
328
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CALLBACK_FAILED);
329
0
        goto err;
330
0
    }
331
0
    if ((x = SRP_Calc_x_ex(s->srp_ctx.s, s->srp_ctx.login, passwd,
332
0
             s->ctx->libctx, s->ctx->propq))
333
0
            == NULL
334
0
        || (K = SRP_Calc_client_key_ex(s->srp_ctx.N, s->srp_ctx.B,
335
0
                s->srp_ctx.g, x,
336
0
                s->srp_ctx.a, u,
337
0
                s->ctx->libctx,
338
0
                s->ctx->propq))
339
0
            == NULL) {
340
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
341
0
        goto err;
342
0
    }
343
344
0
    tmp_len = BN_num_bytes(K);
345
0
    if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) {
346
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
347
0
        goto err;
348
0
    }
349
0
    BN_bn2bin(K, tmp);
350
    /* Calls SSLfatal() as required */
351
0
    ret = ssl_generate_master_secret(s, tmp, tmp_len, 1);
352
0
err:
353
0
    BN_clear_free(K);
354
0
    BN_clear_free(x);
355
0
    if (passwd != NULL)
356
0
        OPENSSL_clear_free(passwd, strlen(passwd));
357
0
    BN_clear_free(u);
358
0
    return ret;
359
0
}
360
361
int srp_verify_server_param(SSL *s)
362
0
{
363
0
    SRP_CTX *srp = &s->srp_ctx;
364
    /*
365
     * Sanity check parameters: we can quickly check B % N == 0 by checking B
366
     * != 0 since B < N
367
     */
368
0
    if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0
369
0
        || BN_is_zero(srp->B)) {
370
0
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DATA);
371
0
        return 0;
372
0
    }
373
374
0
    if (BN_num_bits(srp->N) < srp->strength) {
375
0
        SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_INSUFFICIENT_SECURITY);
376
0
        return 0;
377
0
    }
378
379
0
    if (srp->SRP_verify_param_callback) {
380
0
        if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) {
381
0
            SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_CALLBACK_FAILED);
382
0
            return 0;
383
0
        }
384
0
    } else if (!SRP_check_known_gN_param(srp->g, srp->N)) {
385
0
        SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY,
386
0
            SSL_R_INSUFFICIENT_SECURITY);
387
0
        return 0;
388
0
    }
389
390
0
    return 1;
391
0
}
392
393
/*
394
 * The public API SRP_Calc_A_param() is deprecated so we use
395
 * ssl_srp_calc_a_param_intern() internally.
396
 */
397
int ssl_srp_calc_a_param_intern(SSL *s)
398
0
{
399
0
    unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
400
401
0
    if (RAND_priv_bytes_ex(s->ctx->libctx, rnd, sizeof(rnd), 0) <= 0)
402
0
        return 0;
403
0
    s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
404
0
    OPENSSL_cleanse(rnd, sizeof(rnd));
405
406
0
    if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g)))
407
0
        return 0;
408
409
0
    return 1;
410
0
}
411
412
int SRP_Calc_A_param(SSL *s)
413
0
{
414
0
    return ssl_srp_calc_a_param_intern(s);
415
0
}
416
417
BIGNUM *SSL_get_srp_g(SSL *s)
418
0
{
419
0
    if (s->srp_ctx.g != NULL)
420
0
        return s->srp_ctx.g;
421
0
    return s->ctx->srp_ctx.g;
422
0
}
423
424
BIGNUM *SSL_get_srp_N(SSL *s)
425
0
{
426
0
    if (s->srp_ctx.N != NULL)
427
0
        return s->srp_ctx.N;
428
0
    return s->ctx->srp_ctx.N;
429
0
}
430
431
char *SSL_get_srp_username(SSL *s)
432
0
{
433
0
    if (s->srp_ctx.login != NULL)
434
0
        return s->srp_ctx.login;
435
0
    return s->ctx->srp_ctx.login;
436
0
}
437
438
char *SSL_get_srp_userinfo(SSL *s)
439
0
{
440
0
    if (s->srp_ctx.info != NULL)
441
0
        return s->srp_ctx.info;
442
0
    return s->ctx->srp_ctx.info;
443
0
}
444
445
0
#define tls1_ctx_ctrl ssl3_ctx_ctrl
446
0
#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
447
448
int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name)
449
0
{
450
0
    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name);
451
0
}
452
453
int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password)
454
0
{
455
0
    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password);
456
0
}
457
458
int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
459
0
{
460
0
    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
461
0
        NULL);
462
0
}
463
464
int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
465
    int (*cb)(SSL *, void *))
466
0
{
467
0
    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
468
0
        (void (*)(void))cb);
469
0
}
470
471
int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
472
0
{
473
0
    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg);
474
0
}
475
476
int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
477
    int (*cb)(SSL *, int *, void *))
478
0
{
479
0
    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
480
0
        (void (*)(void))cb);
481
0
}
482
483
int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
484
    char *(*cb)(SSL *, void *))
485
0
{
486
0
    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
487
0
        (void (*)(void))cb);
488
0
}
489
490
#endif