diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 1ba91e5..0c16cb2 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -63,6 +63,7 @@ OPENPAM_MAN = \ OATH_MAN = \ oath_key_alloc.3 \ + oath_key_create.3 \ oath_key_dummy.3 \ oath_key_free.3 \ $(NULL) diff --git a/include/security/oath.h b/include/security/oath.h index 861df94..84d5aa8 100644 --- a/include/security/oath.h +++ b/include/security/oath.h @@ -37,6 +37,8 @@ #include struct oath_key *oath_key_alloc(void); +struct oath_key *oath_key_create(const char *, enum oath_mode, + enum oath_hash, const char *, size_t); void oath_key_free(struct oath_key *); struct oath_key *oath_key_from_uri(const char *); struct oath_key *oath_key_from_file(const char *); diff --git a/lib/liboath/Makefile.am b/lib/liboath/Makefile.am index be2f2cb..461d333 100644 --- a/lib/liboath/Makefile.am +++ b/lib/liboath/Makefile.am @@ -10,6 +10,7 @@ liboath_la_SOURCES = \ oath_hotp.c \ oath_totp.c \ oath_key_alloc.c \ + oath_key_create.c \ oath_key_dummy.c \ oath_key_free.c \ oath_key.c diff --git a/lib/liboath/oath_key_create.c b/lib/liboath/oath_key_create.c new file mode 100644 index 0000000..1fcab74 --- /dev/null +++ b/lib/liboath/oath_key_create.c @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 2013 Universitetet i Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include + +/* + * OATH + * + * Creates an OATH key with the specified parameters + */ + +struct oath_key * +oath_key_create(const char *label, + enum oath_mode mode, enum oath_hash hash, + const char *keydata, size_t keylen) +{ + struct oath_key *key; + int fd, labellen; + + /* check label */ + if (label == NULL || + (labellen = strlen(label)) > OATH_MAX_LABELLEN) + return (NULL); + + /* check key length */ + if (keylen > OATH_MAX_KEYLEN || + (keydata != NULL && keylen == 0)) + return (NULL); + if (keylen == 0) + keylen = 160; + + /* check mode */ + switch (mode) { + case om_hotp: + case om_totp: + break; + default: + return (NULL); + } + + /* check hash */ + switch (hash) { + case oh_undef: + hash = oh_sha1; + break; + case oh_md5: + case oh_sha1: + case oh_sha256: + case oh_sha512: + break; + default: + return (NULL); + } + + /* allocate */ + if ((key = oath_key_alloc()) == NULL) + return (NULL); + + /* label */ + memcpy(key->label, label, labellen); + key->label[labellen] = 0; + key->labellen = labellen; + + /* mode and hash */ + key->mode = mode; + key->hash = hash; + + /* default parameters */ + key->digits = 6; + if (key->mode == om_totp) + key->timestep = 30; + + /* key */ + if (keydata == NULL) { + /* XXX generate random key */ + (void)(fd = 0); + } else { + memcpy(key->key, keydata, keylen); + } + key->keylen = keylen; + + return (key); +} + +/** + * The =oath_key_create function allocates and initializes an OATH key + * structure with the specified parameters. + * + * The =label parameter must point to a string describing the key. + * + * The =mode parameter indicates the OTP algorithm to use: + * + * ;om_hotp: + * RFC 4226 HOTP + * ;om_totp: + * RFC 6238 TOTP + * + * The =hash parameter indicates which hash algorithm to use: + * + * ;oh_md5: + * RFC 1321 MD5 + * ;oh_sha1: + * RFC 3174 SHA-1 + * ;oh_sha256: + * RFC 6234 SHA-256 + * ;oh_sha512: + * RFC 6234 SHA-512 + * + * If =hash is ;oh_undef, the default algorithm (SHA-1) is used. + * + * The =keydata parameter should point to a buffer containing the raw key + * to use. + * If =keydata is NULL, a key will be randomly generated. + * Note that the strength of the generated key is dependent on the + * strength of the operating system's pseudo-random number generator. + * + * The =keylen parameter specifies the length of the provided (or + * generated) key in bytes. + * Note that some OATH HOTP / TOTP implementations do not support key + * lengths that are not a multiple of 20 bits (5 bytes). + * If =keydata is NULL and =keylen is 0, a hardcoded default of 160 bits + * (20 bytes) is used. + * + * The following key parameters are set to hardcoded default values and + * can be changed after key creation: + * + * - For HOTP keys, the initial counter value is set to 0. + * - For TOTP keys, the timestep is set to 30 seconds. + * - For both HOTP and TOTP keys, the number of digits is set to 6. + * + * Keys created with =oath_key_create must be freed using =oath_key_free. + * + * >oath_key_alloc + * >oath_key_free + * + * AUTHOR UIO + */