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