blob: b1d46af5f39a3413215f1306750ec01f46d635ba [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.
*/
#ifndef _SRP_H_
#define _SRP_H_
#include "cstr.h"
#include "srp_aux.h"
#ifdef __cplusplus
extern "C" {
#endif
/* SRP library version identification */
#define SRP_VERSION_MAJOR 2
#define SRP_VERSION_MINOR 0
#define SRP_VERSION_PATCHLEVEL 1
typedef int SRP_RESULT;
/* Returned codes for SRP API functions */
#define SRP_OK(v) ((v) == SRP_SUCCESS)
#define SRP_SUCCESS 0
#define SRP_ERROR -1
/* Set the minimum number of bits acceptable in an SRP modulus */
#define SRP_DEFAULT_MIN_BITS 512
_TYPE( SRP_RESULT ) SRP_set_modulus_min_bits P((int minbits));
_TYPE( int ) SRP_get_modulus_min_bits P((void));
/*
* Sets the "secret size callback" function.
* This function is called with the modulus size in bits,
* and returns the size of the secret exponent in bits.
* The default function always returns 256 bits.
*/
typedef int (_CDECL * SRP_SECRET_BITS_CB)(int modsize);
_TYPE( SRP_RESULT ) SRP_set_secret_bits_cb P((SRP_SECRET_BITS_CB cb));
_TYPE( int ) SRP_get_secret_bits P((int modsize));
typedef struct srp_st SRP;
#if 0
/* Server Lookup API */
typedef struct srp_server_lu_st SRP_SERVER_LOOKUP;
typedef struct srp_s_lu_meth_st {
const char * name;
SRP_RESULT (_CDECL * init)(SRP_SERVER_LOOKUP * slu);
SRP_RESULT (_CDECL * finish)(SRP_SERVER_LOOKUP * slu);
SRP_RESULT (_CDECL * lookup)(SRP_SERVER_LOOKUP * slu, SRP * srp, cstr * username);
void * meth_data;
} SRP_SERVER_LOOKUP_METHOD;
struct srp_server_lu_st {
SRP_SERVER_LOOKUP_METHOD * meth;
void * data;
};
/*
* The Server Lookup API deals with the server-side issue of
* mapping usernames to verifiers. Given a username, a lookup
* mechanism needs to provide parameters (N, g), salt (s), and
* password verifier (v) for that user.
*
* A SRP_SERVER_LOOKUP_METHOD describes the general mechanism
* for performing lookups (e.g. files, LDAP, database, etc.)
* A SRP_SERVER_LOOKUP is an active "object" that is actually
* called to do lookups.
*/
_TYPE( SRP_SERVER_LOOKUP * )
SRP_SERVER_LOOKUP_new P((SRP_SERVER_LOOKUP_METHOD * meth));
_TYPE( SRP_RESULT ) SRP_SERVER_LOOKUP_free P((SRP_SERVER_LOOKUP * slu));
_TYPE( SRP_RESULT ) SRP_SERVER_do_lookup P((SRP_SERVER_LOOKUP * slu,
SRP * srp, cstr * username));
/*
* SRP_SERVER_system_lookup supercedes SRP_server_init_user.
*/
_TYPE( SRP_SERVER_LOOKUP * ) SRP_SERVER_system_lookup P((void));
#endif
/*
* Client Parameter Verification API
*
* This callback is called from the SRP client when the
* parameters (modulus and generator) are set. The callback
* should return SRP_SUCCESS if the parameters are okay,
* otherwise some error code to indicate that the parameters
* should be rejected.
*/
typedef SRP_RESULT (_CDECL * SRP_CLIENT_PARAM_VERIFY_CB)(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
#if 0
/* The default parameter verifier function */
_TYPE( SRP_RESULT ) SRP_CLIENT_default_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
/* A parameter verifier that only accepts builtin params (no prime test) */
_TYPE( SRP_RESULT ) SRP_CLIENT_builtin_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
/* The "classic" parameter verifier that accepts either builtin params
* immediately, and performs safe-prime tests on N and primitive-root
* tests on g otherwise. SECURITY WARNING: This may allow for certain
* attacks based on "trapdoor" moduli, so this is not recommended. */
_TYPE( SRP_RESULT ) SRP_CLIENT_compat_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
#endif
/*
* Main SRP API - SRP and SRP_METHOD
*/
/* SRP method definitions */
typedef struct srp_meth_st {
const char * name;
SRP_RESULT (_CDECL * init)(SRP * srp);
SRP_RESULT (_CDECL * finish)(SRP * srp);
SRP_RESULT (_CDECL * params)(SRP * srp,
const unsigned char * modulus, int modlen,
const unsigned char * generator, int genlen,
const unsigned char * salt, int saltlen);
SRP_RESULT (_CDECL * auth)(SRP * srp, const unsigned char * a, int alen);
SRP_RESULT (_CDECL * passwd)(SRP * srp,
const unsigned char * pass, int passlen);
SRP_RESULT (_CDECL * genpub)(SRP * srp, cstr ** result);
SRP_RESULT (_CDECL * key)(SRP * srp, cstr ** result,
const unsigned char * pubkey, int pubkeylen);
SRP_RESULT (_CDECL * verify)(SRP * srp,
const unsigned char * proof, int prooflen);
SRP_RESULT (_CDECL * respond)(SRP * srp, cstr ** proof);
void * data;
} SRP_METHOD;
/* Magic numbers for the SRP context header */
#define SRP_MAGIC_CLIENT 12
#define SRP_MAGIC_SERVER 28
/* Flag bits for SRP struct */
#define SRP_FLAG_MOD_ACCEL 0x1 /* accelerate modexp operations */
#define SRP_FLAG_LEFT_PAD 0x2 /* left-pad to length-of-N inside hashes */
/*
* A hybrid structure that represents either client or server state.
*/
struct srp_st {
int magic; /* To distinguish client from server (and for sanity) */
int flags;
cstr * username;
BigInteger modulus;
BigInteger generator;
cstr * salt;
BigInteger verifier;
BigInteger password;
BigInteger pubkey;
BigInteger secret;
BigInteger u;
BigInteger key;
cstr * ex_data;
SRP_METHOD * meth;
void * meth_data;
BigIntegerCtx bctx; /* to cache temporaries if available */
BigIntegerModAccel accel; /* to accelerate modexp if available */
SRP_CLIENT_PARAM_VERIFY_CB param_cb; /* to verify params */
//SRP_SERVER_LOOKUP * slu; /* to look up users */
};
/*
* Global initialization/de-initialization functions.
* Call SRP_initialize_library before using the library,
* and SRP_finalize_library when done.
*/
_TYPE( SRP_RESULT ) SRP_initialize_library();
_TYPE( SRP_RESULT ) SRP_finalize_library();
/*
* SRP_new() creates a new SRP context object -
* the method determines which "sense" (client or server)
* the object operates in. SRP_free() frees it.
* (See RFC2945 method definitions below.)
*/
_TYPE( SRP * ) SRP_new P((SRP_METHOD * meth));
_TYPE( SRP_RESULT ) SRP_free P((SRP * srp));
#if 0
/*
* Use the supplied lookup object to look up user parameters and
* password verifier. The lookup function gets called during
* SRP_set_username/SRP_set_user_raw below. Using this function
* means that the server can avoid calling SRP_set_params and
* SRP_set_authenticator, since the lookup function handles that
* internally.
*/
_TYPE( SRP_RESULT ) SRP_set_server_lookup P((SRP * srp,
SRP_SERVER_LOOKUP * lookup));
#endif
/*
* Use the supplied callback function to verify parameters
* (modulus, generator) given to the client.
*/
_TYPE( SRP_RESULT )
SRP_set_client_param_verify_cb P((SRP * srp,
SRP_CLIENT_PARAM_VERIFY_CB cb));
/*
* Both client and server must call both SRP_set_username and
* SRP_set_params, in that order, before calling anything else.
* SRP_set_user_raw is an alternative to SRP_set_username that
* accepts an arbitrary length-bounded octet string as input.
*/
_TYPE( SRP_RESULT ) SRP_set_username P((SRP * srp, const char * username));
_TYPE( SRP_RESULT ) SRP_set_user_raw P((SRP * srp, const unsigned char * user,
int userlen));
_TYPE( SRP_RESULT )
SRP_set_params P((SRP * srp,
const unsigned char * modulus, int modlen,
const unsigned char * generator, int genlen,
const unsigned char * salt, int saltlen));
/*
* On the client, SRP_set_authenticator, SRP_gen_exp, and
* SRP_add_ex_data can be called in any order.
* On the server, SRP_set_authenticator must come first,
* followed by SRP_gen_exp and SRP_add_ex_data in either order.
*/
/*
* The authenticator is the secret possessed by either side.
* For the server, this is the bigendian verifier, as an octet string.
* For the client, this is the bigendian raw secret, as an octet string.
* The server's authenticator must be the generator raised to the power
* of the client's raw secret modulo the common modulus for authentication
* to succeed.
*
* SRP_set_auth_password computes the authenticator from a plaintext
* password and then calls SRP_set_authenticator automatically. This is
* usually used on the client side, while the server usually uses
* SRP_set_authenticator (since it doesn't know the plaintext password).
*/
_TYPE( SRP_RESULT )
SRP_set_authenticator P((SRP * srp, const unsigned char * a, int alen));
_TYPE( SRP_RESULT )
SRP_set_auth_password P((SRP * srp, const char * password));
_TYPE( SRP_RESULT )
SRP_set_auth_password_raw P((SRP * srp,
const unsigned char * password,
int passlen));
/*
* SRP_gen_pub generates the random exponential residue to send
* to the other side. If using SRP-3/RFC2945, the server must
* withhold its result until it receives the client's number.
* If using SRP-6, the server can send its value immediately
* without waiting for the client.
*
* If "result" points to a NULL pointer, a new cstr object will be
* created to hold the result, and "result" will point to it.
* If "result" points to a non-NULL cstr pointer, the result will be
* placed there.
* If "result" itself is NULL, no result will be returned,
* although the big integer value will still be available
* through srp->pubkey in the SRP struct.
*/
_TYPE( SRP_RESULT ) SRP_gen_pub P((SRP * srp, cstr ** result));
/*
* Append the data to the extra data segment. Authentication will
* not succeed unless both sides add precisely the same data in
* the same order.
*/
_TYPE( SRP_RESULT ) SRP_add_ex_data P((SRP * srp, const unsigned char * data,
int datalen));
/*
* SRP_compute_key must be called after the previous three methods.
*/
_TYPE( SRP_RESULT ) SRP_compute_key P((SRP * srp, cstr ** result,
const unsigned char * pubkey,
int pubkeylen));
/*
* On the client, call SRP_respond first to get the response to send
* to the server, and call SRP_verify to verify the server's response.
* On the server, call SRP_verify first to verify the client's response,
* and call SRP_respond ONLY if verification succeeds.
*
* It is an error to call SRP_respond with a NULL pointer.
*/
_TYPE( SRP_RESULT ) SRP_verify P((SRP * srp,
const unsigned char * proof, int prooflen));
_TYPE( SRP_RESULT ) SRP_respond P((SRP * srp, cstr ** response));
/* RFC2945-style SRP authentication */
#define RFC2945_KEY_LEN 40 /* length of session key (bytes) */
#define RFC2945_RESP_LEN 20 /* length of proof hashes (bytes) */
/*
* RFC2945-style SRP authentication methods. Use these like:
* SRP * srp = SRP_new(SRP_RFC2945_client_method());
*/
_TYPE( SRP_METHOD * ) SRP_RFC2945_client_method P((void));
_TYPE( SRP_METHOD * ) SRP_RFC2945_server_method P((void));
/*
* SRP-6 and SRP-6a authentication methods.
* SRP-6a is recommended for better resistance to 2-for-1 attacks.
*/
_TYPE( SRP_METHOD * ) SRP6_client_method P((void));
_TYPE( SRP_METHOD * ) SRP6_server_method P((void));
_TYPE( SRP_METHOD * ) SRP6a_client_method P((void));
_TYPE( SRP_METHOD * ) SRP6a_server_method P((void));
_TYPE( SRP_METHOD * ) SRP6a_sha512_client_method P((void));
/*
* Convenience function - SRP_server_init_user
* Looks up the username from the system EPS configuration and calls
* SRP_set_username, SRP_set_params, and SRP_set_authenticator to
* initialize server state for that user.
*
* This is deprecated in favor of SRP_SERVER_system_lookup() and
* the Server Lookup API.
*/
_TYPE( SRP_RESULT ) SRP_server_init_user P((SRP * srp, const char * username));
/*
* Use the named engine for acceleration.
*/
_TYPE( SRP_RESULT ) SRP_use_engine P((const char * engine));
#ifdef __cplusplus
}
#endif
#endif /* _SRP_H_ */