2 * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #ifndef OPENSSL_NO_SRP
11 # include "internal/cryptlib.h"
12 # include <openssl/sha.h>
13 # include <openssl/srp.h>
14 # include <openssl/evp.h>
15 # include <openssl/buffer.h>
16 # include <openssl/rand.h>
17 # include <openssl/txt_db.h>
19 # define SRP_RANDOM_SALT_LEN 20
22 static char b64table
[] =
23 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
26 * the following two conversion routines have been inspired by code from
31 * Convert a base64 string into raw byte array representation.
33 static int t_fromb64(unsigned char *a
, const char *src
)
39 while (*src
&& (*src
== ' ' || *src
== '\t' || *src
== '\n'))
44 loc
= strchr(b64table
, src
[i
]);
48 a
[i
] = loc
- b64table
;
51 /* if nothing valid to process we have a zero length response */
61 a
[j
] |= (a
[i
] & 3) << 6;
63 a
[j
] = (unsigned char)((a
[i
] & 0x3c) >> 2);
66 a
[j
] |= (a
[i
] & 0xf) << 4;
68 a
[j
] = (unsigned char)((a
[i
] & 0x30) >> 4);
77 while (a
[j
] == 0 && j
<= size
)
86 * Convert a raw byte string into a null-terminated base64 ASCII string.
88 static char *t_tob64(char *dst
, const unsigned char *src
, int size
)
90 int c
, pos
= size
% 3;
91 unsigned char b0
= 0, b1
= 0, b2
= 0, notleading
= 0;
105 c
= (b0
& 0xfc) >> 2;
106 if (notleading
|| c
!= 0) {
107 *dst
++ = b64table
[c
];
110 c
= ((b0
& 3) << 4) | ((b1
& 0xf0) >> 4);
111 if (notleading
|| c
!= 0) {
112 *dst
++ = b64table
[c
];
115 c
= ((b1
& 0xf) << 2) | ((b2
& 0xc0) >> 6);
116 if (notleading
|| c
!= 0) {
117 *dst
++ = b64table
[c
];
121 if (notleading
|| c
!= 0) {
122 *dst
++ = b64table
[c
];
138 void SRP_user_pwd_free(SRP_user_pwd
*user_pwd
)
140 if (user_pwd
== NULL
)
142 BN_free(user_pwd
->s
);
143 BN_clear_free(user_pwd
->v
);
144 OPENSSL_free(user_pwd
->id
);
145 OPENSSL_free(user_pwd
->info
);
146 OPENSSL_free(user_pwd
);
149 static SRP_user_pwd
*SRP_user_pwd_new(void)
151 SRP_user_pwd
*ret
= OPENSSL_malloc(sizeof(*ret
));
163 static void SRP_user_pwd_set_gN(SRP_user_pwd
*vinfo
, const BIGNUM
*g
,
170 static int SRP_user_pwd_set_ids(SRP_user_pwd
*vinfo
, const char *id
,
173 if (id
!= NULL
&& NULL
== (vinfo
->id
= OPENSSL_strdup(id
)))
175 return (info
== NULL
|| NULL
!= (vinfo
->info
= OPENSSL_strdup(info
)));
178 static int SRP_user_pwd_set_sv(SRP_user_pwd
*vinfo
, const char *s
,
181 unsigned char tmp
[MAX_LEN
];
184 if (strlen(s
) > MAX_LEN
|| strlen(v
) > MAX_LEN
)
186 len
= t_fromb64(tmp
, v
);
187 if (NULL
== (vinfo
->v
= BN_bin2bn(tmp
, len
, NULL
)))
189 len
= t_fromb64(tmp
, s
);
190 return ((vinfo
->s
= BN_bin2bn(tmp
, len
, NULL
)) != NULL
);
193 static int SRP_user_pwd_set_sv_BN(SRP_user_pwd
*vinfo
, BIGNUM
*s
, BIGNUM
*v
)
197 return (vinfo
->s
!= NULL
&& vinfo
->v
!= NULL
);
200 static SRP_user_pwd
*srp_user_pwd_dup(SRP_user_pwd
*src
)
206 if ((ret
= SRP_user_pwd_new()) == NULL
)
209 SRP_user_pwd_set_gN(ret
, src
->g
, src
->N
);
210 if (!SRP_user_pwd_set_ids(ret
, src
->id
, src
->info
)
211 || !SRP_user_pwd_set_sv_BN(ret
, BN_dup(src
->s
), BN_dup(src
->v
))) {
212 SRP_user_pwd_free(ret
);
218 SRP_VBASE
*SRP_VBASE_new(char *seed_key
)
220 SRP_VBASE
*vb
= OPENSSL_malloc(sizeof(*vb
));
224 if ((vb
->users_pwd
= sk_SRP_user_pwd_new_null()) == NULL
225 || (vb
->gN_cache
= sk_SRP_gN_cache_new_null()) == NULL
) {
229 vb
->default_g
= NULL
;
230 vb
->default_N
= NULL
;
232 if ((seed_key
!= NULL
) && (vb
->seed_key
= OPENSSL_strdup(seed_key
)) == NULL
) {
233 sk_SRP_user_pwd_free(vb
->users_pwd
);
234 sk_SRP_gN_cache_free(vb
->gN_cache
);
241 void SRP_VBASE_free(SRP_VBASE
*vb
)
245 sk_SRP_user_pwd_pop_free(vb
->users_pwd
, SRP_user_pwd_free
);
246 sk_SRP_gN_cache_free(vb
->gN_cache
);
247 OPENSSL_free(vb
->seed_key
);
251 static SRP_gN_cache
*SRP_gN_new_init(const char *ch
)
253 unsigned char tmp
[MAX_LEN
];
255 SRP_gN_cache
*newgN
= OPENSSL_malloc(sizeof(*newgN
));
260 if ((newgN
->b64_bn
= OPENSSL_strdup(ch
)) == NULL
)
263 len
= t_fromb64(tmp
, ch
);
264 if ((newgN
->bn
= BN_bin2bn(tmp
, len
, NULL
)))
267 OPENSSL_free(newgN
->b64_bn
);
273 static void SRP_gN_free(SRP_gN_cache
*gN_cache
)
275 if (gN_cache
== NULL
)
277 OPENSSL_free(gN_cache
->b64_bn
);
278 BN_free(gN_cache
->bn
);
279 OPENSSL_free(gN_cache
);
282 static SRP_gN
*SRP_get_gN_by_id(const char *id
, STACK_OF(SRP_gN
) *gN_tab
)
288 for (i
= 0; i
< sk_SRP_gN_num(gN_tab
); i
++) {
289 gN
= sk_SRP_gN_value(gN_tab
, i
);
290 if (gN
&& (id
== NULL
|| strcmp(gN
->id
, id
) == 0))
294 return SRP_get_default_gN(id
);
297 static BIGNUM
*SRP_gN_place_bn(STACK_OF(SRP_gN_cache
) *gN_cache
, char *ch
)
300 if (gN_cache
== NULL
)
303 /* search if we have already one... */
304 for (i
= 0; i
< sk_SRP_gN_cache_num(gN_cache
); i
++) {
305 SRP_gN_cache
*cache
= sk_SRP_gN_cache_value(gN_cache
, i
);
306 if (strcmp(cache
->b64_bn
, ch
) == 0)
309 { /* it is the first time that we find it */
310 SRP_gN_cache
*newgN
= SRP_gN_new_init(ch
);
312 if (sk_SRP_gN_cache_insert(gN_cache
, newgN
, 0) > 0)
321 * this function parses verifier file. Format is:
322 * string(index):base64(N):base64(g):0
323 * string(username):base64(v):base64(salt):int(index)
326 int SRP_VBASE_init(SRP_VBASE
*vb
, char *verifier_file
)
329 STACK_OF(SRP_gN
) *SRP_gN_tab
= sk_SRP_gN_new_null();
330 char *last_index
= NULL
;
335 SRP_user_pwd
*user_pwd
= NULL
;
337 TXT_DB
*tmpdb
= NULL
;
338 BIO
*in
= BIO_new(BIO_s_file());
340 error_code
= SRP_ERR_OPEN_FILE
;
342 if (in
== NULL
|| BIO_read_filename(in
, verifier_file
) <= 0)
345 error_code
= SRP_ERR_VBASE_INCOMPLETE_FILE
;
347 if ((tmpdb
= TXT_DB_read(in
, DB_NUMBER
)) == NULL
)
350 error_code
= SRP_ERR_MEMORY
;
353 last_index
= SRP_get_default_gN(NULL
)->id
;
355 for (i
= 0; i
< sk_OPENSSL_PSTRING_num(tmpdb
->data
); i
++) {
356 pp
= sk_OPENSSL_PSTRING_value(tmpdb
->data
, i
);
357 if (pp
[DB_srptype
][0] == DB_SRP_INDEX
) {
359 * we add this couple in the internal Stack
362 if ((gN
= OPENSSL_malloc(sizeof(*gN
))) == NULL
)
365 if ((gN
->id
= OPENSSL_strdup(pp
[DB_srpid
])) == NULL
366 || (gN
->N
= SRP_gN_place_bn(vb
->gN_cache
, pp
[DB_srpverifier
]))
368 || (gN
->g
= SRP_gN_place_bn(vb
->gN_cache
, pp
[DB_srpsalt
]))
370 || sk_SRP_gN_insert(SRP_gN_tab
, gN
, 0) == 0)
375 if (vb
->seed_key
!= NULL
) {
376 last_index
= pp
[DB_srpid
];
378 } else if (pp
[DB_srptype
][0] == DB_SRP_VALID
) {
379 /* it is a user .... */
382 if ((lgN
= SRP_get_gN_by_id(pp
[DB_srpgN
], SRP_gN_tab
)) != NULL
) {
383 error_code
= SRP_ERR_MEMORY
;
384 if ((user_pwd
= SRP_user_pwd_new()) == NULL
)
387 SRP_user_pwd_set_gN(user_pwd
, lgN
->g
, lgN
->N
);
388 if (!SRP_user_pwd_set_ids
389 (user_pwd
, pp
[DB_srpid
], pp
[DB_srpinfo
]))
392 error_code
= SRP_ERR_VBASE_BN_LIB
;
393 if (!SRP_user_pwd_set_sv
394 (user_pwd
, pp
[DB_srpsalt
], pp
[DB_srpverifier
]))
397 if (sk_SRP_user_pwd_insert(vb
->users_pwd
, user_pwd
, 0) == 0)
399 user_pwd
= NULL
; /* abandon responsibility */
404 if (last_index
!= NULL
) {
405 /* this means that we want to simulate a default user */
407 if (((gN
= SRP_get_gN_by_id(last_index
, SRP_gN_tab
)) == NULL
)) {
408 error_code
= SRP_ERR_VBASE_BN_LIB
;
411 vb
->default_g
= gN
->g
;
412 vb
->default_N
= gN
->N
;
415 error_code
= SRP_NO_ERROR
;
419 * there may be still some leaks to fix, if this fails, the application
420 * terminates most likely
424 OPENSSL_free(gN
->id
);
428 SRP_user_pwd_free(user_pwd
);
433 sk_SRP_gN_free(SRP_gN_tab
);
439 static SRP_user_pwd
*find_user(SRP_VBASE
*vb
, char *username
)
447 for (i
= 0; i
< sk_SRP_user_pwd_num(vb
->users_pwd
); i
++) {
448 user
= sk_SRP_user_pwd_value(vb
->users_pwd
, i
);
449 if (strcmp(user
->id
, username
) == 0)
456 #if OPENSSL_API_COMPAT < 0x10100000L
458 * DEPRECATED: use SRP_VBASE_get1_by_user instead.
459 * This method ignores the configured seed and fails for an unknown user.
460 * Ownership of the returned pointer is not released to the caller.
461 * In other words, caller must not free the result.
463 SRP_user_pwd
*SRP_VBASE_get_by_user(SRP_VBASE
*vb
, char *username
)
465 return find_user(vb
, username
);
470 * Ownership of the returned pointer is released to the caller.
471 * In other words, caller must free the result once done.
473 SRP_user_pwd
*SRP_VBASE_get1_by_user(SRP_VBASE
*vb
, char *username
)
476 unsigned char digv
[SHA_DIGEST_LENGTH
];
477 unsigned char digs
[SHA_DIGEST_LENGTH
];
478 EVP_MD_CTX
*ctxt
= NULL
;
483 if ((user
= find_user(vb
, username
)) != NULL
)
484 return srp_user_pwd_dup(user
);
486 if ((vb
->seed_key
== NULL
) ||
487 (vb
->default_g
== NULL
) || (vb
->default_N
== NULL
))
490 /* if the user is unknown we set parameters as well if we have a seed_key */
492 if ((user
= SRP_user_pwd_new()) == NULL
)
495 SRP_user_pwd_set_gN(user
, vb
->default_g
, vb
->default_N
);
497 if (!SRP_user_pwd_set_ids(user
, username
, NULL
))
500 if (RAND_bytes(digv
, SHA_DIGEST_LENGTH
) <= 0)
502 ctxt
= EVP_MD_CTX_new();
503 EVP_DigestInit_ex(ctxt
, EVP_sha1(), NULL
);
504 EVP_DigestUpdate(ctxt
, vb
->seed_key
, strlen(vb
->seed_key
));
505 EVP_DigestUpdate(ctxt
, username
, strlen(username
));
506 EVP_DigestFinal_ex(ctxt
, digs
, NULL
);
507 EVP_MD_CTX_free(ctxt
);
509 if (SRP_user_pwd_set_sv_BN(user
,
510 BN_bin2bn(digs
, SHA_DIGEST_LENGTH
, NULL
),
511 BN_bin2bn(digv
, SHA_DIGEST_LENGTH
, NULL
)))
515 EVP_MD_CTX_free(ctxt
);
516 SRP_user_pwd_free(user
);
521 * create a verifier (*salt,*verifier,g and N are in base64)
523 char *SRP_create_verifier(const char *user
, const char *pass
, char **salt
,
524 char **verifier
, const char *N
, const char *g
)
527 char *result
= NULL
, *vf
= NULL
;
528 BIGNUM
*N_bn
= NULL
, *g_bn
= NULL
, *s
= NULL
, *v
= NULL
;
529 unsigned char tmp
[MAX_LEN
];
530 unsigned char tmp2
[MAX_LEN
];
531 char *defgNid
= NULL
;
534 if ((user
== NULL
) ||
535 (pass
== NULL
) || (salt
== NULL
) || (verifier
== NULL
))
539 if ((len
= t_fromb64(tmp
, N
)) == 0)
541 N_bn
= BN_bin2bn(tmp
, len
, NULL
);
542 if ((len
= t_fromb64(tmp
, g
)) == 0)
544 g_bn
= BN_bin2bn(tmp
, len
, NULL
);
547 SRP_gN
*gN
= SRP_get_gN_by_id(g
, NULL
);
556 if (RAND_bytes(tmp2
, SRP_RANDOM_SALT_LEN
) <= 0)
559 s
= BN_bin2bn(tmp2
, SRP_RANDOM_SALT_LEN
, NULL
);
561 if ((len
= t_fromb64(tmp2
, *salt
)) == 0)
563 s
= BN_bin2bn(tmp2
, len
, NULL
);
566 if (!SRP_create_verifier_BN(user
, pass
, &s
, &v
, N_bn
, g_bn
))
570 vfsize
= BN_num_bytes(v
) * 2;
571 if (((vf
= OPENSSL_malloc(vfsize
)) == NULL
))
573 t_tob64(vf
, tmp
, BN_num_bytes(v
));
578 if ((tmp_salt
= OPENSSL_malloc(SRP_RANDOM_SALT_LEN
* 2)) == NULL
) {
581 t_tob64(tmp_salt
, tmp2
, SRP_RANDOM_SALT_LEN
);
594 OPENSSL_clear_free(vf
, vfsize
);
601 * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL
602 * then the provided salt will be used. On successful exit *verifier will point
603 * to a newly allocated BIGNUM containing the verifier and (if a salt was not
604 * provided) *salt will be populated with a newly allocated BIGNUM containing a
606 * The caller is responsible for freeing the allocated *salt and *verifier
609 int SRP_create_verifier_BN(const char *user
, const char *pass
, BIGNUM
**salt
,
610 BIGNUM
**verifier
, const BIGNUM
*N
,
615 BN_CTX
*bn_ctx
= BN_CTX_new();
616 unsigned char tmp2
[MAX_LEN
];
617 BIGNUM
*salttmp
= NULL
;
619 if ((user
== NULL
) ||
622 (verifier
== NULL
) || (N
== NULL
) || (g
== NULL
) || (bn_ctx
== NULL
))
626 if (RAND_bytes(tmp2
, SRP_RANDOM_SALT_LEN
) <= 0)
629 salttmp
= BN_bin2bn(tmp2
, SRP_RANDOM_SALT_LEN
, NULL
);
634 x
= SRP_Calc_x(salttmp
, user
, pass
);
636 *verifier
= BN_new();
637 if (*verifier
== NULL
)
640 if (!BN_mod_exp(*verifier
, g
, x
, N
, bn_ctx
)) {
641 BN_clear_free(*verifier
);
649 if (salt
!= NULL
&& *salt
!= salttmp
)
650 BN_clear_free(salttmp
);