components/coolkey/patches/07-slot.h.patch
author John Beck <John.Beck@Oracle.COM>
Thu, 13 Oct 2016 08:06:14 -0700
changeset 7109 f298ea535620
parent 6401 8e624b116c1d
permissions -rw-r--r--
24844018 fix for 24826424 needs tweaking

Upstream fixes already included in the latest community updates to coolkey v1.1.0

Adds header definitions for newer CAC and PIV card support.

--- ORIGINAL/./src/coolkey/slot.h	2016-06-24 16:07:28.549068021 -0400
+++ ././src/coolkey/slot.h	2016-06-27 14:01:31.527689321 -0400
@@ -79,9 +79,11 @@
     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 @@
     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);
@@ -211,24 +214,27 @@
     State state;
     CKYByte keyNum;
     CKYBuffer result;
+    PKCS11Object::KeyType keyType;
 
-    CryptOpState() : state(NOT_INITIALIZED), keyNum(0) 
+    CryptOpState() : state(NOT_INITIALIZED), keyNum(0), keyType(PKCS11Object::unknown)
 				{ CKYBuffer_InitEmpty(&result); }
     CryptOpState(const CryptOpState &cpy) : 
-				state(cpy.state), keyNum(cpy.keyNum) { 
+				state(cpy.state), keyNum(cpy.keyNum), keyType(cpy.keyType) { 
 	CKYBuffer_InitFromCopy(&result, &cpy.result);
     }
     CryptOpState &operator=(const CryptOpState &cpy) {
 	state = cpy.state,
 	keyNum = cpy.keyNum;
+        keyType = cpy.keyType;
 	CKYBuffer_Replace(&result, 0, CKYBuffer_Data(&cpy.result),
 				CKYBuffer_Size(&cpy.result));
 	return *this;
     }
     ~CryptOpState() { CKYBuffer_FreeData(&result); }
-    void initialize(CKYByte keyNum) {
+    void initialize(CKYByte keyNum, PKCS11Object::KeyType theKeyType) {
         state = IN_PROCESS;
         this->keyNum = keyNum;
+        this->keyType = theKeyType;
         CKYBuffer_Resize(&result, 0);
     }
 };
@@ -258,6 +264,7 @@
 
     CryptOpState signatureState;
     CryptOpState decryptionState;
+    CryptOpState keyAgreementState;
 };
 
 typedef list<Session> SessionList;
@@ -267,13 +274,11 @@
 class CryptParams {
   private:
     unsigned int keySize; // in bits
-  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; }
+    unsigned int getKeySize() const { return keySize; }
+    enum { DEFAULT_KEY_SIZE = 1024, ECC_DEFAULT_KEY_SIZE=256 };
 
 
     CryptParams(unsigned int keySize_) : keySize(keySize_) { }
@@ -295,6 +300,13 @@
 				 const CKYBuffer *paddedOutput) const = 0;
 };
 
+#define MAX_CERT_SLOTS 10
+typedef enum {
+    ALG_NONE= 0x0,
+    ALG_ECC = 0x1,
+    ALG_RSA = 0x2
+} SlotAlgs;
+
 class Slot {
 
   public:
@@ -304,12 +316,15 @@
         ATR_MATCH = 0x04,
         APPLET_SELECTABLE = 0x08,
         APPLET_PERSONALIZED = 0x10,
-        CAC_CARD = 0x20
+        CAC_CARD = 0x20,
+        PIV_CARD = 0x40
     };
     enum {
 	NONCE_SIZE = 8
     };
 
+    static const SlotState GOV_CARD = (SlotState)(CAC_CARD|PIV_CARD);
+
   private:
     Log *log;
     char *readerName;
@@ -329,6 +344,8 @@
     CKYBuffer nonce;
     CKYBuffer cardATR;
     CKYBuffer mCUID;
+    CKYBuffer cardAID[MAX_CERT_SLOTS];
+    unsigned short cardEF[MAX_CERT_SLOTS];
     bool isVersion1Key;
     bool needLogin;
     long publicFree;
@@ -336,7 +353,12 @@
     long privateFree;
     bool fullTokenName;
     bool mCoolkey;
