From 013161014b868e9162d0649a9945139e27faaa74 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Mon, 3 Feb 2014 15:08:15 +0100 Subject: [PATCH] implement authenticate --- Makefile.am | 6 +++-- configure.ac | 1 + yubico-piv-tool.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index b973506..b8bc1cb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,12 +25,14 @@ # for the parts of OpenSSL used as well as that of the covered work. AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS) -AM_CPPFLAGS = $(PCSC_CFLAGS) +AM_CPPFLAGS = $(PCSC_CFLAGS) $(OPENSSL_CFLAGS) + +ACLOCAL_AMFLAGS = -I m4 bin_PROGRAMS = yubico-piv-tool yubico_piv_tool_SOURCES = yubico-piv-tool.c yubico_piv_tool_SOURCES += cmdline.ggo cmdline.c cmdline.h -yubico_piv_tool_LDADD = $(PCSC_LIBS) +yubico_piv_tool_LDADD = $(PCSC_LIBS) $(OPENSSL_LIBS) cmdline.c cmdline.h: cmdline.ggo Makefile.am gengetopt --input $^ diff --git a/configure.ac b/configure.ac index 9b3d467..f90f63a 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ AM_MISSING_PROG(HELP2MAN, help2man, $missing_dir) PKG_PROG_PKG_CONFIG PKG_CHECK_MODULES(PCSC, libpcsclite) +PKG_CHECK_MODULES(OPENSSL, openssl) AC_ARG_ENABLE([gcc-warnings], [AS_HELP_STRING([--enable-gcc-warnings], diff --git a/yubico-piv-tool.c b/yubico-piv-tool.c index 3111f88..a6e5e34 100644 --- a/yubico-piv-tool.c +++ b/yubico-piv-tool.c @@ -32,6 +32,8 @@ #include #include +#include + #ifdef __APPLE__ #include #else @@ -136,10 +138,9 @@ static bool select_applet(SCARDHANDLE *card, int verbose) { unsigned long recv_len = sizeof(data); int sw; - apdu.st.cla = 0x00; + memset(apdu.raw, 0, sizeof(apdu)); apdu.st.ins = 0xa4; apdu.st.p1 = 0x04; - apdu.st.p2 = 0x00; apdu.st.lc = AID_LEN; memcpy(apdu.st.data, aid, AID_LEN); @@ -151,6 +152,62 @@ static bool select_applet(SCARDHANDLE *card, int verbose) { return false; } +static bool authenticate(SCARDHANDLE *card, unsigned char *key, int verbose) { + APDU apdu; + unsigned char data[0xff]; + unsigned char challenge[8]; + unsigned long recv_len = sizeof(data); + int sw; + + DES_key_schedule ks1, ks2, ks3; + + { + DES_set_key_unchecked(key, &ks1); + DES_set_key_unchecked(key + 8, &ks2); + DES_set_key_unchecked(key + 16, &ks3); + } + + { + memset(apdu.raw, 0, sizeof(apdu)); + apdu.st.ins = 0x87; + apdu.st.p1 = 0x03; /* triple des */ + apdu.st.p2 = 0x9b; /* management key */ + apdu.st.lc = 0x04; + apdu.st.data[0] = 0x7c; + apdu.st.data[1] = 0x02; + apdu.st.data[2] = 0x80; + sw = send_data(card, apdu, 9, data, &recv_len, verbose); + if(sw != 0x9000) { + return false; + } + memcpy(challenge, data + 4, 8); + if(verbose) { + printf("received challenge:\n"); + dump_hex(challenge, 8); + } + } + + { + recv_len = 0xff; + memset(apdu.raw, 0, sizeof(apdu)); + apdu.st.ins = 0x87; + apdu.st.p1 = 0x03; /* triple des */ + apdu.st.p2 = 0x9b; /* management key */ + apdu.st.lc = 12; + apdu.st.data[0] = 0x7c; + apdu.st.data[1] = 10; + apdu.st.data[2] = 0x80; + apdu.st.data[3] = 8; + DES_ecb3_encrypt(challenge, apdu.st.data + 4, &ks1, &ks2, &ks3, 0); + sw = send_data(card, apdu, 17, data, &recv_len, verbose); + } + + if(sw == 0x9000) { + return true; + } + return false; +} + int send_data(SCARDHANDLE *card, APDU apdu, unsigned int send_len, unsigned char *data, unsigned long *recv_len, int verbose) { long rc; int sw; @@ -234,5 +291,9 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } + if(authenticate(&card, key, args_info.verbose_flag) == false) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; }