| /* |
| * 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_ */ |