-
+    bool mOldCAC;
+    bool mCACLocalLogin;
+    int pivContainer;
+    int pivKey;
+    int maxCacCerts;
+    SlotAlgs algs;
     //enum { RW_SESSION_HANDLE = 1, RO_SESSION_HANDLE = 2 };
 
 #ifdef USE_SHMEM
@@ -383,6 +405,7 @@
     const CKYBuffer *getATR();
     bool isLoggedIn();
     bool needLoggedIn();
+    bool getPIVLoginType();
     void testNonce();
 
     void addKeyObject(list<PKCS11Object>& objectList,
@@ -392,6 +415,7 @@
 	const CKYBuffer *derCert, CK_OBJECT_HANDLE handle);
     void addObject(list<PKCS11Object>& objectList,
         const ListObjectInfo& info, CK_OBJECT_HANDLE handle);
+    PKCS11Object *createSecretKeyObject(CK_OBJECT_HANDLE handle, CKYBuffer *secretKeyBuffer,CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount);
 
     void ensureValidSession(SessionHandleSuffix suffix);
 
@@ -399,8 +423,12 @@
     list<ListObjectInfo> fetchCombinedObjects(const CKYBuffer *header);
     list<ListObjectInfo> fetchSeparateObjects();
 
+    CKYStatus getCACAid();
+    CKYStatus readCACCertificateFirst(CKYBuffer *cert, CKYSize *nextSize);
+    CKYStatus readCACCertificateAppend(CKYBuffer *cert, CKYSize nextSize);
+
     void selectApplet();
-    void selectCACApplet(CKYByte instance);
+    void selectCACApplet(CKYByte instance,bool do_disconnect);
     void unloadObjects();
     void loadCACObjects();
     void loadCACCert(CKYByte instance);
@@ -422,14 +450,27 @@
 
     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);
+    void performRSAOp(CKYBuffer *out, const CKYBuffer *input, unsigned int keySize,
+						CKYByte keyNum, CKYByte direction);
+
+    void signECC(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
+        CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
+        CK_ULONG_PTR pulOutputLen, CryptParams& params);
+
+    void performECCSignature(CKYBuffer *out, const CKYBuffer *input, 
+					unsigned int keySize, CKYByte keyNum);
+    void performECCKeyAgreement(CK_MECHANISM_TYPE deriveMech, 
+        CKYBuffer *publicDataBuffer, 
+        CKYBuffer *secretKeyBuffer, CKYByte keyNum, unsigned int keySize);
 
     void processComputeCrypt(CKYBuffer *result, const CKYAPDU *apdu);
 
     CKYByte objectHandleToKeyNum(CK_OBJECT_HANDLE hKey);
+    unsigned int calcECCKeySize(CKYByte keyNum);
+    void initCACShMem(void);
+    void verifyCACShMem(void);
     Slot(const Slot &cpy)
 #ifdef USE_SHMEM
 	: shmem(readerName)
@@ -460,6 +501,11 @@
         return (char )((objectID >> 16) & 0xff) - '0';
     }
 
+    // actually get the size of a key in bits from the card
+    unsigned int getRSAKeySize(CKYByte keyNum);
+    unsigned int getECCKeySize(CKYByte keyNum);
+
+    PKCS11Object::KeyType  getKeyTypeFromHandle(CK_OBJECT_HANDLE hKey);
 
     SessionHandleSuffix openSession(Session::Type type);
     void closeSession(SessionHandleSuffix handleSuffix);
@@ -501,6 +547,16 @@
 	CK_ULONG len);
     void generateRandom(SessionHandleSuffix suffix, CK_BYTE_PTR data,
 	CK_ULONG len);
+
+    void derive(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
+        CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_PTR pTemplate, 
+        CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
+
+    void deriveECC(SessionHandleSuffix suffix, CK_MECHANISM_PTR pMechanism,
+       CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, 
+       CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, CryptParams& params);
+
+    SlotAlgs getAlgs() { return algs; }
 };
 
 class SlotList {
@@ -527,6 +583,8 @@
      * 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);
@@ -592,6 +650,10 @@
     void seedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
         CK_ULONG ulDataLen);
 
+    void derive(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+        CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_PTR pTemplate, 
+        CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey);
+
 
 };
 #endif