1/* 2 * Copyright (c) 1997-1999 The Stanford SRP Authentication Project 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL, 21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER 22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF 23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT 24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 * 26 * In addition, the following conditions apply: 27 * 28 * 1. Any software that incorporates the SRP authentication technology 29 * must display the following acknowlegment: 30 * "This product uses the 'Secure Remote Password' cryptographic 31 * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)." 32 * 33 * 2. Any software that incorporates all or part of the SRP distribution 34 * itself must also display the following acknowledgment: 35 * "This product includes software developed by Tom Wu and Eugene 36 * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)." 37 * 38 * 3. Redistributions in source or binary form must retain an intact copy 39 * of this copyright notice and list of conditions. 40 */ 41 42#ifndef T_PWD_H 43#define T_PWD_H 44 45#ifndef P 46#if defined (__STDC__) || defined (__cplusplus) 47#define P(x) x 48#else 49#define P(x) () 50#endif 51#endif 52 53/* For building dynamic link libraries under windows, windows NT 54 * using MSVC1.5 or MSVC2.0 55 */ 56 57#ifndef _DLLDECL 58#define _DLLDECL 59 60#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */ 61#define _MSVC15EXPORT _export 62#define _MSVC20EXPORT 63#define _DLLAPI _export _pascal 64#define _TYPE(a) a _MSVC15EXPORT 65#define DLLEXPORT 1 66 67#elif MSVC20 68#define _MSVC15EXPORT 69#define _MSVC20EXPORT _declspec(dllexport) 70#define _DLLAPI 71#define _TYPE(a) _MSVC20EXPORT a 72#define DLLEXPORT 1 73 74#else /* Default, non-dll. Use this for Unix or DOS */ 75#define _MSVC15DEXPORT 76#define _MSVC20EXPORT 77#define _DLLAPI 78#define _TYPE(a) a 79#endif 80#endif 81 82#define MAXPARAMBITS 2048 83#define MAXPARAMLEN ((MAXPARAMBITS + 7) / 8) 84#define MAXB64PARAMLEN ((MAXPARAMBITS + 5) / 6 + 1) 85#define MAXHEXPARAMLEN ((MAXPARAMBITS + 3) / 4 + 1) 86#define MAXOCTPARAMLEN ((MAXPARAMBITS + 2) / 3 + 1) 87 88#define MAXUSERLEN 32 89#define MAXSALTLEN 32 90#define MAXB64SALTLEN 44 /* 256 bits in b64 + null */ 91#define SALTLEN 10 /* Normally 80 bits */ 92 93#define RESPONSE_LEN 20 /* 160-bit proof hashes */ 94#define SESSION_KEY_LEN (2 * RESPONSE_LEN) /* 320-bit session key */ 95 96#define DEFAULT_PASSWD "tpasswd" 97 98struct t_num { /* Standard byte-oriented integer representation */ 99 int len; 100 unsigned char * data; 101}; 102 103struct t_preconf { /* Structure returned by t_getpreparam() */ 104 char * mod_b64; 105 char * gen_b64; 106 char * comment; 107 108 struct t_num modulus; 109 struct t_num generator; 110}; 111 112/* 113 * The built-in (known good) parameters access routines 114 * 115 * "t_getprecount" returns the number of precompiled parameter sets. 116 * "t_getpreparam" returns the indicated parameter set. 117 * Memory is statically allocated - callers need not perform any memory mgmt. 118 */ 119_TYPE( int ) t_getprecount(); 120_TYPE( struct t_preconf * ) t_getpreparam P((int)); 121 122struct t_confent { /* One configuration file entry (index, N, g) */ 123 int index; 124 struct t_num modulus; 125 struct t_num generator; 126}; 127 128struct t_conf { /* An open configuration file */ 129 FILE * instream; 130 char close_on_exit; 131 unsigned char modbuf[MAXPARAMLEN]; 132 unsigned char genbuf[MAXPARAMLEN]; 133 struct t_confent tcbuf; 134}; 135 136/* 137 * The configuration file routines are designed along the lines of the 138 * "getpw" functions in the standard C library. 139 * 140 * "t_openconf" accepts a stdio stream and interprets it as a config file. 141 * "t_openconfbyname" accepts a filename and does the same thing. 142 * "t_closeconf" closes the config file. 143 * "t_getconfent" fetches the next sequential configuration entry. 144 * "t_getconfbyindex" fetches the configuration entry whose index 145 * matches the one supplied, or NULL if one can't be found. 146 * "t_getconflast" fetches the last configuration entry in the file. 147 * "t_makeconfent" generates a set of configuration entry parameters 148 * randomly. 149 * "t_newconfent" returns an empty configuration entry. 150 * "t_cmpconfent" compares two configuration entries a la strcmp. 151 * "t_checkconfent" verifies that a set of configuration parameters 152 * are suitable. N must be prime and should be a safe prime. 153 * "t_putconfent" writes a configuration entry to a stream. 154 */ 155_TYPE( struct t_conf * ) t_openconf P((FILE *)); 156_TYPE( struct t_conf * ) t_openconfbyname P((const char *)); 157_TYPE( void ) t_closeconf P((struct t_conf *)); 158_TYPE( void ) t_rewindconf P((struct t_conf *)); 159_TYPE( struct t_confent * ) t_getconfent P((struct t_conf *)); 160_TYPE( struct t_confent * ) t_getconfbyindex P((struct t_conf *, int)); 161_TYPE( struct t_confent * ) t_getconflast P((struct t_conf *)); 162_TYPE( struct t_confent * ) t_makeconfent P((struct t_conf *, int)); 163_TYPE( struct t_confent * ) t_makeconfent_c P((struct t_conf *, int)); 164_TYPE( struct t_confent * ) t_newconfent P((struct t_conf *)); 165_TYPE( int ) t_cmpconfent P((const struct t_confent *, const struct t_confent *)); 166_TYPE( int ) t_checkconfent P((const struct t_confent *)); 167_TYPE( void ) t_putconfent P((const struct t_confent *, FILE *)); 168 169/* libc-style system conf file access */ 170_TYPE( struct t_confent *) gettcent(); 171_TYPE( struct t_confent *) gettcid P((int)); 172_TYPE( void ) settcent(); 173_TYPE( void ) endtcent(); 174 175#ifdef ENABLE_NSW 176extern struct t_confent * _gettcent(); 177extern struct t_confent * _gettcid P((int)); 178extern void _settcent(); 179extern void _endtcent(); 180#endif 181 182/* A hack to support '+'-style entries in the passwd file */ 183 184typedef enum fstate { 185 FILE_ONLY, /* Ordinary file, don't consult NIS ever */ 186 FILE_NIS, /* Currently accessing file, use NIS if encountered */ 187 IN_NIS, /* Currently in a '+' entry; use NIS for getXXent */ 188} FILE_STATE; 189 190struct t_pwent { /* A single password file entry */ 191 char * name; 192 struct t_num password; 193 struct t_num salt; 194 int index; 195}; 196 197struct t_pw { /* An open password file */ 198 FILE * instream; 199 char close_on_exit; 200 FILE_STATE state; 201 char userbuf[MAXUSERLEN]; 202 unsigned char pwbuf[MAXPARAMLEN]; 203 unsigned char saltbuf[SALTLEN]; 204 struct t_pwent pebuf; 205}; 206 207/* 208 * The password manipulation routines are patterned after the getpw* 209 * standard C library function calls. 210 * 211 * "t_openpw" reads a stream as if it were a password file. 212 * "t_openpwbyname" opens the named file as a password file. 213 * "t_closepw" closes an open password file. 214 * "t_rewindpw" starts the internal file pointer from the beginning 215 * of the password file. 216 * "t_getpwent" retrieves the next sequential password entry. 217 * "t_getpwbyname" looks up the password entry corresponding to the 218 * specified user. 219 * "t_makepwent" constructs a password entry from a username, password, 220 * numeric salt, and configuration entry. 221 * "t_putpwent" writes a password entry to a stream. 222 */ 223_TYPE( struct t_pw * ) t_openpw P((FILE *)); 224_TYPE( struct t_pw * ) t_openpwbyname P((const char *)); 225_TYPE( void ) t_closepw P((struct t_pw *)); 226_TYPE( void ) t_rewindpw P((struct t_pw *)); 227_TYPE( struct t_pwent * ) t_getpwent P((struct t_pw *)); 228_TYPE( struct t_pwent * ) t_getpwbyname P((struct t_pw *, const char *)); 229_TYPE( struct t_pwent * ) t_makepwent P((struct t_pw *, const char *, 230 const char *, const struct t_num *, 231 const struct t_confent *)); 232_TYPE( void ) t_putpwent P((const struct t_pwent *, FILE *)); 233 234struct t_passwd { 235 struct t_pwent tp; 236 struct t_confent tc; 237}; 238 239/* libc-style system password file access */ 240_TYPE( struct t_passwd * ) gettpent(); 241_TYPE( struct t_passwd * ) gettpnam P((const char *)); 242_TYPE( void ) settpent(); 243_TYPE( void ) endtpent(); 244 245#ifdef ENABLE_NSW 246extern struct t_passwd * _gettpent(); 247extern struct t_passwd * _gettpnam P((const char *)); 248extern void _settpent(); 249extern void _endtpent(); 250#endif 251 252/* 253 * Utility functions 254 * 255 * "t_verifypw" accepts a username and password, and checks against the 256 * system password file to see if the password for that user is correct. 257 * Returns > 0 if it is correct, 0 if not, and -1 if some error occurred 258 * (i.e. the user doesn't exist on the system). This is intended ONLY 259 * for local authentication; for remote authentication, look at the 260 * t_client and t_server source. (That's the whole point of SRP!) 261 * "t_changepw" modifies the specified file, substituting the given password 262 * entry for the one already in the file. If no matching entry is found, 263 * the new entry is simply appended to the file. 264 * "t_deletepw" removes the specified user from the specified file. 265 */ 266_TYPE( int ) t_verifypw P((const char *, const char *)); 267_TYPE( int ) t_changepw P((const char *, const struct t_pwent *)); 268_TYPE( int ) t_deletepw P((const char *, const char *)); 269 270/* Conversion utilities */ 271 272/* 273 * All these calls accept output as the first parameter. In the case of 274 * t_tohex and t_tob64, the last argument is the length of the byte-string 275 * input. 276 */ 277_TYPE( char * t_tohex ) P((char *, char *, unsigned)); 278_TYPE( int ) t_fromhex P((char *, char *)); 279_TYPE( char * ) t_tob64 P((char *, char *, unsigned)); 280_TYPE( int ) t_fromb64 P((char *, char *)); 281 282/* Miscellaneous utilities */ 283 284/* 285 * "t_random" is a cryptographic random number generator, which is seeded 286 * from various high-entropy sources and uses a one-way hash function 287 * in a feedback configuration. 288 * "t_sessionkey" is the interleaved hash used to generate session keys 289 * from a large integer. 290 * "t_getpass" reads a password from the terminal without echoing. 291 */ 292_TYPE( void ) t_random P((unsigned char *, unsigned)); 293_TYPE( void ) t_stronginitrand(); 294_TYPE( unsigned char * ) 295 t_sessionkey P((unsigned char *, unsigned char *, unsigned)); 296_TYPE( int ) t_getpass P((char *, unsigned, const char *)); 297 298/* 299 * Return value of t_checkprime: 300 * < 0 : not prime 301 * = 0 : prime, but not safe 302 * > 0 : safe 303 */ 304#define NUM_NOTPRIME -1 305#define NUM_NOTSAFE 0 306#define NUM_SAFE 1 307 308_TYPE( int ) t_checkprime P((const struct t_num *)); 309 310#endif 311