This commit is contained in:
parent
468ac7e132
commit
aac760fc51
282
opensc-cardos-CVE-2008-2235.patch
Normal file
282
opensc-cardos-CVE-2008-2235.patch
Normal file
@ -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ä <juha.yrjola@iki.fi>
|
||||||
|
+ * Copyright (C) 2008 Andreas Jellinghaus <aj@dungeon.inka.de>
|
||||||
|
*
|
||||||
|
* 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 <arg>",
|
||||||
|
"Reads public key with ID <arg>, outputs ssh format",
|
||||||
|
+ "Test if the card needs a security update",
|
||||||
|
+ "Update the card with a security update",
|
||||||
|
"Uses reader number <arg>",
|
||||||
|
"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);
|
@ -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
|
Thu Apr 10 12:54:45 CEST 2008 - ro@suse.de
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ BuildRequires: openct-devel
|
|||||||
%endif
|
%endif
|
||||||
Url: http://www.opensc-project.org/opensc/
|
Url: http://www.opensc-project.org/opensc/
|
||||||
Version: 0.11.4
|
Version: 0.11.4
|
||||||
Release: 18
|
Release: 58
|
||||||
Group: Productivity/Security
|
Group: Productivity/Security
|
||||||
Summary: OpenSC Smart Card Library
|
Summary: OpenSC Smart Card Library
|
||||||
License: LGPL v2.1 or later
|
License: LGPL v2.1 or later
|
||||||
@ -31,6 +31,7 @@ Requires: libopensc2 = %{version} pcsc-lite
|
|||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
Source: %{name}-%{version}.tar.bz2
|
Source: %{name}-%{version}.tar.bz2
|
||||||
Source1: http://www.opensc.org/files/doc/init_perso_guide.html
|
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:
|
# Supress all ugly warnings related to required .so and .la files in the main package:
|
||||||
Source2: %{name}-rpmlintrc
|
Source2: %{name}-rpmlintrc
|
||||||
# and also skip-check-libtool-deps (and add these dependencies to the devel package)
|
# and also skip-check-libtool-deps (and add these dependencies to the devel package)
|
||||||
@ -98,6 +99,7 @@ Authors:
|
|||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
|
%patch -p1
|
||||||
chmod -x doc/svn2cl.xsl
|
chmod -x doc/svn2cl.xsl
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -147,6 +149,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{_libdir}/pkgconfig/*.pc
|
%{_libdir}/pkgconfig/*.pc
|
||||||
|
|
||||||
%changelog
|
%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
|
* Thu Apr 10 2008 ro@suse.de
|
||||||
- added baselibs.conf file to build xxbit packages
|
- added baselibs.conf file to build xxbit packages
|
||||||
for multilib support
|
for multilib support
|
||||||
|
Loading…
Reference in New Issue
Block a user