summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/srp/srp_vfy.c
diff options
context:
space:
mode:
authortedu <>2014-07-28 17:57:18 +0000
committertedu <>2014-07-28 17:57:18 +0000
commit9bf4aaa7e0515aa08e8a462348fc47d3fec0e831 (patch)
tree808724802a47d43670e8dfd6f6050aba39dcf93e /src/lib/libcrypto/srp/srp_vfy.c
parent224cc55e7b0aa21110d14dd564e88e13893a294e (diff)
downloadopenbsd-9bf4aaa7e0515aa08e8a462348fc47d3fec0e831.tar.gz
openbsd-9bf4aaa7e0515aa08e8a462348fc47d3fec0e831.tar.bz2
openbsd-9bf4aaa7e0515aa08e8a462348fc47d3fec0e831.zip
Remove SRP code. It contains a bug (this should not surprise anyone), but
the details are under embargo. The original plan was to wait for the embargo to lift, but we've been waiting for quite some time, and there's no indication of when or even if it will end. No sense in dragging this out any longer. The SRP code has never been enabled in OpenBSD, though I understand it is in use by some other people. However, in light of this and other issues, we're officially saying SRP is outside the scope of libressl. (For now.)
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