summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/srp/srp_vfy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/srp/srp_vfy.c')
-rw-r--r--src/lib/libcrypto/srp/srp_vfy.c663
1 files changed, 0 insertions, 663 deletions
diff --git a/src/lib/libcrypto/srp/srp_vfy.c b/src/lib/libcrypto/srp/srp_vfy.c
deleted file mode 100644
index 0b2a3415c2..0000000000
--- a/src/lib/libcrypto/srp/srp_vfy.c
+++ /dev/null
@@ -1,663 +0,0 @@
1/* $OpenBSD: srp_vfy.c,v 1.9 2014/07/22 02:21:20 beck Exp $ */
2/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
3 * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
4 * for the EdelKey project and contributed to the OpenSSL project 2004.
5 */
6/* ====================================================================
7 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#include <openssl/opensslconf.h>
61
62#ifndef OPENSSL_NO_SRP
63
64#include <openssl/buffer.h>
65#include <openssl/evp.h>
66#include <openssl/rand.h>
67#include <openssl/srp.h>
68#include <openssl/txt_db.h>
69
70#include "srp_lcl.h"
71
72#define SRP_RANDOM_SALT_LEN 20
73#define MAX_LEN 2500
74
75static char b64table[] =
76 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
77
78/* the following two conversion routines have been inspired by code from Stanford */
79
80/*
81 * Convert a base64 string into raw byte array representation.
82 */
83static int t_fromb64(unsigned char *a, const char *src)
84 {
85 char *loc;
86 int i, j;
87 int size;
88
89 while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
90 ++src;
91 size = strlen(src);
92 i = 0;
93 while(i < size)
94 {
95 loc = strchr(b64table, src[i]);
96 if(loc == (char *) 0) break;
97 else a[i] = loc - b64table;
98 ++i;
99 }
100 size = i;
101 i = size - 1;
102 j = size;
103 while(1)
104 {
105 a[j] = a[i];
106 if(--i < 0) break;
107 a[j] |= (a[i] & 3) << 6;
108 --j;
109 a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
110 if(--i < 0) break;
111 a[j] |= (a[i] & 0xf) << 4;
112 --j;
113 a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
114 if(--i < 0) break;
115 a[j] |= (a[i] << 2);
116
117 a[--j] = 0;
118 if(--i < 0) break;
119 }
120 while(a[j] == 0 && j <= size) ++j;
121 i = 0;
122 while (j <= size) a[i++] = a[j++];
123 return i;
124 }
125
126
127/*
128 * Convert a raw byte string into a null-terminated base64 ASCII string.
129 */
130static char *t_tob64(char *dst, const unsigned char *src, int size)
131 {
132 int c, pos = size % 3;
133 unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
134 char *olddst = dst;
135
136 switch(pos)
137 {
138 case 1:
139 b2 = src[0];
140 break;
141 case 2:
142 b1 = src[0];
143 b2 = src[1];
144 break;
145 }
146
147 while(1)
148 {
149 c = (b0 & 0xfc) >> 2;
150 if(notleading || c != 0)
151 {
152 *dst++ = b64table[c];
153 notleading = 1;
154 }
155 c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
156 if(notleading || c != 0)
157 {
158 *dst++ = b64table[c];
159 notleading = 1;
160 }
161 c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
162 if(notleading || c != 0)
163 {
164 *dst++ = b64table[c];
165 notleading = 1;
166 }
167 c = b2 & 0x3f;
168 if(notleading || c != 0)
169 {
170 *dst++ = b64table[c];
171 notleading = 1;
172 }
173 if(pos >= size) break;
174 else
175 {
176 b0 = src[pos++];
177 b1 = src[pos++];
178 b2 = src[pos++];
179 }
180 }
181
182 *dst++ = '\0';
183 return olddst;
184 }
185
186static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
187 {
188 if (user_pwd == NULL)
189 return;
190 BN_free(user_pwd->s);
191 BN_clear_free(user_pwd->v);
192 free(user_pwd->id);
193 free(user_pwd->info);
194 free(user_pwd);
195 }
196
197static SRP_user_pwd *SRP_user_pwd_new()
198 {
199 SRP_user_pwd *ret = malloc(sizeof(SRP_user_pwd));
200 if (ret == NULL)
201 return NULL;
202 ret->N = NULL;
203 ret->g = NULL;
204 ret->s = NULL;
205 ret->v = NULL;
206 ret->id = NULL ;
207 ret->info = NULL;
208 return ret;
209 }
210
211static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
212 const BIGNUM *N)
213 {
214 vinfo->N = N;
215 vinfo->g = g;
216 }
217
218static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
219 const char *info)
220 {
221 if (id != NULL && NULL == (vinfo->id = strdup(id)))
222 return 0;
223 return (info == NULL || NULL != (vinfo->info = strdup(info))) ;
224 }
225
226static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
227 const char *v)
228 {
229 unsigned char tmp[MAX_LEN];
230 int len;
231
232 if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN)
233 return 0;
234 len = t_fromb64(tmp, v);
235 if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)) )
236 return 0;
237 len = t_fromb64(tmp, s);
238 return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL) ;
239 }
240
241static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
242 {
243 vinfo->v = v;
244 vinfo->s = s;
245 return (vinfo->s != NULL && vinfo->v != NULL) ;
246 }
247
248SRP_VBASE *SRP_VBASE_new(char *seed_key)
249 {
250 SRP_VBASE *vb = malloc(sizeof(SRP_VBASE));
251
252 if (vb == NULL)
253 return NULL;
254 if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) ||
255 !(vb->gN_cache = sk_SRP_gN_cache_new_null()))
256 {
257 free(vb);
258 return NULL;
259 }
260 vb->default_g = NULL;
261 vb->default_N = NULL;
262 vb->seed_key = NULL;
263 if ((seed_key != NULL) &&
264 (vb->seed_key = strdup(seed_key)) == NULL)
265 {
266 sk_SRP_user_pwd_free(vb->users_pwd);
267 sk_SRP_gN_cache_free(vb->gN_cache);
268 free(vb);
269 return NULL;
270 }
271 return vb;
272 }
273
274
275int SRP_VBASE_free(SRP_VBASE *vb)
276 {
277 sk_SRP_user_pwd_pop_free(vb->users_pwd,SRP_user_pwd_free);
278 sk_SRP_gN_cache_free(vb->gN_cache);
279 free(vb->seed_key);
280 free(vb);
281 return 0;
282 }
283
284
285static SRP_gN_cache *SRP_gN_new_init(const char *ch)
286 {
287 unsigned char tmp[MAX_LEN];
288 int len;
289
290 SRP_gN_cache *newgN = malloc(sizeof(SRP_gN_cache));
291 if (newgN == NULL)
292 return NULL;
293
294 if (ch == NULL || (newgN->b64_bn = strdup(ch)) == NULL)
295 goto err;
296
297 len = t_fromb64(tmp, ch);
298 if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
299 return newgN;
300
301 free(newgN->b64_bn);
302err:
303 free(newgN);
304 return NULL;
305 }
306
307
308static void SRP_gN_free(SRP_gN_cache *gN_cache)
309 {
310 if (gN_cache == NULL)
311 return;
312 free(gN_cache->b64_bn);
313 BN_free(gN_cache->bn);
314 free(gN_cache);
315 }
316
317static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
318 {
319 int i;
320
321 SRP_gN *gN;
322 if (gN_tab != NULL)
323 for(i = 0; i < sk_SRP_gN_num(gN_tab); i++)
324 {
325 gN = sk_SRP_gN_value(gN_tab, i);
326 if (gN && (id == NULL || strcmp(gN->id,id)==0))
327 return gN;
328 }
329
330 return SRP_get_default_gN(id);
331 }
332
333static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
334 {
335 int i;
336 if (gN_cache == NULL)
337 return NULL;
338
339 /* search if we have already one... */
340 for(i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++)
341 {
342 SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
343 if (strcmp(cache->b64_bn,ch)==0)
344 return cache->bn;
345 }
346 { /* it is the first time that we find it */
347 SRP_gN_cache *newgN = SRP_gN_new_init(ch);
348 if (newgN)
349 {
350 if (sk_SRP_gN_cache_insert(gN_cache,newgN,0)>0)
351 return newgN->bn;
352 SRP_gN_free(newgN);
353 }
354 }
355 return NULL;
356 }
357
358/* this function parses verifier file. Format is:
359 * string(index):base64(N):base64(g):0
360 * string(username):base64(v):base64(salt):int(index)
361 */
362
363
364int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
365 {
366 int error_code ;
367 STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
368 char *last_index = NULL;
369 int i;
370 char **pp;
371
372 SRP_gN *gN = NULL;
373 SRP_user_pwd *user_pwd = NULL ;
374
375 TXT_DB *tmpdb = NULL;
376 BIO *in = BIO_new(BIO_s_file());
377
378 error_code = SRP_ERR_OPEN_FILE;
379
380 if (in == NULL || BIO_read_filename(in,verifier_file) <= 0)
381 goto err;
382
383 error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
384
385 if ((tmpdb =TXT_DB_read(in,DB_NUMBER)) == NULL)
386 goto err;
387
388 error_code = SRP_ERR_MEMORY;
389
390
391 if (vb->seed_key)
392 {
393 last_index = SRP_get_default_gN(NULL)->id;
394 }
395 for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++)
396 {
397 pp = sk_OPENSSL_PSTRING_value(tmpdb->data,i);
398 if (pp[DB_srptype][0] == DB_SRP_INDEX)
399 {
400 /*we add this couple in the internal Stack */
401
402 if ((gN = malloc(sizeof(SRP_gN))) == NULL)
403 goto err;
404
405 if ( (pp[DB_srpid] == NULL)
406 || !(gN->id = strdup(pp[DB_srpid]))
407 || !(gN->N = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpverifier]))
408 || !(gN->g = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpsalt]))
409 || sk_SRP_gN_insert(SRP_gN_tab,gN,0) == 0)
410 goto err;
411
412 gN = NULL;
413
414 if (vb->seed_key != NULL)
415 {
416 last_index = pp[DB_srpid];
417 }
418 }
419 else if (pp[DB_srptype][0] == DB_SRP_VALID)
420 {
421 /* it is a user .... */
422 SRP_gN *lgN;
423 if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN],SRP_gN_tab))!=NULL)
424 {
425 error_code = SRP_ERR_MEMORY;
426 if ((user_pwd = SRP_user_pwd_new()) == NULL)
427 goto err;
428
429 SRP_user_pwd_set_gN(user_pwd,lgN->g,lgN->N);
430 if (!SRP_user_pwd_set_ids(user_pwd, pp[DB_srpid],pp[DB_srpinfo]))
431 goto err;
432
433 error_code = SRP_ERR_VBASE_BN_LIB;
434 if (!SRP_user_pwd_set_sv(user_pwd, pp[DB_srpsalt],pp[DB_srpverifier]))
435 goto err;
436
437 if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
438 goto err;
439 user_pwd = NULL; /* abandon responsability */
440 }
441 }
442 }
443
444 if (last_index != NULL)
445 {
446 /* this means that we want to simulate a default user */
447
448 if (((gN = SRP_get_gN_by_id(last_index,SRP_gN_tab))==NULL))
449 {
450 error_code = SRP_ERR_VBASE_BN_LIB;
451 goto err;
452 }
453 vb->default_g = gN->g ;
454 vb->default_N = gN->N ;
455 gN = NULL ;
456 }
457 error_code = SRP_NO_ERROR;
458
459 err:
460 /* there may be still some leaks to fix, if this fails, the application terminates most likely */
461
462 if (gN != NULL)
463 {
464 free(gN->id);
465 free(gN);
466 }
467
468 SRP_user_pwd_free(user_pwd);
469
470 if (tmpdb) TXT_DB_free(tmpdb);
471 if (in) BIO_free_all(in);
472
473 sk_SRP_gN_free(SRP_gN_tab);
474
475 return error_code;
476
477 }
478
479
480SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
481 {
482 int i;
483 SRP_user_pwd *user;
484 unsigned char digv[SHA_DIGEST_LENGTH];
485 unsigned char digs[SHA_DIGEST_LENGTH];
486 EVP_MD_CTX ctxt;
487
488 if (vb == NULL)
489 return NULL;
490 for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++)
491 {
492 user = sk_SRP_user_pwd_value(vb->users_pwd, i);
493 if (strcmp(user->id,username)==0)
494 return user;
495 }
496 if ((vb->seed_key == NULL) ||
497 (vb->default_g == NULL) ||
498 (vb->default_N == NULL))
499 return NULL;
500
501/* if the user is unknown we set parameters as well if we have a seed_key */
502
503 if ((user = SRP_user_pwd_new()) == NULL)
504 return NULL;
505
506 SRP_user_pwd_set_gN(user,vb->default_g,vb->default_N);
507
508 if (!SRP_user_pwd_set_ids(user,username,NULL))
509 goto err;
510
511 RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH);
512 EVP_MD_CTX_init(&ctxt);
513 EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
514 EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
515 EVP_DigestUpdate(&ctxt, username, strlen(username));
516 EVP_DigestFinal_ex(&ctxt, digs, NULL);
517 EVP_MD_CTX_cleanup(&ctxt);
518 if (SRP_user_pwd_set_sv_BN(user, BN_bin2bn(digs,SHA_DIGEST_LENGTH,NULL), BN_bin2bn(digv,SHA_DIGEST_LENGTH, NULL)))
519 return user;
520
521err: SRP_user_pwd_free(user);
522 return NULL;
523 }
524
525
526/*
527 create a verifier (*salt,*verifier,g and N are in base64)
528*/
529char *SRP_create_verifier(const char *user, const char *pass, char **salt,
530 char **verifier, const char *N, const char *g)
531 {
532 int len;
533 char * result=NULL;
534 char *vf;
535 BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL;
536 unsigned char tmp[MAX_LEN];
537 unsigned char tmp2[MAX_LEN];
538 char * defgNid = NULL;
539
540 if ((user == NULL)||
541 (pass == NULL)||
542 (salt == NULL)||
543 (verifier == NULL))
544 goto err;
545
546 if (N)
547 {
548 if (!(len = t_fromb64(tmp, N))) goto err;
549 N_bn = BN_bin2bn(tmp, len, NULL);
550 if (!(len = t_fromb64(tmp, g))) goto err;
551 g_bn = BN_bin2bn(tmp, len, NULL);
552 defgNid = "*";
553 }
554 else
555 {
556 SRP_gN * gN = SRP_get_gN_by_id(g, NULL) ;
557 if (gN == NULL)
558 goto err;
559 N_bn = gN->N;
560 g_bn = gN->g;
561 defgNid = gN->id;
562 }
563
564 if (*salt == NULL)
565 {
566 RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
567
568 s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
569 }
570 else
571 {
572 if (!(len = t_fromb64(tmp2, *salt)))
573 goto err;
574 s = BN_bin2bn(tmp2, len, NULL);
575 }
576
577
578 if(!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) goto err;
579
580 BN_bn2bin(v,tmp);
581 if (((vf = reallocarray(NULL, BN_num_bytes(v), 2)) == NULL))
582 goto err;
583 t_tob64(vf, tmp, BN_num_bytes(v));
584
585 *verifier = vf;
586 if (*salt == NULL)
587 {
588 char *tmp_salt;
589
590 if ((tmp_salt = reallocarray(NULL, SRP_RANDOM_SALT_LEN, 2)) == NULL)
591 {
592 free(vf);
593 goto err;
594 }
595 t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
596 *salt = tmp_salt;
597 }
598
599 result=defgNid;
600
601err:
602 if(N)
603 {
604 BN_free(N_bn);
605 BN_free(g_bn);
606 }
607 return result;
608 }
609
610/*
611 create a verifier (*salt,*verifier,g and N are BIGNUMs)
612*/
613int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g)
614 {
615 int result=0;
616 BIGNUM *x = NULL;
617 BN_CTX *bn_ctx = BN_CTX_new();
618 unsigned char tmp2[MAX_LEN];
619
620 if ((user == NULL)||
621 (pass == NULL)||
622 (salt == NULL)||
623 (verifier == NULL)||
624 (N == NULL)||
625 (g == NULL)||
626 (bn_ctx == NULL))
627 goto err;
628
629 srp_bn_print(N);
630 srp_bn_print(g);
631
632 if (*salt == NULL)
633 {
634 RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
635
636 *salt = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL);
637 }
638
639 x = SRP_Calc_x(*salt,user,pass);
640
641 *verifier = BN_new();
642 if(*verifier == NULL) goto err;
643
644 if (!BN_mod_exp(*verifier,g,x,N,bn_ctx))
645 {
646 BN_clear_free(*verifier);
647 goto err;
648 }
649
650 srp_bn_print(*verifier);
651
652 result=1;
653
654err:
655
656 BN_clear_free(x);
657 BN_CTX_free(bn_ctx);
658 return result;
659 }
660
661
662
663#endif