1/* 2 * oath.h - header file for liboath 3 * Copyright (C) 2009-2016 Simon Josefsson 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public License 7 * as published by the Free Software Foundation; either version 2.1 of 8 * the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * 02110-1301 USA 19 * 20 */ 21 22#ifndef OATH_H 23#define OATH_H 24 25#ifndef OATHAPI 26# if defined LIBOATH_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY 27# define OATHAPI __attribute__((__visibility__("default"))) 28# elif defined LIBOATH_BUILDING && defined _MSC_VER && ! defined LIBOATH_STATIC 29# define OATHAPI __declspec(dllexport) 30# elif defined _MSC_VER && ! defined LIBOATH_STATIC 31# define OATHAPI __declspec(dllimport) 32# else 33# define OATHAPI 34# endif 35#endif 36 37#include <stdbool.h> /* For bool. */ 38#include <stdint.h> /* For uint64_t, SIZE_MAX. */ 39#include <string.h> /* For size_t.t */ 40#include <time.h> /* For time_t. */ 41 42# ifdef __cplusplus 43extern "C" 44{ 45# endif 46 47/** 48 * OATH_VERSION 49 * 50 * Pre-processor symbol with a string that describe the header file 51 * version number. Used together with oath_check_version() to verify 52 * header file and run-time library consistency. 53 */ 54#define OATH_VERSION "@VERSION@" 55 56/** 57 * OATH_VERSION_NUMBER 58 * 59 * Pre-processor symbol with a hexadecimal value describing the header 60 * file version number. For example, when the header version is 1.2.3 61 * this symbol will have the value 0x01020300. The last two digits 62 * are only used between public releases, and will otherwise be 00. 63 */ 64#define OATH_VERSION_NUMBER @VERSION_NUMBER@ 65 66/** 67 * oath_rc: 68 * @OATH_OK: Successful return 69 * @OATH_CRYPTO_ERROR: Internal error in crypto functions 70 * @OATH_INVALID_DIGITS: Unsupported number of OTP digits 71 * @OATH_PRINTF_ERROR: Error from system printf call 72 * @OATH_INVALID_HEX: Hex string is invalid 73 * @OATH_TOO_SMALL_BUFFER: The output buffer is too small 74 * @OATH_INVALID_OTP: The OTP is not valid 75 * @OATH_REPLAYED_OTP: The OTP has been replayed 76 * @OATH_BAD_PASSWORD: The password does not match 77 * @OATH_INVALID_COUNTER: The counter value is corrupt 78 * @OATH_INVALID_TIMESTAMP: The timestamp is corrupt 79 * @OATH_NO_SUCH_FILE: The supplied filename does not exist 80 * @OATH_UNKNOWN_USER: Cannot find information about user 81 * @OATH_FILE_SEEK_ERROR: System error when seeking in file 82 * @OATH_FILE_CREATE_ERROR: System error when creating file 83 * @OATH_FILE_LOCK_ERROR: System error when locking file 84 * @OATH_FILE_RENAME_ERROR: System error when renaming file 85 * @OATH_FILE_UNLINK_ERROR: System error when removing file 86 * @OATH_TIME_ERROR: System error for time manipulation 87 * @OATH_STRCMP_ERROR: A strcmp callback returned an error 88 * @OATH_INVALID_BASE32: Base32 string is invalid 89 * @OATH_BASE32_OVERFLOW: Base32 encoding would overflow 90 * @OATH_MALLOC_ERROR: Memory allocation failed 91 * @OATH_FILE_FLUSH_ERROR: System error when flushing file buffer 92 * @OATH_FILE_SYNC_ERROR: System error when syncing file to disk 93 * @OATH_FILE_CLOSE_ERROR: System error when closing file 94 * @OATH_LAST_ERROR: Meta-error indicating the last error code, for use 95 * when iterating over all error codes or similar. 96 * 97 * Return codes for OATH functions. All return codes are negative 98 * except for the successful code %OATH_OK which are guaranteed to be 99 * 0. Positive values are reserved for non-error return codes. 100 * 101 * Note that the #oath_rc enumeration may be extended at a later date 102 * to include new return codes. 103 */ 104typedef enum 105{ 106 OATH_OK = 0, 107 OATH_CRYPTO_ERROR = -1, 108 OATH_INVALID_DIGITS = -2, 109 OATH_PRINTF_ERROR = -3, 110 OATH_INVALID_HEX = -4, 111 OATH_TOO_SMALL_BUFFER = -5, 112 OATH_INVALID_OTP = -6, 113 OATH_REPLAYED_OTP = -7, 114 OATH_BAD_PASSWORD = -8, 115 OATH_INVALID_COUNTER = -9, 116 OATH_INVALID_TIMESTAMP = -10, 117 OATH_NO_SUCH_FILE = -11, 118 OATH_UNKNOWN_USER = -12, 119 OATH_FILE_SEEK_ERROR = -13, 120 OATH_FILE_CREATE_ERROR = -14, 121 OATH_FILE_LOCK_ERROR = -15, 122 OATH_FILE_RENAME_ERROR = -16, 123 OATH_FILE_UNLINK_ERROR = -17, 124 OATH_TIME_ERROR = -18, 125 OATH_STRCMP_ERROR = -19, 126 OATH_INVALID_BASE32 = -20, 127 OATH_BASE32_OVERFLOW = -21, 128 OATH_MALLOC_ERROR = -22, 129 OATH_FILE_FLUSH_ERROR = -23, 130 OATH_FILE_SYNC_ERROR = -24, 131 OATH_FILE_CLOSE_ERROR = -25, 132 /* When adding anything here, update OATH_LAST_ERROR, errors.c 133 and tests/tst_errors.c. */ 134 OATH_LAST_ERROR = -25 135} oath_rc; 136 137/* Global */ 138 139extern OATHAPI int oath_init (void); 140extern OATHAPI int oath_done (void); 141 142extern OATHAPI const char *oath_check_version (const char *req_version); 143 144/* Error handling */ 145 146extern OATHAPI const char *oath_strerror (int err); 147extern OATHAPI const char *oath_strerror_name (int err); 148 149/* Data encoding */ 150 151extern OATHAPI int oath_hex2bin (const char *hexstr, 152 char *binstr, size_t * binlen); 153extern OATHAPI void oath_bin2hex (const char *binstr, size_t binlen, 154 char *hexstr); 155 156extern OATHAPI int oath_base32_decode (const char *in, size_t inlen, 157 char **out, size_t *outlen); 158extern OATHAPI int oath_base32_encode (const char *in, size_t inlen, 159 char **out, size_t *outlen); 160 161/* HOTP */ 162 163#define OATH_HOTP_LENGTH(digits, checksum) (digits + (checksum ? 1 : 0)) 164 165#define OATH_HOTP_DYNAMIC_TRUNCATION SIZE_MAX 166 167extern OATHAPI int 168oath_hotp_generate (const char *secret, 169 size_t secret_length, 170 uint64_t moving_factor, 171 unsigned digits, 172 bool add_checksum, 173 size_t truncation_offset, 174 char *output_otp); 175 176 177extern OATHAPI int 178oath_hotp_validate (const char *secret, 179 size_t secret_length, 180 uint64_t start_moving_factor, 181 size_t window, const char *otp); 182 183/** 184 * oath_validate_strcmp_function: 185 * @handle: caller handle as passed to oath_hotp_validate_callback() 186 * @test_otp: OTP to match against. 187 * 188 * Prototype of strcmp-like function that will be called by 189 * oath_hotp_validate_callback() or oath_totp_validate_callback() to 190 * validate OTPs. 191 * 192 * The function should be similar to strcmp in that it return 0 only 193 * on matches. It differs by permitting use of negative return codes 194 * as indication of internal failures in the callback. Positive 195 * values indicate OTP mismatch. 196 * 197 * This callback interface is useful when you cannot compare OTPs 198 * directly using normal strcmp, but instead for example only have a 199 * hashed OTP. You would then typically pass in the hashed OTP in the 200 * @strcmp_handle and let your implementation of @oath_strcmp hash the 201 * test_otp OTP using the same hash, and then compare the results. 202 * 203 * Return value: 0 if and only if @test_otp is identical to the OTP to 204 * be validated. Negative value if an internal failure occurs. 205 * Positive value if the test_otp simply doesn't match. 206 * 207 * Since: 1.6.0 208 **/ 209typedef int (*oath_validate_strcmp_function) (void *handle, 210 const char *test_otp); 211 212/* For backwards compatibility with 1.4.x. */ 213#define oath_hotp_validate_strcmp_function oath_validate_strcmp_function 214 215extern OATHAPI int 216oath_hotp_validate_callback (const char *secret, 217 size_t secret_length, 218 uint64_t start_moving_factor, 219 size_t window, 220 unsigned digits, 221 oath_validate_strcmp_function strcmp_otp, 222 void *strcmp_handle); 223 224/* TOTP */ 225 226#define OATH_TOTP_DEFAULT_TIME_STEP_SIZE 30 227#define OATH_TOTP_DEFAULT_START_TIME ((time_t) 0) 228 229/** 230 * oath_totp_flags: 231 * @OATH_TOTP_HMAC_SHA256: Use HMAC-SHA256 instead of HMAC-SHA1. 232 * @OATH_TOTP_HMAC_SHA512: Use HMAC-SHA512 instead of HMAC-SHA1. 233 * 234 * Flags for oath_totp_generate2(). 235 * 236 * Since: 2.6.0 237 */ 238typedef enum { 239 OATH_TOTP_HMAC_SHA256 = 1, 240 OATH_TOTP_HMAC_SHA512 = 2 241} oath_totp_flags; 242 243extern OATHAPI int 244oath_totp_generate (const char *secret, 245 size_t secret_length, 246 time_t now, 247 unsigned time_step_size, 248 time_t start_offset, 249 unsigned digits, char *output_otp); 250 251extern OATHAPI int 252oath_totp_generate2 (const char *secret, 253 size_t secret_length, 254 time_t now, 255 unsigned time_step_size, 256 time_t start_offset, 257 unsigned digits, 258 int flags, 259 char *output_otp); 260 261extern OATHAPI int 262oath_totp_validate (const char *secret, 263 size_t secret_length, 264 time_t now, 265 unsigned time_step_size, 266 time_t start_offset, 267 size_t window, const char *otp); 268 269extern OATHAPI int 270oath_totp_validate_callback (const char *secret, 271 size_t secret_length, 272 time_t now, 273 unsigned time_step_size, 274 time_t start_offset, 275 unsigned digits, 276 size_t window, 277 oath_validate_strcmp_function strcmp_otp, 278 void *strcmp_handle); 279 280extern OATHAPI int 281oath_totp_validate2 (const char *secret, 282 size_t secret_length, 283 time_t now, 284 unsigned time_step_size, 285 time_t start_offset, 286 size_t window, 287 int *otp_pos, 288 const char *otp); 289 290extern OATHAPI int 291oath_totp_validate2_callback (const char *secret, 292 size_t secret_length, 293 time_t now, 294 unsigned time_step_size, 295 time_t start_offset, 296 unsigned digits, 297 size_t window, 298 int *otp_pos, 299 oath_validate_strcmp_function strcmp_otp, 300 void *strcmp_handle); 301 302extern OATHAPI int 303oath_totp_validate3 (const char *secret, 304 size_t secret_length, 305 time_t now, 306 unsigned time_step_size, 307 time_t start_offset, 308 size_t window, 309 int *otp_pos, 310 uint64_t *otp_counter, 311 const char *otp); 312 313extern OATHAPI int 314oath_totp_validate3_callback (const char *secret, 315 size_t secret_length, 316 time_t now, 317 unsigned time_step_size, 318 time_t start_offset, 319 unsigned digits, 320 size_t window, 321 int *otp_pos, 322 uint64_t *otp_counter, 323 oath_validate_strcmp_function strcmp_otp, 324 void *strcmp_handle); 325 326extern OATHAPI int 327oath_totp_validate4 (const char *secret, 328 size_t secret_length, 329 time_t now, 330 unsigned time_step_size, 331 time_t start_offset, 332 size_t window, 333 int *otp_pos, 334 uint64_t *otp_counter, 335 int flags, 336 const char *otp); 337 338extern OATHAPI int 339oath_totp_validate4_callback (const char *secret, 340 size_t secret_length, 341 time_t now, 342 unsigned time_step_size, 343 time_t start_offset, 344 unsigned digits, 345 size_t window, 346 int *otp_pos, 347 uint64_t *otp_counter, 348 int flags, 349 oath_validate_strcmp_function strcmp_otp, 350 void *strcmp_handle); 351 352/* Usersfile */ 353 354extern OATHAPI int 355oath_authenticate_usersfile (const char *usersfile, 356 const char *username, 357 const char *otp, 358 size_t window, 359 const char *passwd, 360 time_t * last_otp); 361 362# ifdef __cplusplus 363} 364# endif 365 366#endif /* OATH_H */ 367