Sync from SUSE:SLFO:Main coolkey revision 49a1525bab253554619a9cae784ac586
This commit is contained in:
commit
ba9ee4f8e8
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
## Default LFS
|
||||||
|
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zst filter=lfs diff=lfs merge=lfs -text
|
3
baselibs.conf
Normal file
3
baselibs.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
coolkey
|
||||||
|
+/usr/lib(64)?/pkcs11/*.so
|
||||||
|
requires "coolkey = <version>"
|
109
coolkey-1.1.0-fail-on-bad-mechanisms.patch
Normal file
109
coolkey-1.1.0-fail-on-bad-mechanisms.patch
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
diff -up ./src/coolkey/coolkey.cpp.fail-on-bad-mechanisms ./src/coolkey/coolkey.cpp
|
||||||
|
--- ./src/coolkey/coolkey.cpp.fail-on-bad-mechanisms 2016-06-16 14:36:05.934755563 -0700
|
||||||
|
+++ ./src/coolkey/coolkey.cpp 2016-06-16 14:36:05.945755372 -0700
|
||||||
|
@@ -77,7 +77,8 @@ rsaMechanismList[] = {
|
||||||
|
|
||||||
|
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} }
|
||||||
|
+ {CKM_ECDSA,{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);
|
||||||
|
diff -up ./src/coolkey/slot.cpp.fail-on-bad-mechanisms ./src/coolkey/slot.cpp
|
||||||
|
--- ./src/coolkey/slot.cpp.fail-on-bad-mechanisms 2016-06-16 14:36:05.943755407 -0700
|
||||||
|
+++ ./src/coolkey/slot.cpp 2016-06-16 15:07:40.255882660 -0700
|
||||||
|
@@ -4185,11 +4185,30 @@ Slot::signInit(SessionHandleSuffix suffi
|
||||||
|
{
|
||||||
|
refreshTokenState();
|
||||||
|
SessionIter session = findSession(suffix);
|
||||||
|
+ PKCS11Object *key = getKeyFromHandle(hKey);
|
||||||
|
if( session == sessions.end() ) {
|
||||||
|
throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
|
||||||
|
}
|
||||||
|
+ if (pMechanism == NULL) {
|
||||||
|
+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (pMechanism->mechanism) {
|
||||||
|
+ case CKM_RSA_PKCS:
|
||||||
|
+ if (key->getKeyType() != Key::rsa) {
|
||||||
|
+ throw PKCS11Exception(CKR_KEY_TYPE_INCONSISTENT);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case CKM_ECDSA:
|
||||||
|
+ if (key->getKeyType() != Key::ecc) {
|
||||||
|
+ throw PKCS11Exception(CKR_KEY_TYPE_INCONSISTENT);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ throw PKCS11Exception(CKR_MECHANISM_INVALID);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- session->signatureState.initialize(getKeyFromHandle(hKey));
|
||||||
|
+ session->signatureState.initialize(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -4198,11 +4217,24 @@ Slot::decryptInit(SessionHandleSuffix su
|
||||||
|
{
|
||||||
|
refreshTokenState();
|
||||||
|
SessionIter session = findSession(suffix);
|
||||||
|
+ PKCS11Object *key = getKeyFromHandle(hKey);
|
||||||
|
if( session == sessions.end() ) {
|
||||||
|
throw PKCS11Exception(CKR_SESSION_HANDLE_INVALID);
|
||||||
|
}
|
||||||
|
+ if (pMechanism == NULL) {
|
||||||
|
+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
|
||||||
|
+ }
|
||||||
|
+ switch (pMechanism->mechanism) {
|
||||||
|
+ case CKM_RSA_PKCS:
|
||||||
|
+ if (key->getKeyType() != Key::rsa) {
|
||||||
|
+ throw PKCS11Exception(CKR_KEY_TYPE_INCONSISTENT);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ throw PKCS11Exception(CKR_MECHANISM_INVALID);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- session->decryptionState.initialize(getKeyFromHandle(hKey));
|
||||||
|
+ session->decryptionState.initialize(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -5008,8 +5040,23 @@ Slot::derive(SessionHandleSuffix suffix,
|
||||||
|
|
||||||
|
ECCKeyAgreementParams params(CryptParams::ECC_DEFAULT_KEY_SIZE);
|
||||||
|
SessionIter session = findSession(suffix);
|
||||||
|
+ PKCS11Object *key=getKeyFromHandle(hBaseKey);
|
||||||
|
|
||||||
|
- session->keyAgreementState.initialize(getKeyFromHandle(hBaseKey));
|
||||||
|
+ if (pMechanism == NULL ) {
|
||||||
|
+ throw PKCS11Exception(CKR_ARGUMENTS_BAD);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (pMechanism->mechanism) {
|
||||||
|
+ case CKM_ECDH1_DERIVE:
|
||||||
|
+ if (key->getKeyType() != Key::ecc) {
|
||||||
|
+ throw PKCS11Exception(CKR_KEY_TYPE_INCONSISTENT);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ throw PKCS11Exception(CKR_MECHANISM_INVALID);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ session->keyAgreementState.initialize(key);
|
||||||
|
deriveECC(suffix, pMechanism, hBaseKey, pTemplate, ulAttributeCount,
|
||||||
|
phKey, params);
|
||||||
|
|
||||||
|
@@ -5018,9 +5065,6 @@ Slot::derive(SessionHandleSuffix suffix,
|
||||||
|
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;
|
||||||
|
|
11
coolkey-1.1.0-fix-spurious-event.patch
Normal file
11
coolkey-1.1.0-fix-spurious-event.patch
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
diff -up ./src/coolkey/slot.cpp.fix-spurious ./src/coolkey/slot.cpp
|
||||||
|
--- ./src/coolkey/slot.cpp.fix-spurious 2014-09-26 15:31:17.277958895 -0700
|
||||||
|
+++ ./src/coolkey/slot.cpp 2014-09-26 15:34:33.218313227 -0700
|
||||||
|
@@ -1412,6 +1412,7 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
|
||||||
|
#endif
|
||||||
|
} while ((status == CKYSUCCESS) ||
|
||||||
|
(CKYCardContext_GetLastError(context) == SCARD_E_TIMEOUT) ||
|
||||||
|
+ (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) );
|
12
coolkey-1.1.0-max-cpu-bug.patch
Normal file
12
coolkey-1.1.0-max-cpu-bug.patch
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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);
|
||||||
|
}
|
61
coolkey-1.1.0-more-keys.patch
Normal file
61
coolkey-1.1.0-more-keys.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
diff -up ./src/coolkey/slot.cpp.more_keys ./src/coolkey/slot.cpp
|
||||||
|
--- ./src/coolkey/slot.cpp.more_keys 2016-06-16 11:50:01.027432856 -0700
|
||||||
|
+++ ./src/coolkey/slot.cpp 2016-06-16 11:50:13.267224824 -0700
|
||||||
|
@@ -32,7 +32,8 @@
|
||||||
|
|
||||||
|
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
-
|
||||||
|
+#define MAX_NUM_KEYS 32
|
||||||
|
+#define MAX_NUM_CERTS 32
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define PRINTF(args) printf args
|
||||||
|
@@ -3458,7 +3459,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 +4155,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 +4912,6 @@ Slot::generateRandom(SessionHandleSuffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define MAX_NUM_KEYS 8
|
||||||
|
unsigned int
|
||||||
|
Slot::getRSAKeySize(PKCS11Object *key)
|
||||||
|
{
|
||||||
|
diff -up ./src/coolkey/slot.h.more_keys ./src/coolkey/slot.h
|
||||||
|
--- ./src/coolkey/slot.h.more_keys 2016-06-16 11:50:08.627303984 -0700
|
||||||
|
+++ ./src/coolkey/slot.h 2016-06-16 11:54:08.872153180 -0700
|
||||||
|
@@ -512,7 +512,17 @@ class Slot {
|
||||||
|
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 + 10;
|
||||||
|
+ }
|
||||||
|
+ return 0x0100 + char_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually get the size of a key in bits from the card
|
18
coolkey-1.1.0-noapplet.patch
Normal file
18
coolkey-1.1.0-noapplet.patch
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
diff -up ./src/coolkey/slot.cpp.noapplet ./src/coolkey/slot.cpp
|
||||||
|
--- ./src/coolkey/slot.cpp.noapplet 2013-09-30 14:30:40.069595018 -0700
|
||||||
|
+++ ./src/coolkey/slot.cpp 2013-09-30 14:31:27.488595000 -0700
|
||||||
|
@@ -762,13 +762,7 @@ Slot::connectToToken()
|
||||||
|
CKYCardConnection_GetLastError(conn));
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
- /* CARD is a PIV card */
|
||||||
|
- state |= PIV_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
|
||||||
|
- isVersion1Key = 0;
|
||||||
|
- needLogin = 1;
|
||||||
|
- mCoolkey = 0;
|
||||||
|
- mOldCAC = 0;
|
||||||
|
- mCACLocalLogin = getPIVLoginType();
|
||||||
|
+ /* CARD is unknown */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state |= CAC_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
|
210
coolkey-1.1.0-p15-coverity.patch
Normal file
210
coolkey-1.1.0-p15-coverity.patch
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
diff -up ./src/coolkey/object.cpp.p15-coverity ./src/coolkey/object.cpp
|
||||||
|
--- ./src/coolkey/object.cpp.p15-coverity 2015-07-06 18:02:34.604191118 -0700
|
||||||
|
+++ ./src/coolkey/object.cpp 2015-07-06 19:06:04.432062377 -0700
|
||||||
|
@@ -1558,7 +1558,7 @@ unsigned long GetBits(const CKYByte *ent
|
||||||
|
/* turn the flags into an int */
|
||||||
|
for (i=0; i < entrySize; i++) {
|
||||||
|
CKYByte c = rev[entry[i]];
|
||||||
|
- bits = bits | (c << i*8);
|
||||||
|
+ bits = bits | (((unsigned long)c) << (i*8));
|
||||||
|
}
|
||||||
|
return bits | bitFlag;
|
||||||
|
}
|
||||||
|
@@ -1585,8 +1585,8 @@ CKYStatus PK15ObjectPath::setObjectPath(
|
||||||
|
if (entry == NULL) { return CKYINVALIDDATA; }
|
||||||
|
tagSize = entry - current;
|
||||||
|
current += entrySize + tagSize;
|
||||||
|
+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
size -= (entrySize +tagSize);
|
||||||
|
- if (size < 0) { return CKYINVALIDDATA; }
|
||||||
|
status = CKYBuffer_Replace(&path, 0, entry, entrySize);
|
||||||
|
if (status != CKYSUCCESS) {
|
||||||
|
return status;
|
||||||
|
@@ -1598,8 +1598,8 @@ CKYStatus PK15ObjectPath::setObjectPath(
|
||||||
|
if (entry == NULL) { return CKYINVALIDDATA; }
|
||||||
|
tagSize = entry - current;
|
||||||
|
current += entrySize + tagSize;
|
||||||
|
+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
size -= (entrySize +tagSize);
|
||||||
|
- if (size < 0) { return CKYINVALIDDATA; }
|
||||||
|
if (entrySize > 5) { return CKYINVALIDDATA; }
|
||||||
|
for (index = 0, i=0; i < entrySize; i++) {
|
||||||
|
index = (index << 8) + (unsigned int) entry[i];
|
||||||
|
@@ -1612,8 +1612,8 @@ CKYStatus PK15ObjectPath::setObjectPath(
|
||||||
|
if (entry == NULL) { return CKYINVALIDDATA; }
|
||||||
|
tagSize = entry - current;
|
||||||
|
current += entrySize + tagSize;
|
||||||
|
+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
size -= (entrySize +tagSize);
|
||||||
|
- if (size < 0) { return CKYINVALIDDATA; }
|
||||||
|
if (entrySize > 5) { return CKYINVALIDDATA; }
|
||||||
|
for (length = 0, i=0; i < entrySize; i++) {
|
||||||
|
length = (length << 8) + (unsigned int) entry[i];
|
||||||
|
@@ -1741,8 +1741,8 @@ set_key_type:
|
||||||
|
/* point current to the next section (cass attributes) */
|
||||||
|
tagSize = commonAttributes - current;
|
||||||
|
current += commonSize + tagSize;
|
||||||
|
+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
currentSize -= (commonSize +tagSize);
|
||||||
|
- if (currentSize < 0) { return CKYINVALIDDATA; }
|
||||||
|
|
||||||
|
/* get the CKA_LABEL */
|
||||||
|
if (commonAttributes[0] != ASN1_UTF8_STRING) { return CKYINVALIDDATA; }
|
||||||
|
@@ -1835,8 +1835,8 @@ PK15Object::completeCertObject(const CKY
|
||||||
|
/* point current to the next section (type attributes) */
|
||||||
|
tagSize = commonCertAttributes - current;
|
||||||
|
current += commonSize + tagSize;
|
||||||
|
+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
currentSize -= (commonSize +tagSize);
|
||||||
|
- if (currentSize < 0) { return CKYINVALIDDATA; }
|
||||||
|
|
||||||
|
/* get the id */
|
||||||
|
if (commonCertAttributes[0] != ASN1_OCTET_STRING) { return CKYINVALIDDATA; }
|
||||||
|
@@ -1907,8 +1907,8 @@ PK15Object::completeAuthObject(const CKY
|
||||||
|
if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
|
||||||
|
tagSize = commonAuthAttributes - current;
|
||||||
|
current += commonSize + tagSize;
|
||||||
|
+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
currentSize -= (commonSize + tagSize);
|
||||||
|
- if (currentSize < 0) { return CKYINVALIDDATA; }
|
||||||
|
if (commonAuthAttributes[0] != ASN1_OCTET_STRING) {
|
||||||
|
return CKYINVALIDDATA;
|
||||||
|
}
|
||||||
|
@@ -1930,8 +1930,8 @@ PK15Object::completeAuthObject(const CKY
|
||||||
|
if (commonAuthAttributes == NULL) { return CKYINVALIDDATA; }
|
||||||
|
tagSize = commonAuthAttributes - current;
|
||||||
|
current += commonSize + tagSize;
|
||||||
|
- currentSize -= (commonSize +tagSize);
|
||||||
|
- if (currentSize < 0) { return CKYINVALIDDATA; }
|
||||||
|
+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
+ currentSize -= (commonSize + tagSize);
|
||||||
|
/*
|
||||||
|
* parse the Pin Auth Attributes
|
||||||
|
* pinFlags BIT_STRING
|
||||||
|
@@ -2093,8 +2093,8 @@ PK15Object::completeKeyObject(const CKYB
|
||||||
|
/* point current to the next section (sublcass attributes) */
|
||||||
|
tagSize = commonKeyAttributes - current;
|
||||||
|
current += commonSize + tagSize;
|
||||||
|
- currentSize -= (commonSize +tagSize);
|
||||||
|
- if (currentSize < 0) { return CKYINVALIDDATA; }
|
||||||
|
+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
+ currentSize -= (commonSize + tagSize);
|
||||||
|
|
||||||
|
/* get the id */
|
||||||
|
if (commonKeyAttributes[0] != ASN1_OCTET_STRING) { return CKYINVALIDDATA; }
|
||||||
|
@@ -2263,8 +2263,8 @@ CKYStatus PK15Object::completePrivKeyObj
|
||||||
|
/* point current to the next section (type attributes) */
|
||||||
|
tagSize = commonPrivKeyAttributes - current;
|
||||||
|
current += commonSize + tagSize;
|
||||||
|
+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
currentSize -= (commonSize +tagSize);
|
||||||
|
- if (currentSize < 0) { return CKYINVALIDDATA; }
|
||||||
|
|
||||||
|
/* subjectName */
|
||||||
|
if (commonPrivKeyAttributes[0] == ASN1_SEQUENCE) {
|
||||||
|
@@ -2385,8 +2385,8 @@ PK15Object::completePubKeyObject(const C
|
||||||
|
/* point current to the next section (type attributes) */
|
||||||
|
tagSize = commonPubKeyAttributes - current;
|
||||||
|
current += commonSize + tagSize;
|
||||||
|
- currentSize -= (commonSize +tagSize);
|
||||||
|
- if (currentSize < 0) { return CKYINVALIDDATA; }
|
||||||
|
+ if (currentSize < (commonSize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
+ currentSize -= (commonSize + tagSize);
|
||||||
|
|
||||||
|
/* subjectName */
|
||||||
|
if (commonPubKeyAttributes[0] == ASN1_SEQUENCE) {
|
||||||
|
@@ -2535,8 +2535,8 @@ PK15Object::completeRawPublicKey(const C
|
||||||
|
if (entry == NULL) { return CKYINVALIDDATA; }
|
||||||
|
tagSize = entry - current;
|
||||||
|
current += entrySize + tagSize;
|
||||||
|
+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
size -= (entrySize +tagSize);
|
||||||
|
- if (size < 0) { return CKYINVALIDDATA; }
|
||||||
|
if ((entry[0] == 0) && (entrySize > 1)) {
|
||||||
|
entry++; entrySize--;
|
||||||
|
}
|
||||||
|
@@ -2548,8 +2548,8 @@ PK15Object::completeRawPublicKey(const C
|
||||||
|
if (entry == NULL) { return CKYINVALIDDATA; }
|
||||||
|
tagSize = entry - current;
|
||||||
|
current += entrySize + tagSize;
|
||||||
|
- size -= (entrySize +tagSize);
|
||||||
|
- if (size < 0) { return CKYINVALIDDATA; }
|
||||||
|
+ if (size < (entrySize + tagSize)) { return CKYINVALIDDATA; }
|
||||||
|
+ size -= (entrySize + tagSize);
|
||||||
|
if ((entry[0] == 0) && (entrySize > 1)) {
|
||||||
|
entry++; entrySize--;
|
||||||
|
}
|
||||||
|
@@ -2682,11 +2682,11 @@ DEREncodedTokenInfo::DEREncodedTokenInfo
|
||||||
|
if (entry == NULL) return;
|
||||||
|
tagSize = entry - current;
|
||||||
|
current += tagSize + entrySize;
|
||||||
|
+ if (size < tagSize + entrySize) return;
|
||||||
|
size -= tagSize + entrySize;
|
||||||
|
if (entrySize < 1) {
|
||||||
|
version = *entry;
|
||||||
|
}
|
||||||
|
- if (size < 0) return;
|
||||||
|
|
||||||
|
/* get the serial number */
|
||||||
|
if (current[0] != ASN1_OCTET_STRING) { return ; }
|
||||||
|
@@ -2729,6 +2729,8 @@ DEREncodedTokenInfo::DEREncodedTokenInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
@@ -2739,6 +2741,7 @@ DEREncodedTokenInfo::DEREncodedTokenInfo
|
||||||
|
size -= tagSize + entrySize;
|
||||||
|
bits = GetBits(entry, entrySize,8,2);
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -up ./src/coolkey/slot.cpp.p15-coverity ./src/coolkey/slot.cpp
|
||||||
|
--- ./src/coolkey/slot.cpp.p15-coverity 2015-07-06 18:02:34.606191081 -0700
|
||||||
|
+++ ./src/coolkey/slot.cpp 2015-07-06 18:02:34.610191006 -0700
|
||||||
|
@@ -3714,7 +3714,6 @@ void
|
||||||
|
Slot::attemptP15Login(CK_USER_TYPE user)
|
||||||
|
{
|
||||||
|
PinCache *pinCachePtr = userPinCache(user);
|
||||||
|
- const CKYBuffer *path;
|
||||||
|
|
||||||
|
if (user == CKU_USER) {
|
||||||
|
loggedIn = false;
|
||||||
|
@@ -3729,7 +3728,6 @@ Slot::attemptP15Login(CK_USER_TYPE user)
|
||||||
|
"No PKCS #15 auth object for user %d\n", user);
|
||||||
|
}
|
||||||
|
|
||||||
|
- path = auth[user]->getObjectPath().getPath();
|
||||||
|
status = selectPath(auth[user]->getObjectPath().getPath(), &result);
|
||||||
|
if( status == CKYSCARDERR ) {
|
||||||
|
handleConnectionError();
|
||||||
|
diff -up ./src/libckyapplet/cky_applet.c.p15-coverity ./src/libckyapplet/cky_applet.c
|
||||||
|
--- ./src/libckyapplet/cky_applet.c.p15-coverity 2015-07-06 18:02:34.606191081 -0700
|
||||||
|
+++ ./src/libckyapplet/cky_applet.c 2015-07-06 18:02:34.610191006 -0700
|
||||||
|
@@ -1361,6 +1361,9 @@ P15Applet_SignDecrypt(CKYCardConnection
|
||||||
|
appendLength = length;
|
||||||
|
} else {
|
||||||
|
ret = CKYBuffer_Reserve(&tmp, length);
|
||||||
|
+ if (ret != CKYSUCCESS) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
CKYBuffer_AppendBuffer(&tmp, data, offset, appendLength);
|
||||||
|
pso.chain = 0;
|
||||||
|
diff -up ./src/libckyapplet/cky_base.c.p15-coverity ./src/libckyapplet/cky_base.c
|
||||||
|
--- ./src/libckyapplet/cky_base.c.p15-coverity 2015-07-06 18:02:34.607191062 -0700
|
||||||
|
+++ ./src/libckyapplet/cky_base.c 2015-07-06 18:02:34.610191006 -0700
|
||||||
|
@@ -736,7 +736,7 @@ CKYAPDU_SetShortReceiveLen(CKYAPDU *apdu
|
||||||
|
CKYStatus ret;
|
||||||
|
|
||||||
|
if (recvlen <= CKYAPDU_MAX_DATA_LEN) {
|
||||||
|
- return APDU_SetReceiveLen(apdu, (CKYByte)(recvlen & 0xff));
|
||||||
|
+ return CKYAPDU_SetReceiveLen(apdu, (CKYByte)(recvlen & 0xff));
|
||||||
|
}
|
||||||
|
ret = CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_HEADER_LEN+2);
|
||||||
|
if (ret != CKYSUCCESS) {
|
4379
coolkey-1.1.0-p15.patch
Normal file
4379
coolkey-1.1.0-p15.patch
Normal file
File diff suppressed because it is too large
Load Diff
858
coolkey-1.1.0-rhel7-alt-cac.patch
Normal file
858
coolkey-1.1.0-rhel7-alt-cac.patch
Normal file
@ -0,0 +1,858 @@
|
|||||||
|
diff -up ./src/coolkey/coolkey.cpp.alt-cac ./src/coolkey/coolkey.cpp
|
||||||
|
--- ./src/coolkey/coolkey.cpp.alt-cac 2016-12-01 15:37:49.106167768 -0800
|
||||||
|
+++ ./src/coolkey/coolkey.cpp 2016-12-01 15:37:49.113167892 -0800
|
||||||
|
@@ -80,9 +80,16 @@ ecMechanismList[] = {
|
||||||
|
{CKM_ECDSA,{256,521,CKF_HW | CKF_SIGN | CKF_EC_F_P}},
|
||||||
|
{CKM_ECDH1_DERIVE,{256, 521, CKF_HW | CKF_DERIVE | CKF_EC_F_P} }
|
||||||
|
};
|
||||||
|
+static const MechInfo
|
||||||
|
+allMechanismList[] = {
|
||||||
|
+ {CKM_RSA_PKCS, { 1024, 4096, CKF_HW | CKF_SIGN | CKF_DECRYPT } },
|
||||||
|
+ {CKM_ECDSA,{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);
|
||||||
|
+unsigned int numAllMechanisms = sizeof(allMechanismList)/sizeof(MechInfo);
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
@@ -382,13 +389,22 @@ C_GetMechanismList(CK_SLOT_ID slotID, CK
|
||||||
|
return CKR_TOKEN_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ( slot->getIsECC()) {
|
||||||
|
+ switch (slot->getAlgs()) {
|
||||||
|
+ case ALG_ECC|ALG_RSA:
|
||||||
|
+ mechanismList = allMechanismList;
|
||||||
|
+ numMechanisms = numAllMechanisms;
|
||||||
|
+ break;
|
||||||
|
+ case ALG_ECC:
|
||||||
|
mechanismList = ecMechanismList;
|
||||||
|
numMechanisms = numECMechanisms;
|
||||||
|
- } else {
|
||||||
|
+ break;
|
||||||
|
+ case ALG_NONE:
|
||||||
|
+ case ALG_RSA:
|
||||||
|
+ default:
|
||||||
|
mechanismList = rsaMechanismList;
|
||||||
|
numMechanisms = numRSAMechanisms;
|
||||||
|
- }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if( pMechanismList != NULL ) {
|
||||||
|
if( *pulCount < numMechanisms ) {
|
||||||
|
@@ -438,13 +454,22 @@ C_GetMechanismInfo(CK_SLOT_ID slotID, CK
|
||||||
|
return CKR_TOKEN_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ( slot->getIsECC()) {
|
||||||
|
+ switch (slot->getAlgs()) {
|
||||||
|
+ case ALG_ECC|ALG_RSA:
|
||||||
|
+ mechanismList = allMechanismList;
|
||||||
|
+ numMechanisms = numAllMechanisms;
|
||||||
|
+ break;
|
||||||
|
+ case ALG_ECC:
|
||||||
|
mechanismList = ecMechanismList;
|
||||||
|
numMechanisms = numECMechanisms;
|
||||||
|
- } else {
|
||||||
|
+ break;
|
||||||
|
+ case ALG_NONE:
|
||||||
|
+ case ALG_RSA:
|
||||||
|
+ default:
|
||||||
|
mechanismList = rsaMechanismList;
|
||||||
|
numMechanisms = numRSAMechanisms;
|
||||||
|
- }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
for(unsigned int i=0; i < numMechanisms; ++i ) {
|
||||||
|
if( mechanismList[i].mech == type ) {
|
||||||
|
diff -up ./src/coolkey/object.cpp.alt-cac ./src/coolkey/object.cpp
|
||||||
|
--- ./src/coolkey/object.cpp.alt-cac 2016-12-01 15:37:49.097167608 -0800
|
||||||
|
+++ ./src/coolkey/object.cpp 2016-12-01 15:37:49.114167910 -0800
|
||||||
|
@@ -1232,7 +1232,7 @@ Reader::Reader(unsigned long muscleObjID
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-CACPrivKey::CACPrivKey(CKYByte instance, const PKCS11Object &cert) :
|
||||||
|
+CACPrivKey::CACPrivKey(CKYByte instance, const PKCS11Object &cert,bool isPIV) :
|
||||||
|
PKCS11Object( ((int)'k') << 24 | ((int)instance+'0') << 16,
|
||||||
|
instance | 0x400)
|
||||||
|
{
|
||||||
|
@@ -1242,7 +1242,9 @@ CACPrivKey::CACPrivKey(CKYByte instance,
|
||||||
|
|
||||||
|
/* So we know what the key is supposed to be used for based on
|
||||||
|
* the instance */
|
||||||
|
- if (instance == 2) {
|
||||||
|
+ /* instance 2 is usually a decryption cert. >2 are usually old decryption
|
||||||
|
+ * certs */
|
||||||
|
+ if (instance == 2 || (instance > (isPIV ? 3 : 2))) {
|
||||||
|
decrypt = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1305,8 +1307,8 @@ CACPrivKey::CACPrivKey(CKYByte instance,
|
||||||
|
CKYBuffer_FreeData(¶m2);
|
||||||
|
}
|
||||||
|
|
||||||
|
-CACPubKey::CACPubKey(CKYByte instance, const PKCS11Object &cert) :
|
||||||
|
- PKCS11Object( ((int)'k') << 24 | ((int)(instance+'5')) << 16,
|
||||||
|
+CACPubKey::CACPubKey(CKYByte instance, const PKCS11Object &cert, bool isPIV) :
|
||||||
|
+ PKCS11Object( ((int)'k') << 24 | ((int)(instance+'a')) << 16,
|
||||||
|
instance | 0x500)
|
||||||
|
{
|
||||||
|
CKYBuffer id;
|
||||||
|
@@ -1315,7 +1317,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) {
|
||||||
|
+ if (instance == 2 || (instance > (isPIV ? 3 : 2))) {
|
||||||
|
encrypt = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1359,6 +1361,9 @@ CACPubKey::CACPubKey(CKYByte instance, c
|
||||||
|
setAttribute(CKA_EC_POINT, ¶m1);
|
||||||
|
setAttribute(CKA_EC_PARAMS, ¶m2);
|
||||||
|
setAttributeULong(CKA_KEY_TYPE, CKK_EC);
|
||||||
|
+ setAttributeBool(CKA_VERIFY_RECOVER, FALSE);
|
||||||
|
+ setAttributeBool(CKA_ENCRYPT, FALSE);
|
||||||
|
+ setAttributeBool(CKA_DERIVE, encrypt);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
@@ -1376,6 +1381,26 @@ static const char *CAC_Label[] = {
|
||||||
|
"CAC ID Certificate",
|
||||||
|
"CAC Email Signature Certificate",
|
||||||
|
"CAC Email Encryption Certificate",
|
||||||
|
+ "CAC Cert 3",
|
||||||
|
+ "CAC Cert 4",
|
||||||
|
+ "CAC Cert 5",
|
||||||
|
+ "CAC Cert 6",
|
||||||
|
+ "CAC Cert 7",
|
||||||
|
+ "CAC Cert 8",
|
||||||
|
+ "CAC Cert 9",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const char *PIV_Label[] = {
|
||||||
|
+ "PIV ID Certificate",
|
||||||
|
+ "PIV Email Signature Certificate",
|
||||||
|
+ "PIV Email Encryption Certificate",
|
||||||
|
+ "PIV Card Authentication Certificate",
|
||||||
|
+ "PIV Cert 4",
|
||||||
|
+ "PIV Cert 5",
|
||||||
|
+ "PIV Cert 6",
|
||||||
|
+ "PIV Cert 7",
|
||||||
|
+ "PIV Cert 8",
|
||||||
|
+ "PIV Cert 9",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char CN_DATA[] = { 0x55, 0x4, 0x3 };
|
||||||
|
@@ -1454,7 +1479,7 @@ GetUserName(const CKYBuffer *dn)
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
-CACCert::CACCert(CKYByte instance, const CKYBuffer *derCert) :
|
||||||
|
+CACCert::CACCert(CKYByte instance, const CKYBuffer *derCert, bool isPIV) :
|
||||||
|
PKCS11Object( ((int)'c') << 24 | ((int)instance+'0') << 16,
|
||||||
|
instance | 0x600)
|
||||||
|
{
|
||||||
|
@@ -1471,7 +1496,7 @@ CACCert::CACCert(CKYByte instance, const
|
||||||
|
setAttribute(CKA_ID, &id);
|
||||||
|
CKYBuffer_FreeData(&id);
|
||||||
|
setAttributeULong(CKA_CERTIFICATE_TYPE, CKC_X_509);
|
||||||
|
- setAttribute(CKA_LABEL, CAC_Label[instance]);
|
||||||
|
+ setAttribute(CKA_LABEL, isPIV ? PIV_Label[instance] : CAC_Label[instance]);
|
||||||
|
|
||||||
|
CKYBuffer derSerial; CKYBuffer_InitEmpty(&derSerial);
|
||||||
|
CKYBuffer derSubject; CKYBuffer_InitEmpty(&derSubject);
|
||||||
|
diff -up ./src/coolkey/object.h.alt-cac ./src/coolkey/object.h
|
||||||
|
--- ./src/coolkey/object.h.alt-cac 2016-12-01 15:37:49.087167430 -0800
|
||||||
|
+++ ./src/coolkey/object.h 2016-12-01 15:37:49.115167928 -0800
|
||||||
|
@@ -219,17 +219,17 @@ class Cert : public PKCS11Object {
|
||||||
|
|
||||||
|
class CACPrivKey : public PKCS11Object {
|
||||||
|
public:
|
||||||
|
- CACPrivKey(CKYByte instance, const PKCS11Object &cert);
|
||||||
|
+ CACPrivKey(CKYByte instance, const PKCS11Object &cert, bool isPIV);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CACPubKey : public PKCS11Object {
|
||||||
|
public:
|
||||||
|
- CACPubKey(CKYByte instance, const PKCS11Object &cert);
|
||||||
|
+ CACPubKey(CKYByte instance, const PKCS11Object &cert, bool isPIV);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CACCert : public PKCS11Object {
|
||||||
|
public:
|
||||||
|
- CACCert(CKYByte instance, const CKYBuffer *derCert);
|
||||||
|
+ CACCert(CKYByte instance, const CKYBuffer *derCert, bool isPIV);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum { PK15StateInit, PK15StateNeedObject,
|
||||||
|
diff -up ./src/coolkey/slot.cpp.alt-cac ./src/coolkey/slot.cpp
|
||||||
|
--- ./src/coolkey/slot.cpp.alt-cac 2016-12-01 15:37:49.110167839 -0800
|
||||||
|
+++ ./src/coolkey/slot.cpp 2016-12-01 15:57:37.307994776 -0800
|
||||||
|
@@ -415,8 +415,9 @@ Slot::Slot(const char *readerName_, Log
|
||||||
|
slotInfoFound(false), context(context_), conn(NULL), state(UNKNOWN),
|
||||||
|
isVersion1Key(false), needLogin(false), fullTokenName(false),
|
||||||
|
mCoolkey(false), mOldCAC(false), mCACLocalLogin(false),
|
||||||
|
- pivContainer(-1), pivKey(-1), mECC(false), p15aid(0), p15odfAddr(0),
|
||||||
|
- p15tokenInfoAddr(0), p15Instance(0),
|
||||||
|
+ pivContainer(-1), pivKey(-1), maxCacCerts(MAX_CERT_SLOTS),
|
||||||
|
+ algs(ALG_NONE), p15aid(0), p15odfAddr(0), p15tokenInfoAddr(0),
|
||||||
|
+ p15Instance(0),
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
shmem(readerName_),
|
||||||
|
#endif
|
||||||
|
@@ -776,6 +777,7 @@ Slot::connectToToken()
|
||||||
|
state |= PIV_CARD | APPLET_SELECTABLE | APPLET_PERSONALIZED;
|
||||||
|
isVersion1Key = 0;
|
||||||
|
needLogin = true;
|
||||||
|
+ maxCacCerts = MAX_CERT_SLOTS;
|
||||||
|
mCoolkey = 0;
|
||||||
|
mOldCAC = 0;
|
||||||
|
mCACLocalLogin = getPIVLoginType();
|
||||||
|
@@ -927,8 +929,12 @@ Slot::getCACAid()
|
||||||
|
}
|
||||||
|
/* yes, fill in the old applets */
|
||||||
|
mOldCAC = true;
|
||||||
|
+ maxCacCerts = 1;
|
||||||
|
for (i=1; i< MAX_CERT_SLOTS; i++) {
|
||||||
|
- CACApplet_SelectPKI(conn, &cardAID[i], i, NULL);
|
||||||
|
+ status = CACApplet_SelectPKI(conn, &cardAID[i], i, NULL);
|
||||||
|
+ if (status == CKYSUCCESS) {
|
||||||
|
+ maxCacCerts = i+1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
return CKYSUCCESS;
|
||||||
|
}
|
||||||
|
@@ -986,6 +992,7 @@ Slot::getCACAid()
|
||||||
|
if (certSlot == 0) {
|
||||||
|
status = CKYAPDUFAIL; /* probably neeed a beter error code */
|
||||||
|
}
|
||||||
|
+ maxCacCerts = certSlot;
|
||||||
|
|
||||||
|
done:
|
||||||
|
CKYBuffer_FreeData(&tBuf);
|
||||||
|
@@ -2168,12 +2175,11 @@ Slot::addKeyObject(list<PKCS11Object>& o
|
||||||
|
}
|
||||||
|
keyObj.completeKey(*iter);
|
||||||
|
|
||||||
|
- /* For now this is how we determine what type of key.
|
||||||
|
- Also for now, allow only one or the other */
|
||||||
|
+ /* use key object to determine what algorithms we support */
|
||||||
|
if ( keyObj.getKeyType() == PKCS11Object::ecc) {
|
||||||
|
- mECC = true;
|
||||||
|
+ algs = (SlotAlgs) (algs | ALG_ECC);
|
||||||
|
} else {
|
||||||
|
- mECC = false;
|
||||||
|
+ algs = (SlotAlgs) (algs | ALG_RSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -2205,7 +2211,7 @@ Slot::addCertObject(list<PKCS11Object>&
|
||||||
|
void
|
||||||
|
Slot::unloadObjects()
|
||||||
|
{
|
||||||
|
- mECC = false;
|
||||||
|
+ algs = ALG_NONE;
|
||||||
|
tokenObjects.clear();
|
||||||
|
free(personName);
|
||||||
|
personName = NULL;
|
||||||
|
@@ -2269,29 +2275,42 @@ Slot::unloadObjects()
|
||||||
|
// Shared memory segments are fixed size (equal to the object memory size of
|
||||||
|
// the token).
|
||||||
|
//
|
||||||
|
+//
|
||||||
|
+//
|
||||||
|
+
|
||||||
|
+struct SlotDataPair {
|
||||||
|
+ unsigned long dataOffset;
|
||||||
|
+ unsigned long dataSize;
|
||||||
|
+};
|
||||||
|
|
||||||
|
struct SlotSegmentHeader {
|
||||||
|
unsigned short version;
|
||||||
|
unsigned short headerSize;
|
||||||
|
unsigned char valid;
|
||||||
|
- unsigned char reserved;
|
||||||
|
+ unsigned char firstCacCert;
|
||||||
|
unsigned char cuid[10];
|
||||||
|
- unsigned short reserved2;
|
||||||
|
+
|
||||||
|
+ unsigned short reserved;
|
||||||
|
unsigned short dataVersion;
|
||||||
|
unsigned short dataHeaderOffset;
|
||||||
|
unsigned short dataOffset;
|
||||||
|
unsigned long dataHeaderSize;
|
||||||
|
unsigned long dataSize;
|
||||||
|
- unsigned long cert2Offset;
|
||||||
|
- unsigned long cert2Size;
|
||||||
|
+ unsigned long nextDataOffset;
|
||||||
|
+ SlotDataPair cacCerts[MAX_CERT_SLOTS];
|
||||||
|
};
|
||||||
|
|
||||||
|
+const unsigned char NOT_A_CAC=0xff; /* place in firstCacCert field */
|
||||||
|
+const unsigned short CAC_DATA_VERSION=2;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
#define MAX_OBJECT_STORE_SIZE 15000
|
||||||
|
//
|
||||||
|
// previous development versions used a segment prefix of
|
||||||
|
// "coolkeypk11s"
|
||||||
|
//
|
||||||
|
-#define SEGMENT_PREFIX "coolkeypk11s"
|
||||||
|
+#define SEGMENT_PREFIX "coolkeypk11t" // update segment since the old cache was
|
||||||
|
+ // incompatible
|
||||||
|
#define CAC_FAKE_CUID "CAC Certs"
|
||||||
|
SlotMemSegment::SlotMemSegment(const char *readerName):
|
||||||
|
segmentAddr(NULL), segmentSize(0), segment(NULL)
|
||||||
|
@@ -2320,9 +2339,8 @@ SlotMemSegment::SlotMemSegment(const cha
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- SlotSegmentHeader *segmentHeader = (SlotSegmentHeader *)segmentAddr;
|
||||||
|
if (needInit) {
|
||||||
|
- segmentHeader->valid = 0;
|
||||||
|
+ clearValid(0);
|
||||||
|
}
|
||||||
|
segmentSize = segment->getSHMemSize();
|
||||||
|
}
|
||||||
|
@@ -2396,6 +2414,18 @@ SlotMemSegment::getDataVersion() const
|
||||||
|
return segmentHeader->dataVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
+unsigned char
|
||||||
|
+SlotMemSegment::getFirstCacCert() const
|
||||||
|
+{
|
||||||
|
+ if (!segment) {
|
||||||
|
+ return NOT_A_CAC;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SlotSegmentHeader *segmentHeader = (SlotSegmentHeader *)segmentAddr;
|
||||||
|
+
|
||||||
|
+ return segmentHeader->firstCacCert;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
SlotMemSegment::setVersion(unsigned short version)
|
||||||
|
{
|
||||||
|
@@ -2419,6 +2449,18 @@ SlotMemSegment::setDataVersion(unsigned
|
||||||
|
segmentHeader->dataVersion = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+SlotMemSegment::setFirstCacCert(unsigned char firstCacCert)
|
||||||
|
+{
|
||||||
|
+ if (!segment) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SlotSegmentHeader *segmentHeader = (SlotSegmentHeader *)segmentAddr;
|
||||||
|
+
|
||||||
|
+ segmentHeader->firstCacCert = firstCacCert;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool
|
||||||
|
SlotMemSegment::isValid() const
|
||||||
|
{
|
||||||
|
@@ -2493,23 +2535,13 @@ SlotMemSegment::readCACCert(CKYBuffer *o
|
||||||
|
int size;
|
||||||
|
CKYByte *data;
|
||||||
|
|
||||||
|
- switch (instance) {
|
||||||
|
- case 0:
|
||||||
|
- data = (CKYByte *) &segmentAddr[segmentHeader->dataHeaderOffset];
|
||||||
|
- size = segmentHeader->dataHeaderSize;
|
||||||
|
- break;
|
||||||
|
- case 1:
|
||||||
|
- data = (CKYByte *) &segmentAddr[segmentHeader->dataOffset];
|
||||||
|
- size = segmentHeader->dataSize;
|
||||||
|
- break;
|
||||||
|
- case 2:
|
||||||
|
- data = (CKYByte *) &segmentAddr[segmentHeader->cert2Offset];
|
||||||
|
- size = segmentHeader->cert2Size;
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
+ if (instance >= MAX_CERT_SLOTS) {
|
||||||
|
CKYBuffer_Resize(objData, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+ data = (CKYByte *) &segmentAddr[segmentHeader->cacCerts[instance]
|
||||||
|
+ .dataOffset];
|
||||||
|
+ size = segmentHeader->cacCerts[instance].dataSize;
|
||||||
|
CKYBuffer_Replace(objData, 0, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2523,30 +2555,20 @@ SlotMemSegment::writeCACCert(const CKYBu
|
||||||
|
SlotSegmentHeader *segmentHeader = (SlotSegmentHeader *)segmentAddr;
|
||||||
|
int size = CKYBuffer_Size(data);
|
||||||
|
CKYByte *shmData;
|
||||||
|
- switch (instance) {
|
||||||
|
- case 0:
|
||||||
|
- segmentHeader->headerSize = sizeof *segmentHeader;
|
||||||
|
- segmentHeader->dataHeaderOffset = sizeof *segmentHeader;
|
||||||
|
- segmentHeader->dataHeaderSize = size;
|
||||||
|
- segmentHeader->dataOffset = segmentHeader->dataHeaderOffset + size;
|
||||||
|
- segmentHeader->dataSize = 0;
|
||||||
|
- segmentHeader->cert2Offset = segmentHeader->dataOffset;
|
||||||
|
- segmentHeader->cert2Size = 0;
|
||||||
|
- shmData = (CKYByte *) &segmentAddr[segmentHeader->dataHeaderOffset];
|
||||||
|
- break;
|
||||||
|
- case 1:
|
||||||
|
- segmentHeader->dataSize = size;
|
||||||
|
- segmentHeader->cert2Offset = segmentHeader->dataOffset + size;
|
||||||
|
- segmentHeader->cert2Size = 0;
|
||||||
|
- shmData = (CKYByte *) &segmentAddr[segmentHeader->dataOffset];
|
||||||
|
- break;
|
||||||
|
- case 2:
|
||||||
|
- segmentHeader->cert2Size = size;
|
||||||
|
- shmData = (CKYByte *) &segmentAddr[segmentHeader->cert2Offset];
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
+
|
||||||
|
+ if (instance >= MAX_CERT_SLOTS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (segmentHeader->firstCacCert == NOT_A_CAC) {
|
||||||
|
+ segmentHeader->firstCacCert = instance;
|
||||||
|
+ }
|
||||||
|
+ unsigned long dataOffset = segmentHeader->nextDataOffset;
|
||||||
|
+ segmentHeader->cacCerts[instance].dataOffset = dataOffset;
|
||||||
|
+ segmentHeader->nextDataOffset += size;
|
||||||
|
+ segmentHeader->cacCerts[instance].dataSize = size;
|
||||||
|
+ shmData = (CKYByte *) &segmentAddr[dataOffset];
|
||||||
|
+
|
||||||
|
memcpy(shmData, CKYBuffer_Data(data), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2558,15 +2580,18 @@ SlotMemSegment::clearValid(CKYByte insta
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SlotSegmentHeader *segmentHeader = (SlotSegmentHeader *)segmentAddr;
|
||||||
|
- switch (instance) {
|
||||||
|
- case 0:
|
||||||
|
- segmentHeader->headerSize = 0;
|
||||||
|
- segmentHeader->dataHeaderSize = 0;
|
||||||
|
- /* fall through */
|
||||||
|
- case 1:
|
||||||
|
- segmentHeader->dataSize = 0;
|
||||||
|
+
|
||||||
|
+ segmentHeader->headerSize = sizeof *segmentHeader;
|
||||||
|
+ segmentHeader->dataHeaderOffset = sizeof *segmentHeader;
|
||||||
|
+ segmentHeader->dataHeaderSize = 0;
|
||||||
|
+ segmentHeader->dataSize = 0;
|
||||||
|
+ for (int i=0; i < MAX_CERT_SLOTS; i++) {
|
||||||
|
+ segmentHeader->cacCerts[i].dataSize = 0;
|
||||||
|
}
|
||||||
|
+ segmentHeader->dataOffset = sizeof *segmentHeader;
|
||||||
|
+ segmentHeader->nextDataOffset = sizeof *segmentHeader;
|
||||||
|
segmentHeader->valid = 0;
|
||||||
|
+ segmentHeader->firstCacCert = NOT_A_CAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -2882,8 +2907,7 @@ berProcess(CKYBuffer *buf, int matchTag,
|
||||||
|
|
||||||
|
|
||||||
|
CKYStatus
|
||||||
|
-Slot::readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
|
||||||
|
- bool throwException)
|
||||||
|
+Slot::readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize)
|
||||||
|
{
|
||||||
|
CKYStatus status;
|
||||||
|
CKYISOStatus apduRC;
|
||||||
|
@@ -2897,9 +2921,6 @@ Slot::readCACCertificateFirst(CKYBuffer
|
||||||
|
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) {
|
||||||
|
@@ -2940,10 +2961,10 @@ Slot::readCACCertificateFirst(CKYBuffer
|
||||||
|
if (mOldCAC) {
|
||||||
|
/* get the first 100 bytes of the cert */
|
||||||
|
status = CACApplet_GetCertificateFirst(conn, cert, nextSize, &apduRC);
|
||||||
|
- if (throwException && (status != CKYSUCCESS)) {
|
||||||
|
- handleConnectionError();
|
||||||
|
+ if (status == CKYSUCCESS) {
|
||||||
|
+ return status;
|
||||||
|
}
|
||||||
|
- return status;
|
||||||
|
+ /* try to use CACApplet_ReadFile before we give up */
|
||||||
|
}
|
||||||
|
|
||||||
|
CKYBuffer tBuf;
|
||||||
|
@@ -2959,11 +2980,11 @@ Slot::readCACCertificateFirst(CKYBuffer
|
||||||
|
|
||||||
|
/* handle the new CAC card read */
|
||||||
|
/* read the TLV */
|
||||||
|
- status = CACApplet_ReadFile(conn, CAC_TAG_FILE, &tBuf, NULL);
|
||||||
|
+ status = CACApplet_ReadFile(conn, CAC_TAG_FILE, &tBuf, &apduRC);
|
||||||
|
if (status != CKYSUCCESS) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
- status = CACApplet_ReadFile(conn, CAC_VALUE_FILE, &vBuf, NULL);
|
||||||
|
+ status = CACApplet_ReadFile(conn, CAC_VALUE_FILE, &vBuf, &apduRC);
|
||||||
|
if (status != CKYSUCCESS) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
@@ -3199,14 +3220,12 @@ Slot::loadCACCert(CKYByte instance)
|
||||||
|
CKYStatus status = CKYSUCCESS;
|
||||||
|
CKYBuffer cert;
|
||||||
|
CKYBuffer rawCert;
|
||||||
|
- CKYBuffer shmCert;
|
||||||
|
CKYSize nextSize;
|
||||||
|
|
||||||
|
OSTime time = OSTimeNow();
|
||||||
|
|
||||||
|
CKYBuffer_InitEmpty(&cert);
|
||||||
|
CKYBuffer_InitEmpty(&rawCert);
|
||||||
|
- CKYBuffer_InitEmpty(&shmCert);
|
||||||
|
|
||||||
|
//
|
||||||
|
// not all CAC cards have all the PKI instances
|
||||||
|
@@ -3215,78 +3234,24 @@ Slot::loadCACCert(CKYByte instance)
|
||||||
|
try {
|
||||||
|
selectCACApplet(instance, false);
|
||||||
|
} catch(PKCS11Exception& e) {
|
||||||
|
- // all CAC's must have instance '0', throw the error it
|
||||||
|
- // they don't.
|
||||||
|
- if (instance == 0) throw e;
|
||||||
|
- // If the CAC doesn't have instance '2', and we were updating
|
||||||
|
- // the shared memory, set it to valid now.
|
||||||
|
- if ((instance == 2) && !shmem.isValid()) {
|
||||||
|
- shmem.setValid();
|
||||||
|
- }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log->log("CAC Cert %d: select CAC applet: %d ms\n",
|
||||||
|
instance, OSTimeNow() - time);
|
||||||
|
|
||||||
|
- 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);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- unsigned short dataVersion = 1;
|
||||||
|
- CKYBool needRead = 1;
|
||||||
|
-
|
||||||
|
/* see if it matches the shared memory */
|
||||||
|
- if (shmem.isValid() && shmem.getDataVersion() == dataVersion) {
|
||||||
|
- shmem.readCACCert(&shmCert, instance);
|
||||||
|
- CKYSize certSize = CKYBuffer_Size(&rawCert);
|
||||||
|
- CKYSize shmCertSize = CKYBuffer_Size(&shmCert);
|
||||||
|
- const CKYByte *shmData = CKYBuffer_Data(&shmCert);
|
||||||
|
-
|
||||||
|
- if (instance != 0) {
|
||||||
|
- needRead = 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (shmCertSize >= certSize) {
|
||||||
|
- if (memcmp(shmData, CKYBuffer_Data(&rawCert), certSize) == 0) {
|
||||||
|
- /* yes it does, no need to read the rest of the cert, use
|
||||||
|
- * the cache */
|
||||||
|
- CKYBuffer_Replace(&rawCert, 0, shmData, shmCertSize);
|
||||||
|
- needRead = 0;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (!needRead && (shmCertSize == 0)) {
|
||||||
|
+ if (shmem.isValid() && shmem.getDataVersion() == CAC_DATA_VERSION) {
|
||||||
|
+ shmem.readCACCert(&rawCert, instance);
|
||||||
|
+ if (CKYBuffer_Size(&rawCert) == 0) {
|
||||||
|
/* no cert of this type, just return */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
- CKYBuffer_FreeData(&shmCert);
|
||||||
|
-
|
||||||
|
- if (needRead) {
|
||||||
|
- /* it doesn't, read the new cert and update the cache */
|
||||||
|
- if (instance == 0) {
|
||||||
|
- shmem.clearValid(0);
|
||||||
|
- shmem.setVersion(SHMEM_VERSION);
|
||||||
|
- shmem.setDataVersion(dataVersion);
|
||||||
|
- } else {
|
||||||
|
- status = readCACCertificateFirst(&rawCert, &nextSize, false);
|
||||||
|
-
|
||||||
|
- 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) {
|
||||||
|
- /* we've attempted to read all the certs, shared memory
|
||||||
|
- * is now valid */
|
||||||
|
- shmem.setValid();
|
||||||
|
- }
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
+ } else {
|
||||||
|
+ status = readCACCertificateFirst(&rawCert, &nextSize);
|
||||||
|
+ if ((status != CKYSUCCESS) || (CKYBuffer_Size(&rawCert) <= 1)) {
|
||||||
|
+ /*this cert doesn't exist, go to the next one */
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextSize) {
|
||||||
|
@@ -3298,9 +3263,6 @@ Slot::loadCACCert(CKYByte instance)
|
||||||
|
handleConnectionError();
|
||||||
|
}
|
||||||
|
shmem.writeCACCert(&rawCert, instance);
|
||||||
|
- if (instance == 2) {
|
||||||
|
- shmem.setValid();
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3368,14 +3330,17 @@ Slot::loadCACCert(CKYByte instance)
|
||||||
|
log->log("CAC Cert %d: Cert has been uncompressed: %d ms\n",
|
||||||
|
instance, OSTimeNow() - time);
|
||||||
|
|
||||||
|
- CACCert certObj(instance, &cert);
|
||||||
|
- CACPrivKey privKey(instance, certObj);
|
||||||
|
- CACPubKey pubKey(instance, certObj);
|
||||||
|
+ bool isPIV = (bool)((state & PIV_CARD) == PIV_CARD);
|
||||||
|
+ CACCert certObj(instance, &cert, isPIV);
|
||||||
|
+ CACPrivKey privKey(instance, certObj, isPIV);
|
||||||
|
+ CACPubKey pubKey(instance, certObj, isPIV);
|
||||||
|
tokenObjects.push_back(privKey);
|
||||||
|
tokenObjects.push_back(pubKey);
|
||||||
|
tokenObjects.push_back(certObj);
|
||||||
|
if ( pubKey.getKeyType() == PKCS11Object::ecc) {
|
||||||
|
- mECC = 1;
|
||||||
|
+ algs = (SlotAlgs) (algs | ALG_ECC);
|
||||||
|
+ } else {
|
||||||
|
+ algs = (SlotAlgs) (algs | ALG_RSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (personName == NULL) {
|
||||||
|
@@ -3388,6 +3353,94 @@ Slot::loadCACCert(CKYByte instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
+Slot::initCACShMem(void)
|
||||||
|
+{
|
||||||
|
+ bool failed = false;
|
||||||
|
+
|
||||||
|
+ unsigned char firstCert = shmem.getFirstCacCert();
|
||||||
|
+
|
||||||
|
+ log->log("init CACShMem: \n");
|
||||||
|
+ /* check to make sure the shared memory is initialized with a CAC card */
|
||||||
|
+ if (shmem.isValid() && shmem.getDataVersion() == CAC_DATA_VERSION
|
||||||
|
+ && firstCert != NOT_A_CAC) {
|
||||||
|
+ CKYBuffer rawCert;
|
||||||
|
+ CKYBuffer shmCert;
|
||||||
|
+ CKYSize nextSize;
|
||||||
|
+
|
||||||
|
+ log->log("init CACShMem: valid CAC cache found firstCert = %d\n",
|
||||||
|
+ firstCert);
|
||||||
|
+ CKYBuffer_InitEmpty(&rawCert);
|
||||||
|
+ CKYBuffer_InitEmpty(&shmCert);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /* yes, see if it's this cac card by comparing the first cert
|
||||||
|
+ * in the chain */
|
||||||
|
+
|
||||||
|
+ /* see if the first cert is in the expected slot */
|
||||||
|
+ try {
|
||||||
|
+ selectCACApplet(firstCert, false);
|
||||||
|
+ } catch(PKCS11Exception& e) {
|
||||||
|
+ failed = true;
|
||||||
|
+ log->log("init CACShMem: applet select failed firstCert = %d\n",
|
||||||
|
+ firstCert);
|
||||||
|
+ }
|
||||||
|
+ if (!failed) {
|
||||||
|
+ CKYStatus status = readCACCertificateFirst(&rawCert, &nextSize);
|
||||||
|
+ if ((status != CKYSUCCESS) || CKYBuffer_Size(&rawCert) <= 1) {
|
||||||
|
+ failed = true;
|
||||||
|
+ log->log("init CACShMem: read Cert failed firstCert = %d\n",
|
||||||
|
+ firstCert);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!failed) {
|
||||||
|
+ shmem.readCACCert(&shmCert, firstCert);
|
||||||
|
+ CKYSize certSize = CKYBuffer_Size(&rawCert);
|
||||||
|
+ CKYSize shmCertSize = CKYBuffer_Size(&shmCert);
|
||||||
|
+ const CKYByte *shmData = CKYBuffer_Data(&shmCert);
|
||||||
|
+
|
||||||
|
+ if (shmCertSize >= certSize) {
|
||||||
|
+ if (memcmp(shmData, CKYBuffer_Data(&rawCert), certSize) == 0) {
|
||||||
|
+ /* this card is cached, go on and use the cache */
|
||||||
|
+ log->log("init CACShMem: entries match, using cache\n");
|
||||||
|
+ CKYBuffer_FreeData(&rawCert);
|
||||||
|
+ CKYBuffer_FreeData(&shmCert);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ log->log("init CACShMem: no entry match certSize=%d"
|
||||||
|
+ " shmCertSize=%d\n",certSize, shmCertSize);
|
||||||
|
+ }
|
||||||
|
+ CKYBuffer_FreeData(&rawCert);
|
||||||
|
+ CKYBuffer_FreeData(&shmCert);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log->log("init CACShMem: starting new cache valid=%d version=%d "
|
||||||
|
+ " firstCert=%d\n",shmem.isValid(), shmem.getDataVersion(),
|
||||||
|
+ firstCert);
|
||||||
|
+ /* cache is either invalid or for another card, start initializing it */
|
||||||
|
+ shmem.clearValid(0);
|
||||||
|
+ shmem.setVersion(SHMEM_VERSION);
|
||||||
|
+ shmem.setDataVersion(CAC_DATA_VERSION);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+Slot::verifyCACShMem(void)
|
||||||
|
+{
|
||||||
|
+ /* if the memory is valid, then nothing to do */
|
||||||
|
+ if (shmem.isValid()) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ /* if we didn't find any cert fail */
|
||||||
|
+ if (shmem.getFirstCacCert() == NOT_A_CAC) {
|
||||||
|
+ shmem.clearValid(0);
|
||||||
|
+ disconnect();
|
||||||
|
+ throw PKCS11Exception(CKR_DEVICE_REMOVED);
|
||||||
|
+ }
|
||||||
|
+ /* we're all set, let others see our results */
|
||||||
|
+ shmem.setValid();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
Slot::loadObjects()
|
||||||
|
{
|
||||||
|
// throw away all token objects!
|
||||||
|
@@ -3406,9 +3459,11 @@ Slot::loadObjects()
|
||||||
|
std::list<ListObjectInfo>::iterator iter;
|
||||||
|
|
||||||
|
if (state & GOV_CARD) {
|
||||||
|
- loadCACCert(0);
|
||||||
|
- loadCACCert(1);
|
||||||
|
- loadCACCert(2);
|
||||||
|
+ initCACShMem();
|
||||||
|
+ for (int i=0; i < maxCacCerts; i++) {
|
||||||
|
+ loadCACCert(i);
|
||||||
|
+ }
|
||||||
|
+ verifyCACShMem();
|
||||||
|
status = trans.end();
|
||||||
|
loadReaderObject();
|
||||||
|
return;
|
||||||
|
@@ -4720,10 +4775,6 @@ Slot::performECCSignature(CKYBuffer *out
|
||||||
|
CKYStatus status = trans.begin(conn);
|
||||||
|
if( status != CKYSUCCESS ) handleConnectionError();
|
||||||
|
|
||||||
|
- if (!mECC) {
|
||||||
|
- throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
CKYISOStatus result;
|
||||||
|
bool loginAttempted = false;
|
||||||
|
|
||||||
|
@@ -4790,9 +4841,6 @@ Slot::performRSAOp(CKYBuffer *output, co
|
||||||
|
unsigned int keySize, const PKCS11Object *key,
|
||||||
|
CKYByte direction)
|
||||||
|
{
|
||||||
|
- if ( mECC ) {
|
||||||
|
- throw PKCS11Exception(CKR_FUNCTION_NOT_SUPPORTED);
|
||||||
|
- }
|
||||||
|
|
||||||
|
//
|
||||||
|
// establish a transaction
|
||||||
|
@@ -5145,10 +5193,6 @@ Slot::performECCKeyAgreement(CK_MECHANIS
|
||||||
|
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();
|
||||||
|
diff -up ./src/coolkey/slot.h.alt-cac ./src/coolkey/slot.h
|
||||||
|
--- ./src/coolkey/slot.h.alt-cac 2016-12-01 15:37:49.104167732 -0800
|
||||||
|
+++ ./src/coolkey/slot.h 2016-12-01 15:37:49.117167964 -0800
|
||||||
|
@@ -79,9 +79,11 @@ public:
|
||||||
|
bool CUIDIsEqual(const CKYBuffer *cuid) const;
|
||||||
|
unsigned short getVersion() const;
|
||||||
|
unsigned short getDataVersion() const;
|
||||||
|
+ unsigned char getFirstCacCert() const;
|
||||||
|
void setCUID(const CKYBuffer *cuid);
|
||||||
|
void setVersion(unsigned short version);
|
||||||
|
void setDataVersion(unsigned short version);
|
||||||
|
+ void setFirstCacCert(unsigned char firstCacCert);
|
||||||
|
bool isValid() const;
|
||||||
|
int size() const;
|
||||||
|
const unsigned char *getCUID() const;
|
||||||
|
@@ -90,6 +92,7 @@ public:
|
||||||
|
void setSize(int size);
|
||||||
|
void readData(CKYBuffer *data) const;
|
||||||
|
void writeData(const CKYBuffer *data);
|
||||||
|
+ void initCACHeaders(void);
|
||||||
|
void readCACCert(CKYBuffer *data, CKYByte instance) const;
|
||||||
|
void writeCACCert(const CKYBuffer *data, CKYByte instance);
|
||||||
|
void clearValid(CKYByte instance);
|
||||||
|
@@ -294,7 +297,13 @@ class CryptParams {
|
||||||
|
const CKYBuffer *paddedOutput) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
-#define MAX_CERT_SLOTS 3
|
||||||
|
+#define MAX_CERT_SLOTS 10
|
||||||
|
+typedef enum {
|
||||||
|
+ ALG_NONE= 0x0,
|
||||||
|
+ ALG_ECC = 0x1,
|
||||||
|
+ ALG_RSA = 0x2
|
||||||
|
+} SlotAlgs;
|
||||||
|
+
|
||||||
|
#define MAX_AUTH_USERS 3
|
||||||
|
class Slot {
|
||||||
|
|
||||||
|
@@ -349,7 +358,8 @@ class Slot {
|
||||||
|
bool mCACLocalLogin;
|
||||||
|
int pivContainer;
|
||||||
|
int pivKey;
|
||||||
|
- bool mECC;
|
||||||
|
+ int maxCacCerts;
|
||||||
|
+ SlotAlgs algs;
|
||||||
|
unsigned short p15aid;
|
||||||
|
unsigned short p15odfAddr;
|
||||||
|
unsigned short p15tokenInfoAddr;
|
||||||
|
@@ -424,8 +434,7 @@ class Slot {
|
||||||
|
list<ListObjectInfo> fetchSeparateObjects();
|
||||||
|
|
||||||
|
CKYStatus getCACAid();
|
||||||
|
- CKYStatus readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize,
|
||||||
|
- bool throwException);
|
||||||
|
+ CKYStatus readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize);
|
||||||
|
CKYStatus readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize);
|
||||||
|
|
||||||
|
CKYStatus getP15Params();
|
||||||
|
@@ -485,6 +494,8 @@ class Slot {
|
||||||
|
void processComputeCrypt(CKYBuffer *result, const CKYAPDU *apdu);
|
||||||
|
|
||||||
|
CKYByte objectToKeyNum(const PKCS11Object *key);
|
||||||
|
+ void initCACShMem(void);
|
||||||
|
+ void verifyCACShMem(void);
|
||||||
|
Slot(const Slot &cpy)
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
: shmem(readerName)
|
||||||
|
@@ -580,7 +591,7 @@ class Slot {
|
||||||
|
CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
|
||||||
|
CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, CryptParams& params);
|
||||||
|
|
||||||
|
- bool getIsECC() { return mECC; }
|
||||||
|
+ SlotAlgs getAlgs() { return algs; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class SlotList {
|
BIN
coolkey-1.1.0.tar.gz
(Stored with Git LFS)
Normal file
BIN
coolkey-1.1.0.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
28
coolkey-cac-1.patch
Normal file
28
coolkey-cac-1.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
1013
coolkey-cac.patch
Normal file
1013
coolkey-cac.patch
Normal file
File diff suppressed because it is too large
Load Diff
192
coolkey-cache-dir-move.patch
Normal file
192
coolkey-cache-dir-move.patch
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
CVE-2007-4129 coolkey file and directory permission flaw
|
||||||
|
|
||||||
|
Steve Grubb reported: "It looks like coolkey creates /tmp/.pk11ipc1 as a
|
||||||
|
world writable directory without the sticky bit. And...it creates the files
|
||||||
|
under that potentially as world writable with the execute bit turned on or
|
||||||
|
uses the file without any sanity check. coolkey runs as root sometimes and
|
||||||
|
that makes it susceptible to doing symlink attacks."
|
||||||
|
|
||||||
|
I know some folks ship coolkey here, so we've set an embargo of 20070904,
|
||||||
|
but as it's low severity are happy to extend if anyone wishes.
|
||||||
|
|
||||||
|
CVE-2007-4129 for this issue.
|
||||||
|
|
||||||
|
Proposed patch from Bob Relyea attached.
|
||||||
|
===================================================================
|
||||||
|
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;
|
86
coolkey-fix-token-removal-failure.patch
Normal file
86
coolkey-fix-token-removal-failure.patch
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
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?r1=5858&r2=5881
|
||||||
|
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;
|
54
coolkey-gcc43.patch
Normal file
54
coolkey-gcc43.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
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;
|
||||||
|
|
685
coolkey-latest.patch
Normal file
685
coolkey-latest.patch
Normal file
@ -0,0 +1,685 @@
|
|||||||
|
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,
|
69
coolkey-pcsc-lite-fix.patch
Normal file
69
coolkey-pcsc-lite-fix.patch
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
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
|
4792
coolkey-piv-ecc-el7.patch
Normal file
4792
coolkey-piv-ecc-el7.patch
Normal file
File diff suppressed because it is too large
Load Diff
71
coolkey-simple-bugs.patch
Normal file
71
coolkey-simple-bugs.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
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;
|
158
coolkey-thread-fix.patch
Normal file
158
coolkey-thread-fix.patch
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
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;
|
89
coolkey.changes
Normal file
89
coolkey.changes
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Aug 15 19:50:30 UTC 2022 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
- light modernization of the spec file
|
||||||
|
- avoid bashism in post scripts (bsc#1195391)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Jul 24 23:02:16 UTC 2017 - jengelh@inai.de
|
||||||
|
|
||||||
|
- Remove vision statement and development methods from description.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Jul 21 14:00:08 CEST 2017 - sbrabec@suse.com
|
||||||
|
|
||||||
|
- Add nssdb installation scripts.
|
||||||
|
- Run spec-cleaner.
|
||||||
|
- Drop coolkey-1.1.0-evoandooo.patch: The patch does nothing now.
|
||||||
|
Evolution and LibreOffice changed over time. They moved its
|
||||||
|
directories and they don't use secmod.db any more.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Jul 17 20:55:48 CEST 2017 - sbrabec@suse.com
|
||||||
|
|
||||||
|
- Integrate latest Centos 7 patches [bsc#1049213]
|
||||||
|
(coolkey-fix-token-removal-failure.patch,
|
||||||
|
coolkey-piv-ecc-el7.patch, coolkey-1.1.0-noapplet.patch,
|
||||||
|
coolkey-1.1.0-fix-spurious-event.patch,
|
||||||
|
coolkey-1.1.0-p15.patch, coolkey-1.1.0-p15-coverity.patch,
|
||||||
|
coolkey-1.1.0-more-keys.patch,
|
||||||
|
coolkey-1.1.0-fail-on-bad-mechanisms.patch,
|
||||||
|
coolkey-1.1.0-max-cpu-bug.patch,
|
||||||
|
coolkey-1.1.0-rhel7-alt-cac.patch).
|
||||||
|
* PK15 support.
|
||||||
|
* Fix CAC card support.
|
||||||
|
* Fix card removal issues.
|
||||||
|
- Use original tarball
|
||||||
|
(coolkey-1.1.0.tar.bz2 -> coolkey-1.1.0.tar.gz).
|
||||||
|
- Drop patch coolkey-null.patch. It is now part of
|
||||||
|
coolkey-piv-ecc-el7.patch.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Nov 22 16:01:46 CET 2016 - sbrabec@suse.com
|
||||||
|
|
||||||
|
- Create baselibs.conf.
|
||||||
|
- Add PKCS11 module to p11-kit-32bit (bsc#996047#c39).
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Sep 30 20:07:51 UTC 2011 - coolo@suse.com
|
||||||
|
|
||||||
|
- add libtool as buildrequire to make the spec file more reliable
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Sat Sep 17 23:52:06 UTC 2011 - jengelh@medozas.de
|
||||||
|
|
||||||
|
- Remove redundant tags/sections from specfile
|
||||||
|
- Use %_smp_mflags for parallel build
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Jan 10 19:19:02 CET 2011 - sbrabec@suse.cz
|
||||||
|
|
||||||
|
- Merged latest Fedora patches (bnc#661643).
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Apr 14 18:37:02 CEST 2009 - sbrabec@suse.cz
|
||||||
|
|
||||||
|
- Fixed wrong C++ delete (bnc#443369, Redhat#485032).
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Oct 29 17:50:46 CET 2007 - sbrabec@suse.cz
|
||||||
|
|
||||||
|
- Fixed gcc 4.3 build errors.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Sep 10 13:28:16 CEST 2007 - sbrabec@suse.cz
|
||||||
|
|
||||||
|
- Fixed file and directory permission flaw (#304180,
|
||||||
|
CVE-2007-4129).
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Sep 6 21:03:20 CEST 2007 - jberkman@novell.com
|
||||||
|
|
||||||
|
- install pk11install
|
||||||
|
- teach pk11install about evolution and openoffice
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Aug 3 12:31:03 CEST 2007 - sbrabec@suse.cz
|
||||||
|
|
||||||
|
- New SuSE package, version 1.1.0.
|
||||||
|
|
2
coolkey.rpmlintrc
Normal file
2
coolkey.rpmlintrc
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Summary is OK.
|
||||||
|
addFilter("name-repeated-in-summary")
|
188
coolkey.spec
Normal file
188
coolkey.spec
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
#
|
||||||
|
# spec file for package coolkey
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022 SUSE LLC
|
||||||
|
#
|
||||||
|
# All modifications and additions to the file contributed by third parties
|
||||||
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
|
# upon. The license for this file, and modifications and additions to the
|
||||||
|
# file, is the same license as for the pristine package itself (unless the
|
||||||
|
# license for the pristine package is not an Open Source License, in which
|
||||||
|
# case the license is the MIT License). An "Open Source License" is a
|
||||||
|
# license that conforms to the Open Source Definition (Version 1.9)
|
||||||
|
# published by the Open Source Initiative.
|
||||||
|
|
||||||
|
# Please submit bugfixes or comments via https://bugs.opensuse.org/
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
%define coolkey_module "CoolKey PKCS #11 Module"
|
||||||
|
%define nssdb %{_sysconfdir}/pki/nssdb
|
||||||
|
Name: coolkey
|
||||||
|
Version: 1.1.0
|
||||||
|
Release: 0
|
||||||
|
Summary: CoolKey and CAC PKCS #11 PKI Module for Smart Cards
|
||||||
|
License: LGPL-2.1-only
|
||||||
|
Group: Productivity/Security
|
||||||
|
URL: https://www.dogtagpki.org/wiki/CoolKey
|
||||||
|
Source: %{name}-%{version}.tar.gz
|
||||||
|
Source1: %{name}.rpmlintrc
|
||||||
|
Source2: baselibs.conf
|
||||||
|
# Patches imported from Fedora and CentOS:
|
||||||
|
# PATCH-FIX-SECURITY coolkey-cache-dir-move.patch sbrabec@suse.cz bnc304180 CVE-2007-4129 -- Fix file and directory permission flaw.
|
||||||
|
Patch1: coolkey-cache-dir-move.patch
|
||||||
|
# PATCH-FIX-FEDORA coolkey-gcc43.patch bnc661643 sbrabec@suse.cz -- Fix for gcc-4.3.
|
||||||
|
Patch2: coolkey-gcc43.patch
|
||||||
|
# PATCH-FEATURE-FEDORA coolkey-latest.patch bnc661643 sbrabec@suse.cz -- The head branch patch.
|
||||||
|
Patch3: coolkey-latest.patch
|
||||||
|
# PATCH-FIX-FEDORA coolkey-simple-bugs.patch bnc661643 sbrabec@suse.cz -- Fix imported from Fedora, mostly merging former SUSE fixes.
|
||||||
|
Patch4: coolkey-simple-bugs.patch
|
||||||
|
# PATCH-FIX-FEDORA coolkey-thread-fix.patch bnc661643 sbrabec@suse.cz -- Fix threading.
|
||||||
|
Patch5: coolkey-thread-fix.patch
|
||||||
|
# PATCH-FEATURE-FEDORA coolkey-cac.patch bnc661643 sbrabec@suse.cz -- Support for CAC cards.
|
||||||
|
Patch6: coolkey-cac.patch
|
||||||
|
# PATCH-FIX-FEDORA coolkey-cac-1.patch bnc661643 sbrabec@suse.cz -- Fixes of CAC support patch.
|
||||||
|
Patch7: coolkey-cac-1.patch
|
||||||
|
# PATCH-FIX-FEDORA coolkey-pcsc-lite-fix.patch bnc661643 sbrabec@suse.cz -- Port to the latest pcsc-lite.
|
||||||
|
Patch8: coolkey-pcsc-lite-fix.patch
|
||||||
|
Patch9: coolkey-fix-token-removal-failure.patch
|
||||||
|
Patch10: coolkey-piv-ecc-el7.patch
|
||||||
|
Patch20: coolkey-1.1.0-noapplet.patch
|
||||||
|
Patch21: coolkey-1.1.0-fix-spurious-event.patch
|
||||||
|
Patch22: coolkey-1.1.0-p15.patch
|
||||||
|
Patch23: coolkey-1.1.0-p15-coverity.patch
|
||||||
|
Patch24: coolkey-1.1.0-more-keys.patch
|
||||||
|
Patch25: coolkey-1.1.0-fail-on-bad-mechanisms.patch
|
||||||
|
Patch26: coolkey-1.1.0-max-cpu-bug.patch
|
||||||
|
Patch27: coolkey-1.1.0-rhel7-alt-cac.patch
|
||||||
|
BuildRequires: gcc-c++
|
||||||
|
BuildRequires: libtool
|
||||||
|
BuildRequires: mozilla-nss-devel
|
||||||
|
BuildRequires: mozilla-nss-sysinit
|
||||||
|
BuildRequires: mozilla-nss-tools
|
||||||
|
BuildRequires: pcsc-lite-devel
|
||||||
|
BuildRequires: pkgconfig
|
||||||
|
BuildRequires: zlib-devel
|
||||||
|
#Requires: pcsc-lite
|
||||||
|
# Requires: ifd-egate
|
||||||
|
Requires: pcsc-ccid
|
||||||
|
# 390 does not have libusb or smartCards
|
||||||
|
ExcludeArch: s390 s390x
|
||||||
|
|
||||||
|
%description
|
||||||
|
Linux Driver support for the CoolKey and CAC products. CoolKeys are
|
||||||
|
part of a complete PKI solution that provides smart card login, single
|
||||||
|
sign-on, secure messaging, and secure email access. In the complete
|
||||||
|
solution, users are issued CoolKeys by their employer, ISP, bank, or
|
||||||
|
other parties. When the user plugs the keys in for the first time, the
|
||||||
|
keys are automatically provisioned with certificates, keys, and a PIN,
|
||||||
|
unique for that user by the Red Hat Certificate System. Once the
|
||||||
|
CoolKey is provisioned, the user can take the key to any system and use
|
||||||
|
it to login (authenticate), send and receive signed and encrypted
|
||||||
|
email, or participate in secure messaging or IRC communication.
|
||||||
|
CoolKeys are based on JavaCard 1.2.
|
||||||
|
|
||||||
|
%package devel
|
||||||
|
Summary: CoolKey and CAC PKCS #11 PKI Module for Smart Cards
|
||||||
|
Group: Development/Libraries/C and C++
|
||||||
|
Requires: %{name} = %{version}
|
||||||
|
|
||||||
|
%description devel
|
||||||
|
Linux Driver support for the CoolKey and CAC products.
|
||||||
|
|
||||||
|
CoolKeys are part of complete PKI solution that provides smart card
|
||||||
|
login, single sign-on, secure messaging, and secure email access. In
|
||||||
|
the complete solution, users are issued CoolKeys by their employer,
|
||||||
|
ISP, bank, or other agency. When the user plugs in the keys for the
|
||||||
|
first time, the keys are automatically provisioned with certificates,
|
||||||
|
keys, and a PIN unique to that user by the Red Hat Certificate System.
|
||||||
|
Once the CoolKey is provisioned, the user can take the key to any
|
||||||
|
system and use it to login (authenticate), send and receive signed and
|
||||||
|
encrypted email, or participate in secure messaging or IRC
|
||||||
|
communication.
|
||||||
|
|
||||||
|
CoolKeys are based on JavaCard 1.2.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q
|
||||||
|
%patch1
|
||||||
|
%patch2
|
||||||
|
%patch3
|
||||||
|
%patch4
|
||||||
|
%patch5
|
||||||
|
%patch6
|
||||||
|
%patch7
|
||||||
|
%patch8
|
||||||
|
%patch9 -p1
|
||||||
|
%patch10
|
||||||
|
%patch20
|
||||||
|
%patch21
|
||||||
|
%patch22
|
||||||
|
%patch23
|
||||||
|
%patch24
|
||||||
|
%patch25
|
||||||
|
%patch26
|
||||||
|
%patch27
|
||||||
|
|
||||||
|
%build
|
||||||
|
autoreconf -f -i
|
||||||
|
export CFLAGS="%{optflags} -fno-strict-aliasing"
|
||||||
|
export CXXFLAGS="%{optflags} -fno-strict-aliasing"
|
||||||
|
%configure\
|
||||||
|
--with-debug\
|
||||||
|
--disable-dependency-tracking\
|
||||||
|
--enable-pk11install
|
||||||
|
%make_build
|
||||||
|
|
||||||
|
%install
|
||||||
|
%make_install
|
||||||
|
ln -s pkcs11/libcoolkeypk11.so %{buildroot}/%{_libdir}
|
||||||
|
|
||||||
|
%triggerin -- mozilla-nss-sysinit mozilla-nss-tools
|
||||||
|
if [ -x %{_bindir}/pk11install -a -x %{_bindir}/modutil -a -f %{_sysconfdir}/pki/nssdb/pkcs11.txt ]; then
|
||||||
|
isThere=`modutil -rawlist -dbdir dbm:%{nssdb} | grep %{coolkey_module} || echo NO`
|
||||||
|
if [ "$isThere" = "NO" ]; then
|
||||||
|
pk11install -l -p %{nssdb} 'name=%{coolkey_module} library=libcoolkeypk11.so' ||:
|
||||||
|
fi
|
||||||
|
isThere=`modutil -rawlist -dbdir sql:%{nssdb} | grep %{coolkey_module} || echo NO`
|
||||||
|
if [ "$isThere" = "NO" ]; then
|
||||||
|
pk11install -s -p %{nssdb} 'name=%{coolkey_module} library=libcoolkeypk11.so' ||:
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
%post
|
||||||
|
/sbin/ldconfig
|
||||||
|
if [ -x %{_bindir}/pk11install -a -x %{_bindir}/modutil -a -f %{_sysconfdir}/pki/nssdb/pkcs11.txt ]; then
|
||||||
|
isThere=`modutil -rawlist -dbdir dbm:%{nssdb} | grep %{coolkey_module} || echo NO`
|
||||||
|
if [ "$isThere" = "NO" ]; then
|
||||||
|
pk11install -l -p %{nssdb} 'name=%{coolkey_module} library=libcoolkeypk11.so' ||:
|
||||||
|
fi
|
||||||
|
isThere=`modutil -rawlist -dbdir sql:%{nssdb} | grep %{coolkey_module} || echo NO`
|
||||||
|
if [ "$isThere" = "NO" ]; then
|
||||||
|
pk11install -s -p %{nssdb} 'name=%{coolkey_module} library=libcoolkeypk11.so' ||:
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
%postun
|
||||||
|
/sbin/ldconfig
|
||||||
|
if [ $1 -eq 0 -a -x %{_bindir}/modutil -a -f %{_sysconfdir}/pki/nssdb/pkcs11.txt ]; then
|
||||||
|
modutil -delete %{coolkey_module} -dbdir dbm:%{nssdb} -force || :
|
||||||
|
modutil -delete %{coolkey_module} -dbdir sql:%{nssdb} -force || :
|
||||||
|
fi
|
||||||
|
|
||||||
|
%files
|
||||||
|
%license LICENSE
|
||||||
|
%doc ChangeLog README
|
||||||
|
%{_bindir}/pk11install
|
||||||
|
%{_libdir}/libcoolkeypk11.so
|
||||||
|
%{_libdir}/pkcs11/*.so
|
||||||
|
%{_libdir}/libckyapplet.so.*
|
||||||
|
# FIXME: Find a common package owning this directory:
|
||||||
|
%dir %{_libdir}/pkcs11
|
||||||
|
|
||||||
|
%files devel
|
||||||
|
%{_libdir}/libckyapplet.so
|
||||||
|
%{_libdir}/pkgconfig/*.pc
|
||||||
|
%{_includedir}/*.h
|
||||||
|
|
||||||
|
%changelog
|
Loading…
Reference in New Issue
Block a user