Use the private RNG for data that is not public
[openssl.git] / crypto / srp / srp_vfy.c
1 /*
2  * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2004, EdelKey Project. All Rights Reserved.
4  *
5  * Licensed under the OpenSSL license (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 #ifndef OPENSSL_NO_SRP
15 # include "internal/cryptlib.h"
16 # include <openssl/sha.h>
17 # include <openssl/srp.h>
18 # include <openssl/evp.h>
19 # include <openssl/buffer.h>
20 # include <openssl/rand.h>
21 # include <openssl/txt_db.h>
22
23 # define SRP_RANDOM_SALT_LEN 20
24 # define MAX_LEN 2500
25
26 /*
27  * Convert a base64 string into raw byte array representation.
28  */
29 static int t_fromb64(unsigned char *a, size_t alen, const char *src)
30 {
31     size_t size = strlen(src);
32
33     /* Four bytes in src become three bytes output. */
34     if (size > INT_MAX || (size / 4) * 3 > alen)
35         return -1;
36
37     return EVP_DecodeBlock(a, (unsigned char *)src, (int)size);
38 }
39
40 /*
41  * Convert a raw byte string into a null-terminated base64 ASCII string.
42  */
43 static void t_tob64(char *dst, const unsigned char *src, int size)
44 {
45     EVP_EncodeBlock((unsigned char *)dst, src, size);
46 }
47
48 void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
49 {
50     if (user_pwd == NULL)
51         return;
52     BN_free(user_pwd->s);
53     BN_clear_free(user_pwd->v);
54     OPENSSL_free(user_pwd->id);
55     OPENSSL_free(user_pwd->info);
56     OPENSSL_free(user_pwd);
57 }
58
59 static SRP_user_pwd *SRP_user_pwd_new(void)
60 {
61     SRP_user_pwd *ret = OPENSSL_malloc(sizeof(*ret));
62     if (ret == NULL)
63         return NULL;
64     ret->N = NULL;
65     ret->g = NULL;
66     ret->s = NULL;
67     ret->v = NULL;
68     ret->id = NULL;
69     ret->info = NULL;
70     return ret;
71 }
72
73 static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
74                                 const BIGNUM *N)
75 {
76     vinfo->N = N;
77     vinfo->g = g;
78 }
79
80 static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
81                                 const char *info)
82 {
83     if (id != NULL && NULL == (vinfo->id = OPENSSL_strdup(id)))
84         return 0;
85     return (info == NULL || NULL != (vinfo->info = OPENSSL_strdup(info)));
86 }
87
88 static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
89                                const char *v)
90 {
91     unsigned char tmp[MAX_LEN];
92     int len;
93
94     vinfo->v = NULL;
95     vinfo->s = NULL;
96
97     len = t_fromb64(tmp, sizeof(tmp), v);
98     if (len < 0)
99         return 0;
100     if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)))
101         return 0;
102     len = t_fromb64(tmp, sizeof(tmp), s);
103     if (len < 0)
104         goto err;
105     vinfo->s = BN_bin2bn(tmp, len, NULL);
106     if (vinfo->s == NULL)
107         goto err;
108     return 1;
109  err:
110     BN_free(vinfo->v);
111     vinfo->v = NULL;
112     return 0;
113 }
114
115 static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
116 {
117     vinfo->v = v;
118     vinfo->s = s;
119     return (vinfo->s != NULL && vinfo->v != NULL);
120 }
121
122 static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src)
123 {
124     SRP_user_pwd *ret;
125
126     if (src == NULL)
127         return NULL;
128     if ((ret = SRP_user_pwd_new()) == NULL)
129         return NULL;
130
131     SRP_user_pwd_set_gN(ret, src->g, src->N);
132     if (!SRP_user_pwd_set_ids(ret, src->id, src->info)
133         || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) {
134             SRP_user_pwd_free(ret);
135             return NULL;
136     }
137     return ret;
138 }
139
140 SRP_VBASE *SRP_VBASE_new(char *seed_key)
141 {
142     SRP_VBASE *vb = OPENSSL_malloc(sizeof(*vb));
143
144     if (vb == NULL)
145         return NULL;
146     if ((vb->users_pwd = sk_SRP_user_pwd_new_null()) == NULL
147         || (vb->gN_cache = sk_SRP_gN_cache_new_null()) == NULL) {
148         OPENSSL_free(vb);
149         return NULL;
150     }
151     vb->default_g = NULL;
152     vb->default_N = NULL;
153     vb->seed_key = NULL;
154     if ((seed_key != NULL) && (vb->seed_key = OPENSSL_strdup(seed_key)) == NULL) {
155         sk_SRP_user_pwd_free(vb->users_pwd);
156         sk_SRP_gN_cache_free(vb->gN_cache);
157         OPENSSL_free(vb);
158         return NULL;
159     }
160     return vb;
161 }
162
163 void SRP_VBASE_free(SRP_VBASE *vb)
164 {
165     if (!vb)
166         return;
167     sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free);
168     sk_SRP_gN_cache_free(vb->gN_cache);
169     OPENSSL_free(vb->seed_key);
170     OPENSSL_free(vb);
171 }
172
173 static SRP_gN_cache *SRP_gN_new_init(const char *ch)
174 {
175     unsigned char tmp[MAX_LEN];
176     int len;
177     SRP_gN_cache *newgN = OPENSSL_malloc(sizeof(*newgN));
178
179     if (newgN == NULL)
180         return NULL;
181
182     len = t_fromb64(tmp, sizeof(tmp), ch);
183     if (len < 0)
184         goto err;
185
186     if ((newgN->b64_bn = OPENSSL_strdup(ch)) == NULL)
187         goto err;
188
189     if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
190         return newgN;
191
192     OPENSSL_free(newgN->b64_bn);
193  err:
194     OPENSSL_free(newgN);
195     return NULL;
196 }
197
198 static void SRP_gN_free(SRP_gN_cache *gN_cache)
199 {
200     if (gN_cache == NULL)
201         return;
202     OPENSSL_free(gN_cache->b64_bn);
203     BN_free(gN_cache->bn);
204     OPENSSL_free(gN_cache);
205 }
206
207 static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
208 {
209     int i;
210
211     SRP_gN *gN;
212     if (gN_tab != NULL)
213         for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) {
214             gN = sk_SRP_gN_value(gN_tab, i);
215             if (gN && (id == NULL || strcmp(gN->id, id) == 0))
216                 return gN;
217         }
218
219     return SRP_get_default_gN(id);
220 }
221
222 static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
223 {
224     int i;
225     if (gN_cache == NULL)
226         return NULL;
227
228     /* search if we have already one... */
229     for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) {
230         SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
231         if (strcmp(cache->b64_bn, ch) == 0)
232             return cache->bn;
233     }
234     {                           /* it is the first time that we find it */
235         SRP_gN_cache *newgN = SRP_gN_new_init(ch);
236         if (newgN) {
237             if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0)
238                 return newgN->bn;
239             SRP_gN_free(newgN);
240         }
241     }
242     return NULL;
243 }
244
245 /*
246  * this function parses verifier file. Format is:
247  * string(index):base64(N):base64(g):0
248  * string(username):base64(v):base64(salt):int(index)
249  */
250
251 int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
252 {
253     int error_code;
254     STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
255     char *last_index = NULL;
256     int i;
257     char **pp;
258
259     SRP_gN *gN = NULL;
260     SRP_user_pwd *user_pwd = NULL;
261
262     TXT_DB *tmpdb = NULL;
263     BIO *in = BIO_new(BIO_s_file());
264
265     error_code = SRP_ERR_OPEN_FILE;
266
267     if (in == NULL || BIO_read_filename(in, verifier_file) <= 0)
268         goto err;
269
270     error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
271
272     if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
273         goto err;
274
275     error_code = SRP_ERR_MEMORY;
276
277     if (vb->seed_key) {
278         last_index = SRP_get_default_gN(NULL)->id;
279     }
280     for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) {
281         pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i);
282         if (pp[DB_srptype][0] == DB_SRP_INDEX) {
283             /*
284              * we add this couple in the internal Stack
285              */
286
287             if ((gN = OPENSSL_malloc(sizeof(*gN))) == NULL)
288                 goto err;
289
290             if ((gN->id = OPENSSL_strdup(pp[DB_srpid])) == NULL
291                 || (gN->N = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier]))
292                         == NULL
293                 || (gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt]))
294                         == NULL
295                 || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0)
296                 goto err;
297
298             gN = NULL;
299
300             if (vb->seed_key != NULL) {
301                 last_index = pp[DB_srpid];
302             }
303         } else if (pp[DB_srptype][0] == DB_SRP_VALID) {
304             /* it is a user .... */
305             const SRP_gN *lgN;
306
307             if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) {
308                 error_code = SRP_ERR_MEMORY;
309                 if ((user_pwd = SRP_user_pwd_new()) == NULL)
310                     goto err;
311
312                 SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N);
313                 if (!SRP_user_pwd_set_ids
314                     (user_pwd, pp[DB_srpid], pp[DB_srpinfo]))
315                     goto err;
316
317                 error_code = SRP_ERR_VBASE_BN_LIB;
318                 if (!SRP_user_pwd_set_sv
319                     (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier]))
320                     goto err;
321
322                 if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
323                     goto err;
324                 user_pwd = NULL; /* abandon responsibility */
325             }
326         }
327     }
328
329     if (last_index != NULL) {
330         /* this means that we want to simulate a default user */
331
332         if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) {
333             error_code = SRP_ERR_VBASE_BN_LIB;
334             goto err;
335         }
336         vb->default_g = gN->g;
337         vb->default_N = gN->N;
338         gN = NULL;
339     }
340     error_code = SRP_NO_ERROR;
341
342  err:
343     /*
344      * there may be still some leaks to fix, if this fails, the application
345      * terminates most likely
346      */
347
348     if (gN != NULL) {
349         OPENSSL_free(gN->id);
350         OPENSSL_free(gN);
351     }
352
353     SRP_user_pwd_free(user_pwd);
354
355     TXT_DB_free(tmpdb);
356     BIO_free_all(in);
357
358     sk_SRP_gN_free(SRP_gN_tab);
359
360     return error_code;
361
362 }
363
364 static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username)
365 {
366     int i;
367     SRP_user_pwd *user;
368
369     if (vb == NULL)
370         return NULL;
371
372     for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) {
373         user = sk_SRP_user_pwd_value(vb->users_pwd, i);
374         if (strcmp(user->id, username) == 0)
375             return user;
376     }
377
378     return NULL;
379 }
380
381 # if OPENSSL_API_COMPAT < 0x10100000L
382 /*
383  * DEPRECATED: use SRP_VBASE_get1_by_user instead.
384  * This method ignores the configured seed and fails for an unknown user.
385  * Ownership of the returned pointer is not released to the caller.
386  * In other words, caller must not free the result.
387  */
388 SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
389 {
390     return find_user(vb, username);
391 }
392 # endif
393
394 /*
395  * Ownership of the returned pointer is released to the caller.
396  * In other words, caller must free the result once done.
397  */
398 SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
399 {
400     SRP_user_pwd *user;
401     unsigned char digv[SHA_DIGEST_LENGTH];
402     unsigned char digs[SHA_DIGEST_LENGTH];
403     EVP_MD_CTX *ctxt = NULL;
404
405     if (vb == NULL)
406         return NULL;
407
408     if ((user = find_user(vb, username)) != NULL)
409         return srp_user_pwd_dup(user);
410
411     if ((vb->seed_key == NULL) ||
412         (vb->default_g == NULL) || (vb->default_N == NULL))
413         return NULL;
414
415 /* if the user is unknown we set parameters as well if we have a seed_key */
416
417     if ((user = SRP_user_pwd_new()) == NULL)
418         return NULL;
419
420     SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N);
421
422     if (!SRP_user_pwd_set_ids(user, username, NULL))
423         goto err;
424
425     if (RAND_priv_bytes(digv, SHA_DIGEST_LENGTH) <= 0)
426         goto err;
427     ctxt = EVP_MD_CTX_new();
428     if (ctxt == NULL
429         || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)
430         || !EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key))
431         || !EVP_DigestUpdate(ctxt, username, strlen(username))
432         || !EVP_DigestFinal_ex(ctxt, digs, NULL))
433         goto err;
434     EVP_MD_CTX_free(ctxt);
435     ctxt = NULL;
436     if (SRP_user_pwd_set_sv_BN(user,
437                                BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL),
438                                BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL)))
439         return user;
440
441  err:
442     EVP_MD_CTX_free(ctxt);
443     SRP_user_pwd_free(user);
444     return NULL;
445 }
446
447 /*
448  * create a verifier (*salt,*verifier,g and N are in base64)
449  */
450 char *SRP_create_verifier(const char *user, const char *pass, char **salt,
451                           char **verifier, const char *N, const char *g)
452 {
453     int len;
454     char *result = NULL, *vf = NULL;
455     const BIGNUM *N_bn = NULL, *g_bn = NULL;
456     BIGNUM *N_bn_alloc = NULL, *g_bn_alloc = NULL, *s = NULL, *v = NULL;
457     unsigned char tmp[MAX_LEN];
458     unsigned char tmp2[MAX_LEN];
459     char *defgNid = NULL;
460     int vfsize = 0;
461
462     if ((user == NULL) ||
463         (pass == NULL) || (salt == NULL) || (verifier == NULL))
464         goto err;
465
466     if (N) {
467         if ((len = t_fromb64(tmp, sizeof(tmp), N)) <= 0)
468             goto err;
469         N_bn_alloc = BN_bin2bn(tmp, len, NULL);
470         N_bn = N_bn_alloc;
471         if ((len = t_fromb64(tmp, sizeof(tmp) ,g)) <= 0)
472             goto err;
473         g_bn_alloc = BN_bin2bn(tmp, len, NULL);
474         g_bn = g_bn_alloc;
475         defgNid = "*";
476     } else {
477         SRP_gN *gN = SRP_get_gN_by_id(g, NULL);
478         if (gN == NULL)
479             goto err;
480         N_bn = gN->N;
481         g_bn = gN->g;
482         defgNid = gN->id;
483     }
484
485     if (*salt == NULL) {
486         if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
487             goto err;
488
489         s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
490     } else {
491         if ((len = t_fromb64(tmp2, sizeof(tmp2), *salt)) <= 0)
492             goto err;
493         s = BN_bin2bn(tmp2, len, NULL);
494     }
495
496     if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn))
497         goto err;
498
499     BN_bn2bin(v, tmp);
500     vfsize = BN_num_bytes(v) * 2;
501     if (((vf = OPENSSL_malloc(vfsize)) == NULL))
502         goto err;
503     t_tob64(vf, tmp, BN_num_bytes(v));
504
505     if (*salt == NULL) {
506         char *tmp_salt;
507
508         if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) {
509             goto err;
510         }
511         t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
512         *salt = tmp_salt;
513     }
514
515     *verifier = vf;
516     vf = NULL;
517     result = defgNid;
518
519  err:
520     BN_free(N_bn_alloc);
521     BN_free(g_bn_alloc);
522     OPENSSL_clear_free(vf, vfsize);
523     BN_clear_free(s);
524     BN_clear_free(v);
525     return result;
526 }
527
528 /*
529  * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL
530  * then the provided salt will be used. On successful exit *verifier will point
531  * to a newly allocated BIGNUM containing the verifier and (if a salt was not
532  * provided) *salt will be populated with a newly allocated BIGNUM containing a
533  * random salt.
534  * The caller is responsible for freeing the allocated *salt and *verifier
535  * BIGNUMS.
536  */
537 int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
538                            BIGNUM **verifier, const BIGNUM *N,
539                            const BIGNUM *g)
540 {
541     int result = 0;
542     BIGNUM *x = NULL;
543     BN_CTX *bn_ctx = BN_CTX_new();
544     unsigned char tmp2[MAX_LEN];
545     BIGNUM *salttmp = NULL;
546
547     if ((user == NULL) ||
548         (pass == NULL) ||
549         (salt == NULL) ||
550         (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL))
551         goto err;
552
553     if (*salt == NULL) {
554         if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
555             goto err;
556
557         salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
558     } else {
559         salttmp = *salt;
560     }
561
562     x = SRP_Calc_x(salttmp, user, pass);
563
564     *verifier = BN_new();
565     if (*verifier == NULL)
566         goto err;
567
568     if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) {
569         BN_clear_free(*verifier);
570         goto err;
571     }
572
573     result = 1;
574     *salt = salttmp;
575
576  err:
577     if (salt != NULL && *salt != salttmp)
578         BN_clear_free(salttmp);
579     BN_clear_free(x);
580     BN_CTX_free(bn_ctx);
581     return result;
582 }
583
584 #endif