From 89b8f5d4fc2fb5b5cfc22a62105560da87df850f Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Thu, 11 Apr 2013 10:10:55 +0200 Subject: [PATCH] start building on JSON export functionality --- Makefile.am | 3 +- configure.ac | 8 +-- libykpers-1.map | 8 +++ ykpers-json.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++ ykpers-json.h | 47 ++++++++++++ ykpers.c | 18 +++++ ykpers.h | 6 ++ 7 files changed, 272 insertions(+), 5 deletions(-) create mode 100644 ykpers-json.c create mode 100644 ykpers-json.h diff --git a/Makefile.am b/Makefile.am index 88d6249..96207ab 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,8 @@ ykpers_include_HEADERS += ykcore/ykstatus.h ykcore/ykcore.h ykcore/ykdef.h ykpers_include_HEADERS += ykpbkdf2.h lib_LTLIBRARIES = libykpers-1.la -libykpers_1_la_SOURCES = ykpers.c ykpers-version.c ykpbkdf2.c ykpers_lcl.h +libykpers_1_la_SOURCES = ykpers.c ykpers-version.c ykpbkdf2.c ykpers-json.c +libykpers_1_la_SOURCES += ykpers_lcl.h ykpers-json.h libykpers_1_la_SOURCES += rfc4634/hmac.c rfc4634/usha.c rfc4634/sha.h \ rfc4634/sha1.c rfc4634/sha224-256.c rfc4634/sha384-512.c \ rfc4634/sha-private.h diff --git a/configure.ac b/configure.ac index 8bf804a..97b76be 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -AC_INIT([yubikey-personalization], [1.12.1], +AC_INIT([yubikey-personalization], [1.13.0], [yubico-devel@googlegroups.com], [ykpers], [http://code.google.com/p/yubikey-personalization/]) AC_CONFIG_AUX_DIR([build-aux]) @@ -36,9 +36,9 @@ AC_CONFIG_MACRO_DIR([m4]) # Interfaces changed/added/removed: CURRENT++ REVISION=0 # Interfaces added: AGE++ # Interfaces removed: AGE=0 -AC_SUBST(LT_CURRENT, 13) -AC_SUBST(LT_REVISION, 1) -AC_SUBST(LT_AGE, 12) +AC_SUBST(LT_CURRENT, 14) +AC_SUBST(LT_REVISION, 0) +AC_SUBST(LT_AGE, 13) AM_INIT_AUTOMAKE([1.11.3 -Wall -Werror]) AM_SILENT_RULES([yes]) diff --git a/libykpers-1.map b/libykpers-1.map index 9a4b82d..2b32bdd 100644 --- a/libykpers-1.map +++ b/libykpers-1.map @@ -190,3 +190,11 @@ LIBYKPERS_1.12 { ykp_set_extflag_LED_INV; # Variables: } LIBYKPERS_1.11; + +LIBYKPERS_1.13 { + global: +# Functions: + ykp_export_config; + ykp_import_config; +# Variables: +} LIBYKPERS_1.12; diff --git a/ykpers-json.c b/ykpers-json.c new file mode 100644 index 0000000..9d9c6bc --- /dev/null +++ b/ykpers-json.c @@ -0,0 +1,187 @@ +/* -*- mode:C; c-file-style: "bsd" -*- */ +/* + * Copyright (c) 2013 Yubico AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT + * OWNER 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. + */ + +#include "ykpers_lcl.h" +#include "ykpers-json.h" + +#include +#include + +struct map_st { + uint8_t flag; + const char *flag_text; + unsigned char mode; +}; + +#define MODE_CHAL_HMAC 0x01 +#define MODE_OATH_HOTP 0x02 +#define MODE_OTP_YUBICO 0x04 +#define MODE_CHAL_YUBICO 0x08 +#define MODE_STATIC_TICKET 0x10 + +#define MODE_CHAL_RESP MODE_CHAL_YUBICO | MODE_CHAL_HMAC +#define MODE_OUTPUT MODE_STATIC_TICKET | MODE_OTP_YUBICO + +static struct map_st ticket_flags_map[] = { + { TKTFLAG_TAB_FIRST, "tabFirst", MODE_OUTPUT }, + { TKTFLAG_APPEND_TAB1, "tabBetween", MODE_OUTPUT }, + { TKTFLAG_APPEND_TAB2, "tabLast", MODE_OUTPUT }, + { TKTFLAG_APPEND_DELAY1, "appendDelay1", MODE_OUTPUT }, /* XXX: name? */ + { TKTFLAG_APPEND_DELAY2, "appendDelay2", MODE_OUTPUT }, /* XXX: name? */ + { TKTFLAG_APPEND_CR, "appendCR", MODE_OUTPUT }, + { TKTFLAG_PROTECT_CFG2, "protectSecond",0 }, + { 0, "", 0 } + /* XXX: deal with modes.. + * { TKTFLAG_OATH_HOTP, "OATH_HOTP", capability_has_oath, 0 }, + { TKTFLAG_CHAL_RESP, "CHAL_RESP", capability_has_chal_resp, 0 }, + { 0, "", 0, 0 }*/ +}; + +static struct map_st config_flags_map[] = { + //{ CFGFLAG_CHAL_YUBICO, "CHAL_YUBICO", capability_has_chal_resp, TKTFLAG_CHAL_RESP }, + //{ CFGFLAG_CHAL_HMAC, "CHAL_HMAC", capability_has_chal_resp, TKTFLAG_CHAL_RESP }, + { CFGFLAG_HMAC_LT64, "hmacLT64", MODE_CHAL_HMAC }, /* XXX: name? */ + { CFGFLAG_CHAL_BTN_TRIG, "chalBtnTrig", MODE_CHAL_RESP }, /* XXX: name? */ + /* TODO: oathDigits + { CFGFLAG_OATH_HOTP8, "oathHotp8" TKTFLAG_OATH_HOTP },*/ + { CFGFLAG_OATH_FIXED_MODHEX1, "oathFixedModhex1", MODE_OATH_HOTP }, /* XXX: name? */ + { CFGFLAG_OATH_FIXED_MODHEX2, "oathFixedModhex2", MODE_OATH_HOTP }, /* XXX: name? */ + { CFGFLAG_OATH_FIXED_MODHEX, "oathFixedModhex", MODE_OATH_HOTP }, /* XXX: name? */ + { CFGFLAG_SEND_REF, "sendRef", MODE_OUTPUT }, /* XXX: name? */ + { CFGFLAG_TICKET_FIRST, "ticketFirst", MODE_OUTPUT }, /* XXX: name? */ + { CFGFLAG_PACING_10MS, "pacing10MS", MODE_OUTPUT }, /* XXX: name? */ + { CFGFLAG_PACING_20MS, "pacing20MS", MODE_OUTPUT }, /* XXX: name? */ + { CFGFLAG_ALLOW_HIDTRIG, "allowHidtrig", MODE_OUTPUT }, /* XXX: name? */ + /* TODO: mode.. */ + /*{ CFGFLAG_STATIC_TICKET, "STATIC_TICKET", capability_has_static, 0 },*/ + { CFGFLAG_SHORT_TICKET, "shortTicket", MODE_STATIC_TICKET }, /* XXX: name? */ + { CFGFLAG_STRONG_PW1, "strongPw1", MODE_STATIC_TICKET }, /* XXX: name? */ + { CFGFLAG_STRONG_PW2, "strongPw2", MODE_STATIC_TICKET }, /* XXX: name? */ + { CFGFLAG_MAN_UPDATE, "manUpdate", MODE_STATIC_TICKET }, /* XXX: name? */ + { 0, "", 0 } +}; + +static struct map_st extended_flags_map[] = { + { EXTFLAG_SERIAL_BTN_VISIBLE, "serialBtnVisible", 0 }, + { EXTFLAG_SERIAL_USB_VISIBLE, "serialUsbVisible", 0 }, + { EXTFLAG_SERIAL_API_VISIBLE, "serialApiVisible", 0 }, + { EXTFLAG_USE_NUMERIC_KEYPAD, "useNumericKeypad", 0 }, + { EXTFLAG_FAST_TRIG, "fastTrig", 0 }, + { EXTFLAG_ALLOW_UPDATE, "allowUpdate", 0 }, + { EXTFLAG_DORMANT, "dormant", 0 }, + { EXTFLAG_LED_INV, "invertLed", 0 }, /* XXX: name? */ + { 0, "", 0 } +}; + +static struct map_st modes_map[] = { + { MODE_OATH_HOTP, "oathHOTP", 0 }, + { MODE_CHAL_HMAC, "hmacCR", 0 }, + { MODE_STATIC_TICKET, "staticTicket", 0 }, /* XXX: name? */ + { MODE_CHAL_YUBICO, "yubicoCR", 0 }, /* XXX: name? */ + { MODE_OTP_YUBICO, "yubicoOTP", 0 }, + { 0, "", 0 } +}; + +int ykp_json_export_cfg(const YKP_CONFIG *cfg, char *json, size_t len) { + YK_CONFIG ycfg = cfg->ykcore_config; + json_object *jobj = json_object_new_object(); + json_object *yprod_json = json_object_new_object(); + json_object *options_json = json_object_new_object(); + + int mode = MODE_OTP_YUBICO; + struct map_st *p; + + if((ycfg.cfgFlags & CFGFLAG_STATIC_TICKET) == CFGFLAG_STATIC_TICKET) { + mode = MODE_STATIC_TICKET; + } + else if((ycfg.tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP){ + if((ycfg.cfgFlags & CFGFLAG_CHAL_YUBICO) == CFGFLAG_CHAL_YUBICO) { + mode = MODE_CHAL_YUBICO; + } else if((ycfg.cfgFlags & CFGFLAG_CHAL_HMAC) == CFGFLAG_CHAL_HMAC) { + mode = MODE_CHAL_HMAC; + } else { + mode = MODE_OATH_HOTP; + } + } + + for(p = modes_map; p->flag; p++) { + if(p->flag == mode) { + json_object *jmode = json_object_new_string(p->flag_text); + json_object_object_add(yprod_json, "mode", jmode); + } + } + + json_object_object_add(jobj, "yubiProdConfig", yprod_json); + json_object_object_add(yprod_json, "options", options_json); + + if(mode == MODE_OATH_HOTP) { /* TODO: handle seed */ + json_object *oathDigits; + if((ycfg.cfgFlags & CFGFLAG_OATH_HOTP8) == CFGFLAG_OATH_HOTP8) { + oathDigits = json_object_new_int(8); + } else { + oathDigits = json_object_new_int(6); + } + json_object_object_add(options_json, "oathDigits", oathDigits); + } + + for(p = ticket_flags_map; p->flag; p++) { + if(!p->mode || (p->mode && (mode & p->mode) == mode)) { + int set = (ycfg.tktFlags & p->flag) == p->flag; + json_object *jsetting = json_object_new_boolean(set); + json_object_object_add(options_json, p->flag_text, jsetting); + } + } + + for(p = config_flags_map; p->flag; p++) { + if(!p->mode || (p->mode && (mode & p->mode) == mode)) { + int set = (ycfg.cfgFlags & p->flag) == p->flag; + json_object *jsetting = json_object_new_boolean(set); + json_object_object_add(options_json, p->flag_text, jsetting); + } + } + + for(p = extended_flags_map; p->flag; p++) { + int set = (ycfg.extFlags & p->flag) == p->flag; + json_object *jsetting = json_object_new_boolean(set); + json_object_object_add(options_json, p->flag_text, jsetting); + } + + + strncpy(json, json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PRETTY), len); + + /* free the root object, will free all children */ + json_object_put(jobj); + return 0; +} + +int ykp_json_import_cfg(const char *json, size_t len, YKP_CONFIG *cfg) { + return 0; +} + diff --git a/ykpers-json.h b/ykpers-json.h new file mode 100644 index 0000000..5271be4 --- /dev/null +++ b/ykpers-json.h @@ -0,0 +1,47 @@ +/* -*- mode:C; c-file-style: "bsd" -*- */ +/* + * Copyright (c) 2013 Yubico AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT + * OWNER 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. + */ + +#ifndef __YKPERS_JSON_H_INCLUDED__ +#define __YKPERS_JSON_H_INCLUDED__ + +#include + +# ifdef __cplusplus +extern "C" { +# endif + +int ykp_json_export_cfg(const YKP_CONFIG *cfg, char *json, size_t len); +int ykp_json_import_cfg(const char *json, size_t len, YKP_CONFIG *cfg); + +# ifdef __cplusplus +} +# endif + +#endif /* __YKPERS_JSON_H_INCLUDED__ */ diff --git a/ykpers.c b/ykpers.c index 1ca50db..6acd385 100644 --- a/ykpers.c +++ b/ykpers.c @@ -31,6 +31,7 @@ #include "ykpers_lcl.h" #include "ykpbkdf2.h" #include "yktsd.h" +#include "ykpers-json.h" #include @@ -913,6 +914,23 @@ static struct map_st extended_flags_map[] = { { 0, "", 0, 0 } }; +int ykp_export_config(const YKP_CONFIG *cfg, char *buf, size_t len, + int format) { + if(format == YKP_FORMAT_JSON) { + return ykp_json_export_cfg(cfg, buf, len); + } + return 1; +} + + +int ykp_import_config(const char *buf, size_t len, YKP_CONFIG *cfg, + int format) { + if(format == YKP_FORMAT_JSON) { + return ykp_json_import_cfg(buf, len, cfg); + } + return 1; +} + int ykp_write_config(const YKP_CONFIG *cfg, int (*writer)(const char *buf, size_t count, void *userdata), diff --git a/ykpers.h b/ykpers.h index 549eeb1..5a81707 100644 --- a/ykpers.h +++ b/ykpers.h @@ -137,6 +137,12 @@ YK_CONFIG *ykp_core_config(YKP_CONFIG *cfg); int ykp_command(YKP_CONFIG *cfg); int ykp_config_num(YKP_CONFIG *cfg); +int ykp_export_config(const YKP_CONFIG *cfg, char *buf, size_t len, int format); +int ykp_import_config(const char *buf, size_t len, YKP_CONFIG *cfg, int format); + +#define YKP_FORMAT_LEGACY 0x01 +#define YKP_FORMAT_JSON 0x02 + extern int * _ykp_errno_location(void); #define ykp_errno (*_ykp_errno_location()) const char *ykp_strerror(int errnum); -- 2.39.5