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