diff --git a/opensc-cardos-CVE-2008-2235.patch b/opensc-cardos-CVE-2008-2235.patch new file mode 100644 index 0000000..30973c7 --- /dev/null +++ b/opensc-cardos-CVE-2008-2235.patch @@ -0,0 +1,282 @@ +diff -udrNPp --exclude=.svn opensc.orig/src/libopensc/card-cardos.c opensc/src/libopensc/card-cardos.c +--- opensc.orig/src/libopensc/card-cardos.c 2007-08-08 22:15:48.000000000 +0200 ++++ opensc/src/libopensc/card-cardos.c 2008-07-30 13:19:22.000000000 +0200 +@@ -385,7 +385,7 @@ static const int df_acl[9] = { + SC_AC_OP_REHABILITATE, /* DF */ + SC_AC_OP_DELETE, /* DF */ + +- -1, /* ADMIN DF */ ++ SC_AC_OP_UPDATE, /* ADMIN DF */ + SC_AC_OP_CREATE, /* Files */ + -1 /* Reserved */ + }; +@@ -400,7 +400,7 @@ static const int ef_acl[9] = { + + /* XXX: ADMIN should be an ACL type of its own, or mapped + * to erase */ +- -1, /* ADMIN EF (modify meta information?) */ ++ SC_AC_OP_UPDATE, /* ADMIN EF (modify meta information?) */ + -1, /* INC (-> cylic fixed files) */ + -1 /* DEC */ + }; +diff -udrNPp --exclude=.svn opensc.orig/src/tools/pkcs15-tool.c opensc/src/tools/pkcs15-tool.c +--- opensc.orig/src/tools/pkcs15-tool.c 2007-06-30 10:55:57.000000000 +0200 ++++ opensc/src/tools/pkcs15-tool.c 2008-07-30 13:19:42.000000000 +0200 +@@ -2,6 +2,7 @@ + * pkcs15-tool.c: Tool for poking with PKCS #15 smart cards + * + * Copyright (C) 2001 Juha Yrjölä ++ * Copyright (C) 2008 Andreas Jellinghaus + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -90,6 +91,8 @@ static const struct option options[] = { + #if defined(HAVE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H)) + { "read-ssh-key", required_argument, NULL, OPT_READ_SSH }, + #endif ++ { "test-update", no_argument, NULL, 'T' }, ++ { "update", no_argument, NULL, 'U' }, + { "reader", required_argument, NULL, OPT_READER }, + { "pin", required_argument, NULL, OPT_PIN }, + { "new-pin", required_argument, NULL, OPT_NEWPIN }, +@@ -116,6 +119,8 @@ static const char *option_help[] = { + "Lists public keys", + "Reads public key with ID ", + "Reads public key with ID , outputs ssh format", ++ "Test if the card needs a security update", ++ "Update the card with a security update", + "Uses reader number ", + "Specify PIN", + "Specify New PIN (when changing or unblocking)", +@@ -1175,6 +1180,182 @@ static int learn_card(void) + return 0; + } + ++static int test_update(sc_card_t *in_card) ++{ ++ sc_apdu_t apdu; ++ static u8 cmd1[2] = { 0x50, 0x15}; ++ u8 rbuf[258]; ++ int rc; ++ int r; ++ static u8 fci_bad[] = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ static u8 fci_good[] = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00 }; ++ ++ ++ ++ if (strcmp("cardos",in_card->driver->short_name) != 0) { ++ printf("not using the cardos driver, card is fine."); ++ rc = 0; ++ goto end; ++ } ++ ++ if (strcmp("OpenSC Card",p15card->label) != 0) { ++ printf("not initialized by opensc, card is fine."); ++ rc = 0; ++ goto end; ++ } ++ ++ /* first select file on 5015 and get fci */ ++ sc_format_apdu(in_card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x08, 0x00); ++ apdu.lc = sizeof(cmd1); ++ apdu.datalen = sizeof(cmd1); ++ apdu.data = cmd1; ++ apdu.le = 256; ++ apdu.resp = rbuf; ++ apdu.resplen = sizeof(rbuf); ++ ++ r = sc_transmit_apdu(card, &apdu); ++ if (r < 0) { ++ printf("selecting folder failed: %s\n", sc_strerror(r)); ++ rc = 2; ++ goto end; ++ } ++ ++ if (apdu.sw1 != 0x90) { ++ printf("apdu command select file: card returned %02X %02X\n", ++ apdu.sw1, apdu.sw2); ++ rc = 2; ++ goto end; ++ ++ } ++ ++ if (apdu.resplen < 6) { ++ printf("select file did not return enough data (length %d)\n", ++ (int) apdu.resplen); ++ goto bad_fci; ++ } ++ ++ if (rbuf[0] != 0x6f) { ++ printf("select file did not return the information we need\n"); ++ goto bad_fci; ++ } ++ ++ if (rbuf[1] != apdu.resplen -2) { ++ printf("select file did return inconsistent information\n"); ++ goto bad_fci; ++ } ++ ++ { ++ int i=0; ++ while(i < rbuf[1]) { ++ if (rbuf[2+i] == 0x86) { /* found our buffer */ ++ break; ++ } ++ /* other tag */ ++ i += 2 + rbuf[2+i+1]; /* length of this tag*/ ++ } ++ if (rbuf[2+i+1] < 9 || 2+i+2+9 > apdu.resplen) { ++ printf("select file did return short fci\n"); ++ goto bad_fci; ++ } ++ ++ if (memcmp(&rbuf[2+i+2],fci_good,sizeof(fci_good)) == 0) { ++ printf("fci is up-to-date, card is fine\n"); ++ rc = 0; ++ goto end; ++ } ++ ++ if (memcmp(&rbuf[2+i+2],fci_bad,sizeof(fci_bad)) == 0) { ++ printf("fci is out-off-date, card is vulnerable\n"); ++ rc = 1; ++ goto end; ++ } ++ ++ printf("select file returned fci with unknown data\n"); ++ goto bad_fci; ++ } ++end: ++ /* 0 = card ok, 1 = card vulnerable, 2 = problem! */ ++ return rc; ++ ++bad_fci: ++ hex_dump(stdout,rbuf,apdu.resplen," "); ++ printf("\n"); ++ return 2; ++} ++ ++static int update(sc_card_t *in_card) ++{ ++ sc_apdu_t apdu; ++ static u8 cmd1[2] = { 0x50, 0x15}; ++ static u8 cmd3[11] = { 0x86, 0x09, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0x00, 0x00}; ++ int r; ++ ++ /* first select file on 5015 */ ++ sc_format_apdu(in_card, &apdu, SC_APDU_CASE_3_SHORT, 0xa4, 0x08, 0x00); ++ apdu.lc = sizeof(cmd1); ++ apdu.datalen = sizeof(cmd1); ++ apdu.data = cmd1; ++ ++ r = sc_transmit_apdu(card, &apdu); ++ if (r < 0) { ++ printf("selecting folder failed: %s\n", sc_strerror(r)); ++ goto end; ++ } ++ ++ if (apdu.sw1 != 0x90) { ++ printf("apdu command select file: card returned %02X %02X\n", ++ apdu.sw1, apdu.sw2); ++ goto end; ++ ++ } ++ ++ /* next phase control / change lifecycle to operational */ ++ memset(&apdu, 0, sizeof(apdu)); ++ sc_format_apdu(in_card, &apdu, SC_APDU_CASE_1, 0x10, 0x00, 0x00); ++ apdu.cla = 0x80; ++ ++ r = sc_transmit_apdu(card, &apdu); ++ if (r < 0) { ++ printf("change lifecycle failed: %s\n", sc_strerror(r)); ++ goto end; ++ } ++ ++ if (apdu.sw1 != 0x90) { ++ printf("apdu command change lifecycle failed: card returned %02X %02X\n", ++ apdu.sw1, apdu.sw2); ++ goto end; ++ ++ } ++ ++ /* last update AC */ ++ memset(&apdu, 0, sizeof(apdu)); ++ sc_format_apdu(in_card, &apdu, SC_APDU_CASE_3_SHORT, 0xda, 0x01, 0x6f); ++ apdu.lc = sizeof(cmd3); ++ apdu.datalen = sizeof(cmd3); ++ apdu.data = cmd3; ++ apdu.le = 0; ++ apdu.resplen = 0; ++ apdu.resp = NULL; ++ ++ r = sc_transmit_apdu(card, &apdu); ++ if (r < 0) { ++ printf("update fci failed: %s\n", sc_strerror(r)); ++ goto end; ++ } ++ ++ if (apdu.sw1 != 0x90) { ++ printf("apdu command update fci failed: card returned %02X %02X\n", ++ apdu.sw1, apdu.sw2); ++ goto end; ++ ++ } ++ ++ printf("security update applied with success.\n"); ++end: ++ return 0; ++} ++ + int main(int argc, char * const argv[]) + { + int err = 0, r, c, long_optind = 0; +@@ -1193,11 +1374,13 @@ int main(int argc, char * const argv[]) + int do_change_pin = 0; + int do_unblock_pin = 0; + int do_learn_card = 0; ++ int do_test_update = 0; ++ int do_update = 0; + int action_count = 0; + sc_context_param_t ctx_param; + + while (1) { +- c = getopt_long(argc, argv, "r:cuko:va:LR:CwD", options, &long_optind); ++ c = getopt_long(argc, argv, "r:cuko:va:LR:CwDTU", options, &long_optind); + if (c == -1) + break; + if (c == '?') +@@ -1261,6 +1444,14 @@ int main(int argc, char * const argv[]) + do_learn_card = 1; + action_count++; + break; ++ case 'T': ++ do_test_update = 1; ++ action_count++; ++ break; ++ case 'U': ++ do_update = 1; ++ action_count++; ++ break; + case OPT_READER: + opt_reader = atoi(optarg); + break; +@@ -1388,6 +1579,18 @@ int main(int argc, char * const argv[]) + goto end; + action_count--; + } ++ if (do_test_update || do_update) { ++ err = test_update(card); ++ action_count--; ++ if (err == 2) { /* problem */ ++ err =1; ++ goto end; ++ } ++ if (do_update && err == 1) { /* card vulnerable */ ++ if ((err = update(card))) ++ goto end; ++ } ++ } + end: + if (p15card) + sc_pkcs15_unbind(p15card); diff --git a/opensc.changes b/opensc.changes index bb34d3d..c812c2d 100644 --- a/opensc.changes +++ b/opensc.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Jul 31 12:45:11 CEST 2008 - sbrabec@suse.cz + +- Fixed initialization access rights for Siemens CardOS M4, added + a security check to pkcs15-tool (bnc#413496, CVE-2008-2235) + ------------------------------------------------------------------- Thu Apr 10 12:54:45 CEST 2008 - ro@suse.de diff --git a/opensc.spec b/opensc.spec index 3d2d0ab..f90fe65 100644 --- a/opensc.spec +++ b/opensc.spec @@ -23,7 +23,7 @@ BuildRequires: openct-devel %endif Url: http://www.opensc-project.org/opensc/ Version: 0.11.4 -Release: 18 +Release: 58 Group: Productivity/Security Summary: OpenSC Smart Card Library License: LGPL v2.1 or later @@ -31,6 +31,7 @@ Requires: libopensc2 = %{version} pcsc-lite BuildRoot: %{_tmppath}/%{name}-%{version}-build Source: %{name}-%{version}.tar.bz2 Source1: http://www.opensc.org/files/doc/init_perso_guide.html +Patch: opensc-cardos-CVE-2008-2235.patch # Supress all ugly warnings related to required .so and .la files in the main package: Source2: %{name}-rpmlintrc # and also skip-check-libtool-deps (and add these dependencies to the devel package) @@ -98,6 +99,7 @@ Authors: %prep %setup -q +%patch -p1 chmod -x doc/svn2cl.xsl %build @@ -147,6 +149,9 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/pkgconfig/*.pc %changelog +* Thu Jul 31 2008 sbrabec@suse.cz +- Fixed initialization access rights for Siemens CardOS M4, added + a security check to pkcs15-tool (bnc#413496, CVE-2008-2235) * Thu Apr 10 2008 ro@suse.de - added baselibs.conf file to build xxbit packages for multilib support