Architecture specific change in rpms/golang-github-spf13-pflag.git
by githook-noreply@fedoraproject.org
The package rpms/golang-github-spf13-pflag.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/golang-github-spf13-pflag.git/com....
Change:
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
Thanks.
Full change:
============
commit 8adea6297b279eb1405db4521a64267264362746
Author: Jan Chaloupka <jchaloup(a)redhat.com>
Date: Fri Mar 2 10:33:56 2018 +0100
Autogenerate some parts using the new macros
diff --git a/golang-github-spf13-pflag.spec b/golang-github-spf13-pflag.spec
index f11b7e4..60097f4 100644
--- a/golang-github-spf13-pflag.spec
+++ b/golang-github-spf13-pflag.spec
@@ -1,58 +1,17 @@
-# If any of the following macros should be set otherwise,
-# you can wrap any of them with the following conditions:
-# - %%if 0%%{centos} == 7
-# - %%if 0%%{?rhel} == 7
-# - %%if 0%%{?fedora} == 23
-# Or just test for particular distribution:
-# - %%if 0%%{centos}
-# - %%if 0%%{?rhel}
-# - %%if 0%%{?fedora}
-#
-# Be aware, on centos, both %%rhel and %%centos are set. If you want to test
-# rhel specific macros, you can use %%if 0%%{?rhel} && 0%%{?centos} == 0 condition.
-# (Don't forget to replace double percentage symbol with single one in order to apply a condition)
-
-# Generate devel rpm
-%global with_devel 1
-# Build project from bundled dependencies
-%global with_bundled 0
-# Build with debug info rpm
-%global with_debug 0
-# Run tests in check section
-# the test (using github.com/ogier/pflag or patching the deps to spf13/pflag
-# still fails, no test -> no deps on ogier so far
-%global with_check 0
-# Generate unit-test rpm
-%global with_unit_test 1
-
-%if 0%{?with_debug}
-%global _dwz_low_mem_die_limit 0
-%else
-%global debug_package %{nil}
-%endif
-
-%global provider github
-%global provider_tld com
-%global project spf13
-%global repo pflag
-# https://github.com/spf13/pflag
-%global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo}
-%global import_path %{provider_prefix}
+# http://github.com/spf13/pflag
+%global provider_prefix github.com/spf13/pflag
+%global gobaseipath %{provider_prefix}
%global commit e57e3eeb33f795204c1ca35f56c44f83227c6e66
-%global shortcommit %(c=%{commit}; echo ${c:0:7})
-Name: golang-%{provider}-%{project}-%{repo}
+%gocraftmeta -i
+
+Name: %{goname}
Version: 1.0.0
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Replacement for Go's flag package
License: ASL 2.0
-URL: https://%{provider_prefix}
-Source0: https://%{provider_prefix}/archive/%{commit}/%{repo}-%{shortcommit}.tar.gz
-
-# e.g. el6 has ppc64 arch without gcc-go, so EA tag is required
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
-# If go_compiler is not set to 1, there is no virtual provide. Use golang instead.
-BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang}
+URL: %{gourl}
+Source0: %{gosource}
%description
pflag is a drop-in replacement for Go's flag package,
@@ -65,17 +24,10 @@ see the "Command-line flag syntax" section below.
pflag is available under the same style of BSD license as the Go language,
which can be found in the LICENSE file.
-%if 0%{?with_devel}
%package devel
Summary: %{summary}
BuildArch: noarch
-%if 0%{?with_check}
-%endif
-
-
-Provides: golang(%{import_path}) = %{version}-%{release}
-
%description devel
pflag is a drop-in replacement for Go's flag package,
implementing POSIX/GNU-style --flags.
@@ -89,89 +41,28 @@ which can be found in the LICENSE file.
This package contains library source intended for
building other packages which use import path with
-%{import_path} prefix.
-%endif
-
-%if 0%{?with_unit_test}
-%package unit-test
-Summary: Unit tests for %{name} package
-
-%if 0%{?with_check}
-#Here comes all BuildRequires: PACKAGE the unit tests
-#in %%check section need for running
-%endif
-
-# test subpackage tests code from devel subpackage
-Requires: %{name}-devel = %{version}-%{release}
-
-%description unit-test
-%{summary}
-
-This package contains unit tests for project
-providing packages with %{import_path} prefix.
-%endif
+%{gobaseipath} prefix.
%prep
-%setup -q -n %{repo}-%{commit}
-
-%build
+%gosetup
%install
-# source codes for building projects
-%if 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-# find all *.go but no *_test.go files and generate devel.file-list
-for file in $(find . -iname "*.go" \! -iname "*_test.go") ; do
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> devel.file-list
-done
-%endif
-
-# testing files for this project
-%if 0%{?with_unit_test}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-# find all *_test.go files and generate unit-test.file-list
-for file in $(find . -iname "*_test.go"); do
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> unit-test.file-list
-done
-%endif
+%goinstall
%check
-%if 0%{?with_check} && 0%{?with_unit_test} && 0%{?with_devel}
-%if ! 0%{?with_bundled}
-export GOPATH=%{buildroot}/%{gopath}:%{gopath}
-%else
-export GOPATH=%{buildroot}/%{gopath}:$(pwd)/Godeps/_workspace:%{gopath}
-%endif
-
-%if ! 0%{?gotest:1}
-%global gotest go test
-%endif
-
-%gotest %{import_path}
-%endif
+%gochecks
#define license tag if not already defined
%{!?_licensedir:%global license %doc}
-%if 0%{?with_devel}
%files devel -f devel.file-list
%license LICENSE
%doc README.md
-%dir %{gopath}/src/%{provider}.%{provider_tld}/%{project}
-%dir %{gopath}/src/%{import_path}
-%endif
-
-%if 0%{?with_unit_test}
-%files unit-test -f unit-test.file-list
-%license LICENSE
-%doc README.md
-%endif
%changelog
+* Fri Mar 02 2018 Jan Chaloupka <jchaloup(a)redhat.com> - 1.0.0-2
+- Autogenerate some parts using the new macros
+
* Wed Feb 21 2018 Kaushal <kshlster(a)gmail.com> - 1.0.0-1
- Update to upstream v1.0.0
6 years, 1 month
Architecture specific change in rpms/coolkey.git
by githook-noreply@fedoraproject.org
The package rpms/coolkey.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/coolkey.git/commit/?id=defeaf277c....
Change:
-ExcludeArch: s390 s390x
Thanks.
Full change:
============
commit defeaf277c91a5142d9b37c32cfe0784d627a24d
Author: Jakub Jelen <jjelen(a)redhat.com>
Date: Fri Mar 2 09:55:40 2018 +0100
Replaced by OpenSC
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 88a91c6..0000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-coolkey-1.1.0.tar.gz
diff --git a/coolkey-1.1.0-max-cpu-bug.patch b/coolkey-1.1.0-max-cpu-bug.patch
deleted file mode 100644
index aab85f7..0000000
--- a/coolkey-1.1.0-max-cpu-bug.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.max-cpu-bug ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.max-cpu-bug 2016-06-30 14:36:10.502785885 -0700
-+++ ./src/coolkey/slot.cpp 2016-06-30 14:36:15.812876256 -0700
-@@ -1875,6 +1875,8 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- if (status != CKYSUCCESS) {
- if ((CKYCardContext_GetLastError(context) ==
- SCARD_E_READER_UNAVAILABLE) ||
-+ (CKYCardContext_GetLastError(context) ==
-+ SCARD_E_UNKNOWN_READER) ||
- (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT)) {
- OSSleep(timeout*PKCS11_CARD_ERROR_LATENCY);
- }
diff --git a/coolkey-cac-1.patch b/coolkey-cac-1.patch
deleted file mode 100644
index ea70187..0000000
--- a/coolkey-cac-1.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff -up ./src/coolkey/object.cpp.cac-1 ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.cac-1 2010-06-23 04:46:35.726198827 -0700
-+++ ./src/coolkey/object.cpp 2010-06-23 04:47:28.073827862 -0700
-@@ -505,6 +505,10 @@ dataStart(const CKYByte *buf, unsigned i
- unsigned char tag;
- unsigned int used_length= 0;
-
-+ if(!buf) {
-+ return NULL;
-+ }
-+
- tag = buf[used_length++];
-
- /* blow out when we come to the end */
-diff -up ./src/coolkey/slot.cpp.cac-1 ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.cac-1 2010-06-23 04:46:22.718371631 -0700
-+++ ./src/coolkey/slot.cpp 2010-06-23 04:57:04.417774402 -0700
-@@ -2192,6 +2192,10 @@ Slot::readCACCertificateFirst(CKYBuffer
- if (throwException && (status != CKYSUCCESS)) {
- handleConnectionError();
- }
-+
-+ if(CKYBuffer_Size(cert) == 0) {
-+ handleConnectionError();
-+ }
- return status;
- }
-
diff --git a/coolkey-cac.patch b/coolkey-cac.patch
deleted file mode 100644
index a2a9732..0000000
--- a/coolkey-cac.patch
+++ /dev/null
@@ -1,1013 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.cac ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.cac 2010-06-16 13:43:51.477181000 -0700
-+++ ./src/coolkey/slot.cpp 2010-06-16 13:43:51.535179000 -0700
-@@ -372,7 +372,7 @@ Slot::Slot(const char *readerName_, Log
- : log(log_), readerName(NULL), personName(NULL), manufacturer(NULL),
- slotInfoFound(false), context(context_), conn(NULL), state(UNKNOWN),
- isVersion1Key(false), needLogin(false), fullTokenName(false),
-- mCoolkey(false),
-+ mCoolkey(false), mOldCAC(false),
- #ifdef USE_SHMEM
- shmem(readerName_),
- #endif
-@@ -412,6 +412,9 @@ Slot::Slot(const char *readerName_, Log
- }
- CKYBuffer_InitEmpty(&cardATR);
- CKYBuffer_InitEmpty(&mCUID);
-+ for (int i=0; i < MAX_CERT_SLOTS; i++) {
-+ CKYBuffer_InitEmpty(&cardAID[i]);
-+ }
- } catch(PKCS11Exception &) {
- if (conn) {
- CKYCardConnection_Destroy(conn);
-@@ -479,6 +482,9 @@ Slot::~Slot()
- CKYBuffer_FreeData(&nonce);
- CKYBuffer_FreeData(&cardATR);
- CKYBuffer_FreeData(&mCUID);
-+ for (int i=0; i < MAX_CERT_SLOTS; i++) {
-+ CKYBuffer_FreeData(&cardAID[i]);
-+ }
- }
-
- template <class C>
-@@ -671,15 +677,9 @@ Slot::connectToToken()
- status = CKYApplet_SelectCoolKeyManager(conn, NULL);
- if (status != CKYSUCCESS) {
- log->log("CoolKey Select failed 0x%x\n", status);
-- status = CACApplet_SelectPKI(conn, 0, NULL);
-+ status = getCACAid();
- if (status != CKYSUCCESS) {
-- log->log("CAC Select failed 0x%x\n", status);
-- if (status == CKYSCARDERR) {
-- log->log("CAC Card Failure 0x%x\n",
-- CKYCardConnection_GetLastError(conn));
-- disconnect();
-- }
-- return;
-+ goto loser;
- }
- state |= CAC_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
- /* skip the read of the cuid. We really don't need it and,
-@@ -690,6 +690,15 @@ Slot::connectToToken()
- needLogin = 1;
- mCoolkey = 0;
- return;
-+
-+loser:
-+ log->log("CAC Select failed 0x%x\n", status);
-+ if (status == CKYSCARDERR) {
-+ log->log("CAC Card Failure 0x%x\n",
-+ CKYCardConnection_GetLastError(conn));
-+ disconnect();
-+ }
-+ return;
- }
- mCoolkey = 1;
- log->log("time connect: Select Applet %d ms\n", OSTimeNow() - time);
-@@ -771,17 +780,111 @@ Slot::disconnect()
- invalidateLogin(false);
- }
-
-+CKYStatus
-+Slot::getCACAid()
-+{
-+ CKYBuffer tBuf;
-+ CKYBuffer vBuf;
-+ CKYSize tlen, vlen;
-+ CKYOffset toffset, voffset;
-+ int certSlot = 0;
-+ int i,length = 0;
-+ CKYStatus status;
-+
-+ CKYBuffer_InitEmpty(&tBuf);
-+ CKYBuffer_InitEmpty(&vBuf);
-+
-+ /* clear out the card AID's */
-+ for (i=0; i < MAX_CERT_SLOTS; i++) {
-+ CKYBuffer_Resize(&cardAID[i],0);
-+ }
-+
-+ status = CACApplet_SelectCCC(conn,NULL);
-+ if (status != CKYSUCCESS) {
-+ /* are we an old CAC */
-+ status = CACApplet_SelectPKI(conn, &cardAID[0], 0, NULL);
-+ if (status != CKYSUCCESS) {
-+ /* no, just fail */
-+ return status;
-+ }
-+ /* yes, fill in the old applets */
-+ mOldCAC = true;
-+ for (i=1; i< MAX_CERT_SLOTS; i++) {
-+ CACApplet_SelectPKI(conn, &cardAID[i], i, NULL);
-+ }
-+ return CKYSUCCESS;
-+ }
-+ /* definately not an old CAC */
-+ mOldCAC = false;
-+
-+ /* read the TLV */
-+ status = CACApplet_ReadFile(conn, CAC_TAG_FILE, &tBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ status = CACApplet_ReadFile(conn, CAC_VALUE_FILE, &vBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ tlen = CKYBuffer_Size(&tBuf);
-+ vlen = CKYBuffer_Size(&vBuf);
-+
-+ for(toffset = 2, voffset=2;
-+ certSlot < MAX_CERT_SLOTS && toffset < tlen && voffset < vlen ;
-+ voffset += length) {
-+
-+ CKYByte tag = CKYBuffer_GetChar(&tBuf, toffset);
-+ length = CKYBuffer_GetChar(&tBuf, toffset+1);
-+ toffset += 2;
-+ if (length == 0xff) {
-+ length = CKYBuffer_GetShortLE(&tBuf, toffset);
-+ toffset +=2;
-+ }
-+ if (tag != CAC_TAG_CARDURL) {
-+ continue;
-+ }
-+ /* CARDURL tags must be at least 10 bytes long */
-+ if (length < 10) {
-+ continue;
-+ }
-+ /* check the app type, should be TLV_APP_PKI */
-+ if (CKYBuffer_GetChar(&vBuf, voffset+5) != CAC_TLV_APP_PKI) {
-+ continue;
-+ }
-+ status = CKYBuffer_AppendBuffer(&cardAID[certSlot], &vBuf, voffset, 5);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ status = CKYBuffer_AppendBuffer(&cardAID[certSlot], &vBuf,
-+ voffset+8, 2);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ cardEF[certSlot] = CKYBuffer_GetShortLE(&vBuf, voffset+6);
-+
-+ certSlot++;
-+ }
-+ status = CKYSUCCESS;
-+ if (certSlot == 0) {
-+ status = CKYAPDUFAIL; /* probably neeed a beter error code */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tBuf);
-+ CKYBuffer_FreeData(&vBuf);
-+ return status;
-+}
-+
- void
- Slot::refreshTokenState()
- {
- if( cardStateMayHaveChanged() ) {
--log->log("card changed\n");
-+ log->log("card changed\n");
- invalidateLogin(true);
- closeAllSessions();
- unloadObjects();
- connectToToken();
-
--
- if( state & APPLET_PERSONALIZED ) {
- try {
- loadObjects();
-@@ -1019,7 +1122,7 @@ Slot::makeModelString(char *model, int m
-
- struct _manList {
- unsigned short type;
-- char *string;
-+ const char *string;
- };
-
- static const struct _manList manList[] = {
-@@ -1280,13 +1383,30 @@ void
- Slot::selectCACApplet(CKYByte instance)
- {
- CKYStatus status;
-- status = CACApplet_SelectPKI(conn, instance, NULL);
-+ CKYBuffer *aid = &cardAID[instance];
-+
-+ if (CKYBuffer_Size(aid) == 0) {
-+ disconnect();
-+ throw PKCS11Exception(CKR_DEVICE_REMOVED);
-+ return;
-+ }
-+
-+ status = CKYApplet_SelectFile(conn, aid, NULL);
- if ( status == CKYSCARDERR ) handleConnectionError();
- if ( status != CKYSUCCESS) {
- // could not select applet: this just means it's not there
- disconnect();
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- }
-+ if (mOldCAC) {
-+ return;
-+ }
-+ status = CACApplet_SelectFile(conn, cardEF[instance], NULL);
-+ if ( status == CKYSCARDERR ) handleConnectionError();
-+ if ( status != CKYSUCCESS) {
-+ disconnect();
-+ throw PKCS11Exception(CKR_DEVICE_REMOVED);
-+ }
- }
- // assume we are already in a transaction
- void
-@@ -2059,10 +2179,85 @@ Slot::fetchCombinedObjects(const CKYBuff
- return objInfoList;
- }
-
-+CKYStatus
-+Slot::readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
-+ bool throwException)
-+{
-+ CKYStatus status;
-+ CKYISOStatus apduRC;
-+
-+ if (mOldCAC) {
-+ /* get the first 100 bytes of the cert */
-+ status = CACApplet_GetCertificateFirst(conn, cert, nextSize, &apduRC);
-+ if (throwException && (status != CKYSUCCESS)) {
-+ handleConnectionError();
-+ }
-+ return status;
-+ }
-+
-+ CKYBuffer tBuf;
-+ CKYBuffer vBuf;
-+ CKYSize tlen, vlen;
-+ CKYOffset toffset, voffset;
-+ int length = 0;
-+
-+ CKYBuffer_InitEmpty(&tBuf);
-+ CKYBuffer_InitEmpty(&vBuf);
-+ CKYBuffer_Resize(cert, 0);
-+
-+ /* handle the new CAC card read */
-+ /* read the TLV */
-+ status = CACApplet_ReadFile(conn, CAC_TAG_FILE, &tBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ status = CACApplet_ReadFile(conn, CAC_VALUE_FILE, &vBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ tlen = CKYBuffer_Size(&tBuf);
-+ vlen = CKYBuffer_Size(&vBuf);
-+
-+ /* look for the Cert out of the TLV */
-+ for(toffset = 2, voffset=2; toffset < tlen && voffset < vlen ;
-+ voffset += length) {
-+
-+ CKYByte tag = CKYBuffer_GetChar(&tBuf, toffset);
-+ length = CKYBuffer_GetChar(&tBuf, toffset+1);
-+ toffset += 2;
-+ if (length == 0xff) {
-+ length = CKYBuffer_GetShortLE(&tBuf, toffset);
-+ toffset +=2;
-+ }
-+ if (tag != CAC_TAG_CERTIFICATE) {
-+ continue;
-+ }
-+ CKYBuffer_AppendBuffer(cert, &vBuf, voffset, length);
-+ break;
-+ }
-+ status = CKYSUCCESS;
-+
-+done:
-+ CKYBuffer_FreeData(&tBuf);
-+ CKYBuffer_FreeData(&vBuf);
-+ return status;
-+}
-+
-+/*
-+ * only necessary for old CAC cards. New CAC cards have to read the
-+ * whole cert in anyway above....
-+ */
-+CKYStatus
-+Slot::readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize)
-+{
-+ CKYISOStatus apduRC;
-+ assert(mOldCAC);
-+ return CACApplet_GetCertificateAppend(conn, cert, nextSize, &apduRC);
-+}
-+
- void
- Slot::loadCACCert(CKYByte instance)
- {
-- CKYISOStatus apduRC;
- CKYStatus status = CKYSUCCESS;
- CKYBuffer cert;
- CKYBuffer rawCert;
-@@ -2097,12 +2292,7 @@ Slot::loadCACCert(CKYByte instance)
- instance, OSTimeNow() - time);
-
- if (instance == 0) {
-- /* get the first 100 bytes of the cert */
-- status = CACApplet_GetCertificateFirst(conn, &rawCert,
-- &nextSize, &apduRC);
-- if (status != CKYSUCCESS) {
-- handleConnectionError();
-- }
-+ readCACCertificateFirst(&rawCert, &nextSize, true);
- log->log("CAC Cert %d: fetch CAC Cert: %d ms\n",
- instance, OSTimeNow() - time);
- }
-@@ -2143,8 +2333,7 @@ Slot::loadCACCert(CKYByte instance)
- shmem.setVersion(SHMEM_VERSION);
- shmem.setDataVersion(dataVersion);
- } else {
-- status = CACApplet_GetCertificateFirst(conn, &rawCert,
-- &nextSize, &apduRC);
-+ status = readCACCertificateFirst(&rawCert, &nextSize, false);
-
- if (status != CKYSUCCESS) {
- /* CAC only requires the Certificate in pki '0' */
-@@ -2159,8 +2348,7 @@ Slot::loadCACCert(CKYByte instance)
- }
-
- if (nextSize) {
-- status = CACApplet_GetCertificateAppend(conn, &rawCert,
-- nextSize, &apduRC);
-+ status = readCACCertificateAppend(&rawCert, nextSize);
- }
- log->log("CAC Cert %d: Fetch rest : %d ms\n",
- instance, OSTimeNow() - time);
-@@ -2176,9 +2364,10 @@ Slot::loadCACCert(CKYByte instance)
-
- log->log("CAC Cert %d: Cert has been read: %d ms\n",
- instance, OSTimeNow() - time);
-- if (CKYBuffer_GetChar(&rawCert,0) == 1) {
-+ if (!mOldCAC || CKYBuffer_GetChar(&rawCert,0) == 1) {
- CKYSize guessFinalSize = CKYBuffer_Size(&rawCert);
- CKYSize certSize = 0;
-+ CKYOffset offset = mOldCAC ? 1 : 0;
- int zret = Z_MEM_ERROR;
-
- do {
-@@ -2189,7 +2378,8 @@ Slot::loadCACCert(CKYByte instance)
- }
- certSize = guessFinalSize;
- zret = uncompress((Bytef *)CKYBuffer_Data(&cert),&certSize,
-- CKYBuffer_Data(&rawCert)+1, CKYBuffer_Size(&rawCert)-1);
-+ CKYBuffer_Data(&rawCert)+offset,
-+ CKYBuffer_Size(&rawCert)-offset);
- } while (zret == Z_BUF_ERROR);
-
- if (zret != Z_OK) {
-@@ -2526,7 +2716,7 @@ Slot::attemptCACLogin()
- switch( result ) {
- case CKYISO_SUCCESS:
- break;
-- case 6981:
-+ case 0x6981:
- throw PKCS11Exception(CKR_PIN_LOCKED);
- default:
- if ((result & 0xff00) == 0x6300) {
-diff -up ./src/coolkey/slot.h.cac ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.cac 2010-06-16 13:43:51.344185000 -0700
-+++ ./src/coolkey/slot.h 2010-06-16 13:43:51.546179000 -0700
-@@ -294,6 +294,7 @@ class CryptParams {
- const CKYBuffer *paddedOutput) const = 0;
- };
-
-+#define MAX_CERT_SLOTS 3
- class Slot {
-
- public:
-@@ -328,6 +329,8 @@ class Slot {
- CKYBuffer nonce;
- CKYBuffer cardATR;
- CKYBuffer mCUID;
-+ CKYBuffer cardAID[MAX_CERT_SLOTS];
-+ unsigned short cardEF[MAX_CERT_SLOTS];
- bool isVersion1Key;
- bool needLogin;
- long publicFree;
-@@ -335,6 +338,7 @@ class Slot {
- long privateFree;
- bool fullTokenName;
- bool mCoolkey;
-+ bool mOldCAC;
-
- //enum { RW_SESSION_HANDLE = 1, RO_SESSION_HANDLE = 2 };
-
-@@ -398,6 +402,11 @@ class Slot {
- list<ListObjectInfo> fetchCombinedObjects(const CKYBuffer *header);
- list<ListObjectInfo> fetchSeparateObjects();
-
-+ CKYStatus getCACAid();
-+ CKYStatus readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
-+ bool throwException);
-+ CKYStatus readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize);
-+
- void selectApplet();
- void selectCACApplet(CKYByte instance);
- void unloadObjects();
-diff -up ./src/libckyapplet/cky_applet.c.cac ./src/libckyapplet/cky_applet.c
---- ./src/libckyapplet/cky_applet.c.cac 2010-06-16 13:43:51.357181000 -0700
-+++ ./src/libckyapplet/cky_applet.c 2010-06-16 14:47:41.305529000 -0700
-@@ -41,7 +41,13 @@
- CKYStatus
- CKYAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
- {
-- return CKYAPDUFactory_SelectFile(apdu,(const CKYBuffer *)param);
-+ return CKYAPDUFactory_SelectFile(apdu, 4, 0, (const CKYBuffer *)param);
-+}
-+
-+CKYStatus
-+CACAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectFile(apdu, 2, 12, (const CKYBuffer *)param);
- }
-
- CKYStatus
-@@ -225,10 +231,17 @@ CKYAppletFactory_GetBuiltinACL(CKYAPDU *
- }
-
- CKYStatus
--CACAppletFactory_SignDecrypt(CKYAPDU *apdu, const void *param)
-+CACAppletFactory_SignDecryptStep(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYBuffer *buf=(CKYBuffer *)param;
-+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_STEP, buf);
-+}
-+
-+CKYStatus
-+CACAppletFactory_SignDecryptFinal(CKYAPDU *apdu, const void *param)
- {
- const CKYBuffer *buf=(CKYBuffer *)param;
-- return CACAPDUFactory_SignDecrypt(apdu, buf);
-+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_FINAL, buf);
- }
-
- CKYStatus
-@@ -246,6 +259,13 @@ CACAppletFactory_GetCertificate(CKYAPDU
- }
-
- CKYStatus
-+CACAppletFactory_ReadFile(CKYAPDU *apdu, const void *param)
-+{
-+ const CACAppletArgReadFile *rfs = (const CACAppletArgReadFile *)param;
-+ return CACAPDUFactory_ReadFile(apdu, rfs->offset, rfs->type, rfs->count);
-+}
-+
-+CKYStatus
- CACAppletFactory_GetProperties(CKYAPDU *apdu, const void *param)
- {
- return CACAPDUFactory_GetProperties(apdu);
-@@ -457,7 +477,7 @@ CKYApplet_SelectFile(CKYCardConnection *
- CKYISOStatus *apduRC)
- {
- return CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, AID, NULL,
-- 0, CKYAppletFill_Null, NULL, apduRC);
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
- }
-
- static CKYByte coolkeyid[] = {0x62, 0x76, 0x01, 0xff, 0x00, 0x00, 0x00 };
-@@ -477,22 +497,23 @@ CKYApplet_SelectCoolKeyManager(CKYCardCo
- return ret;
- }
-
--static CKYByte CACPKIid[] = {0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00 };
-+static CKYByte CACPKIid[] = { 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01 };
- /*
- * Select the CoolKey applet. Must happen after we start a transaction and
- * before we issue any applet specific command.
- */
- CKYStatus
--CACApplet_SelectPKI(CKYCardConnection *conn, CKYByte instance,
-- CKYISOStatus *apduRC)
-+CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cacAID,
-+ CKYByte instance, CKYISOStatus *apduRC)
- {
- CKYStatus ret;
-- CKYBuffer CACPKIAID;
-- CKYBuffer_InitFromData(&CACPKIAID, CACPKIid, sizeof(CACPKIid));
-- CKYBuffer_SetChar(&CACPKIAID, 6, instance);
-- ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CACPKIAID,
-+ CKYBuffer_AppendData(cacAID, CACPKIid, sizeof(CACPKIid));
-+ CKYBuffer_AppendChar(cacAID, instance);
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, cacAID,
- NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-- CKYBuffer_FreeData(&CACPKIAID);
-+ if (ret != CKYSUCCESS) {
-+ CKYBuffer_Resize(cacAID, 0);
-+ }
- return ret;
- }
-
-@@ -515,11 +536,38 @@ CACApplet_SelectCardManager(CKYCardConne
- CKYBuffer CAC_CM_AID;
- CKYBuffer_InitFromData(&CAC_CM_AID, cacmgrid, sizeof(cacmgrid));
- ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
-- NULL, 0, CKYAppletFill_Null, NULL, apduRC);
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
- CKYBuffer_FreeData(&CAC_CM_AID);
- return ret;
- }
-
-+static CKYByte cacCCCid[] = {0xa0, 0x00, 0x00, 0x01, 0x16, 0xdb, 0x00 };
-+CKYStatus
-+CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer CAC_CM_AID;
-+ CKYBuffer_InitFromData(&CAC_CM_AID, cacCCCid, sizeof(cacCCCid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&CAC_CM_AID);
-+ return ret;
-+}
-+
-+CKYStatus
-+CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShortLE(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
- /*
- * GetCPLC cluster -- must be called with CM selected
- */
-@@ -673,8 +721,8 @@ CKYApplet_ComputeCryptProcess(CKYCardCon
- ccd.keyNumber = keyNumber;
- ccd.location = location;
- ccd.data = data;
-- return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptProcess, &ccd,
-- nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptProcess,
-+ &ccd, nonce, 0, CKYAppletFill_Null, NULL, apduRC);
- }
-
- /* computeCrypt returns data in the form :
-@@ -832,11 +880,39 @@ CACApplet_SignDecrypt(CKYCardConnection
- CKYBuffer *result, CKYISOStatus *apduRC)
- {
- CKYStatus ret;
--
-- ret = CKYApplet_HandleAPDU(conn,
-- CACAppletFactory_SignDecrypt, data, NULL,
-- CKYBuffer_Size(data), CKYAppletFill_ReplaceBuffer,
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+
-+ CKYBuffer_Resize(result, 0);
-+ for(offset = 0; (dataSize-offset) > CKY_MAX_WRITE_CHUNK_SIZE;
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE) {
-+ CKYBuffer_Resize(&tmp,0);
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, CKY_MAX_WRITE_CHUNK_SIZE);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptStep,
-+ &tmp, NULL, CKY_SIZE_UNKNOWN,
-+ CKYAppletFill_AppendBuffer,
- result, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ }
-+ CKYBuffer_Resize(&tmp,0);
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, dataSize - offset);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptFinal,
-+ &tmp, NULL, CKY_SIZE_UNKNOWN,
-+ CKYAppletFill_AppendBuffer,
-+ result, apduRC);
-+
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(result) != dataSize)) {
-+ /* RSA returns the same data size as input, didn't happen, so
-+ * something is wrong. */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
- return ret;
- }
-
-@@ -895,6 +971,63 @@ CACApplet_GetCertificate(CKYCardConnecti
- }
- return ret;
- }
-+
-+/*
-+ * Read a CAC Tag/Value file
-+ */
-+CKYStatus
-+CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type, CKYBuffer *buffer,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYByte maxtransfer;
-+ unsigned short offset = 0;
-+ unsigned short size;
-+ CACAppletArgReadFile rfs;
-+
-+ CKYBuffer_Resize(buffer,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+ rfs.offset = 0;
-+ rfs.count = 2;
-+ rfs.type = type;
-+
-+ /* APDU's are expensive, Grab a big chunk of the file first if possible */
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_ReadFile, &rfs, NULL,
-+ rfs.count, CKYAppletFill_AppendBuffer,
-+ buffer, apduRC);
-+ /* file is probably smaller than 100 bytes, get the actual size first */
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ size = CKYBuffer_GetShortLE(buffer, 0) + 2 /* include the length itself */;
-+ maxtransfer = CKY_MAX_READ_CHUNK_SIZE;
-+ /* get the rest of the buffer if necessary */
-+ for (offset = CKYBuffer_Size(buffer); size > offset;
-+ offset = CKYBuffer_Size(buffer)) {
-+ rfs.offset = offset;
-+ rfs.count = MIN(size - offset, maxtransfer);
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_ReadFile, &rfs, NULL,
-+ rfs.count, CKYAppletFill_AppendBuffer,
-+ buffer, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ if (*apduRC == CAC_INVALID_PARAMS) {
-+ maxtransfer = maxtransfer/2;
-+ if (maxtransfer == 0) {
-+ return ret;
-+ }
-+ } else {
-+ return ret;
-+ }
-+ }
-+ }
-+ return ret;
-+}
-+
- CKYStatus
- CACApplet_GetCertificateFirst(CKYCardConnection *conn, CKYBuffer *cert,
- CKYSize *nextSize, CKYISOStatus *apduRC)
-diff -up ./src/libckyapplet/cky_applet.h.cac ./src/libckyapplet/cky_applet.h
---- ./src/libckyapplet/cky_applet.h.cac 2010-06-16 13:43:51.370181000 -0700
-+++ ./src/libckyapplet/cky_applet.h 2010-06-16 13:43:51.572179000 -0700
-@@ -71,6 +71,15 @@ typedef unsigned short CKYISOStatus; /*
- #define CKYISO_INTERNAL_ERROR 0x9cff /* Reserved for debugging,
- * shouldn't happen */
-
-+#define CAC_INVALID_PARAMS 0x6a83
-+#define CAC_TAG_FILE 1
-+#define CAC_VALUE_FILE 2
-+
-+
-+#define CAC_TAG_CARDURL 0xf3
-+#define CAC_TAG_CERTIFICATE 0x70
-+#define CAC_TLV_APP_PKI 0x04
-+
- /*
- * Pin Constants as used by our applet
- */
-@@ -209,6 +218,12 @@ typedef struct _CKYAppletArgComputeCrypt
- const CKYBuffer *sig;
- } CKYAppletArgComputeCrypt;
-
-+typedef struct _CACAppletArgReadFile {
-+ CKYByte type;
-+ CKYByte count;
-+ unsigned short offset;
-+} CACAppletArgReadFile;
-+
- /* fills in an APDU from a structure -- form of all the generic factories*/
- typedef CKYStatus (*CKYAppletFactory)(CKYAPDU *apdu, const void *param);
- /* fills in an a structure from a response -- form of all the fill structures*/
-@@ -451,9 +466,17 @@ CKYStatus CKYApplet_DeleteObject(CKYCard
- /* Select the CAC card manager. Can happen with either applet selected */
- CKYStatus CACApplet_SelectCardManager(CKYCardConnection *conn,
- CKYISOStatus *apduRC);
--/* Can happen with either applet selected */
--CKYStatus CACApplet_SelectPKI(CKYCardConnection *conn, CKYByte instance,
-- CKYISOStatus *apduRC);
-+/* Select the CAC CC container. Can happen with either applet selected */
-+CKYStatus CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+/* Select an old CAC applet and fill in the cardAID */
-+CKYStatus CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cardAid,
-+ CKYByte instance, CKYISOStatus *apduRC);
-+/* read a TLV file */
-+CKYStatus CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type,
-+ CKYBuffer *buffer, CKYISOStatus *apduRC);
-+CKYStatus CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+
- /* must happen with PKI applet selected */
- CKYStatus CACApplet_SignDecrypt(CKYCardConnection *conn, const CKYBuffer *data,
- CKYBuffer *result, CKYISOStatus *apduRC);
-diff -up ./src/libckyapplet/cky_base.c.cac ./src/libckyapplet/cky_base.c
---- ./src/libckyapplet/cky_base.c.cac 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_base.c 2010-06-16 13:43:51.583179000 -0700
-@@ -220,6 +220,22 @@ CKYBuffer_AppendShort(CKYBuffer *buf, un
- return CKYSUCCESS;
- }
-
-+/* append a short in network order */
-+CKYStatus
-+CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 2;
-+ return CKYSUCCESS;
-+}
-+
- /* append a long in applet order */
- CKYStatus
- CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val)
-@@ -238,6 +254,24 @@ CKYBuffer_AppendLong(CKYBuffer *buf, uns
- return CKYSUCCESS;
- }
-
-+/* append a long in applet order */
-+CKYStatus
-+CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+3] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[buf->len+2] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 4;
-+ return CKYSUCCESS;
-+}
-+
- CKYStatus
- CKYBuffer_Replace(CKYBuffer *buf, CKYOffset offset, const CKYByte *data, CKYSize len)
- {
-@@ -351,6 +385,22 @@ CKYBuffer_SetShort(CKYBuffer *buf, CKYOf
- }
-
- CKYStatus
-+CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+2) {
-+ ret = CKYBuffer_Resize(buf,offset+2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
- CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val)
- {
- CKYStatus ret;
-@@ -368,6 +418,24 @@ CKYBuffer_SetLong(CKYBuffer *buf, CKYOff
- return CKYSUCCESS;
- }
-
-+CKYStatus
-+CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+4) {
-+ ret = CKYBuffer_Resize(buf,offset+4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+3] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[offset+2] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
- CKYByte
- CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset)
- {
-@@ -388,6 +456,18 @@ CKYBuffer_GetShort(const CKYBuffer *buf,
- val |= ((unsigned short)buf->data[offset+1]) << 0;
- return val;
- }
-+
-+unsigned short
-+CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned short val;
-+ if (buf->len < offset+2) {
-+ return 0;
-+ }
-+ val = ((unsigned short)buf->data[offset+1]) << 8;
-+ val |= ((unsigned short)buf->data[offset+0]) << 0;
-+ return val;
-+}
-
- unsigned long
- CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset)
-@@ -402,6 +482,20 @@ CKYBuffer_GetLong(const CKYBuffer *buf,
- val |= ((unsigned long)buf->data[offset+3]) << 0;
- return val;
- }
-+
-+unsigned long
-+CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned long val;
-+ if (buf->len < offset+4) {
-+ return 0;
-+ }
-+ val = ((unsigned long)buf->data[offset+3]) << 24;
-+ val |= ((unsigned long)buf->data[offset+2]) << 16;
-+ val |= ((unsigned long)buf->data[offset+1]) << 8;
-+ val |= ((unsigned long)buf->data[offset+0]) << 0;
-+ return val;
-+}
-
- CKYStatus
- CKYBuffer_Resize(CKYBuffer *buf, CKYSize newLen)
-diff -up ./src/libckyapplet/cky_base.h.cac ./src/libckyapplet/cky_base.h
---- ./src/libckyapplet/cky_base.h.cac 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_base.h 2010-06-16 13:43:51.592179000 -0700
-@@ -170,9 +170,15 @@ CKYStatus CKYBuffer_AppendChar(CKYBuffer
- /* append a short in applet order */
- CKYStatus CKYBuffer_AppendShort(CKYBuffer *buf, unsigned short val);
-
-+/* append a short in little endian order */
-+CKYStatus CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val);
-+
- /* append a long in applet order */
- CKYStatus CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val);
-
-+/* append a long in little endian order */
-+CKYStatus CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val);
-+
- /* append data. the data starts at data and extends len bytes */
- CKYStatus CKYBuffer_AppendData(CKYBuffer *buf, const CKYByte *data, CKYSize len);
-
-@@ -210,12 +216,18 @@ CKYStatus CKYBuffer_SetChars(CKYBuffer *
- CKYStatus CKYBuffer_SetShort(CKYBuffer *buf, CKYOffset offset, unsigned short val);
- CKYStatus CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val);
-
-+/* These functions work in little endian order */
-+CKYStatus CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val);
-+CKYStatus CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val);
- /* read a character from offset. If offset is beyond the end of the buffer,
- * then the function returns '0' */
- CKYByte CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset);
- /* These functions work in applet order */
- unsigned short CKYBuffer_GetShort(const CKYBuffer *buf, CKYOffset offset);
- unsigned long CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset);
-+/* These functions work in little endian order */
-+unsigned short CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset);
-+unsigned long CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset);
-
- /* clear out all the data in a buffer */
- void CKYBuffer_Zero(CKYBuffer *buf);
-diff -up ./src/libckyapplet/cky_factory.c.cac ./src/libckyapplet/cky_factory.c
---- ./src/libckyapplet/cky_factory.c.cac 2010-06-16 13:43:51.393185000 -0700
-+++ ./src/libckyapplet/cky_factory.c 2010-06-16 14:48:08.885473000 -0700
-@@ -25,12 +25,13 @@
- * special commands can be issued at any time
- */
- CKYStatus
--CKYAPDUFactory_SelectFile(CKYAPDU *apdu, const CKYBuffer *AID)
-+CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ const CKYBuffer *AID)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
- CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE);
-- CKYAPDU_SetP1(apdu, 0x04);
-- CKYAPDU_SetP2(apdu, 0x00);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
- return CKYAPDU_SetSendDataBuffer(apdu, AID);
- }
-
-@@ -131,6 +132,7 @@ fail:
- return ret;
- }
-
-+
- CKYStatus
- CKYAPDUFactory_ComputeCryptFinal(CKYAPDU *apdu, CKYByte keyNumber,
- CKYByte location, const CKYBuffer *data, const CKYBuffer *sig)
-@@ -572,11 +574,11 @@ CKYAPDUFactory_GetBuiltinACL(CKYAPDU *ap
- }
-
- CKYStatus
--CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, const CKYBuffer *data)
-+CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type, const CKYBuffer *data)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
- CKYAPDU_SetINS(apdu, CAC_INS_SIGN_DECRYPT);
-- CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP1(apdu, type);
- CKYAPDU_SetP2(apdu, 0x00);
- return CKYAPDU_SetSendDataBuffer(apdu, data);
- }
-@@ -592,6 +594,36 @@ CACAPDUFactory_GetCertificate(CKYAPDU *a
- }
-
- CKYStatus
-+CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte type, CKYByte count)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM);
-+ CKYAPDU_SetINS(apdu, CAC_INS_READ_FILE);
-+ CKYAPDU_SetP1(apdu, (offset >> 8) & 0xff);
-+ CKYAPDU_SetP2(apdu, offset & 0xff);
-+ ret = CKYBuffer_Reserve(&buf, 2);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, type);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, count);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
- CACAPDUFactory_GetProperties(CKYAPDU *apdu)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-diff -up ./src/libckyapplet/cky_factory.h.cac ./src/libckyapplet/cky_factory.h
---- ./src/libckyapplet/cky_factory.h.cac 2010-06-16 13:43:51.402181000 -0700
-+++ ./src/libckyapplet/cky_factory.h 2010-06-16 14:43:20.867049000 -0700
-@@ -86,7 +86,11 @@
- #define CAC_INS_SIGN_DECRYPT 0x42
- #define CAC_INS_VERIFY_PIN 0x20
- #define CAC_INS_GET_PROPERTIES 0x56
-+#define CAC_INS_READ_FILE 0x52
-+
- #define CAC_SIZE_GET_PROPERTIES 48
-+#define CAC_P1_STEP 0x80
-+#define CAC_P1_FINAL 0x00
-
- /*
- * Fixed return sized from various commands
-@@ -169,7 +173,8 @@
- CKY_BEGIN_PROTOS
-
- /* function based factorys */
--CKYStatus CKYAPDUFactory_SelectFile(CKYAPDU *apdu, const CKYBuffer *AID);
-+CKYStatus CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ const CKYBuffer *AID);
- CKYStatus CKYAPDUFactory_SelectCardManager(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_GetCPLCData(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_ListKeys(CKYAPDU *apdu, CKYByte sequence);
-@@ -211,9 +216,12 @@ CKYStatus CKYAPDUFactory_SeedRandom(CKYA
- CKYStatus CKYAPDUFactory_GetIssuerInfo(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_GetBuiltinACL(CKYAPDU *apdu);
-
--CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, const CKYBuffer *data);
-+CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type,
-+ const CKYBuffer *data);
- CKYStatus CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin);
- CKYStatus CACAPDUFactory_GetCertificate(CKYAPDU *apdu, CKYSize size);
-+CKYStatus CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte type, CKYByte count);
- CKYStatus CACAPDUFactory_GetProperties(CKYAPDU *apdu);
-
- CKY_END_PROTOS
diff --git a/coolkey-cache-dir-move.patch b/coolkey-cache-dir-move.patch
deleted file mode 100644
index 1b5eaff..0000000
--- a/coolkey-cache-dir-move.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-Index: src/coolkey/machdep.cpp
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/machdep.cpp,v
-retrieving revision 1.4
-diff -u -r1.4 machdep.cpp
---- src/coolkey/machdep.cpp 14 Feb 2007 00:46:28 -0000 1.4
-+++ src/coolkey/machdep.cpp 15 Aug 2007 01:41:11 -0000
-@@ -185,12 +185,20 @@
- #define MAP_INHERIT 0
- #endif
-
-+#ifndef BASEPATH
-+#ifdef MAC
-+#define BASEPATH "/var"
-+#else
-+#define BASEPATH "/var/cache"
-+#endif
-+#endif
-+
- #ifdef FULL_CLEANUP
- #define RESERVED_OFFSET 256
--#define MEMSEGPATH "/tmp/.pk11ipc"
-+#define MEMSEGPATH BASEPATH"/coolkey-lock"
- #else
- #define RESERVED_OFFSET 0
--#define MEMSEGPATH "/tmp/.pk11ipc1"
-+#define MEMSEGPATH BASEPATH"/coolkey"
- #endif
-
- struct SHMemData {
-@@ -208,11 +216,6 @@
- #ifdef FULL_CLEANUP
- flock(fd,LOCK_EX);
- unsigned long ref = --(*(unsigned long *)addr);
--#ifdef notdef
-- if (ref == 0) {
-- unlink(path);
-- }
--#endif
- flock(fd, LOCK_UN);
- #endif
- munmap(addr,size+RESERVED_OFFSET);
-@@ -225,6 +228,73 @@
- }
- }
-
-+/*
-+ * The cache directory is shared and accessible by anyone, make
-+ * sure the cache file we are opening is really a valid cache file.
-+ */
-+int safe_open(char *path, int flags, int mode, int size)
-+{
-+ struct stat buf;
-+ int fd, ret;
-+
-+ fd = open (path, flags|O_NOFOLLOW, mode);
-+
-+ if (fd < 0) {
-+ return fd;
-+ }
-+
-+ ret = fstat(fd, &buf);
-+ if (ret < 0) {
-+ close (fd);
-+ return ret;
-+ }
-+
-+ /* our cache files are pretty specific, make sure we are looking
-+ * at the correct one */
-+
-+ /* first, we should own the file ourselves, don't open a file
-+ * that someone else wanted us to see. */
-+ if (buf.st_uid != getuid()) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* next, there should only be one link in this file. Don't
-+ * use this code to trash another file */
-+ if (buf.st_nlink != 1) {
-+ close(fd);
-+ errno = EMLINK;
-+ return -1;
-+ }
-+
-+ /* next, This better be a regular file */
-+ if (!S_ISREG(buf.st_mode)) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* if the permissions don't match, something is wrong */
-+ if ((buf.st_mode & 03777) != mode) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* finally the file should be the correct size. This
-+ * check isn't so much to protect from an attack, as it is to
-+ * detect a corrupted cache file */
-+ if (buf.st_size != size) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* OK, the file checked out, ok to continue */
-+ return fd;
-+}
-+
- SHMem::SHMem(): shmemData(0) {}
-
- SHMem *
-@@ -248,7 +318,7 @@
- return NULL;
- }
- int mask = umask(0);
-- int ret = mkdir (MEMSEGPATH, 0777);
-+ int ret = mkdir (MEMSEGPATH, 01777);
- umask(mask);
- if ((ret == -1) && (errno != EEXIST)) {
- delete shmemData;
-@@ -264,21 +334,16 @@
- shmemData->path[sizeof(MEMSEGPATH)-1] = '/';
- strcpy(&shmemData->path[sizeof(MEMSEGPATH)],name);
-
-- int mode = 0777;
-- if (strcmp(name,"token_names") != 0) {
-- /* each user gets his own uid array */
-- sprintf(uid_str, "-%u",getuid());
-- strcat(shmemData->path,uid_str);
-- mode = 0700;
-- }
-+ sprintf(uid_str, "-%u",getuid());
-+ strcat(shmemData->path,uid_str);
-+ int mode = 0600;
-+
- shmemData->fd = open(shmemData->path,
- O_CREAT|O_RDWR|O_EXCL|O_APPEND|O_EXLOCK, mode);
-- if (shmemData->fd < 0) {
-- needInit = false;
-- shmemData->fd = open(shmemData->path,O_RDWR|O_EXLOCK, mode);
-- } else {
-+ if (shmemData->fd >= 0) {
- char *buf;
- int len = size+RESERVED_OFFSET;
-+ int ret;
-
- buf = (char *)calloc(1,len);
- if (!buf) {
-@@ -289,8 +354,22 @@
- delete shmemData;
- return NULL;
- }
-- write(shmemData->fd,buf,len);
-+ ret = write(shmemData->fd,buf,len);
-+ if (ret != len) {
-+ unlink(shmemData->path);
-+#ifdef FULL_CLEANUP
-+ flock(shmemData->fd, LOCK_UN);
-+#endif
-+ delete shmemData;
-+ return NULL;
-+ }
-+
- free(buf);
-+ } else if (errno == EEXIST) {
-+ needInit = false;
-+
-+ shmemData->fd = safe_open(shmemData->path,O_RDWR|O_EXLOCK, mode,
-+ size+RESERVED_OFFSET);
- }
- if (shmemData->fd < 0) {
- delete shmemData;
diff --git a/coolkey-fix-token-removal-failure.patch b/coolkey-fix-token-removal-failure.patch
deleted file mode 100644
index 7f8a954..0000000
--- a/coolkey-fix-token-removal-failure.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-Fix insertion/removal detection
-
-pcsc now errors out of the SCardGetStatusChange call with
-SCARD_E_UNKNOWN_READER if any of the passed readers aren't known.
-This includes readers that were very recently forgotton about because
-a user just disconnected them.
-
-(See
- http://anonscm.debian.org/viewvc/pcsclite/trunk/PCSC/src/winscard_clnt.c?...
-for the change to pcsc)
-
-Unfortunately, this means SECMOD_WaitForAnyTokenEvent will fail with a
-SC_NO_EVENT error if a user removes their smartcard at the wrong time.
-
-This patch changes coolkey to detect removed readers before calling
-SCardGetStatusChange, so that it can handle the removal itself.
-
-diff -up coolkey-1.1.0/src/coolkey/slot.cpp.fix coolkey-1.1.0/src/coolkey/slot.cpp
---- coolkey-1.1.0/src/coolkey/slot.cpp.fix 2013-05-22 16:23:41.728846957 -0400
-+++ coolkey-1.1.0/src/coolkey/slot.cpp 2013-05-22 17:09:59.813958927 -0400
-@@ -279,24 +279,22 @@ SlotList::updateReaderList()
- * don't recognize.
- */
-
-- /* first though, let's check to see if any previously removed readers have
-- * come back from the dead. If the ignored bit has been set, we do not need
-- * it any more.
-- */
-+ /* Iterate through all the readers to see if we need to make unavailable any
-+ * freshly removed readers. Also, see if any previously removed
-+ * readers have come back from the dead and don't need to be ignored.
-+ */
-
- const char *curReaderName = NULL;
- unsigned long knownState = 0;
- for(int ri = 0 ; ri < numReaders; ri ++) {
--
- knownState = CKYReader_GetKnownState(&readerStates[ri]);
-- if( !(knownState & SCARD_STATE_IGNORE)) {
-- continue;
-- }
--
-+
- curReaderName = CKYReader_GetReaderName(&readerStates[ri]);
- if(readerNameExistsInList(curReaderName,&readerNames)) {
- CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE);
--
-+ } else {
-+ if (!(knownState & SCARD_STATE_UNAVAILABLE))
-+ CKYReader_SetKnownState(&readerStates[ri], knownState | SCARD_STATE_UNAVAILABLE | SCARD_STATE_CHANGED);
- }
- }
-
-@@ -1238,6 +1236,32 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- throw;
- }
-
-+ /* Before round-tripping to the daemon for the duration of the
-+ * timeout, first see if we lost any readers, and pick a slot
-+ * from that set to return
-+ */
-+ for (i=0; i < numReaders; i++) {
-+ unsigned long knownState = CKYReader_GetKnownState(&readerStates[i]);
-+
-+ if ((knownState & SCARD_STATE_UNAVAILABLE) &&
-+ (knownState & SCARD_STATE_CHANGED)) {
-+ CKYReader_SetKnownState(&readerStates[i], knownState & ~SCARD_STATE_CHANGED);
-+ readerListLock.releaseLock();
-+ *slotp = slotIndexToID(i);
-+ found = TRUE;
-+ break;
-+ }
-+ }
-+
-+ if (found) {
-+ break;
-+ }
-+
-+ if (shuttingDown) {
-+ readerListLock.releaseLock();
-+ break;
-+ }
-+
- if (myNumReaders != numReaders) {
- if (myReaderStates) {
- delete [] myReaderStates;
diff --git a/coolkey-gcc43.patch b/coolkey-gcc43.patch
deleted file mode 100644
index 5e41b5a..0000000
--- a/coolkey-gcc43.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.coolkey-gcc43 ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-gcc43 2008-02-13 18:01:45.000000000 -0800
-+++ ./src/coolkey/slot.cpp 2008-02-13 18:03:05.000000000 -0800
-@@ -25,7 +25,6 @@
- #include "PKCS11Exception.h"
- #include <winscard.h>
- #include "slot.h"
--#include <memory.h>
- #include "zlib.h"
- #include "params.h"
-
-@@ -33,7 +32,6 @@
-
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
-
--using std::auto_ptr;
-
-
- #ifdef DEBUG
-diff -up ./src/coolkey/machdep.cpp.coolkey-gcc43 ./src/coolkey/machdep.cpp
---- ./src/coolkey/machdep.cpp.coolkey-gcc43 2008-02-13 18:02:06.000000000 -0800
-+++ ./src/coolkey/machdep.cpp 2008-02-13 18:04:04.000000000 -0800
-@@ -33,6 +33,8 @@
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <pthread.h>
-+#include <string.h>
-+#include <stdlib.h>
- #endif
-
- #ifdef _WIN32
-diff -up ./src/coolkey/log.cpp.coolkey-gcc43 ./src/coolkey/log.cpp
---- ./src/coolkey/log.cpp.coolkey-gcc43 2008-02-13 18:01:55.000000000 -0800
-+++ ./src/coolkey/log.cpp 2008-02-13 18:03:37.000000000 -0800
-@@ -18,6 +18,8 @@
- * ***** END COPYRIGHT BLOCK *****/
-
- #include <string>
-+#include <string.h>
-+#include <stdlib.h>
- #include "mypkcs11.h"
- #include <assert.h>
- #include <stdio.h>
-diff -up ./src/coolkey/object.cpp.coolkey-gcc43 ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.coolkey-gcc43 2008-02-13 18:02:20.000000000 -0800
-+++ ./src/coolkey/object.cpp 2008-02-13 18:04:22.000000000 -0800
-@@ -21,6 +21,7 @@
- #include "PKCS11Exception.h"
- #include "object.h"
- #include <algorithm>
-+#include <string.h>
-
- using std::find_if;
-
diff --git a/coolkey-latest.patch b/coolkey-latest.patch
deleted file mode 100644
index bc10eb8..0000000
--- a/coolkey-latest.patch
+++ /dev/null
@@ -1,685 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.coolkey-latest ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-latest 2009-09-11 13:58:24.423487305 -0700
-+++ ./src/coolkey/slot.cpp 2009-09-11 14:04:30.813488220 -0700
-@@ -203,6 +203,29 @@ SlotList::readerExists(const char *reade
- return FALSE;
- }
-
-+bool
-+SlotList::readerNameExistsInList(const char *readerName,CKYReaderNameList *readerNameList)
-+{
-+ if( !readerName || !readerNameList) {
-+ return FALSE;
-+ }
-+
-+ int i = 0;
-+ int readerNameCnt = CKYReaderNameList_GetCount(*readerNameList);
-+
-+ const char *curReaderName = NULL;
-+ for(i=0; i < readerNameCnt; i++) {
-+ curReaderName = CKYReaderNameList_GetValue(*readerNameList,i);
-+
-+ if(!strcmp(curReaderName,readerName)) {
-+ return TRUE;
-+ }
-+
-+ }
-+
-+ return FALSE;
-+}
-+
- /*
- * you need to hold the ReaderList Lock before you can update the ReaderList
- */
-@@ -256,6 +279,27 @@ SlotList::updateReaderList()
- * don't recognize.
- */
-
-+ /* first though, let's check to see if any previously removed readers have
-+ * come back from the dead. If the ignored bit has been set, we do not need
-+ * it any more.
-+ */
-+
-+ const char *curReaderName = NULL;
-+ unsigned long knownState = 0;
-+ for(int ri = 0 ; ri < numReaders; ri ++) {
-+
-+ knownState = CKYReader_GetKnownState(&readerStates[ri]);
-+ if( !(knownState & SCARD_STATE_IGNORE)) {
-+ continue;
-+ }
-+
-+ curReaderName = CKYReader_GetReaderName(&readerStates[ri]);
-+ if(readerNameExistsInList(curReaderName,&readerNames)) {
-+ CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE);
-+
-+ }
-+ }
-+
- const char *newReadersData[MAX_READER_DELTA];
- const char **newReaders = &newReadersData[0];
- unsigned int newReaderCount = 0;
-@@ -528,7 +572,7 @@ SlotList::getSlotList(CK_BBOOL tokenPres
- void
- Slot::connectToToken()
- {
-- CKYStatus status;
-+ CKYStatus status = CKYSCARDERR;
- OSTime time = OSTimeNow();
-
- mCoolkey = 0;
-@@ -537,13 +581,31 @@ Slot::connectToToken()
-
- // try to connect to the card
- if( ! CKYCardConnection_IsConnected(conn) ) {
-- status = CKYCardConnection_Connect(conn, readerName);
-- if( status != CKYSUCCESS ) {
-- log->log("Unable to connect to token\n");
-+ int i = 0;
-+ //for cranky readers try again a few more times
-+ while( i++ < 5 && status != CKYSUCCESS )
-+ {
-+ status = CKYCardConnection_Connect(conn, readerName);
-+ if( status != CKYSUCCESS &&
-+ CKYCardConnection_GetLastError(conn) == SCARD_E_PROTO_MISMATCH )
-+ {
-+ log->log("Unable to connect to token status %d ConnGetGetLastError %x .\n",status,CKYCardConnection_GetLastError(conn));
-+
-+ }
-+ else
-+ {
-+ break;
-+ }
-+ OSSleep(100000);
-+ }
-+
-+ if( status != CKYSUCCESS)
-+ {
- state = UNKNOWN;
- return;
- }
- }
-+
- log->log("time connect: Connect Time %d ms\n", OSTimeNow() - time);
- if (!slotInfoFound) {
- readSlotInfo();
-@@ -562,15 +624,10 @@ Slot::connectToToken()
- state = CARD_PRESENT;
- }
-
-- if ( CKYBuffer_DataIsEqual(&cardATR, ATR, sizeof (ATR)) ||
-- CKYBuffer_DataIsEqual(&cardATR, ATR1, sizeof(ATR1)) ||
-- CKYBuffer_DataIsEqual(&cardATR, ATR2, sizeof(ATR2)) ) {
--
-- if (Params::hasParam("noAppletOK"))
-- {
-- state |= APPLET_SELECTABLE;
-- mCoolkey = 1;
-- }
-+ if (Params::hasParam("noAppletOK"))
-+ {
-+ state |= APPLET_SELECTABLE;
-+ mCoolkey = 1;
- }
-
- /* support CAC card. identify the card based on applets, not the ATRS */
-@@ -631,7 +688,7 @@ Slot::connectToToken()
- * unfriendly */
- isVersion1Key = 0;
- needLogin = 1;
--
-+ mCoolkey = 0;
- return;
- }
- mCoolkey = 1;
-@@ -1077,6 +1134,7 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- }
- throw;
- }
-+
- if (myNumReaders != numReaders) {
- if (myReaderStates) {
- delete [] myReaderStates;
-@@ -1103,6 +1161,7 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- }
- }
- }
-+
- if (found || (flag == CKF_DONT_BLOCK) || shuttingDown) {
- break;
- }
-@@ -1272,6 +1331,19 @@ class ObjectHandleMatch {
- }
- };
-
-+class KeyNumMatch {
-+ private:
-+ CKYByte keyNum;
-+ const Slot &slot;
-+ public:
-+ KeyNumMatch(CKYByte keyNum_, const Slot &s) : keyNum(keyNum_), slot(s) { }
-+ bool operator() (const PKCS11Object& obj) {
-+ unsigned long objID = obj.getMuscleObjID();
-+ return (slot.getObjectClass(objID) == 'k')
-+ && (slot.getObjectIndex(objID) == keyNum);
-+ }
-+};
-+
- class ObjectCertCKAIDMatch {
- private:
- CKYByte cka_id;
-@@ -3007,8 +3079,9 @@ Slot::sign(SessionHandleSuffix suffix, C
- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
- {
-+ RSASignatureParams params(CryptParams::DEFAULT_KEY_SIZE);
- cryptRSA(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-- RSASignatureParams(CryptParams::FIXED_KEY_SIZE));
-+ params);
- }
-
- void
-@@ -3016,14 +3089,15 @@ Slot::decrypt(SessionHandleSuffix suffix
- CK_ULONG ulDataLen, CK_BYTE_PTR pDecryptedData,
- CK_ULONG_PTR pulDecryptedDataLen)
- {
-+ RSADecryptParams params(CryptParams::DEFAULT_KEY_SIZE);
- cryptRSA(suffix, pData, ulDataLen, pDecryptedData, pulDecryptedDataLen,
-- RSADecryptParams(CryptParams::FIXED_KEY_SIZE));
-+ params);
- }
-
- void
- Slot::cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
- CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-- CK_ULONG_PTR pulOutputLen, const CryptParams& params)
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params)
- {
- refreshTokenState();
- SessionIter session = findSession(suffix);
-@@ -3041,6 +3115,11 @@ Slot::cryptRSA(SessionHandleSuffix suffi
- CKYBuffer *result = &opState.result;
- CKYByte keyNum = opState.keyNum;
-
-+ unsigned int keySize = getKeySize(keyNum);
-+
-+ if(keySize != CryptParams::DEFAULT_KEY_SIZE)
-+ params.setKeySize(keySize);
-+
- if( CKYBuffer_Size(result) == 0 ) {
- // we haven't already peformed the decryption, so do it now.
- if( pInput == NULL || ulInputLen == 0) {
-@@ -3243,3 +3322,36 @@ Slot::generateRandom(SessionHandleSuffix
- throw PKCS11Exception(CKR_DEVICE_ERROR);
- }
- }
-+
-+#define MAX_NUM_KEYS 8
-+unsigned int
-+Slot::getKeySize(CKYByte keyNum)
-+{
-+ unsigned int keySize = CryptParams::DEFAULT_KEY_SIZE;
-+ int modSize = 0;
-+
-+ if(keyNum >= MAX_NUM_KEYS) {
-+ return keySize;
-+ }
-+
-+ ObjectConstIter iter;
-+ iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-+ KeyNumMatch(keyNum,*this));
-+
-+ if( iter == tokenObjects.end() ) {
-+ return keySize;
-+ }
-+
-+ CKYBuffer const *modulus = iter->getAttribute(CKA_MODULUS);
-+
-+ if(modulus) {
-+ modSize = CKYBuffer_Size(modulus);
-+ if(CKYBuffer_GetChar(modulus,0) == 0x0) {
-+ modSize--;
-+ }
-+ if(modSize > 0)
-+ keySize = modSize * 8;
-+ }
-+
-+ return keySize;
-+}
-diff -up ./src/coolkey/slot.h.coolkey-latest ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.coolkey-latest 2006-06-09 11:39:11.000000000 -0700
-+++ ./src/coolkey/slot.h 2009-09-11 13:58:24.462488099 -0700
-@@ -270,10 +270,9 @@ class CryptParams {
- protected:
- unsigned int getKeySize() const { return keySize; }
- public:
-- // !!!XXX hack. The right way to get the key size is to get all the
-- // key information from the token with MSCListKeys, the same way
-- // we get all the object information with MSCListObjects.
-- enum { FIXED_KEY_SIZE = 1024 };
-+ // set the actual key size obtained from the card
-+ void setKeySize(unsigned int newKeySize) { keySize = newKeySize; }
-+ enum { DEFAULT_KEY_SIZE = 1024 };
-
-
- CryptParams(unsigned int keySize_) : keySize(keySize_) { }
-@@ -422,7 +421,7 @@ class Slot {
-
- void cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
- CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-- CK_ULONG_PTR pulOutputLen, const CryptParams& params);
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params);
-
- void performRSAOp(CKYBuffer *out, const CKYBuffer *input, CKYByte keyNum,
- CKYByte direction);
-@@ -460,6 +459,8 @@ class Slot {
- return (char )((objectID >> 16) & 0xff) - '0';
- }
-
-+ // actually get the size of a key in bits from the card
-+ unsigned int getKeySize(CKYByte keyNum);
-
- SessionHandleSuffix openSession(Session::Type type);
- void closeSession(SessionHandleSuffix handleSuffix);
-@@ -527,6 +528,8 @@ class SlotList {
- * has called 'C_GetSlotList' with a NULL parameter */
- void updateReaderList();
-
-+ /* see if a reader name exists in a caller provided reader name list. */
-+ bool readerNameExistsInList(const char *readerName,CKYReaderNameList *readerNameList );
- bool readerExists(const char *readerName, unsigned int *hint = 0);
- public:
- SlotList(Log *log);
-diff -up ./src/libckyapplet/cky_applet.c.coolkey-latest ./src/libckyapplet/cky_applet.c
---- ./src/libckyapplet/cky_applet.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_applet.c 2009-09-11 13:58:24.464487796 -0700
-@@ -134,6 +134,13 @@ CKYAppletFactory_Logout(CKYAPDU *apdu, c
- /* Future add WriteObject */
-
- CKYStatus
-+CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgWriteObject *wos = (const CKYAppletArgWriteObject *)param;
-+ return CKYAPDUFactory_WriteObject(apdu,wos->objectID,wos->offset,wos->size,wos->data);
-+}
-+
-+CKYStatus
- CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param)
- {
- const CKYAppletArgCreateObject *cos=(const CKYAppletArgCreateObject *)param;
-@@ -192,7 +199,6 @@ CKYAppletFactory_GetLifeCycleV2(CKYAPDU
- {
- return CKYAPDUFactory_GetLifeCycleV2(apdu);
- }
--
- CKYStatus
- CKYAppletFactory_GetRandom(CKYAPDU *apdu, const void *param)
- {
-@@ -725,24 +731,48 @@ CKYApplet_ComputeCrypt(CKYCardConnection
- CKYAppletArgComputeCrypt ccd;
- CKYBuffer empty;
- CKYISOStatus status;
-+ short dataSize = 0;
- int use2APDUs = 0;
-+ int use_dl_object = CKYBuffer_Size(data) > 200 ;
-
- CKYBuffer_InitEmpty(&empty);
- ccd.keyNumber = keyNumber;
- ccd.mode = mode;
- ccd.direction = direction;
-- ccd.location = CKY_DL_APDU;
-+ ccd.location = use_dl_object ? CKY_DL_OBJECT : CKY_DL_APDU;
-
- if (!apduRC)
- apduRC = &status;
-
-+ if (use_dl_object) {
-+ CKYBuffer sizeBuf;
-+
-+ CKYBuffer_InitEmpty(&sizeBuf);
-+ CKYBuffer_AppendShort(&sizeBuf, CKYBuffer_Size(data));
-+
-+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
-+ 0, CKYBuffer_Size(&sizeBuf), nonce,
-+ &sizeBuf, apduRC);
-+
-+ CKYBuffer_FreeData(&sizeBuf);
-+ if( ret != CKYSUCCESS)
-+ goto fail;
-+
-+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
-+ 2, CKYBuffer_Size(data), nonce,
-+ data, apduRC);
-+
-+ if(ret != CKYSUCCESS)
-+ goto fail;
-+ }
-+
- if (mode == CKY_RSA_NO_PAD) {
-- ccd.data = data;
-+ ccd.data = use_dl_object ? &empty : data;
- ccd.sig = sig;
- ret = CKYApplet_HandleAPDU(conn,
- CKYAppletFactory_ComputeCryptOneStep, &ccd, nonce,
- CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
-- result, apduRC);
-+ use_dl_object ? NULL : result, apduRC);
- if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
- use2APDUs = 1; /* maybe it's an old applet */
- }
-@@ -759,13 +789,38 @@ CKYApplet_ComputeCrypt(CKYCardConnection
- CKYAppletFactory_ComputeCryptInit, &ccd, nonce,
- 0, CKYAppletFill_Null, NULL, apduRC);
- if (ret == CKYSUCCESS) {
-- ccd.data = data;
-+ ccd.data = use_dl_object ? &empty : data;
- ret = CKYApplet_HandleAPDU(conn,
- CKYAppletFactory_ComputeCryptFinal, &ccd, nonce,
- CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
-- result, apduRC);
-+ use_dl_object ? NULL : result, apduRC);
- }
- }
-+
-+ if (use_dl_object && ret == CKYSUCCESS) {
-+ CKYBuffer sizeOutBuf;
-+ CKYBuffer_InitEmpty(&sizeOutBuf);
-+
-+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
-+ 0, 2,
-+ nonce,&sizeOutBuf,apduRC);
-+
-+ if(ret != CKYSUCCESS) {
-+ CKYBuffer_FreeData(&sizeOutBuf);
-+ goto fail;
-+ }
-+
-+ dataSize = CKYBuffer_GetShort(&sizeOutBuf, 0);
-+
-+ CKYBuffer_FreeData(&sizeOutBuf);
-+
-+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
-+ 2, dataSize,
-+ nonce,result,apduRC);
-+ }
-+
-+fail:
-+
- return ret;
- }
-
-@@ -1036,6 +1091,44 @@ CKYApplet_ReadObjectFull(CKYCardConnecti
- }
-
- /*
-+ * Write Object
-+ * This makes multiple APDU calls to write the entire object.
-+ *
-+ */
-+
-+CKYStatus
-+CKYApplet_WriteObjectFull(CKYCardConnection *conn, unsigned long objectID,
-+ CKYOffset offset, CKYSize size, const CKYBuffer *nonce,
-+ const CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+
-+ CKYBuffer chunk;
-+ CKYOffset srcOffset = 0;
-+ CKYAppletArgWriteObject wod;
-+ CKYStatus ret = CKYSUCCESS;
-+
-+ wod.objectID = objectID;
-+ wod.offset = offset;
-+ do {
-+ wod.size = (CKYByte) MIN(size, 220);
-+ ret = CKYBuffer_InitFromBuffer(&chunk, data,
-+ srcOffset, wod.size);
-+ if(ret == CKYSUCCESS) {
-+ wod.data = &chunk;
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_WriteObject, &wod,
-+ nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+ size -= wod.size;
-+ wod.offset += wod.size;
-+ srcOffset += wod.size;
-+ CKYBuffer_FreeData(&chunk);
-+ }
-+
-+ } while ((size > 0) && (ret == CKYSUCCESS));
-+
-+ return ret;
-+}
-+
-+/*
- * List Object cluster
- */
- static CKYStatus
-diff -up ./src/libckyapplet/cky_applet.h.coolkey-latest ./src/libckyapplet/cky_applet.h
---- ./src/libckyapplet/cky_applet.h.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_applet.h 2009-09-11 13:58:24.466487772 -0700
-@@ -192,6 +192,14 @@ typedef struct _CKYAppletArgReadObject {
- CKYByte size;
- } CKYAppletArgReadObject;
-
-+typedef struct _CKYAppletArgWriteObject {
-+ unsigned long objectID;
-+ CKYOffset offset;
-+ CKYByte size;
-+ CKYBuffer *data;
-+
-+} CKYAppletArgWriteObject;
-+
- typedef struct _CKYAppletArgComputeCrypt {
- CKYByte keyNumber;
- CKYByte mode;
-@@ -250,6 +258,8 @@ CKYStatus CKYAppletFactory_ListPINs(CKYA
- /* param == CKYByte * (pointer to pinNumber) */
- CKYStatus CKYAppletFactory_Logout(CKYAPDU *apdu, const void *param);
- /* Future add WriteObject */
-+/* parm == CKYAppletArgWriteObject */
-+CKYStatus CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param);
- /* param == CKYAppletArgCreateObject */
- CKYStatus CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param);
- /* param == CKYAppletArgDeleteObject */
-@@ -482,6 +492,17 @@ CKYStatus CKYApplet_ReadObjectAppend(CKY
- CKYStatus CKYApplet_ReadObjectFull(CKYCardConnection *conn,
- unsigned long objectID, CKYOffset offset, CKYSize size,
- const CKYBuffer *nonce, CKYBuffer *data, CKYISOStatus *apduRC);
-+/*
-+ * There is 1 write command:
-+ * CKYApplet_WriteObjectFull can write an entire data object. It makes multiple
-+ * apdu calls in order to write the full amount into the buffer. The buffer is
-+ * overwritten.
-+*/
-+
-+CKYStatus CKYApplet_WriteObjectFull(CKYCardConnection *conn,
-+ unsigned long objectID, CKYOffset offset, CKYSize size,
-+ const CKYBuffer *nonce, const CKYBuffer *data, CKYISOStatus *apduRC);
-+
- CKYStatus CKYApplet_ListObjects(CKYCardConnection *conn, CKYByte seq,
- CKYAppletRespListObjects *lop, CKYISOStatus *apduRC);
- CKYStatus CKYApplet_GetStatus(CKYCardConnection *conn,
-diff -up ./src/libckyapplet/cky_card.c.coolkey-latest ./src/libckyapplet/cky_card.c
---- ./src/libckyapplet/cky_card.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_card.c 2009-09-11 13:58:24.468487469 -0700
-@@ -129,6 +129,7 @@ typedef struct _SCard {
- SCardGetStatusChangeFn SCardGetStatusChange;
- SCardCancelFn SCardCancel;
- SCARD_IO_REQUEST *SCARD_PCI_T0_;
-+ SCARD_IO_REQUEST *SCARD_PCI_T1_;
- } SCard;
-
- #define GET_ADDRESS(library, scard, name) \
-@@ -195,6 +196,12 @@ ckySCard_Init(void)
- if( status != CKYSUCCESS ) {
- goto fail;
- }
-+
-+ status = ckyShLibrary_getAddress( library,
-+ (void**) &scard->SCARD_PCI_T1_, MAKE_DLL_SYMBOL(g_rgSCardT1Pci));
-+ if( status != CKYSUCCESS ) {
-+ goto fail;
-+ }
- return scard;
-
- fail:
-@@ -884,6 +891,7 @@ struct _CKYCardConnection {
- SCARDHANDLE cardHandle;
- unsigned long lastError;
- CKYBool inTransaction;
-+ unsigned long protocol;
- };
-
- static void
-@@ -894,6 +902,7 @@ ckyCardConnection_init(CKYCardConnection
- conn->cardHandle = 0;
- conn->lastError = 0;
- conn->inTransaction = 0;
-+ conn->protocol = SCARD_PROTOCOL_T0;
- }
-
- CKYCardConnection *
-@@ -934,14 +943,13 @@ CKYCardConnection_Connect(CKYCardConnect
- {
- CKYStatus ret;
- unsigned long rv;
-- unsigned long protocol;
-
- ret = CKYCardConnection_Disconnect(conn);
- if (ret != CKYSUCCESS) {
- return ret;
- }
- rv = conn->scard->SCardConnect( conn->ctx->context, readerName,
-- SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &conn->cardHandle, &protocol);
-+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &conn->cardHandle, &conn->protocol);
- if (rv != SCARD_S_SUCCESS) {
- conn->lastError = rv;
- return CKYSCARDERR;
-@@ -978,7 +986,7 @@ ckyCardConnection_reconnectRaw(CKYCardCo
- unsigned long protocol;
-
- rv = conn->scard->SCardReconnect(conn->cardHandle,
-- SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, init, &protocol);
-+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 , init, &protocol);
- if (rv != SCARD_S_SUCCESS) {
- conn->lastError = rv;
- return CKYSCARDERR;
-@@ -1039,10 +1047,17 @@ CKYCardConnection_TransmitAPDU(CKYCardCo
- return ret;
- }
-
-- rv = conn->scard->SCardTransmit(conn->cardHandle,
-- conn->scard->SCARD_PCI_T0_,
-- CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-- NULL, response->data, &response->len);
-+ if( conn->protocol == SCARD_PROTOCOL_T0 ) {
-+ rv = conn->scard->SCardTransmit(conn->cardHandle,
-+ conn->scard->SCARD_PCI_T0_,
-+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-+ NULL, response->data, &response->len);
-+ } else {
-+ rv = conn->scard->SCardTransmit(conn->cardHandle,
-+ conn->scard->SCARD_PCI_T1_,
-+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-+ NULL, response->data, &response->len);
-+ }
-
- if (rv != SCARD_S_SUCCESS) {
- conn->lastError =rv;
-diff -up ./src/libckyapplet/cky_factory.c.coolkey-latest ./src/libckyapplet/cky_factory.c
---- ./src/libckyapplet/cky_factory.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_factory.c 2009-09-11 13:58:24.470495267 -0700
-@@ -190,8 +190,11 @@ CKYAPDUFactory_ComputeCryptOneStep(CKYAP
- CKYSize len;
- CKYBuffer buf;
-
-- if (!idata || !(len = CKYBuffer_Size(idata)) || location != CKY_DL_APDU)
-- return ret;
-+ if (!idata)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT)
-+ return ret;
-
- CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
- CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT);
-@@ -314,8 +317,6 @@ CKYAPDUFactory_Logout(CKYAPDU *apdu, CKY
- return CKYSUCCESS;
- }
-
--/* Future add WriteObject */
--
- CKYStatus
- CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID, CKYSize size,
- unsigned short readACL, unsigned short writeACL, unsigned short deleteACL)
-@@ -419,6 +420,58 @@ fail:
- }
-
- CKYStatus
-+CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset,CKYSize size,CKYBuffer *data)
-+{
-+ CKYBuffer buf;
-+ CKYStatus ret = CKYSUCCESS;
-+ unsigned short dataSize = 0;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_WRITE_OBJ);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ dataSize = (unsigned short) CKYBuffer_Size(data);
-+
-+ if(!dataSize) {
-+ ret = CKYINVALIDARGS;
-+ goto fail;
-+ }
-+
-+ ret = CKYBuffer_AppendLong(&buf,objectID);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendLong(&buf,offset);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, size);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+ ret = CKYAPDU_SetSendDataBuffer(apdu,&buf);
-+
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, data);
-+
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+
-+}
-+
-+CKYStatus
- CKYAPDUFactory_ListObjects(CKYAPDU *apdu, CKYByte sequence)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-diff -up ./src/libckyapplet/cky_factory.h.coolkey-latest ./src/libckyapplet/cky_factory.h
---- ./src/libckyapplet/cky_factory.h.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_factory.h 2009-09-11 13:58:24.472487421 -0700
-@@ -190,7 +190,8 @@ CKYStatus CKYAPDUFactory_ChangePIN(CKYAP
- const char *oldPin, const char *newPin);
- CKYStatus CKYAPDUFactory_ListPINs(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_Logout(CKYAPDU *apdu, CKYByte pinNumber);
--
-+CKYStatus CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset,CKYSize size,CKYBuffer *data);
- /* Future add WriteObject */
- CKYStatus CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID,
- CKYSize size, unsigned short readACL, unsigned short writeACL,
diff --git a/coolkey-more-keys.patch b/coolkey-more-keys.patch
deleted file mode 100644
index 6140bed..0000000
--- a/coolkey-more-keys.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.coolkey-more-keys ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-more-keys 2016-01-20 11:04:38.507533104 -0800
-+++ ./src/coolkey/slot.cpp 2016-01-20 12:14:21.429947833 -0800
-@@ -32,6 +32,8 @@
-
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
-
-+#define MAX_NUM_KEYS 32
-+#define MAX_NUM_CERTS 32
-
-
- #ifdef DEBUG
-@@ -3458,7 +3460,7 @@ Slot::loadObjects()
- } else if( type == 'c' ) {
- // cert attribute object. find the DER encoding
- unsigned short certnum = getObjectIndex(iter->obj.objectID);
-- if( certnum > 9 ) {
-+ if( certnum > MAX_NUM_CERTS ) {
- //invalid object id
- throw PKCS11Exception(CKR_DEVICE_ERROR,
- "Invalid object id %08x",iter->obj.objectID);
-@@ -4154,7 +4156,7 @@ Slot::objectToKeyNum(const PKCS11Object
- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
- unsigned short keyNum = getObjectIndex(id);
-- if( keyNum > 9 ) {
-+ if( keyNum > MAX_NUM_KEYS ) {
- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
- return keyNum & 0xFF;
-@@ -4911,7 +4913,6 @@ Slot::generateRandom(SessionHandleSuffix
- }
- }
-
--#define MAX_NUM_KEYS 8
- unsigned int
- Slot::getRSAKeySize(PKCS11Object *key)
- {
-diff -up ./src/coolkey/slot.h.coolkey-more-keys ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.coolkey-more-keys 2016-01-20 11:04:45.610475971 -0800
-+++ ./src/coolkey/slot.h 2016-01-20 11:43:09.981528125 -0800
-@@ -511,9 +511,20 @@ class Slot {
- char getObjectClass(unsigned long objectID) const {
- return (char) (objectID >> 24) & 0xff;
- }
-+
- unsigned short getObjectIndex(unsigned long objectID) const {
-- return (char )((objectID >> 16) & 0xff) - '0';
-- }
-+ char char_index = (char) ((objectID >> 16) & 0xff);
-+ if (char_index >= '0' && char_index <= '9') {
-+ return char_index - '0';
-+ }
-+ if (char_index >= 'A' && char_index <= 'Z') {
-+ return char_index - 'A' + 10;
-+ }
-+ if (char_index >= 'a' && char_index <= 'z') {
-+ return char_index - 'a' + 26;
-+ }
-+ return 0x0100 + char_index;
-+ }
-
- // actually get the size of a key in bits from the card
- unsigned int getRSAKeySize(PKCS11Object *key);
diff --git a/coolkey-pcsc-lite-fix.patch b/coolkey-pcsc-lite-fix.patch
deleted file mode 100644
index f528676..0000000
--- a/coolkey-pcsc-lite-fix.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.reader-state-fix ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.reader-state-fix 2010-09-08 13:25:14.479109000 -0700
-+++ ./src/coolkey/slot.cpp 2010-09-08 13:25:14.506109000 -0700
-@@ -2185,6 +2185,7 @@ Slot::readCACCertificateFirst(CKYBuffer
- {
- CKYStatus status;
- CKYISOStatus apduRC;
-+ *nextSize = 0;
-
- if (mOldCAC) {
- /* get the first 100 bytes of the cert */
-diff -up ./src/libckyapplet/cky_card.c.reader-state-fix ./src/libckyapplet/cky_card.c
---- ./src/libckyapplet/cky_card.c.reader-state-fix 2010-09-08 14:05:10.859321000 -0700
-+++ ./src/libckyapplet/cky_card.c 2010-09-08 14:05:42.792257000 -0700
-@@ -27,7 +27,6 @@
-
- #ifndef WINAPI
- #define WINAPI
--typedef SCARD_READERSTATE *LPSCARD_READERSTATE;
- #endif
-
- #ifndef SCARD_E_NO_READERS_AVAILABLE
-diff -up ./src/libckyapplet/cky_card.h.reader-state-fix ./src/libckyapplet/cky_card.h
---- ./src/libckyapplet/cky_card.h.reader-state-fix 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_card.h 2010-09-08 13:25:14.518109000 -0700
-@@ -41,23 +41,23 @@ CKYLIST_DECLARE(CKYReaderName, char *)
- CKYLIST_DECLARE(CKYCardConnection, CKYCardConnection *)
-
- CKY_BEGIN_PROTOS
--void CKYReader_Init(SCARD_READERSTATE_A *reader);
--void CKYReader_FreeData(SCARD_READERSTATE_A *reader);
-+void CKYReader_Init(SCARD_READERSTATE *reader);
-+void CKYReader_FreeData(SCARD_READERSTATE *reader);
-
- /*
-- * "Accessors": for SCARD_READERSTATE_A structure as a class.
-- * These functions take an SCARD_READERSTATE_A which can also be referenced
-+ * "Accessors": for SCARD_READERSTATE structure as a class.
-+ * These functions take an SCARD_READERSTATE which can also be referenced
- * directly.
- */
--CKYStatus CKYReader_SetReaderName(SCARD_READERSTATE_A *reader, const char *name);
--const char *CKYReader_GetReaderName(const SCARD_READERSTATE_A *reader);
--CKYStatus CKYReader_SetKnownState(SCARD_READERSTATE_A *reader,
-+CKYStatus CKYReader_SetReaderName(SCARD_READERSTATE *reader, const char *name);
-+const char *CKYReader_GetReaderName(const SCARD_READERSTATE *reader);
-+CKYStatus CKYReader_SetKnownState(SCARD_READERSTATE *reader,
- unsigned long state);
--unsigned long CKYReader_GetKnownState(const SCARD_READERSTATE_A *reader);
--unsigned long CKYReader_GetEventState(const SCARD_READERSTATE_A *reader);
--CKYStatus CKYReader_GetATR(const SCARD_READERSTATE_A *reader, CKYBuffer *buf);
-+unsigned long CKYReader_GetKnownState(const SCARD_READERSTATE *reader);
-+unsigned long CKYReader_GetEventState(const SCARD_READERSTATE *reader);
-+CKYStatus CKYReader_GetATR(const SCARD_READERSTATE *reader, CKYBuffer *buf);
- /* create an array of READERSTATEs from a LIST of Readers */
--SCARD_READERSTATE_A *CKYReader_CreateArray(const CKYReaderNameList readerNames,
-+SCARD_READERSTATE *CKYReader_CreateArray(const CKYReaderNameList readerNames,
- unsigned long *readerCount);
- /* frees the reader, then the full array */
- void CKYReader_DestroyArray(SCARD_READERSTATE *reader, unsigned long count);
-@@ -88,7 +88,7 @@ CKYStatus CKYCardContext_FindReadersByAT
- const CKYBuffer *targetATR);
- /* return if any of the readers in our array has changed in status */
- CKYStatus CKYCardContext_WaitForStatusChange(CKYCardContext *context,
-- SCARD_READERSTATE_A *readers,
-+ SCARD_READERSTATE *readers,
- unsigned long readerCount,
- unsigned long timeout);
- /* cancel any current operation (such as wait for status change) on this
diff --git a/coolkey-simple-bugs.patch b/coolkey-simple-bugs.patch
deleted file mode 100644
index f8f3ab7..0000000
--- a/coolkey-simple-bugs.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-diff -up ./configure.in.coolkey-simple-bugs ./configure.in
---- ./configure.in.coolkey-simple-bugs 2009-09-16 11:21:55.621493844 -0700
-+++ ./configure.in 2009-09-16 11:22:23.354492383 -0700
-@@ -124,9 +124,9 @@ then
- if test $WINDOWS -ne 1; then
- PKG_CHECK_MODULES(NSS, nss, true, [ AC_MSG_ERROR(could not find NSS Crypto libraries) ])
- fi
-- enable_pk11install = "yes"
-+ enable_pk11install="yes"
- else
-- enable_pk11install = "no"
-+ enable_pk11install="no"
- AC_MSG_WARN([skipping pk11install])
- fi
-
-diff -up ./Makefile.am.coolkey-simple-bugs ./Makefile.am
---- ./Makefile.am.coolkey-simple-bugs 2009-09-16 11:23:18.715515063 -0700
-+++ ./Makefile.am 2009-09-16 13:15:29.570492412 -0700
-@@ -25,7 +25,6 @@ if BUILD_PK11INSTALL
- SUBDIRS += src/install
- endif
-
--ACLOCAL_AMFLAGS = -I m4
-
- EXTRA_DIST = cookey.spec LICENSE
-
-diff -up ./src/coolkey/object.cpp.coolkey-simple-bugs ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.coolkey-simple-bugs 2009-09-16 10:36:29.300516245 -0700
-+++ ./src/coolkey/object.cpp 2009-09-16 10:37:17.747492199 -0700
-@@ -397,7 +397,7 @@ PKCS11Object::getLabel()
- {
- // clean up old one
- if (label) {
-- delete label;
-+ delete [] label;
- label = NULL;
- }
- // find matching attribute
-diff -up ./src/coolkey/object.h.coolkey-simple-bugs ./src/coolkey/object.h
---- ./src/coolkey/object.h.coolkey-simple-bugs 2009-09-16 16:05:27.233488140 -0700
-+++ ./src/coolkey/object.h 2009-09-16 16:05:54.161492421 -0700
-@@ -82,7 +82,7 @@ class PKCS11Object {
- PKCS11Object(unsigned long muscleObjID, CK_OBJECT_HANDLE handle);
- PKCS11Object(unsigned long muscleObjID, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle);
-- ~PKCS11Object() { delete label; delete name; CKYBuffer_FreeData(&pubKey); }
-+ ~PKCS11Object() { delete [] label; delete [] name; CKYBuffer_FreeData(&pubKey); }
-
- PKCS11Object(const PKCS11Object& cpy) :
- attributes(cpy.attributes), muscleObjID(cpy.muscleObjID),
-diff -up ./src/coolkey/slot.cpp.coolkey-simple-bugs ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-simple-bugs 2009-09-16 10:28:15.412492201 -0700
-+++ ./src/coolkey/slot.cpp 2009-09-16 10:57:27.692492487 -0700
-@@ -979,7 +979,7 @@ Slot::makeLabelString(char *label, int m
- //
- #define COOLKEY "CoolKey"
- #define POSSESSION " for "
-- if (!personName || personName == "") {
-+ if (!personName || personName[0] == '\0' ) {
- const int coolKeySize = sizeof(COOLKEY) ;
- memcpy(label, COOLKEY, coolKeySize-1);
- makeSerialString(&label[coolKeySize], maxSize-coolKeySize, cuid);
-@@ -1528,7 +1528,7 @@ SlotMemSegment::SlotMemSegment(const cha
- }
- sprintf(segName,SEGMENT_PREFIX"%s",readerName);
- segment = SHMem::initSegment(segName, MAX_OBJECT_STORE_SIZE, needInit);
-- delete segName;
-+ delete [] segName;
- if (!segment) {
- // just run without shared memory
- return;
diff --git a/coolkey-thread-fix.patch b/coolkey-thread-fix.patch
deleted file mode 100644
index e3b552a..0000000
--- a/coolkey-thread-fix.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-Index: src/coolkey/coolkey.cpp
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/coolkey.cpp,v
-retrieving revision 1.2
-diff -u -r1.2 coolkey.cpp
---- src/coolkey/coolkey.cpp 14 Feb 2007 19:54:01 -0000 1.2
-+++ src/coolkey/coolkey.cpp 18 Dec 2009 23:22:58 -0000
-@@ -42,7 +42,9 @@
-
- static SlotList *slotList = NULL;
-
--static OSLock finalizeLock(false);
-+static OSLock *finalizeLock = NULL;
-+#define FINALIZE_GETLOCK() if (finalizeLock) finalizeLock->getLock();
-+#define FINALIZE_RELEASELOCK() if (finalizeLock) finalizeLock->releaseLock();
-
- static CK_BBOOL initialized = FALSE;
- static CK_BBOOL finalizing = FALSE;
-@@ -208,11 +210,13 @@
- if( initialized ) {
- return CKR_CRYPTOKI_ALREADY_INITIALIZED;
- }
-- if (!finalizeLock.isValid()) {
-+ if (finalizeLock && !finalizeLock->isValid()) {
- return CKR_CANT_LOCK;
- }
- CK_C_INITIALIZE_ARGS* initArgs = (CK_C_INITIALIZE_ARGS*) pInitArgs;
-+ OSLock::setThreadSafe(0);
- if( initArgs != NULL ) {
-+ bool needThreads;
- /* work around a bug in NSS where the library parameters are only
- * send if locking is requested */
- if (initArgs->LibraryParameters) {
-@@ -220,7 +224,17 @@
- } else {
- Params::ClearParams();
- }
-- if( (initArgs->flags & CKF_OS_LOCKING_OK) || initArgs->LockMutex ){
-+ needThreads = ((initArgs->flags & CKF_OS_LOCKING_OK) != 0);
-+ OSLock::setThreadSafe(needThreads);
-+ /* don't get a finalize lock unless someone initializes us asking
-+ * us to use threads */
-+ if (needThreads && !finalizeLock) {
-+ finalizeLock = new OSLock(true);
-+ if (finalizeLock == NULL) return CKR_HOST_MEMORY;
-+ }
-+ /* only support OS LOCKING threads */
-+ if( ((initArgs->flags & CKF_OS_LOCKING_OK) == 0)
-+ && initArgs->LockMutex ){
- throw PKCS11Exception(CKR_CANT_LOCK);
- }
- }
-@@ -259,9 +273,9 @@
- // the finalizing call first, we know it will set waitEvent before
- // we can get the lock, so we only need to protect setting finalizing
- // to true.
-- finalizeLock.getLock();
-+ FINALIZE_GETLOCK();
- finalizing = TRUE;
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- if (waitEvent) {
- /* we're waiting on a slot event, shutdown first to allow
- * the wait function to complete before we pull the rug out.
-@@ -273,10 +287,10 @@
- }
- delete slotList;
- delete log;
-- finalizeLock.getLock();
-+ FINALIZE_GETLOCK();
- finalizing = FALSE;
- initialized = FALSE;
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- return CKR_OK;
- }
-
-@@ -595,17 +609,17 @@
- CK_RV
- C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
- {
-- finalizeLock.getLock();
-+ FINALIZE_GETLOCK();
- if( ! initialized ) {
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
- if (finalizing) {
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
- waitEvent = TRUE;
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- try {
- log->log("C_WaitForSlotEvent called\n");
- slotList->waitForSlotEvent(flags, pSlot, pReserved);
-Index: src/coolkey/machdep.cpp
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/machdep.cpp,v
-retrieving revision 1.7
-diff -u -r1.7 machdep.cpp
---- src/coolkey/machdep.cpp 14 Feb 2008 23:48:19 -0000 1.7
-+++ src/coolkey/machdep.cpp 18 Dec 2009 23:22:58 -0000
-@@ -37,6 +37,8 @@
- #include <stdlib.h>
- #endif
-
-+bool OSLock::needThread = 0;
-+
- #ifdef _WIN32
- //
- // Windows functions to grab a named shared memory segment of a specific size,
-@@ -123,6 +125,10 @@
-
- OSLock::OSLock(bool exceptionAllowed)
- {
-+ if (!needThread) {
-+ lockData = NULL;
-+ return;
-+ }
- lockData = new OSLockData;
- if (lockData) {
- InitializeCriticalSection(&lockData->mutex);
-@@ -360,6 +366,9 @@
- int rc;
-
- lockData = NULL;
-+ if (!needThread) {
-+ return;
-+ }
- #ifdef MAC
- if (!OSLock_attr_init) {
- rc = pthread_mutexattr_init(&OSLock_attr);
-Index: src/coolkey/machdep.h
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/machdep.h,v
-retrieving revision 1.1
-diff -u -r1.1 machdep.h
---- src/coolkey/machdep.h 9 Jun 2006 18:39:11 -0000 1.1
-+++ src/coolkey/machdep.h 18 Dec 2009 23:22:58 -0000
-@@ -40,12 +40,14 @@
- class OSLock {
- private:
- OSLockData *lockData;
-+ static bool needThread;
- public:
- OSLock(bool exceptionAllowed = true);
- ~OSLock();
- bool isValid();
- void getLock();
- void releaseLock();
-+ static void setThreadSafe(bool thread) { needThread = thread; }
- };
-
- typedef unsigned long OSTime;
diff --git a/coolkey-update.patch b/coolkey-update.patch
deleted file mode 100644
index 2a1bed3..0000000
--- a/coolkey-update.patch
+++ /dev/null
@@ -1,8043 +0,0 @@
-diff -up ./src/coolkey/coolkey.cpp.coolkey-update ./src/coolkey/coolkey.cpp
---- ./src/coolkey/coolkey.cpp.coolkey-update 2016-01-19 17:48:49.064182244 -0800
-+++ ./src/coolkey/coolkey.cpp 2016-01-19 17:50:46.711214704 -0800
-@@ -34,7 +34,6 @@
- #include "cky_base.h"
- #include "params.h"
-
--#define NULL 0
-
- /* static module data -------------------------------- */
-
-@@ -70,11 +69,19 @@ typedef struct {
- /**********************************************************************
- ************************** MECHANISM TABLE ***************************
- **********************************************************************/
--static MechInfo
--mechanismList[] = {
-+
-+static const MechInfo
-+rsaMechanismList[] = {
- {CKM_RSA_PKCS, { 1024, 4096, CKF_HW | CKF_SIGN | CKF_DECRYPT } }
- };
--static unsigned int numMechanisms = sizeof(mechanismList)/sizeof(MechInfo);
-+
-+static const MechInfo
-+ecMechanismList[] = {
-+ {CKM_ECDSA,{256,521,CKF_HW | CKF_SIGN | CKF_EC_F_P}},{ CKM_ECDSA_SHA1, {256, 521, CKF_HW | CKF_SIGN | CKF_EC_F_P}},{ CKM_ECDH1_DERIVE,{256, 521, CKF_HW | CKF_DERIVE | CKF_EC_F_P} }
-+};
-+
-+unsigned int numRSAMechanisms = sizeof(rsaMechanismList)/sizeof(MechInfo);
-+unsigned int numECMechanisms = sizeof(ecMechanismList)/sizeof(MechInfo);
-
- /* ------------------------------------------------------------ */
-
-@@ -166,7 +173,6 @@ NOTSUPPORTED(C_GenerateKey, (CK_SESSION_
- NOTSUPPORTED(C_GenerateKeyPair, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_ATTRIBUTE_PTR,CK_ULONG,CK_ATTRIBUTE_PTR,CK_ULONG,CK_OBJECT_HANDLE_PTR,CK_OBJECT_HANDLE_PTR))
- NOTSUPPORTED(C_WrapKey, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_OBJECT_HANDLE,CK_OBJECT_HANDLE,CK_BYTE_PTR,CK_ULONG_PTR))
- NOTSUPPORTED(C_UnwrapKey, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_OBJECT_HANDLE,CK_BYTE_PTR,CK_ULONG,CK_ATTRIBUTE_PTR,CK_ULONG,CK_OBJECT_HANDLE_PTR))
--NOTSUPPORTED(C_DeriveKey, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_OBJECT_HANDLE,CK_ATTRIBUTE_PTR,CK_ULONG,CK_OBJECT_HANDLE_PTR))
- NOTSUPPORTED(C_GetFunctionStatus, (CK_SESSION_HANDLE))
- NOTSUPPORTED(C_CancelFunction, (CK_SESSION_HANDLE))
-
-@@ -200,6 +206,10 @@ SUPPORTED(C_SeedRandom, seedRandom,
- SUPPORTED(C_GenerateRandom, generateRandom,
- (CK_SESSION_HANDLE hSession ,CK_BYTE_PTR data,CK_ULONG dataLen),
- (hSession, data, dataLen))
-+SUPPORTED(C_DeriveKey,derive,
-+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ),
-+ (hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey))
-
- /* non-specialized functions supported with the slot directly */
-
-@@ -249,7 +259,7 @@ C_Initialize(CK_VOID_PTR pInitArgs)
- log = new DummyLog();
- }
- log->log("Initialize called, hello %d\n", 5);
-- CKY_SetName("coolkey");
-+ CKY_SetName((char *) "coolkey");
- slotList = new SlotList(log);
- initialized = TRUE;
- return CKR_OK;
-@@ -347,6 +357,11 @@ CK_RV
- C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount)
- {
-+
-+ const MechInfo *mechanismList = NULL;
-+ unsigned int numMechanisms = 0;
-+
-+
- if( ! initialized ) {
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
-@@ -359,11 +374,21 @@ C_GetMechanismList(CK_SLOT_ID slotID, CK
- }
-
- slotList->validateSlotID(slotID);
-- if( ! slotList->getSlot(
-- slotIDToIndex(slotID))->isTokenPresent() ) {
-+
-+ Slot *slot = slotList->getSlot(slotIDToIndex(slotID));
-+
-+ if( ! slot || ! slot->isTokenPresent() ) {
- return CKR_TOKEN_NOT_PRESENT;
- }
-
-+ if ( slot->getIsECC()) {
-+ mechanismList = ecMechanismList;
-+ numMechanisms = numECMechanisms;
-+ } else {
-+ mechanismList = rsaMechanismList;
-+ numMechanisms = numRSAMechanisms;
-+ }
-+
- if( pMechanismList != NULL ) {
- if( *pulCount < numMechanisms ) {
- rv = CKR_BUFFER_TOO_SMALL;
-@@ -390,19 +415,36 @@ CK_RV
- C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo)
- {
-+ const MechInfo *mechanismList = NULL;
-+ unsigned int numMechanisms = 0;
-+
- if( ! initialized ) {
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
-+
-+
- try {
- log->log("C_GetMechanismInfo called\n");
- if( pInfo == NULL ) {
- throw PKCS11Exception(CKR_ARGUMENTS_BAD);
- }
- slotList->validateSlotID(slotID);
-- if( ! slotList->getSlot(slotIDToIndex(slotID))->isTokenPresent() ) {
-+
-+
-+ Slot *slot = slotList->getSlot(slotIDToIndex(slotID));
-+
-+ if( ! slot || ! slot->isTokenPresent() ) {
- return CKR_TOKEN_NOT_PRESENT;
- }
-
-+ if ( slot->getIsECC()) {
-+ mechanismList = ecMechanismList;
-+ numMechanisms = numECMechanisms;
-+ } else {
-+ mechanismList = rsaMechanismList;
-+ numMechanisms = numRSAMechanisms;
-+ }
-+
- for(unsigned int i=0; i < numMechanisms; ++i ) {
- if( mechanismList[i].mech == type ) {
- *pInfo = mechanismList[i].info;
-@@ -557,13 +599,10 @@ C_Login(CK_SESSION_HANDLE hSession, CK_U
- }
- try {
- log->log("C_Login called\n");
-- if( userType != CKU_USER ) {
-- throw PKCS11Exception(CKR_USER_TYPE_INVALID);
-- }
- if( pPin == NULL ) {
- throw PKCS11Exception(CKR_ARGUMENTS_BAD);
- }
-- slotList->login(hSession, pPin, ulPinLen);
-+ slotList->login(hSession, userType, pPin, ulPinLen);
- return CKR_OK;
- } catch(PKCS11Exception &e) {
- e.log(log);
-diff -up ./src/coolkey/machdep.cpp.coolkey-update ./src/coolkey/machdep.cpp
---- ./src/coolkey/machdep.cpp.coolkey-update 2016-01-19 17:51:35.553813017 -0800
-+++ ./src/coolkey/machdep.cpp 2016-01-19 17:51:59.607615196 -0800
-@@ -368,6 +368,7 @@ SHMem::initSegment(const char *name, int
- #ifdef FULL_CLEANUP
- flock(shmemData->fd, LOCK_UN);
- #endif
-+ free(buf);
- delete shmemData;
- return NULL;
- }
-diff -up ./src/coolkey/object.cpp.coolkey-update ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.coolkey-update 2016-01-19 17:52:36.313313325 -0800
-+++ ./src/coolkey/object.cpp 2016-01-19 17:52:50.959192876 -0800
-@@ -19,18 +19,80 @@
-
- #include "mypkcs11.h"
- #include "PKCS11Exception.h"
--#include "object.h"
- #include <algorithm>
- #include <string.h>
-+#include "object.h"
-
- using std::find_if;
-
-+const CKYByte rsaOID[] = {0x2A,0x86,0x48,0x86,0xF7,0x0D, 0x01, 0x01,0x1};
-+const CKYByte eccOID[] = {0x2a,0x86,0x48,0xce,0x3d,0x02,0x01};
-+
-+#ifdef DEBUG
-+void dump(const char *label, const CKYBuffer *buf)
-+{
-+ CKYSize i;
-+ CKYSize size = CKYBuffer_Size(buf);
-+#define ROW_LENGTH 60
-+ char string[ROW_LENGTH+1];
-+ char *bp = &string[0];
-+ CKYByte c;
-+
-+ printf("%s size=%d\n", label, (int)size);
-+
-+ for (i=0; i < size; i++) {
-+ if (i && ((i % (ROW_LENGTH)) == 0) ) {
-+ *bp = 0;
-+ printf(" %s\n",string);
-+ bp = &string[0];
-+ }
-+ c = CKYBuffer_GetChar(buf, i);
-+ printf("%02x ",c);
-+ *bp++ = (c < ' ') ? '.' : ((c & 0x80) ? '*' : c);
-+ }
-+ *bp = 0;
-+ for (i= (i % (ROW_LENGTH)); i && (i < ROW_LENGTH); i++) {
-+ printf(" ");
-+ }
-+ printf(" %s\n",string);
-+ fflush(stdout);
-+}
-+
-+void dumpData(const char *label, const CKYByte *buf, CKYSize size)
-+{
-+ CKYSize i;
-+#define ROW_LENGTH 16
-+ char string[ROW_LENGTH+1];
-+ char *bp = &string[0];
-+ CKYByte c;
-+
-+ printf("%s size=%d:\n",label, (int)size);
-+
-+ for (i=0; i < size; i++) {
-+ if (i && ((i % (ROW_LENGTH)) == 0) ) {
-+ *bp = 0;
-+ printf(" %s\n",string);
-+ bp = &string[0];
-+ }
-+ c = buf[i];
-+ printf("%02x ",c);
-+ *bp++ = (c < ' ') ? '.' : ((c & 0x80) ? '*' : c);
-+ }
-+ *bp = 0;
-+ for (i= (i % (ROW_LENGTH)); i && (i < ROW_LENGTH); i++) {
-+ printf(" ");
-+ }
-+ printf(" %s\n",string);
-+ fflush(stdout);
-+}
-+#endif
-+
-
- bool AttributeMatch::operator()(const PKCS11Attribute& cmp)
- {
- return (attr->type == cmp.getType()) &&
-- CKYBuffer_DataIsEqual(cmp.getValue(),
-- (const CKYByte *)attr->pValue, attr->ulValueLen);
-+ CKYBuffer_DataIsEqual(cmp.getValue(),
-+ (const CKYByte *)attr->pValue, attr->ulValueLen);
- }
-
- class AttributeTypeMatch
-@@ -45,16 +107,23 @@ class AttributeTypeMatch
- };
-
- PKCS11Object::PKCS11Object(unsigned long muscleObjID_,CK_OBJECT_HANDLE handle_)
-- : muscleObjID(muscleObjID_), handle(handle_), label(NULL), name(NULL)
-+ : muscleObjID(muscleObjID_), handle(handle_), label(NULL), keySize(0),
-+ user(CKU_USER), name(NULL), keyType(unknown),
-+ keyRef(PK15_INVALID_KEY_REF)
- {
- CKYBuffer_InitEmpty(&pubKey);
-+ CKYBuffer_InitEmpty(&authId);
-+ CKYBuffer_InitEmpty(&pinAuthId);
- }
-
- PKCS11Object::PKCS11Object(unsigned long muscleObjID_, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle_) : muscleObjID(muscleObjID_), handle(handle_),
-- label(NULL), name(NULL)
-+ label(NULL), keySize(0), user(CKU_USER), name(NULL),
-+ keyType(unknown), keyRef(PK15_INVALID_KEY_REF)
- {
- CKYBuffer_InitEmpty(&pubKey);
-+ CKYBuffer_InitEmpty(&authId);
-+ CKYBuffer_InitEmpty(&pinAuthId);
-
- CKYByte type = CKYBuffer_GetChar(data,0);
- // verify object ID is what we think it is
-@@ -63,9 +132,98 @@ PKCS11Object::PKCS11Object(unsigned long
- "PKCS #11 actual object id does not match stated id");
- }
- if (type == 0) {
-- parseOldObject(data);
-+ parseOldObject(data);
- } else if (type == 1) {
-- parseNewObject(data);
-+ parseNewObject(data);
-+ }
-+}
-+
-+SecretKey::SecretKey(unsigned long muscleObjID_, CK_OBJECT_HANDLE handle_, CKYBuffer *secretKeyBuffer, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
-+ : PKCS11Object(muscleObjID_, handle_)
-+{
-+ static CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
-+ static CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
-+ static CK_BBOOL value = 0x1;
-+
-+ if ( secretKeyBuffer == NULL)
-+ return;
-+
-+ /* Rifle through the input template */
-+
-+ CK_ATTRIBUTE_TYPE type;
-+ CK_ATTRIBUTE attr;
-+ CK_ULONG valueLength = 0;
-+
-+ for(int i = 0; i < (int) ulAttributeCount; i++) {
-+ attr = pTemplate[i];
-+ type = attr.type;
-+
-+ if ( type == CKA_VALUE_LEN) {
-+ //CK_ULONG ulValueLen = attr.ulValueLen;
-+ valueLength = *((CK_ULONG *)attr.pValue);
-+ } else {
-+
-+ CKYBuffer val;
-+ CKYBuffer_InitFromData(&val,(const CK_BYTE *) attr.pValue, attr.ulValueLen);
-+ setAttribute( type, &val);
-+ CKYBuffer_FreeData(&val);
-+ }
-+ }
-+
-+ adjustToKeyValueLength( secretKeyBuffer, valueLength );
-+
-+ /* Fall backs. */
-+
-+ if(!attributeExists(CKA_CLASS))
-+ setAttributeULong(CKA_CLASS, objClass);
-+
-+ if(!attributeExists(CKA_KEY_TYPE))
-+ setAttributeULong(CKA_KEY_TYPE, keyType);
-+
-+ if(!attributeExists(CKA_TOKEN))
-+ setAttributeBool(CKA_TOKEN, value);
-+
-+ if(!attributeExists(CKA_DERIVE))
-+ setAttributeBool(CKA_DERIVE, value);
-+
-+ /* Actual value */
-+ setAttribute(CKA_VALUE, secretKeyBuffer);
-+
-+}
-+
-+void SecretKey::adjustToKeyValueLength(CKYBuffer * secretKeyBuffer,CK_ULONG valueLength)
-+{
-+ const CK_LONG MAX_DIFF = 200; /* Put some bounds on this value */
-+
-+ if ( !secretKeyBuffer ) {
-+ return;
-+ }
-+
-+ CKYBuffer scratch;
-+ CK_ULONG actual_length = CKYBuffer_Size(secretKeyBuffer);
-+
-+ CK_LONG diff = 0;
-+ diff = (CK_LONG) valueLength - actual_length;
-+
-+ if ( diff == 0 ) {
-+ return;
-+ }
-+
-+ if ( diff > 0 && diff < MAX_DIFF ) { /*check for silly values */
-+ /* prepend with zeroes */
-+ CKYBuffer_InitFromLen(&scratch, diff);
-+ CKYBuffer_AppendCopy(&scratch, secretKeyBuffer);
-+
-+ CKYBuffer_FreeData(secretKeyBuffer);
-+ CKYBuffer_InitFromCopy(secretKeyBuffer, &scratch);
-+ CKYBuffer_FreeData(&scratch);
-+
-+ } else if (diff < 0 ) {
-+ /* truncate most significant bytes */
-+ CKYBuffer_InitFromData(&scratch, CKYBuffer_Data(secretKeyBuffer)-diff, valueLength);
-+ CKYBuffer_FreeData(secretKeyBuffer);
-+ CKYBuffer_InitFromCopy(secretKeyBuffer, &scratch);
-+ CKYBuffer_FreeData(&scratch);
- }
- }
-
-@@ -95,29 +253,29 @@ PKCS11Object::parseOldObject(const CKYBu
- attrib.setType(CKYBuffer_GetLong(data, idx));
- idx += 4;
- unsigned int attrLen = CKYBuffer_GetShort(data, idx);
-- idx += 2;
-+ idx += 2;
- if( attrLen > CKYBuffer_Size(data)
-- || (idx + attrLen > CKYBuffer_Size(data)) ) {
-+ || (idx + attrLen > CKYBuffer_Size(data)) ) {
- throw PKCS11Exception(CKR_DEVICE_ERROR,
- "Invalid attribute length %d\n", attrLen);
- }
-- /* these two types are ints, read them back from
-- * the card in host order */
-- if ((attrib.getType() == CKA_CLASS) ||
-- (attrib.getType() == CKA_CERTIFICATE_TYPE) ||
-- (attrib.getType() == CKA_KEY_TYPE)) {
-- /* ulongs are 4 bytes on the token, even if they are 8 or
-- * more in the pkcs11 module */
-- if (attrLen != 4) {
-+ /* these two types are ints, read them back from
-+ * the card in host order */
-+ if ((attrib.getType() == CKA_CLASS) ||
-+ (attrib.getType() == CKA_CERTIFICATE_TYPE) ||
-+ (attrib.getType() == CKA_KEY_TYPE)) {
-+ /* ulongs are 4 bytes on the token, even if they are 8 or
-+ * more in the pkcs11 module */
-+ if (attrLen != 4) {
- throw PKCS11Exception(CKR_DEVICE_ERROR,
- "Invalid attribute length %d\n", attrLen);
-- }
-- CK_ULONG value = makeLEUInt(data,idx);
-+ }
-+ CK_ULONG value = makeLEUInt(data,idx);
-
-- attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-- } else {
-- attrib.setValue(CKYBuffer_Data(data)+idx, attrLen);
-- }
-+ attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-+ } else {
-+ attrib.setValue(CKYBuffer_Data(data)+idx, attrLen);
-+ }
- idx += attrLen;
- attributes.push_back(attrib);
- }
-@@ -177,33 +335,33 @@ PKCS11Object::expandAttributes(unsigned
- unsigned long i;
-
- if (!attributeExists(CKA_ID)) {
-- PKCS11Attribute attrib;
-- attrib.setType(CKA_ID);
-- attrib.setValue(&cka_id, 1);
-+ PKCS11Attribute attrib;
-+ attrib.setType(CKA_ID);
-+ attrib.setValue(&cka_id, 1);
- attributes.push_back(attrib);
- }
- /* unpack the class */
- if (!attributeExists(CKA_CLASS)) {
-- PKCS11Attribute attrib;
-- attrib.setType(CKA_CLASS);
-- attrib.setValue((CKYByte *)&objectType, sizeof(CK_ULONG));
-+ PKCS11Attribute attrib;
-+ attrib.setType(CKA_CLASS);
-+ attrib.setValue((CKYByte *)&objectType, sizeof(CK_ULONG));
- attributes.push_back(attrib);
- }
-
- /* unpack the boolean flags. Note, the default mask is based on
- * the class specified in fixedAttrs, not on the real class */
- for (i=1; i < sizeof(unsigned long)*8; i++) {
-- unsigned long iMask = 1<< i;
-- if ((mask & iMask) == 0) {
-- continue;
-- }
-- if (attributeExists(boolType[i])) {
-- continue;
-- }
-- PKCS11Attribute attrib;
-- CKYByte bVal = (fixedAttrs & iMask) != 0;
-- attrib.setType(boolType[i]);
-- attrib.setValue(&bVal, 1);
-+ unsigned long iMask = 1<< i;
-+ if ((mask & iMask) == 0) {
-+ continue;
-+ }
-+ if (attributeExists(boolType[i])) {
-+ continue;
-+ }
-+ PKCS11Attribute attrib;
-+ CKYByte bVal = (fixedAttrs & iMask) != 0;
-+ attrib.setType(boolType[i]);
-+ attrib.setValue(&bVal, 1);
- attributes.push_back(attrib);
- }
- }
-@@ -224,40 +382,40 @@ PKCS11Object::parseNewObject(const CKYBu
- // load up the explicit attributes first
- for (j=0, offset = 11; j < attributeCount && offset < size; j++) {
- PKCS11Attribute attrib;
-- CKYByte attributeDataType = CKYBuffer_GetChar(data, offset+4);
-- unsigned int attrLen = 0;
-+ CKYByte attributeDataType = CKYBuffer_GetChar(data, offset+4);
-+ unsigned int attrLen = 0;
- attrib.setType(CKYBuffer_GetLong(data, offset));
- offset += 5;
-
-- switch(attributeDataType) {
-- case DATATYPE_STRING:
-- attrLen = CKYBuffer_GetShort(data, offset);
-- offset += 2;
-+ switch(attributeDataType) {
-+ case DATATYPE_STRING:
-+ attrLen = CKYBuffer_GetShort(data, offset);
-+ offset += 2;
- if (attrLen > CKYBuffer_Size(data)
-- || (offset + attrLen > CKYBuffer_Size(data)) ) {
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Invalid attribute length %d\n", attrLen);
-+ || (offset + attrLen > CKYBuffer_Size(data)) ) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Invalid attribute length %d\n", attrLen);
- }
-- attrib.setValue(CKYBuffer_Data(data)+offset, attrLen);
-- break;
-- case DATATYPE_BOOL_FALSE:
-- case DATATYPE_BOOL_TRUE:
-- {
-- CKYByte bval = attributeDataType & 1;
-- attrib.setValue(&bval, 1);
-- }
-- break;
-- case DATATYPE_INTEGER:
-- {
-- CK_ULONG value = CKYBuffer_GetLong(data, offset);
-- attrLen = 4;
-- attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-- }
-- break;
-- default:
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Invalid attribute Data Type %d\n", attributeDataType);
-- }
-+ attrib.setValue(CKYBuffer_Data(data)+offset, attrLen);
-+ break;
-+ case DATATYPE_BOOL_FALSE:
-+ case DATATYPE_BOOL_TRUE:
-+ {
-+ CKYByte bval = attributeDataType & 1;
-+ attrib.setValue(&bval, 1);
-+ }
-+ break;
-+ case DATATYPE_INTEGER:
-+ {
-+ CK_ULONG value = CKYBuffer_GetLong(data, offset);
-+ attrLen = 4;
-+ attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-+ }
-+ break;
-+ default:
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Invalid attribute Data Type %d\n", attributeDataType);
-+ }
- offset += attrLen;
- attributes.push_back(attrib);
- }
-@@ -276,7 +434,7 @@ static const CK_ATTRIBUTE rdr_templat
-
- bool
- PKCS11Object::matchesTemplate(const CK_ATTRIBUTE_PTR pTemplate,
-- CK_ULONG ulCount)
-+ CK_ULONG ulCount)
- const
- {
- unsigned int i;
-@@ -285,10 +443,10 @@ PKCS11Object::matchesTemplate(const CK_A
-
- #if defined( NSS_HIDE_NONSTANDARD_OBJECTS )
- if (!ulCount) {
-- // exclude MOZ reader objects from searches for all objects.
-- // To find an MOZ reader object, one must search for it by
-- // some matching attribute, such as class.
-- iterator iter = find_if(attributes.begin(), attributes.end(),
-+ // exclude MOZ reader objects from searches for all objects.
-+ // To find an MOZ reader object, one must search for it by
-+ // some matching attribute, such as class.
-+ iterator iter = find_if(attributes.begin(), attributes.end(),
- AttributeMatch(&rdr_template[0]));
- return (iter == attributes.end()) ? true : false;
- }
-@@ -325,7 +483,7 @@ PKCS11Object::getAttribute(CK_ATTRIBUTE_
- AttributeTypeMatch(type));
-
- if( iter == attributes.end() ) {
-- return NULL;
-+ return NULL;
- }
- return iter->getValue();
- }
-@@ -349,8 +507,9 @@ PKCS11Object::getAttributeValue(CK_ATTRI
- if( iter == attributes.end() ) {
- // no attribute of this type
- attrTypeInvalid = true;
-- log->log("GetAttributeValue: invalid type 0x%08x on object %x\n",
-- pTemplate[i].type, muscleObjID);
-+ if ( log )
-+ log->log("GetAttributeValue: invalid type 0x%08x on object %x\n",
-+ pTemplate[i].type, muscleObjID);
- pTemplate[i].ulValueLen = (CK_ULONG)-1;
- continue;
- }
-@@ -371,7 +530,7 @@ PKCS11Object::getAttributeValue(CK_ATTRI
- // the buffer is large enough. return the value and set the exact
- // length.
- memcpy(pTemplate[i].pValue, CKYBuffer_Data(iter->getValue()),
-- CKYBuffer_Size(iter->getValue()));
-+ CKYBuffer_Size(iter->getValue()));
- pTemplate[i].ulValueLen = CKYBuffer_Size(iter->getValue());
- }
-
-@@ -406,14 +565,14 @@ PKCS11Object::getLabel()
-
- // none found
- if( iter == attributes.end() ) {
-- return "";
-+ return "";
- }
-
- int size = CKYBuffer_Size(iter->getValue());
-
- label = new char [ size + 1 ];
- if (!label) {
-- return "";
-+ return "";
- }
- memcpy(label, CKYBuffer_Data(iter->getValue()), size);
- label[size] = 0;
-@@ -431,13 +590,13 @@ PKCS11Object::getClass()
-
- // none found */
- if( iter == attributes.end() ) {
-- return (CK_OBJECT_CLASS) -1;
-+ return (CK_OBJECT_CLASS) -1;
- }
-
- int size = CKYBuffer_Size(iter->getValue());
-
- if (size != sizeof(objClass)) {
-- return (CK_OBJECT_CLASS) -1;
-+ return (CK_OBJECT_CLASS) -1;
- }
-
- memcpy(&objClass, CKYBuffer_Data(iter->getValue()), size);
-@@ -453,13 +612,28 @@ PKCS11Object::setAttribute(CK_ATTRIBUTE_
- iter = find_if(attributes.begin(), attributes.end(),
- AttributeTypeMatch(type));
- if( iter != attributes.end() ) {
-- iter->setValue( CKYBuffer_Data(value), CKYBuffer_Size(value));
-+ iter->setValue( CKYBuffer_Data(value), CKYBuffer_Size(value));
- } else {
- attributes.push_back(PKCS11Attribute(type, value));
- }
- }
-
- void
-+PKCS11Object::setAttribute(CK_ATTRIBUTE_TYPE type, const CKYByte *data,
-+ CKYSize size)
-+{
-+ AttributeIter iter;
-+
-+ iter = find_if(attributes.begin(), attributes.end(),
-+ AttributeTypeMatch(type));
-+ if( iter != attributes.end() ) {
-+ iter->setValue( data, size);
-+ } else {
-+ attributes.push_back(PKCS11Attribute(type, data, size));
-+ }
-+}
-+
-+void
- PKCS11Object::setAttribute(CK_ATTRIBUTE_TYPE type, const char *string)
- {
- CKYBuffer buf;
-@@ -491,7 +665,7 @@ PKCS11Object::setAttributeULong(CK_ATTRI
-
- typedef struct {
- const CKYByte*data;
-- unsigned int len;
-+ CKYSize len;
- } CCItem;
-
- typedef enum {
-@@ -499,15 +673,21 @@ typedef enum {
- SECFailure=1
- } SECStatus;
-
--static const CKYByte*
--dataStart(const CKYByte *buf, unsigned int length,
-- unsigned int *data_length, bool includeTag) {
-+const CKYByte*
-+dataStart(const CKYByte *buf, CKYSize length,
-+ CKYSize *data_length, bool includeTag) {
- unsigned char tag;
- unsigned int used_length= 0;
-
-+ *data_length = 0; /* make sure data_length is zero on failure */
-+
- if(!buf) {
- return NULL;
- }
-+ /* there must be at least 2 bytes */
-+ if (length < 2) {
-+ return NULL;
-+ }
-
- tag = buf[used_length++];
-
-@@ -521,15 +701,22 @@ dataStart(const CKYByte *buf, unsigned i
- if (*data_length&0x80) {
- int len_count = *data_length & 0x7f;
-
-+ if (len_count+used_length > length) {
-+ return NULL;
-+ }
-+
- *data_length = 0;
-
- while (len_count-- > 0) {
- *data_length = (*data_length << 8) | buf[used_length++];
- }
- }
-+ /* paranoia, can't happen */
-+ if (length < used_length) {
-+ return NULL;
-+ }
-
- if (*data_length > (length-used_length) ) {
-- *data_length = length-used_length;
- return NULL;
- }
- if (includeTag) *data_length += used_length;
-@@ -538,27 +725,169 @@ dataStart(const CKYByte *buf, unsigned i
- }
-
- static const CKYByte *
--unwrapBitString(const CKYByte *buf, unsigned int len, unsigned int *retLen)
-+unwrapBitString(const CKYByte *buf, CKYSize len, CKYSize *retLen)
- {
- /* for RSA, bit string always has byte number of bits */
- if (buf[0] != 0) {
-- return NULL;
-+ return NULL;
- }
- if (len < 1) {
-- return NULL;
-+ return NULL;
- }
- *retLen = len -1;
- return buf+1;
- }
-
- static SECStatus
--GetKeyFieldItems(const CKYByte *spki_data,unsigned int spki_length,
-+GetECKeyFieldItems(const CKYByte *spki_data, CKYSize spki_length,
-+ CCItem *point, CCItem *params)
-+{
-+ const CKYByte *buf = spki_data;
-+ CKYSize buf_length = spki_length;
-+ const CKYByte *algid;
-+ CKYSize algidlen;
-+ const CKYByte *dummy;
-+ CKYSize dummylen;
-+
-+ if (!point || !params || !buf)
-+ return SECFailure;
-+
-+ point->data = NULL;
-+ point->len = 0;
-+ params->data = NULL;
-+ params->len = 0;
-+
-+ /* unwrap the algorithm id */
-+ dummy = dataStart(buf,buf_length,&dummylen,false);
-+ if (dummy == NULL) return SECFailure;
-+ buf_length -= (dummy-buf) + dummylen;
-+ buf = dummy + dummylen;
-+ /* unwrpped value is in dummy */
-+ algid = dummy;
-+ algidlen = dummylen;
-+ /* skip past algid oid */
-+ dummy = dataStart(algid, algidlen, &dummylen, false);
-+ if (dummy == NULL) return SECFailure;
-+ algidlen -= (dummy-algid) + dummylen;
-+ algid = dummy + dummylen;
-+ params->data = algid;
-+ params->len = algidlen;
-+
-+ /* unwrap the public key info */
-+ buf = dataStart(buf,buf_length,&buf_length,false);
-+ if (buf == NULL) return SECFailure;
-+ buf = unwrapBitString(buf,buf_length,&buf_length);
-+ if (buf == NULL) return SECFailure;
-+
-+ point->data = buf;
-+ point->len = buf_length;
-+
-+ if(point->data == NULL) return SECFailure;
-+
-+ return SECSuccess;
-+}
-+
-+static bool
-+GetKeyOIDMatches(const CKYByte *spki_data, unsigned int length, const CKYByte *oid_data)
-+{
-+ bool ret = TRUE;
-+
-+ if( spki_data == NULL || oid_data == NULL) {
-+ return FALSE;
-+ }
-+
-+ for ( int i = 0 ; i < (int) length ; i++) {
-+ if (spki_data[i] != oid_data[i]) {
-+ ret = FALSE;
-+ break;
-+ }
-+
-+ }
-+
-+ return ret;
-+}
-+
-+static SECStatus
-+GetKeyAlgorithmId(const CKYByte *spki_data, CKYSize spki_length,
-+ CCItem *algorithmId)
-+{
-+
-+ const CKYByte *buf = spki_data;
-+ CKYSize buf_length = spki_length;
-+
-+ if ( algorithmId == NULL) return SECFailure;
-+
-+ /* objtain the algorithm id */
-+ algorithmId->data = dataStart(buf,buf_length,&algorithmId->len,false);
-+ if (algorithmId->data == NULL) return SECFailure;
-+
-+ return SECSuccess;
-+
-+}
-+
-+static PKCS11Object::KeyType
-+GetKeyTypeFromSPKI(const CKYBuffer *key)
-+{
-+ CCItem algIdItem;
-+ SECStatus ret = GetKeyAlgorithmId(CKYBuffer_Data(key),
-+ CKYBuffer_Size(key),&algIdItem);
-+ PKCS11Object::KeyType foundType = PKCS11Object::unknown;
-+
-+ if ( ret != SECSuccess ) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+
-+ CKYSize length = 0;
-+ const CKYByte *keyData = NULL;
-+
-+ /* Get actual oid buffer */
-+
-+ keyData = dataStart(algIdItem.data,algIdItem.len,&length, false);
-+ if (keyData == NULL) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+
-+ bool match = FALSE;
-+
-+ /* Check for outrageous length */
-+
-+ if ( length <= 3 || length >= algIdItem.len) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+ /* check for RSA */
-+
-+ match = GetKeyOIDMatches(keyData, length, rsaOID);
-+
-+ if ( match == TRUE ) {
-+ foundType = PKCS11Object::rsa;
-+ } else {
-+ /* check for ECC */
-+ match = GetKeyOIDMatches(keyData, length, eccOID);
-+
-+ if ( match == TRUE ) {
-+ foundType = PKCS11Object::ecc;
-+ }
-+
-+ }
-+
-+ if ( foundType == PKCS11Object::unknown) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+ return foundType;
-+}
-+
-+static SECStatus
-+GetKeyFieldItems(const CKYByte *spki_data,CKYSize spki_length,
- CCItem *modulus, CCItem *exponent)
- {
- const CKYByte *buf = spki_data;
-- unsigned int buf_length = spki_length;
-+ CKYSize buf_length = spki_length;
- const CKYByte*dummy;
-- unsigned int dummylen;
-+ CKYSize dummylen;
-
- /* skip past the algorithm id */
- dummy = dataStart(buf,buf_length,&dummylen,false);
-@@ -596,7 +925,7 @@ GetKeyFields(const CKYBuffer *spki, CKYB
- CCItem modulusItem, exponentItem;
-
- rv = GetKeyFieldItems(CKYBuffer_Data(spki), CKYBuffer_Size(spki),
-- &modulusItem, &exponentItem);
-+ &modulusItem, &exponentItem);
-
- if( rv != SECSuccess ) {
- throw PKCS11Exception(CKR_FUNCTION_FAILED,
-@@ -607,6 +936,29 @@ GetKeyFields(const CKYBuffer *spki, CKYB
- CKYBuffer_Replace(exponent, 0, exponentItem.data, exponentItem.len);
- }
-
-+static void
-+GetECKeyFields(const CKYBuffer *spki, CKYBuffer *point, CKYBuffer *params)
-+{
-+ SECStatus rv;
-+ CCItem pointItem, paramsItem;
-+
-+ if (spki == NULL || point == NULL || params == NULL) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode certificate Subject Public KeyInfo!");
-+ }
-+
-+ rv = GetECKeyFieldItems(CKYBuffer_Data(spki), CKYBuffer_Size(spki),
-+ &pointItem, ¶msItem);
-+
-+ if( rv != SECSuccess ) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode certificate Subject Public Key Info!");
-+ }
-+
-+ CKYBuffer_Replace(point, 0, pointItem.data, pointItem.len);
-+ CKYBuffer_Replace(params, 0, paramsItem.data, paramsItem.len);
-+}
-+
- Key::Key(unsigned long muscleObjID, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle) : PKCS11Object(muscleObjID, data, handle)
- {
-@@ -616,67 +968,113 @@ Key::Key(unsigned long muscleObjID, cons
- CKYBuffer_InitEmpty(&empty);
-
- if ((objClass == CKO_PUBLIC_KEY) || (objClass == CKO_PRIVATE_KEY)) {
-- /* only CKK_RSA is supported */
-- setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ //we may know already what type of key this is.
-+ if (attributeExists(CKA_KEY_TYPE)) {
-+ CK_ULONG type = 0;
-+ CK_ATTRIBUTE aTemplate = {CKA_KEY_TYPE, &type, sizeof(CK_ULONG)};
-+
-+ getAttributeValue(&aTemplate, 1, NULL);
-+
-+ if (type == 0x3) {
-+ setKeyType(ecc);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ } else {
-+ setKeyType(rsa);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ }
-+ } else {
-+ /* default to rsa */
-+ setKeyType(rsa);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ }
-+
-+ // Could be RSA or ECC
- } else if (objClass == CKO_SECRET_KEY) {
-- if (!attributeExists(CKA_LABEL)) {
-- setAttribute(CKA_LABEL, &empty);
-- }
-- if (!attributeExists(CKA_KEY_TYPE)) {
-- /* default to DES3 */
-- setAttributeULong(CKA_KEY_TYPE, CKK_DES3);
-- }
-+ if (!attributeExists(CKA_LABEL)) {
-+ setAttribute(CKA_LABEL, &empty);
-+ }
-+ if (!attributeExists(CKA_KEY_TYPE)) {
-+ /* default to DES3 */
-+ setAttributeULong(CKA_KEY_TYPE, CKK_DES3);
-+ }
- }
- if (!attributeExists(CKA_START_DATE)) {
-- setAttribute(CKA_START_DATE, &empty);
-+ setAttribute(CKA_START_DATE, &empty);
- }
- if (!attributeExists(CKA_END_DATE)) {
-- setAttribute(CKA_END_DATE, &empty);
-+ setAttribute(CKA_END_DATE, &empty);
- }
- }
-
- void
--Key::completeKey(const PKCS11Object &cert)
-+PKCS11Object::completeKey(const PKCS11Object &cert)
- {
- // infer key attributes from cert
- bool modulusExists, exponentExists;
-- CKYBuffer modulus; CKYBuffer_InitEmpty(&modulus);
-- CKYBuffer exponent; CKYBuffer_InitEmpty(&exponent);
-+ bool pointExists, paramsExists;
-+
-+ PKCS11Object::KeyType keyType;
-+ const CKYBuffer *key = cert.getPubKey();
-
- if (!attributeExists(CKA_LABEL)) {
-- setAttribute(CKA_LABEL, cert.getAttribute(CKA_LABEL));
-+ setAttribute(CKA_LABEL, cert.getAttribute(CKA_LABEL));
- }
-+
-+ CKYBuffer param1; CKYBuffer_InitEmpty(¶m1);
-+ CKYBuffer param2; CKYBuffer_InitEmpty(¶m2);
- try {
-- modulusExists = attributeExists(CKA_MODULUS);
-- exponentExists = attributeExists(CKA_PUBLIC_EXPONENT);
-- if (!modulusExists || !exponentExists) {
-- const CKYBuffer *key = cert.getPubKey();
-- GetKeyFields(key, &modulus, &exponent);
-- if (!modulusExists) {
-- setAttribute(CKA_MODULUS, &modulus);
-- }
-- if (!exponentExists) {
-- setAttribute(CKA_PUBLIC_EXPONENT, &exponent);
-- }
-- }
-+ keyType = GetKeyTypeFromSPKI(key);
-+ setKeyType(keyType);
-+
-+ switch (keyType) {
-+ case rsa:
-+ modulusExists = attributeExists(CKA_MODULUS);
-+ exponentExists = attributeExists(CKA_PUBLIC_EXPONENT);
-+ if (!modulusExists || !exponentExists) {
-+ GetKeyFields(key, ¶m1, ¶m2);
-+ if (!modulusExists) {
-+ setAttribute(CKA_MODULUS, ¶m1);
-+ }
-+ if (!exponentExists) {
-+ setAttribute(CKA_PUBLIC_EXPONENT, ¶m2);
-+ }
-+ }
-+ break;
-+ case ecc:
-+ pointExists = attributeExists(CKA_EC_POINT);
-+ paramsExists = attributeExists(CKA_EC_PARAMS);
-+
-+ if (!pointExists || !paramsExists) {
-+ GetECKeyFields(key, ¶m1, ¶m2);
-+ if (!pointExists) {
-+ setAttribute(CKA_EC_POINT, ¶m1);
-+ }
-+ if (!paramsExists) {
-+ setAttribute(CKA_EC_PARAMS, ¶m2);
-+ }
-+ }
-+ break;
-+ default:
-+ break;
-+ }
- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-- throw e;
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
-+ throw e;
- }
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
- }
-
- static SECStatus
--GetCertFieldItems(const CKYByte *dercert,unsigned int cert_length,
-+GetCertFieldItems(const CKYByte *dercert, CKYSize cert_length,
- CCItem *issuer, CCItem *serial, CCItem *derSN, CCItem *subject,
- CCItem *valid, CCItem *subjkey)
- {
- const CKYByte *buf;
-- unsigned int buf_length;
-+ CKYSize buf_length;
- const CKYByte*dummy;
-- unsigned int dummylen;
-+ CKYSize dummylen;
-
- /* get past the signature wrap */
- buf = dataStart(dercert,cert_length,&buf_length, false);
-@@ -737,14 +1135,14 @@ GetCertFieldItems(const CKYByte *dercert
-
- static void
- GetCertFields(const CKYBuffer *derCert, CKYBuffer *derSerial,
-- CKYBuffer *derSubject, CKYBuffer *derIssuer, CKYBuffer *subjectKey)
-+ CKYBuffer *derSubject, CKYBuffer *derIssuer, CKYBuffer *subjectKey)
- {
- SECStatus rv;
- CCItem issuerItem, serialItem, derSerialItem, subjectItem,
- validityItem, subjectKeyItem;
-
- rv = GetCertFieldItems(CKYBuffer_Data(derCert), CKYBuffer_Size(derCert),
-- &issuerItem, &serialItem, &derSerialItem, &subjectItem, &validityItem,
-+ &issuerItem, &serialItem, &derSerialItem, &subjectItem, &validityItem,
- &subjectKeyItem);
-
- if( rv != SECSuccess ) {
-@@ -769,50 +1167,50 @@ Cert::Cert(unsigned long muscleObjID, co
- CK_ULONG certTypeValue = CKC_X_509;
-
- CKYBuffer_InitFromData(&certType, (CKYByte *)&certTypeValue,
-- sizeof(certTypeValue));
-+ sizeof(certTypeValue));
- CKYBuffer_Resize(&pubKey,0);
-
- try {
-- setAttribute(CKA_CERTIFICATE_TYPE, &certType);
-+ setAttribute(CKA_CERTIFICATE_TYPE, &certType);
-
-- if (!attributeExists(CKA_VALUE)) {
-- if (derCert) {
-- setAttribute(CKA_VALUE, derCert);
-- } else {
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Missing certificate data from token");
-- }
-- }
-+ if (!attributeExists(CKA_VALUE)) {
-+ if (derCert) {
-+ setAttribute(CKA_VALUE, derCert);
-+ } else {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Missing certificate data from token");
-+ }
-+ }
-
-- if (!derCert) {
-- derCert = getAttribute(CKA_VALUE);
-- if (!derCert) {
-- // paranoia, should never happen since we verify the
-- // attribute exists above
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Missing certificate data from token");
-- }
-- }
-+ if (!derCert) {
-+ derCert = getAttribute(CKA_VALUE);
-+ if (!derCert) {
-+ // paranoia, should never happen since we verify the
-+ // attribute exists above
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Missing certificate data from token");
-+ }
-+ }
-
-- // infer cert attributes
-+ // infer cert attributes
-
-- GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-+ GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-
-- if (!attributeExists(CKA_SERIAL_NUMBER)) {
-- setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-- }
-- if (!attributeExists(CKA_SUBJECT)) {
-- setAttribute(CKA_SUBJECT, &derSubject);
-- }
-- if (!attributeExists(CKA_ISSUER)) {
-- setAttribute(CKA_ISSUER, &derIssuer);
-- }
-+ if (!attributeExists(CKA_SERIAL_NUMBER)) {
-+ setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-+ }
-+ if (!attributeExists(CKA_SUBJECT)) {
-+ setAttribute(CKA_SUBJECT, &derSubject);
-+ }
-+ if (!attributeExists(CKA_ISSUER)) {
-+ setAttribute(CKA_ISSUER, &derIssuer);
-+ }
- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&certType);
-- CKYBuffer_FreeData(&derSerial);
-- CKYBuffer_FreeData(&derSubject);
-- CKYBuffer_FreeData(&derIssuer);
-- throw e;
-+ CKYBuffer_FreeData(&certType);
-+ CKYBuffer_FreeData(&derSerial);
-+ CKYBuffer_FreeData(&derSubject);
-+ CKYBuffer_FreeData(&derIssuer);
-+ throw e;
- }
- CKYBuffer_FreeData(&certType);
- CKYBuffer_FreeData(&derSerial);
-@@ -822,7 +1220,7 @@ Cert::Cert(unsigned long muscleObjID, co
-
- Reader::Reader(unsigned long muscleObjID, CK_OBJECT_HANDLE handle,
- const char *reader, const CKYBuffer *cardATR, bool isCoolkey) :
-- PKCS11Object(muscleObjID, handle)
-+ PKCS11Object(muscleObjID, handle)
- {
- setAttributeULong(CKA_CLASS, CKO_MOZ_READER);
- setAttribute(CKA_LABEL, reader);
-@@ -833,9 +1231,10 @@ Reader::Reader(unsigned long muscleObjID
- setAttribute(CKA_MOZ_ATR, cardATR);
- }
-
-+
- CACPrivKey::CACPrivKey(CKYByte instance, const PKCS11Object &cert) :
-- PKCS11Object( ((int)'k') << 24 | ((int)instance+'0') << 16,
-- instance | 0x400)
-+ PKCS11Object( ((int)'k') << 24 | ((int)instance+'0') << 16,
-+ instance | 0x400)
- {
- CKYBuffer id;
- CKYBuffer empty;
-@@ -844,7 +1243,7 @@ CACPrivKey::CACPrivKey(CKYByte instance,
- /* So we know what the key is supposed to be used for based on
- * the instance */
- if (instance == 2) {
-- decrypt = TRUE;
-+ decrypt = TRUE;
- }
-
- CKYBuffer_InitEmpty(&empty);
-@@ -863,33 +1262,52 @@ CACPrivKey::CACPrivKey(CKYByte instance,
- setAttributeBool(CKA_LOCAL, TRUE);
- setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-
-- setAttributeBool(CKA_DECRYPT, decrypt);
- setAttributeBool(CKA_SIGN, !decrypt);
- setAttributeBool(CKA_SIGN_RECOVER, !decrypt);
- setAttributeBool(CKA_UNWRAP, FALSE);
- setAttributeBool(CKA_SENSITIVE, TRUE);
- setAttributeBool(CKA_EXTRACTABLE, FALSE);
-
-- CKYBuffer modulus; CKYBuffer_InitEmpty(&modulus);
-- CKYBuffer exponent; CKYBuffer_InitEmpty(&exponent);
-+ CKYBuffer param1; CKYBuffer_InitEmpty(¶m1);
-+ CKYBuffer param2; CKYBuffer_InitEmpty(¶m2);
-
- try {
-- const CKYBuffer *key = cert.getPubKey();
-- GetKeyFields(key, &modulus, &exponent);
-- setAttribute(CKA_MODULUS, &modulus);
-- setAttribute(CKA_PUBLIC_EXPONENT, &exponent);
-- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-- throw e;
-- }
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-+ const CKYBuffer *key = cert.getPubKey();
-+ keyType = GetKeyTypeFromSPKI(key);
-+ setKeyType(keyType);
-+
-+ switch (keyType) {
-+ case rsa:
-+ GetKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_MODULUS, ¶m1);
-+ setAttribute(CKA_PUBLIC_EXPONENT, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ setAttributeBool(CKA_DECRYPT, decrypt);
-+ setAttributeBool(CKA_DERIVE, FALSE);
-+ break;
-+ case ecc:
-+ GetECKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_EC_POINT, ¶m1);
-+ setAttribute(CKA_EC_PARAMS, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ setAttributeBool(CKA_DECRYPT, FALSE);
-+ setAttributeBool(CKA_DERIVE, decrypt);
-+ break;
-+ default:
-+ break;
-+ }
-+ } catch (PKCS11Exception &e) {
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
-+ throw e;
-+ }
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
- }
-
- CACPubKey::CACPubKey(CKYByte instance, const PKCS11Object &cert) :
-- PKCS11Object( ((int)'k') << 24 | ((int)(instance+'5')) << 16,
-- instance | 0x500)
-+ PKCS11Object( ((int)'k') << 24 | ((int)(instance+'5')) << 16,
-+ instance | 0x500)
- {
- CKYBuffer id;
- CKYBuffer empty;
-@@ -898,7 +1316,7 @@ CACPubKey::CACPubKey(CKYByte instance, c
- /* So we know what the key is supposed to be used for based on
- * the instance */
- if (instance == 2) {
-- encrypt = TRUE;
-+ encrypt = TRUE;
- }
-
- CKYBuffer_InitEmpty(&empty);
-@@ -915,83 +1333,102 @@ CACPubKey::CACPubKey(CKYByte instance, c
- setAttribute(CKA_END_DATE, &empty);
- setAttributeBool(CKA_DERIVE, FALSE);
- setAttributeBool(CKA_LOCAL, TRUE);
-- setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-
- setAttributeBool(CKA_ENCRYPT, encrypt);
- setAttributeBool(CKA_VERIFY, !encrypt);
- setAttributeBool(CKA_VERIFY_RECOVER, !encrypt);
- setAttributeBool(CKA_WRAP, FALSE);
-
-- CKYBuffer modulus; CKYBuffer_InitEmpty(&modulus);
-- CKYBuffer exponent; CKYBuffer_InitEmpty(&exponent);
-+ CKYBuffer param1; CKYBuffer_InitEmpty(¶m1);
-+ CKYBuffer param2; CKYBuffer_InitEmpty(¶m2);
-
- try {
-- const CKYBuffer *key = cert.getPubKey();
-- GetKeyFields(key, &modulus, &exponent);
-- setAttribute(CKA_MODULUS, &modulus);
-- setAttribute(CKA_PUBLIC_EXPONENT, &exponent);
-- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-- throw e;
-- }
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-+ const CKYBuffer *key = cert.getPubKey();
-+ keyType = GetKeyTypeFromSPKI(key);
-+ setKeyType(keyType);
-+
-+ switch (keyType) {
-+ case rsa:
-+ GetKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_MODULUS, ¶m1);
-+ setAttribute(CKA_PUBLIC_EXPONENT, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ break;
-+ case ecc:
-+ GetECKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_EC_POINT, ¶m1);
-+ setAttribute(CKA_EC_PARAMS, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ break;
-+ default:
-+ break;
-+ }
-+ } catch (PKCS11Exception &e) {
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
-+ throw e;
-+ }
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
- }
-
- static const char *CAC_Label[] = {
-- "CAC ID Certificate",
-- "CAC Email Signature Certificate",
-- "CAC Email Encryption Certificate",
-+ "CAC ID Certificate",
-+ "CAC Email Signature Certificate",
-+ "CAC Email Encryption Certificate",
- };
-
- static const unsigned char CN_DATA[] = { 0x55, 0x4, 0x3 };
- const unsigned int CN_LENGTH = sizeof(CN_DATA);
-
- static SECStatus
--GetCN(const CKYByte *dn, unsigned int dn_length, CCItem *cn)
-+GetCN(const CKYByte *dn, CKYSize dn_length, CCItem *cn)
- {
- const CKYByte *buf;
-- unsigned int buf_length;
-+ CKYSize buf_length;
-
- /* unwrap the sequence */
- buf = dataStart(dn,dn_length,&buf_length, false);
- if (buf == NULL) return SECFailure;
-
- while (buf_length) {
-- const CKYByte *name;
-- unsigned int name_length;
-- const CKYByte *oid;
-- unsigned int oid_length;
--
-- /* unwrap the set */
-- name = dataStart(buf, buf_length, &name_length, false);
-+ const CKYByte *name;
-+ CKYSize name_length;
-+ const CKYByte *oid;
-+ CKYSize oid_length;
-+
-+ /* unwrap the set */
-+ name = dataStart(buf, buf_length, &name_length, false);
-+ if (name == NULL) return SECFailure;
-
- /* advance to next set */
-- buf_length -= (name-buf) + name_length;
-- buf = name + name_length;
-+ buf_length -= (name-buf) + name_length;
-+ buf = name + name_length;
-
-- /* unwrap the Sequence */
-- name = dataStart(name, name_length, &name_length, false);
-+ /* unwrap the Sequence */
-+ name = dataStart(name, name_length, &name_length, false);
-+ if (name == NULL) return SECFailure;
-
- /* unwrap the oid */
-- oid = dataStart(name, name_length, &oid_length, false);
-+ oid = dataStart(name, name_length, &oid_length, false);
-+ if (oid == NULL) return SECFailure;
-
-- /* test the oid */
-- if (oid_length != CN_LENGTH) {
-- continue;
-- }
-- if (memcmp(oid, CN_DATA, CN_LENGTH) != 0) {
-- continue;
-- }
--
-- /* advance to CN */
-- name_length -= (oid-name) + oid_length;
-- name = oid + oid_length;
-+ /* test the oid */
-+ if (oid_length != CN_LENGTH) {
-+ continue;
-+ }
-+ if (memcmp(oid, CN_DATA, CN_LENGTH) != 0) {
-+ continue;
-+ }
-
-- /* unwrap the CN */
-- cn->data = dataStart(name, name_length, &cn->len, false);
-- return SECSuccess;
-+ /* advance to CN */
-+ name_length -= (oid-name) + oid_length;
-+ name = oid + oid_length;
-+
-+ /* unwrap the CN */
-+ cn->data = dataStart(name, name_length, &cn->len, false);
-+ if (cn->data == NULL) return SECFailure;
-+ return SECSuccess;
- }
- return SECFailure;
- }
-@@ -1006,11 +1443,11 @@ GetUserName(const CKYBuffer *dn)
- rv = GetCN(CKYBuffer_Data(dn), CKYBuffer_Size(dn) , &cn);
-
- if( rv != SECSuccess ) {
-- return NULL;
-+ return NULL;
- }
- string = new char [ cn.len + 1 ];
- if (string == NULL) {
-- return NULL;
-+ return NULL;
- }
- memcpy(string, cn.data, cn.len);
- string[cn.len] = 0;
-@@ -1018,18 +1455,11 @@ GetUserName(const CKYBuffer *dn)
- }
-
- CACCert::CACCert(CKYByte instance, const CKYBuffer *derCert) :
-- PKCS11Object( ((int)'c') << 24 | ((int)instance+'0') << 16,
-- instance | 0x600)
-+ PKCS11Object( ((int)'c') << 24 | ((int)instance+'0') << 16,
-+ instance | 0x600)
- {
- CKYBuffer id;
- CKYBuffer empty;
-- CK_BBOOL decrypt = FALSE;
--
-- /* So we know what the key is supposed to be used for based on
-- * the instance */
-- if (instance == 2) {
-- decrypt = TRUE;
-- }
-
- CKYBuffer_InitEmpty(&empty);
- setAttributeULong(CKA_CLASS, CKO_CERTIFICATE);
-@@ -1050,19 +1480,19 @@ CACCert::CACCert(CKYByte instance, const
- CKYBuffer_Resize(&pubKey,0);
-
- try {
-- setAttribute(CKA_VALUE, derCert);
-- // infer cert attributes
-+ setAttribute(CKA_VALUE, derCert);
-+ // infer cert attributes
-
-- GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-+ GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-
-- setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-- setAttribute(CKA_SUBJECT, &derSubject);
-- setAttribute(CKA_ISSUER, &derIssuer);
-+ setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-+ setAttribute(CKA_SUBJECT, &derSubject);
-+ setAttribute(CKA_ISSUER, &derIssuer);
- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&derSerial);
-- CKYBuffer_FreeData(&derSubject);
-- CKYBuffer_FreeData(&derIssuer);
-- throw e;
-+ CKYBuffer_FreeData(&derSerial);
-+ CKYBuffer_FreeData(&derSubject);
-+ CKYBuffer_FreeData(&derIssuer);
-+ throw e;
- }
-
- name = GetUserName(&derSubject); /* adopt */
-@@ -1070,3 +1500,1248 @@ CACCert::CACCert(CKYByte instance, const
- CKYBuffer_FreeData(&derSubject);
- CKYBuffer_FreeData(&derIssuer);
- }
-+
-+static const CKYByte rev[] = {
-+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-+};
-+
-+unsigned long GetBits(const CKYByte *entry, CKYSize entrySize,
-+ unsigned int numBits, unsigned int numBytes)
-+{
-+ unsigned long bits = 0;
-+ unsigned long bitFlag = 0;
-+ unsigned int i;
-+
-+ /* size of zero is valid for no bits */
-+ if (entrySize <= 1) {
-+ return 0;
-+ }
-+ entrySize--;
-+ entry++;
-+
-+ /* if we are longer than and unsigned, just bail now */
-+ if (entrySize > sizeof (unsigned long)) {
-+ bitFlag = BROKEN_FLAG;
-+ entrySize = sizeof(unsigned long);
-+ }
-+ /* turn the flags into an int */
-+ for (i=0; i < entrySize; i++) {
-+ CKYByte c = rev[entry[i]];
-+ bits = bits | (((unsigned long)c) << (i*8));
-+ }
-+ return bits | bitFlag;
-+}
-+
-+
-+/*
-+ * parse the path object.
-+ * Caller has already unwrapped the outer ASN1Sequence
-+ */
-+CKYStatus PK15ObjectPath::setObjectPath(const CKYByte *current, CKYSize size)
-+{
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ unsigned int i;
-+ CKYStatus status;
-+
-+
-+ if ((current == NULL) || (current[0] != ASN1_OCTET_STRING)) {
-+ return CKYINVALIDDATA;
-+ }
-+ /* entry */
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ status = CKYBuffer_Replace(&path, 0, entry, entrySize);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+
-+ /* index */
-+ if ((size != 0) && current[0] == ASN1_INTEGER) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ if (entrySize > 5) { return CKYINVALIDDATA; }
-+ for (index = 0, i=0; i < entrySize; i++) {
-+ index = (index << 8) + (unsigned int) entry[i];
-+ }
-+ }
-+
-+ /* length */
-+ if ((size != 0) && ((current[0]|ASN1_CONSTRUCTED) == ASN1_CHOICE_0)) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ if (entrySize > 5) { return CKYINVALIDDATA; }
-+ for (length = 0, i=0; i < entrySize; i++) {
-+ length = (length << 8) + (unsigned int) entry[i];
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+static unsigned int pK15GetTag(PK15ObjectType type) {
-+ switch (type) { case PK15PvKey: case PK15PuKey: return 'k'<<24;
-+ case PK15Cert: return 'c' << 24; default: break; }
-+ return 'v';
-+}
-+
-+
-+PK15Object::PK15Object(CKYByte inst, PK15ObjectType type,
-+ const CKYByte *der, CKYSize derSize)
-+ : PKCS11Object(pK15GetTag(type) | ((inst+'0') << 16), 0xa000 | inst)
-+{
-+ CKYStatus status;
-+
-+ instance = inst;
-+ p15Type = type;
-+ CKYBuffer_InitEmpty(&authId);
-+ CKYBuffer_InitEmpty(&pinAuthId);
-+ state = PK15StateInit;
-+ pinInfo.pinFlags = 0;
-+ pinInfo.pinType = P15PinUTF8;
-+ pinInfo.minLength = 4;
-+ pinInfo.storedLength = 0;
-+ pinInfo.maxLength = 0;
-+ pinInfo.pinRef = 0;
-+ pinInfo.padChar = 0xff;
-+
-+ status = completeObject(der, derSize);
-+ if (status != CKYSUCCESS) {
-+ state = PK15StateInit; /* don't try to fetch any more if we failed */
-+ }
-+}
-+
-+/* returns true if there is more work to do... */
-+CKYStatus
-+PK15Object::completeObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYByte objectTag;
-+ CKYStatus status;
-+ CKYBitFlags bits;
-+
-+ switch (state) {
-+ case PK15StateInit:
-+ case PK15StateNeedObject:
-+ break;
-+ case PK15StateNeedRawPublicKey:
-+ return completeRawPublicKey(current, currentSize);
-+ case PK15StateNeedRawCertificate:
-+ return completeRawCertificate(current, currentSize);
-+ case PK15StateComplete:
-+ return CKYSUCCESS;
-+ }
-+
-+ if (current == NULL) { return CKYINVALIDARGS; }
-+
-+ objectTag = current[0];
-+
-+ setAttributeBool(CKA_TOKEN, TRUE);
-+
-+ /* set type specific attributes */
-+ switch (p15Type) {
-+ case PK15Cert:
-+ setAttributeULong(CKA_CLASS, CKO_CERTIFICATE);
-+ setAttributeULong(CKA_CERTIFICATE_TYPE, CKC_X_509);
-+ if (objectTag != PK15X509CertType) {
-+ return CKYUNSUPPORTED;
-+ }
-+ break;
-+ case PK15PvKey:
-+ setAttributeULong(CKA_CLASS, CKO_PRIVATE_KEY);
-+ goto set_key_type;
-+ case PK15PuKey:
-+ setAttributeULong(CKA_CLASS, CKO_PUBLIC_KEY);
-+set_key_type:
-+ switch (objectTag) {
-+ case PK15RSAKeyType:
-+ keyType = rsa;
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ break;
-+ case PK15ECCKeyType:
-+ keyType = ecc;
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ break;
-+ case PK15DSAKeyType:
-+ case PK15DHKeyType:
-+ default:
-+ return CKYUNSUPPORTED;
-+ }
-+ break;
-+ case PK15AuthObj:
-+ setAttributeULong(CKA_CLASS, CKO_DATA);
-+ break;
-+ default:
-+ return CKYUNSUPPORTED;
-+ }
-+
-+ /* unwrap the object */
-+ current = dataStart(current, currentSize, ¤tSize, false);
-+ if (current == NULL) { return CKYINVALIDDATA; }
-+
-+ /*
-+ * parse the Common Attributes
-+ * label UTF8_STRING
-+ * flags BIT_STRING (optional)
-+ * authid OCTET_STRING (optional)
-+ */
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE))
-+ { return CKYINVALIDDATA; }
-+ /* unwrap */
-+ commonAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* point current to the next section (cass attributes) */
-+ tagSize = commonAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize +tagSize);
-+
-+ /* get the CKA_LABEL */
-+ if (commonAttributes[0] != ASN1_UTF8_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAttributes;
-+ commonAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_LABEL, entry, entrySize);
-+
-+ /* parse optional flags */
-+ bits = BROKEN_FLAG;
-+ if (commonAttributes[0] == ASN1_BIT_STRING) {
-+ entry = dataStart(commonAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAttributes;
-+ commonAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ bits = GetBits(entry,entrySize,2,1);
-+ }
-+
-+ if (commonAttributes[0] == ASN1_OCTET_STRING) {
-+ entry = dataStart(commonAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAttributes;
-+ commonAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ status = CKYBuffer_Replace(&authId, 0, entry, entrySize);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+ }
-+
-+ if (bits & BROKEN_FLAG) {
-+ bits = defaultCommonBits();
-+ }
-+ setAttributeBool(CKA_PRIVATE,
-+ (bits & P15FlagsPrivate) ? TRUE: FALSE);
-+ setAttributeBool(CKA_MODIFIABLE, FALSE); /* our token is ReadOnly, so the
-+ * object is never modifiable for
-+ * us */
-+ /* future common attributes here */
-+
-+ /*
-+ * Parse Class variables
-+ *
-+ */
-+ switch (p15Type) {
-+ case PK15Cert:
-+ status = completeCertObject(current,currentSize);
-+ break;
-+ case PK15PuKey:
-+ case PK15PvKey:
-+ status = completeKeyObject(current,currentSize);
-+ break;
-+ case PK15AuthObj:
-+ status = completeAuthObject(current, currentSize);
-+ break;
-+ }
-+ return status;
-+}
-+
-+
-+CKYStatus
-+PK15Object::completeCertObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonCertAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ CKYByte valueTag;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+
-+ /*
-+ * parse the Common Cert Attributes
-+ * id OCTET_STRING
-+ * authority BOOLEAN DEFAULT FALSE
-+ * requestId BIT_STRING (optional)
-+ * thumbprint [0] PKS15OOBCertHash (optional)
-+ */
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE))
-+ { return CKYINVALIDARGS; }
-+ /* unwrap */
-+ commonCertAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonCertAttributes == NULL) { return CKYINVALIDDATA; }
-+ /* point current to the next section (type attributes) */
-+ tagSize = commonCertAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize +tagSize);
-+
-+ /* get the id */
-+ if (commonCertAttributes[0] != ASN1_OCTET_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonCertAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonCertAttributes;
-+ commonCertAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_ID, entry, entrySize);
-+
-+
-+ /* skip authority (currently unused) */
-+ /* skip requestID */
-+ /* skip thumbprint */
-+ /* future common cert attributes here */
-+
-+ /* certs have not subclass attributes ASN1_CHOICE_0 */
-+
-+ /* handle the X509 type attributes */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDDATA; }
-+ /* unwrap */
-+ commonCertAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonCertAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /*
-+ * PCKS11X504CertificateAttributes
-+ * value SEQUENCE or CHOICE_0
-+ * ... don't care about the rest.
-+ */
-+ valueTag = commonCertAttributes[0];
-+ /* unwrapp */
-+ entry = dataStart(commonCertAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ if (valueTag == ASN1_SEQUENCE) {
-+ entry = dataStart(entry, entrySize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ state = PK15StateNeedRawCertificate;
-+ return status;
-+ }
-+ if (valueTag != ASN1_CHOICE_0) {
-+ return CKYINVALIDDATA;
-+ }
-+ return completeRawCertificate(entry, entrySize);
-+}
-+
-+CKYStatus
-+PK15Object::completeAuthObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonAuthAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+
-+ if (current == NULL) { return CKYINVALIDARGS; }
-+ /* common Auth attributes */
-+ if (current[0] == ASN1_SEQUENCE) {
-+ /* unwrap */
-+ commonAuthAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
-+ tagSize = commonAuthAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+ if (commonAuthAttributes[0] != ASN1_OCTET_STRING) {
-+ return CKYINVALIDDATA;
-+ }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ status = CKYBuffer_Replace(&pinAuthId, 0, entry, entrySize);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+
-+ }
-+ /* auth specific values */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDARGS; }
-+ /* unwrap */
-+ commonAuthAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
-+ tagSize = commonAuthAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+ /*
-+ * parse the Pin Auth Attributes
-+ * pinFlags BIT_STRING
-+ * pinType ENUMERATED (bcd, ascii-numeric, utf8)
-+ * minLength INTEGER
-+ * storedLength INTEGER
-+ * maxlength INTEGER (optional)
-+ * pinReference CHOICE_0 (optional)
-+ * padChar OCTET_STRING (optional)
-+ * lastPinChange GENERALIZED_TIME (optional)
-+ * path PKCS15Path (optional)
-+ */
-+ if (commonAuthAttributes[0] != ASN1_SEQUENCE) { return CKYINVALIDARGS; }
-+ commonAuthAttributes = dataStart(commonAuthAttributes,
-+ commonSize, &commonSize, false);
-+ if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* parse pin flags */
-+ if (commonAuthAttributes[0] != ASN1_BIT_STRING) { return CKYINVALIDDATA; }
-+
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ pinInfo.pinFlags = GetBits(entry,entrySize,9,2);
-+
-+
-+ /* parse PinType */
-+ if (commonAuthAttributes[0] != ASN1_ENUMERATED) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* turn entry into an int */
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.pinType = (P15PinType) *entry;
-+
-+ /* parse minLength */
-+ if (commonAuthAttributes[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.minLength = *entry;
-+
-+ /* parse storedLength */
-+ if (commonAuthAttributes[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.storedLength = *entry;
-+
-+ /* parse maxLength (optional) */
-+ if (commonAuthAttributes[0] == ASN1_INTEGER) {
-+ unsigned long maxPin;
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > sizeof (maxPin)) { return CKYINVALIDARGS; }
-+ maxPin = 0;
-+ CKYSize i;
-+ for (i=0; i < entrySize; i++) {
-+ maxPin = (maxPin << 8) | entry[i];
-+ }
-+ pinInfo.maxLength = maxPin;
-+ }
-+
-+ /* parse pin ref (optional) */
-+ if ((commonAuthAttributes[0]|ASN1_CONSTRUCTED) == ASN1_CHOICE_0) {
-+ CKYByte pinRef;
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 2) { return CKYINVALIDARGS; }
-+ if (entrySize == 2) {
-+ if (*entry != 0) { return CKYINVALIDARGS; }
-+ pinRef = entry[1];
-+ } else pinRef = entry[0];
-+ pinInfo.pinRef = pinRef;
-+ }
-+
-+ /* parse padChar */
-+ if (commonAuthAttributes[0] == ASN1_OCTET_STRING) {
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.padChar = *entry;
-+ }
-+
-+ /* skip lastPinChange */
-+ if (commonAuthAttributes[0] == ASN1_GENERALIZED_TIME) {
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ }
-+ /* parse path */
-+ if (commonAuthAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonAuthAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+ }
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+PK15Object::completeKeyObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonKeyAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ unsigned long bits;
-+ /*bool native; */
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ /*
-+ * parse the Common Key Attributes
-+ * id OCTET_STRING
-+ * usageFlags BIT_STRING
-+ * native BOOLEAN DEFAULT TRUE
-+ * accessFlags BIT_STRING (optional)
-+ * keyReference OCTET_STRING (optional)
-+ * startDate GENERALIZED_TIME (optional)
-+ * endDate [0] GENERALIZED_TYPE (optional)
-+ */
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE))
-+ { return CKYINVALIDARGS; }
-+ /* unwrap */
-+ commonKeyAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* point current to the next section (sublcass attributes) */
-+ tagSize = commonKeyAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+
-+ /* get the id */
-+ if (commonKeyAttributes[0] != ASN1_OCTET_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_ID, entry, entrySize);
-+
-+ /* parse flags */
-+ if (commonKeyAttributes[0] != ASN1_BIT_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ bits = GetBits(entry,entrySize,10,2);
-+ if (bits & BROKEN_FLAG) {
-+ bits = defaultUsageBits();
-+ }
-+ setAttributeBool(CKA_ENCRYPT,
-+ (bits & P15UsageEncrypt) ? TRUE : FALSE);
-+ setAttributeBool(CKA_DECRYPT,
-+ (bits & P15UsageDecrypt) ? TRUE : FALSE);
-+ setAttributeBool(CKA_SIGN,
-+ (bits & P15UsageSign) ? TRUE : FALSE);
-+ setAttributeBool(CKA_SIGN_RECOVER,
-+ (bits & P15UsageSignRecover) ? TRUE : FALSE);
-+ setAttributeBool(CKA_WRAP,
-+ (bits & P15UsageWrap) ? TRUE : FALSE);
-+ setAttributeBool(CKA_UNWRAP,
-+ (bits & P15UsageUnwrap) ? TRUE : FALSE);
-+ setAttributeBool(CKA_VERIFY,
-+ (bits & P15UsageVerify) ? TRUE : FALSE);
-+ setAttributeBool(CKA_VERIFY_RECOVER,
-+ (bits & P15UsageVerifyRecover) ? TRUE : FALSE);
-+ setAttributeBool(CKA_DERIVE,
-+ (bits & P15UsageDerive) ? TRUE : FALSE);
-+ /* no CKA value for P15UsageNonRepudiation */
-+ if (bits & P15UsageNonRepudiation) {
-+ /* set signing and sign recover. Non-repudiation keys are automatically
-+ * signing keys */
-+ setAttributeBool(CKA_SIGN, TRUE);
-+ if (keyType == rsa) {
-+ setAttributeBool(CKA_SIGN_RECOVER, TRUE);
-+ }
-+ }
-+
-+ /* parse native (currently unused) */
-+ /*native=true; */
-+ if (commonKeyAttributes[0] == ASN1_BOOLEAN) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /*if ((entrySize == 1) && (entry[0] == 0)) {
-+ native = false;
-+ } */
-+ }
-+ /* parse access flags */
-+ bits = BROKEN_FLAG;
-+ if (commonKeyAttributes[0] == ASN1_BIT_STRING) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ bits = GetBits(entry,entrySize,4,1);
-+ }
-+ if (bits & BROKEN_FLAG) {
-+ bits = defaultAccessBits();
-+ }
-+ setAttributeBool(CKA_SENSITIVE,
-+ (bits & P15AccessSensitive) ? TRUE : FALSE);
-+ setAttributeBool(CKA_EXTRACTABLE,
-+ (bits & P15AccessExtractable) ? TRUE : FALSE);
-+ setAttributeBool(CKA_ALWAYS_SENSITIVE,
-+ (bits & P15AccessAlwaysSenstive) ? TRUE : FALSE);
-+ setAttributeBool(CKA_NEVER_EXTRACTABLE,
-+ (bits & P15AccessNeverExtractable)? TRUE : FALSE);
-+ setAttributeBool(CKA_LOCAL,
-+ (bits & P15AccessLocal) ? TRUE : FALSE);
-+
-+ /* parse the key reference */
-+ keyRef = PK15_INVALID_KEY_REF; /* invalid keyRef */
-+ if (commonKeyAttributes[0] == ASN1_INTEGER) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize == 1) {
-+ keyRef = entry[0];
-+ } else if ((entrySize == 2) && (entry[0] == 0)) {
-+ keyRef = entry[1];
-+ }
-+ }
-+ setAttribute(CKA_START_DATE, &empty);
-+ if (commonKeyAttributes[0] == ASN1_GENERALIZED_TIME) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_START_DATE,entry, entrySize);
-+ }
-+ setAttribute(CKA_END_DATE, &empty);
-+ if (commonKeyAttributes[0] == ASN1_CHOICE_0) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_END_DATE,entry, entrySize);
-+ }
-+ /* future common key attributes here */
-+
-+ /*
-+ * Parse Class variables
-+ *
-+ */
-+ switch (p15Type) {
-+ case PK15PuKey:
-+ status = completePubKeyObject(current,currentSize);
-+ break;
-+ case PK15PvKey:
-+ status = completePrivKeyObject(current,currentSize);
-+ break;
-+ default:
-+ status=CKYLIBFAIL; /* shouldn't happen */
-+ break;
-+ }
-+ return status;
-+}
-+
-+CKYStatus PK15Object::completePrivKeyObject(const CKYByte *current,
-+ CKYSize currentSize)
-+{
-+ const CKYByte *commonPrivKeyAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ unsigned int modulusSize;
-+ unsigned int i;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ if (current == NULL) { return CKYINVALIDARGS; }
-+
-+ /* optional subclass = CommonPrivateKeyAttributes */
-+ if (current[0] == ASN1_CHOICE_0) {
-+ /*
-+ * PKCS15CommonPrivateKeyAttributes
-+ *
-+ * subjectName SEQUENCE optional
-+ * keyIdentifiers CHOICE 0 optional
-+ */
-+ /* unwrap */
-+ commonPrivKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ /* point current to the next section (type attributes) */
-+ tagSize = commonPrivKeyAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize +tagSize);
-+
-+ /* subjectName */
-+ if (commonPrivKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPrivKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPrivKeyAttributes;
-+ commonPrivKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_SUBJECT, entry, entrySize);
-+ }
-+
-+ /* keyIdentfiers */
-+ /* future CommonPrivateKeyAttributes here */
-+ }
-+
-+
-+ /* Type attributes (either PKCS15RSAPrivateKeyAttributes or
-+ * PKCS15ECCPrivateKeyAttributes) -- Not Optional */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDDATA; }
-+ /*
-+ * PKCS15RSAPrivateKeyAttributes
-+ * value PKCS15ObjectValue
-+ * modulusLength INTEGER
-+ * keyInfo SEQUENCE optional
-+ * PKCS15ECCPrivateKeyAttributes
-+ * value PKCS15ObjectValue
-+ * keyInfo SEQUENCE optional
-+ */
-+ /* unwrap */
-+ commonPrivKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* value */
-+ /* don't support direct private key objects */
-+ if (commonPrivKeyAttributes[0] == ASN1_CHOICE_0) { return CKYUNSUPPORTED; }
-+ if (commonPrivKeyAttributes[0] != ASN1_SEQUENCE) { return CKYINVALIDDATA; }
-+ commonPrivKeyAttributes = dataStart(commonPrivKeyAttributes, commonSize, &commonSize, false);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDARGS; }
-+ entry = dataStart(commonPrivKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPrivKeyAttributes;
-+ commonPrivKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+
-+ /* parse modulus size */
-+ if ((keyType == rsa) && commonPrivKeyAttributes[0] == ASN1_INTEGER) {
-+ entry = dataStart(commonPrivKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPrivKeyAttributes;
-+ commonPrivKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 4) {
-+ return CKYINVALIDDATA;
-+ }
-+ for (modulusSize = 0, i=0; i < entrySize; i++) {
-+ modulusSize = (modulusSize << 8) + entry[i];
-+ }
-+ setKeySize(modulusSize);
-+ }
-+
-+ if (keyType == rsa) {
-+ state = PK15StateComplete;
-+ return CKYSUCCESS; /* we're done with RSA */
-+ }
-+
-+ /* parse keyinfo at this point all we are after is the EC_PARAM*/
-+ if (commonPrivKeyAttributes[0] == ASN1_SEQUENCE) {
-+ /* unwrap */
-+ commonPrivKeyAttributes = dataStart(commonPrivKeyAttributes,
-+ commonSize, &commonSize, true);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ if (commonPrivKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPrivKeyAttributes, commonSize,
-+ &entrySize, true);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ setAttribute(CKA_EC_PARAMS, entry, entrySize);
-+ }
-+ }
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+PK15Object::completePubKeyObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonPubKeyAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ unsigned int modulusSize;
-+ unsigned int i;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ if (current == NULL) { return CKYINVALIDDATA; }
-+
-+ /* optional subclass = CommonPublicKeyAttributes */
-+ if (current[0] == ASN1_CHOICE_0) {
-+ /*
-+ * PKCS15CommonPublicKeyAttributes
-+ *
-+ * subjectName SEQUENCE optional
-+ * keyIdentifiers CHOICE 0 optional
-+ */
-+ /* unwrap */
-+ commonPubKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPubKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ /* point current to the next section (type attributes) */
-+ tagSize = commonPubKeyAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+
-+ /* subjectName */
-+ if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPubKeyAttributes;
-+ commonPubKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_SUBJECT, entry, entrySize);
-+ }
-+ /* future CommonPublicKeyAttributes here */
-+ }
-+
-+
-+ /* Type attributes (either PKCS15RSAPublicKeyAttributes or
-+ * PKCS15ECCPublicKeyAttributes) -- Not Optional */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDDATA; }
-+ /*
-+ * PKCS15RSAPublicKeyAttributes
-+ * value PKCS15ObjectValue
-+ * modulusLength INTEGER
-+ * keyInfo SEQUENCE optional
-+ * PKCS15ECCPublicKeyAttributes
-+ * value PKCS15ObjectValue
-+ * keyInfo SEQUENCE optional
-+ */
-+ /* unwrap */
-+ commonPubKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPubKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* value */
-+ if (commonPubKeyAttributes[0] == ASN1_CHOICE_0) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ status = completeRawPublicKey(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+ } else if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPubKeyAttributes;
-+ commonPubKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+ state = PK15StateNeedRawPublicKey;
-+ }
-+
-+ /* parse modulus size */
-+ if ((keyType == rsa) && commonPubKeyAttributes[0] == ASN1_INTEGER) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPubKeyAttributes;
-+ commonPubKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 4) {
-+ return CKYINVALIDDATA;
-+ }
-+ for (modulusSize = 0, i=0; i < entrySize; i++) {
-+ modulusSize = (modulusSize << 8) + entry[i];
-+ }
-+ setKeySize(modulusSize);
-+ }
-+
-+ if (keyType == rsa) {
-+ return CKYSUCCESS; /* we're done with RSA */
-+ }
-+
-+ /* parse keyinfo at this point all we are after is the EC_PARAM*/
-+ if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ /* unwrap */
-+ commonPubKeyAttributes = dataStart(commonPubKeyAttributes,
-+ commonSize, &commonSize, true);
-+ if (commonPubKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, true);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ setAttribute(CKA_EC_PARAMS, entry, entrySize);
-+ }
-+ }
-+ return CKYSUCCESS;
-+
-+}
-+
-+CKYStatus
-+PK15Object::completeRawCertificate(const CKYByte *derCert, CKYSize derCertSize)
-+{
-+ SECStatus rv;
-+ CCItem issuerItem, serialItem, derSerialItem, subjectItem,
-+ validityItem, subjectKeyItem;
-+ const char *certLabel;
-+
-+ setAttribute(CKA_VALUE, derCert, derCertSize);
-+ rv = GetCertFieldItems(derCert, derCertSize,
-+ &issuerItem, &serialItem, &derSerialItem, &subjectItem, &validityItem,
-+ &subjectKeyItem);
-+ if (rv != SECSuccess) {
-+ return CKYINVALIDDATA;
-+ }
-+ setAttribute(CKA_SERIAL_NUMBER, derSerialItem.data, derSerialItem.len);
-+ setAttribute(CKA_SUBJECT, subjectItem.data, subjectItem.len);
-+ setAttribute(CKA_ISSUER, issuerItem.data, issuerItem.len);
-+ CKYBuffer_Replace(&pubKey, 0, subjectKeyItem.data, subjectKeyItem.len);
-+ /* if we didn't get a label, set one based on the CN */
-+ certLabel = getLabel();
-+ if ((certLabel == NULL) || (*certLabel == 0)) {
-+ CKYBuffer subject;
-+ char *newLabel;
-+ CKYBuffer_InitFromData(&subject, subjectItem.data, subjectItem.len);
-+ newLabel = GetUserName(&subject);
-+ if (newLabel) {
-+ setAttribute(CKA_LABEL, (CKYByte *)newLabel,
-+ (CKYSize) strlen(newLabel)-1);
-+ delete [] newLabel;
-+ }
-+ CKYBuffer_FreeData(&subject);
-+ }
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+PK15Object::completeRawPublicKey(const CKYByte *current, CKYSize size)
-+{
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE)) {
-+ return CKYINVALIDDATA;
-+ }
-+ /* unwrap*/
-+ current = dataStart(current, size, &size, false);
-+ if (current == NULL) { return CKYINVALIDDATA; }
-+
-+ /* modulus */
-+ if (current[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ if ((entry[0] == 0) && (entrySize > 1)) {
-+ entry++; entrySize--;
-+ }
-+ setAttribute(CKA_MODULUS, entry, entrySize);
-+
-+ /* exponent */
-+ if (current[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize + tagSize);
-+ if ((entry[0] == 0) && (entrySize > 1)) {
-+ entry++; entrySize--;
-+ }
-+ setAttribute(CKA_PUBLIC_EXPONENT, entry, entrySize);
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+DEREncodedSignature::DEREncodedSignature(const CKYBuffer *derSig)
-+{
-+
-+ CKYBuffer_InitEmpty(&derEncodedSignature);
-+ CKYBuffer_InitFromCopy(&derEncodedSignature, derSig);
-+}
-+
-+DEREncodedSignature::~DEREncodedSignature()
-+{
-+ CKYBuffer_FreeData(&derEncodedSignature);
-+}
-+
-+int DEREncodedSignature::getRawSignature(CKYBuffer *rawSig,
-+ unsigned int keySize)
-+{
-+ const CKYByte *buf = NULL;
-+
-+ if (rawSig == NULL) {
-+ return -1;
-+ }
-+
-+ if (CKYBuffer_Size(&derEncodedSignature) == 0) {
-+ return -1;
-+ }
-+
-+ CKYBuffer_Zero(rawSig);
-+
-+ CKYSize seq_length = 0;
-+ CKYSize expected_sig_len = ( (keySize + 7) / 8 ) * 2 ;
-+ CKYSize expected_piece_size = expected_sig_len / 2 ;
-+
-+ /* unwrap the sequence */
-+ buf = dataStart(CKYBuffer_Data(&derEncodedSignature), CKYBuffer_Size(&derEncodedSignature),&seq_length, false);
-+
-+ if (buf == NULL) return -1;
-+
-+ // unwrap first multi byte integer
-+
-+ CKYSize int_length = 0;
-+ const CKYByte *int1Buf = NULL;
-+ const CKYByte *int2Buf = NULL;
-+
-+ int1Buf = dataStart(buf, seq_length, &int_length, false );
-+
-+ if (int1Buf == NULL) return -1;
-+ //advance to next entry
-+
-+ if (int_length > expected_piece_size) {
-+
-+ unsigned int diff = int_length - expected_piece_size ;
-+
-+ /* Make sure we are chopping off zeroes
-+ Otherwise give up. */
-+
-+ for (int i = 0 ; i < (int) diff ; i++) {
-+ if ( int1Buf[i] != 0)
-+ return -1;
-+ }
-+
-+ int_length -= diff;
-+ int1Buf += diff;
-+
-+ }
-+
-+ seq_length -= (int1Buf -buf) + int_length;
-+ buf = int1Buf + int_length;
-+
-+ // unwrap second multi byte integer
-+
-+ CKYSize second_int_length = 0;
-+
-+ int2Buf = dataStart(buf, seq_length, &second_int_length, false);
-+
-+ if (int2Buf == NULL) return -1;
-+
-+
-+ if (second_int_length > expected_piece_size) {
-+ unsigned int diff = second_int_length - expected_piece_size ;
-+
-+ /* Make sure we are chopping off zeroes
-+ Otherwise give up. */
-+
-+ for (int i = 0 ; i < (int) diff ; i++) {
-+ if ( int2Buf[i] != 0)
-+ return -1;
-+ }
-+
-+ second_int_length -= diff;
-+ int2Buf += diff;
-+ }
-+
-+ CKYBuffer_AppendData(rawSig, int1Buf, int_length);
-+ CKYBuffer_AppendData(rawSig, int2Buf, second_int_length);
-+
-+ return CKYSUCCESS;
-+}
-+
-+DEREncodedTokenInfo::DEREncodedTokenInfo(CKYBuffer *derTokenInfo)
-+{
-+ const CKYByte *current = CKYBuffer_Data(derTokenInfo);
-+ const CKYByte *entry;
-+ CKYSize size = CKYBuffer_Size(derTokenInfo);
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ /* set token name, etc */
-+
-+ version = -1;
-+ CKYBuffer_InitEmpty(&serialNumber);
-+ manufacturer = NULL;
-+ tokenName = NULL;
-+
-+ if (current[0] != ASN1_SEQUENCE) {
-+ return; /* just use the defaults */
-+ }
-+ /* unwrap */
-+ current = dataStart(current, size, &size, false);
-+ if (current == NULL) return;
-+
-+ /* parse the version */
-+ if (current[0] != ASN1_INTEGER) { return; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ if (size < tagSize + entrySize) return;
-+ size -= tagSize + entrySize;
-+ if (entrySize < 1) {
-+ version = *entry;
-+ }
-+
-+ /* get the serial number */
-+ if (current[0] != ASN1_OCTET_STRING) { return ; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ CKYBuffer_Replace(&serialNumber, 0, entry, entrySize);
-+ /* should we fake the cuid here? */
-+
-+ /* get the optional manufacture ID */
-+ if (current[0] == ASN1_UTF8_STRING) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ manufacturer = (char *)malloc(entrySize+1);
-+ if (manufacturer) {
-+ memcpy(manufacturer, entry, entrySize);
-+ manufacturer[entrySize] = 0;
-+ }
-+ }
-+
-+ /* get the optional token name */
-+ /* most choices are constructed,
-+ * but this one isn't explicity add the flag */
-+ if ((current[0]|ASN1_CONSTRUCTED) == ASN1_CHOICE_0) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ tokenName = (char *)malloc(entrySize+1);
-+ if (tokenName) {
-+ memcpy(tokenName, entry, entrySize);
-+ tokenName[entrySize] = 0;
-+ }
-+ }
-+
-+ /* parsing flags */
-+#ifdef notdef
-+ /* we arn't using this right now, keep it for future reference */
-+ if (current[0] == ASN1_BIT_STRING) {
-+ /* recordinfo parsing would go here */
-+ unsigned long bits;
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ bits = GetBits(entry, entrySize,8,2);
-+ }
-+#endif
-+ return;
-+}
-+
-diff -up ./src/coolkey/object.h.coolkey-update ./src/coolkey/object.h
---- ./src/coolkey/object.h.coolkey-update 2016-01-19 17:53:12.934012153 -0800
-+++ ./src/coolkey/object.h 2016-01-19 17:53:22.057937117 -0800
-@@ -27,6 +27,33 @@
-
- using std::list;
-
-+/*
-+ * Sigh PKCS 15 is heavily ASN.1...
-+ */
-+const CKYByte ASN1_BOOLEAN = 0x01;
-+const CKYByte ASN1_INTEGER = 0x02;
-+const CKYByte ASN1_BIT_STRING = 0x03;
-+const CKYByte ASN1_OCTET_STRING = 0x04;
-+const CKYByte ASN1_ENUMERATED = 0x0a;
-+const CKYByte ASN1_UTF8_STRING = 0x0c;
-+const CKYByte ASN1_GENERALIZED_TIME = 0x18;
-+const CKYByte ASN1_CONSTRUCTED = 0x20;
-+const CKYByte ASN1_SEQUENCE = 0x30;
-+const CKYByte ASN1_CHOICE_0 = 0xa0;
-+const CKYByte ASN1_CHOICE_1 = 0xa1;
-+const CKYByte ASN1_CHOICE_2 = 0xa2;
-+const CKYByte ASN1_CHOICE_3 = 0xa3;
-+
-+const CKYBitFlags BROKEN_FLAG = 0x80000000;
-+const unsigned int PK11_INVALID_KEY_REF = -1;
-+
-+const CKYByte PK15X509CertType = ASN1_SEQUENCE;
-+const CKYByte PK15RSAKeyType = ASN1_SEQUENCE;
-+const CKYByte PK15ECCKeyType = ASN1_CHOICE_0;
-+const CKYByte PK15DHKeyType = ASN1_CHOICE_1;
-+const CKYByte PK15DSAKeyType = ASN1_CHOICE_2;
-+const CKYByte PK15KEAKeyType = ASN1_CHOICE_3;
-+
- class PKCS11Attribute {
- private:
- CK_ATTRIBUTE_TYPE type;
-@@ -49,14 +76,40 @@ class PKCS11Attribute {
- CKYBuffer_Size(&cpy.value));
- return *this;
- }
-- PKCS11Attribute() { CKYBuffer_InitEmpty(&value); }
-+ PKCS11Attribute() : type(0){ CKYBuffer_InitEmpty(&value); }
- PKCS11Attribute(CK_ATTRIBUTE_TYPE type_, const CKYBuffer *value_)
- : type(type_) { CKYBuffer_InitFromCopy(&value, value_); }
-+ PKCS11Attribute(CK_ATTRIBUTE_TYPE type_, const CKYByte *data_,
-+ CKYSize size_) : type(type_)
-+ { CKYBuffer_InitFromData(&value, data_, size_); }
- ~PKCS11Attribute() { CKYBuffer_FreeData(&value); }
- };
-
-+class PK15ObjectPath {
-+ private:
-+ CKYBuffer path;
-+ CKYOffset index;
-+ CKYSize length;
-+ public:
-+ PK15ObjectPath() : index(0), length(0) { CKYBuffer_InitEmpty(&path); }
-+ PK15ObjectPath(const PK15ObjectPath &cpy) :
-+ index(cpy.index), length(cpy.length)
-+ { CKYBuffer_InitFromCopy(&path, &cpy.path); }
-+ ~PK15ObjectPath() { CKYBuffer_FreeData(&path); }
-+ const CKYBuffer *getPath() const { return &path; }
-+ CKYOffset getIndex() const { return index; }
-+ CKYSize getLength() const { return length; }
-+ CKYStatus setObjectPath(const CKYByte *entry, CKYSize size);
-+};
-+
-+
- class PKCS11Object {
- public:
-+ enum KeyType {
-+ rsa,
-+ ecc,
-+ unknown
-+ };
-
- typedef list<PKCS11Attribute> AttributeList;
- typedef AttributeList::iterator AttributeIter;
-@@ -67,6 +120,8 @@ class PKCS11Object {
- unsigned long muscleObjID;
- CK_OBJECT_HANDLE handle;
- char *label;
-+ unsigned int keySize;
-+ CK_USER_TYPE user;
-
- void parseOldObject(const CKYBuffer *data);
- void parseNewObject(const CKYBuffer *data);
-@@ -75,19 +130,39 @@ class PKCS11Object {
- PKCS11Object &operator=(PKCS11Object &cpy) { return *this; } //Disallow
-
- protected :
-- CKYBuffer pubKey;
- char *name;
-+ KeyType keyType;
-+ unsigned int keyRef;
-+ CKYBuffer pubKey;
-+ CKYBuffer authId;
-+ CKYBuffer pinAuthId;
-+ PK15ObjectPath objectPath;
-
- public:
- PKCS11Object(unsigned long muscleObjID, CK_OBJECT_HANDLE handle);
- PKCS11Object(unsigned long muscleObjID, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle);
-- ~PKCS11Object() { delete [] label; delete [] name; CKYBuffer_FreeData(&pubKey); }
-+ virtual ~PKCS11Object() { delete [] label; delete [] name;
-+ CKYBuffer_FreeData(&pubKey); CKYBuffer_FreeData(&authId);
-+ CKYBuffer_FreeData(&pinAuthId); attributes.clear(); }
-
- PKCS11Object(const PKCS11Object& cpy) :
- attributes(cpy.attributes), muscleObjID(cpy.muscleObjID),
-- handle(cpy.handle), label(NULL), name(NULL) {
-- CKYBuffer_InitFromCopy(&pubKey,&cpy.pubKey); }
-+ handle(cpy.handle), label(NULL), keySize(cpy.keySize),
-+ user(cpy.user), name(NULL), keyType(cpy.keyType), keyRef(cpy.keyRef),
-+ objectPath(cpy.objectPath) {
-+ /* label is just a cached value, don't need
-+ * to copy it. */
-+ if (cpy.name != NULL) {
-+ int len = strlen(cpy.name);
-+ name= new char [len+1];
-+ if (name) {
-+ memcpy(name,cpy.name,len+1);
-+ }
-+ }
-+ CKYBuffer_InitFromCopy(&pubKey,&cpy.pubKey);
-+ CKYBuffer_InitFromCopy(&authId,&cpy.authId);
-+ CKYBuffer_InitFromCopy(&pinAuthId,&cpy.pinAuthId); }
-
-
- unsigned long getMuscleObjID() const { return muscleObjID; }
-@@ -100,6 +175,8 @@ class PKCS11Object {
-
- void setAttribute(CK_ATTRIBUTE_TYPE type, const CKYBuffer *value);
- void setAttribute(CK_ATTRIBUTE_TYPE type, const char *);
-+ void setAttribute(CK_ATTRIBUTE_TYPE type, const CKYByte *data,
-+ CKYSize size);
- /* bools and ulongs are too close, don't abuse function overloading
- * for these cases */
- void setAttributeBool(CK_ATTRIBUTE_TYPE type, CK_BBOOL);
-@@ -116,14 +193,22 @@ class PKCS11Object {
- const CKYBuffer *getPubKey(void) const {
- return &pubKey;
- }
-+
-+ KeyType getKeyType(void) const { return keyType;}
-+ unsigned int getKeySize(void) const { return keySize; }
-+ unsigned int getKeyRef(void) const { return keyRef; }
-+ CK_USER_TYPE getUser(void) const { return user; }
-+ void setKeyType(KeyType theType) { keyType = theType; }
-+ void setKeySize(unsigned int keySize_) { keySize = keySize_; }
-+ const CKYBuffer *getAuthId(void) const { return &authId; }
-+ const CKYBuffer *getPinAuthId(void) const { return &pinAuthId; }
-+ const PK15ObjectPath &getObjectPath() const { return objectPath; }
-+ void completeKey(const PKCS11Object &cert);
- };
-
- class Key : public PKCS11Object {
--
- public:
- Key(unsigned long muscleObjID, const CKYBuffer *data, CK_OBJECT_HANDLE handle);
-- void completeKey(const PKCS11Object &cert);
--
- };
-
- class Cert : public PKCS11Object {
-@@ -147,12 +232,124 @@ class CACCert : public PKCS11Object {
- CACCert(CKYByte instance, const CKYBuffer *derCert);
- };
-
-+typedef enum { PK15StateInit, PK15StateNeedObject,
-+ PK15StateNeedRawPublicKey,PK15StateNeedRawCertificate,
-+ PK15StateComplete } PK15State;
-+
-+typedef enum {PK15PvKey, PK15PuKey, PK15Cert, PK15AuthObj} PK15ObjectType;
-+const unsigned int PK15_INVALID_KEY_REF = -1;
-+
-+class PK15Object : public PKCS11Object {
-+ private:
-+ CKYByte instance;
-+ PK15ObjectType p15Type;
-+ PK15State state;
-+ P15PinInfo pinInfo;
-+
-+ CKYStatus completeCertObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeAuthObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeKeyObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completePrivKeyObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completePubKeyObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeRawPublicKey(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeRawCertificate(const CKYByte *buf, CKYSize size);
-+
-+ CKYBitFlags defaultCommonBits() {
-+ return ((p15Type == PK15PvKey) && (CKYBuffer_Size(&authId) != 0)) ?
-+ P15FlagsPrivate : 0;
-+ }
-+ CKYBitFlags defaultUsageBits() {
-+ CKYBitFlags sign, recover, encrypt;
-+ switch (p15Type) {
-+ case PK15PuKey:
-+ sign = P15UsageVerify; recover = P15UsageVerifyRecover;
-+ encrypt = P15UsageEncrypt;
-+ break;
-+ case PK15PvKey:
-+ sign = P15UsageSign; recover = P15UsageSignRecover;
-+ encrypt = P15UsageDecrypt;
-+ break;
-+ default:
-+ sign = 0; recover = 0; encrypt = 0;
-+ break;
-+ }
-+ switch(keyType) {
-+ case rsa:
-+ return sign | recover | encrypt;
-+ case ecc:
-+ return sign | P15UsageDerive;
-+ default:
-+ break;
-+ }
-+ return 0;
-+ }
-+ CKYBitFlags defaultAccessBits() {
-+ switch (p15Type) {
-+ case PK15PuKey:
-+ return P15AccessExtractable | P15AccessLocal;
-+ case PK15PvKey:
-+ return P15AccessSensitive | P15AccessLocal;
-+ default:
-+ break;
-+ }
-+ return 0;
-+ }
-+ CKYBitFlags defaultPinBits() {
-+ return ((p15Type == PK15AuthObj) ? P15PinInitialized : 0);
-+ }
-+
-+ public:
-+ PK15Object(CKYByte inst, PK15ObjectType type,
-+ const CKYByte *derObject, CKYSize size);
-+ CKYStatus completeObject(const CKYByte *data, CKYSize size);
-+ PK15State getState(void) const { return state; }
-+ bool isSO(void) const { return
-+ (pinInfo.pinFlags & P15PinSOPin) ? true : false; }
-+ bool isLocal(void) const { return
-+ (pinInfo.pinFlags & P15PinLocal) ? true : false; }
-+ const P15PinInfo *getPinInfo(void) const { return &pinInfo; }
-+};
-+
- class Reader : public PKCS11Object {
- public:
- Reader(unsigned long muscleObjID, CK_OBJECT_HANDLE handle,
- const char *reader, const CKYBuffer *cardATR, bool isCoolkey);
- };
-
-+class SecretKey : public PKCS11Object {
-+ public:
-+ SecretKey(unsigned long muscleObjID, CK_OBJECT_HANDLE handle, CKYBuffer *secretKeyBuffer, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount);
-+ private:
-+ void adjustToKeyValueLength(CKYBuffer * secretKeyBuffer,CK_ULONG valueLength);
-+
-+};
-+
-+class DEREncodedSignature {
-+
-+ protected :
-+ CKYBuffer derEncodedSignature;
-+ public:
-+ DEREncodedSignature(const CKYBuffer *derSig);
-+ ~DEREncodedSignature();
-+ int getRawSignature(CKYBuffer *rawSig, unsigned int keySize);
-+
-+};
-+
-+class DEREncodedTokenInfo {
-+public:
-+ int version;
-+ CKYBuffer serialNumber;
-+ char *manufacturer;
-+ char *tokenName;
-+ public :
-+ DEREncodedTokenInfo(CKYBuffer *derTokenInfo);
-+ ~DEREncodedTokenInfo() {
-+ CKYBuffer_FreeData(&serialNumber);
-+ free(manufacturer);
-+ free(tokenName);
-+ }
-+};
-+
- class AttributeMatch {
-
- private:
-@@ -175,6 +372,9 @@ makeLEUInt(const CKYBuffer *buf, unsigne
- (b[offset+0] << 0) ;
- }
-
-+const CKYByte* dataStart(const CKYByte *buf, CKYSize length,
-+ CKYSize *data_length, bool includeTag);
-+
- // fixed object ID constants
- #define READER_ID 0x72300000 /* 'r0\0\0' */
- #define COMBINED_ID 0x7a300000 /* 'z0\0\0' */
-diff -up ./src/coolkey/pkcs11t.h.coolkey-update ./src/coolkey/pkcs11t.h
---- ./src/coolkey/pkcs11t.h.coolkey-update 2016-01-19 17:55:02.900107782 -0800
-+++ ./src/coolkey/pkcs11t.h 2016-01-19 17:55:16.040999709 -0800
-@@ -274,6 +274,7 @@ typedef CK_ULONG CK_USER_TYPE;
- #define CKU_SO 0
- /* Normal user */
- #define CKU_USER 1
-+#define CKU_CONTEXT_SPECIFIC 2
-
-
- /* CK_STATE enumerates the session states */
-@@ -492,6 +493,9 @@ typedef CK_ULONG CK_ATTRIBUTE_T
- #define CKA_RESET_ON_INIT 0x00000301
- #define CKA_HAS_RESET 0x00000302
-
-+/* new for v2.20 */
-+#define CKA_ALWAYS_AUTHENTICATE 0x00000202
-+
- #define CKA_VENDOR_DEFINED 0x80000000
-
-
-@@ -1351,4 +1355,41 @@ typedef struct CK_PKCS5_PBKD2_PARAMS {
-
- typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-
-+/* The following EC Key Derivation Functions are defined */
-+
-+#define CKD_NULL 0x00000001
-+
-+#define CKD_SHA1_KDF 0x00000002
-+
-+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11. */
-+
-+ typedef CK_ULONG CK_EC_KDF_TYPE;
-+
-+/*
-+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
-+ *
-+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
-+ *
-+ * where each party contributes one key pair.
-+ *
-+ */
-+
-+typedef struct CK_ECDH1_DERIVE_PARAMS {
-+
-+ CK_EC_KDF_TYPE kdf;
-+
-+ CK_ULONG ulSharedDataLen;
-+
-+ CK_BYTE_PTR pSharedData;
-+
-+ CK_ULONG ulPublicDataLen;
-+
-+ CK_BYTE_PTR pPublicData;
-+
-+} CK_ECDH1_DERIVE_PARAMS;
-+
-+
-+
-+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-+
- #endif
-diff -up ./src/coolkey/slot.cpp.coolkey-update ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-update 2016-01-19 17:55:37.409823970 -0800
-+++ ./src/coolkey/slot.cpp 2016-01-19 17:55:56.591666216 -0800
-@@ -54,6 +54,39 @@ const CKYByte ATR2[] =
- { 0x3B, 0x6F, 0x00, 0xFF, 0x52, 0x53, 0x41, 0x53, 0x65, 0x63, 0x75, 0x72,
- 0x49, 0x44, 0x28, 0x52, 0x29, 0x31, 0x30 };
-
-+/* PKCS #15 AID */
-+const CKYByte P15AID[] =
-+{ 0xa0, 0, 0, 0, 0x63, 'P', 'K', 'C', 'S', '-', '1', '5'};
-+
-+
-+
-+/* ECC curve information
-+ * Provide information for the limited set of curves supported by our smart card(s).
-+ *
-+ */
-+
-+typedef struct curveBytes2Name {
-+ const CKYByte * bytes;
-+ const char *curveName;
-+ unsigned int length;
-+
-+} CurveBytes2Name;
-+
-+/* First byte is length of oid byte array. */
-+
-+const CKYByte nistp256[] = { 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
-+const CKYByte nistp384[] = { 0x5, 0x2b, 0x81, 0x04, 0x00, 0x22 };
-+const CKYByte nistp521[] = { 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23 };
-+
-+const int numECCurves = 3;
-+
-+static CurveBytes2Name curveBytesNamePair[] =
-+{
-+ { nistp256, "nistp256", 256 },
-+ { nistp384, "nistp384", 384 },
-+ { nistp521, "nistp521", 521 }
-+};
-+
- SlotList::SlotList(Log *log_) : log(log_)
- {
- // initialize things to NULL so we can recover from an exception
-@@ -136,7 +169,11 @@ SlotList::updateSlotList()
- throw PKCS11Exception(CKR_HOST_MEMORY);
- memset(newSlots, 0, numReaders*sizeof(Slot*));
-
-- memcpy(newSlots, slots, sizeof(slots[0]) * numSlots);
-+ /* keep coverity happy, even though slot == NULL implies that
-+ * numSlots == 0 */
-+ if (slots) {
-+ memcpy(newSlots, slots, sizeof(slots[0]) * numSlots);
-+ }
-
- for (unsigned int i=numSlots; i < numReaders; i++) {
- newSlots[i] = new
-@@ -237,32 +274,19 @@ SlotList::updateReaderList()
-
- CKYStatus status = CKYCardContext_ListReaders(context, &readerNames);
- if ( status != CKYSUCCESS ) {
-- throw PKCS11Exception(CKR_GENERAL_ERROR,
-+ /* if the service is stopped, treat it as if we have no readers */
-+ if ((CKYCardContext_GetLastError(context) != SCARD_E_NO_SERVICE) &&
-+ (CKYCardContext_GetLastError(context) != SCARD_E_SERVICE_STOPPED)) {
-+ throw PKCS11Exception(CKR_GENERAL_ERROR,
- "Failed to list readers: 0x%x\n",
- CKYCardContext_GetLastError(context));
-+ }
- }
-
-- if (!readerStates) {
-+ if (readerStates == NULL && readerNames != NULL) {
- /* fresh Reader State list, just create it */
- readerStates = CKYReader_CreateArray(readerNames, (CKYSize *)&numReaders);
-
-- /* if we have no readers, make sure we have at least one to keep things
-- * happy */
-- if (readerStates == NULL &&
-- CKYReaderNameList_GetCount(readerNames) == 0) {
-- readerStates = (SCARD_READERSTATE *)
-- malloc(sizeof(SCARD_READERSTATE));
-- if (readerStates) {
-- CKYReader_Init(readerStates);
-- status = CKYReader_SetReaderName(readerStates, "E-Gate 0 0");
-- if (status != CKYSUCCESS) {
-- CKYReader_DestroyArray(readerStates, 1);
-- readerStates = NULL;
-- } else {
-- numReaders = 1;
-- }
-- }
-- }
- CKYReaderNameList_Destroy(readerNames);
-
- if (readerStates == NULL) {
-@@ -272,6 +296,16 @@ SlotList::updateReaderList()
- return;
- }
-
-+ if (readerStates == NULL) {
-+ /* if we didn't have any readers before and we did get new names,
-+ * that is handled above. If we didn't have any readers before, and
-+ * we didn't get any names, there is nothing to update. blow out now.
-+ * This more efficient and makes coverity happy (since coverity doesn't
-+ * know numReaders and readerStates are linked). */
-+ return;
-+ }
-+
-+
- /* it would be tempting at this point just to see if we have more readers
- * then specified previously. The problem with this is it is possible that
- * some readers have been deleted, so the only way to tell if we have
-@@ -286,18 +320,26 @@ SlotList::updateReaderList()
-
- const char *curReaderName = NULL;
- unsigned long knownState = 0;
-- for(int ri = 0 ; ri < numReaders; ri ++) {
-+ for(unsigned int ri = 0 ; ri < numReaders; ri ++) {
- knownState = CKYReader_GetKnownState(&readerStates[ri]);
--
-+
- curReaderName = CKYReader_GetReaderName(&readerStates[ri]);
-- if(readerNameExistsInList(curReaderName,&readerNames)) {
-- CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE);
-+ if(readerNames && readerNameExistsInList(curReaderName,&readerNames)) {
-+ CKYReader_SetKnownState(&readerStates[ri],
-+ knownState & ~SCARD_STATE_IGNORE);
- } else {
-- if (!(knownState & SCARD_STATE_UNAVAILABLE))
-- CKYReader_SetKnownState(&readerStates[ri], knownState | SCARD_STATE_UNAVAILABLE | SCARD_STATE_CHANGED);
-- }
-+ if (!(knownState & SCARD_STATE_UNAVAILABLE))
-+ CKYReader_SetKnownState(&readerStates[ri],
-+ knownState | SCARD_STATE_UNAVAILABLE | SCARD_STATE_CHANGED);
-+ }
- }
-
-+ if (readerNames == NULL) {
-+ /* OK we've marked everything unavailable, we clearly
-+ * aren't adding any readers, so we can blow out here */
-+ return;
-+ }
-+
- const char *newReadersData[MAX_READER_DELTA];
- const char **newReaders = &newReadersData[0];
- unsigned int newReaderCount = 0;
-@@ -368,18 +410,29 @@ SlotList::updateReaderList()
-
- Slot::Slot(const char *readerName_, Log *log_, CKYCardContext* context_)
- : log(log_), readerName(NULL), personName(NULL), manufacturer(NULL),
-+ tokenManufacturer(NULL),
- slotInfoFound(false), context(context_), conn(NULL), state(UNKNOWN),
- isVersion1Key(false), needLogin(false), fullTokenName(false),
-- mCoolkey(false), mOldCAC(false),
-+ mCoolkey(false), mOldCAC(false), mCACLocalLogin(false),
-+ pivContainer(-1), pivKey(-1), mECC(false), p15aid(0), p15odfAddr(0),
-+ p15tokenInfoAddr(0), p15Instance(0),
- #ifdef USE_SHMEM
- shmem(readerName_),
- #endif
- sessionHandleCounter(1), objectHandleCounter(1)
- {
-+ int i;
-+
-+ for (i=0; i < MAX_AUTH_USERS; i++) {
-+ auth[i]=NULL;
-+ }
-
- tokenFWVersion.major = 0;
- tokenFWVersion.minor = 0;
--
-+ CKYBuffer_InitFromData(&p15AID, P15AID, sizeof(P15AID));
-+ CKYBuffer_InitEmpty(&p15tokenInfo);
-+ CKYBuffer_InitEmpty(&p15odf);
-+ CKYBuffer_InitEmpty(&p15serialNumber);
-
- try {
- conn = CKYCardConnection_Create(context);
-@@ -395,6 +448,8 @@ Slot::Slot(const char *readerName_, Log
- loggedIn = false;
- pinCache.invalidate();
- pinCache.clearPin();
-+ contextPinCache.invalidate();
-+ contextPinCache.clearPin();
- //readSlotInfo();
- manufacturer = strdup("Unknown");
- if (!manufacturer) {
-@@ -477,12 +532,23 @@ Slot::~Slot()
- if (manufacturer) {
- free(manufacturer);
- }
-+ if (tokenManufacturer) {
-+ free(tokenManufacturer);
-+ }
- CKYBuffer_FreeData(&nonce);
- CKYBuffer_FreeData(&cardATR);
- CKYBuffer_FreeData(&mCUID);
-+ CKYBuffer_FreeData(&p15AID);
-+ CKYBuffer_FreeData(&p15odf);
-+ CKYBuffer_FreeData(&p15tokenInfo);
-+ CKYBuffer_FreeData(&p15serialNumber);
- for (int i=0; i < MAX_CERT_SLOTS; i++) {
- CKYBuffer_FreeData(&cardAID[i]);
- }
-+ for (int i=0; i < MAX_AUTH_USERS; i++) {
-+ if (auth[i]) delete auth[i];
-+ auth[i]=NULL;
-+ }
- }
-
- template <class C>
-@@ -573,6 +639,36 @@ SlotList::getSlotList(CK_BBOOL tokenPres
- return rv;
- }
-
-+bool
-+Slot::getPIVLoginType(void)
-+{
-+ CKYStatus status;
-+ CKYISOStatus apduRC;
-+ CKYBuffer buffer;
-+ bool local = true;
-+
-+ CKYBuffer_InitEmpty(&buffer);
-+
-+ /* get the discovery object */
-+ status = PIVApplet_GetCertificate(conn, &buffer, 0x7e, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ /* Discovery object optional, PIV defaults to local */
-+ goto done;
-+ }
-+ /* techically we probably should parse out the TLVs, but the PIV
-+ * specifies exactly what they should be, so we know exactly which
-+ * byte to look at */
-+ if ((CKYBuffer_Size(&buffer) >= 20) &&
-+ (CKYBuffer_GetChar(&buffer,17) == 0x60)) {
-+ /* This tells us we should use global login for this piv card */
-+ local = false;
-+ }
-+done:
-+ CKYBuffer_FreeData(&buffer);
-+ return local;
-+}
-+
-+
- void
- Slot::connectToToken()
- {
-@@ -587,6 +683,7 @@ Slot::connectToToken()
- if( ! CKYCardConnection_IsConnected(conn) ) {
- int i = 0;
- //for cranky readers try again a few more times
-+ status = CKYSCARDERR;
- while( i++ < 5 && status != CKYSUCCESS )
- {
- status = CKYCardConnection_Connect(conn, readerName);
-@@ -672,12 +769,40 @@ Slot::connectToToken()
- // see if the applet is selectable
-
- log->log("time connnect: Begin transaction %d ms\n", OSTimeNow() - time);
-+ status = PIVApplet_Select(conn, NULL);
-+ if (status == CKYSUCCESS) {
-+ /* CARD is a PIV card */
-+ state |= PIV_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
-+ isVersion1Key = 0;
-+ needLogin = true;
-+ mCoolkey = 0;
-+ mOldCAC = 0;
-+ mCACLocalLogin = getPIVLoginType();
-+ return;
-+ }
- status = CKYApplet_SelectCoolKeyManager(conn, NULL);
- if (status != CKYSUCCESS) {
- log->log("CoolKey Select failed 0x%x\n", status);
- status = getCACAid();
- if (status != CKYSUCCESS) {
-- goto loser;
-+ log->log("CAC Select failed 0x%x\n", status);
-+ status = getP15Params();
-+ if (status != CKYSUCCESS) {
-+ if (status == CKYSCARDERR) {
-+ log->log("Card Failure 0x%x\n",
-+ CKYCardConnection_GetLastError(conn));
-+ disconnect();
-+ }
-+ /* CARD is unknown */
-+ return;
-+ }
-+ /* enable PCKS 15 */
-+ state |= P15_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
-+ isVersion1Key = 0;
-+ needLogin = false; /* get it from token info */
-+ mCoolkey = 0;
-+ mCACLocalLogin = false;
-+ return;
- }
- state |= CAC_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
- /* skip the read of the cuid. We really don't need it and,
-@@ -685,17 +810,9 @@ Slot::connectToToken()
- * other apps may be running now, so resetting the cac is a bit
- * unfriendly */
- isVersion1Key = 0;
-- needLogin = 1;
-+ needLogin = true;
- mCoolkey = 0;
-- return;
--
--loser:
-- log->log("CAC Select failed 0x%x\n", status);
-- if (status == CKYSCARDERR) {
-- log->log("CAC Card Failure 0x%x\n",
-- CKYCardConnection_GetLastError(conn));
-- disconnect();
-- }
-+ mCACLocalLogin = false;
- return;
- }
- mCoolkey = 1;
-@@ -762,8 +879,10 @@ Slot::invalidateLogin(bool hard)
- }
- } else {
- loggedIn = false;
-+ pinCache.invalidate();
-+ contextPinCache.invalidate();
-+ contextPinCache.clearPin();
- if (hard) {
-- pinCache.invalidate();
- pinCache.clearPin();
- }
- }
-@@ -873,6 +992,414 @@ done:
- return status;
- }
-
-+CKYStatus Slot::getP15Params()
-+{
-+ CKYStatus status = CKYSCARDERR;
-+ int i;
-+ CKYISOStatus apduRC;
-+
-+ /* read the EF(DIR) */
-+ status = CACApplet_SelectFile(conn, 0x2f00, &apduRC);
-+ if (status == CKYSUCCESS) {
-+ CKYBuffer record;
-+
-+ CKYBuffer_InitEmpty(&record);
-+ /* dump it out */
-+ for (i=1; i < 255; i++) {
-+ status = P15Applet_ReadRecord(conn, i, 0, P15_READ_P1, 255,
-+ &record, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(DIR) Read Record %d failed 0x%x apduRC=0x%x\n",
-+ i, status, apduRC);
-+ break;
-+ }
-+ }
-+ CKYBuffer_FreeData(&record);
-+ return CKYSCARDERR; /* don't yet support EF(DIR)*/
-+
-+ } else {
-+ log->log("EF(DIR) Select failed 0x%x apduRC=0x%0x\n", status, apduRC);
-+ p15aid = 0; /* use the default */
-+ p15odfAddr=0x5031;
-+ p15tokenInfoAddr=0x5032;
-+ }
-+
-+ status = CKYApplet_SelectFile(conn, &p15AID, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("DF(PKCS-15) select failed 0x%x apduRC=0x%0x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+ status = P15Applet_SelectFile(conn, p15tokenInfoAddr, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(TokenInfo) select failed 0x%x apduRC=0x%0x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+ /* dump it out */
-+ CKYBuffer_Resize(&p15tokenInfo, 0);
-+ status = P15Applet_ReadBinary(conn, 0, 0, 0, 0, &p15tokenInfo, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(TokenInfo) Read binary failed 0x%x apduRC=0x%x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+ status = P15Applet_SelectFile(conn, p15odfAddr, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(ODF) select failed 0x%x apduRC=0x%0x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+
-+ CKYBuffer_Resize(&p15odf, 0);
-+ status = P15Applet_ReadBinary(conn, 0, 0, 0, 0, &p15odf, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(ODF) Read binary failed 0x%x apduRC=0x%x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+Slot::readFromPath(const PK15ObjectPath &obj, CKYBuffer *file)
-+{
-+ CKYStatus status;
-+ CKYISOStatus apduRC;
-+ CKYSize bufSize;
-+ CKYOffset index = obj.getIndex();
-+ CKYSize length = obj.getLength();
-+
-+ CKYBuffer_Resize(file, 0);
-+ status = selectPath(obj.getPath(), &apduRC);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+ status = P15Applet_ReadBinary(conn, index, 0, 0,
-+ (length >= 256)?0:length, file, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+
-+ /* if we asked for a specific length and got it, or we asked for
-+ * an indeterminate length and got less than 256 bytes, then we
-+ * got everything. */
-+ bufSize = CKYBuffer_Size(file);
-+ if ((length && (bufSize >= length)) || ((length == 0) && (bufSize < 256))) {
-+ /* we've already got it all */
-+ return status;
-+ }
-+ if (bufSize < 0x82) {
-+ /* make sure we have enough bytes to handle the worst case ANS.1
-+ * mistake */
-+ return CKYINVALIDDATA;
-+ }
-+
-+ if (length == 0) {
-+ /* we don't yet know how long the length is, use the ASN.1 parser to
-+ * find out. We lie to dataStart about actual size so that it won't
-+ * fail since we know we don't have the whole buffer yet.*/
-+ (void) dataStart(CKYBuffer_Data(file), 65535, &length, true);
-+ }
-+ if (length > 65535) {
-+ return CKYINVALIDDATA;
-+ }
-+ while ((bufSize =CKYBuffer_Size(file)) < length) {
-+ CKYSize tmpLength = length - bufSize;
-+
-+ if (tmpLength >= 256) tmpLength = 0;
-+
-+ status = P15Applet_ReadBinary(conn, (unsigned short)(index+bufSize),
-+ 0, 0, tmpLength, file, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+ }
-+
-+ return CKYSUCCESS;
-+}
-+
-+void
-+Slot::parseEF_TokenInfo(void)
-+{
-+ DEREncodedTokenInfo derTokenInfo(&p15tokenInfo);
-+ const CKYBuffer *serial=&derTokenInfo.serialNumber;
-+
-+ if (derTokenInfo.version >= 0) {
-+ tokenFWVersion.major = derTokenInfo.version;
-+ tokenFWVersion.minor = 0;
-+ }
-+
-+ if (CKYSize(serial) != 0) {
-+ CKYBuffer_Replace(&p15serialNumber, 0, CKYBuffer_Data(serial),
-+ CKYBuffer_Size(serial));
-+ }
-+
-+ if (derTokenInfo.manufacturer) {
-+ if (tokenManufacturer) {
-+ free(tokenManufacturer);
-+ tokenManufacturer = NULL;
-+ }
-+ tokenManufacturer = derTokenInfo.manufacturer;
-+ derTokenInfo.manufacturer = NULL; /* adopted */
-+ }
-+
-+ if (derTokenInfo.tokenName) {
-+ if (personName) {
-+ free(personName);
-+ personName = NULL;
-+ }
-+ personName = derTokenInfo.tokenName;
-+ derTokenInfo.tokenName = NULL; /* adopted */
-+ fullTokenName = true;
-+ }
-+ return;
-+}
-+
-+void
-+Slot::parseEF_ODF(void)
-+{
-+ const CKYByte *current = CKYBuffer_Data(&p15odf);
-+ CKYSize size = CKYBuffer_Size(&p15odf);
-+ CKYBuffer files;
-+
-+ CKYBuffer_InitEmpty(&files);
-+
-+ while (size > 0) {
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYByte type, type1;
-+ PK15ObjectPath objPath;
-+ bool skip;
-+
-+ type = current[0];
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { break; }
-+ tagSize = entry-current;
-+ current += entrySize + tagSize;
-+ size -= (entrySize + tagSize);
-+
-+ /* skip those entries we aren't going to parse */
-+ skip = false;
-+ switch (type) {
-+ case 0xa2: skip=true; break; /* skip EF(PuKDF-trusted) */
-+ case 0xa3: skip=true; break; /* skip EF(SKDF) */
-+ case 0xa7: skip=true; break; /* skip EF(DODF) */
-+ default: skip=true; break;
-+ case 0xa0: /* EF(PvKDF) */
-+ case 0xa1: /* EF(PuKDF) */
-+ case 0xa4: /* EF(CDF) */
-+ case 0xa5: /* EF(CDF-trusted) */
-+ case 0xa6: /* EF(CDF-useful) */
-+ case 0xa8: break; /* EF(AODF) */
-+ }
-+ if (skip) continue;
-+
-+ type1 = entry[0];
-+ /* unwrap */
-+ entry = dataStart(entry, entrySize, &entrySize, false);
-+ if (entry == NULL) continue;
-+ if (type1 == ASN1_SEQUENCE) {
-+ objPath.setObjectPath(entry, entrySize);
-+ CKYBuffer_Resize(&files, 0);
-+ readFromPath(objPath, &files);
-+ entry = CKYBuffer_Data(&files);
-+ entrySize = CKYBuffer_Size(&files);
-+ } else if (type1 != ASN1_CHOICE_0) {
-+ continue;
-+ }
-+
-+ switch (type) {
-+ case 0xa0: parseEF_Directory(entry, entrySize, PK15PvKey); break;
-+ case 0xa1: parseEF_Directory(entry, entrySize, PK15PuKey); break;
-+ case 0xa4: parseEF_Directory(entry, entrySize, PK15Cert); break;
-+ case 0xa5: parseEF_Directory(entry, entrySize, PK15Cert); break;
-+ case 0xa6: parseEF_Directory(entry, entrySize, PK15Cert); break;
-+ case 0xa8: parseEF_Directory(entry, entrySize, PK15AuthObj); break;
-+ default: break;
-+ }
-+ }
-+ CKYBuffer_FreeData(&files);
-+ return;
-+}
-+
-+
-+class ObjectCertCKAIDMatch {
-+ private:
-+ const CKYBuffer *cka_id;
-+ public:
-+ ObjectCertCKAIDMatch(const CKYBuffer *cka_id_) : cka_id(cka_id_) {}
-+ bool operator()(const PKCS11Object& obj) {
-+ const CKYBuffer *id;
-+ const CKYBuffer *objClass;
-+ CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
-+ objClass = obj.getAttribute(CKA_CLASS);
-+ if (objClass == NULL || !CKYBuffer_DataIsEqual(objClass,
-+ (CKYByte *)&certClass, sizeof(certClass))) {
-+ return false;
-+ }
-+ id = obj.getAttribute(CKA_ID);
-+ return (id != NULL && CKYBuffer_IsEqual(id,cka_id)) ? true : false;
-+ }
-+};
-+
-+class ObjectKeyCKAIDMatch {
-+ private:
-+ const CKYBuffer *cka_id;
-+ public:
-+ ObjectKeyCKAIDMatch(const CKYBuffer *cka_id_) : cka_id(cka_id_) {}
-+ bool operator()(const PKCS11Object& obj) {
-+ const CKYBuffer *id;
-+ const CKYBuffer *objClass;
-+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
-+ objClass = obj.getAttribute(CKA_CLASS);
-+ if (objClass == NULL || !CKYBuffer_DataIsEqual(objClass,
-+ (CKYByte *)&keyClass, sizeof(keyClass))) {
-+ return false;
-+ }
-+ id = obj.getAttribute(CKA_ID);
-+ return (id != NULL && CKYBuffer_IsEqual(id,cka_id)) ? true : false;
-+ }
-+};
-+
-+CKYStatus
-+Slot::parseEF_Directory(const CKYByte *current,
-+ CKYSize size, PK15ObjectType type)
-+{
-+ CKYBuffer file;
-+ CKYBuffer_InitEmpty(&file);
-+ CKYStatus status;
-+
-+
-+ while (size > 0) {
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+
-+ if (current[0] != ASN1_SEQUENCE) {
-+ /* no more */
-+ break;
-+ }
-+
-+ entry = dataStart(current, size, &entrySize, true);
-+ if (entry == NULL) { break; }
-+ current += entrySize;
-+ size -= entrySize;
-+
-+ do {
-+ PK15Object obj(PK15Instance(), type, entry, entrySize);
-+
-+ /* if state failed, then there is something wrong with this
-+ * der, skip this object */
-+ if (obj.getState() == PK15StateInit) {
-+ break;
-+ }
-+ status = CKYSUCCESS;
-+ while (obj.getState() != PK15StateComplete) {
-+ CKYBuffer_Resize(&file, 0);
-+ readFromPath(obj.getObjectPath(), &file);
-+ status = obj.completeObject(CKYBuffer_Data(&file),
-+ CKYBuffer_Size(&file));
-+ if (status != CKYSUCCESS) {
-+ break;
-+ }
-+ }
-+ if (status != CKYSUCCESS) {
-+ break;
-+ }
-+ assert(obj.getState() == PK15StateComplete);
-+ /* handle type specific per object fixups */
-+ switch (type) {
-+ case PK15AuthObj:
-+ /* if we're an auth object, squirrel us away for future use */
-+ if (obj.isSO()) {
-+ if (auth[CKU_SO] != 0) {
-+ auth[CKU_SO] = new PK15Object(obj);
-+ }
-+ } else if (auth[CKU_USER] == NULL) {
-+ auth[CKU_USER] = new PK15Object(obj);
-+ } else if (auth[CKU_CONTEXT_SPECIFIC] == NULL) {
-+ ObjectIter iter;
-+ const CKYBuffer *authid = obj.getPinAuthId();
-+
-+ /* these should put on the individual keys */
-+ auth[CKU_CONTEXT_SPECIFIC] = new PK15Object(obj);
-+
-+ for( iter = tokenObjects.begin();
-+ iter != tokenObjects.end(); ++iter) {
-+ if( CKYBuffer_IsEqual(iter->getAuthId(),authid)) {
-+ iter->setAttributeBool(CKA_ALWAYS_AUTHENTICATE,
-+ TRUE);
-+ }
-+ }
-+ }
-+ /* drop unkown */
-+ break;
-+ case PK15PvKey:
-+ /* does the cert already exist? */
-+ {
-+ ObjectConstIter iter;
-+ const CKYBuffer *id;
-+
-+ id = obj.getAttribute(CKA_ID);
-+ if ((!id) || (CKYBuffer_Size(id) != 1)) {
-+ break;
-+ }
-+ iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-+ ObjectCertCKAIDMatch(id));
-+
-+ if ( iter != tokenObjects.end() ) {
-+ obj.completeKey(*iter);
-+ }
-+ }
-+ break;
-+ case PK15Cert:
-+ /* does a corresponding key already exist? */
-+ {
-+ ObjectIter iter;
-+ const CKYBuffer *id;
-+
-+ id = obj.getAttribute(CKA_ID);
-+ if ((!id) || (CKYBuffer_Size(id) != 1)) {
-+ break;
-+ }
-+ iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-+ ObjectKeyCKAIDMatch(id));
-+
-+ if ( iter != tokenObjects.end() ) {
-+ iter->completeKey(obj);
-+ }
-+ }
-+ break;
-+ case PK15PuKey:
-+ break;
-+ }
-+ tokenObjects.push_back(obj);
-+ } while ( false );
-+ }
-+ CKYBuffer_FreeData(&file);
-+ return CKYSUCCESS;
-+}
-+
-+
-+CKYStatus
-+Slot::selectPath(const CKYBuffer *path, CKYISOStatus *apduRC)
-+{
-+ CKYSize size = CKYBuffer_Size(path);
-+ CKYStatus status = CKYINVALIDARGS;
-+ CKYOffset pos;
-+
-+ for (pos=0; pos < size; pos +=2) {
-+ unsigned short ef = CKYBuffer_GetShort(path, pos);
-+ status = P15Applet_SelectFile(conn, ef, apduRC);
-+ if (status != CKYSUCCESS) {
-+ break;
-+ }
-+ }
-+ return status;
-+}
-+
- void
- Slot::refreshTokenState()
- {
-@@ -1054,8 +1581,20 @@ void
- Slot::makeSerialString(char *serialNumber, int maxSize,
- const unsigned char *cuid)
- {
-+ CKYSize ssize = CKYBuffer_Size(&p15serialNumber);
- memset(serialNumber, ' ', maxSize);
-
-+ if (ssize != 0) {
-+ CKYSize i;
-+ ssize = MIN((CKYSize)maxSize/2, ssize);
-+ for (i=0; i < ssize; i++) {
-+ CKYByte c = CKYBuffer_GetChar(&p15serialNumber, i);
-+ serialNumber[2*i] = hex((c >> 4) & 0xf);
-+ serialNumber[2*i+1] = hex(c & 0xf);
-+ }
-+ }
-+
-+
- // otherwise we use the eepromSerialNumber as a hex value
- if (cuid) {
- makeCUIDString(serialNumber, maxSize, cuid);
-@@ -1126,7 +1665,8 @@ struct _manList {
- static const struct _manList manList[] = {
- { 0x4090, "Axalto" },
- { 0x2050, "Oberthur" },
-- { 0x4780, "RSA" }
-+ { 0x4780, "RSA" },
-+ { 0x534e, "SafeNet" }
- };
-
- static int manListSize = sizeof(manList)/sizeof(manList[0]);
-@@ -1135,8 +1675,15 @@ void
- Slot::makeManufacturerString(char *man, int maxSize, const unsigned char *cuid)
- {
- char *cp = man;
-+ int manLen;
- memset(man, ' ', maxSize);
-
-+ if (tokenManufacturer) {
-+ manLen = strlen(tokenManufacturer);
-+ memcpy(man, tokenManufacturer, MIN(manLen, maxSize));
-+ // UTF8 Truncate fixup! don't drop halfway through a UTF8 character
-+ return;
-+ }
- if (!cuid) {
- return;
- }
-@@ -1202,6 +1749,7 @@ Slot::getTokenInfo(CK_TOKEN_INFO_PTR pTo
-
-
- return CKR_OK;
-+
- }
-
- void
-@@ -1222,7 +1770,16 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- bool found = FALSE;
- CKYStatus status;
- SCARD_READERSTATE *myReaderStates = NULL;
-+ static SCARD_READERSTATE pnp = { 0 };
- unsigned int myNumReaders = 0;
-+
-+ readerListLock.getLock();
-+ if (pnp.szReader == 0) {
-+ CKYReader_Init(&pnp);
-+ pnp.szReader = "\\\\?PnP?\\Notification";
-+ }
-+ readerListLock.releaseLock();
-+
- #ifndef notdef
- do {
- readerListLock.getLock();
-@@ -1241,11 +1798,13 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- * from that set to return
- */
- for (i=0; i < numReaders; i++) {
-- unsigned long knownState = CKYReader_GetKnownState(&readerStates[i]);
-+ unsigned long knownState =
-+ CKYReader_GetKnownState(&readerStates[i]);
-
- if ((knownState & SCARD_STATE_UNAVAILABLE) &&
- (knownState & SCARD_STATE_CHANGED)) {
-- CKYReader_SetKnownState(&readerStates[i], knownState & ~SCARD_STATE_CHANGED);
-+ CKYReader_SetKnownState(&readerStates[i],
-+ knownState & ~SCARD_STATE_CHANGED);
- readerListLock.releaseLock();
- *slotp = slotIndexToID(i);
- found = TRUE;
-@@ -1262,31 +1821,48 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- break;
- }
-
-- if (myNumReaders != numReaders) {
-+ if (myNumReaders != numReaders + 1) {
- if (myReaderStates) {
- delete [] myReaderStates;
- }
-- myReaderStates = new SCARD_READERSTATE [numReaders];
-+ myReaderStates = new SCARD_READERSTATE [numReaders + 1];
-+ myNumReaders = numReaders + 1;
- }
-- memcpy(myReaderStates, readerStates,
-- sizeof(SCARD_READERSTATE)*numReaders);
-- myNumReaders = numReaders;
-+
-+ memcpy(myReaderStates, readerStates,
-+ sizeof(SCARD_READERSTATE) * numReaders);
-+ memcpy(&myReaderStates[numReaders], &pnp, sizeof(pnp));
- readerListLock.releaseLock();
- status = CKYCardContext_WaitForStatusChange(context,
-- myReaderStates, myNumReaders, timeout);
-+ myReaderStates, myNumReaders, timeout);
- if (status == CKYSUCCESS) {
-- for (i=0; i < myNumReaders; i++) {
-- SCARD_READERSTATE *rsp = &myReaderStates[i];
-- unsigned long eventState = CKYReader_GetEventState(rsp);
-+ unsigned long eventState;
-+ for (i=0; i < myNumReaders - 1; i++) {
-+ eventState = CKYReader_GetEventState(&myReaderStates[i]);
- if (eventState & SCARD_STATE_CHANGED) {
- readerListLock.getLock();
-- CKYReader_SetKnownState(&readerStates[i], eventState & ~SCARD_STATE_CHANGED);
-+ CKYReader_SetKnownState(&readerStates[i],
-+ eventState & ~SCARD_STATE_CHANGED);
- readerListLock.releaseLock();
- *slotp = slotIndexToID(i);
- found = TRUE;
- break;
- }
- }
-+ /* No real need to check for an additional card, we already update
-+ * the list when we iterate. */
-+ if (!found) {
-+ eventState = CKYReader_GetEventState(
-+ &myReaderStates[myNumReaders-1]);
-+ if (eventState & SCARD_STATE_CHANGED) {
-+ readerListLock.getLock();
-+ CKYReader_SetKnownState(&pnp,
-+ eventState & ~SCARD_STATE_CHANGED);
-+ readerListLock.releaseLock();
-+ log->log("Reader insertion/removal detected\n");
-+ continue; /* get the update */
-+ }
-+ }
- }
-
- if (found || (flag == CKF_DONT_BLOCK) || shuttingDown) {
-@@ -1294,21 +1870,21 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- }
-
- #ifndef WIN32
-- if (status != CKYSUCCESS) {
--
-- if ( (CKYCardContext_GetLastError(context) ==
-- SCARD_E_READER_UNAVAILABLE) ||
-- (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT))
-- {
-- OSSleep(timeout*PKCS11_CARD_ERROR_LATENCY);
-- }
--
--
-- }
-+ /* pcsc-lite needs to make progress or something */
-+ if (status != CKYSUCCESS) {
-+ if ((CKYCardContext_GetLastError(context) ==
-+ SCARD_E_READER_UNAVAILABLE) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT)) {
-+ OSSleep(timeout*PKCS11_CARD_ERROR_LATENCY);
-+ }
-+ }
- #endif
- } while ((status == CKYSUCCESS) ||
- (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT) ||
-- ( CKYCardContext_GetLastError(context) == SCARD_E_READER_UNAVAILABLE));
-+ (CKYCardContext_GetLastError(context) == SCARD_E_UNKNOWN_READER) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_READER_UNAVAILABLE) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_NO_SERVICE) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_SERVICE_STOPPED) );
- #else
- do {
- OSSleep(100);
-@@ -1345,6 +1921,7 @@ Slot::handleConnectionError()
- case SCARD_W_REMOVED_CARD:
- ckrv = CKR_DEVICE_REMOVED;
- break;
-+
- default:
- ckrv = CKR_DEVICE_ERROR;
- break;
-@@ -1404,13 +1981,46 @@ Slot::selectApplet()
- }
-
- void
--Slot::selectCACApplet(CKYByte instance)
-+Slot::selectCACApplet(CKYByte instance, bool doDisconnect)
- {
- CKYStatus status;
-+ /* PIV containers and keys by instance */
-+ static const int container[] = {
-+ 0x5fc105, 0x5fc10a, 0x5fc10b, 0x5fc101,
-+ 0x5fc10d, 0x5fc10e, 0x5fc10f, 0x5fc110,
-+ 0x5fc111, 0x5fc112, 0x5fc113, 0x5fc114,
-+ 0x5fc115, 0x5fc116, 0x5fc117, 0x5fc118,
-+ 0x5fc119, 0x5fc11a, 0x5fc11b, 0x5fc11c,
-+ 0x5fc11d, 0x5fc11e, 0x5fc11f, 0x5fc120
-+ };
-+ static const int keyRef[] = {
-+ 0x9a, 0x9c, 0x9d, 0x9e,
-+ 0x82, 0x83, 0x84, 0x85,
-+ 0x86, 0x87, 0x88, 0x89,
-+ 0x8a, 0x8b, 0x8c, 0x8d,
-+ 0x8e, 0x8f, 0x90, 0x91,
-+ 0x92, 0x93, 0x94, 0x95
-+ };
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_Select(conn, NULL);
-+ if (status == CKYSCARDERR) handleConnectionError();
-+ if (status != CKYSUCCESS) {
-+ if (doDisconnect) {
-+ disconnect();
-+ }
-+ throw PKCS11Exception(CKR_DEVICE_REMOVED);
-+ }
-+ pivContainer = container[instance];
-+ pivKey = keyRef[instance];
-+ return;
-+ }
- CKYBuffer *aid = &cardAID[instance];
-
- if (CKYBuffer_Size(aid) == 0) {
-- disconnect();
-+ if (doDisconnect) {
-+ disconnect();
-+ }
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- return;
- }
-@@ -1419,7 +2029,9 @@ Slot::selectCACApplet(CKYByte instance)
- if ( status == CKYSCARDERR ) handleConnectionError();
- if ( status != CKYSUCCESS) {
- // could not select applet: this just means it's not there
-- disconnect();
-+ if (doDisconnect) {
-+ disconnect();
-+ }
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- }
- if (mOldCAC) {
-@@ -1428,7 +2040,9 @@ Slot::selectCACApplet(CKYByte instance)
- status = CACApplet_SelectFile(conn, cardEF[instance], NULL);
- if ( status == CKYSCARDERR ) handleConnectionError();
- if ( status != CKYSUCCESS) {
-- disconnect();
-+ if (doDisconnect) {
-+ disconnect();
-+ }
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- }
- }
-@@ -1488,26 +2102,6 @@ class KeyNumMatch {
- }
- };
-
--class ObjectCertCKAIDMatch {
-- private:
-- CKYByte cka_id;
-- public:
-- ObjectCertCKAIDMatch(CKYByte cka_id_) : cka_id(cka_id_) {}
-- bool operator()(const PKCS11Object& obj) {
-- const CKYBuffer *id;
-- const CKYBuffer *objClass;
-- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
-- objClass = obj.getAttribute(CKA_CLASS);
-- if (objClass == NULL || !CKYBuffer_DataIsEqual(objClass,
-- (CKYByte *)&certClass, sizeof(certClass))) {
-- return false;
-- }
-- id = obj.getAttribute(CKA_ID);
-- return (id != NULL && CKYBuffer_DataIsEqual(id,&cka_id, 1))
-- ? true : false;
-- }
--};
--
- CK_OBJECT_HANDLE
- Slot::generateUnusedObjectHandle()
- {
-@@ -1521,6 +2115,29 @@ Slot::generateUnusedObjectHandle()
- return handle;
- }
-
-+/* Create a short lived Secret Key for ECC key derive. */
-+PKCS11Object *
-+Slot::createSecretKeyObject(CK_OBJECT_HANDLE handle, CKYBuffer *secretKeyBuffer, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
-+{
-+
-+ if (secretKeyBuffer == NULL ) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Can't create secret key object for ECC.");
-+ }
-+
-+ unsigned long muscleID = 0xfff;
-+ PKCS11Object *secret = new SecretKey(muscleID, handle, secretKeyBuffer, pTemplate, ulAttributeCount);
-+
-+ if (secret == NULL) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Can't create secret key object for ECC.");
-+ }
-+
-+ tokenObjects.push_back(*secret);
-+
-+ return secret;
-+}
-+
- void
- Slot::addKeyObject(list<PKCS11Object>& objectList, const ListObjectInfo& info,
- CK_OBJECT_HANDLE handle, bool isCombined)
-@@ -1530,24 +2147,32 @@ Slot::addKeyObject(list<PKCS11Object>& o
- CK_OBJECT_CLASS objClass = keyObj.getClass();
- const CKYBuffer *id;
-
--
- if (isCombined &&
-- ((objClass == CKO_PUBLIC_KEY) || (objClass == CKO_PRIVATE_KEY))) {
-- id = keyObj.getAttribute(CKA_ID);
-- if ((!id) || (CKYBuffer_Size(id) != 1)) {
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Missing or invalid CKA_ID value");
-- }
-- iter = find_if(objectList.begin(), objectList.end(),
-- ObjectCertCKAIDMatch(CKYBuffer_GetChar(id,0)));
-- if ( iter == objectList.end() ) {
-+ ((objClass == CKO_PUBLIC_KEY) || (objClass == CKO_PRIVATE_KEY))) {
-+ id = keyObj.getAttribute(CKA_ID);
-+ if ((!id) || (CKYBuffer_Size(id) != 1)) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Missing or invalid CKA_ID value");
-+ }
-+ iter = find_if(objectList.begin(), objectList.end(),
-+ ObjectCertCKAIDMatch(id));
-+ if ( iter == objectList.end() ) {
- // We failed to find a cert with a matching CKA_ID. This
- // can happen if the cert is not present on the token, or
- // the der encoded cert stored on the token was corrupted.
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Failed to find cert with matching CKA_ID value");
-- }
-- keyObj.completeKey(*iter);
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Failed to find cert with matching CKA_ID value");
-+ }
-+ keyObj.completeKey(*iter);
-+
-+ /* For now this is how we determine what type of key.
-+ Also for now, allow only one or the other */
-+ if ( keyObj.getKeyType() == PKCS11Object::ecc) {
-+ mECC = true;
-+ } else {
-+ mECC = false;
-+ }
-+
- }
- objectList.push_back(keyObj);
-
-@@ -1577,10 +2202,16 @@ Slot::addCertObject(list<PKCS11Object>&
- void
- Slot::unloadObjects()
- {
-+ mECC = false;
- tokenObjects.clear();
- free(personName);
- personName = NULL;
- fullTokenName = false;
-+ if (tokenManufacturer) {
-+ free(tokenManufacturer);
-+ tokenManufacturer = NULL;
-+ }
-+ CKYBuffer_Resize(&p15serialNumber,0);
- }
-
- #ifdef USE_SHMEM
-@@ -1970,7 +2601,7 @@ Slot::readCUID(void)
- // shared memory is protected by our transaction call on the card
- //
- CKYStatus status;
-- if (state & CAC_CARD) {
-+ if (state & GOV_CARD) {
- status = CACApplet_SelectCardManager(conn, NULL);
- } else {
- status = CKYApplet_SelectCardManager(conn, NULL);
-@@ -2203,6 +2834,50 @@ Slot::fetchCombinedObjects(const CKYBuff
- return objInfoList;
- }
-
-+typedef enum {
-+ BER_UNWRAP,
-+ BER_NEXT
-+} BERop;
-+
-+static CKYStatus
-+berProcess(CKYBuffer *buf, int matchTag, CKYBuffer *target, BERop type)
-+{
-+ unsigned char tag;
-+ unsigned int used_length= 0;
-+ unsigned int data_length;
-+
-+ tag = CKYBuffer_GetChar(buf,used_length++);
-+
-+ /* blow out when we come to the end */
-+ if (matchTag && tag != matchTag) {
-+ return CKYLIBFAIL;
-+ }
-+
-+ data_length = CKYBuffer_GetChar(buf,used_length++);
-+
-+ if (data_length & 0x80) {
-+ int len_count = data_length & 0x7f;
-+
-+ data_length = 0;
-+
-+ while (len_count-- > 0) {
-+ data_length = (data_length << 8) |
-+ CKYBuffer_GetChar(buf,used_length++);
-+ }
-+ }
-+
-+ if (data_length > (CKYBuffer_Size(buf)-used_length) ) {
-+ return CKYLIBFAIL;
-+ }
-+
-+ if (type == BER_UNWRAP) {
-+ return CKYBuffer_AppendBuffer(target, buf, used_length, data_length);
-+ }
-+ return CKYBuffer_AppendBuffer(target, buf, used_length+data_length,
-+ CKYBuffer_Size(buf)-(used_length+data_length));
-+}
-+
-+
- CKYStatus
- Slot::readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
- bool throwException)
-@@ -2211,16 +2886,60 @@ Slot::readCACCertificateFirst(CKYBuffer
- CKYISOStatus apduRC;
- *nextSize = 0;
-
-+ if (state & PIV_CARD) {
-+ CKYBuffer pivData;
-+ CKYBuffer certInfo;
-+
-+ CKYBuffer_InitEmpty(&pivData);
-+ CKYBuffer_InitEmpty(&certInfo);
-+ CKYBuffer_Resize(cert, 0);
-+ status = PIVApplet_GetCertificate(conn, cert, pivContainer, &apduRC);
-+ if (throwException && (status != CKYSUCCESS)) {
-+ handleConnectionError();
-+ }
-+ /* actually, on success, we need to parse the certificate and find the
-+ * propper tag */
-+ if (status == CKYSUCCESS) {
-+ status = berProcess(cert, 0x53, &pivData, BER_UNWRAP);
-+ CKYBuffer_Resize(cert, 0);
-+ CKYBuffer_AppendChar(cert,0);
-+ do {
-+ CKYByte tag = CKYBuffer_GetChar(&pivData,0);
-+ if (tag == CAC_TAG_CERTIFICATE) {
-+ status = berProcess(&pivData, CAC_TAG_CERTIFICATE,
-+ cert, BER_UNWRAP);
-+ }
-+ if (tag == CAC_TAG_CERTINFO) {
-+ CKYBuffer_Resize(&certInfo, 0);
-+ status = berProcess(&pivData, CAC_TAG_CERTINFO,
-+ &certInfo, BER_UNWRAP);
-+ if (CKYBuffer_Size(&certInfo) == 1) {
-+ CKYBuffer_SetChar(cert,0,
-+ CKYBuffer_GetChar(&certInfo,0));
-+ }
-+ }
-+ if (status == CKYSUCCESS) {
-+ CKYBuffer_Resize(&certInfo, 0);
-+ status = berProcess(&pivData, 0, &certInfo, BER_NEXT);
-+ if (status == CKYSUCCESS) {
-+ CKYBuffer_Resize(&pivData,0);
-+ status = CKYBuffer_AppendCopy(&pivData,&certInfo);
-+ }
-+ }
-+ } while ((status == CKYSUCCESS) && (CKYBuffer_Size(&pivData) != 0));
-+ CKYBuffer_FreeData(&pivData);
-+ CKYBuffer_FreeData(&certInfo);
-+ }
-+
-+ return status;
-+ }
-+
- if (mOldCAC) {
- /* get the first 100 bytes of the cert */
- status = CACApplet_GetCertificateFirst(conn, cert, nextSize, &apduRC);
- if (throwException && (status != CKYSUCCESS)) {
- handleConnectionError();
- }
--
-- if(CKYBuffer_Size(cert) == 0) {
-- handleConnectionError();
-- }
- return status;
- }
-
-@@ -2233,6 +2952,7 @@ Slot::readCACCertificateFirst(CKYBuffer
- CKYBuffer_InitEmpty(&tBuf);
- CKYBuffer_InitEmpty(&vBuf);
- CKYBuffer_Resize(cert, 0);
-+ CKYBuffer_AppendChar(cert,0);
-
- /* handle the new CAC card read */
- /* read the TLV */
-@@ -2258,11 +2978,12 @@ Slot::readCACCertificateFirst(CKYBuffer
- length = CKYBuffer_GetShortLE(&tBuf, toffset);
- toffset +=2;
- }
-- if (tag != CAC_TAG_CERTIFICATE) {
-- continue;
-+ if (tag == CAC_TAG_CERTIFICATE) {
-+ CKYBuffer_AppendBuffer(cert, &vBuf, voffset, length);
-+ }
-+ if (tag == CAC_TAG_CERTINFO) {
-+ CKYBuffer_SetChar(cert,0,CKYBuffer_GetChar(&vBuf,voffset));
- }
-- CKYBuffer_AppendBuffer(cert, &vBuf, voffset, length);
-- break;
- }
- status = CKYSUCCESS;
-
-@@ -2272,6 +2993,191 @@ done:
- return status;
- }
-
-+
-+const static unsigned long crc_table[] = {
-+0x00000000,0x77073096,0xee0e612c,0x990951ba,
-+0x076dc419,0x706af48f,0xe963a535,0x9e6495a3,
-+0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,
-+0x09b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91,
-+0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,
-+0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7,
-+0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,
-+0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5,
-+0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172,
-+0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b,
-+0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940,
-+0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59,
-+0x26d930ac,0x51de003a,0xc8d75180,0xbfd06116,
-+0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f,
-+0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,
-+0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d,
-+0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,
-+0x71b18589,0x06b6b51f,0x9fbfe4a5,0xe8b8d433,
-+0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,
-+0x7f6a0dbb,0x086d3d2d,0x91646c97,0xe6635c01,
-+0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,
-+0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457,
-+0x65b0d9c6,0x12b7e950,0x8bbeb8ea,0xfcb9887c,
-+0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65,
-+0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2,
-+0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb,
-+0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0,
-+0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9,
-+0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,
-+0x5768b525,0x206f85b3,0xb966d409,0xce61e49f,
-+0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,
-+0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad,
-+0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,
-+0xead54739,0x9dd277af,0x04db2615,0x73dc1683,
-+0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8,
-+0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1,
-+0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe,
-+0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7,
-+0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc,
-+0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5,
-+0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252,
-+0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b,
-+0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,
-+0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79,
-+0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,
-+0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f,
-+0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,
-+0xc2d7ffa7,0xb5d0cf31,0x2cd99e8b,0x5bdeae1d,
-+0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a,
-+0x9c0906a9,0xeb0e363f,0x72076785,0x05005713,
-+0x95bf4a82,0xe2b87a14,0x7bb12bae,0x0cb61b38,
-+0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21,
-+0x86d3d2d4,0xf1d4e242,0x68ddb3f8,0x1fda836e,
-+0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777,
-+0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c,
-+0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45,
-+0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,
-+0xa7672661,0xd06016f7,0x4969474d,0x3e6e77db,
-+0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,
-+0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9,
-+0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,
-+0xbad03605,0xcdd70693,0x54de5729,0x23d967bf,
-+0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94,
-+0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d
-+};
-+
-+static unsigned long
-+calc_crc32(const unsigned char *buf, int len)
-+{
-+ unsigned long crc = 0xffffffff;
-+ int i;
-+
-+ for (i=0; i < len; i++) {
-+ unsigned char crc_low = crc & 0xff;
-+ unsigned long crc_high = crc >> 8;
-+ crc = crc_table[crc_low ^ buf[i]] ^ crc_high;
-+ }
-+ return crc ^ 0xffffffff;
-+}
-+
-+/*
-+ * decompress, handles both gzip and zlib trailers
-+ * it also automatically allocates the output buffer and expands it as
-+ * necessary.
-+ */
-+static int
-+decompress(CKYBuffer *out,
-+ CKYBuffer *in, CKYOffset offset, CKYSize len)
-+{
-+ int zret;
-+ CKYStatus status;
-+ z_stream stream;
-+ int chunk = len *2;
-+ int outlen = 0;
-+
-+
-+ /* allocate inflate state */
-+ stream.zalloc = Z_NULL;
-+ stream.zfree = Z_NULL;
-+ stream.opaque = Z_NULL;
-+ stream.avail_in = 0;
-+ stream.next_in = Z_NULL;
-+ zret = inflateInit(&stream);
-+ if (zret != Z_OK)
-+ return zret;
-+
-+ status = CKYBuffer_Reserve(out, outlen);
-+ if (status != CKYSUCCESS) {
-+ return Z_MEM_ERROR;
-+ }
-+
-+ stream.avail_in = len;
-+ stream.next_in = (Bytef *)(CKYBuffer_Data(in) + offset);
-+
-+ do {
-+ CKYBuffer_Resize(out, outlen + chunk);
-+ stream.avail_out = chunk;
-+
-+ stream.next_out = (Bytef *)CKYBuffer_Data(out)+ outlen;
-+
-+ zret= inflate(&stream, Z_NO_FLUSH);
-+
-+ /* we need the length early so it can be used in error processing */
-+ outlen += chunk - stream.avail_out;
-+
-+ /* proccess the error codes */
-+ switch (zret) {
-+ case Z_DATA_ERROR:
-+ /* a DATA error can occur on either corrupted data, or on gzip.
-+ * data. This is because gzip uses CRC32 and zlib used ADLER32
-+ * checksums. We need to check to see if this failure is do to
-+ * a gzip header. */
-+ /* 1) a gzip header includes 4 extra bytes containing the length
-+ * of the gziped data. This means there must be 4 more bytes
-+ * in our input buffer that have not been processed */
-+ if (stream.avail_in != 4) {
-+ break; /* not a gzip header */
-+ }
-+ /* The last 4 bytes of a gzip header include the uncompressed length
-+ * modulo 2^32. Make sure the actual uncompressed length matches
-+ * the header. */
-+ if ((outlen & 0xffffffffL)
-+ != CKYBuffer_GetLongLE(in, offset+len-4)) {
-+ break; /* didn't decode the full length */
-+ }
-+ /* At this point it''s pretty likely we have a gzip trailer. Verify
-+ * the crc32 values to make sure there hasn't been any corruption.
-+ */
-+ if (calc_crc32(CKYBuffer_Data(out), outlen) !=
-+ CKYBuffer_GetLongLE(in,offset+len-8)) {
-+ break; /* CRC didn't match */
-+ }
-+ /* This was valid gzip data, and we've successfully uncompressed
-+ * it. We're now done. */
-+ zret=Z_STREAM_END;
-+ break;
-+ case Z_NEED_DICT:
-+ /* if we need the dict, it wasn't in the data,
-+ * so it's a data error */
-+ zret = Z_DATA_ERROR;
-+ break;
-+ case Z_OK:
-+ /* Z_OK means we need more data, expand the buffer and go again.
-+ * if we don't need more buffer space, then the input must have
-+ * been truncated, that's a data error */
-+ if (stream.avail_out != 0) {
-+ zret = Z_DATA_ERROR;
-+ }
-+ break;
-+ }
-+ } while (zret == Z_OK);
-+
-+ /* cleanup */
-+ if (zret == Z_STREAM_END) {
-+ zret = Z_OK;
-+ CKYBuffer_Resize(out, outlen);
-+ } else {
-+ CKYBuffer_Resize(out, 0);
-+ }
-+ (void)inflateEnd(&stream);
-+ return zret;
-+}
-+
- /*
- * only necessary for old CAC cards. New CAC cards have to read the
- * whole cert in anyway above....
-@@ -2304,7 +3210,7 @@ Slot::loadCACCert(CKYByte instance)
- // catch the applet selection errors if they don't
- //
- try {
-- selectCACApplet(instance);
-+ selectCACApplet(instance, false);
- } catch(PKCS11Exception& e) {
- // all CAC's must have instance '0', throw the error it
- // they don't.
-@@ -2322,6 +3228,10 @@ Slot::loadCACCert(CKYByte instance)
-
- if (instance == 0) {
- readCACCertificateFirst(&rawCert, &nextSize, true);
-+
-+ if(CKYBuffer_Size(&rawCert) <= 1) {
-+ handleConnectionError();
-+ }
- log->log("CAC Cert %d: fetch CAC Cert: %d ms\n",
- instance, OSTimeNow() - time);
- }
-@@ -2364,7 +3274,7 @@ Slot::loadCACCert(CKYByte instance)
- } else {
- status = readCACCertificateFirst(&rawCert, &nextSize, false);
-
-- if (status != CKYSUCCESS) {
-+ if ((status != CKYSUCCESS) || (CKYBuffer_Size(&rawCert) <= 1)) {
- /* CAC only requires the Certificate in pki '0' */
- /* if pki '1' or '2' are empty, treat it as a non-fatal error*/
- if (instance == 2) {
-@@ -2393,31 +3303,61 @@ Slot::loadCACCert(CKYByte instance)
-
- log->log("CAC Cert %d: Cert has been read: %d ms\n",
- instance, OSTimeNow() - time);
-- if (!mOldCAC || CKYBuffer_GetChar(&rawCert,0) == 1) {
-- CKYSize guessFinalSize = CKYBuffer_Size(&rawCert);
-- CKYSize certSize = 0;
-- CKYOffset offset = mOldCAC ? 1 : 0;
-+ /* new CACs, and old CACs with the high one bit are compressed,
-+ * uncompress them */
-+ if ((CKYBuffer_GetChar(&rawCert,0) & 0x3) == 1) {
-+ CKYOffset offset = 1;
- int zret = Z_MEM_ERROR;
-
-- do {
-- guessFinalSize *= 2;
-- status = CKYBuffer_Resize(&cert, guessFinalSize);
-- if (status != CKYSUCCESS) {
-- break;
-+ /* process the GZIP header if present */
-+ /* header_id = 0x1f, 0x8b. CM=8. If we ever support something other
-+ * than CM=8, we need to change the zlib header below. Currently both
-+ * gzip and zlib only support CM=8 (DEFLATE) compression */
-+ if ((CKYBuffer_GetChar(&rawCert,1) == 0x1f) &&
-+ (CKYBuffer_GetChar(&rawCert,2) == 0x8b) &&
-+ (CKYBuffer_GetChar(&rawCert,3) == 8)) {
-+ CKYByte flags = CKYBuffer_GetChar(&rawCert,4);
-+ /* this has a gzip header, not raw data. */
-+ offset += 10; /* base size of the gzip header */
-+ if (flags & 4) { /* FEXTRA */
-+ CKYSize len = CKYBuffer_GetShortLE(&rawCert,offset);
-+ offset += len;
-+ }
-+ if (flags & 8) { /* FNAME */
-+ while (CKYBuffer_GetChar(&rawCert,offset) != 0) {
-+ offset++;
-+ }
-+ offset++;
-+ }
-+ if (flags & 0x10) { /* FComment */
-+ while (CKYBuffer_GetChar(&rawCert,offset) != 0) {
-+ offset++;
-+ }
-+ offset++;
-+ }
-+ if (flags & 2) { /* FHCRC */
-+ offset += 2;
- }
-- certSize = guessFinalSize;
-- zret = uncompress((Bytef *)CKYBuffer_Data(&cert),&certSize,
-- CKYBuffer_Data(&rawCert)+offset,
-- CKYBuffer_Size(&rawCert)-offset);
-- } while (zret == Z_BUF_ERROR);
-+ offset -= 2;
-+
-+ /* add zlib header, so libz will be happy */
-+ /* CINFO=7, CM=8, LEVEL=2, DICTFLAG=0, FCHECK= 1c */
-+ /* NOTE: the zlib will fail when procssing the trailer. this is
-+ * ok because decompress automatically notices the failure and
-+ * and checks the gzip trailer. */
-+ CKYBuffer_SetChar(&rawCert, offset, 0x78);
-+ CKYBuffer_SetChar(&rawCert, offset+1, 0x9c);
-+ }
-+ /* uncompress. This expands cert as necessary. */
-+ zret = decompress(&cert, &rawCert, offset,
-+ CKYBuffer_Size(&rawCert)-offset);
-
- if (zret != Z_OK) {
- CKYBuffer_FreeData(&rawCert);
- CKYBuffer_FreeData(&cert);
- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Corrupted compressed CAC Cert");
-+ "Corrupted compressed CAC/PIV Cert");
- }
-- CKYBuffer_Resize(&cert,certSize);
- } else {
- CKYBuffer_InitFromBuffer(&cert,&rawCert,1,CKYBuffer_Size(&rawCert)-1);
- }
-@@ -2431,6 +3371,9 @@ Slot::loadCACCert(CKYByte instance)
- tokenObjects.push_back(privKey);
- tokenObjects.push_back(pubKey);
- tokenObjects.push_back(certObj);
-+ if ( pubKey.getKeyType() == PKCS11Object::ecc) {
-+ mECC = 1;
-+ }
-
- if (personName == NULL) {
- const char *name = certObj.getName();
-@@ -2459,7 +3402,7 @@ Slot::loadObjects()
- list<ListObjectInfo> objInfoList;
- std::list<ListObjectInfo>::iterator iter;
-
-- if (state & CAC_CARD) {
-+ if (state & GOV_CARD) {
- loadCACCert(0);
- loadCACCert(1);
- loadCACCert(2);
-@@ -2467,6 +3410,17 @@ Slot::loadObjects()
- loadReaderObject();
- return;
- }
-+ if (state & P15_CARD) {
-+ parseEF_TokenInfo();
-+ parseEF_ODF();
-+ if (auth[CKU_USER] != NULL) {
-+ /* set need login */
-+ needLogin = true;
-+ }
-+ status = trans.end();
-+ loadReaderObject();
-+ return;
-+ }
-
- selectApplet();
- log->log("time load object: Select Applet (again) %d ms\n",
-@@ -2634,15 +3588,15 @@ Slot::getSessionInfo(SessionHandleSuffix
- }
-
- void
--SlotList::login(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen)
-+SlotList::login(CK_SESSION_HANDLE hSession, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
- {
- CK_SLOT_ID slotID;
- SessionHandleSuffix suffix;
-
- decomposeSessionHandle(hSession, slotID, suffix);
-
-- slots[slotIDToIndex(slotID)]->login(suffix, pPin, ulPinLen);
-+ slots[slotIDToIndex(slotID)]->login(suffix, user, pPin, ulPinLen);
- }
-
- void
-@@ -2692,8 +3646,8 @@ Slot::isLoggedIn()
- }
-
- void
--Slot::login(SessionHandleSuffix handleSuffix, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen)
-+Slot::login(SessionHandleSuffix handleSuffix, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
- {
- refreshTokenState();
-
-@@ -2702,9 +3656,23 @@ Slot::login(SessionHandleSuffix handleSu
- "Slot::login\n", (unsigned long) handleSuffix);
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-+ /* only support CKU_USER for CAC, PIV, and coolkey... CKU_USER and
-+ * CKU_CONTEX_SPECIFIC for P15Card */
-+ if (user != CKU_USER) {
-+ if ((user != CKU_CONTEXT_SPECIFIC) || ((state & P15_CARD) == 0)) {
-+ throw PKCS11Exception(CKR_USER_TYPE_INVALID);
-+ }
-+ }
-+
-
- if (!isVersion1Key) {
-- pinCache.set((const char *)pPin, ulPinLen);
-+ if (user == CKU_USER) {
-+ pinCache.invalidate();
-+ pinCache.set((const char *)pPin, ulPinLen);
-+ } else {
-+ contextPinCache.invalidate();
-+ contextPinCache.set((const char *)pPin, ulPinLen);
-+ }
- } else if (nonceValid) {
- throw PKCS11Exception(CKR_USER_ALREADY_LOGGED_IN);
- }
-@@ -2713,19 +3681,85 @@ Slot::login(SessionHandleSuffix handleSu
- CKYStatus status = trans.begin(conn);
- if(status != CKYSUCCESS ) handleConnectionError();
-
-- if (state & CAC_CARD) {
-- selectCACApplet(0);
-- } else {
-+ if (state & GOV_CARD) {
-+ selectCACApplet(0, true);
-+ } else if ((state & P15_CARD)== 0) {
-+ /* p15 does the select in attemptLogin */
- selectApplet();
- }
-
- if (isVersion1Key) {
-- attemptLogin((const char *)pPin);
-- } else if (state & CAC_CARD) {
-+ attemptCoolKeyLogin((const char *)pPin);
-+ } else {
-+ attemptLogin(user, false);
-+ }
-+}
-+
-+void
-+Slot::attemptLogin(CK_USER_TYPE user, bool flushPin) {
-+ if (state & GOV_CARD) {
- attemptCACLogin();
-+ } else if (state & P15_CARD) {
-+ attemptP15Login(user);
- } else {
- oldAttemptLogin();
- }
-+ if (flushPin && (user == CKU_CONTEXT_SPECIFIC)) {
-+ contextPinCache.clearPin();
-+ }
-+}
-+void dump(const char *label, const CKYBuffer *buf);
-+
-+void
-+Slot::attemptP15Login(CK_USER_TYPE user)
-+{
-+ PinCache *pinCachePtr = userPinCache(user);
-+
-+ if (user == CKU_USER) {
-+ loggedIn = false;
-+ }
-+ pinCachePtr->invalidate();
-+
-+ CKYStatus status;
-+ CKYISOStatus result;
-+
-+ if ((user >= MAX_AUTH_USERS) || (auth[user] == NULL)) {
-+ throw PKCS11Exception(CKR_USER_TYPE_INVALID,
-+ "No PKCS #15 auth object for user %d\n", user);
-+ }
-+
-+ status = selectPath(auth[user]->getObjectPath().getPath(), &result);
-+ if( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+ if (status != CKYSUCCESS) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR, "Applet select return 0x%04x",
-+ result);
-+ }
-+
-+ status = P15Applet_VerifyPIN(conn,
-+ (const char *)CKYBuffer_Data(pinCachePtr->get()),
-+ auth[user]->getPinInfo(), &result);
-+ if( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+ switch( result ) {
-+ case CKYISO_SUCCESS:
-+ break;
-+ case 0x6983:
-+ pinCachePtr->clearPin();
-+ throw PKCS11Exception(CKR_PIN_LOCKED);
-+ default:
-+ pinCachePtr->clearPin();
-+ if ((result & 0xff00) == 0x6300) {
-+ throw PKCS11Exception(CKR_PIN_INCORRECT);
-+ }
-+ throw PKCS11Exception(CKR_DEVICE_ERROR, "Applet returned 0x%04x",
-+ result);
-+ }
-+ pinCachePtr->validate();
-+ if (user == CKU_USER)
-+ loggedIn = true;
- }
-
- void
-@@ -2738,7 +3772,8 @@ Slot::attemptCACLogin()
- CKYISOStatus result;
-
- status = CACApplet_VerifyPIN(conn,
-- (const char *)CKYBuffer_Data(pinCache.get()), &result);
-+ (const char *)CKYBuffer_Data(pinCache.get()),
-+ mCACLocalLogin, &result);
- if( status == CKYSCARDERR ) {
- handleConnectionError();
- }
-@@ -2746,8 +3781,10 @@ Slot::attemptCACLogin()
- case CKYISO_SUCCESS:
- break;
- case 0x6981:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_PIN_LOCKED);
- default:
-+ pinCache.clearPin();
- if ((result & 0xff00) == 0x6300) {
- throw PKCS11Exception(CKR_PIN_INCORRECT);
- }
-@@ -2759,6 +3796,7 @@ Slot::attemptCACLogin()
- loggedIn = true;
- }
-
-+
- void
- Slot::oldAttemptLogin()
- {
-@@ -2776,10 +3814,13 @@ Slot::oldAttemptLogin()
- case CKYISO_SUCCESS:
- break;
- case CKYISO_AUTH_FAILED:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_PIN_INCORRECT);
- case CKYISO_IDENTITY_BLOCKED:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_PIN_LOCKED);
- default:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_DEVICE_ERROR, "Applet returned 0x%04x",
- result);
- }
-@@ -2790,7 +3831,7 @@ Slot::oldAttemptLogin()
-
- // should already be in a transaction, and applet selected
- void
--Slot::attemptLogin(const char *pin)
-+Slot::attemptCoolKeyLogin(const char *pin)
- {
- CKYStatus status;
- CKYISOStatus result;
-@@ -2866,7 +3907,7 @@ Slot::logout(SessionHandleSuffix suffix)
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-
-- if (state & CAC_CARD) {
-+ if (state & (GOV_CARD|P15_CARD)) {
- CACLogout();
- return;
- }
-@@ -2993,7 +4034,7 @@ Slot::getAttributeValue(SessionHandleSuf
- ObjectConstIter iter = find_if(tokenObjects.begin(), tokenObjects.end(),
- ObjectHandleMatch(hObject));
-
-- if( iter == tokenObjects.end() ) {
-+ if ( iter == tokenObjects.end()) {
- throw PKCS11Exception(CKR_OBJECT_HANDLE_INVALID);
- }
-
-@@ -3077,6 +4118,21 @@ SlotList::generateRandom(CK_SESSION_HAND
- }
-
- void
-+SlotList::derive(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
-+{
-+
-+ CK_SLOT_ID slotID;
-+ SessionHandleSuffix suffix;
-+
-+ decomposeSessionHandle(hSession, slotID, suffix);
-+
-+ slots[slotIDToIndex(slotID)]->derive(suffix, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey);
-+
-+}
-+
-+void
- Slot::ensureValidSession(SessionHandleSuffix suffix)
- {
- if( ! isValidSession(suffix) ) {
-@@ -3090,24 +4146,36 @@ Slot::ensureValidSession(SessionHandleSu
- // from 0-9.
- //
- CKYByte
--Slot::objectHandleToKeyNum(CK_OBJECT_HANDLE hKey)
-+Slot::objectToKeyNum(const PKCS11Object *key)
-+{
-+ unsigned long id = key->getMuscleObjID();
-+
-+ if( getObjectClass(id) != 'k' ) {
-+ throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-+ }
-+ unsigned short keyNum = getObjectIndex(id);
-+ if( keyNum > 9 ) {
-+ throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-+ }
-+ return keyNum & 0xFF;
-+}
-+
-+PKCS11Object *
-+Slot::getKeyFromHandle(CK_OBJECT_HANDLE hKey)
- {
- ObjectConstIter iter = find_if(tokenObjects.begin(), tokenObjects.end(),
- ObjectHandleMatch(hKey));
-+ PKCS11Object &obj = (PKCS11Object &)*iter;
-
- if( iter == tokenObjects.end() ) {
-- // no such object
-- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-+ throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
-
- if( getObjectClass(iter->getMuscleObjID()) != 'k' ) {
- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
-- unsigned short keyNum = getObjectIndex(iter->getMuscleObjID());
-- if( keyNum > 9 ) {
-- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-- }
-- return keyNum & 0xFF;
-+
-+ return &obj;
- }
-
- void
-@@ -3119,7 +4187,8 @@ Slot::signInit(SessionHandleSuffix suffi
- if( session == sessions.end() ) {
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-- session->signatureState.initialize(objectHandleToKeyNum(hKey));
-+
-+ session->signatureState.initialize(getKeyFromHandle(hKey));
- }
-
- void
-@@ -3131,7 +4200,8 @@ Slot::decryptInit(SessionHandleSuffix su
- if( session == sessions.end() ) {
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-- session->decryptionState.initialize(objectHandleToKeyNum(hKey));
-+
-+ session->decryptionState.initialize(getKeyFromHandle(hKey));
- }
-
- /**
-@@ -3240,67 +4310,183 @@ stripRSAPadding(CKYBuffer *stripped, con
- }
- }
-
--class RSASignatureParams : public CryptParams {
-+class ECCKeyAgreementParams : public CryptParams {
- public:
-- RSASignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-+ ECCKeyAgreementParams(unsigned int keysize) : CryptParams(keysize) { }
-
-- CKYByte getDirection() const { return CKY_DIR_ENCRYPT; }
-+ CKYByte getDirection() const { return CKY_DIR_NONE;}
-
- CryptOpState& getOpState(Session& session) const {
-- return session.signatureState;
-+ return session.keyAgreementState;
- }
-
- void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-- // RSA_NO_PAD requires RSA PKCS #1 Type 1 padding
-- CKYStatus status = CKYBuffer_Resize(paddedInput,getKeySize()/8);
-- if (status != CKYSUCCESS) {
-- throw PKCS11Exception(CKR_HOST_MEMORY);
-- }
-- padRSAType1(unpaddedInput, paddedInput);
- return;
- }
-
- void
- unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-- // no need to unpad ciphertext
-- CKYBuffer_Replace(unpaddedOutput, 0, CKYBuffer_Data(paddedOutput),
-- CKYBuffer_Size(paddedOutput));
--
-+ return;
- }
-+
- };
-
--class RSADecryptParams: public CryptParams {
-+class SignatureParams : public CryptParams {
- public:
-- RSADecryptParams(unsigned int keysize) : CryptParams(keysize) { }
-+ SignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-
-- CKYByte getDirection() const { return CKY_DIR_DECRYPT; }
-+ CKYByte getDirection() const { return CKY_DIR_NONE; }
-
- CryptOpState& getOpState(Session& session) const {
-- return session.decryptionState;
-+ return session.signatureState;
- }
-
- void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-- // no need to unpad ciphertext
-- CKYBuffer_Replace(paddedInput, 0, CKYBuffer_Data(unpaddedInput),
-- CKYBuffer_Size(unpaddedInput));
-+ return;
- }
-
- void
- unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-- // strip off PKCS #1 padding
-- stripRSAPadding( unpaddedOutput, paddedOutput );
-- return;
-+ return;
- }
-+
- };
-
--void
--Slot::sign(SessionHandleSuffix suffix, CK_BYTE_PTR pData,
-- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
-- CK_ULONG_PTR pulSignatureLen)
--{
-- RSASignatureParams params(CryptParams::DEFAULT_KEY_SIZE);
-- cryptRSA(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-- params);
-+
-+
-+class ECCSignatureParams : public CryptParams {
-+ public:
-+ ECCSignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-+
-+ CKYByte getDirection() const { return CKY_DIR_NONE; }
-+
-+ CryptOpState& getOpState(Session& session) const {
-+ return session.signatureState;
-+ }
-+
-+ void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-+ return;
-+ }
-+
-+ void
-+ unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-+ /* Here we will unpack the DER encoding of the signature */
-+
-+ if ( unpaddedOutput == NULL || paddedOutput == NULL) {
-+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
-+ }
-+
-+ CKYBuffer rawSignature;
-+ CKYBuffer_InitEmpty(&rawSignature);
-+
-+ DEREncodedSignature sig(paddedOutput);
-+
-+ int rv = sig.getRawSignature(&rawSignature, getKeySize() );
-+
-+ if (rv == CKYSUCCESS) {
-+ CKYBuffer_Replace(unpaddedOutput, 0, CKYBuffer_Data(&rawSignature),
-+ CKYBuffer_Size(&rawSignature));
-+ } else {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR);
-+ }
-+
-+ CKYBuffer_FreeData(&rawSignature);
-+
-+ }
-+
-+};
-+
-+
-+class RSASignatureParams : public CryptParams {
-+ public:
-+ RSASignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-+
-+ CKYByte getDirection() const { return CKY_DIR_ENCRYPT; }
-+
-+ CryptOpState& getOpState(Session& session) const {
-+ return session.signatureState;
-+ }
-+
-+ void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-+ // RSA_NO_PAD requires RSA PKCS #1 Type 1 padding
-+ CKYStatus status = CKYBuffer_Resize(paddedInput,getKeySize()/8);
-+ if (status != CKYSUCCESS) {
-+ throw PKCS11Exception(CKR_HOST_MEMORY);
-+ }
-+ padRSAType1(unpaddedInput, paddedInput);
-+ return;
-+ }
-+
-+ void
-+ unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-+ // no need to unpad ciphertext
-+ CKYBuffer_Replace(unpaddedOutput, 0, CKYBuffer_Data(paddedOutput),
-+ CKYBuffer_Size(paddedOutput));
-+
-+ }
-+};
-+
-+class RSADecryptParams: public CryptParams {
-+ public:
-+ RSADecryptParams(unsigned int keysize) : CryptParams(keysize) { }
-+
-+ CKYByte getDirection() const { return CKY_DIR_DECRYPT; }
-+
-+ CryptOpState& getOpState(Session& session) const {
-+ return session.decryptionState;
-+ }
-+
-+ void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-+ // no need to unpad ciphertext
-+ CKYBuffer_Replace(paddedInput, 0, CKYBuffer_Data(unpaddedInput),
-+ CKYBuffer_Size(unpaddedInput));
-+ }
-+
-+ void
-+ unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-+ // strip off PKCS #1 padding
-+ stripRSAPadding( unpaddedOutput, paddedOutput );
-+ return;
-+ }
-+};
-+
-+void
-+Slot::sign(SessionHandleSuffix suffix, CK_BYTE_PTR pData,
-+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
-+ CK_ULONG_PTR pulSignatureLen)
-+{
-+
-+ refreshTokenState();
-+ SessionIter session = findSession(suffix);
-+ if( session == sessions.end() ) {
-+ throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
-+ }
-+
-+ if (!isVersion1Key && ! isLoggedIn() ) {
-+ throw PKCS11Exception(CKR_USER_NOT_LOGGED_IN);
-+ }
-+
-+ /* Create a default one just to get the sigState */
-+ SignatureParams dummyParams(CryptParams::DEFAULT_KEY_SIZE);
-+
-+ CryptOpState sigState = dummyParams.getOpState(*session);
-+
-+ PKCS11Object::KeyType keyType = sigState.key->getKeyType();
-+
-+ if ( keyType == PKCS11Object::unknown) {
-+ throw PKCS11Exception(CKR_DATA_INVALID);
-+ }
-+
-+ if( keyType == Key::ecc ) {
-+ ECCSignatureParams params(CryptParams::ECC_DEFAULT_KEY_SIZE);
-+ signECC(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-+ params);
-+
-+ } else if (keyType == Key::rsa) {
-+ RSASignatureParams params(CryptParams::DEFAULT_KEY_SIZE);
-+ cryptRSA(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-+ params);
-+ }
- }
-
- void
-@@ -3332,11 +4518,11 @@ Slot::cryptRSA(SessionHandleSuffix suffi
- }
- CryptOpState& opState = params.getOpState(*session);
- CKYBuffer *result = &opState.result;
-- CKYByte keyNum = opState.keyNum;
-+ PKCS11Object *key = opState.key;
-
-- unsigned int keySize = getKeySize(keyNum);
-+ unsigned int keySize = getRSAKeySize(key);
-
-- if(keySize != CryptParams::DEFAULT_KEY_SIZE)
-+ if (keySize != CryptParams::DEFAULT_KEY_SIZE)
- params.setKeySize(keySize);
-
- if( CKYBuffer_Size(result) == 0 ) {
-@@ -3358,7 +4544,8 @@ Slot::cryptRSA(SessionHandleSuffix suffi
- }
- try {
- params.padInput(&inputPad, &input);
-- performRSAOp(&output, &inputPad, keyNum, params.getDirection());
-+ performRSAOp(&output, &inputPad, params.getKeySize(), key,
-+ params.getDirection());
- params.unpadOutput(result, &output);
- CKYBuffer_FreeData(&input);
- CKYBuffer_FreeData(&inputPad);
-@@ -3395,35 +4582,216 @@ Slot::getNonce()
- return &nonce;
- }
-
-+void Slot::signECC(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
-+ CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params)
-+{
-+
-+ if( pulOutputLen == NULL ) {
-+ throw PKCS11Exception(CKR_DATA_INVALID,
-+ "output length is NULL");
-+ }
-+
-+ refreshTokenState();
-+ SessionIter session = findSession(suffix);
-+ if( session == sessions.end() ) {
-+ throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
-+ }
-+ /* version 1 keys may not need login. We catch the error
-+ on the operation. The token will not allow us to sign with
-+ a protected key unless we are logged in.
-+ can be removed when version 0 support is depricated.
-+ */
-+
-+ if (!isVersion1Key && ! isLoggedIn() ) {
-+ throw PKCS11Exception(CKR_USER_NOT_LOGGED_IN);
-+ }
-+ CryptOpState& opState = params.getOpState(*session);
-+ CKYBuffer *result = &opState.result;
-+ PKCS11Object *key = opState.key;
-+
-+ unsigned int keySize = getECCKeySize(key);
-+
-+ if(keySize != CryptParams::ECC_DEFAULT_KEY_SIZE)
-+ params.setKeySize(keySize);
-+
-+ if( CKYBuffer_Size(result) == 0 ) {
-+ unsigned int maxSize = params.getKeySize()/8;
-+
-+ if( pInput == NULL || ulInputLen == 0) {
-+ throw PKCS11Exception(CKR_DATA_LEN_RANGE);
-+ }
-+ if (ulInputLen > maxSize) {
-+ //pInput += ulInputLen - maxSize;
-+ ulInputLen = maxSize;
-+ }
-+
-+ CKYBuffer input;
-+ CKYBuffer output;
-+ CKYBuffer_InitEmpty(&output);
-+ CKYStatus status = CKYBuffer_InitFromData(&input, pInput, ulInputLen);
-+
-+ if (status != CKYSUCCESS) {
-+ CKYBuffer_FreeData(&output);
-+ throw PKCS11Exception(CKR_HOST_MEMORY);
-+ }
-+ try {
-+ performECCSignature(&output, &input, params.getKeySize(), key);
-+ params.unpadOutput(result, &output);
-+ CKYBuffer_FreeData(&input);
-+ CKYBuffer_FreeData(&output);
-+ } catch(PKCS11Exception& e) {
-+ CKYBuffer_FreeData(&input);
-+ CKYBuffer_FreeData(&output);
-+ throw(e);
-+ }
-+ }
-+
-+ if( pOutput != NULL ) {
-+ if( *pulOutputLen < CKYBuffer_Size(result) ) {
-+ *pulOutputLen = CKYBuffer_Size(result);
-+ throw PKCS11Exception(CKR_BUFFER_TOO_SMALL);
-+ }
-+ memcpy(pOutput, CKYBuffer_Data(result), CKYBuffer_Size(result));
-+ }
-+ *pulOutputLen = CKYBuffer_Size(result);
-+}
-+
- void
--Slot::performRSAOp(CKYBuffer *output, const CKYBuffer *input,
-- CKYByte keyNum, CKYByte direction)
-+Slot::selectKey(const PKCS11Object *key, bool retry)
- {
-- //
-- // establish a transaction
-- //
-+ /* P15 cards need to be reselected on retry because P15 must select
-+ * on authentication. PIV, CAC and Coolkeys do not */
-+ if (retry && ((state & GOV_CARD) || ((state & P15_CARD) == 0))) {
-+ return;
-+ }
-+ if (state & GOV_CARD) {
-+ selectCACApplet(objectToKeyNum(key), true);
-+ } else if (state & P15_CARD) {
-+ selectPath(key->getObjectPath().getPath(), NULL);
-+ } else {
-+ selectApplet();
-+ }
-+ return;
-+}
-+
-+void
-+Slot::performECCSignature(CKYBuffer *output, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key)
-+{
-+
-+ /* establish a transaction */
- Transaction trans;
- CKYStatus status = trans.begin(conn);
- if( status != CKYSUCCESS ) handleConnectionError();
-
-- //
-- // select the applet
-- //
-- if (state & CAC_CARD) {
-- selectCACApplet(keyNum);
-+ if (!mECC) {
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ }
-+
-+ CKYISOStatus result;
-+ bool loginAttempted = false;
-+
-+retry:
-+ selectKey(key, loginAttempted);
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_SignDecrypt(conn, pivKey, keySize/8, 0,
-+ input, output, &result);
-+ } else if (state & CAC_CARD) {
-+ status = CACApplet_SignDecrypt(conn, input, output, &result);
-+ } else if (state & P15_CARD) {
-+ status = P15Applet_SignDecrypt(conn, key->getKeyRef(), keySize/8,
-+ CKY_DIR_ENCRYPT, input, output, &result);
-+
- } else {
-- selectApplet();
-+ status = CKYApplet_ComputeECCSignature(conn, objectToKeyNum(key), input, NULL, output, getNonce(), &result);
-+ }
-+ /* map the ISO not logged in code to the coolkey one */
-+ if ((result == CKYISO_CONDITION_NOT_SATISFIED) ||
-+ (result == CKYISO_SECURITY_NOT_SATISFIED)) {
-+ result = (CKYStatus) CKYISO_UNAUTHORIZED;
-+ }
-+
-+ if (status != CKYSUCCESS) {
-+ if ( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+
-+ if (result == CKYISO_DATA_INVALID) {
-+ throw PKCS11Exception(CKR_DATA_INVALID);
-+ }
-+ /* keys could be logged out in the middle by someone else,
-+ * reauthenticate... coolkey version 1 bypasses this issue by
-+ * allowing multiple applications separate login states at once.
-+ */
-+ if (!isVersion1Key && !loginAttempted &&
-+ userPinCache(key->getUser())->isValid() &&
-+ (result == CKYISO_UNAUTHORIZED)) {
-+ /* try to reauthenticate */
-+ try {
-+ attemptLogin(key->getUser(),true);
-+ } catch(PKCS11Exception& ) {
-+ /* attemptLogin can throw things like CKR_PIN_INCORRECT
-+ that don't make sense from a crypto operation. This is
-+ a result of pin caching. We will reformat any login
-+ exception to a CKR_DEVICE_ERROR.
-+ */
-+ throw PKCS11Exception(CKR_DEVICE_ERROR);
-+ }
-+ loginAttempted = true;
-+ goto retry; /* easier to understand than a while loop in this case. */
-+ }
-+ throw PKCS11Exception( result == CKYISO_UNAUTHORIZED ?
-+ CKR_USER_NOT_LOGGED_IN : CKR_DEVICE_ERROR);
-+
- }
-
-+}
-+
-+
-+void
-+Slot::performRSAOp(CKYBuffer *output, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key,
-+ CKYByte direction)
-+{
-+ if ( mECC ) {
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ }
-+
-+ //
-+ // establish a transaction
-+ //
-+ Transaction trans;
-+ CKYStatus status = trans.begin(conn);
-+ if( status != CKYSUCCESS ) handleConnectionError();
- CKYISOStatus result;
-- int loginAttempted = 0;
-+ bool loginAttempted = false;
-+
- retry:
-- if (state & CAC_CARD) {
-+ selectKey(key, loginAttempted);
-+
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_SignDecrypt(conn, pivKey, keySize/8, 0,
-+ input, output, &result);
-+ } else if (state & CAC_CARD) {
- status = CACApplet_SignDecrypt(conn, input, output, &result);
-+ } else if (state & P15_CARD) {
-+ status = P15Applet_SignDecrypt(conn, key->getKeyRef(), keySize/8,
-+ direction, input, output, &result);
- } else {
-- status = CKYApplet_ComputeCrypt(conn, keyNum, CKY_RSA_NO_PAD, direction,
-- input, NULL, output, getNonce(), &result);
-+ status = CKYApplet_ComputeCrypt(conn, objectToKeyNum(key),
-+ CKY_RSA_NO_PAD, direction, input, NULL, output,
-+ getNonce(), &result);
- }
-+
-+ /* map the ISO not logged in code to the coolkey one */
-+ if ((result == CKYISO_CONDITION_NOT_SATISFIED) ||
-+ (result == CKYISO_SECURITY_NOT_SATISFIED)) {
-+ result = CKYISO_UNAUTHORIZED;
-+ }
-+
- if (status != CKYSUCCESS) {
- if ( status == CKYSCARDERR ) {
- handleConnectionError();
-@@ -3435,10 +4803,11 @@ retry:
- // reauthenticate... This code can go away when we depricate.
- // version0 applets.
- if (!isVersion1Key && !loginAttempted &&
-+ userPinCache(key->getUser())->isValid() &&
- (result == CKYISO_UNAUTHORIZED)) {
- // try to reauthenticate
- try {
-- oldAttemptLogin();
-+ attemptLogin(key->getUser(), true);
- } catch(PKCS11Exception& ) {
- // attemptLogin can throw things like CKR_PIN_INCORRECT
- // that don't make sense from a crypto operation. This is
-@@ -3458,7 +4827,7 @@ void
- Slot::seedRandom(SessionHandleSuffix suffix, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen)
- {
-- if (state & CAC_CARD) {
-+ if (state & (GOV_CARD|P15_CARD)) {
- /* should throw unsupported */
- throw PKCS11Exception(CKR_DEVICE_ERROR);
- }
-@@ -3510,7 +4879,7 @@ void
- Slot::generateRandom(SessionHandleSuffix suffix, const CK_BYTE_PTR pData,
- CK_ULONG ulDataLen)
- {
-- if (state & CAC_CARD) {
-+ if (state & (GOV_CARD|P15_CARD)) {
- /* should throw unsupported */
- throw PKCS11Exception(CKR_DEVICE_ERROR);
- }
-@@ -3544,33 +4913,249 @@ Slot::generateRandom(SessionHandleSuffix
-
- #define MAX_NUM_KEYS 8
- unsigned int
--Slot::getKeySize(CKYByte keyNum)
-+Slot::getRSAKeySize(PKCS11Object *key)
- {
- unsigned int keySize = CryptParams::DEFAULT_KEY_SIZE;
- int modSize = 0;
-
-- if(keyNum >= MAX_NUM_KEYS) {
-- return keySize;
-- }
--
-- ObjectConstIter iter;
-- iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-- KeyNumMatch(keyNum,*this));
--
-- if( iter == tokenObjects.end() ) {
-- return keySize;
-+ modSize = key->getKeySize();
-+ if (modSize != 0) {
-+ return modSize;
- }
-
-- CKYBuffer const *modulus = iter->getAttribute(CKA_MODULUS);
-+ CKYBuffer const *modulus = key->getAttribute(CKA_MODULUS);
-
- if(modulus) {
- modSize = CKYBuffer_Size(modulus);
- if(CKYBuffer_GetChar(modulus,0) == 0x0) {
- modSize--;
- }
-- if(modSize > 0)
-+ if(modSize > 0) {
- keySize = modSize * 8;
-+ key->setKeySize(keySize);
-+ }
- }
-
- return keySize;
- }
-+
-+unsigned int
-+Slot::getECCKeySize(PKCS11Object *key)
-+{
-+ unsigned int keySize = CryptParams::ECC_DEFAULT_KEY_SIZE;
-+ unsigned int objKeySize = 0;
-+
-+ objKeySize = key->getKeySize();
-+ if (objKeySize != 0) {
-+ return objKeySize;
-+ }
-+
-+ CKYBuffer const *eccParams = key->getAttribute(CKA_EC_PARAMS);
-+
-+ if (eccParams == NULL) {
-+ return keySize;
-+ }
-+
-+ /* Extract the oid from the params */
-+
-+ CKYByte ecParamsLen = CKYBuffer_GetChar(eccParams, 1);
-+
-+ if ( ecParamsLen == 0 ) {
-+ return keySize;
-+ }
-+
-+/* Now compare against the limited known list of oid byte info */
-+
-+ unsigned int oidByteLen = 0;
-+
-+ CKYByte curByte = 0;
-+
-+ for (int i = 0 ; i < numECCurves ; i++ ) {
-+
-+ oidByteLen = curveBytesNamePair[i].bytes[0];
-+
-+ if ( oidByteLen != (unsigned int ) ecParamsLen ) {
-+ continue;
-+ }
-+
-+ int match = 1;
-+ for ( int j = 0 ; j < ecParamsLen ; j++ ) {
-+ curByte = CKYBuffer_GetChar(eccParams, 2 + j );
-+ if ( curveBytesNamePair[i].bytes[ j + 1 ] != curByte ) {
-+ match = 0;
-+ break;
-+ }
-+ }
-+
-+ if ( match == 1 ) {
-+ keySize = curveBytesNamePair[i].length;
-+ key->setKeySize(keySize);
-+ return keySize;
-+ }
-+
-+ }
-+
-+ return keySize;
-+}
-+
-+void
-+Slot::derive(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
-+{
-+
-+ log->log("Inside of Slot::Derive! \n");
-+
-+ ECCKeyAgreementParams params(CryptParams::ECC_DEFAULT_KEY_SIZE);
-+ SessionIter session = findSession(suffix);
-+
-+ session->keyAgreementState.initialize(getKeyFromHandle(hBaseKey));
-+ deriveECC(suffix, pMechanism, hBaseKey, pTemplate, ulAttributeCount,
-+ phKey, params);
-+
-+}
-+
-+void Slot::deriveECC(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, CryptParams& params)
-+{
-+ if (pMechanism == NULL ) {
-+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
-+ }
-+
-+ CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;
-+
-+ mechParams = (CK_ECDH1_DERIVE_PARAMS*) pMechanism->pParameter;
-+
-+ if (mechParams == NULL || mechParams->kdf != CKD_NULL ) {
-+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
-+ }
-+
-+ refreshTokenState();
-+ SessionIter session = findSession(suffix);
-+ if( session == sessions.end() ) {
-+ throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
-+ }
-+
-+ /* version 1 keys may not need login. We catch the error
-+ on the operation. The token will not allow us to sign with
-+ a protected key unless we are logged in.
-+ can be removed when version 0 support is depricated. */
-+
-+ if (!isVersion1Key && ! isLoggedIn() ) {
-+ throw PKCS11Exception(CKR_USER_NOT_LOGGED_IN);
-+ }
-+
-+ CryptOpState& opState = params.getOpState(*session);
-+ CKYBuffer *result = &opState.result;
-+
-+ unsigned int keySize = getECCKeySize(opState.key);
-+
-+ if(keySize != CryptParams::ECC_DEFAULT_KEY_SIZE)
-+ params.setKeySize(keySize);
-+
-+ CK_MECHANISM_TYPE deriveMech = pMechanism->mechanism;
-+
-+ CK_ULONG otherPublicLen = mechParams->ulPublicDataLen;
-+ CK_BYTE_PTR otherPublicData = mechParams->pPublicData;
-+
-+ CKYBuffer secretKeyBuffer;
-+ CKYBuffer_InitEmpty(&secretKeyBuffer);
-+ CKYBuffer publicDataBuffer;
-+ CKYStatus status = CKYBuffer_InitFromData(&publicDataBuffer,otherPublicData, otherPublicLen);
-+
-+ if (status != CKYSUCCESS) {
-+ CKYBuffer_FreeData(&secretKeyBuffer);
-+ throw PKCS11Exception(CKR_HOST_MEMORY);
-+ }
-+
-+ PKCS11Object *secret = NULL;
-+ *phKey = 0;
-+
-+ if( CKYBuffer_Size(result) == 0 ) {
-+ try {
-+ performECCKeyAgreement(deriveMech, &publicDataBuffer,
-+ &secretKeyBuffer, opState.key, params.getKeySize());
-+ CK_OBJECT_HANDLE keyObjectHandle = generateUnusedObjectHandle();
-+ secret = createSecretKeyObject(keyObjectHandle, &secretKeyBuffer,
-+ pTemplate, ulAttributeCount);
-+ } catch(PKCS11Exception& e) {
-+ CKYBuffer_FreeData(&secretKeyBuffer);
-+ CKYBuffer_FreeData(&publicDataBuffer);
-+ throw(e);
-+ }
-+ }
-+
-+ CKYBuffer_FreeData(&secretKeyBuffer);
-+ CKYBuffer_FreeData(&publicDataBuffer);
-+
-+ if ( secret ) {
-+ *phKey = secret->getHandle();
-+ delete secret;
-+ }
-+}
-+
-+void
-+Slot::performECCKeyAgreement(CK_MECHANISM_TYPE deriveMech,
-+ CKYBuffer *publicDataBuffer, CKYBuffer *secretKeyBuffer,
-+ const PKCS11Object *key, unsigned int keySize)
-+{
-+ if (!mECC) {
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ }
-+
-+ Transaction trans;
-+ CKYStatus status = trans.begin(conn);
-+ if( status != CKYSUCCESS ) handleConnectionError();
-+
-+ CKYISOStatus result;
-+ bool loginAttempted = false;
-+
-+retry:
-+ selectKey(key, loginAttempted);
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_SignDecrypt(conn, pivKey, keySize/8, 1,
-+ publicDataBuffer, secretKeyBuffer, &result);
-+ } else if (state & CAC_CARD) {
-+ status = CACApplet_SignDecrypt(conn, publicDataBuffer,
-+ secretKeyBuffer, &result);
-+ } else if (state & P15_CARD) {
-+ /*status = P15Applet_SignDecrypt(conn, key->getKeyRef(), keySize/8,
-+ publicDataBuffer, secretKeyBuffer, &result); */
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ } else {
-+ status = CKYApplet_ComputeECCKeyAgreement(conn, objectToKeyNum(key),
-+ publicDataBuffer , NULL, secretKeyBuffer,
-+ getNonce(), &result);
-+ }
-+ /* map the ISO not logged in code to the coolkey one */
-+ if ((result == CKYISO_CONDITION_NOT_SATISFIED) ||
-+ (result == CKYISO_SECURITY_NOT_SATISFIED)) {
-+ result = (CKYStatus) CKYISO_UNAUTHORIZED;
-+ }
-+
-+ if (status != CKYSUCCESS) {
-+ if ( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+
-+ if (result == CKYISO_DATA_INVALID) {
-+ throw PKCS11Exception(CKR_DATA_INVALID);
-+ }
-+ if (!isVersion1Key && !loginAttempted &&
-+ userPinCache(key->getUser())->isValid() &&
-+ (result == CKYISO_UNAUTHORIZED)) {
-+ try {
-+ attemptLogin(key->getUser(), true);
-+ } catch(PKCS11Exception& ) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR);
-+ }
-+ loginAttempted = true;
-+ goto retry;
-+ }
-+
-+ throw PKCS11Exception( result == CKYISO_UNAUTHORIZED ?
-+ CKR_USER_NOT_LOGGED_IN : CKR_DEVICE_ERROR);
-+
-+ }
-+}
-diff -up ./src/coolkey/slot.h.coolkey-update ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.coolkey-update 2016-01-19 17:56:25.705426782 -0800
-+++ ./src/coolkey/slot.h 2016-01-19 17:56:35.438346737 -0800
-@@ -183,7 +183,7 @@ struct PinCache {
- CKYBuffer_Replace(&cachedPin, 0, (const CKYByte *)newPin, pinLen);
- CKYBuffer_AppendChar(&cachedPin, 0);
- }
-- void clearPin() { CKYBuffer_Zero(&cachedPin); }
-+ void clearPin() { CKYBuffer_Zero(&cachedPin); valid = false; }
- void invalidate() { valid = false; }
- void validate() { valid = true; }
- const CKYBuffer *get() const { return &cachedPin; }
-@@ -209,26 +209,26 @@ class CryptOpState {
- public:
- enum State { NOT_INITIALIZED, IN_PROCESS, FINALIZED };
- State state;
-- CKYByte keyNum;
- CKYBuffer result;
-+ PKCS11Object *key;
-
-- CryptOpState() : state(NOT_INITIALIZED), keyNum(0)
-+ CryptOpState() : state(NOT_INITIALIZED), key(NULL)
- { CKYBuffer_InitEmpty(&result); }
- CryptOpState(const CryptOpState &cpy) :
-- state(cpy.state), keyNum(cpy.keyNum) {
-+ state(cpy.state), key(cpy.key) {
- CKYBuffer_InitFromCopy(&result, &cpy.result);
- }
- CryptOpState &operator=(const CryptOpState &cpy) {
- state = cpy.state,
-- keyNum = cpy.keyNum;
-+ key = cpy.key;
- CKYBuffer_Replace(&result, 0, CKYBuffer_Data(&cpy.result),
- CKYBuffer_Size(&cpy.result));
- return *this;
- }
- ~CryptOpState() { CKYBuffer_FreeData(&result); }
-- void initialize(CKYByte keyNum) {
-+ void initialize(PKCS11Object *theKey) {
- state = IN_PROCESS;
-- this->keyNum = keyNum;
-+ this->key = theKey;
- CKYBuffer_Resize(&result, 0);
- }
- };
-@@ -258,6 +258,7 @@ class Session {
-
- CryptOpState signatureState;
- CryptOpState decryptionState;
-+ CryptOpState keyAgreementState;
- };
-
- typedef list<Session> SessionList;
-@@ -267,12 +268,11 @@ typedef SessionList::const_iterator Sess
- class CryptParams {
- private:
- unsigned int keySize; // in bits
-- protected:
-- unsigned int getKeySize() const { return keySize; }
- public:
- // set the actual key size obtained from the card
- void setKeySize(unsigned int newKeySize) { keySize = newKeySize; }
-- enum { DEFAULT_KEY_SIZE = 1024 };
-+ unsigned int getKeySize() const { return keySize; }
-+ enum { DEFAULT_KEY_SIZE = 1024, ECC_DEFAULT_KEY_SIZE=256 };
-
-
- CryptParams(unsigned int keySize_) : keySize(keySize_) { }
-@@ -295,6 +295,7 @@ class CryptParams {
- };
-
- #define MAX_CERT_SLOTS 3
-+#define MAX_AUTH_USERS 3
- class Slot {
-
- public:
-@@ -304,17 +305,22 @@ class Slot {
- ATR_MATCH = 0x04,
- APPLET_SELECTABLE = 0x08,
- APPLET_PERSONALIZED = 0x10,
-- CAC_CARD = 0x20
-+ CAC_CARD = 0x20,
-+ PIV_CARD = 0x40,
-+ P15_CARD = 0x80
- };
- enum {
- NONCE_SIZE = 8
- };
-
-+ static const SlotState GOV_CARD = (SlotState)(CAC_CARD|PIV_CARD);
-+
- private:
- Log *log;
- char *readerName;
- char *personName;
- char *manufacturer;
-+ char *tokenManufacturer;
- //char *model;
- CK_VERSION hwVersion;
- CK_VERSION tokenFWVersion;
-@@ -323,6 +329,7 @@ class Slot {
- CKYCardConnection* conn;
- unsigned long state; // = UNKNOWN
- PinCache pinCache;
-+ PinCache contextPinCache;
- bool loggedIn;
- bool reverify;
- bool nonceValid;
-@@ -339,7 +346,18 @@ class Slot {
- bool fullTokenName;
- bool mCoolkey;
- bool mOldCAC;
--
-+ bool mCACLocalLogin;
-+ int pivContainer;
-+ int pivKey;
-+ bool mECC;
-+ unsigned short p15aid;
-+ unsigned short p15odfAddr;
-+ unsigned short p15tokenInfoAddr;
-+ unsigned int p15Instance;
-+ CKYBuffer p15AID;
-+ CKYBuffer p15tokenInfo;
-+ CKYBuffer p15odf;
-+ CKYBuffer p15serialNumber;
- //enum { RW_SESSION_HANDLE = 1, RO_SESSION_HANDLE = 2 };
-
- #ifdef USE_SHMEM
-@@ -358,6 +376,7 @@ class Slot {
-
- void closeAllSessions();
- SessionHandleSuffix generateNewSession(Session::Type type);
-+ PK15Object *auth[MAX_AUTH_USERS];
-
- bool cardStateMayHaveChanged();
- void connectToToken();
-@@ -386,6 +405,7 @@ class Slot {
- const CKYBuffer *getATR();
- bool isLoggedIn();
- bool needLoggedIn();
-+ bool getPIVLoginType();
- void testNonce();
-
- void addKeyObject(list<PKCS11Object>& objectList,
-@@ -395,6 +415,7 @@ class Slot {
- const CKYBuffer *derCert, CK_OBJECT_HANDLE handle);
- void addObject(list<PKCS11Object>& objectList,
- const ListObjectInfo& info, CK_OBJECT_HANDLE handle);
-+ PKCS11Object *createSecretKeyObject(CK_OBJECT_HANDLE handle, CKYBuffer *secretKeyBuffer,CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount);
-
- void ensureValidSession(SessionHandleSuffix suffix);
-
-@@ -407,37 +428,63 @@ class Slot {
- bool throwException);
- CKYStatus readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize);
-
-+ CKYStatus getP15Params();
- void selectApplet();
-- void selectCACApplet(CKYByte instance);
-+ void selectCACApplet(CKYByte instance,bool do_disconnect);
-+ void selectKey(const PKCS11Object *key, bool retry);
-+ CKYStatus selectPath(const CKYBuffer *path, CKYISOStatus *adpurc);
-+ CKYStatus readFromPath(const PK15ObjectPath &obj, CKYBuffer *file);
- void unloadObjects();
- void loadCACObjects();
- void loadCACCert(CKYByte instance);
- void loadObjects();
- void loadReaderObject();
-
-- void attemptLogin(const char *pin);
-+ void attemptCoolKeyLogin(const char *pin);
-+ void attemptLogin(CK_USER_TYPE user, bool flushPin);
-+ void attemptP15Login(CK_USER_TYPE user);
- void attemptCACLogin();
- void oldAttemptLogin();
- void oldLogout(void);
- void CACLogout(void);
-+ PinCache *userPinCache(CK_USER_TYPE user) {
-+ return ((user == CKU_CONTEXT_SPECIFIC) && (state & P15_CARD)) ?
-+ &contextPinCache : &pinCache; }
-+
-+ void parseEF_ODF(void);
-+ void parseEF_TokenInfo(void);
-+ CKYStatus parseEF_Directory(const CKYByte *data, CKYSize size,
-+ PK15ObjectType type);
-+ unsigned int PK15Instance(void) { return p15Instance++; }
-
- void readMuscleObject(CKYBuffer *obj, unsigned long objID,
- unsigned int objSize);
-
- void performSignature(CKYBuffer *sig, const CKYBuffer *unpaddedInput,
-- CKYByte keyNum);
-- void performDecryption(CKYBuffer *data, const CKYBuffer *input, CKYByte keyNum);
-+ const PKCS11Object *key);
-+ void performDecryption(CKYBuffer *data, const CKYBuffer *input,
-+ const PKCS11Object *key);
-
- void cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
- CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
- CK_ULONG_PTR pulOutputLen, CryptParams& params);
-
-- void performRSAOp(CKYBuffer *out, const CKYBuffer *input, CKYByte keyNum,
-- CKYByte direction);
-+ void performRSAOp(CKYBuffer *out, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key, CKYByte direction);
-+
-+ void signECC(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
-+ CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params);
-+
-+ void performECCSignature(CKYBuffer *out, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key);
-+ void performECCKeyAgreement(CK_MECHANISM_TYPE deriveMech,
-+ CKYBuffer *publicDataBuffer, CKYBuffer *secretKeyBuffer,
-+ const PKCS11Object *key, unsigned int keySize);
-
- void processComputeCrypt(CKYBuffer *result, const CKYAPDU *apdu);
-
-- CKYByte objectHandleToKeyNum(CK_OBJECT_HANDLE hKey);
-+ CKYByte objectToKeyNum(const PKCS11Object *key);
- Slot(const Slot &cpy)
- #ifdef USE_SHMEM
- : shmem(readerName)
-@@ -469,7 +516,10 @@ class Slot {
- }
-
- // actually get the size of a key in bits from the card
-- unsigned int getKeySize(CKYByte keyNum);
-+ unsigned int getRSAKeySize(PKCS11Object *key);
-+ unsigned int getECCKeySize(PKCS11Object *key);
-+
-+ PKCS11Object *getKeyFromHandle(CK_OBJECT_HANDLE hKey);
-
- SessionHandleSuffix openSession(Session::Type type);
- void closeSession(SessionHandleSuffix handleSuffix);
-@@ -479,8 +529,8 @@ class Slot {
- void getSessionInfo(SessionHandleSuffix handleSuffix,
- CK_SESSION_INFO_PTR pInfo);
-
-- void login(SessionHandleSuffix handleSuffix, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen);
-+ void login(SessionHandleSuffix handleSuffix, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen);
-
- void logout(SessionHandleSuffix suffix);
-
-@@ -511,6 +561,16 @@ class Slot {
- CK_ULONG len);
- void generateRandom(SessionHandleSuffix suffix, CK_BYTE_PTR data,
- CK_ULONG len);
-+
-+ void derive(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
-+
-+ void deriveECC(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, CryptParams& params);
-+
-+ bool getIsECC() { return mECC; }
- };
-
- class SlotList {
-@@ -569,8 +629,8 @@ class SlotList {
- void getSessionInfo(CK_SESSION_HANDLE sessionHandle,
- CK_SESSION_INFO_PTR pInfo);
-
-- void login(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen);
-+ void login(CK_SESSION_HANDLE hSession, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen);
-
- void logout(CK_SESSION_HANDLE hSession);
-
-@@ -604,6 +664,10 @@ class SlotList {
- void seedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen);
-
-+ void derive(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
-+
-
- };
- #endif
-diff -up ./src/install/pk11install.c.coolkey-update ./src/install/pk11install.c
---- ./src/install/pk11install.c.coolkey-update 2016-01-19 18:20:42.299464185 -0800
-+++ ./src/install/pk11install.c 2016-01-19 18:18:52.766363310 -0800
-@@ -171,7 +171,7 @@ int dirListCount = sizeof(dirList)/sizeo
- static void
- usage(char *prog)
- {
-- fprintf(stderr,"usage: %s [-u][-v] [-p path] module\n", prog);
-+ fprintf(stderr,"usage: %s [-u][-v][-s][-l] [-p path] module\n", prog);
- return;
- }
-
-@@ -181,9 +181,9 @@ usage(char *prog)
-
- #define CONFIG_TAG "configDir="
- int
--installPKCS11(char *dirPath, InstType type, char *module)
-+installPKCS11(char *dirPath, char *dbType, InstType type, char *module)
- {
-- char *paramString = (char *)malloc(strlen(dirPath)+sizeof(CONFIG_TAG)+3);
-+ char *paramString = (char *)malloc(strlen(dbType)+strlen(dirPath)+sizeof(CONFIG_TAG)+3);
- char *cp;
- char **rc;
-
-@@ -191,7 +191,7 @@ installPKCS11(char *dirPath, InstType ty
- PINST_SET_ERROR(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
-- sprintf(paramString,CONFIG_TAG"\"%s\" ",dirPath);
-+ sprintf(paramString,CONFIG_TAG"\"%s%s\" ",dbType,dirPath);
-
- /* translate all the \'s to /'s */
- for (cp=paramString; *cp; cp++) {
-@@ -214,7 +214,7 @@ installPKCS11(char *dirPath, InstType ty
-
-
- int
--installAllPKCS11(char *dirPath, char *search, char *tail,
-+installAllPKCS11(char *dirPath, char *dbType, char *search, char *tail,
- InstType type, char *module)
- {
- char *searchString;
-@@ -282,9 +282,9 @@ installAllPKCS11(char *dirPath, char *se
-
- myPath=PINST_FULLPATH(tempPath,path);
- if (tail) {
-- installAllPKCS11(myPath, tail, NULL, type, module);
-+ installAllPKCS11(myPath, dbType, tail, NULL, type, module);
- } else {
-- installPKCS11(myPath, type, module);
-+ installPKCS11(myPath, dbType, type, module);
- }
- } while (PINST_NEXT(iter, fileData));
- free(tempPath);
-@@ -309,6 +309,7 @@ int main(int argc, char **argv)
- int i;
- InstType type = Install;
- char * path = NULL;
-+ char *dbType = "";
- #ifdef WIN32
- BOOL brc;
- HKEY regKey;
-@@ -333,6 +334,12 @@ int main(int argc, char **argv)
- case 'v':
- verbose = 1;
- break;
-+ case 'l':
-+ dbType = "dbm:";
-+ break;
-+ case 's':
-+ dbType = "sql:";
-+ break;
- case 'p':
- path = *argv++;
- if (path == NULL) {
-@@ -359,7 +366,7 @@ int main(int argc, char **argv)
- }
-
- if (path) {
-- installAllPKCS11(path, "", NULL, type, module);
-+ installAllPKCS11(path, dbType, "", NULL, type, module);
- return 0;
- }
-
-@@ -444,7 +451,7 @@ int main(int argc, char **argv)
- if (!dirPath) {
- continue;
- }
-- installAllPKCS11(dirPath, dirList[i].search, dirList[i].tail,
-+ installAllPKCS11(dirPath, dbType, dirList[i].search, dirList[i].tail,
- type, module);
- }
-
-diff -up ./src/libckyapplet/cky_applet.c.coolkey-update ./src/libckyapplet/cky_applet.c
---- ./src/libckyapplet/cky_applet.c.coolkey-update 2016-01-19 18:01:32.031909257 -0800
-+++ ./src/libckyapplet/cky_applet.c 2016-01-19 18:01:45.612797732 -0800
-@@ -19,6 +19,7 @@
-
- #include <stdio.h>
- #include "cky_applet.h"
-+#include <string.h>
-
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
-
-@@ -51,6 +52,12 @@ CACAppletFactory_SelectFile(CKYAPDU *apd
- }
-
- CKYStatus
-+P15AppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectFile(apdu, 0, 0, (const CKYBuffer *)param);
-+}
-+
-+CKYStatus
- CKYAppletFactory_SelectCardManager(CKYAPDU *apdu, const void *param)
- {
- return CKYAPDUFactory_SelectCardManager(apdu);
-@@ -103,6 +110,22 @@ CKYAppletFactory_ComputeCryptOneStep(CKY
- }
-
- CKYStatus
-+CKYAppletFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgComputeECCSignature *ccs=(const CKYAppletArgComputeECCSignature *)param;
-+ return CKYAPDUFactory_ComputeECCSignatureOneStep(apdu, ccs->keyNumber,
-+ ccs->location, ccs->data, ccs->sig);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, const void *param)
-+{
-+
-+ const CKYAppletArgComputeECCKeyAgreement *ccs=(const CKYAppletArgComputeECCKeyAgreement *)param;
-+ return CKYAPDUFactory_ComputeECCKeyAgreementOneStep(apdu, ccs->keyNumber, ccs->location, ccs->publicValue, ccs->secretKey);
-+}
-+
-+CKYStatus
- CKYAppletFactory_CreatePIN(CKYAPDU *apdu, const void *param)
- {
- const CKYAppletArgCreatePIN *cps = (const CKYAppletArgCreatePIN *)param;
-@@ -245,10 +268,18 @@ CACAppletFactory_SignDecryptFinal(CKYAPD
- }
-
- CKYStatus
--CACAppletFactory_VerifyPIN(CKYAPDU *apdu, const void *param)
-+PIVAppletFactory_SignDecrypt(CKYAPDU *apdu, const void *param)
-+{
-+ const PIVAppletArgSignDecrypt *psd = (const PIVAppletArgSignDecrypt *)param;
-+ return PIVAPDUFactory_SignDecrypt(apdu, psd->chain, psd->alg, psd->key,
-+ psd->len, psd->buf);
-+}
-+
-+CKYStatus
-+P15AppletFactory_VerifyPIN(CKYAPDU *apdu, const void *param)
- {
-- const char *pin=(const char *)param;
-- return CACAPDUFactory_VerifyPIN(apdu, pin);
-+ const P15AppletArgVerifyPIN *vps = (const P15AppletArgVerifyPIN *)param;
-+ return P15APDUFactory_VerifyPIN(apdu, vps->pinRef, vps->pinVal);
- }
-
- CKYStatus
-@@ -259,6 +290,13 @@ CACAppletFactory_GetCertificate(CKYAPDU
- }
-
- CKYStatus
-+PIVAppletFactory_GetCertificate(CKYAPDU *apdu, const void *param)
-+{
-+ CKYBuffer *tag =(CKYBuffer*)param;
-+ return PIVAPDUFactory_GetData(apdu, tag, 0);
-+}
-+
-+CKYStatus
- CACAppletFactory_ReadFile(CKYAPDU *apdu, const void *param)
- {
- const CACAppletArgReadFile *rfs = (const CACAppletArgReadFile *)param;
-@@ -285,6 +323,39 @@ CKYAppletFactory_LogoutAllV0(CKYAPDU *ap
- return CKYAPDU_SetSendData(apdu, data, sizeof(data));
- }
-
-+CKYStatus
-+P15AppletFactory_ReadRecord(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgReadRecord *rrs = (const P15AppletArgReadRecord *)param;
-+ return P15APDUFactory_ReadRecord(apdu, rrs->record,
-+ rrs->short_ef, rrs->flags, rrs->size);
-+}
-+
-+CKYStatus
-+P15AppletFactory_ReadBinary(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgReadBinary *res = (const P15AppletArgReadBinary *)param;
-+ return P15APDUFactory_ReadBinary(apdu, res->offset,
-+ res->short_ef, res->flags, res->size);
-+}
-+
-+CKYStatus
-+P15AppletFactory_ManageSecurityEnvironment(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgManageSecurityEnvironment *mse =
-+ (const P15AppletArgManageSecurityEnvironment *)param;
-+ return P15APDUFactory_ManageSecurityEnvironment(apdu, mse->p1,
-+ mse->p2, mse->keyRef);
-+}
-+
-+CKYStatus
-+P15AppletFactory_PerformSecurityOperation(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgPerformSecurityOperation *pso =
-+ (const P15AppletArgPerformSecurityOperation *)param;
-+ return P15APDUFactory_PerformSecurityOperation(apdu, pso->dir, pso->chain,
-+ pso->retLen, pso->data);
-+}
- /*****************************************************************
- *
- * Generic Fill routines used by several calls in common
-@@ -325,6 +396,7 @@ CKYAppletFill_AppendBuffer(const CKYBuff
- CKYBuffer_Size(response) -2);
- }
-
-+
- CKYStatus
- CKYAppletFill_Byte(const CKYBuffer *response, CKYSize size, void *param)
- {
-@@ -725,6 +797,32 @@ CKYApplet_ComputeCryptProcess(CKYCardCon
- &ccd, nonce, 0, CKYAppletFill_Null, NULL, apduRC);
- }
-
-+/* computeECCValue returns data in the form :
-+ * len: short
-+ * data: byte[len]
-+ * This fill routine returns A buffer with a copy of data and a length of len */
-+static CKYStatus
-+ckyAppletFill_ComputeECCValueFinal(const CKYBuffer *response,
-+ CKYSize size, void *param)
-+{
-+ CKYBuffer *cbuf = (CKYBuffer *)param;
-+ CKYSize respSize = CKYBuffer_Size(response);
-+ CKYSize dataLen;
-+
-+ if (cbuf == 0) {
-+ return CKYSUCCESS; /* app didn't want the result */
-+ }
-+ /* data response code + length code */
-+ if (respSize < 4) {
-+ return CKYAPDUFAIL;
-+ }
-+ dataLen = CKYBuffer_GetShort(response, 0);
-+ if (dataLen > (respSize-4)) {
-+ return CKYAPDUFAIL;
-+ }
-+ return CKYBuffer_Replace(cbuf, 0, CKYBuffer_Data(response)+2, dataLen);
-+}
-+
- /* computeCrypt returns data in the form :
- * len: short
- * data: byte[len]
-@@ -872,6 +970,74 @@ fail:
- return ret;
- }
-
-+CKYStatus
-+CKYApplet_ComputeECCKeyAgreement(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *publicValue, CKYBuffer *sharedSecret,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret = CKYAPDUFAIL;
-+ CKYAppletArgComputeECCKeyAgreement ccd;
-+ CKYBuffer empty;
-+ CKYISOStatus status;
-+ /* Routine creates a sym key, should easily fit in one apdu */
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ ccd.keyNumber = keyNumber;
-+ ccd.location = CKY_DL_APDU;
-+
-+ if (!apduRC)
-+ apduRC = &status;
-+
-+ if (ccd.location == CKY_DL_APDU) {
-+ ccd.publicValue = publicValue;
-+ ccd.secretKey = sharedSecret;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeECCKeyAgreementOneStep, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeECCValueFinal,
-+ result, apduRC);
-+ if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
-+ return ret;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYApplet_ComputeECCSignature(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret = CKYAPDUFAIL;
-+ CKYAppletArgComputeECCSignature ccd;
-+ CKYBuffer empty;
-+ CKYISOStatus status;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ ccd.keyNumber = keyNumber;
-+
-+ /* Assume APDU, the signature can only get so big with our key sizes, ~ 130 for 521 bit key. */
-+ ccd.location = CKY_DL_APDU;
-+
-+ if (!apduRC)
-+ apduRC = &status;
-+
-+ if (ccd.location == CKY_DL_APDU) {
-+ ccd.data = data;
-+ ccd.sig = sig;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeECCSignatureOneStep, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeECCValueFinal,
-+ result, apduRC);
-+ if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
-+ return ret;
-+ }
-+
-+ }
-+
-+ return ret;
-+}
-+
- /*
- * do a CAC Sign/Decrypt
- */
-@@ -916,32 +1082,23 @@ done:
- return ret;
- }
-
-+const P15PinInfo CACPinInfo =
-+ { P15PinInitialized|P15PinNeedsPadding, P15PinUTF8, 0, 8, 8, 0, 0xff };
-+const P15PinInfo PIVPinInfo =
-+ { P15PinLocal|P15PinInitialized|P15PinNeedsPadding,
-+ P15PinUTF8, 0, 8, 8, 0, 0xff };
- /*
- * do a CAC VerifyPIN
- */
- CKYStatus
--CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin, int local,
- CKYISOStatus *apduRC)
- {
-- CKYStatus ret;
-- CKYISOStatus status;
-- if (apduRC == NULL) {
-- apduRC = &status;
-- }
--
-- ret = CKYApplet_HandleAPDU(conn,
-- CACAppletFactory_VerifyPIN, pin, NULL,
-- 0, CKYAppletFill_Null,
-- NULL, apduRC);
-- /* it's unfortunate that the same code that means 'more data to follow' for
-- * GetCertificate also means, auth failure, you only have N more attempts
-- * left in the verify PIN call */
-- if ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-- ret = CKYAPDUFAIL;
-- }
-- return ret;
-+ return P15Applet_VerifyPIN(conn, pin,
-+ local ? &PIVPinInfo: &CACPinInfo, apduRC);
- }
-
-+
- /*
- * Get a CAC Certificate
- */
-@@ -1028,6 +1185,217 @@ CACApplet_ReadFile(CKYCardConnection *co
- return ret;
- }
-
-+/*
-+ * Select a EF
-+ */
-+CKYStatus
-+P15Applet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShort(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, P15AppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15Applet_SelectRootFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShort(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15Applet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ const P15PinInfo *pinInfo, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYSize size;
-+ CKYBuffer encodedPin;
-+ P15AppletArgVerifyPIN vps;
-+
-+ CKYBuffer_InitEmpty(&encodedPin);
-+
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+
-+ size = strlen(pin);
-+ if (pinInfo->pinFlags & P15PinNeedsPadding) {
-+ if (size > pinInfo->storedLength) {
-+ size = pinInfo->storedLength;
-+ }
-+ ret=CKYBuffer_Reserve(&encodedPin, pinInfo->storedLength);
-+ if (ret != CKYSUCCESS) { goto fail; }
-+ }
-+ /* This is where we would do upcase processing for the case insensitive
-+ * flag. It's also where we would do mapping for bcd pins */
-+ ret = CKYBuffer_Replace(&encodedPin, 0, (const CKYByte *)pin, size);
-+ if (ret != CKYSUCCESS) { goto fail; }
-+ if (pinInfo->pinFlags & P15PinNeedsPadding) {
-+ int i;
-+ int padSize = pinInfo->storedLength - size;
-+ for (i=0; i < padSize; i++) {
-+ CKYBuffer_AppendChar(&encodedPin, pinInfo->padChar);
-+ }
-+ }
-+
-+ vps.pinRef = pinInfo->pinRef |
-+ ((pinInfo->pinFlags & P15PinLocal) ? ISO_LOGIN_LOCAL : ISO_LOGIN_GLOBAL);
-+ vps.pinVal = &encodedPin;
-+ ret = CKYApplet_HandleAPDU(conn, P15AppletFactory_VerifyPIN, &vps, NULL,
-+ 0, CKYAppletFill_Null,
-+ NULL, apduRC);
-+ /* it's unfortunate that the same code that means 'more data to follow' for
-+ * GetCertificate also means, auth failure, you only have N more attempts
-+ * left in the verify PIN call */
-+ if ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-+ ret = CKYAPDUFAIL;
-+ }
-+fail:
-+ CKYBuffer_FreeData(&encodedPin);
-+ return ret;
-+}
-+
-+
-+/*
-+ * Read Record
-+ */
-+CKYStatus
-+P15Applet_ReadRecord(CKYCardConnection *conn, CKYByte record, CKYByte short_ef,
-+ CKYByte flags, CKYByte size, CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ P15AppletArgReadRecord rrd;
-+
-+ rrd.record = record;
-+ rrd.short_ef = short_ef;
-+ rrd.flags = flags;
-+ rrd.size = size;
-+ return CKYApplet_HandleAPDU(conn, P15AppletFactory_ReadRecord, &rrd, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_ReplaceBuffer, data, apduRC);
-+}
-+
-+static CKYStatus
-+P15Applet_ManageSecurityEnvironment(CKYCardConnection *conn, CKYByte key,
-+ CKYByte direction, CKYByte p1,
-+ CKYISOStatus *apduRC)
-+{
-+ P15AppletArgManageSecurityEnvironment mse;
-+
-+ mse.p1 = p1; /* this appears to be where most cards disagree */
-+ mse.p2 = (direction == CKY_DIR_DECRYPT) ? ISO_MSE_KEA : ISO_MSE_SIGN;
-+ mse.keyRef = key; /* should be CKYBuffer in the future? */
-+ return CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_ManageSecurityEnvironment, &mse, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+P15Applet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, CKYByte direction,
-+ const CKYBuffer *data, CKYBuffer *result, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ P15AppletArgPerformSecurityOperation pso;
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+ int length = dataSize;
-+ int appendLength = length;
-+ int hasPad = 0;
-+
-+ /* Hack, lie and say we are always doing encipherment */
-+ direction = CKY_DIR_DECRYPT;
-+ CKYBuffer_Resize(result,0);
-+ /*
-+ * first set the security environment
-+ */
-+ ret = P15Applet_ManageSecurityEnvironment(conn, key, direction,
-+ ISO_MSE_SET|ISO_MSE_QUAL_COMPUTE, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+
-+ pso.data = &tmp;
-+ pso.dir = direction;
-+ if (direction == CKY_DIR_DECRYPT) {
-+ length++;
-+ CKYBuffer_AppendChar(&tmp, 0x00); /* pad byte */
-+ hasPad = 1;
-+ }
-+ if (CKYCardConnection_GetProtocol(conn) == SCARD_PROTOCOL_T0) {
-+ ret = CKYBuffer_Reserve(&tmp, CKY_MAX_WRITE_CHUNK_SIZE);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ for(offset = 0; length > CKY_MAX_WRITE_CHUNK_SIZE;
-+ hasPad = 0,
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE,
-+ length -= CKY_MAX_WRITE_CHUNK_SIZE) {
-+ pso.chain = 1;
-+ pso.retLen = 0;
-+ CKYBuffer_AppendBuffer(&tmp, data, offset,
-+ hasPad ? (CKY_MAX_WRITE_CHUNK_SIZE-1) : CKY_MAX_WRITE_CHUNK_SIZE);
-+ ret = CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_PerformSecurityOperation, &pso, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_Resize(&tmp, 0);
-+ }
-+ appendLength = length;
-+ } else {
-+ ret = CKYBuffer_Reserve(&tmp, length);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ }
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, appendLength);
-+ pso.chain = 0;
-+ pso.retLen = dataSize;
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_PerformSecurityOperation, &pso, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_ReplaceBuffer, result, apduRC);
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
-+ return ret;
-+}
-+
-+/*
-+ * Read Binary
-+ */
-+CKYStatus
-+P15Applet_ReadBinary(CKYCardConnection *conn, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte size,
-+ CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ P15AppletArgReadBinary red;
-+
-+ red.offset = offset;
-+ red.short_ef = short_ef;
-+ red.flags = flags;
-+ red.size = size;
-+ return CKYApplet_HandleAPDU(conn, P15AppletFactory_ReadBinary, &red, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, data, apduRC);
-+}
-+
- CKYStatus
- CACApplet_GetCertificateFirst(CKYCardConnection *conn, CKYBuffer *cert,
- CKYSize *nextSize, CKYISOStatus *apduRC)
-@@ -1078,6 +1446,278 @@ CACApplet_GetCertificateAppend(CKYCardCo
- return ret;
- }
-
-+/* Select the PIV applet */
-+static CKYByte pivAid[] = {0xa0, 0x00, 0x00, 0x03, 0x08, 0x00, 0x00,
-+ 0x10, 0x00};
-+CKYStatus
-+PIVApplet_Select(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer PIV_Applet_AID,return_AID;
-+
-+ CKYBuffer_InitEmpty(&return_AID);
-+ CKYBuffer_InitFromData(&PIV_Applet_AID, pivAid, sizeof(pivAid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile,
-+ &PIV_Applet_AID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer,
-+ &return_AID, apduRC);
-+ /* Some cards return OK, but don't switch to our applet */
-+ /* PIV has a well defined return for it's select, check to see if we have
-+ * a PIV card here */
-+ if (CKYBuffer_GetChar(&return_AID,0) != 0x61) {
-+ /* not an application property template, so not a PIV. We could
-+ * check that the aid tag (0x4f) and theallocation authority tag (0x79)
-+ * are present, but what we are really avoiding is broken cards that
-+ * lie about being able to switch to a particular applet, so the first
-+ * tag should be sufficient */
-+ ret = CKYAPDUFAIL; /* what we should have gotten */
-+ }
-+ CKYBuffer_FreeData(&PIV_Applet_AID);
-+ CKYBuffer_FreeData(&return_AID);
-+ return ret;
-+}
-+
-+/*
-+ * Get a PIV Certificate
-+ */
-+CKYStatus
-+PIVApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert, int tag,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYBuffer tagBuf;
-+
-+ CKYBuffer_InitEmpty(&tagBuf);
-+ CKYBuffer_Reserve(&tagBuf,4); /* can be up to 4 bytes */
-+
-+ CKYBuffer_Resize(cert,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+ if (tag >= 0x01000000) {
-+ ret = CKYBuffer_AppendChar(&tagBuf, (tag >> 24) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ if (tag >= 0x010000) {
-+ ret = CKYBuffer_AppendChar(&tagBuf, (tag >> 16) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ if (tag >= 0x0100) {
-+ ret =CKYBuffer_AppendChar(&tagBuf, (tag >> 8) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ ret = CKYBuffer_AppendChar(&tagBuf, tag & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ PIVAppletFactory_GetCertificate, &tagBuf, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+loser:
-+ CKYBuffer_FreeData(&tagBuf);
-+
-+ return ret;
-+}
-+
-+
-+/*
-+ * record the next ber tag and length. NOTE: this is a state machine.
-+ * we can handle the case where we are passed the data just one byte
-+ * at a time.
-+ */
-+static CKYStatus
-+pivUnwrap(const CKYBuffer *buf, CKYOffset *offset,
-+ CKYSize *dataSize, PIVUnwrapState *unwrap)
-+{
-+ if (unwrap->tag == 0) {
-+ unwrap->tag = CKYBuffer_GetChar(buf, *offset);
-+ if (unwrap->tag == 0) unwrap->tag = 0xff;
-+ (*offset)++;
-+ (*dataSize)--;
-+ }
-+ if (*dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ if (unwrap->length_bytes != 0) {
-+ int len;
-+ if (unwrap->length_bytes == -1) {
-+ len = CKYBuffer_GetChar(buf, *offset);
-+ unwrap->length_bytes = 0;
-+ unwrap->length = len;
-+ (*offset)++;
-+ (*dataSize)--;
-+ if (len & 0x80) {
-+ unwrap->length = 0;
-+ unwrap->length_bytes = len & 0x7f;
-+ }
-+ }
-+ while ((*dataSize != 0) && (unwrap->length_bytes != 0)) {
-+ len = CKYBuffer_GetChar(buf, *offset);
-+ (*offset) ++;
-+ (*dataSize) --;
-+ unwrap->length = ((unwrap->length) << 8 | len);
-+ unwrap->length_bytes--;
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+/*
-+ * Remove the BER wrapping first...
-+ */
-+static CKYStatus
-+pivAppletFill_AppendUnwrapBuffer(const CKYBuffer *response,
-+ CKYSize size, void *param)
-+{
-+ PIVAppletRespSignDecrypt *prsd = (PIVAppletRespSignDecrypt *)param;
-+ CKYBuffer *buf = prsd->buf;
-+ CKYSize dataSize = CKYBuffer_Size(response);
-+ CKYOffset offset = 0;
-+
-+ if (dataSize <= 2) {
-+ return CKYSUCCESS;
-+ }
-+ dataSize -= 2;
-+ /* remove the first tag */
-+ (void) pivUnwrap(response, &offset, &dataSize, &prsd->tag_1);
-+ if (dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ /* remove the second tag */
-+ (void) pivUnwrap(response, &offset, &dataSize, &prsd->tag_2);
-+ if (dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ /* the rest is real data */
-+ return CKYBuffer_AppendData(buf, CKYBuffer_Data(response) + offset,
-+ dataSize);
-+}
-+
-+static CKYStatus
-+piv_wrapEncodeLength(CKYBuffer *buf, int length, int ber_len)
-+{
-+ if (ber_len== 1) {
-+ CKYBuffer_AppendChar(buf,length);
-+ } else {
-+ ber_len--;
-+ CKYBuffer_AppendChar(buf,0x80+ber_len);
-+ while(ber_len--) {
-+ CKYBuffer_AppendChar(buf,(length >> (8*ber_len)) & 0xff);
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+/*
-+ * do a PIV Sign/Decrypt
-+ */
-+CKYStatus
-+PIVApplet_SignDecrypt(CKYCardConnection *conn, CKYByte key, unsigned int keySize, int derive,
-+ const CKYBuffer *data, CKYBuffer *result, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYSize outputSize = keySize;
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+ CKYByte alg;
-+ int ber_len_1;
-+ int ber_len_2;
-+ int length;
-+ PIVAppletArgSignDecrypt pasd;
-+ PIVAppletRespSignDecrypt prsd;
-+
-+ /* PIV only defines RSA 1024 and 2048, ECC 256 and ECC 384!!! */
-+ if (keySize == 128) { /* 1024 bit == 128 bytes */
-+ ber_len_2 = 2;
-+ ber_len_1 = 2;
-+ alg = 0x6;
-+ } else if (keySize == 256) { /* 2048 bits == 256 bytes */
-+ ber_len_2 = 3;
-+ ber_len_1 = 3;
-+ alg = 0x7;
-+ } else if (keySize == 32) { /* 256 bits = 32 bytes */
-+ ber_len_2 = 1;
-+ ber_len_1 = 1;
-+ alg = 0x11;
-+ if (!derive) outputSize = keySize*2;
-+ } else if (keySize == 48) { /* 384 bits = 48 bytes */
-+ ber_len_2 = 1;
-+ ber_len_1 = 1;
-+ alg = 0x14;
-+ if (!derive) outputSize = keySize*2;
-+ } else {
-+ return CKYINVALIDARGS;
-+ }
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+ ret = CKYBuffer_Reserve(&tmp, CKY_MAX_WRITE_CHUNK_SIZE);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_AppendChar(&tmp,0x7c);
-+ piv_wrapEncodeLength(&tmp,dataSize + ber_len_2 + 3,ber_len_1);
-+ CKYBuffer_AppendChar(&tmp,0x82);
-+ CKYBuffer_AppendChar(&tmp,0x0);
-+ CKYBuffer_AppendChar(&tmp, derive ? 0x85 : 0x81);
-+ piv_wrapEncodeLength(&tmp,dataSize,ber_len_2);
-+
-+ /* now length == header length from here to the end*/
-+ length = CKYBuffer_Size(&tmp);
-+
-+ if (length + dataSize > CKY_MAX_WRITE_CHUNK_SIZE) {
-+ CKYBuffer_AppendBuffer(&tmp, data, 0, CKY_MAX_WRITE_CHUNK_SIZE-length);
-+ } else {
-+ CKYBuffer_AppendBuffer(&tmp, data, 0, dataSize);
-+ }
-+
-+ prsd.tag_1.tag = 0;
-+ prsd.tag_1.length_bytes = -1;
-+ prsd.tag_1.length = 0;
-+ prsd.tag_2.tag = 0;
-+ prsd.tag_2.length_bytes = -1;
-+ prsd.tag_2.length = 0;
-+ prsd.buf = result;
-+ pasd.alg = alg;
-+ pasd.key = key;
-+ pasd.buf = &tmp;
-+
-+ CKYBuffer_Resize(result,0);
-+ for(offset = -length; (dataSize-offset) > CKY_MAX_WRITE_CHUNK_SIZE; ) {
-+ pasd.chain = 1;
-+ pasd.len = 0;
-+ ret = CKYApplet_HandleAPDU(conn, PIVAppletFactory_SignDecrypt,
-+ &pasd, NULL, CKY_SIZE_UNKNOWN,
-+ pivAppletFill_AppendUnwrapBuffer,
-+ &prsd, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_Resize(&tmp,0);
-+ /* increment before we append the next tmp buffer */
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE;
-+ CKYBuffer_AppendBuffer(&tmp, data, offset,
-+ MIN(dataSize-offset, CKY_MAX_WRITE_CHUNK_SIZE));
-+ }
-+
-+ pasd.chain = 0;
-+ pasd.len = outputSize;
-+
-+ ret = CKYApplet_HandleAPDU(conn, PIVAppletFactory_SignDecrypt,
-+ &pasd, NULL, CKY_SIZE_UNKNOWN,
-+ pivAppletFill_AppendUnwrapBuffer,
-+ &prsd, apduRC);
-+
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(result) != outputSize)) {
-+ /* RSA returns the same data size as input, didn't happen, so
-+ * something is wrong. */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
-+ return ret;
-+}
-
- /*
- * PIN cluster
-@@ -1223,6 +1863,7 @@ CKYApplet_ReadObjectFull(CKYCardConnecti
- return ret;
- }
-
-+
- /*
- * Write Object
- * This makes multiple APDU calls to write the entire object.
-diff -up ./src/libckyapplet/cky_applet.h.coolkey-update ./src/libckyapplet/cky_applet.h
---- ./src/libckyapplet/cky_applet.h.coolkey-update 2016-01-19 18:02:04.200645090 -0800
-+++ ./src/libckyapplet/cky_applet.h 2016-01-19 18:02:11.013589143 -0800
-@@ -43,6 +43,8 @@ typedef unsigned short CKYISOStatus; /*
- #define CKYISO_MORE_MASK 0xff00 /* More data mask */
- #define CKYISO_MORE 0x6300 /* More data available */
- #define CKYISO_DATA_INVALID 0x6984
-+#define CKYISO_CONDITION_NOT_SATISFIED 0x6985 /* AKA not logged in (CAC)*/
-+#define CKYISO_SECURITY_NOT_SATISFIED 0x6982 /* AKA not logged in (PIV)*/
- /* Applet Defined Return codes */
- #define CKYISO_NO_MEMORY_LEFT 0x9c01 /* There have been memory
- * problems on the card */
-@@ -78,6 +80,7 @@ typedef unsigned short CKYISOStatus; /*
-
- #define CAC_TAG_CARDURL 0xf3
- #define CAC_TAG_CERTIFICATE 0x70
-+#define CAC_TAG_CERTINFO 0x71
- #define CAC_TLV_APP_PKI 0x04
-
- /*
-@@ -201,6 +204,7 @@ typedef struct _CKYAppletArgReadObject {
- CKYByte size;
- } CKYAppletArgReadObject;
-
-+
- typedef struct _CKYAppletArgWriteObject {
- unsigned long objectID;
- CKYOffset offset;
-@@ -218,12 +222,80 @@ typedef struct _CKYAppletArgComputeCrypt
- const CKYBuffer *sig;
- } CKYAppletArgComputeCrypt;
-
-+typedef struct _CKYAppletArgComputeECCSignature {
-+ CKYByte keyNumber;
-+ CKYByte location;
-+ const CKYBuffer *data;
-+ const CKYBuffer *sig;
-+} CKYAppletArgComputeECCSignature;
-+
-+typedef struct _CKYAppletArgComputeECCKeyAgreement {
-+ CKYByte keyNumber;
-+ CKYByte location;
-+ const CKYBuffer *publicValue;
-+ const CKYBuffer *secretKey;
-+} CKYAppletArgComputeECCKeyAgreement;
-+
-+
- typedef struct _CACAppletArgReadFile {
- CKYByte type;
- CKYByte count;
- unsigned short offset;
- } CACAppletArgReadFile;
-
-+typedef struct _PIVAppletArgSignDecrypt {
-+ CKYByte alg;
-+ CKYByte key;
-+ CKYByte chain;
-+ CKYSize len;
-+ CKYBuffer *buf;
-+} PIVAppletArgSignDecrypt;
-+
-+typedef struct _pivUnwrapState {
-+ CKYByte tag;
-+ CKYByte length;
-+ int length_bytes;
-+} PIVUnwrapState;
-+
-+typedef struct _PIVAppletRespSignDecrypt {
-+ PIVUnwrapState tag_1;
-+ PIVUnwrapState tag_2;
-+ CKYBuffer *buf;
-+} PIVAppletRespSignDecrypt;
-+
-+typedef struct _P15AppletArgReadRecord {
-+ CKYByte record;
-+ CKYByte short_ef;
-+ CKYByte flags;
-+ CKYByte size;
-+} P15AppletArgReadRecord;
-+
-+typedef struct _P15AppletArgReadBinary {
-+ unsigned short offset;
-+ CKYByte short_ef;
-+ CKYByte flags;
-+ CKYByte size;
-+} P15AppletArgReadBinary;
-+
-+typedef struct _P15AppletArgVerifyPIN {
-+ const CKYBuffer *pinVal;
-+ CKYByte pinRef;
-+} P15AppletArgVerifyPIN;
-+
-+typedef struct _P15AppletArgManageSecurityEnvironment {
-+ CKYByte p1;
-+ CKYByte p2;
-+ CKYByte keyRef;
-+}
-+ P15AppletArgManageSecurityEnvironment;
-+
-+typedef struct _P15AppletArgPerformSecurityOperation {
-+ CKYByte dir;
-+ int chain;
-+ CKYSize retLen;
-+ const CKYBuffer *data;
-+} P15AppletArgPerformSecurityOperation;
-+
- /* fills in an APDU from a structure -- form of all the generic factories*/
- typedef CKYStatus (*CKYAppletFactory)(CKYAPDU *apdu, const void *param);
- /* fills in an a structure from a response -- form of all the fill structures*/
-@@ -335,7 +407,6 @@ CKYStatus CKYAppletFill_AppendBuffer(con
- /* Single value fills: Byte, Short, & Long */
- /* param == CKYByte * */
- CKYStatus CKYAppletFill_Byte(const CKYBuffer *response, CKYSize size, void *param);
--/* param == CKYByte * */
- CKYStatus CKYAppletFill_Short(const CKYBuffer *response, CKYSize size, void *param);
- CKYStatus CKYAppletFill_Long(const CKYBuffer *response, CKYSize size, void *param);
-
-@@ -361,7 +432,7 @@ CKYBool CKYApplet_VerifyResponse(const C
- * Sends the ADPU to the card through the connection conn.
- * Checks that the response was valid (returning the responce code in apduRC.
- * Formats the response data into fillArg with fillFunc
-- * nonce and apduRC can be NULL (no nonce is added, not status returned
-+ * nonce and apduRC can be NULL (no nonce is added, no status returned
- * legal values for afArg are depened on afFunc.
- * legal values for fillArg are depened on fillFunc.
- */
-@@ -377,7 +448,7 @@ CKYStatus CKYApplet_HandleAPDU(CKYCardCo
- * into function calls, with input and output parameters.
- * The application is still responsible for
- * 1) creating a connection to the card,
-- * 2) Getting a tranaction long, then
-+ * 2) Getting a transaction lock, then
- * 3) selecting the appropriate applet (or Card manager).
- * Except for those calls that have been noted, the appropriate applet
- * is the CoolKey applet.
-@@ -477,6 +548,7 @@ CKYStatus CACApplet_ReadFile(CKYCardConn
- CKYStatus CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
- CKYISOStatus *apduRC);
-
-+
- /* must happen with PKI applet selected */
- CKYStatus CACApplet_SignDecrypt(CKYCardConnection *conn, const CKYBuffer *data,
- CKYBuffer *result, CKYISOStatus *apduRC);
-@@ -490,8 +562,37 @@ CKYStatus CACApplet_GetCertificateAppend
- CKYISOStatus *apduRC);
-
- /*CKYStatus CACApplet_GetProperties(); */
--CKYStatus CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-- CKYISOStatus *apduRC);
-+CKYStatus CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ int local, CKYISOStatus *apduRC);
-+
-+/* Select a PIV applet */
-+CKYStatus PIVApplet_Select(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+
-+CKYStatus PIVApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert,
-+ int tag, CKYISOStatus *apduRC);
-+CKYStatus PIVApplet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, int derive,
-+ const CKYBuffer *data, CKYBuffer *result,
-+ CKYISOStatus *apduRC);
-+
-+/* PKCS Commands 15 */
-+CKYStatus P15Applet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_SelectRootFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_ReadRecord(CKYCardConnection *conn, CKYByte record,
-+ CKYByte short_ef, CKYByte flags, CKYByte size, CKYBuffer *data,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_ReadBinary(CKYCardConnection *conn, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte size, CKYBuffer *data,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ const P15PinInfo *pinInfo, CKYISOStatus *apduRC);
-+
-+CKYStatus P15Applet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, CKYByte direction,
-+ const CKYBuffer *data, CKYBuffer *result,
-+ CKYISOStatus *apduRC);
-
- /*
- * There are 3 read commands:
-@@ -553,6 +654,18 @@ CKYStatus CKYApplet_GetIssuerInfo(CKYCar
- CKYStatus CKYApplet_GetBuiltinACL(CKYCardConnection *conn,
- CKYAppletRespGetBuiltinACL *gba, CKYISOStatus *apduRC);
-
-+/** ECC commands
-+ * * */
-+
-+CKYStatus CKYApplet_ComputeECCSignature(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+
-+CKYStatus
-+CKYApplet_ComputeECCKeyAgreement(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *publicValue, CKYBuffer *sharedSecret,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+
-
- /*
- * deprecates 0.x functions
-diff -up ./src/libckyapplet/cky_base.c.coolkey-update ./src/libckyapplet/cky_base.c
---- ./src/libckyapplet/cky_base.c.coolkey-update 2016-01-19 18:02:38.270365312 -0800
-+++ ./src/libckyapplet/cky_base.c 2016-01-19 18:02:51.042260431 -0800
-@@ -41,6 +41,7 @@ ckyBuffer_initBuffer(CKYBuffer *buf)
- buf->data = NULL;
- buf->size = 0;
- buf->len = 0;
-+ buf->reserved = NULL; /* make coverity happy */
- }
-
- /*
-@@ -573,6 +574,7 @@ CKYAPDU_Init(CKYAPDU *apdu)
- assert(sizeof(CKYAPDU) == sizeof(CKYAPDUPublic));
- #endif
- ckyBuffer_initBuffer(&apdu->apduBuf);
-+ apdu->reserved = NULL;
- return CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_MIN_LEN);
- }
-
-@@ -583,6 +585,7 @@ CKYAPDU_InitFromData(CKYAPDU *apdu, cons
- assert(sizeof(CKYAPDU) == sizeof(CKYAPDUPublic));
- #endif
- ckyBuffer_initBuffer(&apdu->apduBuf);
-+ apdu->reserved = NULL;
- if (len > CKYAPDU_MAX_DATA_LEN) {
- return CKYDATATOOLONG;
- }
-@@ -648,21 +651,38 @@ CKYStatus
- CKYAPDU_SetSendData(CKYAPDU *apdu, const CKYByte *data, CKYSize len)
- {
- CKYStatus ret;
-+ CKYOffset offset = 0;
-
-- if (len > CKYAPDU_MAX_DATA_LEN) {
-- return CKYDATATOOLONG;
-- }
-+ /* Encode with T1 if necessary */
-
-- ret = CKYBuffer_Resize(&apdu->apduBuf, len + CKYAPDU_HEADER_LEN);
-- if (ret != CKYSUCCESS) {
-- return ret;
-+ if (len < CKYAPDU_MAX_DATA_LEN) {
-+ offset = 0;
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, len+offset+CKYAPDU_HEADER_LEN);
-+ if (ret != CKYSUCCESS ) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) len);
-+ } else if (len < CKYAPDU_MAX_T1_DATA_LEN) {
-+ offset = 2;
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, len+offset+CKYAPDU_HEADER_LEN);
-+ if (ret != CKYSUCCESS ) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) 0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetShort(&apdu->apduBuf,CKY_LC_OFFSET+1,
-+ (unsigned short)len);
-+ } else {
-+ return CKYDATATOOLONG;
- }
-- ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET,
-- len == CKYAPDU_MAX_DATA_LEN ? 0: (CKYByte) len);
-+
- if (ret != CKYSUCCESS) {
- return ret;
- }
-- return CKYBuffer_Replace(&apdu->apduBuf, CKYAPDU_HEADER_LEN, data, len);
-+ return CKYBuffer_Replace(&apdu->apduBuf,
-+ CKYAPDU_HEADER_LEN + offset , data, len);
- }
-
- CKYStatus
-@@ -682,15 +702,15 @@ CKYAPDU_AppendSendData(CKYAPDU *apdu, co
- }
-
- dataLen = CKYBuffer_Size(&apdu->apduBuf) + len - CKYAPDU_HEADER_LEN;
-- if (dataLen > CKYAPDU_MAX_DATA_LEN) {
-+ /* only handles T0 encoding, not T1 encoding */
-+ if (dataLen >= CKYAPDU_MAX_DATA_LEN) {
- return CKYDATATOOLONG;
- }
- ret = CKYBuffer_AppendData(&apdu->apduBuf, data, len);
- if (ret != CKYSUCCESS) {
- return ret;
- }
-- return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET,
-- dataLen == CKYAPDU_MAX_DATA_LEN ? 0 : (CKYByte) dataLen);
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) dataLen);
- }
-
- CKYStatus
-@@ -710,8 +730,104 @@ CKYAPDU_SetReceiveLen(CKYAPDU *apdu, CKY
- return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LE_OFFSET, recvlen);
- }
-
-+CKYStatus
-+CKYAPDU_SetShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen)
-+{
-+ CKYStatus ret;
-+
-+ if (recvlen <= CKYAPDU_MAX_DATA_LEN) {
-+ return CKYAPDU_SetReceiveLen(apdu, (CKYByte)(recvlen & 0xff));
-+ }
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_HEADER_LEN+2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LE_OFFSET, 0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ return CKYBuffer_SetShort(&apdu->apduBuf, CKY_LE_OFFSET+1, recvlen);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetReceiveLength(CKYAPDU *apdu, CKYSize recvlen)
-+{
-+ if (recvlen <= CKYAPDU_MAX_T1_DATA_LEN) {
-+ return CKYAPDU_SetShortReceiveLen(apdu, (unsigned short)
-+ (recvlen & 0xffff));
-+ }
-+ return CKYDATATOOLONG;
-+}
-+
-+/*
-+ * Append Le, If Le=0, treat it as 256 (CKYAPD_MAX_DATA_LEN)
-+ */
-+CKYStatus
-+CKYAPDU_AppendReceiveLen(CKYAPDU *apdu, CKYByte recvlen)
-+{
-+ /* If we already have a data buffer, make sure that we aren't already
-+ * using T1 encoding */
-+ if (CKYBuffer_Size(&apdu->apduBuf) > CKYAPDU_MIN_LEN) {
-+ if (CKYBuffer_GetChar(&apdu->apduBuf, CKY_LC_OFFSET) == 0) {
-+ /* we are using T1 encoding, use AppendShort*/
-+ return CKYBuffer_AppendShort(&apdu->apduBuf,
-+ recvlen ? (unsigned short) recvlen: CKYAPDU_MAX_DATA_LEN);
-+ }
-+ }
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, recvlen);
-+}
-+
-+/*
-+ * Append a short Le. If Le be encoded with just T0, do so. If Le=0 treat
-+ * it as 65536 (CKYAPDU_MAX_T1_DATA_LEN)
-+ */
-+CKYStatus
-+CKYAPDU_AppendShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen)
-+{
-+ CKYStatus ret;
-+ /* If we already have a data buffer, it's encoding affects ours */
-+ if (CKYBuffer_Size(&apdu->apduBuf) > CKYAPDU_MIN_LEN) {
-+ /* CKY_LC_OFFSET == 0 means T1, otherwise it's T0 */
-+ if (CKYBuffer_GetChar(&apdu->apduBuf, CKY_LC_OFFSET) != 0) {
-+ /* remember 0 is 65536 here */
-+ if ((recvlen == 0) || (recvlen > CKYAPDU_MAX_DATA_LEN)) {
-+ /* we can't a encode T1 receive length if we already have a
-+ * T0 encoded buffer data */
-+ return CKYDATATOOLONG;
-+ }
-+ /* T0 encoding */
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)recvlen&0xff);
-+ }
-+ /* T1 encoding */
-+ return CKYBuffer_AppendShort(&apdu->apduBuf, recvlen);
-+ }
-+ /* if length fits in a bit and we aren't forced into T1 encoding, use
-+ * T0 */
-+ if ((recvlen != 0) && (recvlen <= CKYAPDU_MAX_DATA_LEN)) {
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)recvlen&0xff);
-+ }
-+ /* write the T1 encoding marker */
-+ ret = CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ /* T1 encoded length */
-+ return CKYBuffer_AppendShort(&apdu->apduBuf, recvlen);
-+}
-+
-+CKYStatus
-+CKYAPDU_AppendReceiveLength(CKYAPDU *apdu, CKYSize recvlen)
-+{
-+ if (recvlen > CKYAPDU_MAX_T1_DATA_LEN) {
-+ return CKYDATATOOLONG;
-+ }
-+ return CKYAPDU_AppendShortReceiveLen(apdu,
-+ (unsigned short)(recvlen & 0xffff));
-+}
-+
-+
- void
--CKY_SetName(char *p)
-+CKY_SetName(const char *p)
- {
- }
-
-diff -up ./src/libckyapplet/cky_base.h.coolkey-update ./src/libckyapplet/cky_base.h
---- ./src/libckyapplet/cky_base.h.coolkey-update 2016-01-19 18:03:10.571100060 -0800
-+++ ./src/libckyapplet/cky_base.h 2016-01-19 18:03:23.866990876 -0800
-@@ -32,6 +32,8 @@ typedef unsigned char CKYByte;
- /* Bool type */
- typedef unsigned char CKYBool;
-
-+typedef unsigned long CKYBitFlags;
-+
- #define CKYBUFFER_PUBLIC \
- unsigned long reserved1;\
- unsigned long reserved2;\
-@@ -93,6 +95,8 @@ typedef enum {
- * (command) sent. ADPUIOStatus has more info on
- * why the APDU failed */
- CKYINVALIDARGS, /* Caller passed in bad args */
-+ CKYINVALIDDATA, /* Data supplied was invalid */
-+ CKYUNSUPPORTED, /* Requested Operation or feature is not supported */
- } CKYStatus;
-
- /*
-@@ -107,12 +111,56 @@ typedef enum {
- #define CKY_LE_OFFSET 4
-
- #define CKYAPDU_MAX_DATA_LEN 256
-+#define CKYAPDU_MAX_T1_DATA_LEN 65536
- #define CKYAPDU_MIN_LEN 4
- #define CKYAPDU_HEADER_LEN 5
- #define CKYAPDU_MAX_LEN (CKYAPDU_HEADER_LEN+CKYAPDU_MAX_DATA_LEN)
- #define CKY_MAX_ATR_LEN 32
- #define CKY_OUTRAGEOUS_MALLOC_SIZE (1024*1024)
-
-+#define P15FlagsPrivate 0x00000001
-+#define P15FlagsModifiable 0x00000002
-+
-+#define P15UsageEncrypt 0x00000001
-+#define P15UsageDecrypt 0x00000002
-+#define P15UsageSign 0x00000004
-+#define P15UsageSignRecover 0x00000008
-+#define P15UsageWrap 0x00000010
-+#define P15UsageUnwrap 0x00000020
-+#define P15UsageVerify 0x00000040
-+#define P15UsageVerifyRecover 0x00000080
-+#define P15UsageDerive 0x00000100
-+#define P15UsageNonRepudiation 0x00000200
-+
-+#define P15AccessSensitive 0x00000001
-+#define P15AccessExtractable 0x00000002
-+#define P15AccessAlwaysSenstive 0x00000004
-+#define P15AccessNeverExtractable 0x00000008
-+#define P15AccessLocal 0x00000010
-+
-+#define P15PinCaseSensitive 0x00000001
-+#define P15PinLocal 0x00000002
-+#define P15PinChangeDisabled 0x00000004
-+#define P15PinUnblockDisabled 0x00000008
-+#define P15PinInitialized 0x00000010
-+#define P15PinNeedsPadding 0x00000020
-+#define P15PinUnblockingPin 0x00000040
-+#define P15PinSOPin 0x00000080
-+#define P15PinDisableAllowed 0x00000100
-+
-+typedef enum {P15PinBCD=0, P15PinASCIINum=1, P15PinUTF8=2} P15PinType;
-+
-+typedef struct _P15PinInfo {
-+ CKYBitFlags pinFlags;
-+ P15PinType pinType;
-+ CKYByte minLength;
-+ CKYByte storedLength;
-+ unsigned long maxLength;
-+ CKYByte pinRef;
-+ CKYByte padChar;
-+} P15PinInfo;
-+
-+
- /*
- * allow direct inclusion in C++ files
- */
-@@ -278,9 +326,14 @@ CKYStatus CKYAPDU_AppendSendDataBuffer(C
- /* set Le in the APDU header to the amount of bytes expected to be
- * returned. */
- CKYStatus CKYAPDU_SetReceiveLen(CKYAPDU *apdu, CKYByte recvlen);
-+CKYStatus CKYAPDU_SetShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen);
-+CKYStatus CKYAPDU_SetReceiveLength(CKYAPDU *apdu, CKYSize recvlen);
-+CKYStatus CKYAPDU_AppendReceiveLen(CKYAPDU *apdu, CKYByte recvlen);
-+CKYStatus CKYAPDU_AppendShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen);
-+CKYStatus CKYAPDU_AppendReceiveLength(CKYAPDU *apdu, CKYSize recvlen);
-
- /* set the parent loadmodule name */
--void CKY_SetName(char *name);
-+void CKY_SetName(const char *name);
-
- CKY_END_PROTOS
-
-diff -up ./src/libckyapplet/cky_card.c.coolkey-update ./src/libckyapplet/cky_card.c
---- ./src/libckyapplet/cky_card.c.coolkey-update 2016-01-19 18:03:46.210807391 -0800
-+++ ./src/libckyapplet/cky_card.c 2016-01-19 18:03:59.217700579 -0800
-@@ -27,6 +27,7 @@
-
- #ifndef WINAPI
- #define WINAPI
-+typedef SCARD_READERSTATE *LPSCARD_READERSTATE;
- #endif
-
- #ifndef SCARD_E_NO_READERS_AVAILABLE
-@@ -843,6 +844,11 @@ CKYCardContext_WaitForStatusChange(CKYCa
- rv = ctx->scard->SCardGetStatusChange(ctx->context, timeout,
- readers, readerCount);
- if (rv != SCARD_S_SUCCESS) {
-+ if ((rv == SCARD_E_NO_SERVICE) || (rv == SCARD_E_SERVICE_STOPPED)) {
-+ /* if we were stopped, don't reuse the old context,
-+ * pcsc-lite hangs */
-+ ckyCardContext_release(ctx);
-+ }
- ctx->lastError = rv;
- return CKYSCARDERR;
- }
-@@ -904,6 +910,7 @@ ckyCardConnection_init(CKYCardConnection
- conn->protocol = SCARD_PROTOCOL_T0;
- }
-
-+
- CKYCardConnection *
- CKYCardConnection_Create(const CKYCardContext *ctx)
- {
-@@ -978,6 +985,12 @@ CKYCardConnection_IsConnected(const CKYC
- return (conn->cardHandle != 0);
- }
-
-+unsigned long
-+CKYCardConnection_GetProtocol(const CKYCardConnection *conn)
-+{
-+ return conn->protocol;
-+}
-+
- CKYStatus
- ckyCardConnection_reconnectRaw(CKYCardConnection *conn, unsigned long init)
- {
-@@ -990,6 +1003,7 @@ ckyCardConnection_reconnectRaw(CKYCardCo
- conn->lastError = rv;
- return CKYSCARDERR;
- }
-+ conn->protocol = protocol;
- return CKYSUCCESS;
- }
-
-@@ -1071,25 +1085,39 @@ CKYCardConnection_ExchangeAPDU(CKYCardCo
- CKYBuffer *response)
- {
- CKYStatus ret;
-+ CKYBuffer getResponse;
-+ CKYSize size = 0;
-
- ret = CKYCardConnection_TransmitAPDU(conn, apdu, response);
- if (ret != CKYSUCCESS) {
- return ret;
- }
-+ CKYBuffer_InitEmpty(&getResponse);
-
-- if (CKYBuffer_Size(response) == 2 && CKYBuffer_GetChar(response,0) == 0x61) {
-+ /* automatically handle the response data protocol */
-+ while ((ret == CKYSUCCESS) &&
-+ (size = CKYBuffer_Size(response)) >= 2 &&
-+ (CKYBuffer_GetChar(response,size-2) == 0x61)) {
- /* get the response */
- CKYAPDU getResponseAPDU;
-
-+ CKYBuffer_Zero(&getResponse);
- CKYAPDU_Init(&getResponseAPDU);
- CKYAPDU_SetCLA(&getResponseAPDU, 0x00);
- CKYAPDU_SetINS(&getResponseAPDU, 0xc0);
- CKYAPDU_SetP1(&getResponseAPDU, 0x00);
- CKYAPDU_SetP2(&getResponseAPDU, 0x00);
-- CKYAPDU_SetReceiveLen(&getResponseAPDU, CKYBuffer_GetChar(response,1));
-- ret = CKYCardConnection_TransmitAPDU(conn, &getResponseAPDU, response);
-+ CKYAPDU_SetReceiveLen(&getResponseAPDU,
-+ CKYBuffer_GetChar(response,size-1));
-+ ret = CKYCardConnection_TransmitAPDU(conn, &getResponseAPDU,
-+ &getResponse);
- CKYAPDU_FreeData(&getResponseAPDU);
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(&getResponse) >= 2)) {
-+ CKYBuffer_Resize(response, size-2);
-+ CKYBuffer_AppendCopy(response,&getResponse);
-+ }
- }
-+ CKYBuffer_FreeData(&getResponse);
- return ret;
- }
-
-diff -up ./src/libckyapplet/cky_card.h.coolkey-update ./src/libckyapplet/cky_card.h
---- ./src/libckyapplet/cky_card.h.coolkey-update 2016-01-19 18:04:19.315535537 -0800
-+++ ./src/libckyapplet/cky_card.h 2016-01-19 18:04:28.384461063 -0800
-@@ -116,6 +116,7 @@ CKYStatus CKYCardConnection_ExchangeAPDU
- CKYStatus CKYCardConnection_Connect(CKYCardConnection *connection,
- const char *readerName);
- CKYStatus CKYCardConnection_Disconnect(CKYCardConnection *connection);
-+unsigned long CKYCardConnection_GetProtocol(const CKYCardConnection *conn);
- CKYBool CKYCardConnection_IsConnected(const CKYCardConnection *connection);
- CKYStatus CKYCardConnection_Reconnect(CKYCardConnection *connection);
- CKYStatus CKYCardConnection_GetStatus(CKYCardConnection *connection,
-diff -up ./src/libckyapplet/cky_factory.c.coolkey-update ./src/libckyapplet/cky_factory.c
---- ./src/libckyapplet/cky_factory.c.coolkey-update 2016-01-19 18:04:51.976267329 -0800
-+++ ./src/libckyapplet/cky_factory.c 2016-01-19 18:05:03.518172548 -0800
-@@ -29,7 +29,7 @@ CKYAPDUFactory_SelectFile(CKYAPDU *apdu,
- const CKYBuffer *AID)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-- CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE);
-+ CKYAPDU_SetINS(apdu, ISO_INS_SELECT_FILE);
- CKYAPDU_SetP1(apdu, p1);
- CKYAPDU_SetP2(apdu, p2);
- return CKYAPDU_SetSendDataBuffer(apdu, AID);
-@@ -40,7 +40,7 @@ CKYAPDUFactory_SelectCardManager(CKYAPDU
- {
- CKYByte c = 0;
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-- CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE);
-+ CKYAPDU_SetINS(apdu, ISO_INS_SELECT_FILE);
- CKYAPDU_SetP1(apdu, 0x04);
- CKYAPDU_SetP2(apdu, 0x00);
- /* I can't find the documentation for this, but if you pass an empty
-@@ -57,12 +57,11 @@ CKYStatus
- CKYAPDUFactory_GetCPLCData(CKYAPDU *apdu)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM);
-- CKYAPDU_SetINS(apdu, CKY_INS_GET_DATA);
-+ CKYAPDU_SetINS(apdu, ISO_INS_GET_DATA);
- CKYAPDU_SetP1(apdu, 0x9f);
- CKYAPDU_SetP2(apdu, 0x7f);
- return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_CPLCDATA);
- }
--
- /*
- * applet commands must be issued with the appplet selected.
- */
-@@ -184,6 +183,49 @@ fail:
- }
-
- CKYStatus
-+CKYAPDUFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *publicData, const CKYBuffer *secretKey)
-+{
-+ CKYStatus ret = CKYINVALIDARGS;
-+ CKYSize len;
-+ CKYBuffer buf;
-+
-+ if (!publicData)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(publicData)))
-+ return ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_KEY_AGREEMENT);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)len);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, publicData);
-+ if (ret == CKYSUCCESS && secretKey && 0 < (len = CKYBuffer_Size(secretKey))) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)len);
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, secretKey);
-+ }
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
- CKYAPDUFactory_ComputeCryptOneStep(CKYAPDU *apdu, CKYByte keyNumber, CKYByte mode,
- CKYByte direction, CKYByte location,
- const CKYBuffer *idata, const CKYBuffer *sig)
-@@ -386,6 +428,49 @@ fail:
- }
-
- CKYStatus
-+CKYAPDUFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *idata, const CKYBuffer *sig)
-+{
-+ CKYStatus ret = CKYINVALIDARGS;
-+ CKYSize len;
-+ CKYBuffer buf;
-+
-+ if (!idata)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT)
-+ return ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_SIGNATURE);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)len);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, idata);
-+ if (ret == CKYSUCCESS && sig && 0 < (len = CKYBuffer_Size(sig))) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)len);
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, sig);
-+ }
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
- CKYAPDUFactory_ReadObject(CKYAPDU *apdu, unsigned long objectID,
- CKYOffset offset, CKYByte size)
- {
-@@ -634,32 +719,167 @@ CACAPDUFactory_GetProperties(CKYAPDU *ap
- }
-
- CKYStatus
--CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin)
-+PIVAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte chain, CKYByte alg,
-+ CKYByte key, int len, const CKYBuffer *data)
-+{
-+ CKYStatus ret;
-+ CKYAPDU_SetCLA(apdu, chain ? CKY_CLASS_ISO7816_CHAIN :
-+ CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, PIV_INS_GEN_AUTHENTICATE);
-+ CKYAPDU_SetP1(apdu, alg);
-+ CKYAPDU_SetP2(apdu, key);
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, data);
-+ if (ret == CKYSUCCESS && chain == 0 && len != 0) {
-+ if (len >= 256) len = 0;
-+ ret = CKYAPDU_AppendReceiveLen(apdu, len);
-+ }
-+ return ret;
-+}
-+
-+CKYStatus
-+PIVAPDUFactory_GetData(CKYAPDU *apdu, const CKYBuffer *object, CKYByte count)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+ CKYByte objectSize;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, 0xcb);
-+ CKYAPDU_SetP1(apdu, 0x3f);
-+ CKYAPDU_SetP2(apdu, 0xff);
-+
-+ objectSize = CKYBuffer_Size(object);
-+
-+ ret = CKYBuffer_Reserve(&buf, 2+objectSize);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, 0x5c);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, objectSize);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendCopy(&buf, object);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_AppendReceiveLen(apdu, count);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15APDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte keyRef, const CKYBuffer *pin)
- {
- CKYStatus ret;
-- CKYSize size;
-
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
- CKYAPDU_SetINS(apdu, CAC_INS_VERIFY_PIN);
- CKYAPDU_SetP1(apdu, 0x00);
-- CKYAPDU_SetP2(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, keyRef);
- /* no pin, send an empty buffer */
-- if (!pin) {
-+ if (CKYBuffer_Size(pin) == 0) {
- return CKYAPDU_SetReceiveLen(apdu, 0);
- }
-
- /* all CAC pins are 8 bytes exactly. If to long, truncate it */
-- size = strlen(pin);
-- if (size > 8) {
-- size = 8;
-- }
-- ret = CKYAPDU_SetSendData(apdu, (unsigned char *) pin, size);
-- /* if too short, pad it */
-- if ((ret == CKYSUCCESS) && (size < 8)) {
-- static const unsigned char pad[]= { 0xff , 0xff, 0xff ,0xff,
-- 0xff, 0xff, 0xff, 0xff };
-- return CKYAPDU_AppendSendData(apdu, pad, 8-size);
-- }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, pin);
- return ret;
-
- }
-+
-+CKYStatus
-+P15APDUFactory_ReadRecord(CKYAPDU *apdu, CKYByte record, CKYByte short_ef,
-+ CKYByte flags, CKYByte count)
-+{
-+ CKYByte control;
-+
-+ control = (short_ef << 3) & 0xf8;
-+ control |= flags & 0x07;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_READ_RECORD);
-+ CKYAPDU_SetP1(apdu, record);
-+ CKYAPDU_SetP2(apdu, control);
-+ return CKYAPDU_SetReceiveLen(apdu, count);
-+}
-+
-+CKYStatus
-+P15APDUFactory_ReadBinary(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte count)
-+{
-+ CKYByte p1 = 0,p2 = 0;
-+ unsigned short max_offset = 0;
-+
-+ if (flags & P15_USE_SHORT_EF) {
-+ max_offset = 0xff;
-+ p1 = P15_USE_SHORT_EF | (short_ef & 0x7);
-+ p2 = offset & 0xff;
-+ } else {
-+ max_offset = 0x7fff;
-+ p1 = (offset >> 8) & 0x7f;
-+ p2 = offset & 0xff;
-+ }
-+ if (offset > max_offset) {
-+ return CKYINVALIDARGS;
-+ }
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_READ_BINARY);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ return CKYAPDU_SetReceiveLen(apdu, count);
-+}
-+
-+CKYStatus
-+P15APDUFactory_ManageSecurityEnvironment(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ CKYByte keyRef)
-+{
-+ CKYByte param[3];
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_MANAGE_SECURITY_ENVIRONMENT);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ param[0] = 0x83;
-+ param[1] = 1;
-+ param[2] = keyRef;
-+ return CKYAPDU_SetSendData(apdu, param, sizeof param);
-+}
-+
-+CKYStatus
-+P15APDUFactory_PerformSecurityOperation(CKYAPDU *apdu, CKYByte dir,
-+ int chain, CKYSize retLen, const CKYBuffer *data)
-+{
-+ CKYByte p1,p2;
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, chain ? CKY_CLASS_ISO7816_CHAIN :
-+ CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_PERFORM_SECURITY_OPERATION);
-+ if (dir == CKY_DIR_DECRYPT) {
-+ p1 = ISO_PSO_DECRYPT_P1;
-+ p2 = ISO_PSO_DECRYPT_P2;
-+ } else {
-+ p1 = ISO_PSO_SIGN_P1;
-+ p2 = ISO_PSO_SIGN_P2;
-+ }
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, data);
-+ if (ret == CKYSUCCESS && (chain == 0) && retLen != 0) {
-+ ret = CKYAPDU_AppendReceiveLength(apdu, retLen);
-+ }
-+ return ret;
-+}
-+
-+
-diff -up ./src/libckyapplet/cky_factory.h.coolkey-update ./src/libckyapplet/cky_factory.h
---- ./src/libckyapplet/cky_factory.h.coolkey-update 2016-01-19 18:05:20.615032151 -0800
-+++ ./src/libckyapplet/cky_factory.h 2016-01-19 18:05:30.781948661 -0800
-@@ -25,17 +25,41 @@
- /*
- * Various Class bytes
- */
--#define CKY_CLASS_ISO7816 0x00
-+#define CKY_CLASS_ISO7816 0x00
-+#define CKY_CLASS_ISO7816_CHAIN 0x10
- #define CKY_CLASS_GLOBAL_PLATFORM 0x80
--#define CKY_CLASS_SECURE 0x84
--#define CKY_CLASS_COOLKEY 0xb0
-+#define CKY_CLASS_SECURE 0x84
-+#define CKY_CLASS_COOLKEY 0xb0
-
- /*
- * Applet Instruction Bytes
- */
- /* Card Manager */
--#define CKY_INS_SELECT_FILE 0xa4
--#define CKY_INS_GET_DATA 0xca
-+#define ISO_INS_SELECT_FILE 0xa4
-+#define ISO_INS_GET_DATA 0xca
-+#define ISO_INS_READ_BINARY 0xb0
-+#define ISO_INS_READ_RECORD 0xb2
-+#define ISO_INS_MANAGE_SECURITY_ENVIRONMENT 0x22
-+#define ISO_INS_PERFORM_SECURITY_OPERATION 0x2a
-+
-+/* ISO Parameters: */
-+#define ISO_LOGIN_LOCAL 0x80
-+#define ISO_LOGIN_GLOBAL 0x00
-+#define ISO_MSE_SET 0x01
-+#define ISO_MSE_STORE 0xf2
-+#define ISO_MSE_RESTORE 0xf3
-+#define ISO_MSE_ERASE 0xf4
-+#define ISO_MSE_QUAL_VERIFY 0x80
-+#define ISO_MSE_QUAL_COMPUTE 0x40
-+#define ISO_MSE_AUTH 0xa4
-+#define ISO_MSE_SIGN 0xb6
-+#define ISO_MSE_KEA 0xb8
-+#define ISO_PSO_SIGN_P1 0x9e
-+#define ISO_PSO_SIGN_P2 0x9a
-+#define ISO_PSO_ENCRYPT_P1 0x86
-+#define ISO_PSO_ENCRYPT_P2 0x80
-+#define ISO_PSO_DECRYPT_P1 0x80
-+#define ISO_PSO_DECRYPT_P2 0x86
-
- /* deprecated */
- #define CKY_INS_SETUP 0x2A
-@@ -66,6 +90,8 @@
- /* nonce validated & Secure Channel */
- #define CKY_INS_IMPORT_KEY 0x32
- #define CKY_INS_COMPUTE_CRYPT 0x36
-+#define CKY_INS_COMPUTE_ECC_SIGNATURE 0x37
-+#define CKY_INS_COMPUTE_ECC_KEY_AGREEMENT 0x38
- #define CKY_INS_CREATE_PIN 0x40
- #define CKY_INS_CHANGE_PIN 0x44
- #define CKY_INS_CREATE_OBJ 0x5A
-@@ -81,6 +107,7 @@
- #define CKY_INS_SEC_READ_IOBUF 0x08
- #define CKY_INS_SEC_START_ENROLLMENT 0x0C
-
-+
- /* CAC */
- #define CAC_INS_GET_CERTIFICATE 0x36
- #define CAC_INS_SIGN_DECRYPT 0x42
-@@ -92,6 +119,9 @@
- #define CAC_P1_STEP 0x80
- #define CAC_P1_FINAL 0x00
-
-+/* PIV */
-+#define PIV_INS_GEN_AUTHENTICATE 0x87
-+
- /*
- * Fixed return sized from various commands
- */
-@@ -112,7 +142,7 @@
- /* functions */
- #define CKY_CIPHER_INIT 1
- #define CKY_CIPHER_PROCESS 2
--#define CKY_CIPHER_FINAL 3
-+#define CKY_CIPHER_FINAL 3
- #define CKY_CIPHER_ONE_STEP 4 /* init and final in one APDU */
-
- /* modes */
-@@ -123,6 +153,7 @@
- #define CKY_DES_ECB_NOPAD 0x21
-
- /* operations (Cipher Direction) */
-+#define CKY_DIR_NONE 0x00
- #define CKY_DIR_SIGN 0x01
- #define CKY_DIR_VERIFY 0x02
- #define CKY_DIR_ENCRYPT 0x03
-@@ -163,6 +194,18 @@
- #define CKY_CARDM_MANAGER_LOCKED 0x7f
- #define CKY_CARDM_MANAGER_TERMINATED 0xff
-
-+/* Read Record Flags */
-+#define P15_READ_P1 0x4
-+#define P15_READ_P1_TO_LAST 0x5
-+#define P15_READ_LAST_TO_P1 0x6
-+#define P15_READ_FIRST 0x0
-+#define P15_READ_LAST 0x1
-+#define P15_READ_NEXT 0x2
-+#define P15_READ_PREV 0x3
-+
-+/* Read Binary Flags */
-+#define P15_USE_SHORT_EF 0x80
-+
- /*
- * The following factories 'Fill in' APDUs for each of the
- * functions described below. Nonces are not automatically added.
-@@ -187,6 +230,12 @@ CKYStatus CKYAPDUFactory_ComputeCryptFin
- CKYStatus CKYAPDUFactory_ComputeCryptOneStep(CKYAPDU *apdu, CKYByte keyNumber,
- CKYByte mode, CKYByte direction, CKYByte location,
- const CKYBuffer *data, const CKYBuffer *sig);
-+CKYStatus CKYAPDUFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *data, const CKYBuffer *sig);
-+CKYStatus CKYAPDUFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *publicData, const CKYBuffer *secretKey);
- CKYStatus CKYAPDUFactory_CreatePIN(CKYAPDU *apdu, CKYByte pinNumber,
- CKYByte maxAttempts, const char *pinValue);
- CKYStatus CKYAPDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte pinNumber,
-@@ -218,12 +267,28 @@ CKYStatus CKYAPDUFactory_GetBuiltinACL(C
-
- CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type,
- const CKYBuffer *data);
--CKYStatus CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin);
- CKYStatus CACAPDUFactory_GetCertificate(CKYAPDU *apdu, CKYSize size);
- CKYStatus CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
- CKYByte type, CKYByte count);
- CKYStatus CACAPDUFactory_GetProperties(CKYAPDU *apdu);
-
-+CKYStatus PIVAPDUFactory_GetData(CKYAPDU *apdu, const CKYBuffer *object,
-+ CKYByte count);
-+CKYStatus PIVAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte chain, CKYByte alg,
-+ CKYByte key, int len, const CKYBuffer *data);
-+
-+CKYStatus P15APDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte keyRef,
-+ const CKYBuffer *pin);
-+CKYStatus P15APDUFactory_ReadRecord(CKYAPDU *apdu, CKYByte record,
-+ CKYByte short_ef, CKYByte flags, CKYByte count);
-+CKYStatus P15APDUFactory_ReadBinary(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte count);
-+CKYStatus P15APDUFactory_ManageSecurityEnvironment(CKYAPDU *apdu,
-+ CKYByte p1, CKYByte p2, CKYByte key);
-+CKYStatus P15APDUFactory_PerformSecurityOperation(CKYAPDU *apdu, CKYByte dir,
-+ int chain, CKYSize retLen, const CKYBuffer *data);
-+
-+
- CKY_END_PROTOS
-
- #endif /* CKY_FACTORY_H */
diff --git a/coolkey.spec b/coolkey.spec
deleted file mode 100644
index a8d6526..0000000
--- a/coolkey.spec
+++ /dev/null
@@ -1,283 +0,0 @@
-# BEGIN COPYRIGHT BLOCK
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation version
-# 2.1 of the License.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-# END COPYRIGHT BLOCK
-
-%define coolkey_module "CoolKey PKCS #11 Module"
-%define nssdb %{_sysconfdir}/pki/nssdb
-
-Name: coolkey
-Version: 1.1.0
-Release: 36%{?dist}
-Summary: CoolKey PKCS #11 module
-License: LGPLv2
-URL: http://directory.fedora.redhat.com/wiki/CoolKey
-Source: coolkey-%{version}.tar.gz
-Patch1: coolkey-cache-dir-move.patch
-Patch2: coolkey-gcc43.patch
-Patch3: coolkey-latest.patch
-Patch4: coolkey-simple-bugs.patch
-Patch5: coolkey-thread-fix.patch
-Patch6: coolkey-cac.patch
-Patch7: coolkey-cac-1.patch
-Patch8: coolkey-pcsc-lite-fix.patch
-Patch9: coolkey-fix-token-removal-failure.patch
-Patch10: coolkey-update.patch
-Patch11: coolkey-more-keys.patch
-Patch12: coolkey-1.1.0-max-cpu-bug.patch
-Group: System Environment/Libraries
-BuildRequires: autoconf
-BuildRequires: pcsc-lite-devel
-BuildRequires: zlib-devel
-BuildRequires: nss-devel
-Recommends: opensc
-Requires: nss-tools
-Requires: pcsc-lite
-Requires: pcsc-lite-libs
-Requires: ccid
-Provides: CoolKey Openkey
-Obsoletes: CoolKey Openkey
-# 390 does not have libusb or smartCards
-ExcludeArch: s390 s390x
-
-%description
-Linux Driver support for the CoolKey and CAC products.
-
-%package devel
-Summary: CoolKey Applet libraries
-Group: System Environment/Libraries
-
-%description devel
-Linux Driver support to access the CoolKey applet.
-
-
-%prep
-%setup -q
-%patch1 -b .cache.dir.move
-%patch2 -b .coolkey-gcc43
-%patch3 -b .coolkey-latest
-%patch4 -b .coolkey-simple-bugs
-%patch5 -b .coolkey-thread-fix
-%patch6 -b .cac
-%patch7 -b .cac-1
-%patch8 -b .reader-state-fix
-%patch9 -p1 -b .fix-token-removal-failure
-%patch10 -p1 -b .coolkey-update
-%patch11 -p1 -b .coolkey-more-keys
-%patch12 -p1 -b .max-cpu
-
-%build
-autoconf
-%configure --with-debug --disable-dependency-tracking --enable-pk11install
-make %{?_smp_mflags} CFLAGS="$CFLAGS -g -O2 -fno-strict-aliasing $CFLAGS " CXXFLAGS="$CXXFLAGS -g -O2 -fno-strict-aliasing $CFLAGS"
-
-%install
-rm -rf $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
-ln -s pkcs11/libcoolkeypk11.so $RPM_BUILD_ROOT/%{_libdir}
-mkdir -p $RPM_BUILD_ROOT/var/cache/coolkey
-
-%post
-/sbin/ldconfig
-if [ "$1" == "2" ]; then # not for new installs
- isThere=`modutil -rawlist -dbdir %{nssdb} | grep %{coolkey_module} || echo NO`
- if [ "$isThere" != "NO" ]; then
- # Remove from NSS DB in Fedora 26
- if [ -x %{_bindir}/modutil ]; then
- modutil -delete %{coolkey_module} -dbdir %{nssdb} -force || :
- fi
- fi
-fi
-
-%files
-%defattr(-,root,root,-)
-%doc ChangeLog LICENSE
-%{_bindir}/pk11install
-%{_libdir}/libcoolkeypk11.so
-%{_libdir}/pkcs11
-%{_libdir}/libckyapplet.so.1
-%{_libdir}/libckyapplet.so.1.0.0
-
-%files devel
-%{_libdir}/libckyapplet.so
-%{_libdir}/pkgconfig/libckyapplet.pc
-%{_includedir}/*.h
-
-
-%changelog
-* Wed Feb 07 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-36
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
-
-* Wed Aug 02 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-35
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
-
-* Wed Jul 26 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-34
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
-
-* Thu Mar 09 2017 Jakub Jelen <jjelen(a)redhat.com> - 1.1.0-33
-- Prevent busy loop when removing token (#1430268)
-
-* Tue Feb 28 2017 Jakub Jelen <jjelen(a)redhat.com> - 1.1.0-32
-- Remove PKCS#11 library from the NSS DB after update and for new installs (#1421692)
-
-* Fri Feb 10 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-31
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
-
-* Thu Feb 04 2016 Jack Magne <jmagne(a)redhat.com> - 1.1.0-30
-- Latest coolkey updates.
-- Fix to allow more key indexes than just 0 - 9.
-
-* Wed Feb 03 2016 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-29
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
-
-* Wed Jun 17 2015 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-28
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
-
-* Sat May 02 2015 Kalev Lember <kalevlember(a)gmail.com> - 1.1.0-27
-- Rebuilt for GCC 5 C++11 ABI change
-
-* Sat Aug 16 2014 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-26
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
-
-* Sat Jun 07 2014 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-25
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
-
-* Sat Aug 03 2013 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-24
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
-
-* Wed May 22 2013 Ray Strode <rstrode(a)redhat.com> 1.1.0-23
-- Fix token removal issue
-
-* Wed Feb 13 2013 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-22
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
-
-* Wed Jul 18 2012 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-21
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
-
-* Thu Jan 12 2012 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-20
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
-
-* Tue Feb 08 2011 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-19
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
-
-* Tue Oct 19 2010 Ville Skyttä <ville.skytta(a)iki.fi> - 1.1.0-18
-- Own the %%{_libdir}/pkcs11 dir.
-
-* Wed Sep 8 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-17
-- pscs-lite removed SCARD_READERSTATE_A definition. revert to the prefered
- SCARD_READERSTATE
-
-* Wed Jun 23 2010 Jack Magne <jmagne(a)redhat.com> - 1.1.0-16
-- fix possible crash when loading cac certs.
-
-* Wed Jun 16 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-15
-- better cac support.
-
-* Mon Feb 22 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-14
-- remove dependency on ifd-egate
-
-* Tue Jan 5 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-13
-- bump the release number to rebuild
-
-* Wed Dec 18 2009 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-12
-- Fix threading issue. Coolkey will now work with non-threaded applications
-- that don't link with libpthread.
-
-* Wed Sep 16 2009 Jack magne <jmagne(a)redhat.com> - 1.1.0-11
-- Misc bug fixes. Resolves: 485032, #250738, #497758.
-
-* Fri Sep 11 2009 Jack Magne <jmagne(a)redhat.com> - 1.1.0-10
-- Include latest changes for Gemalto 64K and Safenet 330J.
-
-* Fri Jul 24 2009 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-9
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
-
-* Tue Feb 24 2009 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-8
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
-
-* Sun Sep 14 2008 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.1.0-7
-- BR: nss-devel not mozilla-nss-devel (FTBFS BZ#440753)
-
-* Wed Feb 13 2008 Jack magne <jmagne(a)redhat.com> - 1.1.0-6
-- Clean up building with gcc 4.3.
-* Thu Sep 27 2007 Jack Magne <jmagne(a)redhat.com> - 1.1.0-5
-- Include patch for moving the cache directory to a safe location.
-- Bug #299481.
-* Fri Aug 20 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-4
-- Update License description to the new Fedora standard
-
-* Thu Jun 21 2007 Kai Engert <kengert(a)redhat.com> - 1.1.0-3.1
-- rebuild
-
-* Tue Jun 5 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-3
-- add build requires, bump version number for make tag.
-
-* Thu May 31 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-2
-- Back out RHEL-4 version of spec from CVS, add pcsc-lite-lib requires.
-
-* Tue Feb 20 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-1
-- Pick up lates release.
-
-* Wed Nov 1 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-15
-- Don't grab the CUID on cac's. Resting the card causes it to
-- logout of other applications.
-
-* Wed Nov 1 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-14
-- Shared memory directory needs to be writeable by all so
-- coolkey can create caches for any user. (lack of caches
-- show up in screen savers reactly slowly).
-
-* Fri Oct 20 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-13
-- fix login hw race failures
-
-* Fri Oct 20 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-12
-- add the dist flag
-
-* Wed Oct 18 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-11
-- CAC cards sometimes need to reset before they can get their
-- initial transaction (problem is noticed on insertion an removal)
-
-* Tue Oct 17 2006 Jesse Keating <jkeating(a)redhat.com> - 1.0.1-10
-- Only run pk11install if the binary is there (multilib fun)
-
-* Mon Oct 09 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-9
-- use pk11install which does not require loading the module to install it.
-
-* Mon Oct 09 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-8
-- pcscd must be running in order to add coolkey.
-
-* Thu Oct 4 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-7
-- silence modutil warnings
-
-* Thu Sep 30 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-5
-- install and uninstall coolkey in the system secmod.db
-
-* Thu Sep 7 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-4
-- make the coolkey token caches persist over application calls.
-- make a separate cache for each user.
-
-* Sun Jul 16 2006 Florian La Roche <laroche(a)redhat.com> - 1.0.1-2
-- fix excludearch line
-
-* Mon Jul 10 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-1
-- Don't require pthread library in coolkey
-
-* Mon Jul 10 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.0-2
-- remove s390 from the build
-
-* Mon Jun 5 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.0-1
-- Initial revision for fedora
diff --git a/dead.package b/dead.package
new file mode 100644
index 0000000..5ff2bbd
--- /dev/null
+++ b/dead.package
@@ -0,0 +1 @@
+Replaced by OpenSC
diff --git a/sources b/sources
deleted file mode 100644
index aecaa3b..0000000
--- a/sources
+++ /dev/null
@@ -1 +0,0 @@
-815a1811a46bf9b8782107c073149cbe coolkey-1.1.0.tar.gz
6 years, 1 month
Architecture specific change in rpms/coolkey.git
by githook-noreply@fedoraproject.org
The package rpms/coolkey.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/coolkey.git/commit/?id=1b740645e2....
Change:
-ExcludeArch: s390 s390x
Thanks.
Full change:
============
commit 1b740645e281682c7127a5b1a26a6e5359a28bca
Author: Jakub Jelen <jjelen(a)redhat.com>
Date: Fri Mar 2 09:54:23 2018 +0100
Replaced by OpenSC
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 88a91c6..0000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-coolkey-1.1.0.tar.gz
diff --git a/coolkey-1.1.0-max-cpu-bug.patch b/coolkey-1.1.0-max-cpu-bug.patch
deleted file mode 100644
index aab85f7..0000000
--- a/coolkey-1.1.0-max-cpu-bug.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.max-cpu-bug ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.max-cpu-bug 2016-06-30 14:36:10.502785885 -0700
-+++ ./src/coolkey/slot.cpp 2016-06-30 14:36:15.812876256 -0700
-@@ -1875,6 +1875,8 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- if (status != CKYSUCCESS) {
- if ((CKYCardContext_GetLastError(context) ==
- SCARD_E_READER_UNAVAILABLE) ||
-+ (CKYCardContext_GetLastError(context) ==
-+ SCARD_E_UNKNOWN_READER) ||
- (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT)) {
- OSSleep(timeout*PKCS11_CARD_ERROR_LATENCY);
- }
diff --git a/coolkey-cac-1.patch b/coolkey-cac-1.patch
deleted file mode 100644
index ea70187..0000000
--- a/coolkey-cac-1.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff -up ./src/coolkey/object.cpp.cac-1 ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.cac-1 2010-06-23 04:46:35.726198827 -0700
-+++ ./src/coolkey/object.cpp 2010-06-23 04:47:28.073827862 -0700
-@@ -505,6 +505,10 @@ dataStart(const CKYByte *buf, unsigned i
- unsigned char tag;
- unsigned int used_length= 0;
-
-+ if(!buf) {
-+ return NULL;
-+ }
-+
- tag = buf[used_length++];
-
- /* blow out when we come to the end */
-diff -up ./src/coolkey/slot.cpp.cac-1 ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.cac-1 2010-06-23 04:46:22.718371631 -0700
-+++ ./src/coolkey/slot.cpp 2010-06-23 04:57:04.417774402 -0700
-@@ -2192,6 +2192,10 @@ Slot::readCACCertificateFirst(CKYBuffer
- if (throwException && (status != CKYSUCCESS)) {
- handleConnectionError();
- }
-+
-+ if(CKYBuffer_Size(cert) == 0) {
-+ handleConnectionError();
-+ }
- return status;
- }
-
diff --git a/coolkey-cac.patch b/coolkey-cac.patch
deleted file mode 100644
index a2a9732..0000000
--- a/coolkey-cac.patch
+++ /dev/null
@@ -1,1013 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.cac ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.cac 2010-06-16 13:43:51.477181000 -0700
-+++ ./src/coolkey/slot.cpp 2010-06-16 13:43:51.535179000 -0700
-@@ -372,7 +372,7 @@ Slot::Slot(const char *readerName_, Log
- : log(log_), readerName(NULL), personName(NULL), manufacturer(NULL),
- slotInfoFound(false), context(context_), conn(NULL), state(UNKNOWN),
- isVersion1Key(false), needLogin(false), fullTokenName(false),
-- mCoolkey(false),
-+ mCoolkey(false), mOldCAC(false),
- #ifdef USE_SHMEM
- shmem(readerName_),
- #endif
-@@ -412,6 +412,9 @@ Slot::Slot(const char *readerName_, Log
- }
- CKYBuffer_InitEmpty(&cardATR);
- CKYBuffer_InitEmpty(&mCUID);
-+ for (int i=0; i < MAX_CERT_SLOTS; i++) {
-+ CKYBuffer_InitEmpty(&cardAID[i]);
-+ }
- } catch(PKCS11Exception &) {
- if (conn) {
- CKYCardConnection_Destroy(conn);
-@@ -479,6 +482,9 @@ Slot::~Slot()
- CKYBuffer_FreeData(&nonce);
- CKYBuffer_FreeData(&cardATR);
- CKYBuffer_FreeData(&mCUID);
-+ for (int i=0; i < MAX_CERT_SLOTS; i++) {
-+ CKYBuffer_FreeData(&cardAID[i]);
-+ }
- }
-
- template <class C>
-@@ -671,15 +677,9 @@ Slot::connectToToken()
- status = CKYApplet_SelectCoolKeyManager(conn, NULL);
- if (status != CKYSUCCESS) {
- log->log("CoolKey Select failed 0x%x\n", status);
-- status = CACApplet_SelectPKI(conn, 0, NULL);
-+ status = getCACAid();
- if (status != CKYSUCCESS) {
-- log->log("CAC Select failed 0x%x\n", status);
-- if (status == CKYSCARDERR) {
-- log->log("CAC Card Failure 0x%x\n",
-- CKYCardConnection_GetLastError(conn));
-- disconnect();
-- }
-- return;
-+ goto loser;
- }
- state |= CAC_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
- /* skip the read of the cuid. We really don't need it and,
-@@ -690,6 +690,15 @@ Slot::connectToToken()
- needLogin = 1;
- mCoolkey = 0;
- return;
-+
-+loser:
-+ log->log("CAC Select failed 0x%x\n", status);
-+ if (status == CKYSCARDERR) {
-+ log->log("CAC Card Failure 0x%x\n",
-+ CKYCardConnection_GetLastError(conn));
-+ disconnect();
-+ }
-+ return;
- }
- mCoolkey = 1;
- log->log("time connect: Select Applet %d ms\n", OSTimeNow() - time);
-@@ -771,17 +780,111 @@ Slot::disconnect()
- invalidateLogin(false);
- }
-
-+CKYStatus
-+Slot::getCACAid()
-+{
-+ CKYBuffer tBuf;
-+ CKYBuffer vBuf;
-+ CKYSize tlen, vlen;
-+ CKYOffset toffset, voffset;
-+ int certSlot = 0;
-+ int i,length = 0;
-+ CKYStatus status;
-+
-+ CKYBuffer_InitEmpty(&tBuf);
-+ CKYBuffer_InitEmpty(&vBuf);
-+
-+ /* clear out the card AID's */
-+ for (i=0; i < MAX_CERT_SLOTS; i++) {
-+ CKYBuffer_Resize(&cardAID[i],0);
-+ }
-+
-+ status = CACApplet_SelectCCC(conn,NULL);
-+ if (status != CKYSUCCESS) {
-+ /* are we an old CAC */
-+ status = CACApplet_SelectPKI(conn, &cardAID[0], 0, NULL);
-+ if (status != CKYSUCCESS) {
-+ /* no, just fail */
-+ return status;
-+ }
-+ /* yes, fill in the old applets */
-+ mOldCAC = true;
-+ for (i=1; i< MAX_CERT_SLOTS; i++) {
-+ CACApplet_SelectPKI(conn, &cardAID[i], i, NULL);
-+ }
-+ return CKYSUCCESS;
-+ }
-+ /* definately not an old CAC */
-+ mOldCAC = false;
-+
-+ /* read the TLV */
-+ status = CACApplet_ReadFile(conn, CAC_TAG_FILE, &tBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ status = CACApplet_ReadFile(conn, CAC_VALUE_FILE, &vBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ tlen = CKYBuffer_Size(&tBuf);
-+ vlen = CKYBuffer_Size(&vBuf);
-+
-+ for(toffset = 2, voffset=2;
-+ certSlot < MAX_CERT_SLOTS && toffset < tlen && voffset < vlen ;
-+ voffset += length) {
-+
-+ CKYByte tag = CKYBuffer_GetChar(&tBuf, toffset);
-+ length = CKYBuffer_GetChar(&tBuf, toffset+1);
-+ toffset += 2;
-+ if (length == 0xff) {
-+ length = CKYBuffer_GetShortLE(&tBuf, toffset);
-+ toffset +=2;
-+ }
-+ if (tag != CAC_TAG_CARDURL) {
-+ continue;
-+ }
-+ /* CARDURL tags must be at least 10 bytes long */
-+ if (length < 10) {
-+ continue;
-+ }
-+ /* check the app type, should be TLV_APP_PKI */
-+ if (CKYBuffer_GetChar(&vBuf, voffset+5) != CAC_TLV_APP_PKI) {
-+ continue;
-+ }
-+ status = CKYBuffer_AppendBuffer(&cardAID[certSlot], &vBuf, voffset, 5);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ status = CKYBuffer_AppendBuffer(&cardAID[certSlot], &vBuf,
-+ voffset+8, 2);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ cardEF[certSlot] = CKYBuffer_GetShortLE(&vBuf, voffset+6);
-+
-+ certSlot++;
-+ }
-+ status = CKYSUCCESS;
-+ if (certSlot == 0) {
-+ status = CKYAPDUFAIL; /* probably neeed a beter error code */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tBuf);
-+ CKYBuffer_FreeData(&vBuf);
-+ return status;
-+}
-+
- void
- Slot::refreshTokenState()
- {
- if( cardStateMayHaveChanged() ) {
--log->log("card changed\n");
-+ log->log("card changed\n");
- invalidateLogin(true);
- closeAllSessions();
- unloadObjects();
- connectToToken();
-
--
- if( state & APPLET_PERSONALIZED ) {
- try {
- loadObjects();
-@@ -1019,7 +1122,7 @@ Slot::makeModelString(char *model, int m
-
- struct _manList {
- unsigned short type;
-- char *string;
-+ const char *string;
- };
-
- static const struct _manList manList[] = {
-@@ -1280,13 +1383,30 @@ void
- Slot::selectCACApplet(CKYByte instance)
- {
- CKYStatus status;
-- status = CACApplet_SelectPKI(conn, instance, NULL);
-+ CKYBuffer *aid = &cardAID[instance];
-+
-+ if (CKYBuffer_Size(aid) == 0) {
-+ disconnect();
-+ throw PKCS11Exception(CKR_DEVICE_REMOVED);
-+ return;
-+ }
-+
-+ status = CKYApplet_SelectFile(conn, aid, NULL);
- if ( status == CKYSCARDERR ) handleConnectionError();
- if ( status != CKYSUCCESS) {
- // could not select applet: this just means it's not there
- disconnect();
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- }
-+ if (mOldCAC) {
-+ return;
-+ }
-+ status = CACApplet_SelectFile(conn, cardEF[instance], NULL);
-+ if ( status == CKYSCARDERR ) handleConnectionError();
-+ if ( status != CKYSUCCESS) {
-+ disconnect();
-+ throw PKCS11Exception(CKR_DEVICE_REMOVED);
-+ }
- }
- // assume we are already in a transaction
- void
-@@ -2059,10 +2179,85 @@ Slot::fetchCombinedObjects(const CKYBuff
- return objInfoList;
- }
-
-+CKYStatus
-+Slot::readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
-+ bool throwException)
-+{
-+ CKYStatus status;
-+ CKYISOStatus apduRC;
-+
-+ if (mOldCAC) {
-+ /* get the first 100 bytes of the cert */
-+ status = CACApplet_GetCertificateFirst(conn, cert, nextSize, &apduRC);
-+ if (throwException && (status != CKYSUCCESS)) {
-+ handleConnectionError();
-+ }
-+ return status;
-+ }
-+
-+ CKYBuffer tBuf;
-+ CKYBuffer vBuf;
-+ CKYSize tlen, vlen;
-+ CKYOffset toffset, voffset;
-+ int length = 0;
-+
-+ CKYBuffer_InitEmpty(&tBuf);
-+ CKYBuffer_InitEmpty(&vBuf);
-+ CKYBuffer_Resize(cert, 0);
-+
-+ /* handle the new CAC card read */
-+ /* read the TLV */
-+ status = CACApplet_ReadFile(conn, CAC_TAG_FILE, &tBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ status = CACApplet_ReadFile(conn, CAC_VALUE_FILE, &vBuf, NULL);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+ tlen = CKYBuffer_Size(&tBuf);
-+ vlen = CKYBuffer_Size(&vBuf);
-+
-+ /* look for the Cert out of the TLV */
-+ for(toffset = 2, voffset=2; toffset < tlen && voffset < vlen ;
-+ voffset += length) {
-+
-+ CKYByte tag = CKYBuffer_GetChar(&tBuf, toffset);
-+ length = CKYBuffer_GetChar(&tBuf, toffset+1);
-+ toffset += 2;
-+ if (length == 0xff) {
-+ length = CKYBuffer_GetShortLE(&tBuf, toffset);
-+ toffset +=2;
-+ }
-+ if (tag != CAC_TAG_CERTIFICATE) {
-+ continue;
-+ }
-+ CKYBuffer_AppendBuffer(cert, &vBuf, voffset, length);
-+ break;
-+ }
-+ status = CKYSUCCESS;
-+
-+done:
-+ CKYBuffer_FreeData(&tBuf);
-+ CKYBuffer_FreeData(&vBuf);
-+ return status;
-+}
-+
-+/*
-+ * only necessary for old CAC cards. New CAC cards have to read the
-+ * whole cert in anyway above....
-+ */
-+CKYStatus
-+Slot::readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize)
-+{
-+ CKYISOStatus apduRC;
-+ assert(mOldCAC);
-+ return CACApplet_GetCertificateAppend(conn, cert, nextSize, &apduRC);
-+}
-+
- void
- Slot::loadCACCert(CKYByte instance)
- {
-- CKYISOStatus apduRC;
- CKYStatus status = CKYSUCCESS;
- CKYBuffer cert;
- CKYBuffer rawCert;
-@@ -2097,12 +2292,7 @@ Slot::loadCACCert(CKYByte instance)
- instance, OSTimeNow() - time);
-
- if (instance == 0) {
-- /* get the first 100 bytes of the cert */
-- status = CACApplet_GetCertificateFirst(conn, &rawCert,
-- &nextSize, &apduRC);
-- if (status != CKYSUCCESS) {
-- handleConnectionError();
-- }
-+ readCACCertificateFirst(&rawCert, &nextSize, true);
- log->log("CAC Cert %d: fetch CAC Cert: %d ms\n",
- instance, OSTimeNow() - time);
- }
-@@ -2143,8 +2333,7 @@ Slot::loadCACCert(CKYByte instance)
- shmem.setVersion(SHMEM_VERSION);
- shmem.setDataVersion(dataVersion);
- } else {
-- status = CACApplet_GetCertificateFirst(conn, &rawCert,
-- &nextSize, &apduRC);
-+ status = readCACCertificateFirst(&rawCert, &nextSize, false);
-
- if (status != CKYSUCCESS) {
- /* CAC only requires the Certificate in pki '0' */
-@@ -2159,8 +2348,7 @@ Slot::loadCACCert(CKYByte instance)
- }
-
- if (nextSize) {
-- status = CACApplet_GetCertificateAppend(conn, &rawCert,
-- nextSize, &apduRC);
-+ status = readCACCertificateAppend(&rawCert, nextSize);
- }
- log->log("CAC Cert %d: Fetch rest : %d ms\n",
- instance, OSTimeNow() - time);
-@@ -2176,9 +2364,10 @@ Slot::loadCACCert(CKYByte instance)
-
- log->log("CAC Cert %d: Cert has been read: %d ms\n",
- instance, OSTimeNow() - time);
-- if (CKYBuffer_GetChar(&rawCert,0) == 1) {
-+ if (!mOldCAC || CKYBuffer_GetChar(&rawCert,0) == 1) {
- CKYSize guessFinalSize = CKYBuffer_Size(&rawCert);
- CKYSize certSize = 0;
-+ CKYOffset offset = mOldCAC ? 1 : 0;
- int zret = Z_MEM_ERROR;
-
- do {
-@@ -2189,7 +2378,8 @@ Slot::loadCACCert(CKYByte instance)
- }
- certSize = guessFinalSize;
- zret = uncompress((Bytef *)CKYBuffer_Data(&cert),&certSize,
-- CKYBuffer_Data(&rawCert)+1, CKYBuffer_Size(&rawCert)-1);
-+ CKYBuffer_Data(&rawCert)+offset,
-+ CKYBuffer_Size(&rawCert)-offset);
- } while (zret == Z_BUF_ERROR);
-
- if (zret != Z_OK) {
-@@ -2526,7 +2716,7 @@ Slot::attemptCACLogin()
- switch( result ) {
- case CKYISO_SUCCESS:
- break;
-- case 6981:
-+ case 0x6981:
- throw PKCS11Exception(CKR_PIN_LOCKED);
- default:
- if ((result & 0xff00) == 0x6300) {
-diff -up ./src/coolkey/slot.h.cac ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.cac 2010-06-16 13:43:51.344185000 -0700
-+++ ./src/coolkey/slot.h 2010-06-16 13:43:51.546179000 -0700
-@@ -294,6 +294,7 @@ class CryptParams {
- const CKYBuffer *paddedOutput) const = 0;
- };
-
-+#define MAX_CERT_SLOTS 3
- class Slot {
-
- public:
-@@ -328,6 +329,8 @@ class Slot {
- CKYBuffer nonce;
- CKYBuffer cardATR;
- CKYBuffer mCUID;
-+ CKYBuffer cardAID[MAX_CERT_SLOTS];
-+ unsigned short cardEF[MAX_CERT_SLOTS];
- bool isVersion1Key;
- bool needLogin;
- long publicFree;
-@@ -335,6 +338,7 @@ class Slot {
- long privateFree;
- bool fullTokenName;
- bool mCoolkey;
-+ bool mOldCAC;
-
- //enum { RW_SESSION_HANDLE = 1, RO_SESSION_HANDLE = 2 };
-
-@@ -398,6 +402,11 @@ class Slot {
- list<ListObjectInfo> fetchCombinedObjects(const CKYBuffer *header);
- list<ListObjectInfo> fetchSeparateObjects();
-
-+ CKYStatus getCACAid();
-+ CKYStatus readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
-+ bool throwException);
-+ CKYStatus readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize);
-+
- void selectApplet();
- void selectCACApplet(CKYByte instance);
- void unloadObjects();
-diff -up ./src/libckyapplet/cky_applet.c.cac ./src/libckyapplet/cky_applet.c
---- ./src/libckyapplet/cky_applet.c.cac 2010-06-16 13:43:51.357181000 -0700
-+++ ./src/libckyapplet/cky_applet.c 2010-06-16 14:47:41.305529000 -0700
-@@ -41,7 +41,13 @@
- CKYStatus
- CKYAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
- {
-- return CKYAPDUFactory_SelectFile(apdu,(const CKYBuffer *)param);
-+ return CKYAPDUFactory_SelectFile(apdu, 4, 0, (const CKYBuffer *)param);
-+}
-+
-+CKYStatus
-+CACAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectFile(apdu, 2, 12, (const CKYBuffer *)param);
- }
-
- CKYStatus
-@@ -225,10 +231,17 @@ CKYAppletFactory_GetBuiltinACL(CKYAPDU *
- }
-
- CKYStatus
--CACAppletFactory_SignDecrypt(CKYAPDU *apdu, const void *param)
-+CACAppletFactory_SignDecryptStep(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYBuffer *buf=(CKYBuffer *)param;
-+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_STEP, buf);
-+}
-+
-+CKYStatus
-+CACAppletFactory_SignDecryptFinal(CKYAPDU *apdu, const void *param)
- {
- const CKYBuffer *buf=(CKYBuffer *)param;
-- return CACAPDUFactory_SignDecrypt(apdu, buf);
-+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_FINAL, buf);
- }
-
- CKYStatus
-@@ -246,6 +259,13 @@ CACAppletFactory_GetCertificate(CKYAPDU
- }
-
- CKYStatus
-+CACAppletFactory_ReadFile(CKYAPDU *apdu, const void *param)
-+{
-+ const CACAppletArgReadFile *rfs = (const CACAppletArgReadFile *)param;
-+ return CACAPDUFactory_ReadFile(apdu, rfs->offset, rfs->type, rfs->count);
-+}
-+
-+CKYStatus
- CACAppletFactory_GetProperties(CKYAPDU *apdu, const void *param)
- {
- return CACAPDUFactory_GetProperties(apdu);
-@@ -457,7 +477,7 @@ CKYApplet_SelectFile(CKYCardConnection *
- CKYISOStatus *apduRC)
- {
- return CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, AID, NULL,
-- 0, CKYAppletFill_Null, NULL, apduRC);
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
- }
-
- static CKYByte coolkeyid[] = {0x62, 0x76, 0x01, 0xff, 0x00, 0x00, 0x00 };
-@@ -477,22 +497,23 @@ CKYApplet_SelectCoolKeyManager(CKYCardCo
- return ret;
- }
-
--static CKYByte CACPKIid[] = {0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00 };
-+static CKYByte CACPKIid[] = { 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01 };
- /*
- * Select the CoolKey applet. Must happen after we start a transaction and
- * before we issue any applet specific command.
- */
- CKYStatus
--CACApplet_SelectPKI(CKYCardConnection *conn, CKYByte instance,
-- CKYISOStatus *apduRC)
-+CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cacAID,
-+ CKYByte instance, CKYISOStatus *apduRC)
- {
- CKYStatus ret;
-- CKYBuffer CACPKIAID;
-- CKYBuffer_InitFromData(&CACPKIAID, CACPKIid, sizeof(CACPKIid));
-- CKYBuffer_SetChar(&CACPKIAID, 6, instance);
-- ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CACPKIAID,
-+ CKYBuffer_AppendData(cacAID, CACPKIid, sizeof(CACPKIid));
-+ CKYBuffer_AppendChar(cacAID, instance);
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, cacAID,
- NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-- CKYBuffer_FreeData(&CACPKIAID);
-+ if (ret != CKYSUCCESS) {
-+ CKYBuffer_Resize(cacAID, 0);
-+ }
- return ret;
- }
-
-@@ -515,11 +536,38 @@ CACApplet_SelectCardManager(CKYCardConne
- CKYBuffer CAC_CM_AID;
- CKYBuffer_InitFromData(&CAC_CM_AID, cacmgrid, sizeof(cacmgrid));
- ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
-- NULL, 0, CKYAppletFill_Null, NULL, apduRC);
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
- CKYBuffer_FreeData(&CAC_CM_AID);
- return ret;
- }
-
-+static CKYByte cacCCCid[] = {0xa0, 0x00, 0x00, 0x01, 0x16, 0xdb, 0x00 };
-+CKYStatus
-+CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer CAC_CM_AID;
-+ CKYBuffer_InitFromData(&CAC_CM_AID, cacCCCid, sizeof(cacCCCid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&CAC_CM_AID);
-+ return ret;
-+}
-+
-+CKYStatus
-+CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShortLE(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
- /*
- * GetCPLC cluster -- must be called with CM selected
- */
-@@ -673,8 +721,8 @@ CKYApplet_ComputeCryptProcess(CKYCardCon
- ccd.keyNumber = keyNumber;
- ccd.location = location;
- ccd.data = data;
-- return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptProcess, &ccd,
-- nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptProcess,
-+ &ccd, nonce, 0, CKYAppletFill_Null, NULL, apduRC);
- }
-
- /* computeCrypt returns data in the form :
-@@ -832,11 +880,39 @@ CACApplet_SignDecrypt(CKYCardConnection
- CKYBuffer *result, CKYISOStatus *apduRC)
- {
- CKYStatus ret;
--
-- ret = CKYApplet_HandleAPDU(conn,
-- CACAppletFactory_SignDecrypt, data, NULL,
-- CKYBuffer_Size(data), CKYAppletFill_ReplaceBuffer,
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+
-+ CKYBuffer_Resize(result, 0);
-+ for(offset = 0; (dataSize-offset) > CKY_MAX_WRITE_CHUNK_SIZE;
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE) {
-+ CKYBuffer_Resize(&tmp,0);
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, CKY_MAX_WRITE_CHUNK_SIZE);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptStep,
-+ &tmp, NULL, CKY_SIZE_UNKNOWN,
-+ CKYAppletFill_AppendBuffer,
- result, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ }
-+ CKYBuffer_Resize(&tmp,0);
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, dataSize - offset);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptFinal,
-+ &tmp, NULL, CKY_SIZE_UNKNOWN,
-+ CKYAppletFill_AppendBuffer,
-+ result, apduRC);
-+
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(result) != dataSize)) {
-+ /* RSA returns the same data size as input, didn't happen, so
-+ * something is wrong. */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
- return ret;
- }
-
-@@ -895,6 +971,63 @@ CACApplet_GetCertificate(CKYCardConnecti
- }
- return ret;
- }
-+
-+/*
-+ * Read a CAC Tag/Value file
-+ */
-+CKYStatus
-+CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type, CKYBuffer *buffer,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYByte maxtransfer;
-+ unsigned short offset = 0;
-+ unsigned short size;
-+ CACAppletArgReadFile rfs;
-+
-+ CKYBuffer_Resize(buffer,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+ rfs.offset = 0;
-+ rfs.count = 2;
-+ rfs.type = type;
-+
-+ /* APDU's are expensive, Grab a big chunk of the file first if possible */
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_ReadFile, &rfs, NULL,
-+ rfs.count, CKYAppletFill_AppendBuffer,
-+ buffer, apduRC);
-+ /* file is probably smaller than 100 bytes, get the actual size first */
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ size = CKYBuffer_GetShortLE(buffer, 0) + 2 /* include the length itself */;
-+ maxtransfer = CKY_MAX_READ_CHUNK_SIZE;
-+ /* get the rest of the buffer if necessary */
-+ for (offset = CKYBuffer_Size(buffer); size > offset;
-+ offset = CKYBuffer_Size(buffer)) {
-+ rfs.offset = offset;
-+ rfs.count = MIN(size - offset, maxtransfer);
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_ReadFile, &rfs, NULL,
-+ rfs.count, CKYAppletFill_AppendBuffer,
-+ buffer, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ if (*apduRC == CAC_INVALID_PARAMS) {
-+ maxtransfer = maxtransfer/2;
-+ if (maxtransfer == 0) {
-+ return ret;
-+ }
-+ } else {
-+ return ret;
-+ }
-+ }
-+ }
-+ return ret;
-+}
-+
- CKYStatus
- CACApplet_GetCertificateFirst(CKYCardConnection *conn, CKYBuffer *cert,
- CKYSize *nextSize, CKYISOStatus *apduRC)
-diff -up ./src/libckyapplet/cky_applet.h.cac ./src/libckyapplet/cky_applet.h
---- ./src/libckyapplet/cky_applet.h.cac 2010-06-16 13:43:51.370181000 -0700
-+++ ./src/libckyapplet/cky_applet.h 2010-06-16 13:43:51.572179000 -0700
-@@ -71,6 +71,15 @@ typedef unsigned short CKYISOStatus; /*
- #define CKYISO_INTERNAL_ERROR 0x9cff /* Reserved for debugging,
- * shouldn't happen */
-
-+#define CAC_INVALID_PARAMS 0x6a83
-+#define CAC_TAG_FILE 1
-+#define CAC_VALUE_FILE 2
-+
-+
-+#define CAC_TAG_CARDURL 0xf3
-+#define CAC_TAG_CERTIFICATE 0x70
-+#define CAC_TLV_APP_PKI 0x04
-+
- /*
- * Pin Constants as used by our applet
- */
-@@ -209,6 +218,12 @@ typedef struct _CKYAppletArgComputeCrypt
- const CKYBuffer *sig;
- } CKYAppletArgComputeCrypt;
-
-+typedef struct _CACAppletArgReadFile {
-+ CKYByte type;
-+ CKYByte count;
-+ unsigned short offset;
-+} CACAppletArgReadFile;
-+
- /* fills in an APDU from a structure -- form of all the generic factories*/
- typedef CKYStatus (*CKYAppletFactory)(CKYAPDU *apdu, const void *param);
- /* fills in an a structure from a response -- form of all the fill structures*/
-@@ -451,9 +466,17 @@ CKYStatus CKYApplet_DeleteObject(CKYCard
- /* Select the CAC card manager. Can happen with either applet selected */
- CKYStatus CACApplet_SelectCardManager(CKYCardConnection *conn,
- CKYISOStatus *apduRC);
--/* Can happen with either applet selected */
--CKYStatus CACApplet_SelectPKI(CKYCardConnection *conn, CKYByte instance,
-- CKYISOStatus *apduRC);
-+/* Select the CAC CC container. Can happen with either applet selected */
-+CKYStatus CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+/* Select an old CAC applet and fill in the cardAID */
-+CKYStatus CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cardAid,
-+ CKYByte instance, CKYISOStatus *apduRC);
-+/* read a TLV file */
-+CKYStatus CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type,
-+ CKYBuffer *buffer, CKYISOStatus *apduRC);
-+CKYStatus CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+
- /* must happen with PKI applet selected */
- CKYStatus CACApplet_SignDecrypt(CKYCardConnection *conn, const CKYBuffer *data,
- CKYBuffer *result, CKYISOStatus *apduRC);
-diff -up ./src/libckyapplet/cky_base.c.cac ./src/libckyapplet/cky_base.c
---- ./src/libckyapplet/cky_base.c.cac 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_base.c 2010-06-16 13:43:51.583179000 -0700
-@@ -220,6 +220,22 @@ CKYBuffer_AppendShort(CKYBuffer *buf, un
- return CKYSUCCESS;
- }
-
-+/* append a short in network order */
-+CKYStatus
-+CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 2;
-+ return CKYSUCCESS;
-+}
-+
- /* append a long in applet order */
- CKYStatus
- CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val)
-@@ -238,6 +254,24 @@ CKYBuffer_AppendLong(CKYBuffer *buf, uns
- return CKYSUCCESS;
- }
-
-+/* append a long in applet order */
-+CKYStatus
-+CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+3] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[buf->len+2] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 4;
-+ return CKYSUCCESS;
-+}
-+
- CKYStatus
- CKYBuffer_Replace(CKYBuffer *buf, CKYOffset offset, const CKYByte *data, CKYSize len)
- {
-@@ -351,6 +385,22 @@ CKYBuffer_SetShort(CKYBuffer *buf, CKYOf
- }
-
- CKYStatus
-+CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+2) {
-+ ret = CKYBuffer_Resize(buf,offset+2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
- CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val)
- {
- CKYStatus ret;
-@@ -368,6 +418,24 @@ CKYBuffer_SetLong(CKYBuffer *buf, CKYOff
- return CKYSUCCESS;
- }
-
-+CKYStatus
-+CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+4) {
-+ ret = CKYBuffer_Resize(buf,offset+4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+3] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[offset+2] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
- CKYByte
- CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset)
- {
-@@ -388,6 +456,18 @@ CKYBuffer_GetShort(const CKYBuffer *buf,
- val |= ((unsigned short)buf->data[offset+1]) << 0;
- return val;
- }
-+
-+unsigned short
-+CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned short val;
-+ if (buf->len < offset+2) {
-+ return 0;
-+ }
-+ val = ((unsigned short)buf->data[offset+1]) << 8;
-+ val |= ((unsigned short)buf->data[offset+0]) << 0;
-+ return val;
-+}
-
- unsigned long
- CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset)
-@@ -402,6 +482,20 @@ CKYBuffer_GetLong(const CKYBuffer *buf,
- val |= ((unsigned long)buf->data[offset+3]) << 0;
- return val;
- }
-+
-+unsigned long
-+CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned long val;
-+ if (buf->len < offset+4) {
-+ return 0;
-+ }
-+ val = ((unsigned long)buf->data[offset+3]) << 24;
-+ val |= ((unsigned long)buf->data[offset+2]) << 16;
-+ val |= ((unsigned long)buf->data[offset+1]) << 8;
-+ val |= ((unsigned long)buf->data[offset+0]) << 0;
-+ return val;
-+}
-
- CKYStatus
- CKYBuffer_Resize(CKYBuffer *buf, CKYSize newLen)
-diff -up ./src/libckyapplet/cky_base.h.cac ./src/libckyapplet/cky_base.h
---- ./src/libckyapplet/cky_base.h.cac 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_base.h 2010-06-16 13:43:51.592179000 -0700
-@@ -170,9 +170,15 @@ CKYStatus CKYBuffer_AppendChar(CKYBuffer
- /* append a short in applet order */
- CKYStatus CKYBuffer_AppendShort(CKYBuffer *buf, unsigned short val);
-
-+/* append a short in little endian order */
-+CKYStatus CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val);
-+
- /* append a long in applet order */
- CKYStatus CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val);
-
-+/* append a long in little endian order */
-+CKYStatus CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val);
-+
- /* append data. the data starts at data and extends len bytes */
- CKYStatus CKYBuffer_AppendData(CKYBuffer *buf, const CKYByte *data, CKYSize len);
-
-@@ -210,12 +216,18 @@ CKYStatus CKYBuffer_SetChars(CKYBuffer *
- CKYStatus CKYBuffer_SetShort(CKYBuffer *buf, CKYOffset offset, unsigned short val);
- CKYStatus CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val);
-
-+/* These functions work in little endian order */
-+CKYStatus CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val);
-+CKYStatus CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val);
- /* read a character from offset. If offset is beyond the end of the buffer,
- * then the function returns '0' */
- CKYByte CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset);
- /* These functions work in applet order */
- unsigned short CKYBuffer_GetShort(const CKYBuffer *buf, CKYOffset offset);
- unsigned long CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset);
-+/* These functions work in little endian order */
-+unsigned short CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset);
-+unsigned long CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset);
-
- /* clear out all the data in a buffer */
- void CKYBuffer_Zero(CKYBuffer *buf);
-diff -up ./src/libckyapplet/cky_factory.c.cac ./src/libckyapplet/cky_factory.c
---- ./src/libckyapplet/cky_factory.c.cac 2010-06-16 13:43:51.393185000 -0700
-+++ ./src/libckyapplet/cky_factory.c 2010-06-16 14:48:08.885473000 -0700
-@@ -25,12 +25,13 @@
- * special commands can be issued at any time
- */
- CKYStatus
--CKYAPDUFactory_SelectFile(CKYAPDU *apdu, const CKYBuffer *AID)
-+CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ const CKYBuffer *AID)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
- CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE);
-- CKYAPDU_SetP1(apdu, 0x04);
-- CKYAPDU_SetP2(apdu, 0x00);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
- return CKYAPDU_SetSendDataBuffer(apdu, AID);
- }
-
-@@ -131,6 +132,7 @@ fail:
- return ret;
- }
-
-+
- CKYStatus
- CKYAPDUFactory_ComputeCryptFinal(CKYAPDU *apdu, CKYByte keyNumber,
- CKYByte location, const CKYBuffer *data, const CKYBuffer *sig)
-@@ -572,11 +574,11 @@ CKYAPDUFactory_GetBuiltinACL(CKYAPDU *ap
- }
-
- CKYStatus
--CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, const CKYBuffer *data)
-+CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type, const CKYBuffer *data)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
- CKYAPDU_SetINS(apdu, CAC_INS_SIGN_DECRYPT);
-- CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP1(apdu, type);
- CKYAPDU_SetP2(apdu, 0x00);
- return CKYAPDU_SetSendDataBuffer(apdu, data);
- }
-@@ -592,6 +594,36 @@ CACAPDUFactory_GetCertificate(CKYAPDU *a
- }
-
- CKYStatus
-+CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte type, CKYByte count)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM);
-+ CKYAPDU_SetINS(apdu, CAC_INS_READ_FILE);
-+ CKYAPDU_SetP1(apdu, (offset >> 8) & 0xff);
-+ CKYAPDU_SetP2(apdu, offset & 0xff);
-+ ret = CKYBuffer_Reserve(&buf, 2);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, type);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, count);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
- CACAPDUFactory_GetProperties(CKYAPDU *apdu)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-diff -up ./src/libckyapplet/cky_factory.h.cac ./src/libckyapplet/cky_factory.h
---- ./src/libckyapplet/cky_factory.h.cac 2010-06-16 13:43:51.402181000 -0700
-+++ ./src/libckyapplet/cky_factory.h 2010-06-16 14:43:20.867049000 -0700
-@@ -86,7 +86,11 @@
- #define CAC_INS_SIGN_DECRYPT 0x42
- #define CAC_INS_VERIFY_PIN 0x20
- #define CAC_INS_GET_PROPERTIES 0x56
-+#define CAC_INS_READ_FILE 0x52
-+
- #define CAC_SIZE_GET_PROPERTIES 48
-+#define CAC_P1_STEP 0x80
-+#define CAC_P1_FINAL 0x00
-
- /*
- * Fixed return sized from various commands
-@@ -169,7 +173,8 @@
- CKY_BEGIN_PROTOS
-
- /* function based factorys */
--CKYStatus CKYAPDUFactory_SelectFile(CKYAPDU *apdu, const CKYBuffer *AID);
-+CKYStatus CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ const CKYBuffer *AID);
- CKYStatus CKYAPDUFactory_SelectCardManager(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_GetCPLCData(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_ListKeys(CKYAPDU *apdu, CKYByte sequence);
-@@ -211,9 +216,12 @@ CKYStatus CKYAPDUFactory_SeedRandom(CKYA
- CKYStatus CKYAPDUFactory_GetIssuerInfo(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_GetBuiltinACL(CKYAPDU *apdu);
-
--CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, const CKYBuffer *data);
-+CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type,
-+ const CKYBuffer *data);
- CKYStatus CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin);
- CKYStatus CACAPDUFactory_GetCertificate(CKYAPDU *apdu, CKYSize size);
-+CKYStatus CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte type, CKYByte count);
- CKYStatus CACAPDUFactory_GetProperties(CKYAPDU *apdu);
-
- CKY_END_PROTOS
diff --git a/coolkey-cache-dir-move.patch b/coolkey-cache-dir-move.patch
deleted file mode 100644
index 1b5eaff..0000000
--- a/coolkey-cache-dir-move.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-Index: src/coolkey/machdep.cpp
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/machdep.cpp,v
-retrieving revision 1.4
-diff -u -r1.4 machdep.cpp
---- src/coolkey/machdep.cpp 14 Feb 2007 00:46:28 -0000 1.4
-+++ src/coolkey/machdep.cpp 15 Aug 2007 01:41:11 -0000
-@@ -185,12 +185,20 @@
- #define MAP_INHERIT 0
- #endif
-
-+#ifndef BASEPATH
-+#ifdef MAC
-+#define BASEPATH "/var"
-+#else
-+#define BASEPATH "/var/cache"
-+#endif
-+#endif
-+
- #ifdef FULL_CLEANUP
- #define RESERVED_OFFSET 256
--#define MEMSEGPATH "/tmp/.pk11ipc"
-+#define MEMSEGPATH BASEPATH"/coolkey-lock"
- #else
- #define RESERVED_OFFSET 0
--#define MEMSEGPATH "/tmp/.pk11ipc1"
-+#define MEMSEGPATH BASEPATH"/coolkey"
- #endif
-
- struct SHMemData {
-@@ -208,11 +216,6 @@
- #ifdef FULL_CLEANUP
- flock(fd,LOCK_EX);
- unsigned long ref = --(*(unsigned long *)addr);
--#ifdef notdef
-- if (ref == 0) {
-- unlink(path);
-- }
--#endif
- flock(fd, LOCK_UN);
- #endif
- munmap(addr,size+RESERVED_OFFSET);
-@@ -225,6 +228,73 @@
- }
- }
-
-+/*
-+ * The cache directory is shared and accessible by anyone, make
-+ * sure the cache file we are opening is really a valid cache file.
-+ */
-+int safe_open(char *path, int flags, int mode, int size)
-+{
-+ struct stat buf;
-+ int fd, ret;
-+
-+ fd = open (path, flags|O_NOFOLLOW, mode);
-+
-+ if (fd < 0) {
-+ return fd;
-+ }
-+
-+ ret = fstat(fd, &buf);
-+ if (ret < 0) {
-+ close (fd);
-+ return ret;
-+ }
-+
-+ /* our cache files are pretty specific, make sure we are looking
-+ * at the correct one */
-+
-+ /* first, we should own the file ourselves, don't open a file
-+ * that someone else wanted us to see. */
-+ if (buf.st_uid != getuid()) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* next, there should only be one link in this file. Don't
-+ * use this code to trash another file */
-+ if (buf.st_nlink != 1) {
-+ close(fd);
-+ errno = EMLINK;
-+ return -1;
-+ }
-+
-+ /* next, This better be a regular file */
-+ if (!S_ISREG(buf.st_mode)) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* if the permissions don't match, something is wrong */
-+ if ((buf.st_mode & 03777) != mode) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* finally the file should be the correct size. This
-+ * check isn't so much to protect from an attack, as it is to
-+ * detect a corrupted cache file */
-+ if (buf.st_size != size) {
-+ close(fd);
-+ errno = EACCES;
-+ return -1;
-+ }
-+
-+ /* OK, the file checked out, ok to continue */
-+ return fd;
-+}
-+
- SHMem::SHMem(): shmemData(0) {}
-
- SHMem *
-@@ -248,7 +318,7 @@
- return NULL;
- }
- int mask = umask(0);
-- int ret = mkdir (MEMSEGPATH, 0777);
-+ int ret = mkdir (MEMSEGPATH, 01777);
- umask(mask);
- if ((ret == -1) && (errno != EEXIST)) {
- delete shmemData;
-@@ -264,21 +334,16 @@
- shmemData->path[sizeof(MEMSEGPATH)-1] = '/';
- strcpy(&shmemData->path[sizeof(MEMSEGPATH)],name);
-
-- int mode = 0777;
-- if (strcmp(name,"token_names") != 0) {
-- /* each user gets his own uid array */
-- sprintf(uid_str, "-%u",getuid());
-- strcat(shmemData->path,uid_str);
-- mode = 0700;
-- }
-+ sprintf(uid_str, "-%u",getuid());
-+ strcat(shmemData->path,uid_str);
-+ int mode = 0600;
-+
- shmemData->fd = open(shmemData->path,
- O_CREAT|O_RDWR|O_EXCL|O_APPEND|O_EXLOCK, mode);
-- if (shmemData->fd < 0) {
-- needInit = false;
-- shmemData->fd = open(shmemData->path,O_RDWR|O_EXLOCK, mode);
-- } else {
-+ if (shmemData->fd >= 0) {
- char *buf;
- int len = size+RESERVED_OFFSET;
-+ int ret;
-
- buf = (char *)calloc(1,len);
- if (!buf) {
-@@ -289,8 +354,22 @@
- delete shmemData;
- return NULL;
- }
-- write(shmemData->fd,buf,len);
-+ ret = write(shmemData->fd,buf,len);
-+ if (ret != len) {
-+ unlink(shmemData->path);
-+#ifdef FULL_CLEANUP
-+ flock(shmemData->fd, LOCK_UN);
-+#endif
-+ delete shmemData;
-+ return NULL;
-+ }
-+
- free(buf);
-+ } else if (errno == EEXIST) {
-+ needInit = false;
-+
-+ shmemData->fd = safe_open(shmemData->path,O_RDWR|O_EXLOCK, mode,
-+ size+RESERVED_OFFSET);
- }
- if (shmemData->fd < 0) {
- delete shmemData;
diff --git a/coolkey-fix-token-removal-failure.patch b/coolkey-fix-token-removal-failure.patch
deleted file mode 100644
index 7f8a954..0000000
--- a/coolkey-fix-token-removal-failure.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-Fix insertion/removal detection
-
-pcsc now errors out of the SCardGetStatusChange call with
-SCARD_E_UNKNOWN_READER if any of the passed readers aren't known.
-This includes readers that were very recently forgotton about because
-a user just disconnected them.
-
-(See
- http://anonscm.debian.org/viewvc/pcsclite/trunk/PCSC/src/winscard_clnt.c?...
-for the change to pcsc)
-
-Unfortunately, this means SECMOD_WaitForAnyTokenEvent will fail with a
-SC_NO_EVENT error if a user removes their smartcard at the wrong time.
-
-This patch changes coolkey to detect removed readers before calling
-SCardGetStatusChange, so that it can handle the removal itself.
-
-diff -up coolkey-1.1.0/src/coolkey/slot.cpp.fix coolkey-1.1.0/src/coolkey/slot.cpp
---- coolkey-1.1.0/src/coolkey/slot.cpp.fix 2013-05-22 16:23:41.728846957 -0400
-+++ coolkey-1.1.0/src/coolkey/slot.cpp 2013-05-22 17:09:59.813958927 -0400
-@@ -279,24 +279,22 @@ SlotList::updateReaderList()
- * don't recognize.
- */
-
-- /* first though, let's check to see if any previously removed readers have
-- * come back from the dead. If the ignored bit has been set, we do not need
-- * it any more.
-- */
-+ /* Iterate through all the readers to see if we need to make unavailable any
-+ * freshly removed readers. Also, see if any previously removed
-+ * readers have come back from the dead and don't need to be ignored.
-+ */
-
- const char *curReaderName = NULL;
- unsigned long knownState = 0;
- for(int ri = 0 ; ri < numReaders; ri ++) {
--
- knownState = CKYReader_GetKnownState(&readerStates[ri]);
-- if( !(knownState & SCARD_STATE_IGNORE)) {
-- continue;
-- }
--
-+
- curReaderName = CKYReader_GetReaderName(&readerStates[ri]);
- if(readerNameExistsInList(curReaderName,&readerNames)) {
- CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE);
--
-+ } else {
-+ if (!(knownState & SCARD_STATE_UNAVAILABLE))
-+ CKYReader_SetKnownState(&readerStates[ri], knownState | SCARD_STATE_UNAVAILABLE | SCARD_STATE_CHANGED);
- }
- }
-
-@@ -1238,6 +1236,32 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- throw;
- }
-
-+ /* Before round-tripping to the daemon for the duration of the
-+ * timeout, first see if we lost any readers, and pick a slot
-+ * from that set to return
-+ */
-+ for (i=0; i < numReaders; i++) {
-+ unsigned long knownState = CKYReader_GetKnownState(&readerStates[i]);
-+
-+ if ((knownState & SCARD_STATE_UNAVAILABLE) &&
-+ (knownState & SCARD_STATE_CHANGED)) {
-+ CKYReader_SetKnownState(&readerStates[i], knownState & ~SCARD_STATE_CHANGED);
-+ readerListLock.releaseLock();
-+ *slotp = slotIndexToID(i);
-+ found = TRUE;
-+ break;
-+ }
-+ }
-+
-+ if (found) {
-+ break;
-+ }
-+
-+ if (shuttingDown) {
-+ readerListLock.releaseLock();
-+ break;
-+ }
-+
- if (myNumReaders != numReaders) {
- if (myReaderStates) {
- delete [] myReaderStates;
diff --git a/coolkey-gcc43.patch b/coolkey-gcc43.patch
deleted file mode 100644
index 5e41b5a..0000000
--- a/coolkey-gcc43.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.coolkey-gcc43 ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-gcc43 2008-02-13 18:01:45.000000000 -0800
-+++ ./src/coolkey/slot.cpp 2008-02-13 18:03:05.000000000 -0800
-@@ -25,7 +25,6 @@
- #include "PKCS11Exception.h"
- #include <winscard.h>
- #include "slot.h"
--#include <memory.h>
- #include "zlib.h"
- #include "params.h"
-
-@@ -33,7 +32,6 @@
-
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
-
--using std::auto_ptr;
-
-
- #ifdef DEBUG
-diff -up ./src/coolkey/machdep.cpp.coolkey-gcc43 ./src/coolkey/machdep.cpp
---- ./src/coolkey/machdep.cpp.coolkey-gcc43 2008-02-13 18:02:06.000000000 -0800
-+++ ./src/coolkey/machdep.cpp 2008-02-13 18:04:04.000000000 -0800
-@@ -33,6 +33,8 @@
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <pthread.h>
-+#include <string.h>
-+#include <stdlib.h>
- #endif
-
- #ifdef _WIN32
-diff -up ./src/coolkey/log.cpp.coolkey-gcc43 ./src/coolkey/log.cpp
---- ./src/coolkey/log.cpp.coolkey-gcc43 2008-02-13 18:01:55.000000000 -0800
-+++ ./src/coolkey/log.cpp 2008-02-13 18:03:37.000000000 -0800
-@@ -18,6 +18,8 @@
- * ***** END COPYRIGHT BLOCK *****/
-
- #include <string>
-+#include <string.h>
-+#include <stdlib.h>
- #include "mypkcs11.h"
- #include <assert.h>
- #include <stdio.h>
-diff -up ./src/coolkey/object.cpp.coolkey-gcc43 ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.coolkey-gcc43 2008-02-13 18:02:20.000000000 -0800
-+++ ./src/coolkey/object.cpp 2008-02-13 18:04:22.000000000 -0800
-@@ -21,6 +21,7 @@
- #include "PKCS11Exception.h"
- #include "object.h"
- #include <algorithm>
-+#include <string.h>
-
- using std::find_if;
-
diff --git a/coolkey-latest.patch b/coolkey-latest.patch
deleted file mode 100644
index bc10eb8..0000000
--- a/coolkey-latest.patch
+++ /dev/null
@@ -1,685 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.coolkey-latest ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-latest 2009-09-11 13:58:24.423487305 -0700
-+++ ./src/coolkey/slot.cpp 2009-09-11 14:04:30.813488220 -0700
-@@ -203,6 +203,29 @@ SlotList::readerExists(const char *reade
- return FALSE;
- }
-
-+bool
-+SlotList::readerNameExistsInList(const char *readerName,CKYReaderNameList *readerNameList)
-+{
-+ if( !readerName || !readerNameList) {
-+ return FALSE;
-+ }
-+
-+ int i = 0;
-+ int readerNameCnt = CKYReaderNameList_GetCount(*readerNameList);
-+
-+ const char *curReaderName = NULL;
-+ for(i=0; i < readerNameCnt; i++) {
-+ curReaderName = CKYReaderNameList_GetValue(*readerNameList,i);
-+
-+ if(!strcmp(curReaderName,readerName)) {
-+ return TRUE;
-+ }
-+
-+ }
-+
-+ return FALSE;
-+}
-+
- /*
- * you need to hold the ReaderList Lock before you can update the ReaderList
- */
-@@ -256,6 +279,27 @@ SlotList::updateReaderList()
- * don't recognize.
- */
-
-+ /* first though, let's check to see if any previously removed readers have
-+ * come back from the dead. If the ignored bit has been set, we do not need
-+ * it any more.
-+ */
-+
-+ const char *curReaderName = NULL;
-+ unsigned long knownState = 0;
-+ for(int ri = 0 ; ri < numReaders; ri ++) {
-+
-+ knownState = CKYReader_GetKnownState(&readerStates[ri]);
-+ if( !(knownState & SCARD_STATE_IGNORE)) {
-+ continue;
-+ }
-+
-+ curReaderName = CKYReader_GetReaderName(&readerStates[ri]);
-+ if(readerNameExistsInList(curReaderName,&readerNames)) {
-+ CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE);
-+
-+ }
-+ }
-+
- const char *newReadersData[MAX_READER_DELTA];
- const char **newReaders = &newReadersData[0];
- unsigned int newReaderCount = 0;
-@@ -528,7 +572,7 @@ SlotList::getSlotList(CK_BBOOL tokenPres
- void
- Slot::connectToToken()
- {
-- CKYStatus status;
-+ CKYStatus status = CKYSCARDERR;
- OSTime time = OSTimeNow();
-
- mCoolkey = 0;
-@@ -537,13 +581,31 @@ Slot::connectToToken()
-
- // try to connect to the card
- if( ! CKYCardConnection_IsConnected(conn) ) {
-- status = CKYCardConnection_Connect(conn, readerName);
-- if( status != CKYSUCCESS ) {
-- log->log("Unable to connect to token\n");
-+ int i = 0;
-+ //for cranky readers try again a few more times
-+ while( i++ < 5 && status != CKYSUCCESS )
-+ {
-+ status = CKYCardConnection_Connect(conn, readerName);
-+ if( status != CKYSUCCESS &&
-+ CKYCardConnection_GetLastError(conn) == SCARD_E_PROTO_MISMATCH )
-+ {
-+ log->log("Unable to connect to token status %d ConnGetGetLastError %x .\n",status,CKYCardConnection_GetLastError(conn));
-+
-+ }
-+ else
-+ {
-+ break;
-+ }
-+ OSSleep(100000);
-+ }
-+
-+ if( status != CKYSUCCESS)
-+ {
- state = UNKNOWN;
- return;
- }
- }
-+
- log->log("time connect: Connect Time %d ms\n", OSTimeNow() - time);
- if (!slotInfoFound) {
- readSlotInfo();
-@@ -562,15 +624,10 @@ Slot::connectToToken()
- state = CARD_PRESENT;
- }
-
-- if ( CKYBuffer_DataIsEqual(&cardATR, ATR, sizeof (ATR)) ||
-- CKYBuffer_DataIsEqual(&cardATR, ATR1, sizeof(ATR1)) ||
-- CKYBuffer_DataIsEqual(&cardATR, ATR2, sizeof(ATR2)) ) {
--
-- if (Params::hasParam("noAppletOK"))
-- {
-- state |= APPLET_SELECTABLE;
-- mCoolkey = 1;
-- }
-+ if (Params::hasParam("noAppletOK"))
-+ {
-+ state |= APPLET_SELECTABLE;
-+ mCoolkey = 1;
- }
-
- /* support CAC card. identify the card based on applets, not the ATRS */
-@@ -631,7 +688,7 @@ Slot::connectToToken()
- * unfriendly */
- isVersion1Key = 0;
- needLogin = 1;
--
-+ mCoolkey = 0;
- return;
- }
- mCoolkey = 1;
-@@ -1077,6 +1134,7 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- }
- throw;
- }
-+
- if (myNumReaders != numReaders) {
- if (myReaderStates) {
- delete [] myReaderStates;
-@@ -1103,6 +1161,7 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- }
- }
- }
-+
- if (found || (flag == CKF_DONT_BLOCK) || shuttingDown) {
- break;
- }
-@@ -1272,6 +1331,19 @@ class ObjectHandleMatch {
- }
- };
-
-+class KeyNumMatch {
-+ private:
-+ CKYByte keyNum;
-+ const Slot &slot;
-+ public:
-+ KeyNumMatch(CKYByte keyNum_, const Slot &s) : keyNum(keyNum_), slot(s) { }
-+ bool operator() (const PKCS11Object& obj) {
-+ unsigned long objID = obj.getMuscleObjID();
-+ return (slot.getObjectClass(objID) == 'k')
-+ && (slot.getObjectIndex(objID) == keyNum);
-+ }
-+};
-+
- class ObjectCertCKAIDMatch {
- private:
- CKYByte cka_id;
-@@ -3007,8 +3079,9 @@ Slot::sign(SessionHandleSuffix suffix, C
- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
- {
-+ RSASignatureParams params(CryptParams::DEFAULT_KEY_SIZE);
- cryptRSA(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-- RSASignatureParams(CryptParams::FIXED_KEY_SIZE));
-+ params);
- }
-
- void
-@@ -3016,14 +3089,15 @@ Slot::decrypt(SessionHandleSuffix suffix
- CK_ULONG ulDataLen, CK_BYTE_PTR pDecryptedData,
- CK_ULONG_PTR pulDecryptedDataLen)
- {
-+ RSADecryptParams params(CryptParams::DEFAULT_KEY_SIZE);
- cryptRSA(suffix, pData, ulDataLen, pDecryptedData, pulDecryptedDataLen,
-- RSADecryptParams(CryptParams::FIXED_KEY_SIZE));
-+ params);
- }
-
- void
- Slot::cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
- CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-- CK_ULONG_PTR pulOutputLen, const CryptParams& params)
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params)
- {
- refreshTokenState();
- SessionIter session = findSession(suffix);
-@@ -3041,6 +3115,11 @@ Slot::cryptRSA(SessionHandleSuffix suffi
- CKYBuffer *result = &opState.result;
- CKYByte keyNum = opState.keyNum;
-
-+ unsigned int keySize = getKeySize(keyNum);
-+
-+ if(keySize != CryptParams::DEFAULT_KEY_SIZE)
-+ params.setKeySize(keySize);
-+
- if( CKYBuffer_Size(result) == 0 ) {
- // we haven't already peformed the decryption, so do it now.
- if( pInput == NULL || ulInputLen == 0) {
-@@ -3243,3 +3322,36 @@ Slot::generateRandom(SessionHandleSuffix
- throw PKCS11Exception(CKR_DEVICE_ERROR);
- }
- }
-+
-+#define MAX_NUM_KEYS 8
-+unsigned int
-+Slot::getKeySize(CKYByte keyNum)
-+{
-+ unsigned int keySize = CryptParams::DEFAULT_KEY_SIZE;
-+ int modSize = 0;
-+
-+ if(keyNum >= MAX_NUM_KEYS) {
-+ return keySize;
-+ }
-+
-+ ObjectConstIter iter;
-+ iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-+ KeyNumMatch(keyNum,*this));
-+
-+ if( iter == tokenObjects.end() ) {
-+ return keySize;
-+ }
-+
-+ CKYBuffer const *modulus = iter->getAttribute(CKA_MODULUS);
-+
-+ if(modulus) {
-+ modSize = CKYBuffer_Size(modulus);
-+ if(CKYBuffer_GetChar(modulus,0) == 0x0) {
-+ modSize--;
-+ }
-+ if(modSize > 0)
-+ keySize = modSize * 8;
-+ }
-+
-+ return keySize;
-+}
-diff -up ./src/coolkey/slot.h.coolkey-latest ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.coolkey-latest 2006-06-09 11:39:11.000000000 -0700
-+++ ./src/coolkey/slot.h 2009-09-11 13:58:24.462488099 -0700
-@@ -270,10 +270,9 @@ class CryptParams {
- protected:
- unsigned int getKeySize() const { return keySize; }
- public:
-- // !!!XXX hack. The right way to get the key size is to get all the
-- // key information from the token with MSCListKeys, the same way
-- // we get all the object information with MSCListObjects.
-- enum { FIXED_KEY_SIZE = 1024 };
-+ // set the actual key size obtained from the card
-+ void setKeySize(unsigned int newKeySize) { keySize = newKeySize; }
-+ enum { DEFAULT_KEY_SIZE = 1024 };
-
-
- CryptParams(unsigned int keySize_) : keySize(keySize_) { }
-@@ -422,7 +421,7 @@ class Slot {
-
- void cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
- CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-- CK_ULONG_PTR pulOutputLen, const CryptParams& params);
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params);
-
- void performRSAOp(CKYBuffer *out, const CKYBuffer *input, CKYByte keyNum,
- CKYByte direction);
-@@ -460,6 +459,8 @@ class Slot {
- return (char )((objectID >> 16) & 0xff) - '0';
- }
-
-+ // actually get the size of a key in bits from the card
-+ unsigned int getKeySize(CKYByte keyNum);
-
- SessionHandleSuffix openSession(Session::Type type);
- void closeSession(SessionHandleSuffix handleSuffix);
-@@ -527,6 +528,8 @@ class SlotList {
- * has called 'C_GetSlotList' with a NULL parameter */
- void updateReaderList();
-
-+ /* see if a reader name exists in a caller provided reader name list. */
-+ bool readerNameExistsInList(const char *readerName,CKYReaderNameList *readerNameList );
- bool readerExists(const char *readerName, unsigned int *hint = 0);
- public:
- SlotList(Log *log);
-diff -up ./src/libckyapplet/cky_applet.c.coolkey-latest ./src/libckyapplet/cky_applet.c
---- ./src/libckyapplet/cky_applet.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_applet.c 2009-09-11 13:58:24.464487796 -0700
-@@ -134,6 +134,13 @@ CKYAppletFactory_Logout(CKYAPDU *apdu, c
- /* Future add WriteObject */
-
- CKYStatus
-+CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgWriteObject *wos = (const CKYAppletArgWriteObject *)param;
-+ return CKYAPDUFactory_WriteObject(apdu,wos->objectID,wos->offset,wos->size,wos->data);
-+}
-+
-+CKYStatus
- CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param)
- {
- const CKYAppletArgCreateObject *cos=(const CKYAppletArgCreateObject *)param;
-@@ -192,7 +199,6 @@ CKYAppletFactory_GetLifeCycleV2(CKYAPDU
- {
- return CKYAPDUFactory_GetLifeCycleV2(apdu);
- }
--
- CKYStatus
- CKYAppletFactory_GetRandom(CKYAPDU *apdu, const void *param)
- {
-@@ -725,24 +731,48 @@ CKYApplet_ComputeCrypt(CKYCardConnection
- CKYAppletArgComputeCrypt ccd;
- CKYBuffer empty;
- CKYISOStatus status;
-+ short dataSize = 0;
- int use2APDUs = 0;
-+ int use_dl_object = CKYBuffer_Size(data) > 200 ;
-
- CKYBuffer_InitEmpty(&empty);
- ccd.keyNumber = keyNumber;
- ccd.mode = mode;
- ccd.direction = direction;
-- ccd.location = CKY_DL_APDU;
-+ ccd.location = use_dl_object ? CKY_DL_OBJECT : CKY_DL_APDU;
-
- if (!apduRC)
- apduRC = &status;
-
-+ if (use_dl_object) {
-+ CKYBuffer sizeBuf;
-+
-+ CKYBuffer_InitEmpty(&sizeBuf);
-+ CKYBuffer_AppendShort(&sizeBuf, CKYBuffer_Size(data));
-+
-+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
-+ 0, CKYBuffer_Size(&sizeBuf), nonce,
-+ &sizeBuf, apduRC);
-+
-+ CKYBuffer_FreeData(&sizeBuf);
-+ if( ret != CKYSUCCESS)
-+ goto fail;
-+
-+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
-+ 2, CKYBuffer_Size(data), nonce,
-+ data, apduRC);
-+
-+ if(ret != CKYSUCCESS)
-+ goto fail;
-+ }
-+
- if (mode == CKY_RSA_NO_PAD) {
-- ccd.data = data;
-+ ccd.data = use_dl_object ? &empty : data;
- ccd.sig = sig;
- ret = CKYApplet_HandleAPDU(conn,
- CKYAppletFactory_ComputeCryptOneStep, &ccd, nonce,
- CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
-- result, apduRC);
-+ use_dl_object ? NULL : result, apduRC);
- if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
- use2APDUs = 1; /* maybe it's an old applet */
- }
-@@ -759,13 +789,38 @@ CKYApplet_ComputeCrypt(CKYCardConnection
- CKYAppletFactory_ComputeCryptInit, &ccd, nonce,
- 0, CKYAppletFill_Null, NULL, apduRC);
- if (ret == CKYSUCCESS) {
-- ccd.data = data;
-+ ccd.data = use_dl_object ? &empty : data;
- ret = CKYApplet_HandleAPDU(conn,
- CKYAppletFactory_ComputeCryptFinal, &ccd, nonce,
- CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
-- result, apduRC);
-+ use_dl_object ? NULL : result, apduRC);
- }
- }
-+
-+ if (use_dl_object && ret == CKYSUCCESS) {
-+ CKYBuffer sizeOutBuf;
-+ CKYBuffer_InitEmpty(&sizeOutBuf);
-+
-+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
-+ 0, 2,
-+ nonce,&sizeOutBuf,apduRC);
-+
-+ if(ret != CKYSUCCESS) {
-+ CKYBuffer_FreeData(&sizeOutBuf);
-+ goto fail;
-+ }
-+
-+ dataSize = CKYBuffer_GetShort(&sizeOutBuf, 0);
-+
-+ CKYBuffer_FreeData(&sizeOutBuf);
-+
-+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
-+ 2, dataSize,
-+ nonce,result,apduRC);
-+ }
-+
-+fail:
-+
- return ret;
- }
-
-@@ -1036,6 +1091,44 @@ CKYApplet_ReadObjectFull(CKYCardConnecti
- }
-
- /*
-+ * Write Object
-+ * This makes multiple APDU calls to write the entire object.
-+ *
-+ */
-+
-+CKYStatus
-+CKYApplet_WriteObjectFull(CKYCardConnection *conn, unsigned long objectID,
-+ CKYOffset offset, CKYSize size, const CKYBuffer *nonce,
-+ const CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+
-+ CKYBuffer chunk;
-+ CKYOffset srcOffset = 0;
-+ CKYAppletArgWriteObject wod;
-+ CKYStatus ret = CKYSUCCESS;
-+
-+ wod.objectID = objectID;
-+ wod.offset = offset;
-+ do {
-+ wod.size = (CKYByte) MIN(size, 220);
-+ ret = CKYBuffer_InitFromBuffer(&chunk, data,
-+ srcOffset, wod.size);
-+ if(ret == CKYSUCCESS) {
-+ wod.data = &chunk;
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_WriteObject, &wod,
-+ nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+ size -= wod.size;
-+ wod.offset += wod.size;
-+ srcOffset += wod.size;
-+ CKYBuffer_FreeData(&chunk);
-+ }
-+
-+ } while ((size > 0) && (ret == CKYSUCCESS));
-+
-+ return ret;
-+}
-+
-+/*
- * List Object cluster
- */
- static CKYStatus
-diff -up ./src/libckyapplet/cky_applet.h.coolkey-latest ./src/libckyapplet/cky_applet.h
---- ./src/libckyapplet/cky_applet.h.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_applet.h 2009-09-11 13:58:24.466487772 -0700
-@@ -192,6 +192,14 @@ typedef struct _CKYAppletArgReadObject {
- CKYByte size;
- } CKYAppletArgReadObject;
-
-+typedef struct _CKYAppletArgWriteObject {
-+ unsigned long objectID;
-+ CKYOffset offset;
-+ CKYByte size;
-+ CKYBuffer *data;
-+
-+} CKYAppletArgWriteObject;
-+
- typedef struct _CKYAppletArgComputeCrypt {
- CKYByte keyNumber;
- CKYByte mode;
-@@ -250,6 +258,8 @@ CKYStatus CKYAppletFactory_ListPINs(CKYA
- /* param == CKYByte * (pointer to pinNumber) */
- CKYStatus CKYAppletFactory_Logout(CKYAPDU *apdu, const void *param);
- /* Future add WriteObject */
-+/* parm == CKYAppletArgWriteObject */
-+CKYStatus CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param);
- /* param == CKYAppletArgCreateObject */
- CKYStatus CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param);
- /* param == CKYAppletArgDeleteObject */
-@@ -482,6 +492,17 @@ CKYStatus CKYApplet_ReadObjectAppend(CKY
- CKYStatus CKYApplet_ReadObjectFull(CKYCardConnection *conn,
- unsigned long objectID, CKYOffset offset, CKYSize size,
- const CKYBuffer *nonce, CKYBuffer *data, CKYISOStatus *apduRC);
-+/*
-+ * There is 1 write command:
-+ * CKYApplet_WriteObjectFull can write an entire data object. It makes multiple
-+ * apdu calls in order to write the full amount into the buffer. The buffer is
-+ * overwritten.
-+*/
-+
-+CKYStatus CKYApplet_WriteObjectFull(CKYCardConnection *conn,
-+ unsigned long objectID, CKYOffset offset, CKYSize size,
-+ const CKYBuffer *nonce, const CKYBuffer *data, CKYISOStatus *apduRC);
-+
- CKYStatus CKYApplet_ListObjects(CKYCardConnection *conn, CKYByte seq,
- CKYAppletRespListObjects *lop, CKYISOStatus *apduRC);
- CKYStatus CKYApplet_GetStatus(CKYCardConnection *conn,
-diff -up ./src/libckyapplet/cky_card.c.coolkey-latest ./src/libckyapplet/cky_card.c
---- ./src/libckyapplet/cky_card.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_card.c 2009-09-11 13:58:24.468487469 -0700
-@@ -129,6 +129,7 @@ typedef struct _SCard {
- SCardGetStatusChangeFn SCardGetStatusChange;
- SCardCancelFn SCardCancel;
- SCARD_IO_REQUEST *SCARD_PCI_T0_;
-+ SCARD_IO_REQUEST *SCARD_PCI_T1_;
- } SCard;
-
- #define GET_ADDRESS(library, scard, name) \
-@@ -195,6 +196,12 @@ ckySCard_Init(void)
- if( status != CKYSUCCESS ) {
- goto fail;
- }
-+
-+ status = ckyShLibrary_getAddress( library,
-+ (void**) &scard->SCARD_PCI_T1_, MAKE_DLL_SYMBOL(g_rgSCardT1Pci));
-+ if( status != CKYSUCCESS ) {
-+ goto fail;
-+ }
- return scard;
-
- fail:
-@@ -884,6 +891,7 @@ struct _CKYCardConnection {
- SCARDHANDLE cardHandle;
- unsigned long lastError;
- CKYBool inTransaction;
-+ unsigned long protocol;
- };
-
- static void
-@@ -894,6 +902,7 @@ ckyCardConnection_init(CKYCardConnection
- conn->cardHandle = 0;
- conn->lastError = 0;
- conn->inTransaction = 0;
-+ conn->protocol = SCARD_PROTOCOL_T0;
- }
-
- CKYCardConnection *
-@@ -934,14 +943,13 @@ CKYCardConnection_Connect(CKYCardConnect
- {
- CKYStatus ret;
- unsigned long rv;
-- unsigned long protocol;
-
- ret = CKYCardConnection_Disconnect(conn);
- if (ret != CKYSUCCESS) {
- return ret;
- }
- rv = conn->scard->SCardConnect( conn->ctx->context, readerName,
-- SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &conn->cardHandle, &protocol);
-+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &conn->cardHandle, &conn->protocol);
- if (rv != SCARD_S_SUCCESS) {
- conn->lastError = rv;
- return CKYSCARDERR;
-@@ -978,7 +986,7 @@ ckyCardConnection_reconnectRaw(CKYCardCo
- unsigned long protocol;
-
- rv = conn->scard->SCardReconnect(conn->cardHandle,
-- SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, init, &protocol);
-+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 , init, &protocol);
- if (rv != SCARD_S_SUCCESS) {
- conn->lastError = rv;
- return CKYSCARDERR;
-@@ -1039,10 +1047,17 @@ CKYCardConnection_TransmitAPDU(CKYCardCo
- return ret;
- }
-
-- rv = conn->scard->SCardTransmit(conn->cardHandle,
-- conn->scard->SCARD_PCI_T0_,
-- CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-- NULL, response->data, &response->len);
-+ if( conn->protocol == SCARD_PROTOCOL_T0 ) {
-+ rv = conn->scard->SCardTransmit(conn->cardHandle,
-+ conn->scard->SCARD_PCI_T0_,
-+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-+ NULL, response->data, &response->len);
-+ } else {
-+ rv = conn->scard->SCardTransmit(conn->cardHandle,
-+ conn->scard->SCARD_PCI_T1_,
-+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-+ NULL, response->data, &response->len);
-+ }
-
- if (rv != SCARD_S_SUCCESS) {
- conn->lastError =rv;
-diff -up ./src/libckyapplet/cky_factory.c.coolkey-latest ./src/libckyapplet/cky_factory.c
---- ./src/libckyapplet/cky_factory.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_factory.c 2009-09-11 13:58:24.470495267 -0700
-@@ -190,8 +190,11 @@ CKYAPDUFactory_ComputeCryptOneStep(CKYAP
- CKYSize len;
- CKYBuffer buf;
-
-- if (!idata || !(len = CKYBuffer_Size(idata)) || location != CKY_DL_APDU)
-- return ret;
-+ if (!idata)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT)
-+ return ret;
-
- CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
- CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT);
-@@ -314,8 +317,6 @@ CKYAPDUFactory_Logout(CKYAPDU *apdu, CKY
- return CKYSUCCESS;
- }
-
--/* Future add WriteObject */
--
- CKYStatus
- CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID, CKYSize size,
- unsigned short readACL, unsigned short writeACL, unsigned short deleteACL)
-@@ -419,6 +420,58 @@ fail:
- }
-
- CKYStatus
-+CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset,CKYSize size,CKYBuffer *data)
-+{
-+ CKYBuffer buf;
-+ CKYStatus ret = CKYSUCCESS;
-+ unsigned short dataSize = 0;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_WRITE_OBJ);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ dataSize = (unsigned short) CKYBuffer_Size(data);
-+
-+ if(!dataSize) {
-+ ret = CKYINVALIDARGS;
-+ goto fail;
-+ }
-+
-+ ret = CKYBuffer_AppendLong(&buf,objectID);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendLong(&buf,offset);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, size);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+ ret = CKYAPDU_SetSendDataBuffer(apdu,&buf);
-+
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, data);
-+
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+
-+}
-+
-+CKYStatus
- CKYAPDUFactory_ListObjects(CKYAPDU *apdu, CKYByte sequence)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-diff -up ./src/libckyapplet/cky_factory.h.coolkey-latest ./src/libckyapplet/cky_factory.h
---- ./src/libckyapplet/cky_factory.h.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_factory.h 2009-09-11 13:58:24.472487421 -0700
-@@ -190,7 +190,8 @@ CKYStatus CKYAPDUFactory_ChangePIN(CKYAP
- const char *oldPin, const char *newPin);
- CKYStatus CKYAPDUFactory_ListPINs(CKYAPDU *apdu);
- CKYStatus CKYAPDUFactory_Logout(CKYAPDU *apdu, CKYByte pinNumber);
--
-+CKYStatus CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset,CKYSize size,CKYBuffer *data);
- /* Future add WriteObject */
- CKYStatus CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID,
- CKYSize size, unsigned short readACL, unsigned short writeACL,
diff --git a/coolkey-more-keys.patch b/coolkey-more-keys.patch
deleted file mode 100644
index 6140bed..0000000
--- a/coolkey-more-keys.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.coolkey-more-keys ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-more-keys 2016-01-20 11:04:38.507533104 -0800
-+++ ./src/coolkey/slot.cpp 2016-01-20 12:14:21.429947833 -0800
-@@ -32,6 +32,8 @@
-
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
-
-+#define MAX_NUM_KEYS 32
-+#define MAX_NUM_CERTS 32
-
-
- #ifdef DEBUG
-@@ -3458,7 +3460,7 @@ Slot::loadObjects()
- } else if( type == 'c' ) {
- // cert attribute object. find the DER encoding
- unsigned short certnum = getObjectIndex(iter->obj.objectID);
-- if( certnum > 9 ) {
-+ if( certnum > MAX_NUM_CERTS ) {
- //invalid object id
- throw PKCS11Exception(CKR_DEVICE_ERROR,
- "Invalid object id %08x",iter->obj.objectID);
-@@ -4154,7 +4156,7 @@ Slot::objectToKeyNum(const PKCS11Object
- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
- unsigned short keyNum = getObjectIndex(id);
-- if( keyNum > 9 ) {
-+ if( keyNum > MAX_NUM_KEYS ) {
- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
- return keyNum & 0xFF;
-@@ -4911,7 +4913,6 @@ Slot::generateRandom(SessionHandleSuffix
- }
- }
-
--#define MAX_NUM_KEYS 8
- unsigned int
- Slot::getRSAKeySize(PKCS11Object *key)
- {
-diff -up ./src/coolkey/slot.h.coolkey-more-keys ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.coolkey-more-keys 2016-01-20 11:04:45.610475971 -0800
-+++ ./src/coolkey/slot.h 2016-01-20 11:43:09.981528125 -0800
-@@ -511,9 +511,20 @@ class Slot {
- char getObjectClass(unsigned long objectID) const {
- return (char) (objectID >> 24) & 0xff;
- }
-+
- unsigned short getObjectIndex(unsigned long objectID) const {
-- return (char )((objectID >> 16) & 0xff) - '0';
-- }
-+ char char_index = (char) ((objectID >> 16) & 0xff);
-+ if (char_index >= '0' && char_index <= '9') {
-+ return char_index - '0';
-+ }
-+ if (char_index >= 'A' && char_index <= 'Z') {
-+ return char_index - 'A' + 10;
-+ }
-+ if (char_index >= 'a' && char_index <= 'z') {
-+ return char_index - 'a' + 26;
-+ }
-+ return 0x0100 + char_index;
-+ }
-
- // actually get the size of a key in bits from the card
- unsigned int getRSAKeySize(PKCS11Object *key);
diff --git a/coolkey-pcsc-lite-fix.patch b/coolkey-pcsc-lite-fix.patch
deleted file mode 100644
index f528676..0000000
--- a/coolkey-pcsc-lite-fix.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-diff -up ./src/coolkey/slot.cpp.reader-state-fix ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.reader-state-fix 2010-09-08 13:25:14.479109000 -0700
-+++ ./src/coolkey/slot.cpp 2010-09-08 13:25:14.506109000 -0700
-@@ -2185,6 +2185,7 @@ Slot::readCACCertificateFirst(CKYBuffer
- {
- CKYStatus status;
- CKYISOStatus apduRC;
-+ *nextSize = 0;
-
- if (mOldCAC) {
- /* get the first 100 bytes of the cert */
-diff -up ./src/libckyapplet/cky_card.c.reader-state-fix ./src/libckyapplet/cky_card.c
---- ./src/libckyapplet/cky_card.c.reader-state-fix 2010-09-08 14:05:10.859321000 -0700
-+++ ./src/libckyapplet/cky_card.c 2010-09-08 14:05:42.792257000 -0700
-@@ -27,7 +27,6 @@
-
- #ifndef WINAPI
- #define WINAPI
--typedef SCARD_READERSTATE *LPSCARD_READERSTATE;
- #endif
-
- #ifndef SCARD_E_NO_READERS_AVAILABLE
-diff -up ./src/libckyapplet/cky_card.h.reader-state-fix ./src/libckyapplet/cky_card.h
---- ./src/libckyapplet/cky_card.h.reader-state-fix 2006-06-09 11:44:17.000000000 -0700
-+++ ./src/libckyapplet/cky_card.h 2010-09-08 13:25:14.518109000 -0700
-@@ -41,23 +41,23 @@ CKYLIST_DECLARE(CKYReaderName, char *)
- CKYLIST_DECLARE(CKYCardConnection, CKYCardConnection *)
-
- CKY_BEGIN_PROTOS
--void CKYReader_Init(SCARD_READERSTATE_A *reader);
--void CKYReader_FreeData(SCARD_READERSTATE_A *reader);
-+void CKYReader_Init(SCARD_READERSTATE *reader);
-+void CKYReader_FreeData(SCARD_READERSTATE *reader);
-
- /*
-- * "Accessors": for SCARD_READERSTATE_A structure as a class.
-- * These functions take an SCARD_READERSTATE_A which can also be referenced
-+ * "Accessors": for SCARD_READERSTATE structure as a class.
-+ * These functions take an SCARD_READERSTATE which can also be referenced
- * directly.
- */
--CKYStatus CKYReader_SetReaderName(SCARD_READERSTATE_A *reader, const char *name);
--const char *CKYReader_GetReaderName(const SCARD_READERSTATE_A *reader);
--CKYStatus CKYReader_SetKnownState(SCARD_READERSTATE_A *reader,
-+CKYStatus CKYReader_SetReaderName(SCARD_READERSTATE *reader, const char *name);
-+const char *CKYReader_GetReaderName(const SCARD_READERSTATE *reader);
-+CKYStatus CKYReader_SetKnownState(SCARD_READERSTATE *reader,
- unsigned long state);
--unsigned long CKYReader_GetKnownState(const SCARD_READERSTATE_A *reader);
--unsigned long CKYReader_GetEventState(const SCARD_READERSTATE_A *reader);
--CKYStatus CKYReader_GetATR(const SCARD_READERSTATE_A *reader, CKYBuffer *buf);
-+unsigned long CKYReader_GetKnownState(const SCARD_READERSTATE *reader);
-+unsigned long CKYReader_GetEventState(const SCARD_READERSTATE *reader);
-+CKYStatus CKYReader_GetATR(const SCARD_READERSTATE *reader, CKYBuffer *buf);
- /* create an array of READERSTATEs from a LIST of Readers */
--SCARD_READERSTATE_A *CKYReader_CreateArray(const CKYReaderNameList readerNames,
-+SCARD_READERSTATE *CKYReader_CreateArray(const CKYReaderNameList readerNames,
- unsigned long *readerCount);
- /* frees the reader, then the full array */
- void CKYReader_DestroyArray(SCARD_READERSTATE *reader, unsigned long count);
-@@ -88,7 +88,7 @@ CKYStatus CKYCardContext_FindReadersByAT
- const CKYBuffer *targetATR);
- /* return if any of the readers in our array has changed in status */
- CKYStatus CKYCardContext_WaitForStatusChange(CKYCardContext *context,
-- SCARD_READERSTATE_A *readers,
-+ SCARD_READERSTATE *readers,
- unsigned long readerCount,
- unsigned long timeout);
- /* cancel any current operation (such as wait for status change) on this
diff --git a/coolkey-simple-bugs.patch b/coolkey-simple-bugs.patch
deleted file mode 100644
index f8f3ab7..0000000
--- a/coolkey-simple-bugs.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-diff -up ./configure.in.coolkey-simple-bugs ./configure.in
---- ./configure.in.coolkey-simple-bugs 2009-09-16 11:21:55.621493844 -0700
-+++ ./configure.in 2009-09-16 11:22:23.354492383 -0700
-@@ -124,9 +124,9 @@ then
- if test $WINDOWS -ne 1; then
- PKG_CHECK_MODULES(NSS, nss, true, [ AC_MSG_ERROR(could not find NSS Crypto libraries) ])
- fi
-- enable_pk11install = "yes"
-+ enable_pk11install="yes"
- else
-- enable_pk11install = "no"
-+ enable_pk11install="no"
- AC_MSG_WARN([skipping pk11install])
- fi
-
-diff -up ./Makefile.am.coolkey-simple-bugs ./Makefile.am
---- ./Makefile.am.coolkey-simple-bugs 2009-09-16 11:23:18.715515063 -0700
-+++ ./Makefile.am 2009-09-16 13:15:29.570492412 -0700
-@@ -25,7 +25,6 @@ if BUILD_PK11INSTALL
- SUBDIRS += src/install
- endif
-
--ACLOCAL_AMFLAGS = -I m4
-
- EXTRA_DIST = cookey.spec LICENSE
-
-diff -up ./src/coolkey/object.cpp.coolkey-simple-bugs ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.coolkey-simple-bugs 2009-09-16 10:36:29.300516245 -0700
-+++ ./src/coolkey/object.cpp 2009-09-16 10:37:17.747492199 -0700
-@@ -397,7 +397,7 @@ PKCS11Object::getLabel()
- {
- // clean up old one
- if (label) {
-- delete label;
-+ delete [] label;
- label = NULL;
- }
- // find matching attribute
-diff -up ./src/coolkey/object.h.coolkey-simple-bugs ./src/coolkey/object.h
---- ./src/coolkey/object.h.coolkey-simple-bugs 2009-09-16 16:05:27.233488140 -0700
-+++ ./src/coolkey/object.h 2009-09-16 16:05:54.161492421 -0700
-@@ -82,7 +82,7 @@ class PKCS11Object {
- PKCS11Object(unsigned long muscleObjID, CK_OBJECT_HANDLE handle);
- PKCS11Object(unsigned long muscleObjID, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle);
-- ~PKCS11Object() { delete label; delete name; CKYBuffer_FreeData(&pubKey); }
-+ ~PKCS11Object() { delete [] label; delete [] name; CKYBuffer_FreeData(&pubKey); }
-
- PKCS11Object(const PKCS11Object& cpy) :
- attributes(cpy.attributes), muscleObjID(cpy.muscleObjID),
-diff -up ./src/coolkey/slot.cpp.coolkey-simple-bugs ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-simple-bugs 2009-09-16 10:28:15.412492201 -0700
-+++ ./src/coolkey/slot.cpp 2009-09-16 10:57:27.692492487 -0700
-@@ -979,7 +979,7 @@ Slot::makeLabelString(char *label, int m
- //
- #define COOLKEY "CoolKey"
- #define POSSESSION " for "
-- if (!personName || personName == "") {
-+ if (!personName || personName[0] == '\0' ) {
- const int coolKeySize = sizeof(COOLKEY) ;
- memcpy(label, COOLKEY, coolKeySize-1);
- makeSerialString(&label[coolKeySize], maxSize-coolKeySize, cuid);
-@@ -1528,7 +1528,7 @@ SlotMemSegment::SlotMemSegment(const cha
- }
- sprintf(segName,SEGMENT_PREFIX"%s",readerName);
- segment = SHMem::initSegment(segName, MAX_OBJECT_STORE_SIZE, needInit);
-- delete segName;
-+ delete [] segName;
- if (!segment) {
- // just run without shared memory
- return;
diff --git a/coolkey-thread-fix.patch b/coolkey-thread-fix.patch
deleted file mode 100644
index e3b552a..0000000
--- a/coolkey-thread-fix.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-Index: src/coolkey/coolkey.cpp
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/coolkey.cpp,v
-retrieving revision 1.2
-diff -u -r1.2 coolkey.cpp
---- src/coolkey/coolkey.cpp 14 Feb 2007 19:54:01 -0000 1.2
-+++ src/coolkey/coolkey.cpp 18 Dec 2009 23:22:58 -0000
-@@ -42,7 +42,9 @@
-
- static SlotList *slotList = NULL;
-
--static OSLock finalizeLock(false);
-+static OSLock *finalizeLock = NULL;
-+#define FINALIZE_GETLOCK() if (finalizeLock) finalizeLock->getLock();
-+#define FINALIZE_RELEASELOCK() if (finalizeLock) finalizeLock->releaseLock();
-
- static CK_BBOOL initialized = FALSE;
- static CK_BBOOL finalizing = FALSE;
-@@ -208,11 +210,13 @@
- if( initialized ) {
- return CKR_CRYPTOKI_ALREADY_INITIALIZED;
- }
-- if (!finalizeLock.isValid()) {
-+ if (finalizeLock && !finalizeLock->isValid()) {
- return CKR_CANT_LOCK;
- }
- CK_C_INITIALIZE_ARGS* initArgs = (CK_C_INITIALIZE_ARGS*) pInitArgs;
-+ OSLock::setThreadSafe(0);
- if( initArgs != NULL ) {
-+ bool needThreads;
- /* work around a bug in NSS where the library parameters are only
- * send if locking is requested */
- if (initArgs->LibraryParameters) {
-@@ -220,7 +224,17 @@
- } else {
- Params::ClearParams();
- }
-- if( (initArgs->flags & CKF_OS_LOCKING_OK) || initArgs->LockMutex ){
-+ needThreads = ((initArgs->flags & CKF_OS_LOCKING_OK) != 0);
-+ OSLock::setThreadSafe(needThreads);
-+ /* don't get a finalize lock unless someone initializes us asking
-+ * us to use threads */
-+ if (needThreads && !finalizeLock) {
-+ finalizeLock = new OSLock(true);
-+ if (finalizeLock == NULL) return CKR_HOST_MEMORY;
-+ }
-+ /* only support OS LOCKING threads */
-+ if( ((initArgs->flags & CKF_OS_LOCKING_OK) == 0)
-+ && initArgs->LockMutex ){
- throw PKCS11Exception(CKR_CANT_LOCK);
- }
- }
-@@ -259,9 +273,9 @@
- // the finalizing call first, we know it will set waitEvent before
- // we can get the lock, so we only need to protect setting finalizing
- // to true.
-- finalizeLock.getLock();
-+ FINALIZE_GETLOCK();
- finalizing = TRUE;
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- if (waitEvent) {
- /* we're waiting on a slot event, shutdown first to allow
- * the wait function to complete before we pull the rug out.
-@@ -273,10 +287,10 @@
- }
- delete slotList;
- delete log;
-- finalizeLock.getLock();
-+ FINALIZE_GETLOCK();
- finalizing = FALSE;
- initialized = FALSE;
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- return CKR_OK;
- }
-
-@@ -595,17 +609,17 @@
- CK_RV
- C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
- {
-- finalizeLock.getLock();
-+ FINALIZE_GETLOCK();
- if( ! initialized ) {
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
- if (finalizing) {
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
- waitEvent = TRUE;
-- finalizeLock.releaseLock();
-+ FINALIZE_RELEASELOCK();
- try {
- log->log("C_WaitForSlotEvent called\n");
- slotList->waitForSlotEvent(flags, pSlot, pReserved);
-Index: src/coolkey/machdep.cpp
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/machdep.cpp,v
-retrieving revision 1.7
-diff -u -r1.7 machdep.cpp
---- src/coolkey/machdep.cpp 14 Feb 2008 23:48:19 -0000 1.7
-+++ src/coolkey/machdep.cpp 18 Dec 2009 23:22:58 -0000
-@@ -37,6 +37,8 @@
- #include <stdlib.h>
- #endif
-
-+bool OSLock::needThread = 0;
-+
- #ifdef _WIN32
- //
- // Windows functions to grab a named shared memory segment of a specific size,
-@@ -123,6 +125,10 @@
-
- OSLock::OSLock(bool exceptionAllowed)
- {
-+ if (!needThread) {
-+ lockData = NULL;
-+ return;
-+ }
- lockData = new OSLockData;
- if (lockData) {
- InitializeCriticalSection(&lockData->mutex);
-@@ -360,6 +366,9 @@
- int rc;
-
- lockData = NULL;
-+ if (!needThread) {
-+ return;
-+ }
- #ifdef MAC
- if (!OSLock_attr_init) {
- rc = pthread_mutexattr_init(&OSLock_attr);
-Index: src/coolkey/machdep.h
-===================================================================
-RCS file: /cvs/dirsec/coolkey/src/coolkey/machdep.h,v
-retrieving revision 1.1
-diff -u -r1.1 machdep.h
---- src/coolkey/machdep.h 9 Jun 2006 18:39:11 -0000 1.1
-+++ src/coolkey/machdep.h 18 Dec 2009 23:22:58 -0000
-@@ -40,12 +40,14 @@
- class OSLock {
- private:
- OSLockData *lockData;
-+ static bool needThread;
- public:
- OSLock(bool exceptionAllowed = true);
- ~OSLock();
- bool isValid();
- void getLock();
- void releaseLock();
-+ static void setThreadSafe(bool thread) { needThread = thread; }
- };
-
- typedef unsigned long OSTime;
diff --git a/coolkey-update.patch b/coolkey-update.patch
deleted file mode 100644
index 2a1bed3..0000000
--- a/coolkey-update.patch
+++ /dev/null
@@ -1,8043 +0,0 @@
-diff -up ./src/coolkey/coolkey.cpp.coolkey-update ./src/coolkey/coolkey.cpp
---- ./src/coolkey/coolkey.cpp.coolkey-update 2016-01-19 17:48:49.064182244 -0800
-+++ ./src/coolkey/coolkey.cpp 2016-01-19 17:50:46.711214704 -0800
-@@ -34,7 +34,6 @@
- #include "cky_base.h"
- #include "params.h"
-
--#define NULL 0
-
- /* static module data -------------------------------- */
-
-@@ -70,11 +69,19 @@ typedef struct {
- /**********************************************************************
- ************************** MECHANISM TABLE ***************************
- **********************************************************************/
--static MechInfo
--mechanismList[] = {
-+
-+static const MechInfo
-+rsaMechanismList[] = {
- {CKM_RSA_PKCS, { 1024, 4096, CKF_HW | CKF_SIGN | CKF_DECRYPT } }
- };
--static unsigned int numMechanisms = sizeof(mechanismList)/sizeof(MechInfo);
-+
-+static const MechInfo
-+ecMechanismList[] = {
-+ {CKM_ECDSA,{256,521,CKF_HW | CKF_SIGN | CKF_EC_F_P}},{ CKM_ECDSA_SHA1, {256, 521, CKF_HW | CKF_SIGN | CKF_EC_F_P}},{ CKM_ECDH1_DERIVE,{256, 521, CKF_HW | CKF_DERIVE | CKF_EC_F_P} }
-+};
-+
-+unsigned int numRSAMechanisms = sizeof(rsaMechanismList)/sizeof(MechInfo);
-+unsigned int numECMechanisms = sizeof(ecMechanismList)/sizeof(MechInfo);
-
- /* ------------------------------------------------------------ */
-
-@@ -166,7 +173,6 @@ NOTSUPPORTED(C_GenerateKey, (CK_SESSION_
- NOTSUPPORTED(C_GenerateKeyPair, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_ATTRIBUTE_PTR,CK_ULONG,CK_ATTRIBUTE_PTR,CK_ULONG,CK_OBJECT_HANDLE_PTR,CK_OBJECT_HANDLE_PTR))
- NOTSUPPORTED(C_WrapKey, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_OBJECT_HANDLE,CK_OBJECT_HANDLE,CK_BYTE_PTR,CK_ULONG_PTR))
- NOTSUPPORTED(C_UnwrapKey, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_OBJECT_HANDLE,CK_BYTE_PTR,CK_ULONG,CK_ATTRIBUTE_PTR,CK_ULONG,CK_OBJECT_HANDLE_PTR))
--NOTSUPPORTED(C_DeriveKey, (CK_SESSION_HANDLE,CK_MECHANISM_PTR,CK_OBJECT_HANDLE,CK_ATTRIBUTE_PTR,CK_ULONG,CK_OBJECT_HANDLE_PTR))
- NOTSUPPORTED(C_GetFunctionStatus, (CK_SESSION_HANDLE))
- NOTSUPPORTED(C_CancelFunction, (CK_SESSION_HANDLE))
-
-@@ -200,6 +206,10 @@ SUPPORTED(C_SeedRandom, seedRandom,
- SUPPORTED(C_GenerateRandom, generateRandom,
- (CK_SESSION_HANDLE hSession ,CK_BYTE_PTR data,CK_ULONG dataLen),
- (hSession, data, dataLen))
-+SUPPORTED(C_DeriveKey,derive,
-+ (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ),
-+ (hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey))
-
- /* non-specialized functions supported with the slot directly */
-
-@@ -249,7 +259,7 @@ C_Initialize(CK_VOID_PTR pInitArgs)
- log = new DummyLog();
- }
- log->log("Initialize called, hello %d\n", 5);
-- CKY_SetName("coolkey");
-+ CKY_SetName((char *) "coolkey");
- slotList = new SlotList(log);
- initialized = TRUE;
- return CKR_OK;
-@@ -347,6 +357,11 @@ CK_RV
- C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount)
- {
-+
-+ const MechInfo *mechanismList = NULL;
-+ unsigned int numMechanisms = 0;
-+
-+
- if( ! initialized ) {
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
-@@ -359,11 +374,21 @@ C_GetMechanismList(CK_SLOT_ID slotID, CK
- }
-
- slotList->validateSlotID(slotID);
-- if( ! slotList->getSlot(
-- slotIDToIndex(slotID))->isTokenPresent() ) {
-+
-+ Slot *slot = slotList->getSlot(slotIDToIndex(slotID));
-+
-+ if( ! slot || ! slot->isTokenPresent() ) {
- return CKR_TOKEN_NOT_PRESENT;
- }
-
-+ if ( slot->getIsECC()) {
-+ mechanismList = ecMechanismList;
-+ numMechanisms = numECMechanisms;
-+ } else {
-+ mechanismList = rsaMechanismList;
-+ numMechanisms = numRSAMechanisms;
-+ }
-+
- if( pMechanismList != NULL ) {
- if( *pulCount < numMechanisms ) {
- rv = CKR_BUFFER_TOO_SMALL;
-@@ -390,19 +415,36 @@ CK_RV
- C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo)
- {
-+ const MechInfo *mechanismList = NULL;
-+ unsigned int numMechanisms = 0;
-+
- if( ! initialized ) {
- return CKR_CRYPTOKI_NOT_INITIALIZED;
- }
-+
-+
- try {
- log->log("C_GetMechanismInfo called\n");
- if( pInfo == NULL ) {
- throw PKCS11Exception(CKR_ARGUMENTS_BAD);
- }
- slotList->validateSlotID(slotID);
-- if( ! slotList->getSlot(slotIDToIndex(slotID))->isTokenPresent() ) {
-+
-+
-+ Slot *slot = slotList->getSlot(slotIDToIndex(slotID));
-+
-+ if( ! slot || ! slot->isTokenPresent() ) {
- return CKR_TOKEN_NOT_PRESENT;
- }
-
-+ if ( slot->getIsECC()) {
-+ mechanismList = ecMechanismList;
-+ numMechanisms = numECMechanisms;
-+ } else {
-+ mechanismList = rsaMechanismList;
-+ numMechanisms = numRSAMechanisms;
-+ }
-+
- for(unsigned int i=0; i < numMechanisms; ++i ) {
- if( mechanismList[i].mech == type ) {
- *pInfo = mechanismList[i].info;
-@@ -557,13 +599,10 @@ C_Login(CK_SESSION_HANDLE hSession, CK_U
- }
- try {
- log->log("C_Login called\n");
-- if( userType != CKU_USER ) {
-- throw PKCS11Exception(CKR_USER_TYPE_INVALID);
-- }
- if( pPin == NULL ) {
- throw PKCS11Exception(CKR_ARGUMENTS_BAD);
- }
-- slotList->login(hSession, pPin, ulPinLen);
-+ slotList->login(hSession, userType, pPin, ulPinLen);
- return CKR_OK;
- } catch(PKCS11Exception &e) {
- e.log(log);
-diff -up ./src/coolkey/machdep.cpp.coolkey-update ./src/coolkey/machdep.cpp
---- ./src/coolkey/machdep.cpp.coolkey-update 2016-01-19 17:51:35.553813017 -0800
-+++ ./src/coolkey/machdep.cpp 2016-01-19 17:51:59.607615196 -0800
-@@ -368,6 +368,7 @@ SHMem::initSegment(const char *name, int
- #ifdef FULL_CLEANUP
- flock(shmemData->fd, LOCK_UN);
- #endif
-+ free(buf);
- delete shmemData;
- return NULL;
- }
-diff -up ./src/coolkey/object.cpp.coolkey-update ./src/coolkey/object.cpp
---- ./src/coolkey/object.cpp.coolkey-update 2016-01-19 17:52:36.313313325 -0800
-+++ ./src/coolkey/object.cpp 2016-01-19 17:52:50.959192876 -0800
-@@ -19,18 +19,80 @@
-
- #include "mypkcs11.h"
- #include "PKCS11Exception.h"
--#include "object.h"
- #include <algorithm>
- #include <string.h>
-+#include "object.h"
-
- using std::find_if;
-
-+const CKYByte rsaOID[] = {0x2A,0x86,0x48,0x86,0xF7,0x0D, 0x01, 0x01,0x1};
-+const CKYByte eccOID[] = {0x2a,0x86,0x48,0xce,0x3d,0x02,0x01};
-+
-+#ifdef DEBUG
-+void dump(const char *label, const CKYBuffer *buf)
-+{
-+ CKYSize i;
-+ CKYSize size = CKYBuffer_Size(buf);
-+#define ROW_LENGTH 60
-+ char string[ROW_LENGTH+1];
-+ char *bp = &string[0];
-+ CKYByte c;
-+
-+ printf("%s size=%d\n", label, (int)size);
-+
-+ for (i=0; i < size; i++) {
-+ if (i && ((i % (ROW_LENGTH)) == 0) ) {
-+ *bp = 0;
-+ printf(" %s\n",string);
-+ bp = &string[0];
-+ }
-+ c = CKYBuffer_GetChar(buf, i);
-+ printf("%02x ",c);
-+ *bp++ = (c < ' ') ? '.' : ((c & 0x80) ? '*' : c);
-+ }
-+ *bp = 0;
-+ for (i= (i % (ROW_LENGTH)); i && (i < ROW_LENGTH); i++) {
-+ printf(" ");
-+ }
-+ printf(" %s\n",string);
-+ fflush(stdout);
-+}
-+
-+void dumpData(const char *label, const CKYByte *buf, CKYSize size)
-+{
-+ CKYSize i;
-+#define ROW_LENGTH 16
-+ char string[ROW_LENGTH+1];
-+ char *bp = &string[0];
-+ CKYByte c;
-+
-+ printf("%s size=%d:\n",label, (int)size);
-+
-+ for (i=0; i < size; i++) {
-+ if (i && ((i % (ROW_LENGTH)) == 0) ) {
-+ *bp = 0;
-+ printf(" %s\n",string);
-+ bp = &string[0];
-+ }
-+ c = buf[i];
-+ printf("%02x ",c);
-+ *bp++ = (c < ' ') ? '.' : ((c & 0x80) ? '*' : c);
-+ }
-+ *bp = 0;
-+ for (i= (i % (ROW_LENGTH)); i && (i < ROW_LENGTH); i++) {
-+ printf(" ");
-+ }
-+ printf(" %s\n",string);
-+ fflush(stdout);
-+}
-+#endif
-+
-
- bool AttributeMatch::operator()(const PKCS11Attribute& cmp)
- {
- return (attr->type == cmp.getType()) &&
-- CKYBuffer_DataIsEqual(cmp.getValue(),
-- (const CKYByte *)attr->pValue, attr->ulValueLen);
-+ CKYBuffer_DataIsEqual(cmp.getValue(),
-+ (const CKYByte *)attr->pValue, attr->ulValueLen);
- }
-
- class AttributeTypeMatch
-@@ -45,16 +107,23 @@ class AttributeTypeMatch
- };
-
- PKCS11Object::PKCS11Object(unsigned long muscleObjID_,CK_OBJECT_HANDLE handle_)
-- : muscleObjID(muscleObjID_), handle(handle_), label(NULL), name(NULL)
-+ : muscleObjID(muscleObjID_), handle(handle_), label(NULL), keySize(0),
-+ user(CKU_USER), name(NULL), keyType(unknown),
-+ keyRef(PK15_INVALID_KEY_REF)
- {
- CKYBuffer_InitEmpty(&pubKey);
-+ CKYBuffer_InitEmpty(&authId);
-+ CKYBuffer_InitEmpty(&pinAuthId);
- }
-
- PKCS11Object::PKCS11Object(unsigned long muscleObjID_, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle_) : muscleObjID(muscleObjID_), handle(handle_),
-- label(NULL), name(NULL)
-+ label(NULL), keySize(0), user(CKU_USER), name(NULL),
-+ keyType(unknown), keyRef(PK15_INVALID_KEY_REF)
- {
- CKYBuffer_InitEmpty(&pubKey);
-+ CKYBuffer_InitEmpty(&authId);
-+ CKYBuffer_InitEmpty(&pinAuthId);
-
- CKYByte type = CKYBuffer_GetChar(data,0);
- // verify object ID is what we think it is
-@@ -63,9 +132,98 @@ PKCS11Object::PKCS11Object(unsigned long
- "PKCS #11 actual object id does not match stated id");
- }
- if (type == 0) {
-- parseOldObject(data);
-+ parseOldObject(data);
- } else if (type == 1) {
-- parseNewObject(data);
-+ parseNewObject(data);
-+ }
-+}
-+
-+SecretKey::SecretKey(unsigned long muscleObjID_, CK_OBJECT_HANDLE handle_, CKYBuffer *secretKeyBuffer, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
-+ : PKCS11Object(muscleObjID_, handle_)
-+{
-+ static CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
-+ static CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
-+ static CK_BBOOL value = 0x1;
-+
-+ if ( secretKeyBuffer == NULL)
-+ return;
-+
-+ /* Rifle through the input template */
-+
-+ CK_ATTRIBUTE_TYPE type;
-+ CK_ATTRIBUTE attr;
-+ CK_ULONG valueLength = 0;
-+
-+ for(int i = 0; i < (int) ulAttributeCount; i++) {
-+ attr = pTemplate[i];
-+ type = attr.type;
-+
-+ if ( type == CKA_VALUE_LEN) {
-+ //CK_ULONG ulValueLen = attr.ulValueLen;
-+ valueLength = *((CK_ULONG *)attr.pValue);
-+ } else {
-+
-+ CKYBuffer val;
-+ CKYBuffer_InitFromData(&val,(const CK_BYTE *) attr.pValue, attr.ulValueLen);
-+ setAttribute( type, &val);
-+ CKYBuffer_FreeData(&val);
-+ }
-+ }
-+
-+ adjustToKeyValueLength( secretKeyBuffer, valueLength );
-+
-+ /* Fall backs. */
-+
-+ if(!attributeExists(CKA_CLASS))
-+ setAttributeULong(CKA_CLASS, objClass);
-+
-+ if(!attributeExists(CKA_KEY_TYPE))
-+ setAttributeULong(CKA_KEY_TYPE, keyType);
-+
-+ if(!attributeExists(CKA_TOKEN))
-+ setAttributeBool(CKA_TOKEN, value);
-+
-+ if(!attributeExists(CKA_DERIVE))
-+ setAttributeBool(CKA_DERIVE, value);
-+
-+ /* Actual value */
-+ setAttribute(CKA_VALUE, secretKeyBuffer);
-+
-+}
-+
-+void SecretKey::adjustToKeyValueLength(CKYBuffer * secretKeyBuffer,CK_ULONG valueLength)
-+{
-+ const CK_LONG MAX_DIFF = 200; /* Put some bounds on this value */
-+
-+ if ( !secretKeyBuffer ) {
-+ return;
-+ }
-+
-+ CKYBuffer scratch;
-+ CK_ULONG actual_length = CKYBuffer_Size(secretKeyBuffer);
-+
-+ CK_LONG diff = 0;
-+ diff = (CK_LONG) valueLength - actual_length;
-+
-+ if ( diff == 0 ) {
-+ return;
-+ }
-+
-+ if ( diff > 0 && diff < MAX_DIFF ) { /*check for silly values */
-+ /* prepend with zeroes */
-+ CKYBuffer_InitFromLen(&scratch, diff);
-+ CKYBuffer_AppendCopy(&scratch, secretKeyBuffer);
-+
-+ CKYBuffer_FreeData(secretKeyBuffer);
-+ CKYBuffer_InitFromCopy(secretKeyBuffer, &scratch);
-+ CKYBuffer_FreeData(&scratch);
-+
-+ } else if (diff < 0 ) {
-+ /* truncate most significant bytes */
-+ CKYBuffer_InitFromData(&scratch, CKYBuffer_Data(secretKeyBuffer)-diff, valueLength);
-+ CKYBuffer_FreeData(secretKeyBuffer);
-+ CKYBuffer_InitFromCopy(secretKeyBuffer, &scratch);
-+ CKYBuffer_FreeData(&scratch);
- }
- }
-
-@@ -95,29 +253,29 @@ PKCS11Object::parseOldObject(const CKYBu
- attrib.setType(CKYBuffer_GetLong(data, idx));
- idx += 4;
- unsigned int attrLen = CKYBuffer_GetShort(data, idx);
-- idx += 2;
-+ idx += 2;
- if( attrLen > CKYBuffer_Size(data)
-- || (idx + attrLen > CKYBuffer_Size(data)) ) {
-+ || (idx + attrLen > CKYBuffer_Size(data)) ) {
- throw PKCS11Exception(CKR_DEVICE_ERROR,
- "Invalid attribute length %d\n", attrLen);
- }
-- /* these two types are ints, read them back from
-- * the card in host order */
-- if ((attrib.getType() == CKA_CLASS) ||
-- (attrib.getType() == CKA_CERTIFICATE_TYPE) ||
-- (attrib.getType() == CKA_KEY_TYPE)) {
-- /* ulongs are 4 bytes on the token, even if they are 8 or
-- * more in the pkcs11 module */
-- if (attrLen != 4) {
-+ /* these two types are ints, read them back from
-+ * the card in host order */
-+ if ((attrib.getType() == CKA_CLASS) ||
-+ (attrib.getType() == CKA_CERTIFICATE_TYPE) ||
-+ (attrib.getType() == CKA_KEY_TYPE)) {
-+ /* ulongs are 4 bytes on the token, even if they are 8 or
-+ * more in the pkcs11 module */
-+ if (attrLen != 4) {
- throw PKCS11Exception(CKR_DEVICE_ERROR,
- "Invalid attribute length %d\n", attrLen);
-- }
-- CK_ULONG value = makeLEUInt(data,idx);
-+ }
-+ CK_ULONG value = makeLEUInt(data,idx);
-
-- attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-- } else {
-- attrib.setValue(CKYBuffer_Data(data)+idx, attrLen);
-- }
-+ attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-+ } else {
-+ attrib.setValue(CKYBuffer_Data(data)+idx, attrLen);
-+ }
- idx += attrLen;
- attributes.push_back(attrib);
- }
-@@ -177,33 +335,33 @@ PKCS11Object::expandAttributes(unsigned
- unsigned long i;
-
- if (!attributeExists(CKA_ID)) {
-- PKCS11Attribute attrib;
-- attrib.setType(CKA_ID);
-- attrib.setValue(&cka_id, 1);
-+ PKCS11Attribute attrib;
-+ attrib.setType(CKA_ID);
-+ attrib.setValue(&cka_id, 1);
- attributes.push_back(attrib);
- }
- /* unpack the class */
- if (!attributeExists(CKA_CLASS)) {
-- PKCS11Attribute attrib;
-- attrib.setType(CKA_CLASS);
-- attrib.setValue((CKYByte *)&objectType, sizeof(CK_ULONG));
-+ PKCS11Attribute attrib;
-+ attrib.setType(CKA_CLASS);
-+ attrib.setValue((CKYByte *)&objectType, sizeof(CK_ULONG));
- attributes.push_back(attrib);
- }
-
- /* unpack the boolean flags. Note, the default mask is based on
- * the class specified in fixedAttrs, not on the real class */
- for (i=1; i < sizeof(unsigned long)*8; i++) {
-- unsigned long iMask = 1<< i;
-- if ((mask & iMask) == 0) {
-- continue;
-- }
-- if (attributeExists(boolType[i])) {
-- continue;
-- }
-- PKCS11Attribute attrib;
-- CKYByte bVal = (fixedAttrs & iMask) != 0;
-- attrib.setType(boolType[i]);
-- attrib.setValue(&bVal, 1);
-+ unsigned long iMask = 1<< i;
-+ if ((mask & iMask) == 0) {
-+ continue;
-+ }
-+ if (attributeExists(boolType[i])) {
-+ continue;
-+ }
-+ PKCS11Attribute attrib;
-+ CKYByte bVal = (fixedAttrs & iMask) != 0;
-+ attrib.setType(boolType[i]);
-+ attrib.setValue(&bVal, 1);
- attributes.push_back(attrib);
- }
- }
-@@ -224,40 +382,40 @@ PKCS11Object::parseNewObject(const CKYBu
- // load up the explicit attributes first
- for (j=0, offset = 11; j < attributeCount && offset < size; j++) {
- PKCS11Attribute attrib;
-- CKYByte attributeDataType = CKYBuffer_GetChar(data, offset+4);
-- unsigned int attrLen = 0;
-+ CKYByte attributeDataType = CKYBuffer_GetChar(data, offset+4);
-+ unsigned int attrLen = 0;
- attrib.setType(CKYBuffer_GetLong(data, offset));
- offset += 5;
-
-- switch(attributeDataType) {
-- case DATATYPE_STRING:
-- attrLen = CKYBuffer_GetShort(data, offset);
-- offset += 2;
-+ switch(attributeDataType) {
-+ case DATATYPE_STRING:
-+ attrLen = CKYBuffer_GetShort(data, offset);
-+ offset += 2;
- if (attrLen > CKYBuffer_Size(data)
-- || (offset + attrLen > CKYBuffer_Size(data)) ) {
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Invalid attribute length %d\n", attrLen);
-+ || (offset + attrLen > CKYBuffer_Size(data)) ) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Invalid attribute length %d\n", attrLen);
- }
-- attrib.setValue(CKYBuffer_Data(data)+offset, attrLen);
-- break;
-- case DATATYPE_BOOL_FALSE:
-- case DATATYPE_BOOL_TRUE:
-- {
-- CKYByte bval = attributeDataType & 1;
-- attrib.setValue(&bval, 1);
-- }
-- break;
-- case DATATYPE_INTEGER:
-- {
-- CK_ULONG value = CKYBuffer_GetLong(data, offset);
-- attrLen = 4;
-- attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-- }
-- break;
-- default:
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Invalid attribute Data Type %d\n", attributeDataType);
-- }
-+ attrib.setValue(CKYBuffer_Data(data)+offset, attrLen);
-+ break;
-+ case DATATYPE_BOOL_FALSE:
-+ case DATATYPE_BOOL_TRUE:
-+ {
-+ CKYByte bval = attributeDataType & 1;
-+ attrib.setValue(&bval, 1);
-+ }
-+ break;
-+ case DATATYPE_INTEGER:
-+ {
-+ CK_ULONG value = CKYBuffer_GetLong(data, offset);
-+ attrLen = 4;
-+ attrib.setValue((const CKYByte *)&value, sizeof(CK_ULONG));
-+ }
-+ break;
-+ default:
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Invalid attribute Data Type %d\n", attributeDataType);
-+ }
- offset += attrLen;
- attributes.push_back(attrib);
- }
-@@ -276,7 +434,7 @@ static const CK_ATTRIBUTE rdr_templat
-
- bool
- PKCS11Object::matchesTemplate(const CK_ATTRIBUTE_PTR pTemplate,
-- CK_ULONG ulCount)
-+ CK_ULONG ulCount)
- const
- {
- unsigned int i;
-@@ -285,10 +443,10 @@ PKCS11Object::matchesTemplate(const CK_A
-
- #if defined( NSS_HIDE_NONSTANDARD_OBJECTS )
- if (!ulCount) {
-- // exclude MOZ reader objects from searches for all objects.
-- // To find an MOZ reader object, one must search for it by
-- // some matching attribute, such as class.
-- iterator iter = find_if(attributes.begin(), attributes.end(),
-+ // exclude MOZ reader objects from searches for all objects.
-+ // To find an MOZ reader object, one must search for it by
-+ // some matching attribute, such as class.
-+ iterator iter = find_if(attributes.begin(), attributes.end(),
- AttributeMatch(&rdr_template[0]));
- return (iter == attributes.end()) ? true : false;
- }
-@@ -325,7 +483,7 @@ PKCS11Object::getAttribute(CK_ATTRIBUTE_
- AttributeTypeMatch(type));
-
- if( iter == attributes.end() ) {
-- return NULL;
-+ return NULL;
- }
- return iter->getValue();
- }
-@@ -349,8 +507,9 @@ PKCS11Object::getAttributeValue(CK_ATTRI
- if( iter == attributes.end() ) {
- // no attribute of this type
- attrTypeInvalid = true;
-- log->log("GetAttributeValue: invalid type 0x%08x on object %x\n",
-- pTemplate[i].type, muscleObjID);
-+ if ( log )
-+ log->log("GetAttributeValue: invalid type 0x%08x on object %x\n",
-+ pTemplate[i].type, muscleObjID);
- pTemplate[i].ulValueLen = (CK_ULONG)-1;
- continue;
- }
-@@ -371,7 +530,7 @@ PKCS11Object::getAttributeValue(CK_ATTRI
- // the buffer is large enough. return the value and set the exact
- // length.
- memcpy(pTemplate[i].pValue, CKYBuffer_Data(iter->getValue()),
-- CKYBuffer_Size(iter->getValue()));
-+ CKYBuffer_Size(iter->getValue()));
- pTemplate[i].ulValueLen = CKYBuffer_Size(iter->getValue());
- }
-
-@@ -406,14 +565,14 @@ PKCS11Object::getLabel()
-
- // none found
- if( iter == attributes.end() ) {
-- return "";
-+ return "";
- }
-
- int size = CKYBuffer_Size(iter->getValue());
-
- label = new char [ size + 1 ];
- if (!label) {
-- return "";
-+ return "";
- }
- memcpy(label, CKYBuffer_Data(iter->getValue()), size);
- label[size] = 0;
-@@ -431,13 +590,13 @@ PKCS11Object::getClass()
-
- // none found */
- if( iter == attributes.end() ) {
-- return (CK_OBJECT_CLASS) -1;
-+ return (CK_OBJECT_CLASS) -1;
- }
-
- int size = CKYBuffer_Size(iter->getValue());
-
- if (size != sizeof(objClass)) {
-- return (CK_OBJECT_CLASS) -1;
-+ return (CK_OBJECT_CLASS) -1;
- }
-
- memcpy(&objClass, CKYBuffer_Data(iter->getValue()), size);
-@@ -453,13 +612,28 @@ PKCS11Object::setAttribute(CK_ATTRIBUTE_
- iter = find_if(attributes.begin(), attributes.end(),
- AttributeTypeMatch(type));
- if( iter != attributes.end() ) {
-- iter->setValue( CKYBuffer_Data(value), CKYBuffer_Size(value));
-+ iter->setValue( CKYBuffer_Data(value), CKYBuffer_Size(value));
- } else {
- attributes.push_back(PKCS11Attribute(type, value));
- }
- }
-
- void
-+PKCS11Object::setAttribute(CK_ATTRIBUTE_TYPE type, const CKYByte *data,
-+ CKYSize size)
-+{
-+ AttributeIter iter;
-+
-+ iter = find_if(attributes.begin(), attributes.end(),
-+ AttributeTypeMatch(type));
-+ if( iter != attributes.end() ) {
-+ iter->setValue( data, size);
-+ } else {
-+ attributes.push_back(PKCS11Attribute(type, data, size));
-+ }
-+}
-+
-+void
- PKCS11Object::setAttribute(CK_ATTRIBUTE_TYPE type, const char *string)
- {
- CKYBuffer buf;
-@@ -491,7 +665,7 @@ PKCS11Object::setAttributeULong(CK_ATTRI
-
- typedef struct {
- const CKYByte*data;
-- unsigned int len;
-+ CKYSize len;
- } CCItem;
-
- typedef enum {
-@@ -499,15 +673,21 @@ typedef enum {
- SECFailure=1
- } SECStatus;
-
--static const CKYByte*
--dataStart(const CKYByte *buf, unsigned int length,
-- unsigned int *data_length, bool includeTag) {
-+const CKYByte*
-+dataStart(const CKYByte *buf, CKYSize length,
-+ CKYSize *data_length, bool includeTag) {
- unsigned char tag;
- unsigned int used_length= 0;
-
-+ *data_length = 0; /* make sure data_length is zero on failure */
-+
- if(!buf) {
- return NULL;
- }
-+ /* there must be at least 2 bytes */
-+ if (length < 2) {
-+ return NULL;
-+ }
-
- tag = buf[used_length++];
-
-@@ -521,15 +701,22 @@ dataStart(const CKYByte *buf, unsigned i
- if (*data_length&0x80) {
- int len_count = *data_length & 0x7f;
-
-+ if (len_count+used_length > length) {
-+ return NULL;
-+ }
-+
- *data_length = 0;
-
- while (len_count-- > 0) {
- *data_length = (*data_length << 8) | buf[used_length++];
- }
- }
-+ /* paranoia, can't happen */
-+ if (length < used_length) {
-+ return NULL;
-+ }
-
- if (*data_length > (length-used_length) ) {
-- *data_length = length-used_length;
- return NULL;
- }
- if (includeTag) *data_length += used_length;
-@@ -538,27 +725,169 @@ dataStart(const CKYByte *buf, unsigned i
- }
-
- static const CKYByte *
--unwrapBitString(const CKYByte *buf, unsigned int len, unsigned int *retLen)
-+unwrapBitString(const CKYByte *buf, CKYSize len, CKYSize *retLen)
- {
- /* for RSA, bit string always has byte number of bits */
- if (buf[0] != 0) {
-- return NULL;
-+ return NULL;
- }
- if (len < 1) {
-- return NULL;
-+ return NULL;
- }
- *retLen = len -1;
- return buf+1;
- }
-
- static SECStatus
--GetKeyFieldItems(const CKYByte *spki_data,unsigned int spki_length,
-+GetECKeyFieldItems(const CKYByte *spki_data, CKYSize spki_length,
-+ CCItem *point, CCItem *params)
-+{
-+ const CKYByte *buf = spki_data;
-+ CKYSize buf_length = spki_length;
-+ const CKYByte *algid;
-+ CKYSize algidlen;
-+ const CKYByte *dummy;
-+ CKYSize dummylen;
-+
-+ if (!point || !params || !buf)
-+ return SECFailure;
-+
-+ point->data = NULL;
-+ point->len = 0;
-+ params->data = NULL;
-+ params->len = 0;
-+
-+ /* unwrap the algorithm id */
-+ dummy = dataStart(buf,buf_length,&dummylen,false);
-+ if (dummy == NULL) return SECFailure;
-+ buf_length -= (dummy-buf) + dummylen;
-+ buf = dummy + dummylen;
-+ /* unwrpped value is in dummy */
-+ algid = dummy;
-+ algidlen = dummylen;
-+ /* skip past algid oid */
-+ dummy = dataStart(algid, algidlen, &dummylen, false);
-+ if (dummy == NULL) return SECFailure;
-+ algidlen -= (dummy-algid) + dummylen;
-+ algid = dummy + dummylen;
-+ params->data = algid;
-+ params->len = algidlen;
-+
-+ /* unwrap the public key info */
-+ buf = dataStart(buf,buf_length,&buf_length,false);
-+ if (buf == NULL) return SECFailure;
-+ buf = unwrapBitString(buf,buf_length,&buf_length);
-+ if (buf == NULL) return SECFailure;
-+
-+ point->data = buf;
-+ point->len = buf_length;
-+
-+ if(point->data == NULL) return SECFailure;
-+
-+ return SECSuccess;
-+}
-+
-+static bool
-+GetKeyOIDMatches(const CKYByte *spki_data, unsigned int length, const CKYByte *oid_data)
-+{
-+ bool ret = TRUE;
-+
-+ if( spki_data == NULL || oid_data == NULL) {
-+ return FALSE;
-+ }
-+
-+ for ( int i = 0 ; i < (int) length ; i++) {
-+ if (spki_data[i] != oid_data[i]) {
-+ ret = FALSE;
-+ break;
-+ }
-+
-+ }
-+
-+ return ret;
-+}
-+
-+static SECStatus
-+GetKeyAlgorithmId(const CKYByte *spki_data, CKYSize spki_length,
-+ CCItem *algorithmId)
-+{
-+
-+ const CKYByte *buf = spki_data;
-+ CKYSize buf_length = spki_length;
-+
-+ if ( algorithmId == NULL) return SECFailure;
-+
-+ /* objtain the algorithm id */
-+ algorithmId->data = dataStart(buf,buf_length,&algorithmId->len,false);
-+ if (algorithmId->data == NULL) return SECFailure;
-+
-+ return SECSuccess;
-+
-+}
-+
-+static PKCS11Object::KeyType
-+GetKeyTypeFromSPKI(const CKYBuffer *key)
-+{
-+ CCItem algIdItem;
-+ SECStatus ret = GetKeyAlgorithmId(CKYBuffer_Data(key),
-+ CKYBuffer_Size(key),&algIdItem);
-+ PKCS11Object::KeyType foundType = PKCS11Object::unknown;
-+
-+ if ( ret != SECSuccess ) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+
-+ CKYSize length = 0;
-+ const CKYByte *keyData = NULL;
-+
-+ /* Get actual oid buffer */
-+
-+ keyData = dataStart(algIdItem.data,algIdItem.len,&length, false);
-+ if (keyData == NULL) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+
-+ bool match = FALSE;
-+
-+ /* Check for outrageous length */
-+
-+ if ( length <= 3 || length >= algIdItem.len) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+ /* check for RSA */
-+
-+ match = GetKeyOIDMatches(keyData, length, rsaOID);
-+
-+ if ( match == TRUE ) {
-+ foundType = PKCS11Object::rsa;
-+ } else {
-+ /* check for ECC */
-+ match = GetKeyOIDMatches(keyData, length, eccOID);
-+
-+ if ( match == TRUE ) {
-+ foundType = PKCS11Object::ecc;
-+ }
-+
-+ }
-+
-+ if ( foundType == PKCS11Object::unknown) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode key algorithm ID.");
-+ }
-+ return foundType;
-+}
-+
-+static SECStatus
-+GetKeyFieldItems(const CKYByte *spki_data,CKYSize spki_length,
- CCItem *modulus, CCItem *exponent)
- {
- const CKYByte *buf = spki_data;
-- unsigned int buf_length = spki_length;
-+ CKYSize buf_length = spki_length;
- const CKYByte*dummy;
-- unsigned int dummylen;
-+ CKYSize dummylen;
-
- /* skip past the algorithm id */
- dummy = dataStart(buf,buf_length,&dummylen,false);
-@@ -596,7 +925,7 @@ GetKeyFields(const CKYBuffer *spki, CKYB
- CCItem modulusItem, exponentItem;
-
- rv = GetKeyFieldItems(CKYBuffer_Data(spki), CKYBuffer_Size(spki),
-- &modulusItem, &exponentItem);
-+ &modulusItem, &exponentItem);
-
- if( rv != SECSuccess ) {
- throw PKCS11Exception(CKR_FUNCTION_FAILED,
-@@ -607,6 +936,29 @@ GetKeyFields(const CKYBuffer *spki, CKYB
- CKYBuffer_Replace(exponent, 0, exponentItem.data, exponentItem.len);
- }
-
-+static void
-+GetECKeyFields(const CKYBuffer *spki, CKYBuffer *point, CKYBuffer *params)
-+{
-+ SECStatus rv;
-+ CCItem pointItem, paramsItem;
-+
-+ if (spki == NULL || point == NULL || params == NULL) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode certificate Subject Public KeyInfo!");
-+ }
-+
-+ rv = GetECKeyFieldItems(CKYBuffer_Data(spki), CKYBuffer_Size(spki),
-+ &pointItem, ¶msItem);
-+
-+ if( rv != SECSuccess ) {
-+ throw PKCS11Exception(CKR_FUNCTION_FAILED,
-+ "Failed to decode certificate Subject Public Key Info!");
-+ }
-+
-+ CKYBuffer_Replace(point, 0, pointItem.data, pointItem.len);
-+ CKYBuffer_Replace(params, 0, paramsItem.data, paramsItem.len);
-+}
-+
- Key::Key(unsigned long muscleObjID, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle) : PKCS11Object(muscleObjID, data, handle)
- {
-@@ -616,67 +968,113 @@ Key::Key(unsigned long muscleObjID, cons
- CKYBuffer_InitEmpty(&empty);
-
- if ((objClass == CKO_PUBLIC_KEY) || (objClass == CKO_PRIVATE_KEY)) {
-- /* only CKK_RSA is supported */
-- setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ //we may know already what type of key this is.
-+ if (attributeExists(CKA_KEY_TYPE)) {
-+ CK_ULONG type = 0;
-+ CK_ATTRIBUTE aTemplate = {CKA_KEY_TYPE, &type, sizeof(CK_ULONG)};
-+
-+ getAttributeValue(&aTemplate, 1, NULL);
-+
-+ if (type == 0x3) {
-+ setKeyType(ecc);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ } else {
-+ setKeyType(rsa);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ }
-+ } else {
-+ /* default to rsa */
-+ setKeyType(rsa);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ }
-+
-+ // Could be RSA or ECC
- } else if (objClass == CKO_SECRET_KEY) {
-- if (!attributeExists(CKA_LABEL)) {
-- setAttribute(CKA_LABEL, &empty);
-- }
-- if (!attributeExists(CKA_KEY_TYPE)) {
-- /* default to DES3 */
-- setAttributeULong(CKA_KEY_TYPE, CKK_DES3);
-- }
-+ if (!attributeExists(CKA_LABEL)) {
-+ setAttribute(CKA_LABEL, &empty);
-+ }
-+ if (!attributeExists(CKA_KEY_TYPE)) {
-+ /* default to DES3 */
-+ setAttributeULong(CKA_KEY_TYPE, CKK_DES3);
-+ }
- }
- if (!attributeExists(CKA_START_DATE)) {
-- setAttribute(CKA_START_DATE, &empty);
-+ setAttribute(CKA_START_DATE, &empty);
- }
- if (!attributeExists(CKA_END_DATE)) {
-- setAttribute(CKA_END_DATE, &empty);
-+ setAttribute(CKA_END_DATE, &empty);
- }
- }
-
- void
--Key::completeKey(const PKCS11Object &cert)
-+PKCS11Object::completeKey(const PKCS11Object &cert)
- {
- // infer key attributes from cert
- bool modulusExists, exponentExists;
-- CKYBuffer modulus; CKYBuffer_InitEmpty(&modulus);
-- CKYBuffer exponent; CKYBuffer_InitEmpty(&exponent);
-+ bool pointExists, paramsExists;
-+
-+ PKCS11Object::KeyType keyType;
-+ const CKYBuffer *key = cert.getPubKey();
-
- if (!attributeExists(CKA_LABEL)) {
-- setAttribute(CKA_LABEL, cert.getAttribute(CKA_LABEL));
-+ setAttribute(CKA_LABEL, cert.getAttribute(CKA_LABEL));
- }
-+
-+ CKYBuffer param1; CKYBuffer_InitEmpty(¶m1);
-+ CKYBuffer param2; CKYBuffer_InitEmpty(¶m2);
- try {
-- modulusExists = attributeExists(CKA_MODULUS);
-- exponentExists = attributeExists(CKA_PUBLIC_EXPONENT);
-- if (!modulusExists || !exponentExists) {
-- const CKYBuffer *key = cert.getPubKey();
-- GetKeyFields(key, &modulus, &exponent);
-- if (!modulusExists) {
-- setAttribute(CKA_MODULUS, &modulus);
-- }
-- if (!exponentExists) {
-- setAttribute(CKA_PUBLIC_EXPONENT, &exponent);
-- }
-- }
-+ keyType = GetKeyTypeFromSPKI(key);
-+ setKeyType(keyType);
-+
-+ switch (keyType) {
-+ case rsa:
-+ modulusExists = attributeExists(CKA_MODULUS);
-+ exponentExists = attributeExists(CKA_PUBLIC_EXPONENT);
-+ if (!modulusExists || !exponentExists) {
-+ GetKeyFields(key, ¶m1, ¶m2);
-+ if (!modulusExists) {
-+ setAttribute(CKA_MODULUS, ¶m1);
-+ }
-+ if (!exponentExists) {
-+ setAttribute(CKA_PUBLIC_EXPONENT, ¶m2);
-+ }
-+ }
-+ break;
-+ case ecc:
-+ pointExists = attributeExists(CKA_EC_POINT);
-+ paramsExists = attributeExists(CKA_EC_PARAMS);
-+
-+ if (!pointExists || !paramsExists) {
-+ GetECKeyFields(key, ¶m1, ¶m2);
-+ if (!pointExists) {
-+ setAttribute(CKA_EC_POINT, ¶m1);
-+ }
-+ if (!paramsExists) {
-+ setAttribute(CKA_EC_PARAMS, ¶m2);
-+ }
-+ }
-+ break;
-+ default:
-+ break;
-+ }
- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-- throw e;
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
-+ throw e;
- }
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
- }
-
- static SECStatus
--GetCertFieldItems(const CKYByte *dercert,unsigned int cert_length,
-+GetCertFieldItems(const CKYByte *dercert, CKYSize cert_length,
- CCItem *issuer, CCItem *serial, CCItem *derSN, CCItem *subject,
- CCItem *valid, CCItem *subjkey)
- {
- const CKYByte *buf;
-- unsigned int buf_length;
-+ CKYSize buf_length;
- const CKYByte*dummy;
-- unsigned int dummylen;
-+ CKYSize dummylen;
-
- /* get past the signature wrap */
- buf = dataStart(dercert,cert_length,&buf_length, false);
-@@ -737,14 +1135,14 @@ GetCertFieldItems(const CKYByte *dercert
-
- static void
- GetCertFields(const CKYBuffer *derCert, CKYBuffer *derSerial,
-- CKYBuffer *derSubject, CKYBuffer *derIssuer, CKYBuffer *subjectKey)
-+ CKYBuffer *derSubject, CKYBuffer *derIssuer, CKYBuffer *subjectKey)
- {
- SECStatus rv;
- CCItem issuerItem, serialItem, derSerialItem, subjectItem,
- validityItem, subjectKeyItem;
-
- rv = GetCertFieldItems(CKYBuffer_Data(derCert), CKYBuffer_Size(derCert),
-- &issuerItem, &serialItem, &derSerialItem, &subjectItem, &validityItem,
-+ &issuerItem, &serialItem, &derSerialItem, &subjectItem, &validityItem,
- &subjectKeyItem);
-
- if( rv != SECSuccess ) {
-@@ -769,50 +1167,50 @@ Cert::Cert(unsigned long muscleObjID, co
- CK_ULONG certTypeValue = CKC_X_509;
-
- CKYBuffer_InitFromData(&certType, (CKYByte *)&certTypeValue,
-- sizeof(certTypeValue));
-+ sizeof(certTypeValue));
- CKYBuffer_Resize(&pubKey,0);
-
- try {
-- setAttribute(CKA_CERTIFICATE_TYPE, &certType);
-+ setAttribute(CKA_CERTIFICATE_TYPE, &certType);
-
-- if (!attributeExists(CKA_VALUE)) {
-- if (derCert) {
-- setAttribute(CKA_VALUE, derCert);
-- } else {
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Missing certificate data from token");
-- }
-- }
-+ if (!attributeExists(CKA_VALUE)) {
-+ if (derCert) {
-+ setAttribute(CKA_VALUE, derCert);
-+ } else {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Missing certificate data from token");
-+ }
-+ }
-
-- if (!derCert) {
-- derCert = getAttribute(CKA_VALUE);
-- if (!derCert) {
-- // paranoia, should never happen since we verify the
-- // attribute exists above
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Missing certificate data from token");
-- }
-- }
-+ if (!derCert) {
-+ derCert = getAttribute(CKA_VALUE);
-+ if (!derCert) {
-+ // paranoia, should never happen since we verify the
-+ // attribute exists above
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Missing certificate data from token");
-+ }
-+ }
-
-- // infer cert attributes
-+ // infer cert attributes
-
-- GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-+ GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-
-- if (!attributeExists(CKA_SERIAL_NUMBER)) {
-- setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-- }
-- if (!attributeExists(CKA_SUBJECT)) {
-- setAttribute(CKA_SUBJECT, &derSubject);
-- }
-- if (!attributeExists(CKA_ISSUER)) {
-- setAttribute(CKA_ISSUER, &derIssuer);
-- }
-+ if (!attributeExists(CKA_SERIAL_NUMBER)) {
-+ setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-+ }
-+ if (!attributeExists(CKA_SUBJECT)) {
-+ setAttribute(CKA_SUBJECT, &derSubject);
-+ }
-+ if (!attributeExists(CKA_ISSUER)) {
-+ setAttribute(CKA_ISSUER, &derIssuer);
-+ }
- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&certType);
-- CKYBuffer_FreeData(&derSerial);
-- CKYBuffer_FreeData(&derSubject);
-- CKYBuffer_FreeData(&derIssuer);
-- throw e;
-+ CKYBuffer_FreeData(&certType);
-+ CKYBuffer_FreeData(&derSerial);
-+ CKYBuffer_FreeData(&derSubject);
-+ CKYBuffer_FreeData(&derIssuer);
-+ throw e;
- }
- CKYBuffer_FreeData(&certType);
- CKYBuffer_FreeData(&derSerial);
-@@ -822,7 +1220,7 @@ Cert::Cert(unsigned long muscleObjID, co
-
- Reader::Reader(unsigned long muscleObjID, CK_OBJECT_HANDLE handle,
- const char *reader, const CKYBuffer *cardATR, bool isCoolkey) :
-- PKCS11Object(muscleObjID, handle)
-+ PKCS11Object(muscleObjID, handle)
- {
- setAttributeULong(CKA_CLASS, CKO_MOZ_READER);
- setAttribute(CKA_LABEL, reader);
-@@ -833,9 +1231,10 @@ Reader::Reader(unsigned long muscleObjID
- setAttribute(CKA_MOZ_ATR, cardATR);
- }
-
-+
- CACPrivKey::CACPrivKey(CKYByte instance, const PKCS11Object &cert) :
-- PKCS11Object( ((int)'k') << 24 | ((int)instance+'0') << 16,
-- instance | 0x400)
-+ PKCS11Object( ((int)'k') << 24 | ((int)instance+'0') << 16,
-+ instance | 0x400)
- {
- CKYBuffer id;
- CKYBuffer empty;
-@@ -844,7 +1243,7 @@ CACPrivKey::CACPrivKey(CKYByte instance,
- /* So we know what the key is supposed to be used for based on
- * the instance */
- if (instance == 2) {
-- decrypt = TRUE;
-+ decrypt = TRUE;
- }
-
- CKYBuffer_InitEmpty(&empty);
-@@ -863,33 +1262,52 @@ CACPrivKey::CACPrivKey(CKYByte instance,
- setAttributeBool(CKA_LOCAL, TRUE);
- setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-
-- setAttributeBool(CKA_DECRYPT, decrypt);
- setAttributeBool(CKA_SIGN, !decrypt);
- setAttributeBool(CKA_SIGN_RECOVER, !decrypt);
- setAttributeBool(CKA_UNWRAP, FALSE);
- setAttributeBool(CKA_SENSITIVE, TRUE);
- setAttributeBool(CKA_EXTRACTABLE, FALSE);
-
-- CKYBuffer modulus; CKYBuffer_InitEmpty(&modulus);
-- CKYBuffer exponent; CKYBuffer_InitEmpty(&exponent);
-+ CKYBuffer param1; CKYBuffer_InitEmpty(¶m1);
-+ CKYBuffer param2; CKYBuffer_InitEmpty(¶m2);
-
- try {
-- const CKYBuffer *key = cert.getPubKey();
-- GetKeyFields(key, &modulus, &exponent);
-- setAttribute(CKA_MODULUS, &modulus);
-- setAttribute(CKA_PUBLIC_EXPONENT, &exponent);
-- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-- throw e;
-- }
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-+ const CKYBuffer *key = cert.getPubKey();
-+ keyType = GetKeyTypeFromSPKI(key);
-+ setKeyType(keyType);
-+
-+ switch (keyType) {
-+ case rsa:
-+ GetKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_MODULUS, ¶m1);
-+ setAttribute(CKA_PUBLIC_EXPONENT, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ setAttributeBool(CKA_DECRYPT, decrypt);
-+ setAttributeBool(CKA_DERIVE, FALSE);
-+ break;
-+ case ecc:
-+ GetECKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_EC_POINT, ¶m1);
-+ setAttribute(CKA_EC_PARAMS, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ setAttributeBool(CKA_DECRYPT, FALSE);
-+ setAttributeBool(CKA_DERIVE, decrypt);
-+ break;
-+ default:
-+ break;
-+ }
-+ } catch (PKCS11Exception &e) {
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
-+ throw e;
-+ }
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
- }
-
- CACPubKey::CACPubKey(CKYByte instance, const PKCS11Object &cert) :
-- PKCS11Object( ((int)'k') << 24 | ((int)(instance+'5')) << 16,
-- instance | 0x500)
-+ PKCS11Object( ((int)'k') << 24 | ((int)(instance+'5')) << 16,
-+ instance | 0x500)
- {
- CKYBuffer id;
- CKYBuffer empty;
-@@ -898,7 +1316,7 @@ CACPubKey::CACPubKey(CKYByte instance, c
- /* So we know what the key is supposed to be used for based on
- * the instance */
- if (instance == 2) {
-- encrypt = TRUE;
-+ encrypt = TRUE;
- }
-
- CKYBuffer_InitEmpty(&empty);
-@@ -915,83 +1333,102 @@ CACPubKey::CACPubKey(CKYByte instance, c
- setAttribute(CKA_END_DATE, &empty);
- setAttributeBool(CKA_DERIVE, FALSE);
- setAttributeBool(CKA_LOCAL, TRUE);
-- setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-
- setAttributeBool(CKA_ENCRYPT, encrypt);
- setAttributeBool(CKA_VERIFY, !encrypt);
- setAttributeBool(CKA_VERIFY_RECOVER, !encrypt);
- setAttributeBool(CKA_WRAP, FALSE);
-
-- CKYBuffer modulus; CKYBuffer_InitEmpty(&modulus);
-- CKYBuffer exponent; CKYBuffer_InitEmpty(&exponent);
-+ CKYBuffer param1; CKYBuffer_InitEmpty(¶m1);
-+ CKYBuffer param2; CKYBuffer_InitEmpty(¶m2);
-
- try {
-- const CKYBuffer *key = cert.getPubKey();
-- GetKeyFields(key, &modulus, &exponent);
-- setAttribute(CKA_MODULUS, &modulus);
-- setAttribute(CKA_PUBLIC_EXPONENT, &exponent);
-- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-- throw e;
-- }
-- CKYBuffer_FreeData(&modulus);
-- CKYBuffer_FreeData(&exponent);
-+ const CKYBuffer *key = cert.getPubKey();
-+ keyType = GetKeyTypeFromSPKI(key);
-+ setKeyType(keyType);
-+
-+ switch (keyType) {
-+ case rsa:
-+ GetKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_MODULUS, ¶m1);
-+ setAttribute(CKA_PUBLIC_EXPONENT, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ break;
-+ case ecc:
-+ GetECKeyFields(key, ¶m1, ¶m2);
-+ setAttribute(CKA_EC_POINT, ¶m1);
-+ setAttribute(CKA_EC_PARAMS, ¶m2);
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ break;
-+ default:
-+ break;
-+ }
-+ } catch (PKCS11Exception &e) {
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
-+ throw e;
-+ }
-+ CKYBuffer_FreeData(¶m1);
-+ CKYBuffer_FreeData(¶m2);
- }
-
- static const char *CAC_Label[] = {
-- "CAC ID Certificate",
-- "CAC Email Signature Certificate",
-- "CAC Email Encryption Certificate",
-+ "CAC ID Certificate",
-+ "CAC Email Signature Certificate",
-+ "CAC Email Encryption Certificate",
- };
-
- static const unsigned char CN_DATA[] = { 0x55, 0x4, 0x3 };
- const unsigned int CN_LENGTH = sizeof(CN_DATA);
-
- static SECStatus
--GetCN(const CKYByte *dn, unsigned int dn_length, CCItem *cn)
-+GetCN(const CKYByte *dn, CKYSize dn_length, CCItem *cn)
- {
- const CKYByte *buf;
-- unsigned int buf_length;
-+ CKYSize buf_length;
-
- /* unwrap the sequence */
- buf = dataStart(dn,dn_length,&buf_length, false);
- if (buf == NULL) return SECFailure;
-
- while (buf_length) {
-- const CKYByte *name;
-- unsigned int name_length;
-- const CKYByte *oid;
-- unsigned int oid_length;
--
-- /* unwrap the set */
-- name = dataStart(buf, buf_length, &name_length, false);
-+ const CKYByte *name;
-+ CKYSize name_length;
-+ const CKYByte *oid;
-+ CKYSize oid_length;
-+
-+ /* unwrap the set */
-+ name = dataStart(buf, buf_length, &name_length, false);
-+ if (name == NULL) return SECFailure;
-
- /* advance to next set */
-- buf_length -= (name-buf) + name_length;
-- buf = name + name_length;
-+ buf_length -= (name-buf) + name_length;
-+ buf = name + name_length;
-
-- /* unwrap the Sequence */
-- name = dataStart(name, name_length, &name_length, false);
-+ /* unwrap the Sequence */
-+ name = dataStart(name, name_length, &name_length, false);
-+ if (name == NULL) return SECFailure;
-
- /* unwrap the oid */
-- oid = dataStart(name, name_length, &oid_length, false);
-+ oid = dataStart(name, name_length, &oid_length, false);
-+ if (oid == NULL) return SECFailure;
-
-- /* test the oid */
-- if (oid_length != CN_LENGTH) {
-- continue;
-- }
-- if (memcmp(oid, CN_DATA, CN_LENGTH) != 0) {
-- continue;
-- }
--
-- /* advance to CN */
-- name_length -= (oid-name) + oid_length;
-- name = oid + oid_length;
-+ /* test the oid */
-+ if (oid_length != CN_LENGTH) {
-+ continue;
-+ }
-+ if (memcmp(oid, CN_DATA, CN_LENGTH) != 0) {
-+ continue;
-+ }
-
-- /* unwrap the CN */
-- cn->data = dataStart(name, name_length, &cn->len, false);
-- return SECSuccess;
-+ /* advance to CN */
-+ name_length -= (oid-name) + oid_length;
-+ name = oid + oid_length;
-+
-+ /* unwrap the CN */
-+ cn->data = dataStart(name, name_length, &cn->len, false);
-+ if (cn->data == NULL) return SECFailure;
-+ return SECSuccess;
- }
- return SECFailure;
- }
-@@ -1006,11 +1443,11 @@ GetUserName(const CKYBuffer *dn)
- rv = GetCN(CKYBuffer_Data(dn), CKYBuffer_Size(dn) , &cn);
-
- if( rv != SECSuccess ) {
-- return NULL;
-+ return NULL;
- }
- string = new char [ cn.len + 1 ];
- if (string == NULL) {
-- return NULL;
-+ return NULL;
- }
- memcpy(string, cn.data, cn.len);
- string[cn.len] = 0;
-@@ -1018,18 +1455,11 @@ GetUserName(const CKYBuffer *dn)
- }
-
- CACCert::CACCert(CKYByte instance, const CKYBuffer *derCert) :
-- PKCS11Object( ((int)'c') << 24 | ((int)instance+'0') << 16,
-- instance | 0x600)
-+ PKCS11Object( ((int)'c') << 24 | ((int)instance+'0') << 16,
-+ instance | 0x600)
- {
- CKYBuffer id;
- CKYBuffer empty;
-- CK_BBOOL decrypt = FALSE;
--
-- /* So we know what the key is supposed to be used for based on
-- * the instance */
-- if (instance == 2) {
-- decrypt = TRUE;
-- }
-
- CKYBuffer_InitEmpty(&empty);
- setAttributeULong(CKA_CLASS, CKO_CERTIFICATE);
-@@ -1050,19 +1480,19 @@ CACCert::CACCert(CKYByte instance, const
- CKYBuffer_Resize(&pubKey,0);
-
- try {
-- setAttribute(CKA_VALUE, derCert);
-- // infer cert attributes
-+ setAttribute(CKA_VALUE, derCert);
-+ // infer cert attributes
-
-- GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-+ GetCertFields(derCert, &derSerial, &derSubject, &derIssuer, &pubKey);
-
-- setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-- setAttribute(CKA_SUBJECT, &derSubject);
-- setAttribute(CKA_ISSUER, &derIssuer);
-+ setAttribute(CKA_SERIAL_NUMBER, &derSerial);
-+ setAttribute(CKA_SUBJECT, &derSubject);
-+ setAttribute(CKA_ISSUER, &derIssuer);
- } catch (PKCS11Exception &e) {
-- CKYBuffer_FreeData(&derSerial);
-- CKYBuffer_FreeData(&derSubject);
-- CKYBuffer_FreeData(&derIssuer);
-- throw e;
-+ CKYBuffer_FreeData(&derSerial);
-+ CKYBuffer_FreeData(&derSubject);
-+ CKYBuffer_FreeData(&derIssuer);
-+ throw e;
- }
-
- name = GetUserName(&derSubject); /* adopt */
-@@ -1070,3 +1500,1248 @@ CACCert::CACCert(CKYByte instance, const
- CKYBuffer_FreeData(&derSubject);
- CKYBuffer_FreeData(&derIssuer);
- }
-+
-+static const CKYByte rev[] = {
-+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-+};
-+
-+unsigned long GetBits(const CKYByte *entry, CKYSize entrySize,
-+ unsigned int numBits, unsigned int numBytes)
-+{
-+ unsigned long bits = 0;
-+ unsigned long bitFlag = 0;
-+ unsigned int i;
-+
-+ /* size of zero is valid for no bits */
-+ if (entrySize <= 1) {
-+ return 0;
-+ }
-+ entrySize--;
-+ entry++;
-+
-+ /* if we are longer than and unsigned, just bail now */
-+ if (entrySize > sizeof (unsigned long)) {
-+ bitFlag = BROKEN_FLAG;
-+ entrySize = sizeof(unsigned long);
-+ }
-+ /* turn the flags into an int */
-+ for (i=0; i < entrySize; i++) {
-+ CKYByte c = rev[entry[i]];
-+ bits = bits | (((unsigned long)c) << (i*8));
-+ }
-+ return bits | bitFlag;
-+}
-+
-+
-+/*
-+ * parse the path object.
-+ * Caller has already unwrapped the outer ASN1Sequence
-+ */
-+CKYStatus PK15ObjectPath::setObjectPath(const CKYByte *current, CKYSize size)
-+{
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ unsigned int i;
-+ CKYStatus status;
-+
-+
-+ if ((current == NULL) || (current[0] != ASN1_OCTET_STRING)) {
-+ return CKYINVALIDDATA;
-+ }
-+ /* entry */
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ status = CKYBuffer_Replace(&path, 0, entry, entrySize);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+
-+ /* index */
-+ if ((size != 0) && current[0] == ASN1_INTEGER) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ if (entrySize > 5) { return CKYINVALIDDATA; }
-+ for (index = 0, i=0; i < entrySize; i++) {
-+ index = (index << 8) + (unsigned int) entry[i];
-+ }
-+ }
-+
-+ /* length */
-+ if ((size != 0) && ((current[0]|ASN1_CONSTRUCTED) == ASN1_CHOICE_0)) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ if (entrySize > 5) { return CKYINVALIDDATA; }
-+ for (length = 0, i=0; i < entrySize; i++) {
-+ length = (length << 8) + (unsigned int) entry[i];
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+static unsigned int pK15GetTag(PK15ObjectType type) {
-+ switch (type) { case PK15PvKey: case PK15PuKey: return 'k'<<24;
-+ case PK15Cert: return 'c' << 24; default: break; }
-+ return 'v';
-+}
-+
-+
-+PK15Object::PK15Object(CKYByte inst, PK15ObjectType type,
-+ const CKYByte *der, CKYSize derSize)
-+ : PKCS11Object(pK15GetTag(type) | ((inst+'0') << 16), 0xa000 | inst)
-+{
-+ CKYStatus status;
-+
-+ instance = inst;
-+ p15Type = type;
-+ CKYBuffer_InitEmpty(&authId);
-+ CKYBuffer_InitEmpty(&pinAuthId);
-+ state = PK15StateInit;
-+ pinInfo.pinFlags = 0;
-+ pinInfo.pinType = P15PinUTF8;
-+ pinInfo.minLength = 4;
-+ pinInfo.storedLength = 0;
-+ pinInfo.maxLength = 0;
-+ pinInfo.pinRef = 0;
-+ pinInfo.padChar = 0xff;
-+
-+ status = completeObject(der, derSize);
-+ if (status != CKYSUCCESS) {
-+ state = PK15StateInit; /* don't try to fetch any more if we failed */
-+ }
-+}
-+
-+/* returns true if there is more work to do... */
-+CKYStatus
-+PK15Object::completeObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYByte objectTag;
-+ CKYStatus status;
-+ CKYBitFlags bits;
-+
-+ switch (state) {
-+ case PK15StateInit:
-+ case PK15StateNeedObject:
-+ break;
-+ case PK15StateNeedRawPublicKey:
-+ return completeRawPublicKey(current, currentSize);
-+ case PK15StateNeedRawCertificate:
-+ return completeRawCertificate(current, currentSize);
-+ case PK15StateComplete:
-+ return CKYSUCCESS;
-+ }
-+
-+ if (current == NULL) { return CKYINVALIDARGS; }
-+
-+ objectTag = current[0];
-+
-+ setAttributeBool(CKA_TOKEN, TRUE);
-+
-+ /* set type specific attributes */
-+ switch (p15Type) {
-+ case PK15Cert:
-+ setAttributeULong(CKA_CLASS, CKO_CERTIFICATE);
-+ setAttributeULong(CKA_CERTIFICATE_TYPE, CKC_X_509);
-+ if (objectTag != PK15X509CertType) {
-+ return CKYUNSUPPORTED;
-+ }
-+ break;
-+ case PK15PvKey:
-+ setAttributeULong(CKA_CLASS, CKO_PRIVATE_KEY);
-+ goto set_key_type;
-+ case PK15PuKey:
-+ setAttributeULong(CKA_CLASS, CKO_PUBLIC_KEY);
-+set_key_type:
-+ switch (objectTag) {
-+ case PK15RSAKeyType:
-+ keyType = rsa;
-+ setAttributeULong(CKA_KEY_TYPE, CKK_RSA);
-+ break;
-+ case PK15ECCKeyType:
-+ keyType = ecc;
-+ setAttributeULong(CKA_KEY_TYPE, CKK_EC);
-+ break;
-+ case PK15DSAKeyType:
-+ case PK15DHKeyType:
-+ default:
-+ return CKYUNSUPPORTED;
-+ }
-+ break;
-+ case PK15AuthObj:
-+ setAttributeULong(CKA_CLASS, CKO_DATA);
-+ break;
-+ default:
-+ return CKYUNSUPPORTED;
-+ }
-+
-+ /* unwrap the object */
-+ current = dataStart(current, currentSize, ¤tSize, false);
-+ if (current == NULL) { return CKYINVALIDDATA; }
-+
-+ /*
-+ * parse the Common Attributes
-+ * label UTF8_STRING
-+ * flags BIT_STRING (optional)
-+ * authid OCTET_STRING (optional)
-+ */
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE))
-+ { return CKYINVALIDDATA; }
-+ /* unwrap */
-+ commonAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* point current to the next section (cass attributes) */
-+ tagSize = commonAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize +tagSize);
-+
-+ /* get the CKA_LABEL */
-+ if (commonAttributes[0] != ASN1_UTF8_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAttributes;
-+ commonAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_LABEL, entry, entrySize);
-+
-+ /* parse optional flags */
-+ bits = BROKEN_FLAG;
-+ if (commonAttributes[0] == ASN1_BIT_STRING) {
-+ entry = dataStart(commonAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAttributes;
-+ commonAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ bits = GetBits(entry,entrySize,2,1);
-+ }
-+
-+ if (commonAttributes[0] == ASN1_OCTET_STRING) {
-+ entry = dataStart(commonAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAttributes;
-+ commonAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ status = CKYBuffer_Replace(&authId, 0, entry, entrySize);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+ }
-+
-+ if (bits & BROKEN_FLAG) {
-+ bits = defaultCommonBits();
-+ }
-+ setAttributeBool(CKA_PRIVATE,
-+ (bits & P15FlagsPrivate) ? TRUE: FALSE);
-+ setAttributeBool(CKA_MODIFIABLE, FALSE); /* our token is ReadOnly, so the
-+ * object is never modifiable for
-+ * us */
-+ /* future common attributes here */
-+
-+ /*
-+ * Parse Class variables
-+ *
-+ */
-+ switch (p15Type) {
-+ case PK15Cert:
-+ status = completeCertObject(current,currentSize);
-+ break;
-+ case PK15PuKey:
-+ case PK15PvKey:
-+ status = completeKeyObject(current,currentSize);
-+ break;
-+ case PK15AuthObj:
-+ status = completeAuthObject(current, currentSize);
-+ break;
-+ }
-+ return status;
-+}
-+
-+
-+CKYStatus
-+PK15Object::completeCertObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonCertAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ CKYByte valueTag;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+
-+ /*
-+ * parse the Common Cert Attributes
-+ * id OCTET_STRING
-+ * authority BOOLEAN DEFAULT FALSE
-+ * requestId BIT_STRING (optional)
-+ * thumbprint [0] PKS15OOBCertHash (optional)
-+ */
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE))
-+ { return CKYINVALIDARGS; }
-+ /* unwrap */
-+ commonCertAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonCertAttributes == NULL) { return CKYINVALIDDATA; }
-+ /* point current to the next section (type attributes) */
-+ tagSize = commonCertAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize +tagSize);
-+
-+ /* get the id */
-+ if (commonCertAttributes[0] != ASN1_OCTET_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonCertAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonCertAttributes;
-+ commonCertAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_ID, entry, entrySize);
-+
-+
-+ /* skip authority (currently unused) */
-+ /* skip requestID */
-+ /* skip thumbprint */
-+ /* future common cert attributes here */
-+
-+ /* certs have not subclass attributes ASN1_CHOICE_0 */
-+
-+ /* handle the X509 type attributes */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDDATA; }
-+ /* unwrap */
-+ commonCertAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonCertAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /*
-+ * PCKS11X504CertificateAttributes
-+ * value SEQUENCE or CHOICE_0
-+ * ... don't care about the rest.
-+ */
-+ valueTag = commonCertAttributes[0];
-+ /* unwrapp */
-+ entry = dataStart(commonCertAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ if (valueTag == ASN1_SEQUENCE) {
-+ entry = dataStart(entry, entrySize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ state = PK15StateNeedRawCertificate;
-+ return status;
-+ }
-+ if (valueTag != ASN1_CHOICE_0) {
-+ return CKYINVALIDDATA;
-+ }
-+ return completeRawCertificate(entry, entrySize);
-+}
-+
-+CKYStatus
-+PK15Object::completeAuthObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonAuthAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+
-+ if (current == NULL) { return CKYINVALIDARGS; }
-+ /* common Auth attributes */
-+ if (current[0] == ASN1_SEQUENCE) {
-+ /* unwrap */
-+ commonAuthAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
-+ tagSize = commonAuthAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+ if (commonAuthAttributes[0] != ASN1_OCTET_STRING) {
-+ return CKYINVALIDDATA;
-+ }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ status = CKYBuffer_Replace(&pinAuthId, 0, entry, entrySize);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+
-+ }
-+ /* auth specific values */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDARGS; }
-+ /* unwrap */
-+ commonAuthAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
-+ tagSize = commonAuthAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+ /*
-+ * parse the Pin Auth Attributes
-+ * pinFlags BIT_STRING
-+ * pinType ENUMERATED (bcd, ascii-numeric, utf8)
-+ * minLength INTEGER
-+ * storedLength INTEGER
-+ * maxlength INTEGER (optional)
-+ * pinReference CHOICE_0 (optional)
-+ * padChar OCTET_STRING (optional)
-+ * lastPinChange GENERALIZED_TIME (optional)
-+ * path PKCS15Path (optional)
-+ */
-+ if (commonAuthAttributes[0] != ASN1_SEQUENCE) { return CKYINVALIDARGS; }
-+ commonAuthAttributes = dataStart(commonAuthAttributes,
-+ commonSize, &commonSize, false);
-+ if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* parse pin flags */
-+ if (commonAuthAttributes[0] != ASN1_BIT_STRING) { return CKYINVALIDDATA; }
-+
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ pinInfo.pinFlags = GetBits(entry,entrySize,9,2);
-+
-+
-+ /* parse PinType */
-+ if (commonAuthAttributes[0] != ASN1_ENUMERATED) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* turn entry into an int */
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.pinType = (P15PinType) *entry;
-+
-+ /* parse minLength */
-+ if (commonAuthAttributes[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.minLength = *entry;
-+
-+ /* parse storedLength */
-+ if (commonAuthAttributes[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.storedLength = *entry;
-+
-+ /* parse maxLength (optional) */
-+ if (commonAuthAttributes[0] == ASN1_INTEGER) {
-+ unsigned long maxPin;
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > sizeof (maxPin)) { return CKYINVALIDARGS; }
-+ maxPin = 0;
-+ CKYSize i;
-+ for (i=0; i < entrySize; i++) {
-+ maxPin = (maxPin << 8) | entry[i];
-+ }
-+ pinInfo.maxLength = maxPin;
-+ }
-+
-+ /* parse pin ref (optional) */
-+ if ((commonAuthAttributes[0]|ASN1_CONSTRUCTED) == ASN1_CHOICE_0) {
-+ CKYByte pinRef;
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 2) { return CKYINVALIDARGS; }
-+ if (entrySize == 2) {
-+ if (*entry != 0) { return CKYINVALIDARGS; }
-+ pinRef = entry[1];
-+ } else pinRef = entry[0];
-+ pinInfo.pinRef = pinRef;
-+ }
-+
-+ /* parse padChar */
-+ if (commonAuthAttributes[0] == ASN1_OCTET_STRING) {
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 1) { return CKYINVALIDARGS; }
-+ pinInfo.padChar = *entry;
-+ }
-+
-+ /* skip lastPinChange */
-+ if (commonAuthAttributes[0] == ASN1_GENERALIZED_TIME) {
-+ entry = dataStart(commonAuthAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ }
-+ /* parse path */
-+ if (commonAuthAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonAuthAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonAuthAttributes;
-+ commonAuthAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+ }
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+PK15Object::completeKeyObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonKeyAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ unsigned long bits;
-+ /*bool native; */
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ /*
-+ * parse the Common Key Attributes
-+ * id OCTET_STRING
-+ * usageFlags BIT_STRING
-+ * native BOOLEAN DEFAULT TRUE
-+ * accessFlags BIT_STRING (optional)
-+ * keyReference OCTET_STRING (optional)
-+ * startDate GENERALIZED_TIME (optional)
-+ * endDate [0] GENERALIZED_TYPE (optional)
-+ */
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE))
-+ { return CKYINVALIDARGS; }
-+ /* unwrap */
-+ commonKeyAttributes = dataStart(current, currentSize, &commonSize, false);
-+ if (commonKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* point current to the next section (sublcass attributes) */
-+ tagSize = commonKeyAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+
-+ /* get the id */
-+ if (commonKeyAttributes[0] != ASN1_OCTET_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_ID, entry, entrySize);
-+
-+ /* parse flags */
-+ if (commonKeyAttributes[0] != ASN1_BIT_STRING) { return CKYINVALIDDATA; }
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ bits = GetBits(entry,entrySize,10,2);
-+ if (bits & BROKEN_FLAG) {
-+ bits = defaultUsageBits();
-+ }
-+ setAttributeBool(CKA_ENCRYPT,
-+ (bits & P15UsageEncrypt) ? TRUE : FALSE);
-+ setAttributeBool(CKA_DECRYPT,
-+ (bits & P15UsageDecrypt) ? TRUE : FALSE);
-+ setAttributeBool(CKA_SIGN,
-+ (bits & P15UsageSign) ? TRUE : FALSE);
-+ setAttributeBool(CKA_SIGN_RECOVER,
-+ (bits & P15UsageSignRecover) ? TRUE : FALSE);
-+ setAttributeBool(CKA_WRAP,
-+ (bits & P15UsageWrap) ? TRUE : FALSE);
-+ setAttributeBool(CKA_UNWRAP,
-+ (bits & P15UsageUnwrap) ? TRUE : FALSE);
-+ setAttributeBool(CKA_VERIFY,
-+ (bits & P15UsageVerify) ? TRUE : FALSE);
-+ setAttributeBool(CKA_VERIFY_RECOVER,
-+ (bits & P15UsageVerifyRecover) ? TRUE : FALSE);
-+ setAttributeBool(CKA_DERIVE,
-+ (bits & P15UsageDerive) ? TRUE : FALSE);
-+ /* no CKA value for P15UsageNonRepudiation */
-+ if (bits & P15UsageNonRepudiation) {
-+ /* set signing and sign recover. Non-repudiation keys are automatically
-+ * signing keys */
-+ setAttributeBool(CKA_SIGN, TRUE);
-+ if (keyType == rsa) {
-+ setAttributeBool(CKA_SIGN_RECOVER, TRUE);
-+ }
-+ }
-+
-+ /* parse native (currently unused) */
-+ /*native=true; */
-+ if (commonKeyAttributes[0] == ASN1_BOOLEAN) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /*if ((entrySize == 1) && (entry[0] == 0)) {
-+ native = false;
-+ } */
-+ }
-+ /* parse access flags */
-+ bits = BROKEN_FLAG;
-+ if (commonKeyAttributes[0] == ASN1_BIT_STRING) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ bits = GetBits(entry,entrySize,4,1);
-+ }
-+ if (bits & BROKEN_FLAG) {
-+ bits = defaultAccessBits();
-+ }
-+ setAttributeBool(CKA_SENSITIVE,
-+ (bits & P15AccessSensitive) ? TRUE : FALSE);
-+ setAttributeBool(CKA_EXTRACTABLE,
-+ (bits & P15AccessExtractable) ? TRUE : FALSE);
-+ setAttributeBool(CKA_ALWAYS_SENSITIVE,
-+ (bits & P15AccessAlwaysSenstive) ? TRUE : FALSE);
-+ setAttributeBool(CKA_NEVER_EXTRACTABLE,
-+ (bits & P15AccessNeverExtractable)? TRUE : FALSE);
-+ setAttributeBool(CKA_LOCAL,
-+ (bits & P15AccessLocal) ? TRUE : FALSE);
-+
-+ /* parse the key reference */
-+ keyRef = PK15_INVALID_KEY_REF; /* invalid keyRef */
-+ if (commonKeyAttributes[0] == ASN1_INTEGER) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize == 1) {
-+ keyRef = entry[0];
-+ } else if ((entrySize == 2) && (entry[0] == 0)) {
-+ keyRef = entry[1];
-+ }
-+ }
-+ setAttribute(CKA_START_DATE, &empty);
-+ if (commonKeyAttributes[0] == ASN1_GENERALIZED_TIME) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_START_DATE,entry, entrySize);
-+ }
-+ setAttribute(CKA_END_DATE, &empty);
-+ if (commonKeyAttributes[0] == ASN1_CHOICE_0) {
-+ entry = dataStart(commonKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonKeyAttributes;
-+ commonKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_END_DATE,entry, entrySize);
-+ }
-+ /* future common key attributes here */
-+
-+ /*
-+ * Parse Class variables
-+ *
-+ */
-+ switch (p15Type) {
-+ case PK15PuKey:
-+ status = completePubKeyObject(current,currentSize);
-+ break;
-+ case PK15PvKey:
-+ status = completePrivKeyObject(current,currentSize);
-+ break;
-+ default:
-+ status=CKYLIBFAIL; /* shouldn't happen */
-+ break;
-+ }
-+ return status;
-+}
-+
-+CKYStatus PK15Object::completePrivKeyObject(const CKYByte *current,
-+ CKYSize currentSize)
-+{
-+ const CKYByte *commonPrivKeyAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ unsigned int modulusSize;
-+ unsigned int i;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ if (current == NULL) { return CKYINVALIDARGS; }
-+
-+ /* optional subclass = CommonPrivateKeyAttributes */
-+ if (current[0] == ASN1_CHOICE_0) {
-+ /*
-+ * PKCS15CommonPrivateKeyAttributes
-+ *
-+ * subjectName SEQUENCE optional
-+ * keyIdentifiers CHOICE 0 optional
-+ */
-+ /* unwrap */
-+ commonPrivKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ /* point current to the next section (type attributes) */
-+ tagSize = commonPrivKeyAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize +tagSize);
-+
-+ /* subjectName */
-+ if (commonPrivKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPrivKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPrivKeyAttributes;
-+ commonPrivKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_SUBJECT, entry, entrySize);
-+ }
-+
-+ /* keyIdentfiers */
-+ /* future CommonPrivateKeyAttributes here */
-+ }
-+
-+
-+ /* Type attributes (either PKCS15RSAPrivateKeyAttributes or
-+ * PKCS15ECCPrivateKeyAttributes) -- Not Optional */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDDATA; }
-+ /*
-+ * PKCS15RSAPrivateKeyAttributes
-+ * value PKCS15ObjectValue
-+ * modulusLength INTEGER
-+ * keyInfo SEQUENCE optional
-+ * PKCS15ECCPrivateKeyAttributes
-+ * value PKCS15ObjectValue
-+ * keyInfo SEQUENCE optional
-+ */
-+ /* unwrap */
-+ commonPrivKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* value */
-+ /* don't support direct private key objects */
-+ if (commonPrivKeyAttributes[0] == ASN1_CHOICE_0) { return CKYUNSUPPORTED; }
-+ if (commonPrivKeyAttributes[0] != ASN1_SEQUENCE) { return CKYINVALIDDATA; }
-+ commonPrivKeyAttributes = dataStart(commonPrivKeyAttributes, commonSize, &commonSize, false);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDARGS; }
-+ entry = dataStart(commonPrivKeyAttributes, commonSize, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPrivKeyAttributes;
-+ commonPrivKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+
-+ /* parse modulus size */
-+ if ((keyType == rsa) && commonPrivKeyAttributes[0] == ASN1_INTEGER) {
-+ entry = dataStart(commonPrivKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPrivKeyAttributes;
-+ commonPrivKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 4) {
-+ return CKYINVALIDDATA;
-+ }
-+ for (modulusSize = 0, i=0; i < entrySize; i++) {
-+ modulusSize = (modulusSize << 8) + entry[i];
-+ }
-+ setKeySize(modulusSize);
-+ }
-+
-+ if (keyType == rsa) {
-+ state = PK15StateComplete;
-+ return CKYSUCCESS; /* we're done with RSA */
-+ }
-+
-+ /* parse keyinfo at this point all we are after is the EC_PARAM*/
-+ if (commonPrivKeyAttributes[0] == ASN1_SEQUENCE) {
-+ /* unwrap */
-+ commonPrivKeyAttributes = dataStart(commonPrivKeyAttributes,
-+ commonSize, &commonSize, true);
-+ if (commonPrivKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ if (commonPrivKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPrivKeyAttributes, commonSize,
-+ &entrySize, true);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ setAttribute(CKA_EC_PARAMS, entry, entrySize);
-+ }
-+ }
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+PK15Object::completePubKeyObject(const CKYByte *current, CKYSize currentSize)
-+{
-+ const CKYByte *commonPubKeyAttributes;
-+ CKYSize commonSize;
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYBuffer empty;
-+ CKYStatus status;
-+ unsigned int modulusSize;
-+ unsigned int i;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ if (current == NULL) { return CKYINVALIDDATA; }
-+
-+ /* optional subclass = CommonPublicKeyAttributes */
-+ if (current[0] == ASN1_CHOICE_0) {
-+ /*
-+ * PKCS15CommonPublicKeyAttributes
-+ *
-+ * subjectName SEQUENCE optional
-+ * keyIdentifiers CHOICE 0 optional
-+ */
-+ /* unwrap */
-+ commonPubKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPubKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ /* point current to the next section (type attributes) */
-+ tagSize = commonPubKeyAttributes - current;
-+ current += commonSize + tagSize;
-+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
-+ currentSize -= (commonSize + tagSize);
-+
-+ /* subjectName */
-+ if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPubKeyAttributes;
-+ commonPubKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ setAttribute(CKA_SUBJECT, entry, entrySize);
-+ }
-+ /* future CommonPublicKeyAttributes here */
-+ }
-+
-+
-+ /* Type attributes (either PKCS15RSAPublicKeyAttributes or
-+ * PKCS15ECCPublicKeyAttributes) -- Not Optional */
-+ if (current[0] != ASN1_CHOICE_1) { return CKYINVALIDDATA; }
-+ /*
-+ * PKCS15RSAPublicKeyAttributes
-+ * value PKCS15ObjectValue
-+ * modulusLength INTEGER
-+ * keyInfo SEQUENCE optional
-+ * PKCS15ECCPublicKeyAttributes
-+ * value PKCS15ObjectValue
-+ * keyInfo SEQUENCE optional
-+ */
-+ /* unwrap */
-+ commonPubKeyAttributes =
-+ dataStart(current, currentSize, &commonSize, false);
-+ if (commonPubKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+
-+ /* value */
-+ if (commonPubKeyAttributes[0] == ASN1_CHOICE_0) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ status = completeRawPublicKey(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+ } else if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPubKeyAttributes;
-+ commonPubKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ /* if we have a path, the actual object is in another file,
-+ * tell the caller to get it and come back here */
-+ status = objectPath.setObjectPath(entry, entrySize);
-+ if (status != CKYSUCCESS) { return status; }
-+ state = PK15StateNeedRawPublicKey;
-+ }
-+
-+ /* parse modulus size */
-+ if ((keyType == rsa) && commonPubKeyAttributes[0] == ASN1_INTEGER) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDARGS; }
-+ tagSize = entry - commonPubKeyAttributes;
-+ commonPubKeyAttributes += entrySize + tagSize;
-+ commonSize -= (entrySize +tagSize);
-+ if (entrySize > 4) {
-+ return CKYINVALIDDATA;
-+ }
-+ for (modulusSize = 0, i=0; i < entrySize; i++) {
-+ modulusSize = (modulusSize << 8) + entry[i];
-+ }
-+ setKeySize(modulusSize);
-+ }
-+
-+ if (keyType == rsa) {
-+ return CKYSUCCESS; /* we're done with RSA */
-+ }
-+
-+ /* parse keyinfo at this point all we are after is the EC_PARAM*/
-+ if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ /* unwrap */
-+ commonPubKeyAttributes = dataStart(commonPubKeyAttributes,
-+ commonSize, &commonSize, true);
-+ if (commonPubKeyAttributes == NULL) { return CKYINVALIDDATA; }
-+ if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
-+ entry = dataStart(commonPubKeyAttributes, commonSize,
-+ &entrySize, true);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ setAttribute(CKA_EC_PARAMS, entry, entrySize);
-+ }
-+ }
-+ return CKYSUCCESS;
-+
-+}
-+
-+CKYStatus
-+PK15Object::completeRawCertificate(const CKYByte *derCert, CKYSize derCertSize)
-+{
-+ SECStatus rv;
-+ CCItem issuerItem, serialItem, derSerialItem, subjectItem,
-+ validityItem, subjectKeyItem;
-+ const char *certLabel;
-+
-+ setAttribute(CKA_VALUE, derCert, derCertSize);
-+ rv = GetCertFieldItems(derCert, derCertSize,
-+ &issuerItem, &serialItem, &derSerialItem, &subjectItem, &validityItem,
-+ &subjectKeyItem);
-+ if (rv != SECSuccess) {
-+ return CKYINVALIDDATA;
-+ }
-+ setAttribute(CKA_SERIAL_NUMBER, derSerialItem.data, derSerialItem.len);
-+ setAttribute(CKA_SUBJECT, subjectItem.data, subjectItem.len);
-+ setAttribute(CKA_ISSUER, issuerItem.data, issuerItem.len);
-+ CKYBuffer_Replace(&pubKey, 0, subjectKeyItem.data, subjectKeyItem.len);
-+ /* if we didn't get a label, set one based on the CN */
-+ certLabel = getLabel();
-+ if ((certLabel == NULL) || (*certLabel == 0)) {
-+ CKYBuffer subject;
-+ char *newLabel;
-+ CKYBuffer_InitFromData(&subject, subjectItem.data, subjectItem.len);
-+ newLabel = GetUserName(&subject);
-+ if (newLabel) {
-+ setAttribute(CKA_LABEL, (CKYByte *)newLabel,
-+ (CKYSize) strlen(newLabel)-1);
-+ delete [] newLabel;
-+ }
-+ CKYBuffer_FreeData(&subject);
-+ }
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+PK15Object::completeRawPublicKey(const CKYByte *current, CKYSize size)
-+{
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+
-+ if ((current == NULL) || (current[0] != ASN1_SEQUENCE)) {
-+ return CKYINVALIDDATA;
-+ }
-+ /* unwrap*/
-+ current = dataStart(current, size, &size, false);
-+ if (current == NULL) { return CKYINVALIDDATA; }
-+
-+ /* modulus */
-+ if (current[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize +tagSize);
-+ if ((entry[0] == 0) && (entrySize > 1)) {
-+ entry++; entrySize--;
-+ }
-+ setAttribute(CKA_MODULUS, entry, entrySize);
-+
-+ /* exponent */
-+ if (current[0] != ASN1_INTEGER) { return CKYINVALIDDATA; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { return CKYINVALIDDATA; }
-+ tagSize = entry - current;
-+ current += entrySize + tagSize;
-+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
-+ size -= (entrySize + tagSize);
-+ if ((entry[0] == 0) && (entrySize > 1)) {
-+ entry++; entrySize--;
-+ }
-+ setAttribute(CKA_PUBLIC_EXPONENT, entry, entrySize);
-+ state = PK15StateComplete;
-+ return CKYSUCCESS;
-+}
-+
-+DEREncodedSignature::DEREncodedSignature(const CKYBuffer *derSig)
-+{
-+
-+ CKYBuffer_InitEmpty(&derEncodedSignature);
-+ CKYBuffer_InitFromCopy(&derEncodedSignature, derSig);
-+}
-+
-+DEREncodedSignature::~DEREncodedSignature()
-+{
-+ CKYBuffer_FreeData(&derEncodedSignature);
-+}
-+
-+int DEREncodedSignature::getRawSignature(CKYBuffer *rawSig,
-+ unsigned int keySize)
-+{
-+ const CKYByte *buf = NULL;
-+
-+ if (rawSig == NULL) {
-+ return -1;
-+ }
-+
-+ if (CKYBuffer_Size(&derEncodedSignature) == 0) {
-+ return -1;
-+ }
-+
-+ CKYBuffer_Zero(rawSig);
-+
-+ CKYSize seq_length = 0;
-+ CKYSize expected_sig_len = ( (keySize + 7) / 8 ) * 2 ;
-+ CKYSize expected_piece_size = expected_sig_len / 2 ;
-+
-+ /* unwrap the sequence */
-+ buf = dataStart(CKYBuffer_Data(&derEncodedSignature), CKYBuffer_Size(&derEncodedSignature),&seq_length, false);
-+
-+ if (buf == NULL) return -1;
-+
-+ // unwrap first multi byte integer
-+
-+ CKYSize int_length = 0;
-+ const CKYByte *int1Buf = NULL;
-+ const CKYByte *int2Buf = NULL;
-+
-+ int1Buf = dataStart(buf, seq_length, &int_length, false );
-+
-+ if (int1Buf == NULL) return -1;
-+ //advance to next entry
-+
-+ if (int_length > expected_piece_size) {
-+
-+ unsigned int diff = int_length - expected_piece_size ;
-+
-+ /* Make sure we are chopping off zeroes
-+ Otherwise give up. */
-+
-+ for (int i = 0 ; i < (int) diff ; i++) {
-+ if ( int1Buf[i] != 0)
-+ return -1;
-+ }
-+
-+ int_length -= diff;
-+ int1Buf += diff;
-+
-+ }
-+
-+ seq_length -= (int1Buf -buf) + int_length;
-+ buf = int1Buf + int_length;
-+
-+ // unwrap second multi byte integer
-+
-+ CKYSize second_int_length = 0;
-+
-+ int2Buf = dataStart(buf, seq_length, &second_int_length, false);
-+
-+ if (int2Buf == NULL) return -1;
-+
-+
-+ if (second_int_length > expected_piece_size) {
-+ unsigned int diff = second_int_length - expected_piece_size ;
-+
-+ /* Make sure we are chopping off zeroes
-+ Otherwise give up. */
-+
-+ for (int i = 0 ; i < (int) diff ; i++) {
-+ if ( int2Buf[i] != 0)
-+ return -1;
-+ }
-+
-+ second_int_length -= diff;
-+ int2Buf += diff;
-+ }
-+
-+ CKYBuffer_AppendData(rawSig, int1Buf, int_length);
-+ CKYBuffer_AppendData(rawSig, int2Buf, second_int_length);
-+
-+ return CKYSUCCESS;
-+}
-+
-+DEREncodedTokenInfo::DEREncodedTokenInfo(CKYBuffer *derTokenInfo)
-+{
-+ const CKYByte *current = CKYBuffer_Data(derTokenInfo);
-+ const CKYByte *entry;
-+ CKYSize size = CKYBuffer_Size(derTokenInfo);
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ /* set token name, etc */
-+
-+ version = -1;
-+ CKYBuffer_InitEmpty(&serialNumber);
-+ manufacturer = NULL;
-+ tokenName = NULL;
-+
-+ if (current[0] != ASN1_SEQUENCE) {
-+ return; /* just use the defaults */
-+ }
-+ /* unwrap */
-+ current = dataStart(current, size, &size, false);
-+ if (current == NULL) return;
-+
-+ /* parse the version */
-+ if (current[0] != ASN1_INTEGER) { return; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ if (size < tagSize + entrySize) return;
-+ size -= tagSize + entrySize;
-+ if (entrySize < 1) {
-+ version = *entry;
-+ }
-+
-+ /* get the serial number */
-+ if (current[0] != ASN1_OCTET_STRING) { return ; }
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ CKYBuffer_Replace(&serialNumber, 0, entry, entrySize);
-+ /* should we fake the cuid here? */
-+
-+ /* get the optional manufacture ID */
-+ if (current[0] == ASN1_UTF8_STRING) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ manufacturer = (char *)malloc(entrySize+1);
-+ if (manufacturer) {
-+ memcpy(manufacturer, entry, entrySize);
-+ manufacturer[entrySize] = 0;
-+ }
-+ }
-+
-+ /* get the optional token name */
-+ /* most choices are constructed,
-+ * but this one isn't explicity add the flag */
-+ if ((current[0]|ASN1_CONSTRUCTED) == ASN1_CHOICE_0) {
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ tokenName = (char *)malloc(entrySize+1);
-+ if (tokenName) {
-+ memcpy(tokenName, entry, entrySize);
-+ tokenName[entrySize] = 0;
-+ }
-+ }
-+
-+ /* parsing flags */
-+#ifdef notdef
-+ /* we arn't using this right now, keep it for future reference */
-+ if (current[0] == ASN1_BIT_STRING) {
-+ /* recordinfo parsing would go here */
-+ unsigned long bits;
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) return;
-+ tagSize = entry - current;
-+ current += tagSize + entrySize;
-+ size -= tagSize + entrySize;
-+ bits = GetBits(entry, entrySize,8,2);
-+ }
-+#endif
-+ return;
-+}
-+
-diff -up ./src/coolkey/object.h.coolkey-update ./src/coolkey/object.h
---- ./src/coolkey/object.h.coolkey-update 2016-01-19 17:53:12.934012153 -0800
-+++ ./src/coolkey/object.h 2016-01-19 17:53:22.057937117 -0800
-@@ -27,6 +27,33 @@
-
- using std::list;
-
-+/*
-+ * Sigh PKCS 15 is heavily ASN.1...
-+ */
-+const CKYByte ASN1_BOOLEAN = 0x01;
-+const CKYByte ASN1_INTEGER = 0x02;
-+const CKYByte ASN1_BIT_STRING = 0x03;
-+const CKYByte ASN1_OCTET_STRING = 0x04;
-+const CKYByte ASN1_ENUMERATED = 0x0a;
-+const CKYByte ASN1_UTF8_STRING = 0x0c;
-+const CKYByte ASN1_GENERALIZED_TIME = 0x18;
-+const CKYByte ASN1_CONSTRUCTED = 0x20;
-+const CKYByte ASN1_SEQUENCE = 0x30;
-+const CKYByte ASN1_CHOICE_0 = 0xa0;
-+const CKYByte ASN1_CHOICE_1 = 0xa1;
-+const CKYByte ASN1_CHOICE_2 = 0xa2;
-+const CKYByte ASN1_CHOICE_3 = 0xa3;
-+
-+const CKYBitFlags BROKEN_FLAG = 0x80000000;
-+const unsigned int PK11_INVALID_KEY_REF = -1;
-+
-+const CKYByte PK15X509CertType = ASN1_SEQUENCE;
-+const CKYByte PK15RSAKeyType = ASN1_SEQUENCE;
-+const CKYByte PK15ECCKeyType = ASN1_CHOICE_0;
-+const CKYByte PK15DHKeyType = ASN1_CHOICE_1;
-+const CKYByte PK15DSAKeyType = ASN1_CHOICE_2;
-+const CKYByte PK15KEAKeyType = ASN1_CHOICE_3;
-+
- class PKCS11Attribute {
- private:
- CK_ATTRIBUTE_TYPE type;
-@@ -49,14 +76,40 @@ class PKCS11Attribute {
- CKYBuffer_Size(&cpy.value));
- return *this;
- }
-- PKCS11Attribute() { CKYBuffer_InitEmpty(&value); }
-+ PKCS11Attribute() : type(0){ CKYBuffer_InitEmpty(&value); }
- PKCS11Attribute(CK_ATTRIBUTE_TYPE type_, const CKYBuffer *value_)
- : type(type_) { CKYBuffer_InitFromCopy(&value, value_); }
-+ PKCS11Attribute(CK_ATTRIBUTE_TYPE type_, const CKYByte *data_,
-+ CKYSize size_) : type(type_)
-+ { CKYBuffer_InitFromData(&value, data_, size_); }
- ~PKCS11Attribute() { CKYBuffer_FreeData(&value); }
- };
-
-+class PK15ObjectPath {
-+ private:
-+ CKYBuffer path;
-+ CKYOffset index;
-+ CKYSize length;
-+ public:
-+ PK15ObjectPath() : index(0), length(0) { CKYBuffer_InitEmpty(&path); }
-+ PK15ObjectPath(const PK15ObjectPath &cpy) :
-+ index(cpy.index), length(cpy.length)
-+ { CKYBuffer_InitFromCopy(&path, &cpy.path); }
-+ ~PK15ObjectPath() { CKYBuffer_FreeData(&path); }
-+ const CKYBuffer *getPath() const { return &path; }
-+ CKYOffset getIndex() const { return index; }
-+ CKYSize getLength() const { return length; }
-+ CKYStatus setObjectPath(const CKYByte *entry, CKYSize size);
-+};
-+
-+
- class PKCS11Object {
- public:
-+ enum KeyType {
-+ rsa,
-+ ecc,
-+ unknown
-+ };
-
- typedef list<PKCS11Attribute> AttributeList;
- typedef AttributeList::iterator AttributeIter;
-@@ -67,6 +120,8 @@ class PKCS11Object {
- unsigned long muscleObjID;
- CK_OBJECT_HANDLE handle;
- char *label;
-+ unsigned int keySize;
-+ CK_USER_TYPE user;
-
- void parseOldObject(const CKYBuffer *data);
- void parseNewObject(const CKYBuffer *data);
-@@ -75,19 +130,39 @@ class PKCS11Object {
- PKCS11Object &operator=(PKCS11Object &cpy) { return *this; } //Disallow
-
- protected :
-- CKYBuffer pubKey;
- char *name;
-+ KeyType keyType;
-+ unsigned int keyRef;
-+ CKYBuffer pubKey;
-+ CKYBuffer authId;
-+ CKYBuffer pinAuthId;
-+ PK15ObjectPath objectPath;
-
- public:
- PKCS11Object(unsigned long muscleObjID, CK_OBJECT_HANDLE handle);
- PKCS11Object(unsigned long muscleObjID, const CKYBuffer *data,
- CK_OBJECT_HANDLE handle);
-- ~PKCS11Object() { delete [] label; delete [] name; CKYBuffer_FreeData(&pubKey); }
-+ virtual ~PKCS11Object() { delete [] label; delete [] name;
-+ CKYBuffer_FreeData(&pubKey); CKYBuffer_FreeData(&authId);
-+ CKYBuffer_FreeData(&pinAuthId); attributes.clear(); }
-
- PKCS11Object(const PKCS11Object& cpy) :
- attributes(cpy.attributes), muscleObjID(cpy.muscleObjID),
-- handle(cpy.handle), label(NULL), name(NULL) {
-- CKYBuffer_InitFromCopy(&pubKey,&cpy.pubKey); }
-+ handle(cpy.handle), label(NULL), keySize(cpy.keySize),
-+ user(cpy.user), name(NULL), keyType(cpy.keyType), keyRef(cpy.keyRef),
-+ objectPath(cpy.objectPath) {
-+ /* label is just a cached value, don't need
-+ * to copy it. */
-+ if (cpy.name != NULL) {
-+ int len = strlen(cpy.name);
-+ name= new char [len+1];
-+ if (name) {
-+ memcpy(name,cpy.name,len+1);
-+ }
-+ }
-+ CKYBuffer_InitFromCopy(&pubKey,&cpy.pubKey);
-+ CKYBuffer_InitFromCopy(&authId,&cpy.authId);
-+ CKYBuffer_InitFromCopy(&pinAuthId,&cpy.pinAuthId); }
-
-
- unsigned long getMuscleObjID() const { return muscleObjID; }
-@@ -100,6 +175,8 @@ class PKCS11Object {
-
- void setAttribute(CK_ATTRIBUTE_TYPE type, const CKYBuffer *value);
- void setAttribute(CK_ATTRIBUTE_TYPE type, const char *);
-+ void setAttribute(CK_ATTRIBUTE_TYPE type, const CKYByte *data,
-+ CKYSize size);
- /* bools and ulongs are too close, don't abuse function overloading
- * for these cases */
- void setAttributeBool(CK_ATTRIBUTE_TYPE type, CK_BBOOL);
-@@ -116,14 +193,22 @@ class PKCS11Object {
- const CKYBuffer *getPubKey(void) const {
- return &pubKey;
- }
-+
-+ KeyType getKeyType(void) const { return keyType;}
-+ unsigned int getKeySize(void) const { return keySize; }
-+ unsigned int getKeyRef(void) const { return keyRef; }
-+ CK_USER_TYPE getUser(void) const { return user; }
-+ void setKeyType(KeyType theType) { keyType = theType; }
-+ void setKeySize(unsigned int keySize_) { keySize = keySize_; }
-+ const CKYBuffer *getAuthId(void) const { return &authId; }
-+ const CKYBuffer *getPinAuthId(void) const { return &pinAuthId; }
-+ const PK15ObjectPath &getObjectPath() const { return objectPath; }
-+ void completeKey(const PKCS11Object &cert);
- };
-
- class Key : public PKCS11Object {
--
- public:
- Key(unsigned long muscleObjID, const CKYBuffer *data, CK_OBJECT_HANDLE handle);
-- void completeKey(const PKCS11Object &cert);
--
- };
-
- class Cert : public PKCS11Object {
-@@ -147,12 +232,124 @@ class CACCert : public PKCS11Object {
- CACCert(CKYByte instance, const CKYBuffer *derCert);
- };
-
-+typedef enum { PK15StateInit, PK15StateNeedObject,
-+ PK15StateNeedRawPublicKey,PK15StateNeedRawCertificate,
-+ PK15StateComplete } PK15State;
-+
-+typedef enum {PK15PvKey, PK15PuKey, PK15Cert, PK15AuthObj} PK15ObjectType;
-+const unsigned int PK15_INVALID_KEY_REF = -1;
-+
-+class PK15Object : public PKCS11Object {
-+ private:
-+ CKYByte instance;
-+ PK15ObjectType p15Type;
-+ PK15State state;
-+ P15PinInfo pinInfo;
-+
-+ CKYStatus completeCertObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeAuthObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeKeyObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completePrivKeyObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completePubKeyObject(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeRawPublicKey(const CKYByte *buf, CKYSize size);
-+ CKYStatus completeRawCertificate(const CKYByte *buf, CKYSize size);
-+
-+ CKYBitFlags defaultCommonBits() {
-+ return ((p15Type == PK15PvKey) && (CKYBuffer_Size(&authId) != 0)) ?
-+ P15FlagsPrivate : 0;
-+ }
-+ CKYBitFlags defaultUsageBits() {
-+ CKYBitFlags sign, recover, encrypt;
-+ switch (p15Type) {
-+ case PK15PuKey:
-+ sign = P15UsageVerify; recover = P15UsageVerifyRecover;
-+ encrypt = P15UsageEncrypt;
-+ break;
-+ case PK15PvKey:
-+ sign = P15UsageSign; recover = P15UsageSignRecover;
-+ encrypt = P15UsageDecrypt;
-+ break;
-+ default:
-+ sign = 0; recover = 0; encrypt = 0;
-+ break;
-+ }
-+ switch(keyType) {
-+ case rsa:
-+ return sign | recover | encrypt;
-+ case ecc:
-+ return sign | P15UsageDerive;
-+ default:
-+ break;
-+ }
-+ return 0;
-+ }
-+ CKYBitFlags defaultAccessBits() {
-+ switch (p15Type) {
-+ case PK15PuKey:
-+ return P15AccessExtractable | P15AccessLocal;
-+ case PK15PvKey:
-+ return P15AccessSensitive | P15AccessLocal;
-+ default:
-+ break;
-+ }
-+ return 0;
-+ }
-+ CKYBitFlags defaultPinBits() {
-+ return ((p15Type == PK15AuthObj) ? P15PinInitialized : 0);
-+ }
-+
-+ public:
-+ PK15Object(CKYByte inst, PK15ObjectType type,
-+ const CKYByte *derObject, CKYSize size);
-+ CKYStatus completeObject(const CKYByte *data, CKYSize size);
-+ PK15State getState(void) const { return state; }
-+ bool isSO(void) const { return
-+ (pinInfo.pinFlags & P15PinSOPin) ? true : false; }
-+ bool isLocal(void) const { return
-+ (pinInfo.pinFlags & P15PinLocal) ? true : false; }
-+ const P15PinInfo *getPinInfo(void) const { return &pinInfo; }
-+};
-+
- class Reader : public PKCS11Object {
- public:
- Reader(unsigned long muscleObjID, CK_OBJECT_HANDLE handle,
- const char *reader, const CKYBuffer *cardATR, bool isCoolkey);
- };
-
-+class SecretKey : public PKCS11Object {
-+ public:
-+ SecretKey(unsigned long muscleObjID, CK_OBJECT_HANDLE handle, CKYBuffer *secretKeyBuffer, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount);
-+ private:
-+ void adjustToKeyValueLength(CKYBuffer * secretKeyBuffer,CK_ULONG valueLength);
-+
-+};
-+
-+class DEREncodedSignature {
-+
-+ protected :
-+ CKYBuffer derEncodedSignature;
-+ public:
-+ DEREncodedSignature(const CKYBuffer *derSig);
-+ ~DEREncodedSignature();
-+ int getRawSignature(CKYBuffer *rawSig, unsigned int keySize);
-+
-+};
-+
-+class DEREncodedTokenInfo {
-+public:
-+ int version;
-+ CKYBuffer serialNumber;
-+ char *manufacturer;
-+ char *tokenName;
-+ public :
-+ DEREncodedTokenInfo(CKYBuffer *derTokenInfo);
-+ ~DEREncodedTokenInfo() {
-+ CKYBuffer_FreeData(&serialNumber);
-+ free(manufacturer);
-+ free(tokenName);
-+ }
-+};
-+
- class AttributeMatch {
-
- private:
-@@ -175,6 +372,9 @@ makeLEUInt(const CKYBuffer *buf, unsigne
- (b[offset+0] << 0) ;
- }
-
-+const CKYByte* dataStart(const CKYByte *buf, CKYSize length,
-+ CKYSize *data_length, bool includeTag);
-+
- // fixed object ID constants
- #define READER_ID 0x72300000 /* 'r0\0\0' */
- #define COMBINED_ID 0x7a300000 /* 'z0\0\0' */
-diff -up ./src/coolkey/pkcs11t.h.coolkey-update ./src/coolkey/pkcs11t.h
---- ./src/coolkey/pkcs11t.h.coolkey-update 2016-01-19 17:55:02.900107782 -0800
-+++ ./src/coolkey/pkcs11t.h 2016-01-19 17:55:16.040999709 -0800
-@@ -274,6 +274,7 @@ typedef CK_ULONG CK_USER_TYPE;
- #define CKU_SO 0
- /* Normal user */
- #define CKU_USER 1
-+#define CKU_CONTEXT_SPECIFIC 2
-
-
- /* CK_STATE enumerates the session states */
-@@ -492,6 +493,9 @@ typedef CK_ULONG CK_ATTRIBUTE_T
- #define CKA_RESET_ON_INIT 0x00000301
- #define CKA_HAS_RESET 0x00000302
-
-+/* new for v2.20 */
-+#define CKA_ALWAYS_AUTHENTICATE 0x00000202
-+
- #define CKA_VENDOR_DEFINED 0x80000000
-
-
-@@ -1351,4 +1355,41 @@ typedef struct CK_PKCS5_PBKD2_PARAMS {
-
- typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-
-+/* The following EC Key Derivation Functions are defined */
-+
-+#define CKD_NULL 0x00000001
-+
-+#define CKD_SHA1_KDF 0x00000002
-+
-+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11. */
-+
-+ typedef CK_ULONG CK_EC_KDF_TYPE;
-+
-+/*
-+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
-+ *
-+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
-+ *
-+ * where each party contributes one key pair.
-+ *
-+ */
-+
-+typedef struct CK_ECDH1_DERIVE_PARAMS {
-+
-+ CK_EC_KDF_TYPE kdf;
-+
-+ CK_ULONG ulSharedDataLen;
-+
-+ CK_BYTE_PTR pSharedData;
-+
-+ CK_ULONG ulPublicDataLen;
-+
-+ CK_BYTE_PTR pPublicData;
-+
-+} CK_ECDH1_DERIVE_PARAMS;
-+
-+
-+
-+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-+
- #endif
-diff -up ./src/coolkey/slot.cpp.coolkey-update ./src/coolkey/slot.cpp
---- ./src/coolkey/slot.cpp.coolkey-update 2016-01-19 17:55:37.409823970 -0800
-+++ ./src/coolkey/slot.cpp 2016-01-19 17:55:56.591666216 -0800
-@@ -54,6 +54,39 @@ const CKYByte ATR2[] =
- { 0x3B, 0x6F, 0x00, 0xFF, 0x52, 0x53, 0x41, 0x53, 0x65, 0x63, 0x75, 0x72,
- 0x49, 0x44, 0x28, 0x52, 0x29, 0x31, 0x30 };
-
-+/* PKCS #15 AID */
-+const CKYByte P15AID[] =
-+{ 0xa0, 0, 0, 0, 0x63, 'P', 'K', 'C', 'S', '-', '1', '5'};
-+
-+
-+
-+/* ECC curve information
-+ * Provide information for the limited set of curves supported by our smart card(s).
-+ *
-+ */
-+
-+typedef struct curveBytes2Name {
-+ const CKYByte * bytes;
-+ const char *curveName;
-+ unsigned int length;
-+
-+} CurveBytes2Name;
-+
-+/* First byte is length of oid byte array. */
-+
-+const CKYByte nistp256[] = { 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
-+const CKYByte nistp384[] = { 0x5, 0x2b, 0x81, 0x04, 0x00, 0x22 };
-+const CKYByte nistp521[] = { 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23 };
-+
-+const int numECCurves = 3;
-+
-+static CurveBytes2Name curveBytesNamePair[] =
-+{
-+ { nistp256, "nistp256", 256 },
-+ { nistp384, "nistp384", 384 },
-+ { nistp521, "nistp521", 521 }
-+};
-+
- SlotList::SlotList(Log *log_) : log(log_)
- {
- // initialize things to NULL so we can recover from an exception
-@@ -136,7 +169,11 @@ SlotList::updateSlotList()
- throw PKCS11Exception(CKR_HOST_MEMORY);
- memset(newSlots, 0, numReaders*sizeof(Slot*));
-
-- memcpy(newSlots, slots, sizeof(slots[0]) * numSlots);
-+ /* keep coverity happy, even though slot == NULL implies that
-+ * numSlots == 0 */
-+ if (slots) {
-+ memcpy(newSlots, slots, sizeof(slots[0]) * numSlots);
-+ }
-
- for (unsigned int i=numSlots; i < numReaders; i++) {
- newSlots[i] = new
-@@ -237,32 +274,19 @@ SlotList::updateReaderList()
-
- CKYStatus status = CKYCardContext_ListReaders(context, &readerNames);
- if ( status != CKYSUCCESS ) {
-- throw PKCS11Exception(CKR_GENERAL_ERROR,
-+ /* if the service is stopped, treat it as if we have no readers */
-+ if ((CKYCardContext_GetLastError(context) != SCARD_E_NO_SERVICE) &&
-+ (CKYCardContext_GetLastError(context) != SCARD_E_SERVICE_STOPPED)) {
-+ throw PKCS11Exception(CKR_GENERAL_ERROR,
- "Failed to list readers: 0x%x\n",
- CKYCardContext_GetLastError(context));
-+ }
- }
-
-- if (!readerStates) {
-+ if (readerStates == NULL && readerNames != NULL) {
- /* fresh Reader State list, just create it */
- readerStates = CKYReader_CreateArray(readerNames, (CKYSize *)&numReaders);
-
-- /* if we have no readers, make sure we have at least one to keep things
-- * happy */
-- if (readerStates == NULL &&
-- CKYReaderNameList_GetCount(readerNames) == 0) {
-- readerStates = (SCARD_READERSTATE *)
-- malloc(sizeof(SCARD_READERSTATE));
-- if (readerStates) {
-- CKYReader_Init(readerStates);
-- status = CKYReader_SetReaderName(readerStates, "E-Gate 0 0");
-- if (status != CKYSUCCESS) {
-- CKYReader_DestroyArray(readerStates, 1);
-- readerStates = NULL;
-- } else {
-- numReaders = 1;
-- }
-- }
-- }
- CKYReaderNameList_Destroy(readerNames);
-
- if (readerStates == NULL) {
-@@ -272,6 +296,16 @@ SlotList::updateReaderList()
- return;
- }
-
-+ if (readerStates == NULL) {
-+ /* if we didn't have any readers before and we did get new names,
-+ * that is handled above. If we didn't have any readers before, and
-+ * we didn't get any names, there is nothing to update. blow out now.
-+ * This more efficient and makes coverity happy (since coverity doesn't
-+ * know numReaders and readerStates are linked). */
-+ return;
-+ }
-+
-+
- /* it would be tempting at this point just to see if we have more readers
- * then specified previously. The problem with this is it is possible that
- * some readers have been deleted, so the only way to tell if we have
-@@ -286,18 +320,26 @@ SlotList::updateReaderList()
-
- const char *curReaderName = NULL;
- unsigned long knownState = 0;
-- for(int ri = 0 ; ri < numReaders; ri ++) {
-+ for(unsigned int ri = 0 ; ri < numReaders; ri ++) {
- knownState = CKYReader_GetKnownState(&readerStates[ri]);
--
-+
- curReaderName = CKYReader_GetReaderName(&readerStates[ri]);
-- if(readerNameExistsInList(curReaderName,&readerNames)) {
-- CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE);
-+ if(readerNames && readerNameExistsInList(curReaderName,&readerNames)) {
-+ CKYReader_SetKnownState(&readerStates[ri],
-+ knownState & ~SCARD_STATE_IGNORE);
- } else {
-- if (!(knownState & SCARD_STATE_UNAVAILABLE))
-- CKYReader_SetKnownState(&readerStates[ri], knownState | SCARD_STATE_UNAVAILABLE | SCARD_STATE_CHANGED);
-- }
-+ if (!(knownState & SCARD_STATE_UNAVAILABLE))
-+ CKYReader_SetKnownState(&readerStates[ri],
-+ knownState | SCARD_STATE_UNAVAILABLE | SCARD_STATE_CHANGED);
-+ }
- }
-
-+ if (readerNames == NULL) {
-+ /* OK we've marked everything unavailable, we clearly
-+ * aren't adding any readers, so we can blow out here */
-+ return;
-+ }
-+
- const char *newReadersData[MAX_READER_DELTA];
- const char **newReaders = &newReadersData[0];
- unsigned int newReaderCount = 0;
-@@ -368,18 +410,29 @@ SlotList::updateReaderList()
-
- Slot::Slot(const char *readerName_, Log *log_, CKYCardContext* context_)
- : log(log_), readerName(NULL), personName(NULL), manufacturer(NULL),
-+ tokenManufacturer(NULL),
- slotInfoFound(false), context(context_), conn(NULL), state(UNKNOWN),
- isVersion1Key(false), needLogin(false), fullTokenName(false),
-- mCoolkey(false), mOldCAC(false),
-+ mCoolkey(false), mOldCAC(false), mCACLocalLogin(false),
-+ pivContainer(-1), pivKey(-1), mECC(false), p15aid(0), p15odfAddr(0),
-+ p15tokenInfoAddr(0), p15Instance(0),
- #ifdef USE_SHMEM
- shmem(readerName_),
- #endif
- sessionHandleCounter(1), objectHandleCounter(1)
- {
-+ int i;
-+
-+ for (i=0; i < MAX_AUTH_USERS; i++) {
-+ auth[i]=NULL;
-+ }
-
- tokenFWVersion.major = 0;
- tokenFWVersion.minor = 0;
--
-+ CKYBuffer_InitFromData(&p15AID, P15AID, sizeof(P15AID));
-+ CKYBuffer_InitEmpty(&p15tokenInfo);
-+ CKYBuffer_InitEmpty(&p15odf);
-+ CKYBuffer_InitEmpty(&p15serialNumber);
-
- try {
- conn = CKYCardConnection_Create(context);
-@@ -395,6 +448,8 @@ Slot::Slot(const char *readerName_, Log
- loggedIn = false;
- pinCache.invalidate();
- pinCache.clearPin();
-+ contextPinCache.invalidate();
-+ contextPinCache.clearPin();
- //readSlotInfo();
- manufacturer = strdup("Unknown");
- if (!manufacturer) {
-@@ -477,12 +532,23 @@ Slot::~Slot()
- if (manufacturer) {
- free(manufacturer);
- }
-+ if (tokenManufacturer) {
-+ free(tokenManufacturer);
-+ }
- CKYBuffer_FreeData(&nonce);
- CKYBuffer_FreeData(&cardATR);
- CKYBuffer_FreeData(&mCUID);
-+ CKYBuffer_FreeData(&p15AID);
-+ CKYBuffer_FreeData(&p15odf);
-+ CKYBuffer_FreeData(&p15tokenInfo);
-+ CKYBuffer_FreeData(&p15serialNumber);
- for (int i=0; i < MAX_CERT_SLOTS; i++) {
- CKYBuffer_FreeData(&cardAID[i]);
- }
-+ for (int i=0; i < MAX_AUTH_USERS; i++) {
-+ if (auth[i]) delete auth[i];
-+ auth[i]=NULL;
-+ }
- }
-
- template <class C>
-@@ -573,6 +639,36 @@ SlotList::getSlotList(CK_BBOOL tokenPres
- return rv;
- }
-
-+bool
-+Slot::getPIVLoginType(void)
-+{
-+ CKYStatus status;
-+ CKYISOStatus apduRC;
-+ CKYBuffer buffer;
-+ bool local = true;
-+
-+ CKYBuffer_InitEmpty(&buffer);
-+
-+ /* get the discovery object */
-+ status = PIVApplet_GetCertificate(conn, &buffer, 0x7e, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ /* Discovery object optional, PIV defaults to local */
-+ goto done;
-+ }
-+ /* techically we probably should parse out the TLVs, but the PIV
-+ * specifies exactly what they should be, so we know exactly which
-+ * byte to look at */
-+ if ((CKYBuffer_Size(&buffer) >= 20) &&
-+ (CKYBuffer_GetChar(&buffer,17) == 0x60)) {
-+ /* This tells us we should use global login for this piv card */
-+ local = false;
-+ }
-+done:
-+ CKYBuffer_FreeData(&buffer);
-+ return local;
-+}
-+
-+
- void
- Slot::connectToToken()
- {
-@@ -587,6 +683,7 @@ Slot::connectToToken()
- if( ! CKYCardConnection_IsConnected(conn) ) {
- int i = 0;
- //for cranky readers try again a few more times
-+ status = CKYSCARDERR;
- while( i++ < 5 && status != CKYSUCCESS )
- {
- status = CKYCardConnection_Connect(conn, readerName);
-@@ -672,12 +769,40 @@ Slot::connectToToken()
- // see if the applet is selectable
-
- log->log("time connnect: Begin transaction %d ms\n", OSTimeNow() - time);
-+ status = PIVApplet_Select(conn, NULL);
-+ if (status == CKYSUCCESS) {
-+ /* CARD is a PIV card */
-+ state |= PIV_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
-+ isVersion1Key = 0;
-+ needLogin = true;
-+ mCoolkey = 0;
-+ mOldCAC = 0;
-+ mCACLocalLogin = getPIVLoginType();
-+ return;
-+ }
- status = CKYApplet_SelectCoolKeyManager(conn, NULL);
- if (status != CKYSUCCESS) {
- log->log("CoolKey Select failed 0x%x\n", status);
- status = getCACAid();
- if (status != CKYSUCCESS) {
-- goto loser;
-+ log->log("CAC Select failed 0x%x\n", status);
-+ status = getP15Params();
-+ if (status != CKYSUCCESS) {
-+ if (status == CKYSCARDERR) {
-+ log->log("Card Failure 0x%x\n",
-+ CKYCardConnection_GetLastError(conn));
-+ disconnect();
-+ }
-+ /* CARD is unknown */
-+ return;
-+ }
-+ /* enable PCKS 15 */
-+ state |= P15_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
-+ isVersion1Key = 0;
-+ needLogin = false; /* get it from token info */
-+ mCoolkey = 0;
-+ mCACLocalLogin = false;
-+ return;
- }
- state |= CAC_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
- /* skip the read of the cuid. We really don't need it and,
-@@ -685,17 +810,9 @@ Slot::connectToToken()
- * other apps may be running now, so resetting the cac is a bit
- * unfriendly */
- isVersion1Key = 0;
-- needLogin = 1;
-+ needLogin = true;
- mCoolkey = 0;
-- return;
--
--loser:
-- log->log("CAC Select failed 0x%x\n", status);
-- if (status == CKYSCARDERR) {
-- log->log("CAC Card Failure 0x%x\n",
-- CKYCardConnection_GetLastError(conn));
-- disconnect();
-- }
-+ mCACLocalLogin = false;
- return;
- }
- mCoolkey = 1;
-@@ -762,8 +879,10 @@ Slot::invalidateLogin(bool hard)
- }
- } else {
- loggedIn = false;
-+ pinCache.invalidate();
-+ contextPinCache.invalidate();
-+ contextPinCache.clearPin();
- if (hard) {
-- pinCache.invalidate();
- pinCache.clearPin();
- }
- }
-@@ -873,6 +992,414 @@ done:
- return status;
- }
-
-+CKYStatus Slot::getP15Params()
-+{
-+ CKYStatus status = CKYSCARDERR;
-+ int i;
-+ CKYISOStatus apduRC;
-+
-+ /* read the EF(DIR) */
-+ status = CACApplet_SelectFile(conn, 0x2f00, &apduRC);
-+ if (status == CKYSUCCESS) {
-+ CKYBuffer record;
-+
-+ CKYBuffer_InitEmpty(&record);
-+ /* dump it out */
-+ for (i=1; i < 255; i++) {
-+ status = P15Applet_ReadRecord(conn, i, 0, P15_READ_P1, 255,
-+ &record, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(DIR) Read Record %d failed 0x%x apduRC=0x%x\n",
-+ i, status, apduRC);
-+ break;
-+ }
-+ }
-+ CKYBuffer_FreeData(&record);
-+ return CKYSCARDERR; /* don't yet support EF(DIR)*/
-+
-+ } else {
-+ log->log("EF(DIR) Select failed 0x%x apduRC=0x%0x\n", status, apduRC);
-+ p15aid = 0; /* use the default */
-+ p15odfAddr=0x5031;
-+ p15tokenInfoAddr=0x5032;
-+ }
-+
-+ status = CKYApplet_SelectFile(conn, &p15AID, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("DF(PKCS-15) select failed 0x%x apduRC=0x%0x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+ status = P15Applet_SelectFile(conn, p15tokenInfoAddr, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(TokenInfo) select failed 0x%x apduRC=0x%0x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+ /* dump it out */
-+ CKYBuffer_Resize(&p15tokenInfo, 0);
-+ status = P15Applet_ReadBinary(conn, 0, 0, 0, 0, &p15tokenInfo, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(TokenInfo) Read binary failed 0x%x apduRC=0x%x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+ status = P15Applet_SelectFile(conn, p15odfAddr, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(ODF) select failed 0x%x apduRC=0x%0x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+
-+ CKYBuffer_Resize(&p15odf, 0);
-+ status = P15Applet_ReadBinary(conn, 0, 0, 0, 0, &p15odf, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ log->log("EF(ODF) Read binary failed 0x%x apduRC=0x%x\n", status,
-+ apduRC);
-+ return status;
-+ }
-+
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+Slot::readFromPath(const PK15ObjectPath &obj, CKYBuffer *file)
-+{
-+ CKYStatus status;
-+ CKYISOStatus apduRC;
-+ CKYSize bufSize;
-+ CKYOffset index = obj.getIndex();
-+ CKYSize length = obj.getLength();
-+
-+ CKYBuffer_Resize(file, 0);
-+ status = selectPath(obj.getPath(), &apduRC);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+ status = P15Applet_ReadBinary(conn, index, 0, 0,
-+ (length >= 256)?0:length, file, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+
-+ /* if we asked for a specific length and got it, or we asked for
-+ * an indeterminate length and got less than 256 bytes, then we
-+ * got everything. */
-+ bufSize = CKYBuffer_Size(file);
-+ if ((length && (bufSize >= length)) || ((length == 0) && (bufSize < 256))) {
-+ /* we've already got it all */
-+ return status;
-+ }
-+ if (bufSize < 0x82) {
-+ /* make sure we have enough bytes to handle the worst case ANS.1
-+ * mistake */
-+ return CKYINVALIDDATA;
-+ }
-+
-+ if (length == 0) {
-+ /* we don't yet know how long the length is, use the ASN.1 parser to
-+ * find out. We lie to dataStart about actual size so that it won't
-+ * fail since we know we don't have the whole buffer yet.*/
-+ (void) dataStart(CKYBuffer_Data(file), 65535, &length, true);
-+ }
-+ if (length > 65535) {
-+ return CKYINVALIDDATA;
-+ }
-+ while ((bufSize =CKYBuffer_Size(file)) < length) {
-+ CKYSize tmpLength = length - bufSize;
-+
-+ if (tmpLength >= 256) tmpLength = 0;
-+
-+ status = P15Applet_ReadBinary(conn, (unsigned short)(index+bufSize),
-+ 0, 0, tmpLength, file, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+ }
-+
-+ return CKYSUCCESS;
-+}
-+
-+void
-+Slot::parseEF_TokenInfo(void)
-+{
-+ DEREncodedTokenInfo derTokenInfo(&p15tokenInfo);
-+ const CKYBuffer *serial=&derTokenInfo.serialNumber;
-+
-+ if (derTokenInfo.version >= 0) {
-+ tokenFWVersion.major = derTokenInfo.version;
-+ tokenFWVersion.minor = 0;
-+ }
-+
-+ if (CKYSize(serial) != 0) {
-+ CKYBuffer_Replace(&p15serialNumber, 0, CKYBuffer_Data(serial),
-+ CKYBuffer_Size(serial));
-+ }
-+
-+ if (derTokenInfo.manufacturer) {
-+ if (tokenManufacturer) {
-+ free(tokenManufacturer);
-+ tokenManufacturer = NULL;
-+ }
-+ tokenManufacturer = derTokenInfo.manufacturer;
-+ derTokenInfo.manufacturer = NULL; /* adopted */
-+ }
-+
-+ if (derTokenInfo.tokenName) {
-+ if (personName) {
-+ free(personName);
-+ personName = NULL;
-+ }
-+ personName = derTokenInfo.tokenName;
-+ derTokenInfo.tokenName = NULL; /* adopted */
-+ fullTokenName = true;
-+ }
-+ return;
-+}
-+
-+void
-+Slot::parseEF_ODF(void)
-+{
-+ const CKYByte *current = CKYBuffer_Data(&p15odf);
-+ CKYSize size = CKYBuffer_Size(&p15odf);
-+ CKYBuffer files;
-+
-+ CKYBuffer_InitEmpty(&files);
-+
-+ while (size > 0) {
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+ CKYSize tagSize;
-+ CKYByte type, type1;
-+ PK15ObjectPath objPath;
-+ bool skip;
-+
-+ type = current[0];
-+ entry = dataStart(current, size, &entrySize, false);
-+ if (entry == NULL) { break; }
-+ tagSize = entry-current;
-+ current += entrySize + tagSize;
-+ size -= (entrySize + tagSize);
-+
-+ /* skip those entries we aren't going to parse */
-+ skip = false;
-+ switch (type) {
-+ case 0xa2: skip=true; break; /* skip EF(PuKDF-trusted) */
-+ case 0xa3: skip=true; break; /* skip EF(SKDF) */
-+ case 0xa7: skip=true; break; /* skip EF(DODF) */
-+ default: skip=true; break;
-+ case 0xa0: /* EF(PvKDF) */
-+ case 0xa1: /* EF(PuKDF) */
-+ case 0xa4: /* EF(CDF) */
-+ case 0xa5: /* EF(CDF-trusted) */
-+ case 0xa6: /* EF(CDF-useful) */
-+ case 0xa8: break; /* EF(AODF) */
-+ }
-+ if (skip) continue;
-+
-+ type1 = entry[0];
-+ /* unwrap */
-+ entry = dataStart(entry, entrySize, &entrySize, false);
-+ if (entry == NULL) continue;
-+ if (type1 == ASN1_SEQUENCE) {
-+ objPath.setObjectPath(entry, entrySize);
-+ CKYBuffer_Resize(&files, 0);
-+ readFromPath(objPath, &files);
-+ entry = CKYBuffer_Data(&files);
-+ entrySize = CKYBuffer_Size(&files);
-+ } else if (type1 != ASN1_CHOICE_0) {
-+ continue;
-+ }
-+
-+ switch (type) {
-+ case 0xa0: parseEF_Directory(entry, entrySize, PK15PvKey); break;
-+ case 0xa1: parseEF_Directory(entry, entrySize, PK15PuKey); break;
-+ case 0xa4: parseEF_Directory(entry, entrySize, PK15Cert); break;
-+ case 0xa5: parseEF_Directory(entry, entrySize, PK15Cert); break;
-+ case 0xa6: parseEF_Directory(entry, entrySize, PK15Cert); break;
-+ case 0xa8: parseEF_Directory(entry, entrySize, PK15AuthObj); break;
-+ default: break;
-+ }
-+ }
-+ CKYBuffer_FreeData(&files);
-+ return;
-+}
-+
-+
-+class ObjectCertCKAIDMatch {
-+ private:
-+ const CKYBuffer *cka_id;
-+ public:
-+ ObjectCertCKAIDMatch(const CKYBuffer *cka_id_) : cka_id(cka_id_) {}
-+ bool operator()(const PKCS11Object& obj) {
-+ const CKYBuffer *id;
-+ const CKYBuffer *objClass;
-+ CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
-+ objClass = obj.getAttribute(CKA_CLASS);
-+ if (objClass == NULL || !CKYBuffer_DataIsEqual(objClass,
-+ (CKYByte *)&certClass, sizeof(certClass))) {
-+ return false;
-+ }
-+ id = obj.getAttribute(CKA_ID);
-+ return (id != NULL && CKYBuffer_IsEqual(id,cka_id)) ? true : false;
-+ }
-+};
-+
-+class ObjectKeyCKAIDMatch {
-+ private:
-+ const CKYBuffer *cka_id;
-+ public:
-+ ObjectKeyCKAIDMatch(const CKYBuffer *cka_id_) : cka_id(cka_id_) {}
-+ bool operator()(const PKCS11Object& obj) {
-+ const CKYBuffer *id;
-+ const CKYBuffer *objClass;
-+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
-+ objClass = obj.getAttribute(CKA_CLASS);
-+ if (objClass == NULL || !CKYBuffer_DataIsEqual(objClass,
-+ (CKYByte *)&keyClass, sizeof(keyClass))) {
-+ return false;
-+ }
-+ id = obj.getAttribute(CKA_ID);
-+ return (id != NULL && CKYBuffer_IsEqual(id,cka_id)) ? true : false;
-+ }
-+};
-+
-+CKYStatus
-+Slot::parseEF_Directory(const CKYByte *current,
-+ CKYSize size, PK15ObjectType type)
-+{
-+ CKYBuffer file;
-+ CKYBuffer_InitEmpty(&file);
-+ CKYStatus status;
-+
-+
-+ while (size > 0) {
-+ const CKYByte *entry;
-+ CKYSize entrySize;
-+
-+ if (current[0] != ASN1_SEQUENCE) {
-+ /* no more */
-+ break;
-+ }
-+
-+ entry = dataStart(current, size, &entrySize, true);
-+ if (entry == NULL) { break; }
-+ current += entrySize;
-+ size -= entrySize;
-+
-+ do {
-+ PK15Object obj(PK15Instance(), type, entry, entrySize);
-+
-+ /* if state failed, then there is something wrong with this
-+ * der, skip this object */
-+ if (obj.getState() == PK15StateInit) {
-+ break;
-+ }
-+ status = CKYSUCCESS;
-+ while (obj.getState() != PK15StateComplete) {
-+ CKYBuffer_Resize(&file, 0);
-+ readFromPath(obj.getObjectPath(), &file);
-+ status = obj.completeObject(CKYBuffer_Data(&file),
-+ CKYBuffer_Size(&file));
-+ if (status != CKYSUCCESS) {
-+ break;
-+ }
-+ }
-+ if (status != CKYSUCCESS) {
-+ break;
-+ }
-+ assert(obj.getState() == PK15StateComplete);
-+ /* handle type specific per object fixups */
-+ switch (type) {
-+ case PK15AuthObj:
-+ /* if we're an auth object, squirrel us away for future use */
-+ if (obj.isSO()) {
-+ if (auth[CKU_SO] != 0) {
-+ auth[CKU_SO] = new PK15Object(obj);
-+ }
-+ } else if (auth[CKU_USER] == NULL) {
-+ auth[CKU_USER] = new PK15Object(obj);
-+ } else if (auth[CKU_CONTEXT_SPECIFIC] == NULL) {
-+ ObjectIter iter;
-+ const CKYBuffer *authid = obj.getPinAuthId();
-+
-+ /* these should put on the individual keys */
-+ auth[CKU_CONTEXT_SPECIFIC] = new PK15Object(obj);
-+
-+ for( iter = tokenObjects.begin();
-+ iter != tokenObjects.end(); ++iter) {
-+ if( CKYBuffer_IsEqual(iter->getAuthId(),authid)) {
-+ iter->setAttributeBool(CKA_ALWAYS_AUTHENTICATE,
-+ TRUE);
-+ }
-+ }
-+ }
-+ /* drop unkown */
-+ break;
-+ case PK15PvKey:
-+ /* does the cert already exist? */
-+ {
-+ ObjectConstIter iter;
-+ const CKYBuffer *id;
-+
-+ id = obj.getAttribute(CKA_ID);
-+ if ((!id) || (CKYBuffer_Size(id) != 1)) {
-+ break;
-+ }
-+ iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-+ ObjectCertCKAIDMatch(id));
-+
-+ if ( iter != tokenObjects.end() ) {
-+ obj.completeKey(*iter);
-+ }
-+ }
-+ break;
-+ case PK15Cert:
-+ /* does a corresponding key already exist? */
-+ {
-+ ObjectIter iter;
-+ const CKYBuffer *id;
-+
-+ id = obj.getAttribute(CKA_ID);
-+ if ((!id) || (CKYBuffer_Size(id) != 1)) {
-+ break;
-+ }
-+ iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-+ ObjectKeyCKAIDMatch(id));
-+
-+ if ( iter != tokenObjects.end() ) {
-+ iter->completeKey(obj);
-+ }
-+ }
-+ break;
-+ case PK15PuKey:
-+ break;
-+ }
-+ tokenObjects.push_back(obj);
-+ } while ( false );
-+ }
-+ CKYBuffer_FreeData(&file);
-+ return CKYSUCCESS;
-+}
-+
-+
-+CKYStatus
-+Slot::selectPath(const CKYBuffer *path, CKYISOStatus *apduRC)
-+{
-+ CKYSize size = CKYBuffer_Size(path);
-+ CKYStatus status = CKYINVALIDARGS;
-+ CKYOffset pos;
-+
-+ for (pos=0; pos < size; pos +=2) {
-+ unsigned short ef = CKYBuffer_GetShort(path, pos);
-+ status = P15Applet_SelectFile(conn, ef, apduRC);
-+ if (status != CKYSUCCESS) {
-+ break;
-+ }
-+ }
-+ return status;
-+}
-+
- void
- Slot::refreshTokenState()
- {
-@@ -1054,8 +1581,20 @@ void
- Slot::makeSerialString(char *serialNumber, int maxSize,
- const unsigned char *cuid)
- {
-+ CKYSize ssize = CKYBuffer_Size(&p15serialNumber);
- memset(serialNumber, ' ', maxSize);
-
-+ if (ssize != 0) {
-+ CKYSize i;
-+ ssize = MIN((CKYSize)maxSize/2, ssize);
-+ for (i=0; i < ssize; i++) {
-+ CKYByte c = CKYBuffer_GetChar(&p15serialNumber, i);
-+ serialNumber[2*i] = hex((c >> 4) & 0xf);
-+ serialNumber[2*i+1] = hex(c & 0xf);
-+ }
-+ }
-+
-+
- // otherwise we use the eepromSerialNumber as a hex value
- if (cuid) {
- makeCUIDString(serialNumber, maxSize, cuid);
-@@ -1126,7 +1665,8 @@ struct _manList {
- static const struct _manList manList[] = {
- { 0x4090, "Axalto" },
- { 0x2050, "Oberthur" },
-- { 0x4780, "RSA" }
-+ { 0x4780, "RSA" },
-+ { 0x534e, "SafeNet" }
- };
-
- static int manListSize = sizeof(manList)/sizeof(manList[0]);
-@@ -1135,8 +1675,15 @@ void
- Slot::makeManufacturerString(char *man, int maxSize, const unsigned char *cuid)
- {
- char *cp = man;
-+ int manLen;
- memset(man, ' ', maxSize);
-
-+ if (tokenManufacturer) {
-+ manLen = strlen(tokenManufacturer);
-+ memcpy(man, tokenManufacturer, MIN(manLen, maxSize));
-+ // UTF8 Truncate fixup! don't drop halfway through a UTF8 character
-+ return;
-+ }
- if (!cuid) {
- return;
- }
-@@ -1202,6 +1749,7 @@ Slot::getTokenInfo(CK_TOKEN_INFO_PTR pTo
-
-
- return CKR_OK;
-+
- }
-
- void
-@@ -1222,7 +1770,16 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- bool found = FALSE;
- CKYStatus status;
- SCARD_READERSTATE *myReaderStates = NULL;
-+ static SCARD_READERSTATE pnp = { 0 };
- unsigned int myNumReaders = 0;
-+
-+ readerListLock.getLock();
-+ if (pnp.szReader == 0) {
-+ CKYReader_Init(&pnp);
-+ pnp.szReader = "\\\\?PnP?\\Notification";
-+ }
-+ readerListLock.releaseLock();
-+
- #ifndef notdef
- do {
- readerListLock.getLock();
-@@ -1241,11 +1798,13 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- * from that set to return
- */
- for (i=0; i < numReaders; i++) {
-- unsigned long knownState = CKYReader_GetKnownState(&readerStates[i]);
-+ unsigned long knownState =
-+ CKYReader_GetKnownState(&readerStates[i]);
-
- if ((knownState & SCARD_STATE_UNAVAILABLE) &&
- (knownState & SCARD_STATE_CHANGED)) {
-- CKYReader_SetKnownState(&readerStates[i], knownState & ~SCARD_STATE_CHANGED);
-+ CKYReader_SetKnownState(&readerStates[i],
-+ knownState & ~SCARD_STATE_CHANGED);
- readerListLock.releaseLock();
- *slotp = slotIndexToID(i);
- found = TRUE;
-@@ -1262,31 +1821,48 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- break;
- }
-
-- if (myNumReaders != numReaders) {
-+ if (myNumReaders != numReaders + 1) {
- if (myReaderStates) {
- delete [] myReaderStates;
- }
-- myReaderStates = new SCARD_READERSTATE [numReaders];
-+ myReaderStates = new SCARD_READERSTATE [numReaders + 1];
-+ myNumReaders = numReaders + 1;
- }
-- memcpy(myReaderStates, readerStates,
-- sizeof(SCARD_READERSTATE)*numReaders);
-- myNumReaders = numReaders;
-+
-+ memcpy(myReaderStates, readerStates,
-+ sizeof(SCARD_READERSTATE) * numReaders);
-+ memcpy(&myReaderStates[numReaders], &pnp, sizeof(pnp));
- readerListLock.releaseLock();
- status = CKYCardContext_WaitForStatusChange(context,
-- myReaderStates, myNumReaders, timeout);
-+ myReaderStates, myNumReaders, timeout);
- if (status == CKYSUCCESS) {
-- for (i=0; i < myNumReaders; i++) {
-- SCARD_READERSTATE *rsp = &myReaderStates[i];
-- unsigned long eventState = CKYReader_GetEventState(rsp);
-+ unsigned long eventState;
-+ for (i=0; i < myNumReaders - 1; i++) {
-+ eventState = CKYReader_GetEventState(&myReaderStates[i]);
- if (eventState & SCARD_STATE_CHANGED) {
- readerListLock.getLock();
-- CKYReader_SetKnownState(&readerStates[i], eventState & ~SCARD_STATE_CHANGED);
-+ CKYReader_SetKnownState(&readerStates[i],
-+ eventState & ~SCARD_STATE_CHANGED);
- readerListLock.releaseLock();
- *slotp = slotIndexToID(i);
- found = TRUE;
- break;
- }
- }
-+ /* No real need to check for an additional card, we already update
-+ * the list when we iterate. */
-+ if (!found) {
-+ eventState = CKYReader_GetEventState(
-+ &myReaderStates[myNumReaders-1]);
-+ if (eventState & SCARD_STATE_CHANGED) {
-+ readerListLock.getLock();
-+ CKYReader_SetKnownState(&pnp,
-+ eventState & ~SCARD_STATE_CHANGED);
-+ readerListLock.releaseLock();
-+ log->log("Reader insertion/removal detected\n");
-+ continue; /* get the update */
-+ }
-+ }
- }
-
- if (found || (flag == CKF_DONT_BLOCK) || shuttingDown) {
-@@ -1294,21 +1870,21 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
- }
-
- #ifndef WIN32
-- if (status != CKYSUCCESS) {
--
-- if ( (CKYCardContext_GetLastError(context) ==
-- SCARD_E_READER_UNAVAILABLE) ||
-- (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT))
-- {
-- OSSleep(timeout*PKCS11_CARD_ERROR_LATENCY);
-- }
--
--
-- }
-+ /* pcsc-lite needs to make progress or something */
-+ if (status != CKYSUCCESS) {
-+ if ((CKYCardContext_GetLastError(context) ==
-+ SCARD_E_READER_UNAVAILABLE) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT)) {
-+ OSSleep(timeout*PKCS11_CARD_ERROR_LATENCY);
-+ }
-+ }
- #endif
- } while ((status == CKYSUCCESS) ||
- (CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT) ||
-- ( CKYCardContext_GetLastError(context) == SCARD_E_READER_UNAVAILABLE));
-+ (CKYCardContext_GetLastError(context) == SCARD_E_UNKNOWN_READER) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_READER_UNAVAILABLE) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_NO_SERVICE) ||
-+ (CKYCardContext_GetLastError(context) == SCARD_E_SERVICE_STOPPED) );
- #else
- do {
- OSSleep(100);
-@@ -1345,6 +1921,7 @@ Slot::handleConnectionError()
- case SCARD_W_REMOVED_CARD:
- ckrv = CKR_DEVICE_REMOVED;
- break;
-+
- default:
- ckrv = CKR_DEVICE_ERROR;
- break;
-@@ -1404,13 +1981,46 @@ Slot::selectApplet()
- }
-
- void
--Slot::selectCACApplet(CKYByte instance)
-+Slot::selectCACApplet(CKYByte instance, bool doDisconnect)
- {
- CKYStatus status;
-+ /* PIV containers and keys by instance */
-+ static const int container[] = {
-+ 0x5fc105, 0x5fc10a, 0x5fc10b, 0x5fc101,
-+ 0x5fc10d, 0x5fc10e, 0x5fc10f, 0x5fc110,
-+ 0x5fc111, 0x5fc112, 0x5fc113, 0x5fc114,
-+ 0x5fc115, 0x5fc116, 0x5fc117, 0x5fc118,
-+ 0x5fc119, 0x5fc11a, 0x5fc11b, 0x5fc11c,
-+ 0x5fc11d, 0x5fc11e, 0x5fc11f, 0x5fc120
-+ };
-+ static const int keyRef[] = {
-+ 0x9a, 0x9c, 0x9d, 0x9e,
-+ 0x82, 0x83, 0x84, 0x85,
-+ 0x86, 0x87, 0x88, 0x89,
-+ 0x8a, 0x8b, 0x8c, 0x8d,
-+ 0x8e, 0x8f, 0x90, 0x91,
-+ 0x92, 0x93, 0x94, 0x95
-+ };
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_Select(conn, NULL);
-+ if (status == CKYSCARDERR) handleConnectionError();
-+ if (status != CKYSUCCESS) {
-+ if (doDisconnect) {
-+ disconnect();
-+ }
-+ throw PKCS11Exception(CKR_DEVICE_REMOVED);
-+ }
-+ pivContainer = container[instance];
-+ pivKey = keyRef[instance];
-+ return;
-+ }
- CKYBuffer *aid = &cardAID[instance];
-
- if (CKYBuffer_Size(aid) == 0) {
-- disconnect();
-+ if (doDisconnect) {
-+ disconnect();
-+ }
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- return;
- }
-@@ -1419,7 +2029,9 @@ Slot::selectCACApplet(CKYByte instance)
- if ( status == CKYSCARDERR ) handleConnectionError();
- if ( status != CKYSUCCESS) {
- // could not select applet: this just means it's not there
-- disconnect();
-+ if (doDisconnect) {
-+ disconnect();
-+ }
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- }
- if (mOldCAC) {
-@@ -1428,7 +2040,9 @@ Slot::selectCACApplet(CKYByte instance)
- status = CACApplet_SelectFile(conn, cardEF[instance], NULL);
- if ( status == CKYSCARDERR ) handleConnectionError();
- if ( status != CKYSUCCESS) {
-- disconnect();
-+ if (doDisconnect) {
-+ disconnect();
-+ }
- throw PKCS11Exception(CKR_DEVICE_REMOVED);
- }
- }
-@@ -1488,26 +2102,6 @@ class KeyNumMatch {
- }
- };
-
--class ObjectCertCKAIDMatch {
-- private:
-- CKYByte cka_id;
-- public:
-- ObjectCertCKAIDMatch(CKYByte cka_id_) : cka_id(cka_id_) {}
-- bool operator()(const PKCS11Object& obj) {
-- const CKYBuffer *id;
-- const CKYBuffer *objClass;
-- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
-- objClass = obj.getAttribute(CKA_CLASS);
-- if (objClass == NULL || !CKYBuffer_DataIsEqual(objClass,
-- (CKYByte *)&certClass, sizeof(certClass))) {
-- return false;
-- }
-- id = obj.getAttribute(CKA_ID);
-- return (id != NULL && CKYBuffer_DataIsEqual(id,&cka_id, 1))
-- ? true : false;
-- }
--};
--
- CK_OBJECT_HANDLE
- Slot::generateUnusedObjectHandle()
- {
-@@ -1521,6 +2115,29 @@ Slot::generateUnusedObjectHandle()
- return handle;
- }
-
-+/* Create a short lived Secret Key for ECC key derive. */
-+PKCS11Object *
-+Slot::createSecretKeyObject(CK_OBJECT_HANDLE handle, CKYBuffer *secretKeyBuffer, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
-+{
-+
-+ if (secretKeyBuffer == NULL ) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Can't create secret key object for ECC.");
-+ }
-+
-+ unsigned long muscleID = 0xfff;
-+ PKCS11Object *secret = new SecretKey(muscleID, handle, secretKeyBuffer, pTemplate, ulAttributeCount);
-+
-+ if (secret == NULL) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Can't create secret key object for ECC.");
-+ }
-+
-+ tokenObjects.push_back(*secret);
-+
-+ return secret;
-+}
-+
- void
- Slot::addKeyObject(list<PKCS11Object>& objectList, const ListObjectInfo& info,
- CK_OBJECT_HANDLE handle, bool isCombined)
-@@ -1530,24 +2147,32 @@ Slot::addKeyObject(list<PKCS11Object>& o
- CK_OBJECT_CLASS objClass = keyObj.getClass();
- const CKYBuffer *id;
-
--
- if (isCombined &&
-- ((objClass == CKO_PUBLIC_KEY) || (objClass == CKO_PRIVATE_KEY))) {
-- id = keyObj.getAttribute(CKA_ID);
-- if ((!id) || (CKYBuffer_Size(id) != 1)) {
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Missing or invalid CKA_ID value");
-- }
-- iter = find_if(objectList.begin(), objectList.end(),
-- ObjectCertCKAIDMatch(CKYBuffer_GetChar(id,0)));
-- if ( iter == objectList.end() ) {
-+ ((objClass == CKO_PUBLIC_KEY) || (objClass == CKO_PRIVATE_KEY))) {
-+ id = keyObj.getAttribute(CKA_ID);
-+ if ((!id) || (CKYBuffer_Size(id) != 1)) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Missing or invalid CKA_ID value");
-+ }
-+ iter = find_if(objectList.begin(), objectList.end(),
-+ ObjectCertCKAIDMatch(id));
-+ if ( iter == objectList.end() ) {
- // We failed to find a cert with a matching CKA_ID. This
- // can happen if the cert is not present on the token, or
- // the der encoded cert stored on the token was corrupted.
-- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Failed to find cert with matching CKA_ID value");
-- }
-- keyObj.completeKey(*iter);
-+ throw PKCS11Exception(CKR_DEVICE_ERROR,
-+ "Failed to find cert with matching CKA_ID value");
-+ }
-+ keyObj.completeKey(*iter);
-+
-+ /* For now this is how we determine what type of key.
-+ Also for now, allow only one or the other */
-+ if ( keyObj.getKeyType() == PKCS11Object::ecc) {
-+ mECC = true;
-+ } else {
-+ mECC = false;
-+ }
-+
- }
- objectList.push_back(keyObj);
-
-@@ -1577,10 +2202,16 @@ Slot::addCertObject(list<PKCS11Object>&
- void
- Slot::unloadObjects()
- {
-+ mECC = false;
- tokenObjects.clear();
- free(personName);
- personName = NULL;
- fullTokenName = false;
-+ if (tokenManufacturer) {
-+ free(tokenManufacturer);
-+ tokenManufacturer = NULL;
-+ }
-+ CKYBuffer_Resize(&p15serialNumber,0);
- }
-
- #ifdef USE_SHMEM
-@@ -1970,7 +2601,7 @@ Slot::readCUID(void)
- // shared memory is protected by our transaction call on the card
- //
- CKYStatus status;
-- if (state & CAC_CARD) {
-+ if (state & GOV_CARD) {
- status = CACApplet_SelectCardManager(conn, NULL);
- } else {
- status = CKYApplet_SelectCardManager(conn, NULL);
-@@ -2203,6 +2834,50 @@ Slot::fetchCombinedObjects(const CKYBuff
- return objInfoList;
- }
-
-+typedef enum {
-+ BER_UNWRAP,
-+ BER_NEXT
-+} BERop;
-+
-+static CKYStatus
-+berProcess(CKYBuffer *buf, int matchTag, CKYBuffer *target, BERop type)
-+{
-+ unsigned char tag;
-+ unsigned int used_length= 0;
-+ unsigned int data_length;
-+
-+ tag = CKYBuffer_GetChar(buf,used_length++);
-+
-+ /* blow out when we come to the end */
-+ if (matchTag && tag != matchTag) {
-+ return CKYLIBFAIL;
-+ }
-+
-+ data_length = CKYBuffer_GetChar(buf,used_length++);
-+
-+ if (data_length & 0x80) {
-+ int len_count = data_length & 0x7f;
-+
-+ data_length = 0;
-+
-+ while (len_count-- > 0) {
-+ data_length = (data_length << 8) |
-+ CKYBuffer_GetChar(buf,used_length++);
-+ }
-+ }
-+
-+ if (data_length > (CKYBuffer_Size(buf)-used_length) ) {
-+ return CKYLIBFAIL;
-+ }
-+
-+ if (type == BER_UNWRAP) {
-+ return CKYBuffer_AppendBuffer(target, buf, used_length, data_length);
-+ }
-+ return CKYBuffer_AppendBuffer(target, buf, used_length+data_length,
-+ CKYBuffer_Size(buf)-(used_length+data_length));
-+}
-+
-+
- CKYStatus
- Slot::readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
- bool throwException)
-@@ -2211,16 +2886,60 @@ Slot::readCACCertificateFirst(CKYBuffer
- CKYISOStatus apduRC;
- *nextSize = 0;
-
-+ if (state & PIV_CARD) {
-+ CKYBuffer pivData;
-+ CKYBuffer certInfo;
-+
-+ CKYBuffer_InitEmpty(&pivData);
-+ CKYBuffer_InitEmpty(&certInfo);
-+ CKYBuffer_Resize(cert, 0);
-+ status = PIVApplet_GetCertificate(conn, cert, pivContainer, &apduRC);
-+ if (throwException && (status != CKYSUCCESS)) {
-+ handleConnectionError();
-+ }
-+ /* actually, on success, we need to parse the certificate and find the
-+ * propper tag */
-+ if (status == CKYSUCCESS) {
-+ status = berProcess(cert, 0x53, &pivData, BER_UNWRAP);
-+ CKYBuffer_Resize(cert, 0);
-+ CKYBuffer_AppendChar(cert,0);
-+ do {
-+ CKYByte tag = CKYBuffer_GetChar(&pivData,0);
-+ if (tag == CAC_TAG_CERTIFICATE) {
-+ status = berProcess(&pivData, CAC_TAG_CERTIFICATE,
-+ cert, BER_UNWRAP);
-+ }
-+ if (tag == CAC_TAG_CERTINFO) {
-+ CKYBuffer_Resize(&certInfo, 0);
-+ status = berProcess(&pivData, CAC_TAG_CERTINFO,
-+ &certInfo, BER_UNWRAP);
-+ if (CKYBuffer_Size(&certInfo) == 1) {
-+ CKYBuffer_SetChar(cert,0,
-+ CKYBuffer_GetChar(&certInfo,0));
-+ }
-+ }
-+ if (status == CKYSUCCESS) {
-+ CKYBuffer_Resize(&certInfo, 0);
-+ status = berProcess(&pivData, 0, &certInfo, BER_NEXT);
-+ if (status == CKYSUCCESS) {
-+ CKYBuffer_Resize(&pivData,0);
-+ status = CKYBuffer_AppendCopy(&pivData,&certInfo);
-+ }
-+ }
-+ } while ((status == CKYSUCCESS) && (CKYBuffer_Size(&pivData) != 0));
-+ CKYBuffer_FreeData(&pivData);
-+ CKYBuffer_FreeData(&certInfo);
-+ }
-+
-+ return status;
-+ }
-+
- if (mOldCAC) {
- /* get the first 100 bytes of the cert */
- status = CACApplet_GetCertificateFirst(conn, cert, nextSize, &apduRC);
- if (throwException && (status != CKYSUCCESS)) {
- handleConnectionError();
- }
--
-- if(CKYBuffer_Size(cert) == 0) {
-- handleConnectionError();
-- }
- return status;
- }
-
-@@ -2233,6 +2952,7 @@ Slot::readCACCertificateFirst(CKYBuffer
- CKYBuffer_InitEmpty(&tBuf);
- CKYBuffer_InitEmpty(&vBuf);
- CKYBuffer_Resize(cert, 0);
-+ CKYBuffer_AppendChar(cert,0);
-
- /* handle the new CAC card read */
- /* read the TLV */
-@@ -2258,11 +2978,12 @@ Slot::readCACCertificateFirst(CKYBuffer
- length = CKYBuffer_GetShortLE(&tBuf, toffset);
- toffset +=2;
- }
-- if (tag != CAC_TAG_CERTIFICATE) {
-- continue;
-+ if (tag == CAC_TAG_CERTIFICATE) {
-+ CKYBuffer_AppendBuffer(cert, &vBuf, voffset, length);
-+ }
-+ if (tag == CAC_TAG_CERTINFO) {
-+ CKYBuffer_SetChar(cert,0,CKYBuffer_GetChar(&vBuf,voffset));
- }
-- CKYBuffer_AppendBuffer(cert, &vBuf, voffset, length);
-- break;
- }
- status = CKYSUCCESS;
-
-@@ -2272,6 +2993,191 @@ done:
- return status;
- }
-
-+
-+const static unsigned long crc_table[] = {
-+0x00000000,0x77073096,0xee0e612c,0x990951ba,
-+0x076dc419,0x706af48f,0xe963a535,0x9e6495a3,
-+0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,
-+0x09b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91,
-+0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,
-+0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7,
-+0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,
-+0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5,
-+0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172,
-+0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b,
-+0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940,
-+0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59,
-+0x26d930ac,0x51de003a,0xc8d75180,0xbfd06116,
-+0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f,
-+0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,
-+0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d,
-+0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,
-+0x71b18589,0x06b6b51f,0x9fbfe4a5,0xe8b8d433,
-+0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,
-+0x7f6a0dbb,0x086d3d2d,0x91646c97,0xe6635c01,
-+0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,
-+0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457,
-+0x65b0d9c6,0x12b7e950,0x8bbeb8ea,0xfcb9887c,
-+0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65,
-+0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2,
-+0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb,
-+0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0,
-+0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9,
-+0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,
-+0x5768b525,0x206f85b3,0xb966d409,0xce61e49f,
-+0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,
-+0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad,
-+0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,
-+0xead54739,0x9dd277af,0x04db2615,0x73dc1683,
-+0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8,
-+0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1,
-+0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe,
-+0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7,
-+0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc,
-+0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5,
-+0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252,
-+0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b,
-+0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,
-+0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79,
-+0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,
-+0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f,
-+0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,
-+0xc2d7ffa7,0xb5d0cf31,0x2cd99e8b,0x5bdeae1d,
-+0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a,
-+0x9c0906a9,0xeb0e363f,0x72076785,0x05005713,
-+0x95bf4a82,0xe2b87a14,0x7bb12bae,0x0cb61b38,
-+0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21,
-+0x86d3d2d4,0xf1d4e242,0x68ddb3f8,0x1fda836e,
-+0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777,
-+0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c,
-+0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45,
-+0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,
-+0xa7672661,0xd06016f7,0x4969474d,0x3e6e77db,
-+0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,
-+0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9,
-+0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,
-+0xbad03605,0xcdd70693,0x54de5729,0x23d967bf,
-+0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94,
-+0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d
-+};
-+
-+static unsigned long
-+calc_crc32(const unsigned char *buf, int len)
-+{
-+ unsigned long crc = 0xffffffff;
-+ int i;
-+
-+ for (i=0; i < len; i++) {
-+ unsigned char crc_low = crc & 0xff;
-+ unsigned long crc_high = crc >> 8;
-+ crc = crc_table[crc_low ^ buf[i]] ^ crc_high;
-+ }
-+ return crc ^ 0xffffffff;
-+}
-+
-+/*
-+ * decompress, handles both gzip and zlib trailers
-+ * it also automatically allocates the output buffer and expands it as
-+ * necessary.
-+ */
-+static int
-+decompress(CKYBuffer *out,
-+ CKYBuffer *in, CKYOffset offset, CKYSize len)
-+{
-+ int zret;
-+ CKYStatus status;
-+ z_stream stream;
-+ int chunk = len *2;
-+ int outlen = 0;
-+
-+
-+ /* allocate inflate state */
-+ stream.zalloc = Z_NULL;
-+ stream.zfree = Z_NULL;
-+ stream.opaque = Z_NULL;
-+ stream.avail_in = 0;
-+ stream.next_in = Z_NULL;
-+ zret = inflateInit(&stream);
-+ if (zret != Z_OK)
-+ return zret;
-+
-+ status = CKYBuffer_Reserve(out, outlen);
-+ if (status != CKYSUCCESS) {
-+ return Z_MEM_ERROR;
-+ }
-+
-+ stream.avail_in = len;
-+ stream.next_in = (Bytef *)(CKYBuffer_Data(in) + offset);
-+
-+ do {
-+ CKYBuffer_Resize(out, outlen + chunk);
-+ stream.avail_out = chunk;
-+
-+ stream.next_out = (Bytef *)CKYBuffer_Data(out)+ outlen;
-+
-+ zret= inflate(&stream, Z_NO_FLUSH);
-+
-+ /* we need the length early so it can be used in error processing */
-+ outlen += chunk - stream.avail_out;
-+
-+ /* proccess the error codes */
-+ switch (zret) {
-+ case Z_DATA_ERROR:
-+ /* a DATA error can occur on either corrupted data, or on gzip.
-+ * data. This is because gzip uses CRC32 and zlib used ADLER32
-+ * checksums. We need to check to see if this failure is do to
-+ * a gzip header. */
-+ /* 1) a gzip header includes 4 extra bytes containing the length
-+ * of the gziped data. This means there must be 4 more bytes
-+ * in our input buffer that have not been processed */
-+ if (stream.avail_in != 4) {
-+ break; /* not a gzip header */
-+ }
-+ /* The last 4 bytes of a gzip header include the uncompressed length
-+ * modulo 2^32. Make sure the actual uncompressed length matches
-+ * the header. */
-+ if ((outlen & 0xffffffffL)
-+ != CKYBuffer_GetLongLE(in, offset+len-4)) {
-+ break; /* didn't decode the full length */
-+ }
-+ /* At this point it''s pretty likely we have a gzip trailer. Verify
-+ * the crc32 values to make sure there hasn't been any corruption.
-+ */
-+ if (calc_crc32(CKYBuffer_Data(out), outlen) !=
-+ CKYBuffer_GetLongLE(in,offset+len-8)) {
-+ break; /* CRC didn't match */
-+ }
-+ /* This was valid gzip data, and we've successfully uncompressed
-+ * it. We're now done. */
-+ zret=Z_STREAM_END;
-+ break;
-+ case Z_NEED_DICT:
-+ /* if we need the dict, it wasn't in the data,
-+ * so it's a data error */
-+ zret = Z_DATA_ERROR;
-+ break;
-+ case Z_OK:
-+ /* Z_OK means we need more data, expand the buffer and go again.
-+ * if we don't need more buffer space, then the input must have
-+ * been truncated, that's a data error */
-+ if (stream.avail_out != 0) {
-+ zret = Z_DATA_ERROR;
-+ }
-+ break;
-+ }
-+ } while (zret == Z_OK);
-+
-+ /* cleanup */
-+ if (zret == Z_STREAM_END) {
-+ zret = Z_OK;
-+ CKYBuffer_Resize(out, outlen);
-+ } else {
-+ CKYBuffer_Resize(out, 0);
-+ }
-+ (void)inflateEnd(&stream);
-+ return zret;
-+}
-+
- /*
- * only necessary for old CAC cards. New CAC cards have to read the
- * whole cert in anyway above....
-@@ -2304,7 +3210,7 @@ Slot::loadCACCert(CKYByte instance)
- // catch the applet selection errors if they don't
- //
- try {
-- selectCACApplet(instance);
-+ selectCACApplet(instance, false);
- } catch(PKCS11Exception& e) {
- // all CAC's must have instance '0', throw the error it
- // they don't.
-@@ -2322,6 +3228,10 @@ Slot::loadCACCert(CKYByte instance)
-
- if (instance == 0) {
- readCACCertificateFirst(&rawCert, &nextSize, true);
-+
-+ if(CKYBuffer_Size(&rawCert) <= 1) {
-+ handleConnectionError();
-+ }
- log->log("CAC Cert %d: fetch CAC Cert: %d ms\n",
- instance, OSTimeNow() - time);
- }
-@@ -2364,7 +3274,7 @@ Slot::loadCACCert(CKYByte instance)
- } else {
- status = readCACCertificateFirst(&rawCert, &nextSize, false);
-
-- if (status != CKYSUCCESS) {
-+ if ((status != CKYSUCCESS) || (CKYBuffer_Size(&rawCert) <= 1)) {
- /* CAC only requires the Certificate in pki '0' */
- /* if pki '1' or '2' are empty, treat it as a non-fatal error*/
- if (instance == 2) {
-@@ -2393,31 +3303,61 @@ Slot::loadCACCert(CKYByte instance)
-
- log->log("CAC Cert %d: Cert has been read: %d ms\n",
- instance, OSTimeNow() - time);
-- if (!mOldCAC || CKYBuffer_GetChar(&rawCert,0) == 1) {
-- CKYSize guessFinalSize = CKYBuffer_Size(&rawCert);
-- CKYSize certSize = 0;
-- CKYOffset offset = mOldCAC ? 1 : 0;
-+ /* new CACs, and old CACs with the high one bit are compressed,
-+ * uncompress them */
-+ if ((CKYBuffer_GetChar(&rawCert,0) & 0x3) == 1) {
-+ CKYOffset offset = 1;
- int zret = Z_MEM_ERROR;
-
-- do {
-- guessFinalSize *= 2;
-- status = CKYBuffer_Resize(&cert, guessFinalSize);
-- if (status != CKYSUCCESS) {
-- break;
-+ /* process the GZIP header if present */
-+ /* header_id = 0x1f, 0x8b. CM=8. If we ever support something other
-+ * than CM=8, we need to change the zlib header below. Currently both
-+ * gzip and zlib only support CM=8 (DEFLATE) compression */
-+ if ((CKYBuffer_GetChar(&rawCert,1) == 0x1f) &&
-+ (CKYBuffer_GetChar(&rawCert,2) == 0x8b) &&
-+ (CKYBuffer_GetChar(&rawCert,3) == 8)) {
-+ CKYByte flags = CKYBuffer_GetChar(&rawCert,4);
-+ /* this has a gzip header, not raw data. */
-+ offset += 10; /* base size of the gzip header */
-+ if (flags & 4) { /* FEXTRA */
-+ CKYSize len = CKYBuffer_GetShortLE(&rawCert,offset);
-+ offset += len;
-+ }
-+ if (flags & 8) { /* FNAME */
-+ while (CKYBuffer_GetChar(&rawCert,offset) != 0) {
-+ offset++;
-+ }
-+ offset++;
-+ }
-+ if (flags & 0x10) { /* FComment */
-+ while (CKYBuffer_GetChar(&rawCert,offset) != 0) {
-+ offset++;
-+ }
-+ offset++;
-+ }
-+ if (flags & 2) { /* FHCRC */
-+ offset += 2;
- }
-- certSize = guessFinalSize;
-- zret = uncompress((Bytef *)CKYBuffer_Data(&cert),&certSize,
-- CKYBuffer_Data(&rawCert)+offset,
-- CKYBuffer_Size(&rawCert)-offset);
-- } while (zret == Z_BUF_ERROR);
-+ offset -= 2;
-+
-+ /* add zlib header, so libz will be happy */
-+ /* CINFO=7, CM=8, LEVEL=2, DICTFLAG=0, FCHECK= 1c */
-+ /* NOTE: the zlib will fail when procssing the trailer. this is
-+ * ok because decompress automatically notices the failure and
-+ * and checks the gzip trailer. */
-+ CKYBuffer_SetChar(&rawCert, offset, 0x78);
-+ CKYBuffer_SetChar(&rawCert, offset+1, 0x9c);
-+ }
-+ /* uncompress. This expands cert as necessary. */
-+ zret = decompress(&cert, &rawCert, offset,
-+ CKYBuffer_Size(&rawCert)-offset);
-
- if (zret != Z_OK) {
- CKYBuffer_FreeData(&rawCert);
- CKYBuffer_FreeData(&cert);
- throw PKCS11Exception(CKR_DEVICE_ERROR,
-- "Corrupted compressed CAC Cert");
-+ "Corrupted compressed CAC/PIV Cert");
- }
-- CKYBuffer_Resize(&cert,certSize);
- } else {
- CKYBuffer_InitFromBuffer(&cert,&rawCert,1,CKYBuffer_Size(&rawCert)-1);
- }
-@@ -2431,6 +3371,9 @@ Slot::loadCACCert(CKYByte instance)
- tokenObjects.push_back(privKey);
- tokenObjects.push_back(pubKey);
- tokenObjects.push_back(certObj);
-+ if ( pubKey.getKeyType() == PKCS11Object::ecc) {
-+ mECC = 1;
-+ }
-
- if (personName == NULL) {
- const char *name = certObj.getName();
-@@ -2459,7 +3402,7 @@ Slot::loadObjects()
- list<ListObjectInfo> objInfoList;
- std::list<ListObjectInfo>::iterator iter;
-
-- if (state & CAC_CARD) {
-+ if (state & GOV_CARD) {
- loadCACCert(0);
- loadCACCert(1);
- loadCACCert(2);
-@@ -2467,6 +3410,17 @@ Slot::loadObjects()
- loadReaderObject();
- return;
- }
-+ if (state & P15_CARD) {
-+ parseEF_TokenInfo();
-+ parseEF_ODF();
-+ if (auth[CKU_USER] != NULL) {
-+ /* set need login */
-+ needLogin = true;
-+ }
-+ status = trans.end();
-+ loadReaderObject();
-+ return;
-+ }
-
- selectApplet();
- log->log("time load object: Select Applet (again) %d ms\n",
-@@ -2634,15 +3588,15 @@ Slot::getSessionInfo(SessionHandleSuffix
- }
-
- void
--SlotList::login(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen)
-+SlotList::login(CK_SESSION_HANDLE hSession, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
- {
- CK_SLOT_ID slotID;
- SessionHandleSuffix suffix;
-
- decomposeSessionHandle(hSession, slotID, suffix);
-
-- slots[slotIDToIndex(slotID)]->login(suffix, pPin, ulPinLen);
-+ slots[slotIDToIndex(slotID)]->login(suffix, user, pPin, ulPinLen);
- }
-
- void
-@@ -2692,8 +3646,8 @@ Slot::isLoggedIn()
- }
-
- void
--Slot::login(SessionHandleSuffix handleSuffix, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen)
-+Slot::login(SessionHandleSuffix handleSuffix, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
- {
- refreshTokenState();
-
-@@ -2702,9 +3656,23 @@ Slot::login(SessionHandleSuffix handleSu
- "Slot::login\n", (unsigned long) handleSuffix);
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-+ /* only support CKU_USER for CAC, PIV, and coolkey... CKU_USER and
-+ * CKU_CONTEX_SPECIFIC for P15Card */
-+ if (user != CKU_USER) {
-+ if ((user != CKU_CONTEXT_SPECIFIC) || ((state & P15_CARD) == 0)) {
-+ throw PKCS11Exception(CKR_USER_TYPE_INVALID);
-+ }
-+ }
-+
-
- if (!isVersion1Key) {
-- pinCache.set((const char *)pPin, ulPinLen);
-+ if (user == CKU_USER) {
-+ pinCache.invalidate();
-+ pinCache.set((const char *)pPin, ulPinLen);
-+ } else {
-+ contextPinCache.invalidate();
-+ contextPinCache.set((const char *)pPin, ulPinLen);
-+ }
- } else if (nonceValid) {
- throw PKCS11Exception(CKR_USER_ALREADY_LOGGED_IN);
- }
-@@ -2713,19 +3681,85 @@ Slot::login(SessionHandleSuffix handleSu
- CKYStatus status = trans.begin(conn);
- if(status != CKYSUCCESS ) handleConnectionError();
-
-- if (state & CAC_CARD) {
-- selectCACApplet(0);
-- } else {
-+ if (state & GOV_CARD) {
-+ selectCACApplet(0, true);
-+ } else if ((state & P15_CARD)== 0) {
-+ /* p15 does the select in attemptLogin */
- selectApplet();
- }
-
- if (isVersion1Key) {
-- attemptLogin((const char *)pPin);
-- } else if (state & CAC_CARD) {
-+ attemptCoolKeyLogin((const char *)pPin);
-+ } else {
-+ attemptLogin(user, false);
-+ }
-+}
-+
-+void
-+Slot::attemptLogin(CK_USER_TYPE user, bool flushPin) {
-+ if (state & GOV_CARD) {
- attemptCACLogin();
-+ } else if (state & P15_CARD) {
-+ attemptP15Login(user);
- } else {
- oldAttemptLogin();
- }
-+ if (flushPin && (user == CKU_CONTEXT_SPECIFIC)) {
-+ contextPinCache.clearPin();
-+ }
-+}
-+void dump(const char *label, const CKYBuffer *buf);
-+
-+void
-+Slot::attemptP15Login(CK_USER_TYPE user)
-+{
-+ PinCache *pinCachePtr = userPinCache(user);
-+
-+ if (user == CKU_USER) {
-+ loggedIn = false;
-+ }
-+ pinCachePtr->invalidate();
-+
-+ CKYStatus status;
-+ CKYISOStatus result;
-+
-+ if ((user >= MAX_AUTH_USERS) || (auth[user] == NULL)) {
-+ throw PKCS11Exception(CKR_USER_TYPE_INVALID,
-+ "No PKCS #15 auth object for user %d\n", user);
-+ }
-+
-+ status = selectPath(auth[user]->getObjectPath().getPath(), &result);
-+ if( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+ if (status != CKYSUCCESS) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR, "Applet select return 0x%04x",
-+ result);
-+ }
-+
-+ status = P15Applet_VerifyPIN(conn,
-+ (const char *)CKYBuffer_Data(pinCachePtr->get()),
-+ auth[user]->getPinInfo(), &result);
-+ if( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+ switch( result ) {
-+ case CKYISO_SUCCESS:
-+ break;
-+ case 0x6983:
-+ pinCachePtr->clearPin();
-+ throw PKCS11Exception(CKR_PIN_LOCKED);
-+ default:
-+ pinCachePtr->clearPin();
-+ if ((result & 0xff00) == 0x6300) {
-+ throw PKCS11Exception(CKR_PIN_INCORRECT);
-+ }
-+ throw PKCS11Exception(CKR_DEVICE_ERROR, "Applet returned 0x%04x",
-+ result);
-+ }
-+ pinCachePtr->validate();
-+ if (user == CKU_USER)
-+ loggedIn = true;
- }
-
- void
-@@ -2738,7 +3772,8 @@ Slot::attemptCACLogin()
- CKYISOStatus result;
-
- status = CACApplet_VerifyPIN(conn,
-- (const char *)CKYBuffer_Data(pinCache.get()), &result);
-+ (const char *)CKYBuffer_Data(pinCache.get()),
-+ mCACLocalLogin, &result);
- if( status == CKYSCARDERR ) {
- handleConnectionError();
- }
-@@ -2746,8 +3781,10 @@ Slot::attemptCACLogin()
- case CKYISO_SUCCESS:
- break;
- case 0x6981:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_PIN_LOCKED);
- default:
-+ pinCache.clearPin();
- if ((result & 0xff00) == 0x6300) {
- throw PKCS11Exception(CKR_PIN_INCORRECT);
- }
-@@ -2759,6 +3796,7 @@ Slot::attemptCACLogin()
- loggedIn = true;
- }
-
-+
- void
- Slot::oldAttemptLogin()
- {
-@@ -2776,10 +3814,13 @@ Slot::oldAttemptLogin()
- case CKYISO_SUCCESS:
- break;
- case CKYISO_AUTH_FAILED:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_PIN_INCORRECT);
- case CKYISO_IDENTITY_BLOCKED:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_PIN_LOCKED);
- default:
-+ pinCache.clearPin();
- throw PKCS11Exception(CKR_DEVICE_ERROR, "Applet returned 0x%04x",
- result);
- }
-@@ -2790,7 +3831,7 @@ Slot::oldAttemptLogin()
-
- // should already be in a transaction, and applet selected
- void
--Slot::attemptLogin(const char *pin)
-+Slot::attemptCoolKeyLogin(const char *pin)
- {
- CKYStatus status;
- CKYISOStatus result;
-@@ -2866,7 +3907,7 @@ Slot::logout(SessionHandleSuffix suffix)
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-
-- if (state & CAC_CARD) {
-+ if (state & (GOV_CARD|P15_CARD)) {
- CACLogout();
- return;
- }
-@@ -2993,7 +4034,7 @@ Slot::getAttributeValue(SessionHandleSuf
- ObjectConstIter iter = find_if(tokenObjects.begin(), tokenObjects.end(),
- ObjectHandleMatch(hObject));
-
-- if( iter == tokenObjects.end() ) {
-+ if ( iter == tokenObjects.end()) {
- throw PKCS11Exception(CKR_OBJECT_HANDLE_INVALID);
- }
-
-@@ -3077,6 +4118,21 @@ SlotList::generateRandom(CK_SESSION_HAND
- }
-
- void
-+SlotList::derive(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
-+{
-+
-+ CK_SLOT_ID slotID;
-+ SessionHandleSuffix suffix;
-+
-+ decomposeSessionHandle(hSession, slotID, suffix);
-+
-+ slots[slotIDToIndex(slotID)]->derive(suffix, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey);
-+
-+}
-+
-+void
- Slot::ensureValidSession(SessionHandleSuffix suffix)
- {
- if( ! isValidSession(suffix) ) {
-@@ -3090,24 +4146,36 @@ Slot::ensureValidSession(SessionHandleSu
- // from 0-9.
- //
- CKYByte
--Slot::objectHandleToKeyNum(CK_OBJECT_HANDLE hKey)
-+Slot::objectToKeyNum(const PKCS11Object *key)
-+{
-+ unsigned long id = key->getMuscleObjID();
-+
-+ if( getObjectClass(id) != 'k' ) {
-+ throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-+ }
-+ unsigned short keyNum = getObjectIndex(id);
-+ if( keyNum > 9 ) {
-+ throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-+ }
-+ return keyNum & 0xFF;
-+}
-+
-+PKCS11Object *
-+Slot::getKeyFromHandle(CK_OBJECT_HANDLE hKey)
- {
- ObjectConstIter iter = find_if(tokenObjects.begin(), tokenObjects.end(),
- ObjectHandleMatch(hKey));
-+ PKCS11Object &obj = (PKCS11Object &)*iter;
-
- if( iter == tokenObjects.end() ) {
-- // no such object
-- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-+ throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
-
- if( getObjectClass(iter->getMuscleObjID()) != 'k' ) {
- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
- }
-- unsigned short keyNum = getObjectIndex(iter->getMuscleObjID());
-- if( keyNum > 9 ) {
-- throw PKCS11Exception(CKR_KEY_HANDLE_INVALID);
-- }
-- return keyNum & 0xFF;
-+
-+ return &obj;
- }
-
- void
-@@ -3119,7 +4187,8 @@ Slot::signInit(SessionHandleSuffix suffi
- if( session == sessions.end() ) {
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-- session->signatureState.initialize(objectHandleToKeyNum(hKey));
-+
-+ session->signatureState.initialize(getKeyFromHandle(hKey));
- }
-
- void
-@@ -3131,7 +4200,8 @@ Slot::decryptInit(SessionHandleSuffix su
- if( session == sessions.end() ) {
- throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
- }
-- session->decryptionState.initialize(objectHandleToKeyNum(hKey));
-+
-+ session->decryptionState.initialize(getKeyFromHandle(hKey));
- }
-
- /**
-@@ -3240,67 +4310,183 @@ stripRSAPadding(CKYBuffer *stripped, con
- }
- }
-
--class RSASignatureParams : public CryptParams {
-+class ECCKeyAgreementParams : public CryptParams {
- public:
-- RSASignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-+ ECCKeyAgreementParams(unsigned int keysize) : CryptParams(keysize) { }
-
-- CKYByte getDirection() const { return CKY_DIR_ENCRYPT; }
-+ CKYByte getDirection() const { return CKY_DIR_NONE;}
-
- CryptOpState& getOpState(Session& session) const {
-- return session.signatureState;
-+ return session.keyAgreementState;
- }
-
- void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-- // RSA_NO_PAD requires RSA PKCS #1 Type 1 padding
-- CKYStatus status = CKYBuffer_Resize(paddedInput,getKeySize()/8);
-- if (status != CKYSUCCESS) {
-- throw PKCS11Exception(CKR_HOST_MEMORY);
-- }
-- padRSAType1(unpaddedInput, paddedInput);
- return;
- }
-
- void
- unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-- // no need to unpad ciphertext
-- CKYBuffer_Replace(unpaddedOutput, 0, CKYBuffer_Data(paddedOutput),
-- CKYBuffer_Size(paddedOutput));
--
-+ return;
- }
-+
- };
-
--class RSADecryptParams: public CryptParams {
-+class SignatureParams : public CryptParams {
- public:
-- RSADecryptParams(unsigned int keysize) : CryptParams(keysize) { }
-+ SignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-
-- CKYByte getDirection() const { return CKY_DIR_DECRYPT; }
-+ CKYByte getDirection() const { return CKY_DIR_NONE; }
-
- CryptOpState& getOpState(Session& session) const {
-- return session.decryptionState;
-+ return session.signatureState;
- }
-
- void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-- // no need to unpad ciphertext
-- CKYBuffer_Replace(paddedInput, 0, CKYBuffer_Data(unpaddedInput),
-- CKYBuffer_Size(unpaddedInput));
-+ return;
- }
-
- void
- unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-- // strip off PKCS #1 padding
-- stripRSAPadding( unpaddedOutput, paddedOutput );
-- return;
-+ return;
- }
-+
- };
-
--void
--Slot::sign(SessionHandleSuffix suffix, CK_BYTE_PTR pData,
-- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
-- CK_ULONG_PTR pulSignatureLen)
--{
-- RSASignatureParams params(CryptParams::DEFAULT_KEY_SIZE);
-- cryptRSA(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-- params);
-+
-+
-+class ECCSignatureParams : public CryptParams {
-+ public:
-+ ECCSignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-+
-+ CKYByte getDirection() const { return CKY_DIR_NONE; }
-+
-+ CryptOpState& getOpState(Session& session) const {
-+ return session.signatureState;
-+ }
-+
-+ void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-+ return;
-+ }
-+
-+ void
-+ unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-+ /* Here we will unpack the DER encoding of the signature */
-+
-+ if ( unpaddedOutput == NULL || paddedOutput == NULL) {
-+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
-+ }
-+
-+ CKYBuffer rawSignature;
-+ CKYBuffer_InitEmpty(&rawSignature);
-+
-+ DEREncodedSignature sig(paddedOutput);
-+
-+ int rv = sig.getRawSignature(&rawSignature, getKeySize() );
-+
-+ if (rv == CKYSUCCESS) {
-+ CKYBuffer_Replace(unpaddedOutput, 0, CKYBuffer_Data(&rawSignature),
-+ CKYBuffer_Size(&rawSignature));
-+ } else {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR);
-+ }
-+
-+ CKYBuffer_FreeData(&rawSignature);
-+
-+ }
-+
-+};
-+
-+
-+class RSASignatureParams : public CryptParams {
-+ public:
-+ RSASignatureParams(unsigned int keysize) : CryptParams(keysize) { }
-+
-+ CKYByte getDirection() const { return CKY_DIR_ENCRYPT; }
-+
-+ CryptOpState& getOpState(Session& session) const {
-+ return session.signatureState;
-+ }
-+
-+ void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-+ // RSA_NO_PAD requires RSA PKCS #1 Type 1 padding
-+ CKYStatus status = CKYBuffer_Resize(paddedInput,getKeySize()/8);
-+ if (status != CKYSUCCESS) {
-+ throw PKCS11Exception(CKR_HOST_MEMORY);
-+ }
-+ padRSAType1(unpaddedInput, paddedInput);
-+ return;
-+ }
-+
-+ void
-+ unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-+ // no need to unpad ciphertext
-+ CKYBuffer_Replace(unpaddedOutput, 0, CKYBuffer_Data(paddedOutput),
-+ CKYBuffer_Size(paddedOutput));
-+
-+ }
-+};
-+
-+class RSADecryptParams: public CryptParams {
-+ public:
-+ RSADecryptParams(unsigned int keysize) : CryptParams(keysize) { }
-+
-+ CKYByte getDirection() const { return CKY_DIR_DECRYPT; }
-+
-+ CryptOpState& getOpState(Session& session) const {
-+ return session.decryptionState;
-+ }
-+
-+ void padInput(CKYBuffer *paddedInput, const CKYBuffer *unpaddedInput) const {
-+ // no need to unpad ciphertext
-+ CKYBuffer_Replace(paddedInput, 0, CKYBuffer_Data(unpaddedInput),
-+ CKYBuffer_Size(unpaddedInput));
-+ }
-+
-+ void
-+ unpadOutput(CKYBuffer *unpaddedOutput, const CKYBuffer *paddedOutput) const {
-+ // strip off PKCS #1 padding
-+ stripRSAPadding( unpaddedOutput, paddedOutput );
-+ return;
-+ }
-+};
-+
-+void
-+Slot::sign(SessionHandleSuffix suffix, CK_BYTE_PTR pData,
-+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
-+ CK_ULONG_PTR pulSignatureLen)
-+{
-+
-+ refreshTokenState();
-+ SessionIter session = findSession(suffix);
-+ if( session == sessions.end() ) {
-+ throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
-+ }
-+
-+ if (!isVersion1Key && ! isLoggedIn() ) {
-+ throw PKCS11Exception(CKR_USER_NOT_LOGGED_IN);
-+ }
-+
-+ /* Create a default one just to get the sigState */
-+ SignatureParams dummyParams(CryptParams::DEFAULT_KEY_SIZE);
-+
-+ CryptOpState sigState = dummyParams.getOpState(*session);
-+
-+ PKCS11Object::KeyType keyType = sigState.key->getKeyType();
-+
-+ if ( keyType == PKCS11Object::unknown) {
-+ throw PKCS11Exception(CKR_DATA_INVALID);
-+ }
-+
-+ if( keyType == Key::ecc ) {
-+ ECCSignatureParams params(CryptParams::ECC_DEFAULT_KEY_SIZE);
-+ signECC(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-+ params);
-+
-+ } else if (keyType == Key::rsa) {
-+ RSASignatureParams params(CryptParams::DEFAULT_KEY_SIZE);
-+ cryptRSA(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
-+ params);
-+ }
- }
-
- void
-@@ -3332,11 +4518,11 @@ Slot::cryptRSA(SessionHandleSuffix suffi
- }
- CryptOpState& opState = params.getOpState(*session);
- CKYBuffer *result = &opState.result;
-- CKYByte keyNum = opState.keyNum;
-+ PKCS11Object *key = opState.key;
-
-- unsigned int keySize = getKeySize(keyNum);
-+ unsigned int keySize = getRSAKeySize(key);
-
-- if(keySize != CryptParams::DEFAULT_KEY_SIZE)
-+ if (keySize != CryptParams::DEFAULT_KEY_SIZE)
- params.setKeySize(keySize);
-
- if( CKYBuffer_Size(result) == 0 ) {
-@@ -3358,7 +4544,8 @@ Slot::cryptRSA(SessionHandleSuffix suffi
- }
- try {
- params.padInput(&inputPad, &input);
-- performRSAOp(&output, &inputPad, keyNum, params.getDirection());
-+ performRSAOp(&output, &inputPad, params.getKeySize(), key,
-+ params.getDirection());
- params.unpadOutput(result, &output);
- CKYBuffer_FreeData(&input);
- CKYBuffer_FreeData(&inputPad);
-@@ -3395,35 +4582,216 @@ Slot::getNonce()
- return &nonce;
- }
-
-+void Slot::signECC(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
-+ CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params)
-+{
-+
-+ if( pulOutputLen == NULL ) {
-+ throw PKCS11Exception(CKR_DATA_INVALID,
-+ "output length is NULL");
-+ }
-+
-+ refreshTokenState();
-+ SessionIter session = findSession(suffix);
-+ if( session == sessions.end() ) {
-+ throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
-+ }
-+ /* version 1 keys may not need login. We catch the error
-+ on the operation. The token will not allow us to sign with
-+ a protected key unless we are logged in.
-+ can be removed when version 0 support is depricated.
-+ */
-+
-+ if (!isVersion1Key && ! isLoggedIn() ) {
-+ throw PKCS11Exception(CKR_USER_NOT_LOGGED_IN);
-+ }
-+ CryptOpState& opState = params.getOpState(*session);
-+ CKYBuffer *result = &opState.result;
-+ PKCS11Object *key = opState.key;
-+
-+ unsigned int keySize = getECCKeySize(key);
-+
-+ if(keySize != CryptParams::ECC_DEFAULT_KEY_SIZE)
-+ params.setKeySize(keySize);
-+
-+ if( CKYBuffer_Size(result) == 0 ) {
-+ unsigned int maxSize = params.getKeySize()/8;
-+
-+ if( pInput == NULL || ulInputLen == 0) {
-+ throw PKCS11Exception(CKR_DATA_LEN_RANGE);
-+ }
-+ if (ulInputLen > maxSize) {
-+ //pInput += ulInputLen - maxSize;
-+ ulInputLen = maxSize;
-+ }
-+
-+ CKYBuffer input;
-+ CKYBuffer output;
-+ CKYBuffer_InitEmpty(&output);
-+ CKYStatus status = CKYBuffer_InitFromData(&input, pInput, ulInputLen);
-+
-+ if (status != CKYSUCCESS) {
-+ CKYBuffer_FreeData(&output);
-+ throw PKCS11Exception(CKR_HOST_MEMORY);
-+ }
-+ try {
-+ performECCSignature(&output, &input, params.getKeySize(), key);
-+ params.unpadOutput(result, &output);
-+ CKYBuffer_FreeData(&input);
-+ CKYBuffer_FreeData(&output);
-+ } catch(PKCS11Exception& e) {
-+ CKYBuffer_FreeData(&input);
-+ CKYBuffer_FreeData(&output);
-+ throw(e);
-+ }
-+ }
-+
-+ if( pOutput != NULL ) {
-+ if( *pulOutputLen < CKYBuffer_Size(result) ) {
-+ *pulOutputLen = CKYBuffer_Size(result);
-+ throw PKCS11Exception(CKR_BUFFER_TOO_SMALL);
-+ }
-+ memcpy(pOutput, CKYBuffer_Data(result), CKYBuffer_Size(result));
-+ }
-+ *pulOutputLen = CKYBuffer_Size(result);
-+}
-+
- void
--Slot::performRSAOp(CKYBuffer *output, const CKYBuffer *input,
-- CKYByte keyNum, CKYByte direction)
-+Slot::selectKey(const PKCS11Object *key, bool retry)
- {
-- //
-- // establish a transaction
-- //
-+ /* P15 cards need to be reselected on retry because P15 must select
-+ * on authentication. PIV, CAC and Coolkeys do not */
-+ if (retry && ((state & GOV_CARD) || ((state & P15_CARD) == 0))) {
-+ return;
-+ }
-+ if (state & GOV_CARD) {
-+ selectCACApplet(objectToKeyNum(key), true);
-+ } else if (state & P15_CARD) {
-+ selectPath(key->getObjectPath().getPath(), NULL);
-+ } else {
-+ selectApplet();
-+ }
-+ return;
-+}
-+
-+void
-+Slot::performECCSignature(CKYBuffer *output, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key)
-+{
-+
-+ /* establish a transaction */
- Transaction trans;
- CKYStatus status = trans.begin(conn);
- if( status != CKYSUCCESS ) handleConnectionError();
-
-- //
-- // select the applet
-- //
-- if (state & CAC_CARD) {
-- selectCACApplet(keyNum);
-+ if (!mECC) {
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ }
-+
-+ CKYISOStatus result;
-+ bool loginAttempted = false;
-+
-+retry:
-+ selectKey(key, loginAttempted);
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_SignDecrypt(conn, pivKey, keySize/8, 0,
-+ input, output, &result);
-+ } else if (state & CAC_CARD) {
-+ status = CACApplet_SignDecrypt(conn, input, output, &result);
-+ } else if (state & P15_CARD) {
-+ status = P15Applet_SignDecrypt(conn, key->getKeyRef(), keySize/8,
-+ CKY_DIR_ENCRYPT, input, output, &result);
-+
- } else {
-- selectApplet();
-+ status = CKYApplet_ComputeECCSignature(conn, objectToKeyNum(key), input, NULL, output, getNonce(), &result);
-+ }
-+ /* map the ISO not logged in code to the coolkey one */
-+ if ((result == CKYISO_CONDITION_NOT_SATISFIED) ||
-+ (result == CKYISO_SECURITY_NOT_SATISFIED)) {
-+ result = (CKYStatus) CKYISO_UNAUTHORIZED;
-+ }
-+
-+ if (status != CKYSUCCESS) {
-+ if ( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+
-+ if (result == CKYISO_DATA_INVALID) {
-+ throw PKCS11Exception(CKR_DATA_INVALID);
-+ }
-+ /* keys could be logged out in the middle by someone else,
-+ * reauthenticate... coolkey version 1 bypasses this issue by
-+ * allowing multiple applications separate login states at once.
-+ */
-+ if (!isVersion1Key && !loginAttempted &&
-+ userPinCache(key->getUser())->isValid() &&
-+ (result == CKYISO_UNAUTHORIZED)) {
-+ /* try to reauthenticate */
-+ try {
-+ attemptLogin(key->getUser(),true);
-+ } catch(PKCS11Exception& ) {
-+ /* attemptLogin can throw things like CKR_PIN_INCORRECT
-+ that don't make sense from a crypto operation. This is
-+ a result of pin caching. We will reformat any login
-+ exception to a CKR_DEVICE_ERROR.
-+ */
-+ throw PKCS11Exception(CKR_DEVICE_ERROR);
-+ }
-+ loginAttempted = true;
-+ goto retry; /* easier to understand than a while loop in this case. */
-+ }
-+ throw PKCS11Exception( result == CKYISO_UNAUTHORIZED ?
-+ CKR_USER_NOT_LOGGED_IN : CKR_DEVICE_ERROR);
-+
- }
-
-+}
-+
-+
-+void
-+Slot::performRSAOp(CKYBuffer *output, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key,
-+ CKYByte direction)
-+{
-+ if ( mECC ) {
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ }
-+
-+ //
-+ // establish a transaction
-+ //
-+ Transaction trans;
-+ CKYStatus status = trans.begin(conn);
-+ if( status != CKYSUCCESS ) handleConnectionError();
- CKYISOStatus result;
-- int loginAttempted = 0;
-+ bool loginAttempted = false;
-+
- retry:
-- if (state & CAC_CARD) {
-+ selectKey(key, loginAttempted);
-+
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_SignDecrypt(conn, pivKey, keySize/8, 0,
-+ input, output, &result);
-+ } else if (state & CAC_CARD) {
- status = CACApplet_SignDecrypt(conn, input, output, &result);
-+ } else if (state & P15_CARD) {
-+ status = P15Applet_SignDecrypt(conn, key->getKeyRef(), keySize/8,
-+ direction, input, output, &result);
- } else {
-- status = CKYApplet_ComputeCrypt(conn, keyNum, CKY_RSA_NO_PAD, direction,
-- input, NULL, output, getNonce(), &result);
-+ status = CKYApplet_ComputeCrypt(conn, objectToKeyNum(key),
-+ CKY_RSA_NO_PAD, direction, input, NULL, output,
-+ getNonce(), &result);
- }
-+
-+ /* map the ISO not logged in code to the coolkey one */
-+ if ((result == CKYISO_CONDITION_NOT_SATISFIED) ||
-+ (result == CKYISO_SECURITY_NOT_SATISFIED)) {
-+ result = CKYISO_UNAUTHORIZED;
-+ }
-+
- if (status != CKYSUCCESS) {
- if ( status == CKYSCARDERR ) {
- handleConnectionError();
-@@ -3435,10 +4803,11 @@ retry:
- // reauthenticate... This code can go away when we depricate.
- // version0 applets.
- if (!isVersion1Key && !loginAttempted &&
-+ userPinCache(key->getUser())->isValid() &&
- (result == CKYISO_UNAUTHORIZED)) {
- // try to reauthenticate
- try {
-- oldAttemptLogin();
-+ attemptLogin(key->getUser(), true);
- } catch(PKCS11Exception& ) {
- // attemptLogin can throw things like CKR_PIN_INCORRECT
- // that don't make sense from a crypto operation. This is
-@@ -3458,7 +4827,7 @@ void
- Slot::seedRandom(SessionHandleSuffix suffix, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen)
- {
-- if (state & CAC_CARD) {
-+ if (state & (GOV_CARD|P15_CARD)) {
- /* should throw unsupported */
- throw PKCS11Exception(CKR_DEVICE_ERROR);
- }
-@@ -3510,7 +4879,7 @@ void
- Slot::generateRandom(SessionHandleSuffix suffix, const CK_BYTE_PTR pData,
- CK_ULONG ulDataLen)
- {
-- if (state & CAC_CARD) {
-+ if (state & (GOV_CARD|P15_CARD)) {
- /* should throw unsupported */
- throw PKCS11Exception(CKR_DEVICE_ERROR);
- }
-@@ -3544,33 +4913,249 @@ Slot::generateRandom(SessionHandleSuffix
-
- #define MAX_NUM_KEYS 8
- unsigned int
--Slot::getKeySize(CKYByte keyNum)
-+Slot::getRSAKeySize(PKCS11Object *key)
- {
- unsigned int keySize = CryptParams::DEFAULT_KEY_SIZE;
- int modSize = 0;
-
-- if(keyNum >= MAX_NUM_KEYS) {
-- return keySize;
-- }
--
-- ObjectConstIter iter;
-- iter = find_if(tokenObjects.begin(), tokenObjects.end(),
-- KeyNumMatch(keyNum,*this));
--
-- if( iter == tokenObjects.end() ) {
-- return keySize;
-+ modSize = key->getKeySize();
-+ if (modSize != 0) {
-+ return modSize;
- }
-
-- CKYBuffer const *modulus = iter->getAttribute(CKA_MODULUS);
-+ CKYBuffer const *modulus = key->getAttribute(CKA_MODULUS);
-
- if(modulus) {
- modSize = CKYBuffer_Size(modulus);
- if(CKYBuffer_GetChar(modulus,0) == 0x0) {
- modSize--;
- }
-- if(modSize > 0)
-+ if(modSize > 0) {
- keySize = modSize * 8;
-+ key->setKeySize(keySize);
-+ }
- }
-
- return keySize;
- }
-+
-+unsigned int
-+Slot::getECCKeySize(PKCS11Object *key)
-+{
-+ unsigned int keySize = CryptParams::ECC_DEFAULT_KEY_SIZE;
-+ unsigned int objKeySize = 0;
-+
-+ objKeySize = key->getKeySize();
-+ if (objKeySize != 0) {
-+ return objKeySize;
-+ }
-+
-+ CKYBuffer const *eccParams = key->getAttribute(CKA_EC_PARAMS);
-+
-+ if (eccParams == NULL) {
-+ return keySize;
-+ }
-+
-+ /* Extract the oid from the params */
-+
-+ CKYByte ecParamsLen = CKYBuffer_GetChar(eccParams, 1);
-+
-+ if ( ecParamsLen == 0 ) {
-+ return keySize;
-+ }
-+
-+/* Now compare against the limited known list of oid byte info */
-+
-+ unsigned int oidByteLen = 0;
-+
-+ CKYByte curByte = 0;
-+
-+ for (int i = 0 ; i < numECCurves ; i++ ) {
-+
-+ oidByteLen = curveBytesNamePair[i].bytes[0];
-+
-+ if ( oidByteLen != (unsigned int ) ecParamsLen ) {
-+ continue;
-+ }
-+
-+ int match = 1;
-+ for ( int j = 0 ; j < ecParamsLen ; j++ ) {
-+ curByte = CKYBuffer_GetChar(eccParams, 2 + j );
-+ if ( curveBytesNamePair[i].bytes[ j + 1 ] != curByte ) {
-+ match = 0;
-+ break;
-+ }
-+ }
-+
-+ if ( match == 1 ) {
-+ keySize = curveBytesNamePair[i].length;
-+ key->setKeySize(keySize);
-+ return keySize;
-+ }
-+
-+ }
-+
-+ return keySize;
-+}
-+
-+void
-+Slot::derive(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
-+{
-+
-+ log->log("Inside of Slot::Derive! \n");
-+
-+ ECCKeyAgreementParams params(CryptParams::ECC_DEFAULT_KEY_SIZE);
-+ SessionIter session = findSession(suffix);
-+
-+ session->keyAgreementState.initialize(getKeyFromHandle(hBaseKey));
-+ deriveECC(suffix, pMechanism, hBaseKey, pTemplate, ulAttributeCount,
-+ phKey, params);
-+
-+}
-+
-+void Slot::deriveECC(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, CryptParams& params)
-+{
-+ if (pMechanism == NULL ) {
-+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
-+ }
-+
-+ CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;
-+
-+ mechParams = (CK_ECDH1_DERIVE_PARAMS*) pMechanism->pParameter;
-+
-+ if (mechParams == NULL || mechParams->kdf != CKD_NULL ) {
-+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
-+ }
-+
-+ refreshTokenState();
-+ SessionIter session = findSession(suffix);
-+ if( session == sessions.end() ) {
-+ throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
-+ }
-+
-+ /* version 1 keys may not need login. We catch the error
-+ on the operation. The token will not allow us to sign with
-+ a protected key unless we are logged in.
-+ can be removed when version 0 support is depricated. */
-+
-+ if (!isVersion1Key && ! isLoggedIn() ) {
-+ throw PKCS11Exception(CKR_USER_NOT_LOGGED_IN);
-+ }
-+
-+ CryptOpState& opState = params.getOpState(*session);
-+ CKYBuffer *result = &opState.result;
-+
-+ unsigned int keySize = getECCKeySize(opState.key);
-+
-+ if(keySize != CryptParams::ECC_DEFAULT_KEY_SIZE)
-+ params.setKeySize(keySize);
-+
-+ CK_MECHANISM_TYPE deriveMech = pMechanism->mechanism;
-+
-+ CK_ULONG otherPublicLen = mechParams->ulPublicDataLen;
-+ CK_BYTE_PTR otherPublicData = mechParams->pPublicData;
-+
-+ CKYBuffer secretKeyBuffer;
-+ CKYBuffer_InitEmpty(&secretKeyBuffer);
-+ CKYBuffer publicDataBuffer;
-+ CKYStatus status = CKYBuffer_InitFromData(&publicDataBuffer,otherPublicData, otherPublicLen);
-+
-+ if (status != CKYSUCCESS) {
-+ CKYBuffer_FreeData(&secretKeyBuffer);
-+ throw PKCS11Exception(CKR_HOST_MEMORY);
-+ }
-+
-+ PKCS11Object *secret = NULL;
-+ *phKey = 0;
-+
-+ if( CKYBuffer_Size(result) == 0 ) {
-+ try {
-+ performECCKeyAgreement(deriveMech, &publicDataBuffer,
-+ &secretKeyBuffer, opState.key, params.getKeySize());
-+ CK_OBJECT_HANDLE keyObjectHandle = generateUnusedObjectHandle();
-+ secret = createSecretKeyObject(keyObjectHandle, &secretKeyBuffer,
-+ pTemplate, ulAttributeCount);
-+ } catch(PKCS11Exception& e) {
-+ CKYBuffer_FreeData(&secretKeyBuffer);
-+ CKYBuffer_FreeData(&publicDataBuffer);
-+ throw(e);
-+ }
-+ }
-+
-+ CKYBuffer_FreeData(&secretKeyBuffer);
-+ CKYBuffer_FreeData(&publicDataBuffer);
-+
-+ if ( secret ) {
-+ *phKey = secret->getHandle();
-+ delete secret;
-+ }
-+}
-+
-+void
-+Slot::performECCKeyAgreement(CK_MECHANISM_TYPE deriveMech,
-+ CKYBuffer *publicDataBuffer, CKYBuffer *secretKeyBuffer,
-+ const PKCS11Object *key, unsigned int keySize)
-+{
-+ if (!mECC) {
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ }
-+
-+ Transaction trans;
-+ CKYStatus status = trans.begin(conn);
-+ if( status != CKYSUCCESS ) handleConnectionError();
-+
-+ CKYISOStatus result;
-+ bool loginAttempted = false;
-+
-+retry:
-+ selectKey(key, loginAttempted);
-+
-+ if (state & PIV_CARD) {
-+ status = PIVApplet_SignDecrypt(conn, pivKey, keySize/8, 1,
-+ publicDataBuffer, secretKeyBuffer, &result);
-+ } else if (state & CAC_CARD) {
-+ status = CACApplet_SignDecrypt(conn, publicDataBuffer,
-+ secretKeyBuffer, &result);
-+ } else if (state & P15_CARD) {
-+ /*status = P15Applet_SignDecrypt(conn, key->getKeyRef(), keySize/8,
-+ publicDataBuffer, secretKeyBuffer, &result); */
-+ throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
-+ } else {
-+ status = CKYApplet_ComputeECCKeyAgreement(conn, objectToKeyNum(key),
-+ publicDataBuffer , NULL, secretKeyBuffer,
-+ getNonce(), &result);
-+ }
-+ /* map the ISO not logged in code to the coolkey one */
-+ if ((result == CKYISO_CONDITION_NOT_SATISFIED) ||
-+ (result == CKYISO_SECURITY_NOT_SATISFIED)) {
-+ result = (CKYStatus) CKYISO_UNAUTHORIZED;
-+ }
-+
-+ if (status != CKYSUCCESS) {
-+ if ( status == CKYSCARDERR ) {
-+ handleConnectionError();
-+ }
-+
-+ if (result == CKYISO_DATA_INVALID) {
-+ throw PKCS11Exception(CKR_DATA_INVALID);
-+ }
-+ if (!isVersion1Key && !loginAttempted &&
-+ userPinCache(key->getUser())->isValid() &&
-+ (result == CKYISO_UNAUTHORIZED)) {
-+ try {
-+ attemptLogin(key->getUser(), true);
-+ } catch(PKCS11Exception& ) {
-+ throw PKCS11Exception(CKR_DEVICE_ERROR);
-+ }
-+ loginAttempted = true;
-+ goto retry;
-+ }
-+
-+ throw PKCS11Exception( result == CKYISO_UNAUTHORIZED ?
-+ CKR_USER_NOT_LOGGED_IN : CKR_DEVICE_ERROR);
-+
-+ }
-+}
-diff -up ./src/coolkey/slot.h.coolkey-update ./src/coolkey/slot.h
---- ./src/coolkey/slot.h.coolkey-update 2016-01-19 17:56:25.705426782 -0800
-+++ ./src/coolkey/slot.h 2016-01-19 17:56:35.438346737 -0800
-@@ -183,7 +183,7 @@ struct PinCache {
- CKYBuffer_Replace(&cachedPin, 0, (const CKYByte *)newPin, pinLen);
- CKYBuffer_AppendChar(&cachedPin, 0);
- }
-- void clearPin() { CKYBuffer_Zero(&cachedPin); }
-+ void clearPin() { CKYBuffer_Zero(&cachedPin); valid = false; }
- void invalidate() { valid = false; }
- void validate() { valid = true; }
- const CKYBuffer *get() const { return &cachedPin; }
-@@ -209,26 +209,26 @@ class CryptOpState {
- public:
- enum State { NOT_INITIALIZED, IN_PROCESS, FINALIZED };
- State state;
-- CKYByte keyNum;
- CKYBuffer result;
-+ PKCS11Object *key;
-
-- CryptOpState() : state(NOT_INITIALIZED), keyNum(0)
-+ CryptOpState() : state(NOT_INITIALIZED), key(NULL)
- { CKYBuffer_InitEmpty(&result); }
- CryptOpState(const CryptOpState &cpy) :
-- state(cpy.state), keyNum(cpy.keyNum) {
-+ state(cpy.state), key(cpy.key) {
- CKYBuffer_InitFromCopy(&result, &cpy.result);
- }
- CryptOpState &operator=(const CryptOpState &cpy) {
- state = cpy.state,
-- keyNum = cpy.keyNum;
-+ key = cpy.key;
- CKYBuffer_Replace(&result, 0, CKYBuffer_Data(&cpy.result),
- CKYBuffer_Size(&cpy.result));
- return *this;
- }
- ~CryptOpState() { CKYBuffer_FreeData(&result); }
-- void initialize(CKYByte keyNum) {
-+ void initialize(PKCS11Object *theKey) {
- state = IN_PROCESS;
-- this->keyNum = keyNum;
-+ this->key = theKey;
- CKYBuffer_Resize(&result, 0);
- }
- };
-@@ -258,6 +258,7 @@ class Session {
-
- CryptOpState signatureState;
- CryptOpState decryptionState;
-+ CryptOpState keyAgreementState;
- };
-
- typedef list<Session> SessionList;
-@@ -267,12 +268,11 @@ typedef SessionList::const_iterator Sess
- class CryptParams {
- private:
- unsigned int keySize; // in bits
-- protected:
-- unsigned int getKeySize() const { return keySize; }
- public:
- // set the actual key size obtained from the card
- void setKeySize(unsigned int newKeySize) { keySize = newKeySize; }
-- enum { DEFAULT_KEY_SIZE = 1024 };
-+ unsigned int getKeySize() const { return keySize; }
-+ enum { DEFAULT_KEY_SIZE = 1024, ECC_DEFAULT_KEY_SIZE=256 };
-
-
- CryptParams(unsigned int keySize_) : keySize(keySize_) { }
-@@ -295,6 +295,7 @@ class CryptParams {
- };
-
- #define MAX_CERT_SLOTS 3
-+#define MAX_AUTH_USERS 3
- class Slot {
-
- public:
-@@ -304,17 +305,22 @@ class Slot {
- ATR_MATCH = 0x04,
- APPLET_SELECTABLE = 0x08,
- APPLET_PERSONALIZED = 0x10,
-- CAC_CARD = 0x20
-+ CAC_CARD = 0x20,
-+ PIV_CARD = 0x40,
-+ P15_CARD = 0x80
- };
- enum {
- NONCE_SIZE = 8
- };
-
-+ static const SlotState GOV_CARD = (SlotState)(CAC_CARD|PIV_CARD);
-+
- private:
- Log *log;
- char *readerName;
- char *personName;
- char *manufacturer;
-+ char *tokenManufacturer;
- //char *model;
- CK_VERSION hwVersion;
- CK_VERSION tokenFWVersion;
-@@ -323,6 +329,7 @@ class Slot {
- CKYCardConnection* conn;
- unsigned long state; // = UNKNOWN
- PinCache pinCache;
-+ PinCache contextPinCache;
- bool loggedIn;
- bool reverify;
- bool nonceValid;
-@@ -339,7 +346,18 @@ class Slot {
- bool fullTokenName;
- bool mCoolkey;
- bool mOldCAC;
--
-+ bool mCACLocalLogin;
-+ int pivContainer;
-+ int pivKey;
-+ bool mECC;
-+ unsigned short p15aid;
-+ unsigned short p15odfAddr;
-+ unsigned short p15tokenInfoAddr;
-+ unsigned int p15Instance;
-+ CKYBuffer p15AID;
-+ CKYBuffer p15tokenInfo;
-+ CKYBuffer p15odf;
-+ CKYBuffer p15serialNumber;
- //enum { RW_SESSION_HANDLE = 1, RO_SESSION_HANDLE = 2 };
-
- #ifdef USE_SHMEM
-@@ -358,6 +376,7 @@ class Slot {
-
- void closeAllSessions();
- SessionHandleSuffix generateNewSession(Session::Type type);
-+ PK15Object *auth[MAX_AUTH_USERS];
-
- bool cardStateMayHaveChanged();
- void connectToToken();
-@@ -386,6 +405,7 @@ class Slot {
- const CKYBuffer *getATR();
- bool isLoggedIn();
- bool needLoggedIn();
-+ bool getPIVLoginType();
- void testNonce();
-
- void addKeyObject(list<PKCS11Object>& objectList,
-@@ -395,6 +415,7 @@ class Slot {
- const CKYBuffer *derCert, CK_OBJECT_HANDLE handle);
- void addObject(list<PKCS11Object>& objectList,
- const ListObjectInfo& info, CK_OBJECT_HANDLE handle);
-+ PKCS11Object *createSecretKeyObject(CK_OBJECT_HANDLE handle, CKYBuffer *secretKeyBuffer,CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount);
-
- void ensureValidSession(SessionHandleSuffix suffix);
-
-@@ -407,37 +428,63 @@ class Slot {
- bool throwException);
- CKYStatus readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize);
-
-+ CKYStatus getP15Params();
- void selectApplet();
-- void selectCACApplet(CKYByte instance);
-+ void selectCACApplet(CKYByte instance,bool do_disconnect);
-+ void selectKey(const PKCS11Object *key, bool retry);
-+ CKYStatus selectPath(const CKYBuffer *path, CKYISOStatus *adpurc);
-+ CKYStatus readFromPath(const PK15ObjectPath &obj, CKYBuffer *file);
- void unloadObjects();
- void loadCACObjects();
- void loadCACCert(CKYByte instance);
- void loadObjects();
- void loadReaderObject();
-
-- void attemptLogin(const char *pin);
-+ void attemptCoolKeyLogin(const char *pin);
-+ void attemptLogin(CK_USER_TYPE user, bool flushPin);
-+ void attemptP15Login(CK_USER_TYPE user);
- void attemptCACLogin();
- void oldAttemptLogin();
- void oldLogout(void);
- void CACLogout(void);
-+ PinCache *userPinCache(CK_USER_TYPE user) {
-+ return ((user == CKU_CONTEXT_SPECIFIC) && (state & P15_CARD)) ?
-+ &contextPinCache : &pinCache; }
-+
-+ void parseEF_ODF(void);
-+ void parseEF_TokenInfo(void);
-+ CKYStatus parseEF_Directory(const CKYByte *data, CKYSize size,
-+ PK15ObjectType type);
-+ unsigned int PK15Instance(void) { return p15Instance++; }
-
- void readMuscleObject(CKYBuffer *obj, unsigned long objID,
- unsigned int objSize);
-
- void performSignature(CKYBuffer *sig, const CKYBuffer *unpaddedInput,
-- CKYByte keyNum);
-- void performDecryption(CKYBuffer *data, const CKYBuffer *input, CKYByte keyNum);
-+ const PKCS11Object *key);
-+ void performDecryption(CKYBuffer *data, const CKYBuffer *input,
-+ const PKCS11Object *key);
-
- void cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
- CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
- CK_ULONG_PTR pulOutputLen, CryptParams& params);
-
-- void performRSAOp(CKYBuffer *out, const CKYBuffer *input, CKYByte keyNum,
-- CKYByte direction);
-+ void performRSAOp(CKYBuffer *out, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key, CKYByte direction);
-+
-+ void signECC(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
-+ CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
-+ CK_ULONG_PTR pulOutputLen, CryptParams& params);
-+
-+ void performECCSignature(CKYBuffer *out, const CKYBuffer *input,
-+ unsigned int keySize, const PKCS11Object *key);
-+ void performECCKeyAgreement(CK_MECHANISM_TYPE deriveMech,
-+ CKYBuffer *publicDataBuffer, CKYBuffer *secretKeyBuffer,
-+ const PKCS11Object *key, unsigned int keySize);
-
- void processComputeCrypt(CKYBuffer *result, const CKYAPDU *apdu);
-
-- CKYByte objectHandleToKeyNum(CK_OBJECT_HANDLE hKey);
-+ CKYByte objectToKeyNum(const PKCS11Object *key);
- Slot(const Slot &cpy)
- #ifdef USE_SHMEM
- : shmem(readerName)
-@@ -469,7 +516,10 @@ class Slot {
- }
-
- // actually get the size of a key in bits from the card
-- unsigned int getKeySize(CKYByte keyNum);
-+ unsigned int getRSAKeySize(PKCS11Object *key);
-+ unsigned int getECCKeySize(PKCS11Object *key);
-+
-+ PKCS11Object *getKeyFromHandle(CK_OBJECT_HANDLE hKey);
-
- SessionHandleSuffix openSession(Session::Type type);
- void closeSession(SessionHandleSuffix handleSuffix);
-@@ -479,8 +529,8 @@ class Slot {
- void getSessionInfo(SessionHandleSuffix handleSuffix,
- CK_SESSION_INFO_PTR pInfo);
-
-- void login(SessionHandleSuffix handleSuffix, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen);
-+ void login(SessionHandleSuffix handleSuffix, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen);
-
- void logout(SessionHandleSuffix suffix);
-
-@@ -511,6 +561,16 @@ class Slot {
- CK_ULONG len);
- void generateRandom(SessionHandleSuffix suffix, CK_BYTE_PTR data,
- CK_ULONG len);
-+
-+ void derive(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
-+
-+ void deriveECC(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, CryptParams& params);
-+
-+ bool getIsECC() { return mECC; }
- };
-
- class SlotList {
-@@ -569,8 +629,8 @@ class SlotList {
- void getSessionInfo(CK_SESSION_HANDLE sessionHandle,
- CK_SESSION_INFO_PTR pInfo);
-
-- void login(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
-- CK_ULONG ulPinLen);
-+ void login(CK_SESSION_HANDLE hSession, CK_USER_TYPE user,
-+ CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen);
-
- void logout(CK_SESSION_HANDLE hSession);
-
-@@ -604,6 +664,10 @@ class SlotList {
- void seedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen);
-
-+ void derive(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
-+ CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
-+
-
- };
- #endif
-diff -up ./src/install/pk11install.c.coolkey-update ./src/install/pk11install.c
---- ./src/install/pk11install.c.coolkey-update 2016-01-19 18:20:42.299464185 -0800
-+++ ./src/install/pk11install.c 2016-01-19 18:18:52.766363310 -0800
-@@ -171,7 +171,7 @@ int dirListCount = sizeof(dirList)/sizeo
- static void
- usage(char *prog)
- {
-- fprintf(stderr,"usage: %s [-u][-v] [-p path] module\n", prog);
-+ fprintf(stderr,"usage: %s [-u][-v][-s][-l] [-p path] module\n", prog);
- return;
- }
-
-@@ -181,9 +181,9 @@ usage(char *prog)
-
- #define CONFIG_TAG "configDir="
- int
--installPKCS11(char *dirPath, InstType type, char *module)
-+installPKCS11(char *dirPath, char *dbType, InstType type, char *module)
- {
-- char *paramString = (char *)malloc(strlen(dirPath)+sizeof(CONFIG_TAG)+3);
-+ char *paramString = (char *)malloc(strlen(dbType)+strlen(dirPath)+sizeof(CONFIG_TAG)+3);
- char *cp;
- char **rc;
-
-@@ -191,7 +191,7 @@ installPKCS11(char *dirPath, InstType ty
- PINST_SET_ERROR(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
-- sprintf(paramString,CONFIG_TAG"\"%s\" ",dirPath);
-+ sprintf(paramString,CONFIG_TAG"\"%s%s\" ",dbType,dirPath);
-
- /* translate all the \'s to /'s */
- for (cp=paramString; *cp; cp++) {
-@@ -214,7 +214,7 @@ installPKCS11(char *dirPath, InstType ty
-
-
- int
--installAllPKCS11(char *dirPath, char *search, char *tail,
-+installAllPKCS11(char *dirPath, char *dbType, char *search, char *tail,
- InstType type, char *module)
- {
- char *searchString;
-@@ -282,9 +282,9 @@ installAllPKCS11(char *dirPath, char *se
-
- myPath=PINST_FULLPATH(tempPath,path);
- if (tail) {
-- installAllPKCS11(myPath, tail, NULL, type, module);
-+ installAllPKCS11(myPath, dbType, tail, NULL, type, module);
- } else {
-- installPKCS11(myPath, type, module);
-+ installPKCS11(myPath, dbType, type, module);
- }
- } while (PINST_NEXT(iter, fileData));
- free(tempPath);
-@@ -309,6 +309,7 @@ int main(int argc, char **argv)
- int i;
- InstType type = Install;
- char * path = NULL;
-+ char *dbType = "";
- #ifdef WIN32
- BOOL brc;
- HKEY regKey;
-@@ -333,6 +334,12 @@ int main(int argc, char **argv)
- case 'v':
- verbose = 1;
- break;
-+ case 'l':
-+ dbType = "dbm:";
-+ break;
-+ case 's':
-+ dbType = "sql:";
-+ break;
- case 'p':
- path = *argv++;
- if (path == NULL) {
-@@ -359,7 +366,7 @@ int main(int argc, char **argv)
- }
-
- if (path) {
-- installAllPKCS11(path, "", NULL, type, module);
-+ installAllPKCS11(path, dbType, "", NULL, type, module);
- return 0;
- }
-
-@@ -444,7 +451,7 @@ int main(int argc, char **argv)
- if (!dirPath) {
- continue;
- }
-- installAllPKCS11(dirPath, dirList[i].search, dirList[i].tail,
-+ installAllPKCS11(dirPath, dbType, dirList[i].search, dirList[i].tail,
- type, module);
- }
-
-diff -up ./src/libckyapplet/cky_applet.c.coolkey-update ./src/libckyapplet/cky_applet.c
---- ./src/libckyapplet/cky_applet.c.coolkey-update 2016-01-19 18:01:32.031909257 -0800
-+++ ./src/libckyapplet/cky_applet.c 2016-01-19 18:01:45.612797732 -0800
-@@ -19,6 +19,7 @@
-
- #include <stdio.h>
- #include "cky_applet.h"
-+#include <string.h>
-
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
-
-@@ -51,6 +52,12 @@ CACAppletFactory_SelectFile(CKYAPDU *apd
- }
-
- CKYStatus
-+P15AppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectFile(apdu, 0, 0, (const CKYBuffer *)param);
-+}
-+
-+CKYStatus
- CKYAppletFactory_SelectCardManager(CKYAPDU *apdu, const void *param)
- {
- return CKYAPDUFactory_SelectCardManager(apdu);
-@@ -103,6 +110,22 @@ CKYAppletFactory_ComputeCryptOneStep(CKY
- }
-
- CKYStatus
-+CKYAppletFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgComputeECCSignature *ccs=(const CKYAppletArgComputeECCSignature *)param;
-+ return CKYAPDUFactory_ComputeECCSignatureOneStep(apdu, ccs->keyNumber,
-+ ccs->location, ccs->data, ccs->sig);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, const void *param)
-+{
-+
-+ const CKYAppletArgComputeECCKeyAgreement *ccs=(const CKYAppletArgComputeECCKeyAgreement *)param;
-+ return CKYAPDUFactory_ComputeECCKeyAgreementOneStep(apdu, ccs->keyNumber, ccs->location, ccs->publicValue, ccs->secretKey);
-+}
-+
-+CKYStatus
- CKYAppletFactory_CreatePIN(CKYAPDU *apdu, const void *param)
- {
- const CKYAppletArgCreatePIN *cps = (const CKYAppletArgCreatePIN *)param;
-@@ -245,10 +268,18 @@ CACAppletFactory_SignDecryptFinal(CKYAPD
- }
-
- CKYStatus
--CACAppletFactory_VerifyPIN(CKYAPDU *apdu, const void *param)
-+PIVAppletFactory_SignDecrypt(CKYAPDU *apdu, const void *param)
-+{
-+ const PIVAppletArgSignDecrypt *psd = (const PIVAppletArgSignDecrypt *)param;
-+ return PIVAPDUFactory_SignDecrypt(apdu, psd->chain, psd->alg, psd->key,
-+ psd->len, psd->buf);
-+}
-+
-+CKYStatus
-+P15AppletFactory_VerifyPIN(CKYAPDU *apdu, const void *param)
- {
-- const char *pin=(const char *)param;
-- return CACAPDUFactory_VerifyPIN(apdu, pin);
-+ const P15AppletArgVerifyPIN *vps = (const P15AppletArgVerifyPIN *)param;
-+ return P15APDUFactory_VerifyPIN(apdu, vps->pinRef, vps->pinVal);
- }
-
- CKYStatus
-@@ -259,6 +290,13 @@ CACAppletFactory_GetCertificate(CKYAPDU
- }
-
- CKYStatus
-+PIVAppletFactory_GetCertificate(CKYAPDU *apdu, const void *param)
-+{
-+ CKYBuffer *tag =(CKYBuffer*)param;
-+ return PIVAPDUFactory_GetData(apdu, tag, 0);
-+}
-+
-+CKYStatus
- CACAppletFactory_ReadFile(CKYAPDU *apdu, const void *param)
- {
- const CACAppletArgReadFile *rfs = (const CACAppletArgReadFile *)param;
-@@ -285,6 +323,39 @@ CKYAppletFactory_LogoutAllV0(CKYAPDU *ap
- return CKYAPDU_SetSendData(apdu, data, sizeof(data));
- }
-
-+CKYStatus
-+P15AppletFactory_ReadRecord(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgReadRecord *rrs = (const P15AppletArgReadRecord *)param;
-+ return P15APDUFactory_ReadRecord(apdu, rrs->record,
-+ rrs->short_ef, rrs->flags, rrs->size);
-+}
-+
-+CKYStatus
-+P15AppletFactory_ReadBinary(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgReadBinary *res = (const P15AppletArgReadBinary *)param;
-+ return P15APDUFactory_ReadBinary(apdu, res->offset,
-+ res->short_ef, res->flags, res->size);
-+}
-+
-+CKYStatus
-+P15AppletFactory_ManageSecurityEnvironment(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgManageSecurityEnvironment *mse =
-+ (const P15AppletArgManageSecurityEnvironment *)param;
-+ return P15APDUFactory_ManageSecurityEnvironment(apdu, mse->p1,
-+ mse->p2, mse->keyRef);
-+}
-+
-+CKYStatus
-+P15AppletFactory_PerformSecurityOperation(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgPerformSecurityOperation *pso =
-+ (const P15AppletArgPerformSecurityOperation *)param;
-+ return P15APDUFactory_PerformSecurityOperation(apdu, pso->dir, pso->chain,
-+ pso->retLen, pso->data);
-+}
- /*****************************************************************
- *
- * Generic Fill routines used by several calls in common
-@@ -325,6 +396,7 @@ CKYAppletFill_AppendBuffer(const CKYBuff
- CKYBuffer_Size(response) -2);
- }
-
-+
- CKYStatus
- CKYAppletFill_Byte(const CKYBuffer *response, CKYSize size, void *param)
- {
-@@ -725,6 +797,32 @@ CKYApplet_ComputeCryptProcess(CKYCardCon
- &ccd, nonce, 0, CKYAppletFill_Null, NULL, apduRC);
- }
-
-+/* computeECCValue returns data in the form :
-+ * len: short
-+ * data: byte[len]
-+ * This fill routine returns A buffer with a copy of data and a length of len */
-+static CKYStatus
-+ckyAppletFill_ComputeECCValueFinal(const CKYBuffer *response,
-+ CKYSize size, void *param)
-+{
-+ CKYBuffer *cbuf = (CKYBuffer *)param;
-+ CKYSize respSize = CKYBuffer_Size(response);
-+ CKYSize dataLen;
-+
-+ if (cbuf == 0) {
-+ return CKYSUCCESS; /* app didn't want the result */
-+ }
-+ /* data response code + length code */
-+ if (respSize < 4) {
-+ return CKYAPDUFAIL;
-+ }
-+ dataLen = CKYBuffer_GetShort(response, 0);
-+ if (dataLen > (respSize-4)) {
-+ return CKYAPDUFAIL;
-+ }
-+ return CKYBuffer_Replace(cbuf, 0, CKYBuffer_Data(response)+2, dataLen);
-+}
-+
- /* computeCrypt returns data in the form :
- * len: short
- * data: byte[len]
-@@ -872,6 +970,74 @@ fail:
- return ret;
- }
-
-+CKYStatus
-+CKYApplet_ComputeECCKeyAgreement(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *publicValue, CKYBuffer *sharedSecret,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret = CKYAPDUFAIL;
-+ CKYAppletArgComputeECCKeyAgreement ccd;
-+ CKYBuffer empty;
-+ CKYISOStatus status;
-+ /* Routine creates a sym key, should easily fit in one apdu */
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ ccd.keyNumber = keyNumber;
-+ ccd.location = CKY_DL_APDU;
-+
-+ if (!apduRC)
-+ apduRC = &status;
-+
-+ if (ccd.location == CKY_DL_APDU) {
-+ ccd.publicValue = publicValue;
-+ ccd.secretKey = sharedSecret;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeECCKeyAgreementOneStep, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeECCValueFinal,
-+ result, apduRC);
-+ if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
-+ return ret;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYApplet_ComputeECCSignature(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret = CKYAPDUFAIL;
-+ CKYAppletArgComputeECCSignature ccd;
-+ CKYBuffer empty;
-+ CKYISOStatus status;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ ccd.keyNumber = keyNumber;
-+
-+ /* Assume APDU, the signature can only get so big with our key sizes, ~ 130 for 521 bit key. */
-+ ccd.location = CKY_DL_APDU;
-+
-+ if (!apduRC)
-+ apduRC = &status;
-+
-+ if (ccd.location == CKY_DL_APDU) {
-+ ccd.data = data;
-+ ccd.sig = sig;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeECCSignatureOneStep, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeECCValueFinal,
-+ result, apduRC);
-+ if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
-+ return ret;
-+ }
-+
-+ }
-+
-+ return ret;
-+}
-+
- /*
- * do a CAC Sign/Decrypt
- */
-@@ -916,32 +1082,23 @@ done:
- return ret;
- }
-
-+const P15PinInfo CACPinInfo =
-+ { P15PinInitialized|P15PinNeedsPadding, P15PinUTF8, 0, 8, 8, 0, 0xff };
-+const P15PinInfo PIVPinInfo =
-+ { P15PinLocal|P15PinInitialized|P15PinNeedsPadding,
-+ P15PinUTF8, 0, 8, 8, 0, 0xff };
- /*
- * do a CAC VerifyPIN
- */
- CKYStatus
--CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin, int local,
- CKYISOStatus *apduRC)
- {
-- CKYStatus ret;
-- CKYISOStatus status;
-- if (apduRC == NULL) {
-- apduRC = &status;
-- }
--
-- ret = CKYApplet_HandleAPDU(conn,
-- CACAppletFactory_VerifyPIN, pin, NULL,
-- 0, CKYAppletFill_Null,
-- NULL, apduRC);
-- /* it's unfortunate that the same code that means 'more data to follow' for
-- * GetCertificate also means, auth failure, you only have N more attempts
-- * left in the verify PIN call */
-- if ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-- ret = CKYAPDUFAIL;
-- }
-- return ret;
-+ return P15Applet_VerifyPIN(conn, pin,
-+ local ? &PIVPinInfo: &CACPinInfo, apduRC);
- }
-
-+
- /*
- * Get a CAC Certificate
- */
-@@ -1028,6 +1185,217 @@ CACApplet_ReadFile(CKYCardConnection *co
- return ret;
- }
-
-+/*
-+ * Select a EF
-+ */
-+CKYStatus
-+P15Applet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShort(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, P15AppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15Applet_SelectRootFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShort(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15Applet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ const P15PinInfo *pinInfo, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYSize size;
-+ CKYBuffer encodedPin;
-+ P15AppletArgVerifyPIN vps;
-+
-+ CKYBuffer_InitEmpty(&encodedPin);
-+
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+
-+ size = strlen(pin);
-+ if (pinInfo->pinFlags & P15PinNeedsPadding) {
-+ if (size > pinInfo->storedLength) {
-+ size = pinInfo->storedLength;
-+ }
-+ ret=CKYBuffer_Reserve(&encodedPin, pinInfo->storedLength);
-+ if (ret != CKYSUCCESS) { goto fail; }
-+ }
-+ /* This is where we would do upcase processing for the case insensitive
-+ * flag. It's also where we would do mapping for bcd pins */
-+ ret = CKYBuffer_Replace(&encodedPin, 0, (const CKYByte *)pin, size);
-+ if (ret != CKYSUCCESS) { goto fail; }
-+ if (pinInfo->pinFlags & P15PinNeedsPadding) {
-+ int i;
-+ int padSize = pinInfo->storedLength - size;
-+ for (i=0; i < padSize; i++) {
-+ CKYBuffer_AppendChar(&encodedPin, pinInfo->padChar);
-+ }
-+ }
-+
-+ vps.pinRef = pinInfo->pinRef |
-+ ((pinInfo->pinFlags & P15PinLocal) ? ISO_LOGIN_LOCAL : ISO_LOGIN_GLOBAL);
-+ vps.pinVal = &encodedPin;
-+ ret = CKYApplet_HandleAPDU(conn, P15AppletFactory_VerifyPIN, &vps, NULL,
-+ 0, CKYAppletFill_Null,
-+ NULL, apduRC);
-+ /* it's unfortunate that the same code that means 'more data to follow' for
-+ * GetCertificate also means, auth failure, you only have N more attempts
-+ * left in the verify PIN call */
-+ if ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-+ ret = CKYAPDUFAIL;
-+ }
-+fail:
-+ CKYBuffer_FreeData(&encodedPin);
-+ return ret;
-+}
-+
-+
-+/*
-+ * Read Record
-+ */
-+CKYStatus
-+P15Applet_ReadRecord(CKYCardConnection *conn, CKYByte record, CKYByte short_ef,
-+ CKYByte flags, CKYByte size, CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ P15AppletArgReadRecord rrd;
-+
-+ rrd.record = record;
-+ rrd.short_ef = short_ef;
-+ rrd.flags = flags;
-+ rrd.size = size;
-+ return CKYApplet_HandleAPDU(conn, P15AppletFactory_ReadRecord, &rrd, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_ReplaceBuffer, data, apduRC);
-+}
-+
-+static CKYStatus
-+P15Applet_ManageSecurityEnvironment(CKYCardConnection *conn, CKYByte key,
-+ CKYByte direction, CKYByte p1,
-+ CKYISOStatus *apduRC)
-+{
-+ P15AppletArgManageSecurityEnvironment mse;
-+
-+ mse.p1 = p1; /* this appears to be where most cards disagree */
-+ mse.p2 = (direction == CKY_DIR_DECRYPT) ? ISO_MSE_KEA : ISO_MSE_SIGN;
-+ mse.keyRef = key; /* should be CKYBuffer in the future? */
-+ return CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_ManageSecurityEnvironment, &mse, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+P15Applet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, CKYByte direction,
-+ const CKYBuffer *data, CKYBuffer *result, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ P15AppletArgPerformSecurityOperation pso;
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+ int length = dataSize;
-+ int appendLength = length;
-+ int hasPad = 0;
-+
-+ /* Hack, lie and say we are always doing encipherment */
-+ direction = CKY_DIR_DECRYPT;
-+ CKYBuffer_Resize(result,0);
-+ /*
-+ * first set the security environment
-+ */
-+ ret = P15Applet_ManageSecurityEnvironment(conn, key, direction,
-+ ISO_MSE_SET|ISO_MSE_QUAL_COMPUTE, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+
-+ pso.data = &tmp;
-+ pso.dir = direction;
-+ if (direction == CKY_DIR_DECRYPT) {
-+ length++;
-+ CKYBuffer_AppendChar(&tmp, 0x00); /* pad byte */
-+ hasPad = 1;
-+ }
-+ if (CKYCardConnection_GetProtocol(conn) == SCARD_PROTOCOL_T0) {
-+ ret = CKYBuffer_Reserve(&tmp, CKY_MAX_WRITE_CHUNK_SIZE);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ for(offset = 0; length > CKY_MAX_WRITE_CHUNK_SIZE;
-+ hasPad = 0,
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE,
-+ length -= CKY_MAX_WRITE_CHUNK_SIZE) {
-+ pso.chain = 1;
-+ pso.retLen = 0;
-+ CKYBuffer_AppendBuffer(&tmp, data, offset,
-+ hasPad ? (CKY_MAX_WRITE_CHUNK_SIZE-1) : CKY_MAX_WRITE_CHUNK_SIZE);
-+ ret = CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_PerformSecurityOperation, &pso, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_Resize(&tmp, 0);
-+ }
-+ appendLength = length;
-+ } else {
-+ ret = CKYBuffer_Reserve(&tmp, length);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ }
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, appendLength);
-+ pso.chain = 0;
-+ pso.retLen = dataSize;
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_PerformSecurityOperation, &pso, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_ReplaceBuffer, result, apduRC);
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
-+ return ret;
-+}
-+
-+/*
-+ * Read Binary
-+ */
-+CKYStatus
-+P15Applet_ReadBinary(CKYCardConnection *conn, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte size,
-+ CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ P15AppletArgReadBinary red;
-+
-+ red.offset = offset;
-+ red.short_ef = short_ef;
-+ red.flags = flags;
-+ red.size = size;
-+ return CKYApplet_HandleAPDU(conn, P15AppletFactory_ReadBinary, &red, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, data, apduRC);
-+}
-+
- CKYStatus
- CACApplet_GetCertificateFirst(CKYCardConnection *conn, CKYBuffer *cert,
- CKYSize *nextSize, CKYISOStatus *apduRC)
-@@ -1078,6 +1446,278 @@ CACApplet_GetCertificateAppend(CKYCardCo
- return ret;
- }
-
-+/* Select the PIV applet */
-+static CKYByte pivAid[] = {0xa0, 0x00, 0x00, 0x03, 0x08, 0x00, 0x00,
-+ 0x10, 0x00};
-+CKYStatus
-+PIVApplet_Select(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer PIV_Applet_AID,return_AID;
-+
-+ CKYBuffer_InitEmpty(&return_AID);
-+ CKYBuffer_InitFromData(&PIV_Applet_AID, pivAid, sizeof(pivAid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile,
-+ &PIV_Applet_AID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer,
-+ &return_AID, apduRC);
-+ /* Some cards return OK, but don't switch to our applet */
-+ /* PIV has a well defined return for it's select, check to see if we have
-+ * a PIV card here */
-+ if (CKYBuffer_GetChar(&return_AID,0) != 0x61) {
-+ /* not an application property template, so not a PIV. We could
-+ * check that the aid tag (0x4f) and theallocation authority tag (0x79)
-+ * are present, but what we are really avoiding is broken cards that
-+ * lie about being able to switch to a particular applet, so the first
-+ * tag should be sufficient */
-+ ret = CKYAPDUFAIL; /* what we should have gotten */
-+ }
-+ CKYBuffer_FreeData(&PIV_Applet_AID);
-+ CKYBuffer_FreeData(&return_AID);
-+ return ret;
-+}
-+
-+/*
-+ * Get a PIV Certificate
-+ */
-+CKYStatus
-+PIVApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert, int tag,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYBuffer tagBuf;
-+
-+ CKYBuffer_InitEmpty(&tagBuf);
-+ CKYBuffer_Reserve(&tagBuf,4); /* can be up to 4 bytes */
-+
-+ CKYBuffer_Resize(cert,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+ if (tag >= 0x01000000) {
-+ ret = CKYBuffer_AppendChar(&tagBuf, (tag >> 24) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ if (tag >= 0x010000) {
-+ ret = CKYBuffer_AppendChar(&tagBuf, (tag >> 16) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ if (tag >= 0x0100) {
-+ ret =CKYBuffer_AppendChar(&tagBuf, (tag >> 8) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ ret = CKYBuffer_AppendChar(&tagBuf, tag & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ PIVAppletFactory_GetCertificate, &tagBuf, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+loser:
-+ CKYBuffer_FreeData(&tagBuf);
-+
-+ return ret;
-+}
-+
-+
-+/*
-+ * record the next ber tag and length. NOTE: this is a state machine.
-+ * we can handle the case where we are passed the data just one byte
-+ * at a time.
-+ */
-+static CKYStatus
-+pivUnwrap(const CKYBuffer *buf, CKYOffset *offset,
-+ CKYSize *dataSize, PIVUnwrapState *unwrap)
-+{
-+ if (unwrap->tag == 0) {
-+ unwrap->tag = CKYBuffer_GetChar(buf, *offset);
-+ if (unwrap->tag == 0) unwrap->tag = 0xff;
-+ (*offset)++;
-+ (*dataSize)--;
-+ }
-+ if (*dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ if (unwrap->length_bytes != 0) {
-+ int len;
-+ if (unwrap->length_bytes == -1) {
-+ len = CKYBuffer_GetChar(buf, *offset);
-+ unwrap->length_bytes = 0;
-+ unwrap->length = len;
-+ (*offset)++;
-+ (*dataSize)--;
-+ if (len & 0x80) {
-+ unwrap->length = 0;
-+ unwrap->length_bytes = len & 0x7f;
-+ }
-+ }
-+ while ((*dataSize != 0) && (unwrap->length_bytes != 0)) {
-+ len = CKYBuffer_GetChar(buf, *offset);
-+ (*offset) ++;
-+ (*dataSize) --;
-+ unwrap->length = ((unwrap->length) << 8 | len);
-+ unwrap->length_bytes--;
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+/*
-+ * Remove the BER wrapping first...
-+ */
-+static CKYStatus
-+pivAppletFill_AppendUnwrapBuffer(const CKYBuffer *response,
-+ CKYSize size, void *param)
-+{
-+ PIVAppletRespSignDecrypt *prsd = (PIVAppletRespSignDecrypt *)param;
-+ CKYBuffer *buf = prsd->buf;
-+ CKYSize dataSize = CKYBuffer_Size(response);
-+ CKYOffset offset = 0;
-+
-+ if (dataSize <= 2) {
-+ return CKYSUCCESS;
-+ }
-+ dataSize -= 2;
-+ /* remove the first tag */
-+ (void) pivUnwrap(response, &offset, &dataSize, &prsd->tag_1);
-+ if (dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ /* remove the second tag */
-+ (void) pivUnwrap(response, &offset, &dataSize, &prsd->tag_2);
-+ if (dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ /* the rest is real data */
-+ return CKYBuffer_AppendData(buf, CKYBuffer_Data(response) + offset,
-+ dataSize);
-+}
-+
-+static CKYStatus
-+piv_wrapEncodeLength(CKYBuffer *buf, int length, int ber_len)
-+{
-+ if (ber_len== 1) {
-+ CKYBuffer_AppendChar(buf,length);
-+ } else {
-+ ber_len--;
-+ CKYBuffer_AppendChar(buf,0x80+ber_len);
-+ while(ber_len--) {
-+ CKYBuffer_AppendChar(buf,(length >> (8*ber_len)) & 0xff);
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+/*
-+ * do a PIV Sign/Decrypt
-+ */
-+CKYStatus
-+PIVApplet_SignDecrypt(CKYCardConnection *conn, CKYByte key, unsigned int keySize, int derive,
-+ const CKYBuffer *data, CKYBuffer *result, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYSize outputSize = keySize;
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+ CKYByte alg;
-+ int ber_len_1;
-+ int ber_len_2;
-+ int length;
-+ PIVAppletArgSignDecrypt pasd;
-+ PIVAppletRespSignDecrypt prsd;
-+
-+ /* PIV only defines RSA 1024 and 2048, ECC 256 and ECC 384!!! */
-+ if (keySize == 128) { /* 1024 bit == 128 bytes */
-+ ber_len_2 = 2;
-+ ber_len_1 = 2;
-+ alg = 0x6;
-+ } else if (keySize == 256) { /* 2048 bits == 256 bytes */
-+ ber_len_2 = 3;
-+ ber_len_1 = 3;
-+ alg = 0x7;
-+ } else if (keySize == 32) { /* 256 bits = 32 bytes */
-+ ber_len_2 = 1;
-+ ber_len_1 = 1;
-+ alg = 0x11;
-+ if (!derive) outputSize = keySize*2;
-+ } else if (keySize == 48) { /* 384 bits = 48 bytes */
-+ ber_len_2 = 1;
-+ ber_len_1 = 1;
-+ alg = 0x14;
-+ if (!derive) outputSize = keySize*2;
-+ } else {
-+ return CKYINVALIDARGS;
-+ }
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+ ret = CKYBuffer_Reserve(&tmp, CKY_MAX_WRITE_CHUNK_SIZE);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_AppendChar(&tmp,0x7c);
-+ piv_wrapEncodeLength(&tmp,dataSize + ber_len_2 + 3,ber_len_1);
-+ CKYBuffer_AppendChar(&tmp,0x82);
-+ CKYBuffer_AppendChar(&tmp,0x0);
-+ CKYBuffer_AppendChar(&tmp, derive ? 0x85 : 0x81);
-+ piv_wrapEncodeLength(&tmp,dataSize,ber_len_2);
-+
-+ /* now length == header length from here to the end*/
-+ length = CKYBuffer_Size(&tmp);
-+
-+ if (length + dataSize > CKY_MAX_WRITE_CHUNK_SIZE) {
-+ CKYBuffer_AppendBuffer(&tmp, data, 0, CKY_MAX_WRITE_CHUNK_SIZE-length);
-+ } else {
-+ CKYBuffer_AppendBuffer(&tmp, data, 0, dataSize);
-+ }
-+
-+ prsd.tag_1.tag = 0;
-+ prsd.tag_1.length_bytes = -1;
-+ prsd.tag_1.length = 0;
-+ prsd.tag_2.tag = 0;
-+ prsd.tag_2.length_bytes = -1;
-+ prsd.tag_2.length = 0;
-+ prsd.buf = result;
-+ pasd.alg = alg;
-+ pasd.key = key;
-+ pasd.buf = &tmp;
-+
-+ CKYBuffer_Resize(result,0);
-+ for(offset = -length; (dataSize-offset) > CKY_MAX_WRITE_CHUNK_SIZE; ) {
-+ pasd.chain = 1;
-+ pasd.len = 0;
-+ ret = CKYApplet_HandleAPDU(conn, PIVAppletFactory_SignDecrypt,
-+ &pasd, NULL, CKY_SIZE_UNKNOWN,
-+ pivAppletFill_AppendUnwrapBuffer,
-+ &prsd, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_Resize(&tmp,0);
-+ /* increment before we append the next tmp buffer */
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE;
-+ CKYBuffer_AppendBuffer(&tmp, data, offset,
-+ MIN(dataSize-offset, CKY_MAX_WRITE_CHUNK_SIZE));
-+ }
-+
-+ pasd.chain = 0;
-+ pasd.len = outputSize;
-+
-+ ret = CKYApplet_HandleAPDU(conn, PIVAppletFactory_SignDecrypt,
-+ &pasd, NULL, CKY_SIZE_UNKNOWN,
-+ pivAppletFill_AppendUnwrapBuffer,
-+ &prsd, apduRC);
-+
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(result) != outputSize)) {
-+ /* RSA returns the same data size as input, didn't happen, so
-+ * something is wrong. */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
-+ return ret;
-+}
-
- /*
- * PIN cluster
-@@ -1223,6 +1863,7 @@ CKYApplet_ReadObjectFull(CKYCardConnecti
- return ret;
- }
-
-+
- /*
- * Write Object
- * This makes multiple APDU calls to write the entire object.
-diff -up ./src/libckyapplet/cky_applet.h.coolkey-update ./src/libckyapplet/cky_applet.h
---- ./src/libckyapplet/cky_applet.h.coolkey-update 2016-01-19 18:02:04.200645090 -0800
-+++ ./src/libckyapplet/cky_applet.h 2016-01-19 18:02:11.013589143 -0800
-@@ -43,6 +43,8 @@ typedef unsigned short CKYISOStatus; /*
- #define CKYISO_MORE_MASK 0xff00 /* More data mask */
- #define CKYISO_MORE 0x6300 /* More data available */
- #define CKYISO_DATA_INVALID 0x6984
-+#define CKYISO_CONDITION_NOT_SATISFIED 0x6985 /* AKA not logged in (CAC)*/
-+#define CKYISO_SECURITY_NOT_SATISFIED 0x6982 /* AKA not logged in (PIV)*/
- /* Applet Defined Return codes */
- #define CKYISO_NO_MEMORY_LEFT 0x9c01 /* There have been memory
- * problems on the card */
-@@ -78,6 +80,7 @@ typedef unsigned short CKYISOStatus; /*
-
- #define CAC_TAG_CARDURL 0xf3
- #define CAC_TAG_CERTIFICATE 0x70
-+#define CAC_TAG_CERTINFO 0x71
- #define CAC_TLV_APP_PKI 0x04
-
- /*
-@@ -201,6 +204,7 @@ typedef struct _CKYAppletArgReadObject {
- CKYByte size;
- } CKYAppletArgReadObject;
-
-+
- typedef struct _CKYAppletArgWriteObject {
- unsigned long objectID;
- CKYOffset offset;
-@@ -218,12 +222,80 @@ typedef struct _CKYAppletArgComputeCrypt
- const CKYBuffer *sig;
- } CKYAppletArgComputeCrypt;
-
-+typedef struct _CKYAppletArgComputeECCSignature {
-+ CKYByte keyNumber;
-+ CKYByte location;
-+ const CKYBuffer *data;
-+ const CKYBuffer *sig;
-+} CKYAppletArgComputeECCSignature;
-+
-+typedef struct _CKYAppletArgComputeECCKeyAgreement {
-+ CKYByte keyNumber;
-+ CKYByte location;
-+ const CKYBuffer *publicValue;
-+ const CKYBuffer *secretKey;
-+} CKYAppletArgComputeECCKeyAgreement;
-+
-+
- typedef struct _CACAppletArgReadFile {
- CKYByte type;
- CKYByte count;
- unsigned short offset;
- } CACAppletArgReadFile;
-
-+typedef struct _PIVAppletArgSignDecrypt {
-+ CKYByte alg;
-+ CKYByte key;
-+ CKYByte chain;
-+ CKYSize len;
-+ CKYBuffer *buf;
-+} PIVAppletArgSignDecrypt;
-+
-+typedef struct _pivUnwrapState {
-+ CKYByte tag;
-+ CKYByte length;
-+ int length_bytes;
-+} PIVUnwrapState;
-+
-+typedef struct _PIVAppletRespSignDecrypt {
-+ PIVUnwrapState tag_1;
-+ PIVUnwrapState tag_2;
-+ CKYBuffer *buf;
-+} PIVAppletRespSignDecrypt;
-+
-+typedef struct _P15AppletArgReadRecord {
-+ CKYByte record;
-+ CKYByte short_ef;
-+ CKYByte flags;
-+ CKYByte size;
-+} P15AppletArgReadRecord;
-+
-+typedef struct _P15AppletArgReadBinary {
-+ unsigned short offset;
-+ CKYByte short_ef;
-+ CKYByte flags;
-+ CKYByte size;
-+} P15AppletArgReadBinary;
-+
-+typedef struct _P15AppletArgVerifyPIN {
-+ const CKYBuffer *pinVal;
-+ CKYByte pinRef;
-+} P15AppletArgVerifyPIN;
-+
-+typedef struct _P15AppletArgManageSecurityEnvironment {
-+ CKYByte p1;
-+ CKYByte p2;
-+ CKYByte keyRef;
-+}
-+ P15AppletArgManageSecurityEnvironment;
-+
-+typedef struct _P15AppletArgPerformSecurityOperation {
-+ CKYByte dir;
-+ int chain;
-+ CKYSize retLen;
-+ const CKYBuffer *data;
-+} P15AppletArgPerformSecurityOperation;
-+
- /* fills in an APDU from a structure -- form of all the generic factories*/
- typedef CKYStatus (*CKYAppletFactory)(CKYAPDU *apdu, const void *param);
- /* fills in an a structure from a response -- form of all the fill structures*/
-@@ -335,7 +407,6 @@ CKYStatus CKYAppletFill_AppendBuffer(con
- /* Single value fills: Byte, Short, & Long */
- /* param == CKYByte * */
- CKYStatus CKYAppletFill_Byte(const CKYBuffer *response, CKYSize size, void *param);
--/* param == CKYByte * */
- CKYStatus CKYAppletFill_Short(const CKYBuffer *response, CKYSize size, void *param);
- CKYStatus CKYAppletFill_Long(const CKYBuffer *response, CKYSize size, void *param);
-
-@@ -361,7 +432,7 @@ CKYBool CKYApplet_VerifyResponse(const C
- * Sends the ADPU to the card through the connection conn.
- * Checks that the response was valid (returning the responce code in apduRC.
- * Formats the response data into fillArg with fillFunc
-- * nonce and apduRC can be NULL (no nonce is added, not status returned
-+ * nonce and apduRC can be NULL (no nonce is added, no status returned
- * legal values for afArg are depened on afFunc.
- * legal values for fillArg are depened on fillFunc.
- */
-@@ -377,7 +448,7 @@ CKYStatus CKYApplet_HandleAPDU(CKYCardCo
- * into function calls, with input and output parameters.
- * The application is still responsible for
- * 1) creating a connection to the card,
-- * 2) Getting a tranaction long, then
-+ * 2) Getting a transaction lock, then
- * 3) selecting the appropriate applet (or Card manager).
- * Except for those calls that have been noted, the appropriate applet
- * is the CoolKey applet.
-@@ -477,6 +548,7 @@ CKYStatus CACApplet_ReadFile(CKYCardConn
- CKYStatus CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
- CKYISOStatus *apduRC);
-
-+
- /* must happen with PKI applet selected */
- CKYStatus CACApplet_SignDecrypt(CKYCardConnection *conn, const CKYBuffer *data,
- CKYBuffer *result, CKYISOStatus *apduRC);
-@@ -490,8 +562,37 @@ CKYStatus CACApplet_GetCertificateAppend
- CKYISOStatus *apduRC);
-
- /*CKYStatus CACApplet_GetProperties(); */
--CKYStatus CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-- CKYISOStatus *apduRC);
-+CKYStatus CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ int local, CKYISOStatus *apduRC);
-+
-+/* Select a PIV applet */
-+CKYStatus PIVApplet_Select(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+
-+CKYStatus PIVApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert,
-+ int tag, CKYISOStatus *apduRC);
-+CKYStatus PIVApplet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, int derive,
-+ const CKYBuffer *data, CKYBuffer *result,
-+ CKYISOStatus *apduRC);
-+
-+/* PKCS Commands 15 */
-+CKYStatus P15Applet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_SelectRootFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_ReadRecord(CKYCardConnection *conn, CKYByte record,
-+ CKYByte short_ef, CKYByte flags, CKYByte size, CKYBuffer *data,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_ReadBinary(CKYCardConnection *conn, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte size, CKYBuffer *data,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ const P15PinInfo *pinInfo, CKYISOStatus *apduRC);
-+
-+CKYStatus P15Applet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, CKYByte direction,
-+ const CKYBuffer *data, CKYBuffer *result,
-+ CKYISOStatus *apduRC);
-
- /*
- * There are 3 read commands:
-@@ -553,6 +654,18 @@ CKYStatus CKYApplet_GetIssuerInfo(CKYCar
- CKYStatus CKYApplet_GetBuiltinACL(CKYCardConnection *conn,
- CKYAppletRespGetBuiltinACL *gba, CKYISOStatus *apduRC);
-
-+/** ECC commands
-+ * * */
-+
-+CKYStatus CKYApplet_ComputeECCSignature(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+
-+CKYStatus
-+CKYApplet_ComputeECCKeyAgreement(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *publicValue, CKYBuffer *sharedSecret,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+
-
- /*
- * deprecates 0.x functions
-diff -up ./src/libckyapplet/cky_base.c.coolkey-update ./src/libckyapplet/cky_base.c
---- ./src/libckyapplet/cky_base.c.coolkey-update 2016-01-19 18:02:38.270365312 -0800
-+++ ./src/libckyapplet/cky_base.c 2016-01-19 18:02:51.042260431 -0800
-@@ -41,6 +41,7 @@ ckyBuffer_initBuffer(CKYBuffer *buf)
- buf->data = NULL;
- buf->size = 0;
- buf->len = 0;
-+ buf->reserved = NULL; /* make coverity happy */
- }
-
- /*
-@@ -573,6 +574,7 @@ CKYAPDU_Init(CKYAPDU *apdu)
- assert(sizeof(CKYAPDU) == sizeof(CKYAPDUPublic));
- #endif
- ckyBuffer_initBuffer(&apdu->apduBuf);
-+ apdu->reserved = NULL;
- return CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_MIN_LEN);
- }
-
-@@ -583,6 +585,7 @@ CKYAPDU_InitFromData(CKYAPDU *apdu, cons
- assert(sizeof(CKYAPDU) == sizeof(CKYAPDUPublic));
- #endif
- ckyBuffer_initBuffer(&apdu->apduBuf);
-+ apdu->reserved = NULL;
- if (len > CKYAPDU_MAX_DATA_LEN) {
- return CKYDATATOOLONG;
- }
-@@ -648,21 +651,38 @@ CKYStatus
- CKYAPDU_SetSendData(CKYAPDU *apdu, const CKYByte *data, CKYSize len)
- {
- CKYStatus ret;
-+ CKYOffset offset = 0;
-
-- if (len > CKYAPDU_MAX_DATA_LEN) {
-- return CKYDATATOOLONG;
-- }
-+ /* Encode with T1 if necessary */
-
-- ret = CKYBuffer_Resize(&apdu->apduBuf, len + CKYAPDU_HEADER_LEN);
-- if (ret != CKYSUCCESS) {
-- return ret;
-+ if (len < CKYAPDU_MAX_DATA_LEN) {
-+ offset = 0;
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, len+offset+CKYAPDU_HEADER_LEN);
-+ if (ret != CKYSUCCESS ) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) len);
-+ } else if (len < CKYAPDU_MAX_T1_DATA_LEN) {
-+ offset = 2;
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, len+offset+CKYAPDU_HEADER_LEN);
-+ if (ret != CKYSUCCESS ) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) 0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetShort(&apdu->apduBuf,CKY_LC_OFFSET+1,
-+ (unsigned short)len);
-+ } else {
-+ return CKYDATATOOLONG;
- }
-- ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET,
-- len == CKYAPDU_MAX_DATA_LEN ? 0: (CKYByte) len);
-+
- if (ret != CKYSUCCESS) {
- return ret;
- }
-- return CKYBuffer_Replace(&apdu->apduBuf, CKYAPDU_HEADER_LEN, data, len);
-+ return CKYBuffer_Replace(&apdu->apduBuf,
-+ CKYAPDU_HEADER_LEN + offset , data, len);
- }
-
- CKYStatus
-@@ -682,15 +702,15 @@ CKYAPDU_AppendSendData(CKYAPDU *apdu, co
- }
-
- dataLen = CKYBuffer_Size(&apdu->apduBuf) + len - CKYAPDU_HEADER_LEN;
-- if (dataLen > CKYAPDU_MAX_DATA_LEN) {
-+ /* only handles T0 encoding, not T1 encoding */
-+ if (dataLen >= CKYAPDU_MAX_DATA_LEN) {
- return CKYDATATOOLONG;
- }
- ret = CKYBuffer_AppendData(&apdu->apduBuf, data, len);
- if (ret != CKYSUCCESS) {
- return ret;
- }
-- return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET,
-- dataLen == CKYAPDU_MAX_DATA_LEN ? 0 : (CKYByte) dataLen);
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) dataLen);
- }
-
- CKYStatus
-@@ -710,8 +730,104 @@ CKYAPDU_SetReceiveLen(CKYAPDU *apdu, CKY
- return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LE_OFFSET, recvlen);
- }
-
-+CKYStatus
-+CKYAPDU_SetShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen)
-+{
-+ CKYStatus ret;
-+
-+ if (recvlen <= CKYAPDU_MAX_DATA_LEN) {
-+ return CKYAPDU_SetReceiveLen(apdu, (CKYByte)(recvlen & 0xff));
-+ }
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_HEADER_LEN+2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LE_OFFSET, 0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ return CKYBuffer_SetShort(&apdu->apduBuf, CKY_LE_OFFSET+1, recvlen);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetReceiveLength(CKYAPDU *apdu, CKYSize recvlen)
-+{
-+ if (recvlen <= CKYAPDU_MAX_T1_DATA_LEN) {
-+ return CKYAPDU_SetShortReceiveLen(apdu, (unsigned short)
-+ (recvlen & 0xffff));
-+ }
-+ return CKYDATATOOLONG;
-+}
-+
-+/*
-+ * Append Le, If Le=0, treat it as 256 (CKYAPD_MAX_DATA_LEN)
-+ */
-+CKYStatus
-+CKYAPDU_AppendReceiveLen(CKYAPDU *apdu, CKYByte recvlen)
-+{
-+ /* If we already have a data buffer, make sure that we aren't already
-+ * using T1 encoding */
-+ if (CKYBuffer_Size(&apdu->apduBuf) > CKYAPDU_MIN_LEN) {
-+ if (CKYBuffer_GetChar(&apdu->apduBuf, CKY_LC_OFFSET) == 0) {
-+ /* we are using T1 encoding, use AppendShort*/
-+ return CKYBuffer_AppendShort(&apdu->apduBuf,
-+ recvlen ? (unsigned short) recvlen: CKYAPDU_MAX_DATA_LEN);
-+ }
-+ }
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, recvlen);
-+}
-+
-+/*
-+ * Append a short Le. If Le be encoded with just T0, do so. If Le=0 treat
-+ * it as 65536 (CKYAPDU_MAX_T1_DATA_LEN)
-+ */
-+CKYStatus
-+CKYAPDU_AppendShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen)
-+{
-+ CKYStatus ret;
-+ /* If we already have a data buffer, it's encoding affects ours */
-+ if (CKYBuffer_Size(&apdu->apduBuf) > CKYAPDU_MIN_LEN) {
-+ /* CKY_LC_OFFSET == 0 means T1, otherwise it's T0 */
-+ if (CKYBuffer_GetChar(&apdu->apduBuf, CKY_LC_OFFSET) != 0) {
-+ /* remember 0 is 65536 here */
-+ if ((recvlen == 0) || (recvlen > CKYAPDU_MAX_DATA_LEN)) {
-+ /* we can't a encode T1 receive length if we already have a
-+ * T0 encoded buffer data */
-+ return CKYDATATOOLONG;
-+ }
-+ /* T0 encoding */
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)recvlen&0xff);
-+ }
-+ /* T1 encoding */
-+ return CKYBuffer_AppendShort(&apdu->apduBuf, recvlen);
-+ }
-+ /* if length fits in a bit and we aren't forced into T1 encoding, use
-+ * T0 */
-+ if ((recvlen != 0) && (recvlen <= CKYAPDU_MAX_DATA_LEN)) {
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)recvlen&0xff);
-+ }
-+ /* write the T1 encoding marker */
-+ ret = CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ /* T1 encoded length */
-+ return CKYBuffer_AppendShort(&apdu->apduBuf, recvlen);
-+}
-+
-+CKYStatus
-+CKYAPDU_AppendReceiveLength(CKYAPDU *apdu, CKYSize recvlen)
-+{
-+ if (recvlen > CKYAPDU_MAX_T1_DATA_LEN) {
-+ return CKYDATATOOLONG;
-+ }
-+ return CKYAPDU_AppendShortReceiveLen(apdu,
-+ (unsigned short)(recvlen & 0xffff));
-+}
-+
-+
- void
--CKY_SetName(char *p)
-+CKY_SetName(const char *p)
- {
- }
-
-diff -up ./src/libckyapplet/cky_base.h.coolkey-update ./src/libckyapplet/cky_base.h
---- ./src/libckyapplet/cky_base.h.coolkey-update 2016-01-19 18:03:10.571100060 -0800
-+++ ./src/libckyapplet/cky_base.h 2016-01-19 18:03:23.866990876 -0800
-@@ -32,6 +32,8 @@ typedef unsigned char CKYByte;
- /* Bool type */
- typedef unsigned char CKYBool;
-
-+typedef unsigned long CKYBitFlags;
-+
- #define CKYBUFFER_PUBLIC \
- unsigned long reserved1;\
- unsigned long reserved2;\
-@@ -93,6 +95,8 @@ typedef enum {
- * (command) sent. ADPUIOStatus has more info on
- * why the APDU failed */
- CKYINVALIDARGS, /* Caller passed in bad args */
-+ CKYINVALIDDATA, /* Data supplied was invalid */
-+ CKYUNSUPPORTED, /* Requested Operation or feature is not supported */
- } CKYStatus;
-
- /*
-@@ -107,12 +111,56 @@ typedef enum {
- #define CKY_LE_OFFSET 4
-
- #define CKYAPDU_MAX_DATA_LEN 256
-+#define CKYAPDU_MAX_T1_DATA_LEN 65536
- #define CKYAPDU_MIN_LEN 4
- #define CKYAPDU_HEADER_LEN 5
- #define CKYAPDU_MAX_LEN (CKYAPDU_HEADER_LEN+CKYAPDU_MAX_DATA_LEN)
- #define CKY_MAX_ATR_LEN 32
- #define CKY_OUTRAGEOUS_MALLOC_SIZE (1024*1024)
-
-+#define P15FlagsPrivate 0x00000001
-+#define P15FlagsModifiable 0x00000002
-+
-+#define P15UsageEncrypt 0x00000001
-+#define P15UsageDecrypt 0x00000002
-+#define P15UsageSign 0x00000004
-+#define P15UsageSignRecover 0x00000008
-+#define P15UsageWrap 0x00000010
-+#define P15UsageUnwrap 0x00000020
-+#define P15UsageVerify 0x00000040
-+#define P15UsageVerifyRecover 0x00000080
-+#define P15UsageDerive 0x00000100
-+#define P15UsageNonRepudiation 0x00000200
-+
-+#define P15AccessSensitive 0x00000001
-+#define P15AccessExtractable 0x00000002
-+#define P15AccessAlwaysSenstive 0x00000004
-+#define P15AccessNeverExtractable 0x00000008
-+#define P15AccessLocal 0x00000010
-+
-+#define P15PinCaseSensitive 0x00000001
-+#define P15PinLocal 0x00000002
-+#define P15PinChangeDisabled 0x00000004
-+#define P15PinUnblockDisabled 0x00000008
-+#define P15PinInitialized 0x00000010
-+#define P15PinNeedsPadding 0x00000020
-+#define P15PinUnblockingPin 0x00000040
-+#define P15PinSOPin 0x00000080
-+#define P15PinDisableAllowed 0x00000100
-+
-+typedef enum {P15PinBCD=0, P15PinASCIINum=1, P15PinUTF8=2} P15PinType;
-+
-+typedef struct _P15PinInfo {
-+ CKYBitFlags pinFlags;
-+ P15PinType pinType;
-+ CKYByte minLength;
-+ CKYByte storedLength;
-+ unsigned long maxLength;
-+ CKYByte pinRef;
-+ CKYByte padChar;
-+} P15PinInfo;
-+
-+
- /*
- * allow direct inclusion in C++ files
- */
-@@ -278,9 +326,14 @@ CKYStatus CKYAPDU_AppendSendDataBuffer(C
- /* set Le in the APDU header to the amount of bytes expected to be
- * returned. */
- CKYStatus CKYAPDU_SetReceiveLen(CKYAPDU *apdu, CKYByte recvlen);
-+CKYStatus CKYAPDU_SetShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen);
-+CKYStatus CKYAPDU_SetReceiveLength(CKYAPDU *apdu, CKYSize recvlen);
-+CKYStatus CKYAPDU_AppendReceiveLen(CKYAPDU *apdu, CKYByte recvlen);
-+CKYStatus CKYAPDU_AppendShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen);
-+CKYStatus CKYAPDU_AppendReceiveLength(CKYAPDU *apdu, CKYSize recvlen);
-
- /* set the parent loadmodule name */
--void CKY_SetName(char *name);
-+void CKY_SetName(const char *name);
-
- CKY_END_PROTOS
-
-diff -up ./src/libckyapplet/cky_card.c.coolkey-update ./src/libckyapplet/cky_card.c
---- ./src/libckyapplet/cky_card.c.coolkey-update 2016-01-19 18:03:46.210807391 -0800
-+++ ./src/libckyapplet/cky_card.c 2016-01-19 18:03:59.217700579 -0800
-@@ -27,6 +27,7 @@
-
- #ifndef WINAPI
- #define WINAPI
-+typedef SCARD_READERSTATE *LPSCARD_READERSTATE;
- #endif
-
- #ifndef SCARD_E_NO_READERS_AVAILABLE
-@@ -843,6 +844,11 @@ CKYCardContext_WaitForStatusChange(CKYCa
- rv = ctx->scard->SCardGetStatusChange(ctx->context, timeout,
- readers, readerCount);
- if (rv != SCARD_S_SUCCESS) {
-+ if ((rv == SCARD_E_NO_SERVICE) || (rv == SCARD_E_SERVICE_STOPPED)) {
-+ /* if we were stopped, don't reuse the old context,
-+ * pcsc-lite hangs */
-+ ckyCardContext_release(ctx);
-+ }
- ctx->lastError = rv;
- return CKYSCARDERR;
- }
-@@ -904,6 +910,7 @@ ckyCardConnection_init(CKYCardConnection
- conn->protocol = SCARD_PROTOCOL_T0;
- }
-
-+
- CKYCardConnection *
- CKYCardConnection_Create(const CKYCardContext *ctx)
- {
-@@ -978,6 +985,12 @@ CKYCardConnection_IsConnected(const CKYC
- return (conn->cardHandle != 0);
- }
-
-+unsigned long
-+CKYCardConnection_GetProtocol(const CKYCardConnection *conn)
-+{
-+ return conn->protocol;
-+}
-+
- CKYStatus
- ckyCardConnection_reconnectRaw(CKYCardConnection *conn, unsigned long init)
- {
-@@ -990,6 +1003,7 @@ ckyCardConnection_reconnectRaw(CKYCardCo
- conn->lastError = rv;
- return CKYSCARDERR;
- }
-+ conn->protocol = protocol;
- return CKYSUCCESS;
- }
-
-@@ -1071,25 +1085,39 @@ CKYCardConnection_ExchangeAPDU(CKYCardCo
- CKYBuffer *response)
- {
- CKYStatus ret;
-+ CKYBuffer getResponse;
-+ CKYSize size = 0;
-
- ret = CKYCardConnection_TransmitAPDU(conn, apdu, response);
- if (ret != CKYSUCCESS) {
- return ret;
- }
-+ CKYBuffer_InitEmpty(&getResponse);
-
-- if (CKYBuffer_Size(response) == 2 && CKYBuffer_GetChar(response,0) == 0x61) {
-+ /* automatically handle the response data protocol */
-+ while ((ret == CKYSUCCESS) &&
-+ (size = CKYBuffer_Size(response)) >= 2 &&
-+ (CKYBuffer_GetChar(response,size-2) == 0x61)) {
- /* get the response */
- CKYAPDU getResponseAPDU;
-
-+ CKYBuffer_Zero(&getResponse);
- CKYAPDU_Init(&getResponseAPDU);
- CKYAPDU_SetCLA(&getResponseAPDU, 0x00);
- CKYAPDU_SetINS(&getResponseAPDU, 0xc0);
- CKYAPDU_SetP1(&getResponseAPDU, 0x00);
- CKYAPDU_SetP2(&getResponseAPDU, 0x00);
-- CKYAPDU_SetReceiveLen(&getResponseAPDU, CKYBuffer_GetChar(response,1));
-- ret = CKYCardConnection_TransmitAPDU(conn, &getResponseAPDU, response);
-+ CKYAPDU_SetReceiveLen(&getResponseAPDU,
-+ CKYBuffer_GetChar(response,size-1));
-+ ret = CKYCardConnection_TransmitAPDU(conn, &getResponseAPDU,
-+ &getResponse);
- CKYAPDU_FreeData(&getResponseAPDU);
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(&getResponse) >= 2)) {
-+ CKYBuffer_Resize(response, size-2);
-+ CKYBuffer_AppendCopy(response,&getResponse);
-+ }
- }
-+ CKYBuffer_FreeData(&getResponse);
- return ret;
- }
-
-diff -up ./src/libckyapplet/cky_card.h.coolkey-update ./src/libckyapplet/cky_card.h
---- ./src/libckyapplet/cky_card.h.coolkey-update 2016-01-19 18:04:19.315535537 -0800
-+++ ./src/libckyapplet/cky_card.h 2016-01-19 18:04:28.384461063 -0800
-@@ -116,6 +116,7 @@ CKYStatus CKYCardConnection_ExchangeAPDU
- CKYStatus CKYCardConnection_Connect(CKYCardConnection *connection,
- const char *readerName);
- CKYStatus CKYCardConnection_Disconnect(CKYCardConnection *connection);
-+unsigned long CKYCardConnection_GetProtocol(const CKYCardConnection *conn);
- CKYBool CKYCardConnection_IsConnected(const CKYCardConnection *connection);
- CKYStatus CKYCardConnection_Reconnect(CKYCardConnection *connection);
- CKYStatus CKYCardConnection_GetStatus(CKYCardConnection *connection,
-diff -up ./src/libckyapplet/cky_factory.c.coolkey-update ./src/libckyapplet/cky_factory.c
---- ./src/libckyapplet/cky_factory.c.coolkey-update 2016-01-19 18:04:51.976267329 -0800
-+++ ./src/libckyapplet/cky_factory.c 2016-01-19 18:05:03.518172548 -0800
-@@ -29,7 +29,7 @@ CKYAPDUFactory_SelectFile(CKYAPDU *apdu,
- const CKYBuffer *AID)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-- CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE);
-+ CKYAPDU_SetINS(apdu, ISO_INS_SELECT_FILE);
- CKYAPDU_SetP1(apdu, p1);
- CKYAPDU_SetP2(apdu, p2);
- return CKYAPDU_SetSendDataBuffer(apdu, AID);
-@@ -40,7 +40,7 @@ CKYAPDUFactory_SelectCardManager(CKYAPDU
- {
- CKYByte c = 0;
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-- CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE);
-+ CKYAPDU_SetINS(apdu, ISO_INS_SELECT_FILE);
- CKYAPDU_SetP1(apdu, 0x04);
- CKYAPDU_SetP2(apdu, 0x00);
- /* I can't find the documentation for this, but if you pass an empty
-@@ -57,12 +57,11 @@ CKYStatus
- CKYAPDUFactory_GetCPLCData(CKYAPDU *apdu)
- {
- CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM);
-- CKYAPDU_SetINS(apdu, CKY_INS_GET_DATA);
-+ CKYAPDU_SetINS(apdu, ISO_INS_GET_DATA);
- CKYAPDU_SetP1(apdu, 0x9f);
- CKYAPDU_SetP2(apdu, 0x7f);
- return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_CPLCDATA);
- }
--
- /*
- * applet commands must be issued with the appplet selected.
- */
-@@ -184,6 +183,49 @@ fail:
- }
-
- CKYStatus
-+CKYAPDUFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *publicData, const CKYBuffer *secretKey)
-+{
-+ CKYStatus ret = CKYINVALIDARGS;
-+ CKYSize len;
-+ CKYBuffer buf;
-+
-+ if (!publicData)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(publicData)))
-+ return ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_KEY_AGREEMENT);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)len);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, publicData);
-+ if (ret == CKYSUCCESS && secretKey && 0 < (len = CKYBuffer_Size(secretKey))) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)len);
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, secretKey);
-+ }
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
- CKYAPDUFactory_ComputeCryptOneStep(CKYAPDU *apdu, CKYByte keyNumber, CKYByte mode,
- CKYByte direction, CKYByte location,
- const CKYBuffer *idata, const CKYBuffer *sig)
-@@ -386,6 +428,49 @@ fail:
- }
-
- CKYStatus
-+CKYAPDUFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *idata, const CKYBuffer *sig)
-+{
-+ CKYStatus ret = CKYINVALIDARGS;
-+ CKYSize len;
-+ CKYBuffer buf;
-+
-+ if (!idata)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT)
-+ return ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_SIGNATURE);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)len);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, idata);
-+ if (ret == CKYSUCCESS && sig && 0 < (len = CKYBuffer_Size(sig))) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)len);
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, sig);
-+ }
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
- CKYAPDUFactory_ReadObject(CKYAPDU *apdu, unsigned long objectID,
- CKYOffset offset, CKYByte size)
- {
-@@ -634,32 +719,167 @@ CACAPDUFactory_GetProperties(CKYAPDU *ap
- }
-
- CKYStatus
--CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin)
-+PIVAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte chain, CKYByte alg,
-+ CKYByte key, int len, const CKYBuffer *data)
-+{
-+ CKYStatus ret;
-+ CKYAPDU_SetCLA(apdu, chain ? CKY_CLASS_ISO7816_CHAIN :
-+ CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, PIV_INS_GEN_AUTHENTICATE);
-+ CKYAPDU_SetP1(apdu, alg);
-+ CKYAPDU_SetP2(apdu, key);
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, data);
-+ if (ret == CKYSUCCESS && chain == 0 && len != 0) {
-+ if (len >= 256) len = 0;
-+ ret = CKYAPDU_AppendReceiveLen(apdu, len);
-+ }
-+ return ret;
-+}
-+
-+CKYStatus
-+PIVAPDUFactory_GetData(CKYAPDU *apdu, const CKYBuffer *object, CKYByte count)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+ CKYByte objectSize;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, 0xcb);
-+ CKYAPDU_SetP1(apdu, 0x3f);
-+ CKYAPDU_SetP2(apdu, 0xff);
-+
-+ objectSize = CKYBuffer_Size(object);
-+
-+ ret = CKYBuffer_Reserve(&buf, 2+objectSize);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, 0x5c);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, objectSize);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendCopy(&buf, object);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_AppendReceiveLen(apdu, count);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15APDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte keyRef, const CKYBuffer *pin)
- {
- CKYStatus ret;
-- CKYSize size;
-
- CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
- CKYAPDU_SetINS(apdu, CAC_INS_VERIFY_PIN);
- CKYAPDU_SetP1(apdu, 0x00);
-- CKYAPDU_SetP2(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, keyRef);
- /* no pin, send an empty buffer */
-- if (!pin) {
-+ if (CKYBuffer_Size(pin) == 0) {
- return CKYAPDU_SetReceiveLen(apdu, 0);
- }
-
- /* all CAC pins are 8 bytes exactly. If to long, truncate it */
-- size = strlen(pin);
-- if (size > 8) {
-- size = 8;
-- }
-- ret = CKYAPDU_SetSendData(apdu, (unsigned char *) pin, size);
-- /* if too short, pad it */
-- if ((ret == CKYSUCCESS) && (size < 8)) {
-- static const unsigned char pad[]= { 0xff , 0xff, 0xff ,0xff,
-- 0xff, 0xff, 0xff, 0xff };
-- return CKYAPDU_AppendSendData(apdu, pad, 8-size);
-- }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, pin);
- return ret;
-
- }
-+
-+CKYStatus
-+P15APDUFactory_ReadRecord(CKYAPDU *apdu, CKYByte record, CKYByte short_ef,
-+ CKYByte flags, CKYByte count)
-+{
-+ CKYByte control;
-+
-+ control = (short_ef << 3) & 0xf8;
-+ control |= flags & 0x07;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_READ_RECORD);
-+ CKYAPDU_SetP1(apdu, record);
-+ CKYAPDU_SetP2(apdu, control);
-+ return CKYAPDU_SetReceiveLen(apdu, count);
-+}
-+
-+CKYStatus
-+P15APDUFactory_ReadBinary(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte count)
-+{
-+ CKYByte p1 = 0,p2 = 0;
-+ unsigned short max_offset = 0;
-+
-+ if (flags & P15_USE_SHORT_EF) {
-+ max_offset = 0xff;
-+ p1 = P15_USE_SHORT_EF | (short_ef & 0x7);
-+ p2 = offset & 0xff;
-+ } else {
-+ max_offset = 0x7fff;
-+ p1 = (offset >> 8) & 0x7f;
-+ p2 = offset & 0xff;
-+ }
-+ if (offset > max_offset) {
-+ return CKYINVALIDARGS;
-+ }
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_READ_BINARY);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ return CKYAPDU_SetReceiveLen(apdu, count);
-+}
-+
-+CKYStatus
-+P15APDUFactory_ManageSecurityEnvironment(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ CKYByte keyRef)
-+{
-+ CKYByte param[3];
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_MANAGE_SECURITY_ENVIRONMENT);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ param[0] = 0x83;
-+ param[1] = 1;
-+ param[2] = keyRef;
-+ return CKYAPDU_SetSendData(apdu, param, sizeof param);
-+}
-+
-+CKYStatus
-+P15APDUFactory_PerformSecurityOperation(CKYAPDU *apdu, CKYByte dir,
-+ int chain, CKYSize retLen, const CKYBuffer *data)
-+{
-+ CKYByte p1,p2;
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, chain ? CKY_CLASS_ISO7816_CHAIN :
-+ CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_PERFORM_SECURITY_OPERATION);
-+ if (dir == CKY_DIR_DECRYPT) {
-+ p1 = ISO_PSO_DECRYPT_P1;
-+ p2 = ISO_PSO_DECRYPT_P2;
-+ } else {
-+ p1 = ISO_PSO_SIGN_P1;
-+ p2 = ISO_PSO_SIGN_P2;
-+ }
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, data);
-+ if (ret == CKYSUCCESS && (chain == 0) && retLen != 0) {
-+ ret = CKYAPDU_AppendReceiveLength(apdu, retLen);
-+ }
-+ return ret;
-+}
-+
-+
-diff -up ./src/libckyapplet/cky_factory.h.coolkey-update ./src/libckyapplet/cky_factory.h
---- ./src/libckyapplet/cky_factory.h.coolkey-update 2016-01-19 18:05:20.615032151 -0800
-+++ ./src/libckyapplet/cky_factory.h 2016-01-19 18:05:30.781948661 -0800
-@@ -25,17 +25,41 @@
- /*
- * Various Class bytes
- */
--#define CKY_CLASS_ISO7816 0x00
-+#define CKY_CLASS_ISO7816 0x00
-+#define CKY_CLASS_ISO7816_CHAIN 0x10
- #define CKY_CLASS_GLOBAL_PLATFORM 0x80
--#define CKY_CLASS_SECURE 0x84
--#define CKY_CLASS_COOLKEY 0xb0
-+#define CKY_CLASS_SECURE 0x84
-+#define CKY_CLASS_COOLKEY 0xb0
-
- /*
- * Applet Instruction Bytes
- */
- /* Card Manager */
--#define CKY_INS_SELECT_FILE 0xa4
--#define CKY_INS_GET_DATA 0xca
-+#define ISO_INS_SELECT_FILE 0xa4
-+#define ISO_INS_GET_DATA 0xca
-+#define ISO_INS_READ_BINARY 0xb0
-+#define ISO_INS_READ_RECORD 0xb2
-+#define ISO_INS_MANAGE_SECURITY_ENVIRONMENT 0x22
-+#define ISO_INS_PERFORM_SECURITY_OPERATION 0x2a
-+
-+/* ISO Parameters: */
-+#define ISO_LOGIN_LOCAL 0x80
-+#define ISO_LOGIN_GLOBAL 0x00
-+#define ISO_MSE_SET 0x01
-+#define ISO_MSE_STORE 0xf2
-+#define ISO_MSE_RESTORE 0xf3
-+#define ISO_MSE_ERASE 0xf4
-+#define ISO_MSE_QUAL_VERIFY 0x80
-+#define ISO_MSE_QUAL_COMPUTE 0x40
-+#define ISO_MSE_AUTH 0xa4
-+#define ISO_MSE_SIGN 0xb6
-+#define ISO_MSE_KEA 0xb8
-+#define ISO_PSO_SIGN_P1 0x9e
-+#define ISO_PSO_SIGN_P2 0x9a
-+#define ISO_PSO_ENCRYPT_P1 0x86
-+#define ISO_PSO_ENCRYPT_P2 0x80
-+#define ISO_PSO_DECRYPT_P1 0x80
-+#define ISO_PSO_DECRYPT_P2 0x86
-
- /* deprecated */
- #define CKY_INS_SETUP 0x2A
-@@ -66,6 +90,8 @@
- /* nonce validated & Secure Channel */
- #define CKY_INS_IMPORT_KEY 0x32
- #define CKY_INS_COMPUTE_CRYPT 0x36
-+#define CKY_INS_COMPUTE_ECC_SIGNATURE 0x37
-+#define CKY_INS_COMPUTE_ECC_KEY_AGREEMENT 0x38
- #define CKY_INS_CREATE_PIN 0x40
- #define CKY_INS_CHANGE_PIN 0x44
- #define CKY_INS_CREATE_OBJ 0x5A
-@@ -81,6 +107,7 @@
- #define CKY_INS_SEC_READ_IOBUF 0x08
- #define CKY_INS_SEC_START_ENROLLMENT 0x0C
-
-+
- /* CAC */
- #define CAC_INS_GET_CERTIFICATE 0x36
- #define CAC_INS_SIGN_DECRYPT 0x42
-@@ -92,6 +119,9 @@
- #define CAC_P1_STEP 0x80
- #define CAC_P1_FINAL 0x00
-
-+/* PIV */
-+#define PIV_INS_GEN_AUTHENTICATE 0x87
-+
- /*
- * Fixed return sized from various commands
- */
-@@ -112,7 +142,7 @@
- /* functions */
- #define CKY_CIPHER_INIT 1
- #define CKY_CIPHER_PROCESS 2
--#define CKY_CIPHER_FINAL 3
-+#define CKY_CIPHER_FINAL 3
- #define CKY_CIPHER_ONE_STEP 4 /* init and final in one APDU */
-
- /* modes */
-@@ -123,6 +153,7 @@
- #define CKY_DES_ECB_NOPAD 0x21
-
- /* operations (Cipher Direction) */
-+#define CKY_DIR_NONE 0x00
- #define CKY_DIR_SIGN 0x01
- #define CKY_DIR_VERIFY 0x02
- #define CKY_DIR_ENCRYPT 0x03
-@@ -163,6 +194,18 @@
- #define CKY_CARDM_MANAGER_LOCKED 0x7f
- #define CKY_CARDM_MANAGER_TERMINATED 0xff
-
-+/* Read Record Flags */
-+#define P15_READ_P1 0x4
-+#define P15_READ_P1_TO_LAST 0x5
-+#define P15_READ_LAST_TO_P1 0x6
-+#define P15_READ_FIRST 0x0
-+#define P15_READ_LAST 0x1
-+#define P15_READ_NEXT 0x2
-+#define P15_READ_PREV 0x3
-+
-+/* Read Binary Flags */
-+#define P15_USE_SHORT_EF 0x80
-+
- /*
- * The following factories 'Fill in' APDUs for each of the
- * functions described below. Nonces are not automatically added.
-@@ -187,6 +230,12 @@ CKYStatus CKYAPDUFactory_ComputeCryptFin
- CKYStatus CKYAPDUFactory_ComputeCryptOneStep(CKYAPDU *apdu, CKYByte keyNumber,
- CKYByte mode, CKYByte direction, CKYByte location,
- const CKYBuffer *data, const CKYBuffer *sig);
-+CKYStatus CKYAPDUFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *data, const CKYBuffer *sig);
-+CKYStatus CKYAPDUFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *publicData, const CKYBuffer *secretKey);
- CKYStatus CKYAPDUFactory_CreatePIN(CKYAPDU *apdu, CKYByte pinNumber,
- CKYByte maxAttempts, const char *pinValue);
- CKYStatus CKYAPDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte pinNumber,
-@@ -218,12 +267,28 @@ CKYStatus CKYAPDUFactory_GetBuiltinACL(C
-
- CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type,
- const CKYBuffer *data);
--CKYStatus CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin);
- CKYStatus CACAPDUFactory_GetCertificate(CKYAPDU *apdu, CKYSize size);
- CKYStatus CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
- CKYByte type, CKYByte count);
- CKYStatus CACAPDUFactory_GetProperties(CKYAPDU *apdu);
-
-+CKYStatus PIVAPDUFactory_GetData(CKYAPDU *apdu, const CKYBuffer *object,
-+ CKYByte count);
-+CKYStatus PIVAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte chain, CKYByte alg,
-+ CKYByte key, int len, const CKYBuffer *data);
-+
-+CKYStatus P15APDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte keyRef,
-+ const CKYBuffer *pin);
-+CKYStatus P15APDUFactory_ReadRecord(CKYAPDU *apdu, CKYByte record,
-+ CKYByte short_ef, CKYByte flags, CKYByte count);
-+CKYStatus P15APDUFactory_ReadBinary(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte count);
-+CKYStatus P15APDUFactory_ManageSecurityEnvironment(CKYAPDU *apdu,
-+ CKYByte p1, CKYByte p2, CKYByte key);
-+CKYStatus P15APDUFactory_PerformSecurityOperation(CKYAPDU *apdu, CKYByte dir,
-+ int chain, CKYSize retLen, const CKYBuffer *data);
-+
-+
- CKY_END_PROTOS
-
- #endif /* CKY_FACTORY_H */
diff --git a/coolkey.spec b/coolkey.spec
deleted file mode 100644
index a8d6526..0000000
--- a/coolkey.spec
+++ /dev/null
@@ -1,283 +0,0 @@
-# BEGIN COPYRIGHT BLOCK
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation version
-# 2.1 of the License.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-# END COPYRIGHT BLOCK
-
-%define coolkey_module "CoolKey PKCS #11 Module"
-%define nssdb %{_sysconfdir}/pki/nssdb
-
-Name: coolkey
-Version: 1.1.0
-Release: 36%{?dist}
-Summary: CoolKey PKCS #11 module
-License: LGPLv2
-URL: http://directory.fedora.redhat.com/wiki/CoolKey
-Source: coolkey-%{version}.tar.gz
-Patch1: coolkey-cache-dir-move.patch
-Patch2: coolkey-gcc43.patch
-Patch3: coolkey-latest.patch
-Patch4: coolkey-simple-bugs.patch
-Patch5: coolkey-thread-fix.patch
-Patch6: coolkey-cac.patch
-Patch7: coolkey-cac-1.patch
-Patch8: coolkey-pcsc-lite-fix.patch
-Patch9: coolkey-fix-token-removal-failure.patch
-Patch10: coolkey-update.patch
-Patch11: coolkey-more-keys.patch
-Patch12: coolkey-1.1.0-max-cpu-bug.patch
-Group: System Environment/Libraries
-BuildRequires: autoconf
-BuildRequires: pcsc-lite-devel
-BuildRequires: zlib-devel
-BuildRequires: nss-devel
-Recommends: opensc
-Requires: nss-tools
-Requires: pcsc-lite
-Requires: pcsc-lite-libs
-Requires: ccid
-Provides: CoolKey Openkey
-Obsoletes: CoolKey Openkey
-# 390 does not have libusb or smartCards
-ExcludeArch: s390 s390x
-
-%description
-Linux Driver support for the CoolKey and CAC products.
-
-%package devel
-Summary: CoolKey Applet libraries
-Group: System Environment/Libraries
-
-%description devel
-Linux Driver support to access the CoolKey applet.
-
-
-%prep
-%setup -q
-%patch1 -b .cache.dir.move
-%patch2 -b .coolkey-gcc43
-%patch3 -b .coolkey-latest
-%patch4 -b .coolkey-simple-bugs
-%patch5 -b .coolkey-thread-fix
-%patch6 -b .cac
-%patch7 -b .cac-1
-%patch8 -b .reader-state-fix
-%patch9 -p1 -b .fix-token-removal-failure
-%patch10 -p1 -b .coolkey-update
-%patch11 -p1 -b .coolkey-more-keys
-%patch12 -p1 -b .max-cpu
-
-%build
-autoconf
-%configure --with-debug --disable-dependency-tracking --enable-pk11install
-make %{?_smp_mflags} CFLAGS="$CFLAGS -g -O2 -fno-strict-aliasing $CFLAGS " CXXFLAGS="$CXXFLAGS -g -O2 -fno-strict-aliasing $CFLAGS"
-
-%install
-rm -rf $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
-ln -s pkcs11/libcoolkeypk11.so $RPM_BUILD_ROOT/%{_libdir}
-mkdir -p $RPM_BUILD_ROOT/var/cache/coolkey
-
-%post
-/sbin/ldconfig
-if [ "$1" == "2" ]; then # not for new installs
- isThere=`modutil -rawlist -dbdir %{nssdb} | grep %{coolkey_module} || echo NO`
- if [ "$isThere" != "NO" ]; then
- # Remove from NSS DB in Fedora 26
- if [ -x %{_bindir}/modutil ]; then
- modutil -delete %{coolkey_module} -dbdir %{nssdb} -force || :
- fi
- fi
-fi
-
-%files
-%defattr(-,root,root,-)
-%doc ChangeLog LICENSE
-%{_bindir}/pk11install
-%{_libdir}/libcoolkeypk11.so
-%{_libdir}/pkcs11
-%{_libdir}/libckyapplet.so.1
-%{_libdir}/libckyapplet.so.1.0.0
-
-%files devel
-%{_libdir}/libckyapplet.so
-%{_libdir}/pkgconfig/libckyapplet.pc
-%{_includedir}/*.h
-
-
-%changelog
-* Wed Feb 07 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-36
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
-
-* Wed Aug 02 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-35
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
-
-* Wed Jul 26 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-34
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
-
-* Thu Mar 09 2017 Jakub Jelen <jjelen(a)redhat.com> - 1.1.0-33
-- Prevent busy loop when removing token (#1430268)
-
-* Tue Feb 28 2017 Jakub Jelen <jjelen(a)redhat.com> - 1.1.0-32
-- Remove PKCS#11 library from the NSS DB after update and for new installs (#1421692)
-
-* Fri Feb 10 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-31
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
-
-* Thu Feb 04 2016 Jack Magne <jmagne(a)redhat.com> - 1.1.0-30
-- Latest coolkey updates.
-- Fix to allow more key indexes than just 0 - 9.
-
-* Wed Feb 03 2016 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1.0-29
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
-
-* Wed Jun 17 2015 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-28
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
-
-* Sat May 02 2015 Kalev Lember <kalevlember(a)gmail.com> - 1.1.0-27
-- Rebuilt for GCC 5 C++11 ABI change
-
-* Sat Aug 16 2014 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-26
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
-
-* Sat Jun 07 2014 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-25
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
-
-* Sat Aug 03 2013 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-24
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
-
-* Wed May 22 2013 Ray Strode <rstrode(a)redhat.com> 1.1.0-23
-- Fix token removal issue
-
-* Wed Feb 13 2013 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-22
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
-
-* Wed Jul 18 2012 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-21
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
-
-* Thu Jan 12 2012 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-20
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
-
-* Tue Feb 08 2011 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-19
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
-
-* Tue Oct 19 2010 Ville Skyttä <ville.skytta(a)iki.fi> - 1.1.0-18
-- Own the %%{_libdir}/pkcs11 dir.
-
-* Wed Sep 8 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-17
-- pscs-lite removed SCARD_READERSTATE_A definition. revert to the prefered
- SCARD_READERSTATE
-
-* Wed Jun 23 2010 Jack Magne <jmagne(a)redhat.com> - 1.1.0-16
-- fix possible crash when loading cac certs.
-
-* Wed Jun 16 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-15
-- better cac support.
-
-* Mon Feb 22 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-14
-- remove dependency on ifd-egate
-
-* Tue Jan 5 2010 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-13
-- bump the release number to rebuild
-
-* Wed Dec 18 2009 Robert Relyea <rrelyea(a)redhat.com> - 1.1.0-12
-- Fix threading issue. Coolkey will now work with non-threaded applications
-- that don't link with libpthread.
-
-* Wed Sep 16 2009 Jack magne <jmagne(a)redhat.com> - 1.1.0-11
-- Misc bug fixes. Resolves: 485032, #250738, #497758.
-
-* Fri Sep 11 2009 Jack Magne <jmagne(a)redhat.com> - 1.1.0-10
-- Include latest changes for Gemalto 64K and Safenet 330J.
-
-* Fri Jul 24 2009 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-9
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
-
-* Tue Feb 24 2009 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.1.0-8
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
-
-* Sun Sep 14 2008 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.1.0-7
-- BR: nss-devel not mozilla-nss-devel (FTBFS BZ#440753)
-
-* Wed Feb 13 2008 Jack magne <jmagne(a)redhat.com> - 1.1.0-6
-- Clean up building with gcc 4.3.
-* Thu Sep 27 2007 Jack Magne <jmagne(a)redhat.com> - 1.1.0-5
-- Include patch for moving the cache directory to a safe location.
-- Bug #299481.
-* Fri Aug 20 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-4
-- Update License description to the new Fedora standard
-
-* Thu Jun 21 2007 Kai Engert <kengert(a)redhat.com> - 1.1.0-3.1
-- rebuild
-
-* Tue Jun 5 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-3
-- add build requires, bump version number for make tag.
-
-* Thu May 31 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-2
-- Back out RHEL-4 version of spec from CVS, add pcsc-lite-lib requires.
-
-* Tue Feb 20 2007 Bob Relyea <rrelyea(a)redhat.com> - 1.1.0-1
-- Pick up lates release.
-
-* Wed Nov 1 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-15
-- Don't grab the CUID on cac's. Resting the card causes it to
-- logout of other applications.
-
-* Wed Nov 1 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-14
-- Shared memory directory needs to be writeable by all so
-- coolkey can create caches for any user. (lack of caches
-- show up in screen savers reactly slowly).
-
-* Fri Oct 20 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-13
-- fix login hw race failures
-
-* Fri Oct 20 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-12
-- add the dist flag
-
-* Wed Oct 18 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-11
-- CAC cards sometimes need to reset before they can get their
-- initial transaction (problem is noticed on insertion an removal)
-
-* Tue Oct 17 2006 Jesse Keating <jkeating(a)redhat.com> - 1.0.1-10
-- Only run pk11install if the binary is there (multilib fun)
-
-* Mon Oct 09 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-9
-- use pk11install which does not require loading the module to install it.
-
-* Mon Oct 09 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-8
-- pcscd must be running in order to add coolkey.
-
-* Thu Oct 4 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-7
-- silence modutil warnings
-
-* Thu Sep 30 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-5
-- install and uninstall coolkey in the system secmod.db
-
-* Thu Sep 7 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-4
-- make the coolkey token caches persist over application calls.
-- make a separate cache for each user.
-
-* Sun Jul 16 2006 Florian La Roche <laroche(a)redhat.com> - 1.0.1-2
-- fix excludearch line
-
-* Mon Jul 10 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.1-1
-- Don't require pthread library in coolkey
-
-* Mon Jul 10 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.0-2
-- remove s390 from the build
-
-* Mon Jun 5 2006 Bob Relyea <rrelyea(a)redhat.com> - 1.0.0-1
-- Initial revision for fedora
diff --git a/dead.package b/dead.package
new file mode 100644
index 0000000..5ff2bbd
--- /dev/null
+++ b/dead.package
@@ -0,0 +1 @@
+Replaced by OpenSC
diff --git a/sources b/sources
deleted file mode 100644
index aecaa3b..0000000
--- a/sources
+++ /dev/null
@@ -1 +0,0 @@
-815a1811a46bf9b8782107c073149cbe coolkey-1.1.0.tar.gz
6 years, 1 month
Architecture specific change in rpms/golang-github-russross-blackfriday.git
by githook-noreply@fedoraproject.org
The package rpms/golang-github-russross-blackfriday.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/golang-github-russross-blackfrida....
Change:
-%ifarch 0%{?gccgo_arches}
Thanks.
Full change:
============
commit fd2416533135a482b48daf762e58df49addcae05
Author: Jan Chaloupka <jchaloup(a)redhat.com>
Date: Thu Mar 1 23:25:33 2018 +0100
Autogenerate some parts using the new macros
diff --git a/golang-github-russross-blackfriday.spec b/golang-github-russross-blackfriday.spec
index fc40ab7..ad76132 100644
--- a/golang-github-russross-blackfriday.spec
+++ b/golang-github-russross-blackfriday.spec
@@ -1,161 +1,53 @@
-# If any of the following macros should be set otherwise,
-# you can wrap any of them with the following conditions:
-# - %%if 0%%{centos} == 7
-# - %%if 0%%{?rhel} == 7
-# - %%if 0%%{?fedora} == 23
-# Or just test for particular distribution:
-# - %%if 0%%{centos}
-# - %%if 0%%{?rhel}
-# - %%if 0%%{?fedora}
-#
-# Be aware, on centos, both %%rhel and %%centos are set. If you want to test
-# rhel specific macros, you can use %%if 0%%{?rhel} && 0%%{?centos} == 0 condition.
-# (Don't forget to replace double percentage symbol with single one in order to apply a condition)
-
-# Generate devel rpm
-%global with_devel 1
-# Build project from bundled dependencies
-%global with_bundled 0
-# Build with debug info rpm
-%global with_debug 0
-# Run tests in check section
-%global with_check 1
-# Generate unit-test rpm
-%global with_unit_test 1
-
-%if 0%{?with_debug}
-%global _dwz_low_mem_die_limit 0
-%else
-%global debug_package %{nil}
-%endif
-
-%global provider github
-%global provider_tld com
-%global project russross
-%global repo blackfriday
-# https://github.com/russross/blackfriday
-%global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo}
-%global import_path %{provider_prefix}
+# http://github.com/russross/blackfriday
+%global provider_prefix github.com/russross/blackfriday
+%global gobaseipath %{provider_prefix}
%global commit 4048872b16cc0fc2c5fd9eacf0ed2c2fedaa0c8c
-%global shortcommit %(c=%{commit}; echo ${c:0:7})
+%global commitdate 20170728
-Name: golang-%{provider}-%{project}-%{repo}
+%gocraftmeta -i
+
+Name: %{goname}
Version: 1.5
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: Markdown processor implemented in Go
License: BSD
-URL: https://%{provider_prefix}
-Source0: https://%{provider_prefix}/archive/%{commit}/%{repo}-%{shortcommit}.tar.gz
-
-# e.g. el6 has ppc64 arch without gcc-go, so EA tag is required
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
-# If go_compiler is not set to 1, there is no virtual provide. Use golang instead.
-BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang}
+URL: %{gourl}
+Source0: %{gosource}
%description
%{summary}
-%if 0%{?with_devel}
%package devel
Summary: %{summary}
BuildArch: noarch
-%if 0%{?with_check}
-%endif
-
-Provides: golang(%{import_path}) = %{version}-%{release}
-
%description devel
%{summary}
This package contains library source intended for
building other packages which use import path with
-%{import_path} prefix.
-%endif
-
-%if 0%{?with_unit_test}
-%package unit-test
-Summary: Unit tests for %{name} package
-
-%if 0%{?with_check}
-#Here comes all BuildRequires: PACKAGE the unit tests
-#in %%check section need for running
-%endif
-
-# test subpackage tests code from devel subpackage
-Requires: %{name}-devel = %{version}-%{release}
-
-%description unit-test
-%{summary}
-
-This package contains unit tests for project
-providing packages with %{import_path} prefix.
-%endif
+%{gobaseipath} prefix.
%prep
-%setup -q -n %{repo}-%{commit}
-
-%build
+%gosetup
%install
-# source codes for building projects
-%if 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-# find all *.go but no *_test.go files and generate devel.file-list
-for file in $(find . -iname "*.go" \! -iname "*_test.go") ; do
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> devel.file-list
-done
-%endif
-
-# testing files for this project
-%if 0%{?with_unit_test}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-# find all *_test.go files and generate unit-test.file-list
-for file in $(find . -iname "*_test.go"); do
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> unit-test.file-list
-done
-cp -r testdata %{buildroot}/%{gopath}/src/%{import_path}/.
-echo "%%{gopath}/src/%%{import_path}/testdata" >> unit-test.file-list
-%endif
+%goinstall $(find . -iname "testdata" -type d)
%check
-%if 0%{?with_check} && 0%{?with_unit_test} && 0%{?with_devel}
-%ifarch 0%{?gccgo_arches}
-function gotest { %{gcc_go_test} "$@"; }
-%else
-%if 0%{?golang_test:1}
-function gotest { %{golang_test} "$@"; }
-%else
-function gotest { go test "$@"; }
-%endif
-%endif
-
-export GOPATH=%{buildroot}/%{gopath}:%{gopath}
-gotest %{import_path}
-%endif
+%gochecks
#define license tag if not already defined
%{!?_licensedir:%global license %doc}
-%if 0%{?with_devel}
%files devel -f devel.file-list
%license LICENSE.txt
%doc README.md
-%dir %{gopath}/src/%{provider}.%{provider_tld}/%{project}
-%dir %{gopath}/src/%{import_path}
-%endif
-
-%if 0%{?with_unit_test}
-%files unit-test -f unit-test.file-list
-%license LICENSE.txt
-%doc README.md
-%endif
%changelog
+* Thu Mar 01 2018 Jan Chaloupka <jchaloup(a)redhat.com>
+- Autogenerate some parts using the new macros
+
* Wed Feb 07 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.5-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
6 years, 1 month
Architecture specific change in rpms/golang-github-mesos-mesos-go.git
by githook-noreply@fedoraproject.org
The package rpms/golang-github-mesos-mesos-go.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/golang-github-mesos-mesos-go.git/....
Change:
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
Thanks.
Full change:
============
commit e3551adf8ce8a101391e9b69b3098e263acff9f8
Author: Jan Chaloupka <jchaloup(a)redhat.com>
Date: Thu Mar 1 14:24:51 2018 +0100
Autogenerate some parts using the new macros
diff --git a/golang-github-mesos-mesos-go.spec b/golang-github-mesos-mesos-go.spec
index 6b0a686..303a823 100644
--- a/golang-github-mesos-mesos-go.spec
+++ b/golang-github-mesos-mesos-go.spec
@@ -1,55 +1,26 @@
-%if 0%{?fedora} || 0%{?rhel} == 6
-%global with_devel 1
-%global with_bundled 0
-%global with_debug 0
-%global with_check 1
-%global with_unit_test 1
-%else
-%global with_devel 0
-%global with_bundled 0
-%global with_debug 0
-%global with_check 0
-%global with_unit_test 0
-%endif
-
-%if 0%{?with_debug}
-%global _dwz_low_mem_die_limit 0
-%else
-%global debug_package %{nil}
-%endif
-
-%global provider github
-%global provider_tld com
-%global project mesos
-%global repo mesos-go
-# https://github.com/mesos/mesos-go
-%global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo}
-%global import_path %{provider_prefix}
+# http://github.com/mesos/mesos-go
+%global provider_prefix github.com/mesos/mesos-go
+%global gobaseipath %{provider_prefix}
%global commit 83b52d7f648d2a2fa91330123d348d4090be2aed
-%global shortcommit %(c=%{commit}; echo ${c:0:7})
+%global commitdate 20150708
-Name: golang-%{provider}-%{project}-%{repo}
+%gocraftmeta -i
+
+Name: %{goname}
Version: 0
-Release: 0.10.git%{shortcommit}%{?dist}
+Release: 0.11.%{commitdate}git%{shortcommit}%{?dist}
Summary: Go language bindings for Apache Mesos
License: ASL 2.0
-URL: https://%{provider_prefix}
-Source0: https://%{provider_prefix}/archive/%{commit}/%{repo}-%{shortcommit}.tar.gz
-
-# e.g. el6 has ppc64 arch without gcc-go, so EA tag is required
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
-# If go_compiler is not set to 1, there is no virtual provide. Use golang instead.
-BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang}
+URL: %{gourl}
+Source0: %{gosource}
%description
%{summary}
-%if 0%{?with_devel}
%package devel
Summary: %{summary}
BuildArch: noarch
-%if 0%{?with_check}
BuildRequires: golang(code.google.com/p/go-uuid/uuid)
BuildRequires: golang(github.com/gogo/protobuf/proto)
BuildRequires: golang(github.com/golang/glog)
@@ -58,148 +29,34 @@ BuildRequires: golang(github.com/stretchr/testify/assert)
BuildRequires: golang(github.com/stretchr/testify/mock)
BuildRequires: golang(github.com/stretchr/testify/suite)
BuildRequires: golang(golang.org/x/net/context)
-%endif
-
-Requires: golang(code.google.com/p/go-uuid/uuid)
-Requires: golang(github.com/gogo/protobuf/proto)
-Requires: golang(github.com/golang/glog)
-Requires: golang(github.com/samuel/go-zookeeper/zk)
-Requires: golang(github.com/stretchr/testify/assert)
-Requires: golang(github.com/stretchr/testify/mock)
-Requires: golang(github.com/stretchr/testify/suite)
-Requires: golang(golang.org/x/net/context)
-
-Provides: golang(%{import_path}/auth) = %{version}-%{release}
-Provides: golang(%{import_path}/auth/callback) = %{version}-%{release}
-Provides: golang(%{import_path}/auth/sasl) = %{version}-%{release}
-Provides: golang(%{import_path}/auth/sasl/mech) = %{version}-%{release}
-Provides: golang(%{import_path}/auth/sasl/mech/crammd5) = %{version}-%{release}
-Provides: golang(%{import_path}/detector) = %{version}-%{release}
-Provides: golang(%{import_path}/detector/zoo) = %{version}-%{release}
-Provides: golang(%{import_path}/executor) = %{version}-%{release}
-Provides: golang(%{import_path}/healthchecker) = %{version}-%{release}
-Provides: golang(%{import_path}/mesos) = %{version}-%{release}
-Provides: golang(%{import_path}/mesosproto) = %{version}-%{release}
-Provides: golang(%{import_path}/mesosutil) = %{version}-%{release}
-Provides: golang(%{import_path}/mesosutil/process) = %{version}-%{release}
-Provides: golang(%{import_path}/messenger) = %{version}-%{release}
-Provides: golang(%{import_path}/messenger/testmessage) = %{version}-%{release}
-Provides: golang(%{import_path}/scheduler) = %{version}-%{release}
-Provides: golang(%{import_path}/testutil) = %{version}-%{release}
-Provides: golang(%{import_path}/upid) = %{version}-%{release}
%description devel
%{summary}
This package contains library source intended for
building other packages which use import path with
-%{import_path} prefix.
-%endif
-
-%if 0%{?with_unit_test} && 0%{?with_devel}
-%package unit-test
-Summary: Unit tests for %{name} package
-# If go_compiler is not set to 1, there is no virtual provide. Use golang instead.
-BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang}
-
-%if 0%{?with_check}
-#Here comes all BuildRequires: PACKAGE the unit tests
-#in %%check section need for running
-%endif
-
-# test subpackage tests code from devel subpackage
-Requires: %{name}-devel = %{version}-%{release}
-
-%description unit-test
-%{summary}
-
-This package contains unit tests for project
-providing packages with %{import_path} prefix.
-%endif
+%{gobaseipath} prefix.
%prep
-%setup -q -n %{repo}-%{commit}
-
-%build
+%gosetup
%install
-# source codes for building projects
-%if 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-echo "%%dir %%{gopath}/src/%%{import_path}/." >> devel.file-list
-# *.proto files defines a golang package as well
-for file in $(find . -iname "*.proto") ; do
- echo "%%dir %%{gopath}/src/%%{import_path}/$(dirname $file)" >> devel.file-list
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> devel.file-list
-done
-# find all *.go but no *_test.go files and generate unit-test.file-list
-for file in $(find . -iname "*.go" \! -iname "*_test.go") ; do
- echo "%%dir %%{gopath}/src/%%{import_path}/$(dirname $file)" >> devel.file-list
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> devel.file-list
-done
-%endif
-
-# testing files for this project
-%if 0%{?with_unit_test} && 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-# find all *_test.go files and generate unit-test.file-list
-for file in $(find . -iname "*_test.go"); do
- echo "%%dir %%{gopath}/src/%%{import_path}/$(dirname $file)" >> devel.file-list
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> unit-test.file-list
-done
-%endif
-
-%if 0%{?with_devel}
-sort -u -o devel.file-list devel.file-list
-%endif
+%goinstall
%check
-%if 0%{?with_check} && 0%{?with_unit_test} && 0%{?with_devel}
-%if ! 0%{?with_bundled}
-export GOPATH=%{buildroot}/%{gopath}:%{gopath}
-%else
-export GOPATH=%{buildroot}/%{gopath}:$(pwd)/Godeps/_workspace:%{gopath}
-%endif
-
-%if ! 0%{?gotest:1}
-%global gotest go test
-%endif
-
-%gotest %{import_path}/auth/sasl
-%gotest %{import_path}/detector
-#%%gotest %%{import_path}/detector/zoo
-#%%gotest %%{import_path}/executor
-%gotest %{import_path}/healthchecker
-%gotest %{import_path}/mesosproto
-%gotest %{import_path}/mesosutil
-%gotest %{import_path}/messenger
-#%%gotest %%{import_path}/scheduler
-%gotest %{import_path}/upid
-%endif
+%gochecks %{gobaseipath}/{detector/zoo,executor,scheduler,healthchecker,upid}
#define license tag if not already defined
%{!?_licensedir:%global license %doc}
-%if 0%{?with_devel}
%files devel -f devel.file-list
%license LICENSE
%doc README.md Godeps/Godeps.json
-%dir %{gopath}/src/%{provider}.%{provider_tld}/%{project}
-%endif
-
-%if 0%{?with_unit_test} && 0%{?with_devel}
-%files unit-test -f unit-test.file-list
-%license LICENSE
-%doc README.md messenger/README.md
-%endif
%changelog
+* Thu Mar 01 2018 Jan Chaloupka <jchaloup(a)redhat.com> - 0-0.11.20150708git83b52d7
+- Autogenerate some parts using the new macros
+
* Wed Feb 07 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 0-0.10.git83b52d7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
6 years, 1 month
Architecture specific change in rpms/cqrlog.git
by githook-noreply@fedoraproject.org
The package rpms/cqrlog.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/cqrlog.git/commit/?id=7552c568a64....
Change:
-ExcludeArch: armv7hl
Thanks.
Full change:
============
commit 7552c568a64f2eca25e209b4b569c0da02d0759b
Author: Richard Shaw <hobbes1069(a)gmail.com>
Date: Thu Mar 1 14:57:59 2018 -0600
Fix arm builds, improved translations, and other fixes.
diff --git a/cqrlog-install.patch b/cqrlog-install.patch
index ef898d2..2a982e4 100644
--- a/cqrlog-install.patch
+++ b/cqrlog-install.patch
@@ -16,8 +16,8 @@
+ rm -f -v tools/cqrlog.1
rm -rf src/backup
rm -f -v src/richmemo/*.o src/richmemo/*.ppu src/richmemo/gtk2/*.ppu src/richmemo/gtk2/*.o
-
-@@ -34,8 +32,8 @@ install:
+ rm -f -v tools/adif_hash_generator tools/adif_hash_generator.lpi tools/adif_hash_generator.lps
+@@ -35,8 +33,8 @@ install:
install -d -v $(datadir)/images/icon/64x64
install -d -v $(datadir)/images/icon/128x128
install -d -v $(datadir)/images/icon/256x256
@@ -28,7 +28,7 @@
install -d -v $(sharedir)/applications
install -d -v $(sharedir)/appdata
install -d -v $(sharedir)/man/man1
-@@ -52,8 +50,8 @@ install:
+@@ -53,8 +51,8 @@ install:
install -v -m 0644 zipcodes/* $(datadir)/zipcodes/
# install -v -m 0644 -t images/* $(datadir)/images/
cp -v -R images/* $(datadir)/images
@@ -39,7 +39,7 @@
# install -v -m 0644 images/icon/32x32/* $(datadir)/images/icon/32x32/
# install -v -m 0644 images/icon/64x64/* $(datadir)/images/icon/64x64/
# install -v -m 0644 images/icon/128x128/* $(datadir)/images/icon/128x128/
-@@ -61,15 +59,15 @@ install:
+@@ -62,15 +60,15 @@ install:
# install -v -m 0644 images/* $(datadir)/images/
install -v -m 0644 tools/cqrlog.desktop $(sharedir)/applications/cqrlog.desktop
install -v -m 0644 tools/cqrlog.appdata.xml $(sharedir)/appdata/cqrlog.appdata.xml
diff --git a/cqrlog.spec b/cqrlog.spec
index 67575d1..8e78f46 100644
--- a/cqrlog.spec
+++ b/cqrlog.spec
@@ -1,23 +1,21 @@
Name: cqrlog
Version: 2.2.0
-Release: 3%{?dist}
+Release: 4%{?dist}
Summary: An amateur radio contact logging program
License: GPLv2
URL: http://www.cqrlog.com/
Source0: https://github.com/ok2cqr/cqrlog/archive/v%{version}/%{name}-%{version}.t...
-Patch0: cqrlog-install.patch
-Patch1: cqrlog-desktop.patch
+# Fixes arm builds, translation improvements, and other bug fixes.
+Patch0: cqrlog-fixes.patch
+Patch1: cqrlog-install.patch
+Patch2: cqrlog-desktop.patch
ExclusiveArch: %{fpc_arches}
-# fpc/lazarus is broken, see:
-# https://bugzilla.redhat.com/show_bug.cgi?id=1517323
-# https://bugzilla.redhat.com/show_bug.cgi?id=1491788
-ExcludeArch: armv7hl
-BuildRequires: fpc >= 2.6.4
-BuildRequires: lazarus
+BuildRequires: fpc >= 3.0.4
+BuildRequires: lazarus >= 1.8
BuildRequires: libappstream-glib
BuildRequires: desktop-file-utils
@@ -111,6 +109,9 @@ fi
%changelog
+* Thu Mar 01 2018 Richard Shaw <hobbes1069(a)gmail.com> - 2.2.0-4
+- Fix arm builds, improved translations, and other fixes.
+
* Fri Feb 09 2018 Igor Gnatenko <ignatenkobrain(a)fedoraproject.org> - 2.2.0-3
- Escape macros in %%changelog
6 years, 1 month
Architecture specific change in rpms/xorg-x11-drv-voodoo.git
by githook-noreply@fedoraproject.org
The package rpms/xorg-x11-drv-voodoo.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/xorg-x11-drv-voodoo.git/commit/?i....
Change:
-ExcludeArch: s390 s390x %{?rhel:ppc ppc64}
Thanks.
Full change:
============
commit ae82717146c519d3951c07ab10cdf7aa9cbaa03f
Author: Adam Jackson <ajax(a)redhat.com>
Date: Thu Mar 1 15:14:24 2018 -0500
2018-03-01: retired driver, because it does not support KMS: https://lists.fedoraproject.org/pipermail/devel/2013-August/188429.html
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 5b1fa06..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-xf86-video-voodoo-1.2.4.tar.bz2
-/xf86-video-voodoo-1.2.5.tar.bz2
diff --git a/0001-Remove-obsolete-miInitializeBackingStore-call.patch b/0001-Remove-obsolete-miInitializeBackingStore-call.patch
deleted file mode 100644
index dc11bca..0000000
--- a/0001-Remove-obsolete-miInitializeBackingStore-call.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0616ca0bf3b6e5b676e29a01c8af4d0df6768526 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede(a)redhat.com>
-Date: Thu, 29 Sep 2016 19:48:17 +0200
-Subject: [PATCH xf86-video-voodoo] Remove obsolete miInitializeBackingStore()
- call
-
-Recent servers do not need this, and the latest servers do not
-even provide it.
-
-Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
----
- src/voodoo_driver.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/src/voodoo_driver.c b/src/voodoo_driver.c
-index 6ef12ae..04b6d9c 100644
---- a/src/voodoo_driver.c
-+++ b/src/voodoo_driver.c
-@@ -680,7 +680,6 @@ VoodooScreenInit(SCREEN_INIT_ARGS_DECL)
- if(pVoo->Accel)
- Voodoo2XAAInit(pScreen);
-
-- miInitializeBackingStore(pScreen);
- xf86SetBackingStore(pScreen);
-
-
---
-2.9.3
-
diff --git a/commitid b/commitid
deleted file mode 100644
index def32d7..0000000
--- a/commitid
+++ /dev/null
@@ -1 +0,0 @@
-51b6eec500f23e4c9a012a1ab4fe9b4012bc3703
diff --git a/dead.package b/dead.package
new file mode 100644
index 0000000..22f928a
--- /dev/null
+++ b/dead.package
@@ -0,0 +1 @@
+2018-03-01: retired driver, because it does not support KMS: https://lists.fedoraproject.org/pipermail/devel/2013-August/188429.html
diff --git a/make-git-snapshot.sh b/make-git-snapshot.sh
deleted file mode 100755
index e01415a..0000000
--- a/make-git-snapshot.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-DIRNAME=xf86-video-voodoo-$( date +%Y%m%d )
-
-rm -rf $DIRNAME
-git clone git://git.freedesktop.org/git/xorg/driver/xf86-video-voodoo $DIRNAME
-cd $DIRNAME
-if [ -z "$1" ]; then
- git log | head -1
-else
- git checkout $1
-fi
-git log | head -1 | awk '{ print $2 }' > ../commitid
-git repack -a -d
-cd ..
-tar jcf $DIRNAME.tar.bz2 $DIRNAME
-rm -rf $DIRNAME
diff --git a/sources b/sources
deleted file mode 100644
index 75f87c1..0000000
--- a/sources
+++ /dev/null
@@ -1 +0,0 @@
-fe71b83352cb96c41ff6a73a46a05e20 xf86-video-voodoo-1.2.5.tar.bz2
diff --git a/xf86-video-voodoo-1.2.5-build-fix.patch b/xf86-video-voodoo-1.2.5-build-fix.patch
deleted file mode 100644
index 7fb91e9..0000000
--- a/xf86-video-voodoo-1.2.5-build-fix.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 9172ae566a0e85313fc80ab62b4455393eefe593 Mon Sep 17 00:00:00 2001
-From: Dave Airlie <airlied(a)redhat.com>
-Date: Mon, 22 Sep 2014 10:56:02 +1000
-Subject: don't use PCITAG in struct anymore
-
-
-diff --git a/src/voodoo.h b/src/voodoo.h
-index bfed497..c3eb64e 100644
---- a/src/voodoo.h
-+++ b/src/voodoo.h
-@@ -23,7 +23,9 @@ typedef struct {
-
- Bool Voodoo2; /* Set if Voodoo2 */
- pciVideoPtr PciInfo; /* PCI data */
-+#ifndef XSERVER_LIBPCIACCESS
- PCITAG PciTag;
-+#endif
- CARD32 PhysBase;
-
- CARD32 Width; /* Current width */
---
-cgit v0.10.2
-
diff --git a/xorg-x11-drv-voodoo.spec b/xorg-x11-drv-voodoo.spec
deleted file mode 100644
index fccdbb8..0000000
--- a/xorg-x11-drv-voodoo.spec
+++ /dev/null
@@ -1,283 +0,0 @@
-%global tarball xf86-video-voodoo
-%global moduledir %(pkg-config xorg-server --variable=moduledir )
-%global driverdir %{moduledir}/drivers
-
-%undefine _hardened_build
-
-Summary: Xorg X11 voodoo video driver
-Name: xorg-x11-drv-voodoo
-Version: 1.2.5
-Release: 29%{?dist}
-URL: http://www.x.org
-License: MIT
-Group: User Interface/X Hardware Support
-
-Source0: ftp://ftp.x.org/pub/individual/driver/%{tarball}-%{version}.tar.bz2
-Source2: make-git-snapshot.sh
-Source3: commitid
-Patch0: xf86-video-voodoo-1.2.5-build-fix.patch
-Patch1: 0001-Remove-obsolete-miInitializeBackingStore-call.patch
-
-ExcludeArch: s390 s390x %{?rhel:ppc ppc64}
-
-BuildRequires: xorg-x11-server-devel >= 1.10.99.902
-BuildRequires: autoconf automake libtool
-
-Requires: Xorg %(xserver-sdk-abi-requires ansic)
-Requires: Xorg %(xserver-sdk-abi-requires videodrv)
-Requires: xorg-x11-server-wrapper
-
-%description
-X.Org X11 voodoo video driver.
-
-%prep
-%setup -q -n %{tarball}-%{version}
-%patch0 -p1
-%patch1 -p1
-
-%build
-autoreconf -vif
-%configure --disable-static
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-
-make install DESTDIR=$RPM_BUILD_ROOT
-
-# FIXME: Remove all libtool archives (*.la) from modules directory. This
-# should be fixed in upstream Makefile.am or whatever.
-find $RPM_BUILD_ROOT -regex ".*\.la$" | xargs rm -f --
-
-%files
-%{driverdir}/voodoo_drv.so
-%{_mandir}/man4/voodoo.4*
-
-%changelog
-* Fri Feb 09 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.2.5-29
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
-
-* Thu Aug 03 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.2.5-28
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
-
-* Thu Jul 27 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.2.5-27
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
-
-* Sat Feb 11 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.2.5-26
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
-
-* Thu Sep 29 2016 Hans de Goede <hdegoede(a)redhat.com> - 1.2.5-25
-- Rebuild against xserver-1.19
-
-* Fri Feb 05 2016 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.2.5-24
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
-
-* Thu Jan 28 2016 Peter Hutterer <peter.hutterer(a)redhat.com>
-- Remove unnecessary defattr
-
-* Wed Jan 20 2016 Peter Hutterer <peter.hutterer(a)redhat.com>
-- s/define/global/
-
-* Wed Jul 29 2015 Dave Airlie <airlied(a)redhat.com> - 1.2.5-23
-- 1.15 ABI rebuild
-
-* Tue Jun 23 2015 Adam Jackson <ajax(a)redhat.com> - 1.2.5-22
-- Undefine _hardened_build
-
-* Fri Jun 19 2015 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.5-21
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
-
-* Wed Feb 11 2015 Hans de Goede <hdegoede(a)redhat.com> - 1.2.5-20
-- Drop switch to ExclusiveArch <intel> done in last commit, other archs
- have PCI slots too
-
-* Wed Feb 11 2015 Hans de Goede <hdegoede(a)redhat.com> - 1.2.5-19
-- xserver 1.17 ABI rebuild
-
-* Mon Aug 18 2014 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.5-18
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
-
-* Mon Jun 16 2014 Hans de Goede <hdegoede(a)redhat.com> - 1.2.5-17
-- xserver 1.15.99.903 ABI rebuild
-
-* Sun Jun 08 2014 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.5-16
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
-
-* Mon Apr 28 2014 Hans de Goede <hdegoede(a)redhat.com> - 1.2.5-15
-- xserver 1.15.99-20140428 git snapshot ABI rebuild
-
-* Mon Jan 13 2014 Adam Jackson <ajax(a)redhat.com> - 1.2.5-14
-- 1.15 ABI rebuild
-
-* Tue Dec 17 2013 Adam Jackson <ajax(a)redhat.com> - 1.2.5-13
-- 1.15RC4 ABI rebuild
-
-* Wed Nov 20 2013 Adam Jackson <ajax(a)redhat.com> - 1.2.5-12
-- 1.15RC2 ABI rebuild
-
-* Wed Nov 06 2013 Adam Jackson <ajax(a)redhat.com> - 1.2.5-11
-- 1.15RC1 ABI rebuild
-
-* Fri Oct 25 2013 Adam Jackson <ajax(a)redhat.com> - 1.2.5-10
-- ABI rebuild
-
-* Sun Aug 04 2013 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.5-9
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
-
-* Thu Mar 07 2013 Dave Airlie <airlied(a)redhat.com> 1.2.5-8
-- autoconf for aarch64
-
-* Thu Mar 07 2013 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.5-7
-- require xorg-x11-server-devel, not -sdk
-
-* Thu Mar 07 2013 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.5-6
-- ABI rebuild
-
-* Fri Feb 15 2013 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.5-5
-- ABI rebuild
-
-* Fri Feb 15 2013 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.5-4
-- ABI rebuild
-
-* Thu Jan 10 2013 Adam Jackson <ajax(a)redhat.com> - 1.2.5-3
-- ABI rebuild
-
-* Sun Jul 22 2012 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.5-2
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
-
-* Wed Jul 18 2012 Dave Airlie <airlied(a)redhat.com> 1.2.5-1
-- voodoo 1.2.5
-
-* Thu Apr 05 2012 Adam Jackson <ajax(a)redhat.com> - 1.2.4-15
-- RHEL arch exclude updates
-
-* Sat Feb 11 2012 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.4-14
-- ABI rebuild
-
-* Fri Feb 10 2012 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.4-13
-- ABI rebuild
-
-* Tue Jan 24 2012 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.4-12
-- ABI rebuild
-
-* Wed Jan 04 2012 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.4-11
-- Rebuild for server 1.12
-
-* Fri Dec 16 2011 Adam Jackson <ajax(a)redhat.com> - 1.2.4-10
-- Drop xinf file
-
-* Mon Nov 14 2011 Adam Jackson <ajax(a)redhat.com> - 1.2.4-9
-- ABI rebuild
-
-* Wed Nov 09 2011 ajax <ajax(a)redhat.com> - 1.2.4-8
-- ABI rebuild
-
-* Thu Aug 18 2011 Adam Jackson <ajax(a)redhat.com> - 1.2.4-7
-- Rebuild for xserver 1.11 ABI
-
-* Wed May 11 2011 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.4-6
-- Rebuild for server 1.11
-
-* Mon Feb 28 2011 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.4-5
-- Rebuild for server 1.10
-
-* Tue Feb 08 2011 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.4-4
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
-
-* Thu Dec 02 2010 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.4-3
-- Rebuild for server 1.10
-
-* Wed Oct 27 2010 Adam Jackson <ajax(a)redhat.com> 1.2.4-2
-- Add ABI requires magic (#542742)
-
-* Mon Jul 05 2010 Dave Airlie <airlied(a)redhat.com> 1.2.4-1
-- build voodoo latest for server 1.9
-
-* Mon Jul 05 2010 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.3-3
-- rebuild for X Server 1.9
-
-* Thu Jan 21 2010 Peter Hutterer <peter.hutterer(a)redhat.com> - 1.2.3-2
-- Rebuild for server 1.8
-
-* Tue Aug 04 2009 Dave Airlie <airlied(a)redhat.com> 1.2.3-1
-- voodoo 1.2.3
-
-* Mon Jul 27 2009 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.2-2.1
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
-
-* Wed Jul 15 2009 Adam Jackson <ajax(a)redhat.com> - 1.2.2-1.1
-- ABI bump
-
-* Thu Jul 02 2009 Adam Jackson <ajax(a)redhat.com> 1.2.2-1
-- voodoo 1.2.2
-
-* Thu Feb 26 2009 Fedora Release Engineering <rel-eng(a)lists.fedoraproject.org> - 1.2.1-2
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
-
-* Tue Feb 24 2009 Adam Jackson <ajax(a)redhat.com> 1.2.1-1
-- voodoo 1.2.1
-
-* Thu Mar 20 2008 Dave Airlie <airlied(a)redhat.com> 1.2.0-1
-- upgrade to latest upstream release
-
-* Mon Mar 10 2008 Dave Airlie <airlied(a)redhat.com> 1.1.1-3.20080310
-- update to fixed snapshot
-
-* Mon Mar 03 2008 Adam Jackson <ajax(a)redhat.com> 1.1.1-3.20080303
-- git snapshot for pciaccess conversion
-
-* Wed Feb 20 2008 Fedora Release Engineering <rel-eng(a)fedoraproject.org> - 1.1.1-2
-- Autorebuild for GCC 4.3
-
-* Mon Sep 24 2007 Adam Jackson <ajax(a)redhat.com> 1.1.1-1
-- xf86-video-voodoo 1.1.1
-
-* Thu Aug 23 2007 Adam Jackson <ajax(a)redhat.com> - 1.1.0-6
-- Rebuild for ppc toolchain bug
-
-* Mon Jun 18 2007 Adam Jackson <ajax(a)redhat.com> 1.1.0-5
-- Update Requires and BuildRequires. Disown the module directories. Add
- Requires: hwdata.
-
-* Fri Feb 16 2007 Adam Jackson <ajax(a)redhat.com> 1.1.0-4
-- ExclusiveArch -> ExcludeArch
-
-* Wed Jul 12 2006 Jesse Keating <jkeating(a)redhat.com> - sh: line 0: fg: no job control
-- rebuild
-
-* Fri May 26 2006 Mike A. Harris <mharris(a)redhat.com> 1.1.0-3
-- Bumped sdk dep to pick up proto-devel indirectly.
-
-* Tue May 23 2006 Adam Jackson <ajackson(a)redhat.com> 1.1.0-2
-- Rebuild for 7.1 ABI fix.
-
-* Sun Apr 9 2006 Adam Jackson <ajackson(a)redhat.com> 1.1.0-1
-- Update to 1.1.0 from 7.1RC1.
-
-* Fri Feb 10 2006 Jesse Keating <jkeating(a)redhat.com> - 1.0.0.5-1.2
-- bump again for double-long bug on ppc(64)
-
-* Tue Feb 07 2006 Jesse Keating <jkeating(a)redhat.com> - 1.0.0.5-1.1
-- rebuilt for new gcc4.1 snapshot and glibc changes
-
-* Wed Jan 18 2006 Mike A. Harris <mharris(a)redhat.com> 1.0.0.5-1
-- Updated xorg-x11-drv-voodoo to version 1.0.0.5 from X11R7.0
-
-* Tue Dec 20 2005 Mike A. Harris <mharris(a)redhat.com> 1.0.0.4-1
-- Updated xorg-x11-drv-voodoo to version 1.0.0.4 from X11R7 RC4
-- Removed 'x' suffix from manpage dirs to match RC4 upstream.
-
-* Wed Nov 16 2005 Mike A. Harris <mharris(a)redhat.com> 1.0.0.2-1
-- Updated xorg-x11-drv-voodoo to version 1.0.0.2 from X11R7 RC2
-
-* Fri Nov 4 2005 Mike A. Harris <mharris(a)redhat.com> 1.0.0.1-1
-- Updated xorg-x11-drv-voodoo to version 1.0.0.1 from X11R7 RC1
-- Fix *.la file removal.
-* Tue Oct 4 2005 Mike A. Harris <mharris(a)redhat.com> 1.0.0-1
-- Update BuildRoot to use Fedora Packaging Guidelines.
-- Deglob file manifest.
-- Limit "ExclusiveArch" to x86, x86_64 ia64 ppc alpha sparc sparc64
-
-* Fri Sep 2 2005 Mike A. Harris <mharris(a)redhat.com> 1.0.0-0
-- Initial spec file for voodoo video driver generated automatically
- by my xorg-driverspecgen script.
6 years, 1 month
Architecture specific change in rpms/golang-github-julienschmidt-httprouter.git
by githook-noreply@fedoraproject.org
The package rpms/golang-github-julienschmidt-httprouter.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/golang-github-julienschmidt-httpr....
Change:
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
Thanks.
Full change:
============
commit 55565759cf2ebcbdca9387f7110fe1e109258c6f
Author: Jan Chaloupka <jchaloup(a)redhat.com>
Date: Thu Mar 1 12:34:56 2018 +0100
Autogenerate some parts using the new macros
diff --git a/golang-github-julienschmidt-httprouter.spec b/golang-github-julienschmidt-httprouter.spec
index ae58afd..07778cb 100644
--- a/golang-github-julienschmidt-httprouter.spec
+++ b/golang-github-julienschmidt-httprouter.spec
@@ -1,183 +1,53 @@
-# If any of the following macros should be set otherwise,
-# you can wrap any of them with the following conditions:
-# - %%if 0%%{centos} == 7
-# - %%if 0%%{?rhel} == 7
-# - %%if 0%%{?fedora} == 23
-# Or just test for particular distribution:
-# - %%if 0%%{centos}
-# - %%if 0%%{?rhel}
-# - %%if 0%%{?fedora}
-#
-# Be aware, on centos, both %%rhel and %%centos are set. If you want to test
-# rhel specific macros, you can use %%if 0%%{?rhel} && 0%%{?centos} == 0 condition.
-# (Don't forget to replace double percentage symbol with single one in order to apply a condition)
-
-# Generate devel rpm
-%global with_devel 1
-# Build project from bundled dependencies
-%global with_bundled 0
-# Build with debug info rpm
-%global with_debug 0
-# Run tests in check section
-%global with_check 1
-# Generate unit-test rpm
-%global with_unit_test 1
-
-%if 0%{?with_debug}
-%global _dwz_low_mem_die_limit 0
-%else
-%global debug_package %{nil}
-%endif
-
-%global isgccgoarch 0
-%if 0%{?gccgo_arches:1}
-%ifarch %{gccgo_arches}
-%global isgccgoarch 1
-%endif
-%endif
-
-%global provider github
-%global provider_tld com
-%global project julienschmidt
-%global repo httprouter
-# https://github.com/julienschmidt/httprouter
-%global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo}
-%global import_path %{provider_prefix}
+# http://github.com/julienschmidt/httprouter
+%global provider_prefix github.com/julienschmidt/httprouter
+%global gobaseipath %{provider_prefix}
%global commit 6aacfd5ab513e34f7e64ea9627ab9670371b34e7
-%global shortcommit %(c=%{commit}; echo ${c:0:7})
+%global commitdate 20150708
-Name: golang-%{provider}-%{project}-%{repo}
+%gocraftmeta -i
+
+Name: %{goname}
Version: 1.1
-Release: 10%{?dist}
+Release: 11%{?dist}
Summary: A high performance HTTP request router that scales well
License: BSD
-URL: https://%{provider_prefix}
-Source0: https://%{provider_prefix}/archive/%{commit}/%{repo}-%{shortcommit}.tar.gz
-
-# e.g. el6 has ppc64 arch without gcc-go, so EA tag is required
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
-# If go_compiler is not set to 1, there is no virtual provide. Use golang instead.
-BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang}
+URL: %{gourl}
+Source0: %{gosource}
%description
%{summary}
-%if 0%{?with_devel}
%package devel
Summary: %{summary}
BuildArch: noarch
-%if 0%{?with_check}
-%endif
-
-Provides: golang(%{import_path}) = %{version}-%{release}
-
%description devel
%{summary}
This package contains library source intended for
building other packages which use import path with
-%{import_path} prefix.
-%endif
-
-%if 0%{?with_unit_test} && 0%{?with_devel}
-%package unit-test
-Summary: Unit tests for %{name} package
-# If go_compiler is not set to 1, there is no virtual provide. Use golang instead.
-BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang}
-
-%if 0%{?with_check}
-#Here comes all BuildRequires: PACKAGE the unit tests
-#in %%check section need for running
-%endif
-
-# test subpackage tests code from devel subpackage
-Requires: %{name}-devel = %{version}-%{release}
-
-%description unit-test
-%{summary}
-
-This package contains unit tests for project
-providing packages with %{import_path} prefix.
-%endif
+%{gobaseipath} prefix.
%prep
-%setup -q -n %{repo}-%{commit}
-
-%build
+%gosetup
%install
-# source codes for building projects
-%if 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-echo "%%dir %%{gopath}/src/%%{import_path}/." >> devel.file-list
-# find all *.go but no *_test.go files and generate devel.file-list
-for file in $(find . -iname "*.go" \! -iname "*_test.go") ; do
- echo "%%dir %%{gopath}/src/%%{import_path}/$(dirname $file)" >> devel.file-list
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> devel.file-list
-done
-%endif
-
-# testing files for this project
-%if 0%{?with_unit_test} && 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-# find all *_test.go files and generate unit-test.file-list
-for file in $(find . -iname "*_test.go"); do
- echo "%%dir %%{gopath}/src/%%{import_path}/$(dirname $file)" >> devel.file-list
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$(dirname $file)
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> unit-test.file-list
-done
-%endif
-
-%if 0%{?with_devel}
-sort -u -o devel.file-list devel.file-list
-%endif
+%goinstall
%check
-%if 0%{?with_check} && 0%{?with_unit_test} && 0%{?with_devel}
-%if %{isgccgoarch}
-function gotest { %{gcc_go_test} "$@"; }
-%else
-%if 0%{?golang_test:1}
-function gotest { %{golang_test} "$@"; }
-%else
-function gotest { go test "$@"; }
-%endif
-%endif
-
-%if ! 0%{?with_bundled}
-export GOPATH=%{buildroot}/%{gopath}:%{gopath}
-%else
-export GOPATH=%{buildroot}/%{gopath}:$(pwd)/Godeps/_workspace:%{gopath}
-%endif
-
-%if ! 0%{?gotest:1}
-%global gotest go test
-%endif
-
-%gotest %{import_path}
-%endif
+%gochecks %{gobaseipath}
#define license tag if not already defined
%{!?_licensedir:%global license %doc}
-%if 0%{?with_devel}
%files devel -f devel.file-list
%license LICENSE
%doc README.md
-%dir %{gopath}/src/%{provider}.%{provider_tld}/%{project}
-%endif
-
-%if 0%{?with_unit_test} && 0%{?with_devel}
-%files unit-test -f unit-test.file-list
-%license LICENSE
-%doc README.md
-%endif
%changelog
+* Thu Mar 01 2018 Jan Chaloupka <jchaloup(a)redhat.com> - 1.1-11
+- Autogenerate some parts using the new macros
+
* Wed Feb 07 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 1.1-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
6 years, 1 month
Architecture specific change in rpms/golang-github-karlseguin-ccache.git
by githook-noreply@fedoraproject.org
The package rpms/golang-github-karlseguin-ccache.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/golang-github-karlseguin-ccache.g....
Change:
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
Thanks.
Full change:
============
commit 5497283488c0c723235482390c5afded93ce0daa
Author: Jan Chaloupka <jchaloup(a)redhat.com>
Date: Thu Mar 1 12:36:02 2018 +0100
Autogenerate some parts using the new macros
diff --git a/golang-github-karlseguin-ccache.spec b/golang-github-karlseguin-ccache.spec
index fb1eba1..041b91a 100644
--- a/golang-github-karlseguin-ccache.spec
+++ b/golang-github-karlseguin-ccache.spec
@@ -1,187 +1,57 @@
-# If any of the following macros should be set otherwise,
-# you can wrap any of them with the following conditions:
-# - %%if 0%%{centos} == 7
-# - %%if 0%%{?rhel} == 7
-# - %%if 0%%{?fedora} == 23
-# Or just test for particular distribution:
-# - %%if 0%%{centos}
-# - %%if 0%%{?rhel}
-# - %%if 0%%{?fedora}
-#
-# Be aware, on centos, both %%rhel and %%centos are set. If you want to test
-# rhel specific macros, you can use %%if 0%%{?rhel} && 0%%{?centos} == 0 condition.
-# (Don't forget to replace double percentage symbol with single one in order to apply a condition)
-
-# Generate devel rpm
-%global with_devel 1
-# Build project from bundled dependencies
-%global with_bundled 0
-# Build with debug info rpm
-%global with_debug 0
-# Run tests in check section
-%global with_check 1
-# Generate unit-test rpm
-%global with_unit_test 1
-
-%if 0%{?with_debug}
-%global _dwz_low_mem_die_limit 0
-%else
-%global debug_package %{nil}
-%endif
-
-
-%global provider github
-%global provider_tld com
-%global project karlseguin
-%global repo ccache
-# https://github.com/karlseguin/ccache
-%global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo}
-%global import_path %{provider_prefix}
+# http://github.com/karlseguin/ccache
+%global provider_prefix github.com/karlseguin/ccache
+%global gobaseipath %{provider_prefix}
%global commit a2d62155777b39595c825ed3824279e642a5db3c
-%global shortcommit %(c=%{commit}; echo ${c:0:7})
+%global commitdate 20161103
-Name: golang-%{provider}-%{project}-%{repo}
+%gocraftmeta -i
+
+Name: %{goname}
Version: 2.0.2
-Release: 0.4.git%{shortcommit}%{?dist}
+Release: 0.5.%{commitdate}git%{shortcommit}%{?dist}
Summary: A golang LRU Cache for high concurrency
# Detected licences
# - MIT/X11 (BSD like) at 'license.txt'
License: MIT
-URL: https://%{provider_prefix}
-Source0: https://%{provider_prefix}/archive/%{commit}/%{repo}-%{shortcommit}.tar.gz
-
-# e.g. el6 has ppc64 arch without gcc-go, so EA tag is required
-ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
-# If go_compiler is not set to 1, there is no virtual provide. Use golang instead.
-BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang}
-
-
+URL: %{gourl}
+Source0: %{gosource}
%description
%{summary}
-%if 0%{?with_devel}
%package devel
Summary: %{summary}
BuildArch: noarch
-%if 0%{?with_check} && ! 0%{?with_bundled}
-%endif
-
-
-Provides: golang(%{import_path}) = %{version}-%{release}
+BuildRequires: golang(github.com/karlseguin/expect)
%description devel
%{summary}
This package contains library source intended for
building other packages which use import path with
-%{import_path} prefix.
-%endif
-
-%if 0%{?with_unit_test} && 0%{?with_devel}
-%package unit-test-devel
-Summary: Unit tests for %{name} package
-%if 0%{?with_check}
-#Here comes all BuildRequires: PACKAGE the unit tests
-#in %%check section need for running
-%endif
-
-# test subpackage tests code from devel subpackage
-Requires: %{name}-devel = %{version}-%{release}
-
-%if 0%{?with_check} && ! 0%{?with_bundled}
-BuildRequires: golang(github.com/karlseguin/expect)
-%endif
-
-Requires: golang(github.com/karlseguin/expect)
-
-%description unit-test-devel
-%{summary}
-
-This package contains unit tests for project
-providing packages with %{import_path} prefix.
-%endif
+%{gobaseipath} prefix.
%prep
-%setup -q -n %{repo}-%{commit}
+%gosetup
-%build
%install
-# source codes for building projects
-%if 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-echo "%%dir %%{gopath}/src/%%{import_path}/." >> devel.file-list
-# find all *.go but no *_test.go files and generate devel.file-list
-for file in $(find . \( -iname "*.go" -or -iname "*.s" \) \! -iname "*_test.go") ; do
- dirprefix=$(dirname $file)
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$dirprefix
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> devel.file-list
-
- while [ "$dirprefix" != "." ]; do
- echo "%%dir %%{gopath}/src/%%{import_path}/$dirprefix" >> devel.file-list
- dirprefix=$(dirname $dirprefix)
- done
-done
-%endif
-
-# testing files for this project
-%if 0%{?with_unit_test} && 0%{?with_devel}
-install -d -p %{buildroot}/%{gopath}/src/%{import_path}/
-# find all *_test.go files and generate unit-test-devel.file-list
-for file in $(find . -iname "*_test.go") ; do
- dirprefix=$(dirname $file)
- install -d -p %{buildroot}/%{gopath}/src/%{import_path}/$dirprefix
- cp -pav $file %{buildroot}/%{gopath}/src/%{import_path}/$file
- echo "%%{gopath}/src/%%{import_path}/$file" >> unit-test-devel.file-list
-
- while [ "$dirprefix" != "." ]; do
- echo "%%dir %%{gopath}/src/%%{import_path}/$dirprefix" >> devel.file-list
- dirprefix=$(dirname $dirprefix)
- done
-done
-%endif
-
-%if 0%{?with_devel}
-sort -u -o devel.file-list devel.file-list
-%endif
+%goinstall
%check
-%if 0%{?with_check} && 0%{?with_unit_test} && 0%{?with_devel}
-%if ! 0%{?with_bundled}
-export GOPATH=%{buildroot}/%{gopath}:%{gopath}
-%else
-# No dependency directories so far
-
-export GOPATH=%{buildroot}/%{gopath}:%{gopath}
-%endif
-
-%if ! 0%{?gotest:1}
-%global gotest go test
-%endif
-
-%gotest %{import_path}
-%endif
+%gochecks %{gobaseipath}
#define license tag if not already defined
%{!?_licensedir:%global license %doc}
-
-%if 0%{?with_devel}
%files devel -f devel.file-list
%license license.txt
%doc readme.md
-%dir %{gopath}/src/%{provider}.%{provider_tld}/%{project}
-%endif
-
-%if 0%{?with_unit_test} && 0%{?with_devel}
-%files unit-test-devel -f unit-test-devel.file-list
-%license license.txt
-%doc readme.md
-%endif
%changelog
+* Thu Mar 01 2018 Jan Chaloupka <jchaloup(a)redhat.com> - 2.0.2-0.5.20161103gita2d6215
+- Autogenerate some parts using the new macros
+
* Wed Feb 07 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.0.2-0.4.gita2d6215
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
6 years, 1 month
Architecture specific change in rpms/ProDy.git
by githook-noreply@fedoraproject.org
The package rpms/ProDy.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/ProDy.git/commit/?id=3c5c120b251a....
Change:
-ExcludeArch: ppc64 s390x
Thanks.
Full change:
============
commit 3c5c120b251a8b9e97a1a3839e04621cee4d53ff
Author: sagitter <sagitter(a)fedoraproject.org>
Date: Thu Mar 1 18:39:06 2018 +0100
Release 1.9 final (1.9.3 post-release)
diff --git a/.gitignore b/.gitignore
index 0c4b06e..c58bec7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@
/ProDy-1.8.tar.gz
/ProDy-1.8.2.tar.gz
/ProDy-1.9.3.tar.gz
+/ProDy-1.9.tar.gz
diff --git a/ProDy.spec b/ProDy.spec
index 58a9e79..25d5d5b 100644
--- a/ProDy.spec
+++ b/ProDy.spec
@@ -1,8 +1,13 @@
+## https://github.com/prody/ProDy/issues/266
+ExcludeArch: ppc64 s390x
+
%if 0%{?fedora}
%global with_python3 1
%endif
-%global with_check 1
+# Tests need internet connection;
+# correctly executed in local.
+%global with_check 0
%if 0%{?rhel} && 0%{?rhel} <= 6
%{!?__python2: %global __python2 /usr/bin/python2}
@@ -25,14 +30,13 @@
Name: ProDy
Summary: Application for protein structure, dynamics and sequence analysis
Version: 1.9.3
-Release: 4%{?dist}
+Release: 5.final%{?dist}
License: GPLv3+
Group: Applications/Engineering
URL: http://www.csb.pitt.edu/ProDy
-Source0: https://github.com/prody/ProDy/archive/v%{version}.tar.gz/%{name}-%{versi...
+Source0: https://github.com/prody/ProDy/archive/v%{version}.tar.gz/%{name}-1.9.tar.gz
-## https://github.com/prody/ProDy/issues/266
-ExcludeArch: ppc64 s390x
+BuildRequires: gcc
%description
ProDy is a free and open-source Python package for protein structure, dynamics,
@@ -59,7 +63,7 @@ BuildRequires: python2-devel
BuildRequires: python-nose
BuildRequires: python-argparse
BuildRequires: scipy
-BuildRequires: python-biopython
+BuildRequires: python2-biopython
BuildRequires: numpy
BuildRequires: python-matplotlib
BuildRequires: python-unittest2
@@ -67,7 +71,7 @@ BuildRequires: pyparsing
Requires: python-argparse
Requires: pyparsing
-Requires: python-biopython
+Requires: python2-biopython
Requires: ipython, pyparsing
Requires: scipy
@@ -87,6 +91,8 @@ visual analysis.
%if 0%{?with_python3}
%package -n python3-%{name}
Summary: Application for protein structure, dynamics and sequence analysis
+%{?python_provide:%python_provide python3-%{name}}
+Provides: ProDy-python3 = 0:%{version}-%{release}
BuildRequires: python3-devel
BuildRequires: python3-nose
@@ -104,7 +110,6 @@ Requires: python3-pyparsing
## Explicit library require for using plotting functions
Requires: python3-matplotlib
-%{?python_provide:%python_provide python3-%{name}}
%description -n python3-%{name}
This is ProDy Python3 package for protein structure, dynamics,
@@ -118,18 +123,15 @@ visual analysis.
%prep
%setup -qc
-mv %{name}-%{version} python2
-pushd python2
-## Removing bundled files
-rm prody/atomic/pyparsing*
-rm -rf prody/KDTree
-rm prody/proteins/pairwise2.py prody/proteins/cpairwise2.c
-rm prody/apps/argparse.py
-popd
+rm -rf %{name}-1.9/kdtree
+
+%if 0%{?rhel}
+cp -a %{name}-1.9 python2
+%endif
%if 0%{?with_python3}
-cp -a python2 python3
+mv %{name}-1.9 python3
%endif # with_python3
%build
@@ -214,21 +216,6 @@ popd
##Some tests skipped for missing internet connections on koji
pushd python2/scripts
PYTHONPATH=$RPM_BUILD_ROOT%{python2_sitearch} nosetests --verbosity=2 \
- -e test_select.py \
-%if 0%{?rhel} && 0%{?rhel} < 7
- -e test_frame.py \
- -e test_dcdfile.py \
- -e test_analysis.py \
- -e test_kdtree.py \
- -e test_ensemble.py \
- -e test_prody_anm.py \
- -e test_prody_gnm.py \
- -e test_prody_catdcd.py \
- -e test_prody_pca.py \
- -e test_prody_examples.py \
- -e test_enms.py \
- -e test_editing.py \
-%endif
-w $RPM_BUILD_ROOT%{python2_sitearch}/prody/tests --tests prody -a '!slow'
popd
%endif
@@ -236,16 +223,6 @@ popd
%if 0%{?with_python3}
pushd python3/scripts
PYTHONPATH=$RPM_BUILD_ROOT%{python3_sitearch} nosetests-%{python3_version} --verbosity=2 \
- -e test_atomic.py \
- -e test_pdbfile.py \
- -e test_measure.py \
- -e test_wwpdb.py \
- -e test_localpdb.py \
- -e test_msafile.py \
- -e test_pathtools.py \
- -e test_select.py \
- -e test_dcdfile.py \
- -e test_enms.py \
-w $RPM_BUILD_ROOT%{python3_sitearch}/prody/tests --tests prody -a '!slow'
popd
%endif
@@ -283,6 +260,9 @@ popd
%endif
%changelog
+* Wed Feb 28 2018 Antonio Trande <sagitterATfedoraproject.org> - 1.9.3-5.final
+- Release 1.9 final (1.9.3 post-release)
+
* Mon Feb 19 2018 Antonio Trande <sagitterATfedoraproject.org> - 1.9.3-4
- Fix python3 shebang
diff --git a/sources b/sources
index 9234da4..6ffa941 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (ProDy-1.9.3.tar.gz) = a1ef78863116c92e4389435b037480da83187ded9bccb62006eabdec3db29fbbcaeb5eeb626faf4ca6ebded8daee3d55f8f1a72db316ddd8fe4ecd40d795a82d
+SHA512 (ProDy-1.9.tar.gz) = 2d2f674eea685bf1cb81b199502ac92afbf0c560a973de99f72cd5af9ed7ea5a59581adb11c4ba8e97479f592035c7b44dcd45d28da41a56ba11e4c36a3fbec9
6 years, 1 month