diff options
author | tedu <> | 2014-07-28 17:57:18 +0000 |
---|---|---|
committer | tedu <> | 2014-07-28 17:57:18 +0000 |
commit | 9bf4aaa7e0515aa08e8a462348fc47d3fec0e831 (patch) | |
tree | 808724802a47d43670e8dfd6f6050aba39dcf93e /src/lib/libcrypto/srp/srp_vfy.c | |
parent | 224cc55e7b0aa21110d14dd564e88e13893a294e (diff) | |
download | openbsd-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.c | 663 |
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 | |||
75 | static 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 | */ | ||
83 | static 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 | */ | ||
130 | static 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 | |||
186 | static 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 | |||
197 | static 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 | |||
211 | static 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 | |||
218 | static 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 | |||
226 | static 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 | |||
241 | static 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 | |||
248 | SRP_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 | |||
275 | int 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 | |||
285 | static 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); | ||
302 | err: | ||
303 | free(newgN); | ||
304 | return NULL; | ||
305 | } | ||
306 | |||
307 | |||
308 | static 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 | |||
317 | static 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 | |||
333 | static 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 | |||
364 | int 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 | |||
480 | SRP_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 | |||
521 | err: 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 | */ | ||
529 | char *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 | |||
601 | err: | ||
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 | */ | ||
613 | int 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 | |||
654 | err: | ||
655 | |||
656 | BN_clear_free(x); | ||
657 | BN_CTX_free(bn_ctx); | ||
658 | return result; | ||
659 | } | ||
660 | |||
661 | |||
662 | |||
663 | #endif | ||