blob: 74e1f981979247cfb893f041119c702d1a7e4b46 [file] [log] [blame]
/*
* 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;
}