| /* |
| * Copyright (c) 1997-2007 The Stanford SRP Authentication Project |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sublicense, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be |
| * included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY |
| * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. |
| * |
| * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL, |
| * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER |
| * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF |
| * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT |
| * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| * |
| * Redistributions in source or binary form must retain an intact copy |
| * of this copyright notice. |
| */ |
| |
| #include "t_defines.h" |
| #include "srp.h" |
| |
| static int library_initialized = 0; |
| |
| _TYPE( SRP_RESULT ) |
| SRP_initialize_library() |
| { |
| if(library_initialized == 0) { |
| BigIntegerInitialize(); |
| t_stronginitrand(); |
| library_initialized = 1; |
| } |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_finalize_library() |
| { |
| if(library_initialized > 0) { |
| library_initialized = 0; |
| BigIntegerFinalize(); |
| } |
| return SRP_SUCCESS; |
| } |
| |
| static int srp_modulus_min_bits = SRP_DEFAULT_MIN_BITS; |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_modulus_min_bits(int minbits) |
| { |
| srp_modulus_min_bits = minbits; |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( int ) |
| SRP_get_modulus_min_bits() |
| { |
| return srp_modulus_min_bits; |
| } |
| |
| static int |
| default_secret_bits_cb(int modsize) |
| { |
| return 256; |
| /*return modsize;*/ /* Warning: Very Slow */ |
| } |
| |
| static SRP_SECRET_BITS_CB srp_sb_cb = default_secret_bits_cb; |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_secret_bits_cb(SRP_SECRET_BITS_CB cb) |
| { |
| srp_sb_cb = cb; |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( int ) |
| SRP_get_secret_bits(int modsize) |
| { |
| return (*srp_sb_cb)(modsize); |
| } |
| |
| _TYPE( SRP * ) |
| SRP_new(SRP_METHOD * meth) |
| { |
| SRP * srp = (SRP *) malloc(sizeof(SRP)); |
| |
| if(srp == NULL) |
| return NULL; |
| |
| srp->flags = 0; |
| srp->username = cstr_new(); |
| srp->bctx = BigIntegerCtxNew(); |
| srp->modulus = NULL; |
| srp->accel = NULL; |
| srp->generator = NULL; |
| srp->salt = NULL; |
| srp->verifier = NULL; |
| srp->password = NULL; |
| srp->pubkey = NULL; |
| srp->secret = NULL; |
| srp->u = NULL; |
| srp->key = NULL; |
| srp->ex_data = cstr_new(); |
| srp->param_cb = NULL; |
| srp->meth = meth; |
| srp->meth_data = NULL; |
| //srp->slu = NULL; |
| if(srp->meth->init == NULL || (*srp->meth->init)(srp) == SRP_SUCCESS) |
| return srp; |
| free(srp); |
| return NULL; |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_free(SRP * srp) |
| { |
| if(srp->meth->finish) |
| (*srp->meth->finish)(srp); |
| |
| if(srp->username) |
| cstr_clear_free(srp->username); |
| if(srp->modulus) |
| BigIntegerFree(srp->modulus); |
| if(srp->accel) |
| BigIntegerModAccelFree(srp->accel); |
| if(srp->generator) |
| BigIntegerFree(srp->generator); |
| if(srp->salt) |
| cstr_clear_free(srp->salt); |
| if(srp->verifier) |
| BigIntegerClearFree(srp->verifier); |
| if(srp->password) |
| BigIntegerClearFree(srp->password); |
| if(srp->pubkey) |
| BigIntegerFree(srp->pubkey); |
| if(srp->secret) |
| BigIntegerClearFree(srp->secret); |
| if(srp->u) |
| BigIntegerFree(srp->u); |
| if(srp->key) |
| BigIntegerClearFree(srp->key); |
| if(srp->bctx) |
| BigIntegerCtxFree(srp->bctx); |
| if(srp->ex_data) |
| cstr_clear_free(srp->ex_data); |
| free(srp); |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_client_param_verify_cb(SRP * srp, SRP_CLIENT_PARAM_VERIFY_CB cb) |
| { |
| srp->param_cb = cb; |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_username(SRP * srp, const char * username) |
| { |
| cstr_set(srp->username, username); |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_user_raw(SRP * srp, const unsigned char * user, int userlen) |
| { |
| cstr_setn(srp->username, (const char*)user, userlen); |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_params(SRP * srp, const unsigned char * modulus, int modlen, |
| const unsigned char * generator, int genlen, |
| const unsigned char * salt, int saltlen) |
| { |
| SRP_RESULT rc; |
| |
| if(modulus == NULL || generator == NULL || salt == NULL) |
| return SRP_ERROR; |
| |
| /* Set fields in SRP context */ |
| srp->modulus = BigIntegerFromBytes(modulus, modlen); |
| if(srp->flags & SRP_FLAG_MOD_ACCEL) |
| srp->accel = BigIntegerModAccelNew(srp->modulus, srp->bctx); |
| srp->generator = BigIntegerFromBytes(generator, genlen); |
| if(srp->salt == NULL) |
| srp->salt = cstr_new(); |
| cstr_setn(srp->salt, (const char*)salt, saltlen); |
| |
| /* Now attempt to validate parameters */ |
| if(BigIntegerBitLen(srp->modulus) < SRP_get_modulus_min_bits()) |
| return SRP_ERROR; |
| |
| if(srp->param_cb) { |
| rc = (*srp->param_cb)(srp, modulus, modlen, generator, genlen); |
| if(!SRP_OK(rc)) |
| return rc; |
| } |
| |
| return (*srp->meth->params)(srp, modulus, modlen, generator, genlen, |
| salt, saltlen); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_authenticator(SRP * srp, const unsigned char * a, int alen) |
| { |
| return (*srp->meth->auth)(srp, a, alen); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_auth_password(SRP * srp, const char * password) |
| { |
| return (*srp->meth->passwd)(srp, (const unsigned char *)password, |
| strlen(password)); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_set_auth_password_raw(SRP * srp, |
| const unsigned char * password, int passlen) |
| { |
| return (*srp->meth->passwd)(srp, password, passlen); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_gen_pub(SRP * srp, cstr ** result) |
| { |
| return (*srp->meth->genpub)(srp, result); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_add_ex_data(SRP * srp, const unsigned char * data, int datalen) |
| { |
| cstr_appendn(srp->ex_data, (const char*)data, datalen); |
| return SRP_SUCCESS; |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_compute_key(SRP * srp, cstr ** result, |
| const unsigned char * pubkey, int pubkeylen) |
| { |
| return (*srp->meth->key)(srp, result, pubkey, pubkeylen); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_verify(SRP * srp, const unsigned char * proof, int prooflen) |
| { |
| return (*srp->meth->verify)(srp, proof, prooflen); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_respond(SRP * srp, cstr ** proof) |
| { |
| return (*srp->meth->respond)(srp, proof); |
| } |
| |
| _TYPE( SRP_RESULT ) |
| SRP_use_engine(const char * engine) |
| { |
| if(BigIntegerOK(BigIntegerUseEngine(engine))) |
| return SRP_SUCCESS; |
| else |
| return SRP_ERROR; |
| } |