From 9c999e0d3108f6efee34297e260dcee5a6f1f0e0 Mon Sep 17 00:00:00 2001 From: "David M. Syzdek" Date: Thu, 12 Jan 2023 15:30:06 -0900 Subject: libotputil: refactoring otputil_skey_code() --- include/otputil.h | 13 ++++++ lib/libotputil/lcore.c | 90 ++++++++++++++++++++++++++++++++++++++++++ lib/libotputil/lrfc1760-skey.c | 42 +++----------------- 3 files changed, 108 insertions(+), 37 deletions(-) diff --git a/include/otputil.h b/include/otputil.h index effb553..9e2f261 100644 --- a/include/otputil.h +++ b/include/otputil.h @@ -127,6 +127,11 @@ #define OTPUTIL_OPT_TOTP_TIME 0x0204 // (uint64_t *) current UNIX time #define OTPUTIL_OPT_TOTP_DIGITS 0x0205 // (int *) #define OTPUTIL_OPT_TOTP_HMAC 0x0206 // (int *) +// S/KEY options (RFC1760) +#define OTPUTIL_OPT_SKEY_PASS 0x0300 // (char *) +#define OTPUTIL_OPT_SKEY_SEQ 0x0301 // (int *) +#define OTPUTIL_OPT_SKEY_HASH 0x0302 // (int *) +#define OTPUTIL_OPT_SKEY_ENCODE 0x0303 // (int *) // OTP options (RFC2289) #define OTPUTIL_OPT_OTP_PASS 0x0400 // (char *) #define OTPUTIL_OPT_OTP_SEED 0x0401 // (char *) @@ -152,9 +157,11 @@ #define OTPUTIL_METH_RFC4226 0x0001 #define OTPUTIL_METH_RFC6238 0x0002 +#define OTPUTIL_METH_RFC1760 0x0003 #define OTPUTIL_METH_RFC2289 0x0004 #define OTPUTIL_METH_HOTP OTPUTIL_METH_RFC4226 #define OTPUTIL_METH_OTP OTPUTIL_METH_RFC2289 +#define OTPUTIL_METH_SKEY OTPUTIL_METH_RFC1760 #define OTPUTIL_METH_TOTP OTPUTIL_METH_RFC6238 @@ -169,6 +176,11 @@ #define OTPUTIL_DFLT_OTP_SEQ 1 #define OTPUTIL_DFLT_OTP_HASH OTPUTIL_MD_SHA1 #define OTPUTIL_DFLT_OTP_ENCODE OTPUTIL_ENC_SIXWORD +// S/KEY defaults +#define OTPUTIL_DFLT_SKEY_PASS NULL +#define OTPUTIL_DFLT_SKEY_SEQ 1 +#define OTPUTIL_DFLT_SKEY_HASH OTPUTIL_MD_MD4 +#define OTPUTIL_DFLT_SKEY_ENCODE OTPUTIL_ENC_SIXWORD // TOTP defaults #define OTPUTIL_DFLT_TOTP_T0 0ULL #define OTPUTIL_DFLT_TOTP_X 30ULL @@ -417,6 +429,7 @@ _OTPUTIL_F int otputil_skey_code( const char * skey_pass, int skey_seq, + int skey_hash, uint64_t * skey_resultp ); diff --git a/lib/libotputil/lcore.c b/lib/libotputil/lcore.c index 35c4e91..5ccc143 100644 --- a/lib/libotputil/lcore.c +++ b/lib/libotputil/lcore.c @@ -90,6 +90,11 @@ const otputil_t otputil_const_defaults = .otp_seq = OTPUTIL_DFLT_OTP_SEQ, .otp_hash = OTPUTIL_DFLT_OTP_HASH, .otp_encoding = OTPUTIL_DFLT_OTP_ENCODE, + // S/KEY options + .skey_pass = OTPUTIL_DFLT_SKEY_PASS, + .skey_seq = OTPUTIL_DFLT_SKEY_SEQ, + .skey_hash = OTPUTIL_DFLT_SKEY_HASH, + .skey_encoding = OTPUTIL_DFLT_SKEY_ENCODE, // TOTP options .totp_k = &otputil_const_defaults_k, .totp_time = OTPUTIL_DFLT_TOTP_TIME, @@ -117,6 +122,11 @@ otputil_t otputil_defaults = .otp_seq = OTPUTIL_DFLT_OTP_SEQ, .otp_hash = OTPUTIL_DFLT_OTP_HASH, .otp_encoding = OTPUTIL_DFLT_OTP_ENCODE, + // S/KEY options + .skey_pass = OTPUTIL_DFLT_SKEY_PASS, + .skey_seq = OTPUTIL_DFLT_SKEY_SEQ, + .skey_hash = OTPUTIL_DFLT_SKEY_HASH, + .skey_encoding = OTPUTIL_DFLT_SKEY_ENCODE, // TOTP options .totp_k = NULL, .totp_time = OTPUTIL_DFLT_TOTP_TIME, @@ -261,6 +271,29 @@ otputil_get_param( *((int *)outvalue) = (int)tud->otp_seq; return(OTPUTIL_SUCCESS); + ///////////////////////////// + // S/KEY options (RFC1760) // + ///////////////////////////// + + case OTPUTIL_OPT_SKEY_ENCODE: + *((int *)outvalue) = (int)tud->skey_encoding; + return(OTPUTIL_SUCCESS); + + case OTPUTIL_OPT_SKEY_HASH: + *((int *)outvalue) = (int)tud->skey_hash; + return(OTPUTIL_SUCCESS); + + case OTPUTIL_OPT_SKEY_PASS: + *((char **)outvalue) = NULL; + if ((tud->skey_pass)) + if (( *((char **)outvalue) = bindle_strdup(tud->skey_pass)) == NULL) + return(OTPUTIL_ENOMEM); + return(OTPUTIL_SUCCESS); + + case OTPUTIL_OPT_SKEY_SEQ: + *((int *)outvalue) = (int)tud->skey_seq; + return(OTPUTIL_SUCCESS); + //////////////////////////// // TOTP options (RFC6238) // //////////////////////////// @@ -383,6 +416,28 @@ otputil_initialize( return(rc); }; + // defaults for S/KEY options + if ((rc = otputil_set_param(tud, OTPUTIL_OPT_SKEY_ENCODE, NULL)) != OTPUTIL_SUCCESS) + { + otputil_free(tud); + return(rc); + }; + if ((rc = otputil_set_param(tud, OTPUTIL_OPT_SKEY_HASH, NULL)) != OTPUTIL_SUCCESS) + { + otputil_free(tud); + return(rc); + }; + if ((rc = otputil_set_param(tud, OTPUTIL_OPT_SKEY_PASS, NULL)) != OTPUTIL_SUCCESS) + { + otputil_free(tud); + return(rc); + }; + if ((rc = otputil_set_param(tud, OTPUTIL_OPT_SKEY_SEQ, NULL)) != OTPUTIL_SUCCESS) + { + otputil_free(tud); + return(rc); + }; + // defaults for TOTP options if ((rc = otputil_set_param(tud, OTPUTIL_OPT_TOTP_K, NULL)) != OTPUTIL_SUCCESS) { @@ -551,6 +606,41 @@ otputil_set_param( tud->otp_seq = _SET_INPUT_NUM(int, defaults->otp_seq); return(OTPUTIL_SUCCESS); + ///////////////////////////// + // S/KEY options (RFC1760) // + ///////////////////////////// + + case OTPUTIL_OPT_SKEY_ENCODE: + switch (_SET_INPUT_NUM(int, defaults->skey_encoding)) + { case OTPUTIL_ENC_HEX: break; + case OTPUTIL_ENC_SIXWORD: break; + default: return(OTPUTIL_EOPTVAL); + }; + tud->skey_encoding = _SET_INPUT_NUM(int, defaults->skey_encoding); + return(OTPUTIL_SUCCESS); + + case OTPUTIL_OPT_SKEY_HASH: + if (otputil_md2str(_SET_INPUT_NUM(int, defaults->skey_hash)) == NULL) + return(OTPUTIL_EOPTVAL); + tud->skey_hash = (int8_t)_SET_INPUT_NUM(int, defaults->skey_hash); + return(OTPUTIL_SUCCESS); + + case OTPUTIL_OPT_SKEY_PASS: + ptr = NULL; + if ((invalue = ((invalue)) ? invalue : defaults->skey_pass) != NULL) + if ((ptr = bindle_strdup(((const char *)invalue))) == NULL) + return(OTPUTIL_ENOMEM); + if ((tud->skey_pass)) + free(tud->skey_pass); + tud->skey_pass = ptr; + return(OTPUTIL_SUCCESS); + + case OTPUTIL_OPT_SKEY_SEQ: + if (_SET_INPUT_NUM(int, defaults->skey_seq) < 0) + return(OTPUTIL_EOPTVAL); + tud->skey_seq = _SET_INPUT_NUM(int, defaults->skey_seq); + return(OTPUTIL_SUCCESS); + //////////////////////////// // TOTP options (RFC6238) // //////////////////////////// diff --git a/lib/libotputil/lrfc1760-skey.c b/lib/libotputil/lrfc1760-skey.c index 1853455..adb61a1 100644 --- a/lib/libotputil/lrfc1760-skey.c +++ b/lib/libotputil/lrfc1760-skey.c @@ -147,45 +147,13 @@ int otputil_skey_code( const char * skey_pass, int skey_seq, + int skey_hash, uint64_t * skey_resultp ) { - unsigned char secret[OTPUTIL_SKEY_PASS_MAX_LEN+1]; - const EVP_MD * evp_md; - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned md_len; - unsigned secret_len; - unsigned u; - int pos; - assert(skey_pass != NULL); - - // generate secret - secret_len = (int)strlen(skey_pass); - if (secret_len > OTPUTIL_SKEY_PASS_MAX_LEN) - return(-1); - bindle_strlcpy((char *)secret, skey_pass, sizeof(secret)); - - // check otp_hash - evp_md = EVP_md4(); - - // generate hashes - for(pos = 0; (pos <= skey_seq); pos++) - { - md_len = sizeof(md); - if (!(EVP_Digest(secret, secret_len, md, &md_len, evp_md, NULL))) - return(-1); - for(u = 0; (u < 8); u++) - md[u] ^= md[u+8]; - memcpy(secret, md, 8); - secret_len = 8; - }; - - *skey_resultp = ((uint64_t)secret[0] << 56) | ((uint64_t)secret[1] << 48) - | ((uint64_t)secret[2] << 40) | ((uint64_t)secret[3] << 32) - | ((uint64_t)secret[4] << 24) | ((uint64_t)secret[5] << 16) - | ((uint64_t)secret[6] << 8) | ((uint64_t)secret[7] << 0); - - return(0); + skey_seq = (skey_seq >= 0) ? skey_seq : otputil_defaults.skey_seq; + skey_hash = ((skey_hash)) ? skey_hash : otputil_defaults.skey_hash; + return(otputil_otp_code(skey_pass, NULL, skey_seq, skey_hash, skey_resultp)); } @@ -206,7 +174,7 @@ otputil_skey_str( res.bv_val = bv_val; res.bv_len = sizeof(bv_val); - if (otputil_skey_code(skey_pass, skey_seq, &val) == -1) + if (otputil_skey_code(skey_pass, skey_seq, 0, &val) == -1) return(NULL); bv_val[0] = (val >> 56) & 0xff; -- cgit v1.2.3