changeset 14475:c6da1ce5c680

8265462: Handle multiple slots in the NSS Internal Module from SunPKCS11's Secmod Reviewed-by: valeriep, andrew
author mbalao
date Tue, 18 May 2021 22:34:27 +0000
parents 63e69aef6997
children 219c9107171b
files src/share/classes/sun/security/pkcs11/Secmod.java src/share/native/sun/security/pkcs11/j2secmod.c src/share/native/sun/security/pkcs11/j2secmod.h src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h
diffstat 4 files changed, 165 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/pkcs11/Secmod.java	Wed May 26 18:02:22 2021 +0100
+++ b/src/share/classes/sun/security/pkcs11/Secmod.java	Tue May 18 22:34:27 2021 +0000
@@ -73,6 +73,15 @@
 
     private final static String TRUST_LIB_NAME = "nssckbi";
 
+    // Slot IDs - defined in j2secmod.h on the native side
+    // Values obtained from NSS's pkcs11i.h header
+
+    private final static int NETSCAPE_SLOT_ID = 0x1;
+
+    private final static int PRIVATE_KEY_SLOT_ID = 0x2;
+
+    private final static int FIPS_SLOT_ID = 0x3;
+
     // handle to be passed to the native code, 0 means not initialized
     private long nssHandle;
 
@@ -392,20 +401,21 @@
         private Map<Bytes,TrustAttributes> trust;
 
         Module(String libraryDir, String libraryName, String commonName,
-                boolean fips, int slot) {
+                int slotIndex, int slotId) {
             ModuleType type;
 
             if ((libraryName == null) || (libraryName.length() == 0)) {
                 // must be softtoken
                 libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME);
-                if (fips == false) {
-                    type = (slot == 0) ? ModuleType.CRYPTO : ModuleType.KEYSTORE;
-                } else {
+                if (slotId == NETSCAPE_SLOT_ID) {
+                    type = ModuleType.CRYPTO;
+                } else if (slotId == PRIVATE_KEY_SLOT_ID) {
+                    type = ModuleType.KEYSTORE;
+                } else if (slotId == FIPS_SLOT_ID) {
                     type = ModuleType.FIPS;
-                    if (slot != 0) {
-                        throw new RuntimeException
-                            ("Slot index should be 0 for FIPS slot");
-                    }
+                } else {
+                    throw new RuntimeException("Unexpected slot ID " + slotId +
+                            " in the NSS Internal Module");
                 }
             } else {
                 if (libraryName.endsWith(System.mapLibraryName(TRUST_LIB_NAME))
@@ -426,7 +436,7 @@
             }
             this.libraryName = libraryFile.getPath();
             this.commonName = commonName;
-            this.slot = slot;
+            this.slot = slotIndex;
             this.type = type;
             initConfiguration();
         }
--- a/src/share/native/sun/security/pkcs11/j2secmod.c	Wed May 26 18:02:22 2021 +0100
+++ b/src/share/native/sun/security/pkcs11/j2secmod.c	Tue May 18 22:34:27 2021 +0000
@@ -153,8 +153,7 @@
     jobject jList, jModule;
     jmethodID jListConstructor, jAdd, jModuleConstructor;
     jstring jCommonName, jDllName;
-    jboolean jFIPS;
-    jint i;
+    jint i, jSlotID;
 
     if (getModuleList == NULL) {
         dprintf("-getmodulelist function not found\n");
@@ -187,7 +186,7 @@
         return NULL;
     }
     jModuleConstructor = (*env)->GetMethodID(env, jModuleClass, "<init>",
-        "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V");
+        "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V");
     if (jModuleConstructor == NULL) {
         return NULL;
     }
@@ -213,10 +212,15 @@
                 return NULL;
             }
         }
-        jFIPS = module->isFIPS;
         for (i = 0; i < module->slotCount; i++ ) {
+            jSlotID = module->slots[i]->slotID;
+            if (jDllName == NULL && jSlotID != NETSCAPE_SLOT_ID &&
+                    jSlotID != PRIVATE_KEY_SLOT_ID && jSlotID != FIPS_SLOT_ID) {
+                // Ignore unknown slot IDs in the NSS Internal Module. See JDK-8265462.
+                continue;
+            }
             jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor,
-                jLibDir, jDllName, jCommonName, jFIPS, i);
+                    jLibDir, jDllName, jCommonName, i, jSlotID);
             if (jModule == NULL) {
                 return NULL;
             }
--- a/src/share/native/sun/security/pkcs11/j2secmod.h	Wed May 26 18:02:22 2021 +0100
+++ b/src/share/native/sun/security/pkcs11/j2secmod.h	Tue May 18 22:34:27 2021 +0000
@@ -51,32 +51,150 @@
 // NSS types
 
 typedef int PRBool;
+typedef unsigned short PRUint16;
+typedef short PRInt16;
+typedef unsigned int PRUint32;
+typedef int PRInt32;
+typedef long long PRInt64;
+
+typedef PRUint32 PRIntervalTime;
+typedef PRInt64 PRTime;
+
+typedef struct PK11SlotInfoStr PK11SlotInfo;
 
 typedef struct SECMODModuleStr SECMODModule;
 typedef struct SECMODModuleListStr SECMODModuleList;
 
+// Defined in NSS's secmodt.h header
+/* PKCS #11 disable reasons */
+typedef enum {
+    PK11_DIS_NONE = 0,
+    PK11_DIS_USER_SELECTED = 1,
+    PK11_DIS_COULD_NOT_INIT_TOKEN = 2,
+    PK11_DIS_TOKEN_VERIFY_FAILED = 3,
+    PK11_DIS_TOKEN_NOT_PRESENT = 4
+} PK11DisableReasons;
+
+// Slot IDs - defined in Secmod.java on the Java side
+// Values obtained from NSS's pkcs11i.h header
+#define NETSCAPE_SLOT_ID 1
+#define PRIVATE_KEY_SLOT_ID 2
+#define FIPS_SLOT_ID 3
+
+// Defined in NSS's secmodti.h header
+/* represent a pkcs#11 slot reference counted. */
+struct PK11SlotInfoStr {
+    /* the PKCS11 function list for this slot */
+    void *functionList;
+    SECMODModule *module; /* our parent module */
+    /* Boolean to indicate the current state of this slot */
+    PRBool needTest;           /* Has this slot been tested for Export complience */
+    PRBool isPerm;             /* is this slot a permanment device */
+    PRBool isHW;               /* is this slot a hardware device */
+    PRBool isInternal;         /* is this slot one of our internal PKCS #11 devices */
+    PRBool disabled;           /* is this slot disabled... */
+    PK11DisableReasons reason; /* Why this slot is disabled */
+    PRBool readOnly;           /* is the token in this slot read-only */
+    PRBool needLogin;          /* does the token of the type that needs
+                                * authentication (still true even if token is logged
+                                * in) */
+    PRBool hasRandom;          /* can this token generated random numbers */
+    PRBool defRWSession;       /* is the default session RW (we open our default
+                                * session rw if the token can only handle one session
+                                * at a time. */
+    PRBool isThreadSafe;       /* copied from the module */
+    /* The actual flags (many of which are distilled into the above PRBools) */
+    CK_FLAGS flags; /* flags from PKCS #11 token Info */
+    /* a default session handle to do quick and dirty functions */
+    CK_SESSION_HANDLE session;
+    void *sessionLock; /* lock for this session */
+    /* our ID */
+    CK_SLOT_ID slotID;
+    /* persistant flags saved from startup to startup */
+    unsigned long defaultFlags;
+    /* keep track of who is using us so we don't accidently get freed while
+     * still in use */
+    PRInt32 refCount; /* to be in/decremented by atomic calls ONLY! */
+    void *freeListLock;
+    void *freeSymKeysWithSessionHead;
+    void *freeSymKeysHead;
+    int keyCount;
+    int maxKeyCount;
+    /* Password control functions for this slot. many of these are only
+     * active if the appropriate flag is on in defaultFlags */
+    int askpw;           /* what our password options are */
+    int timeout;         /* If we're ask_timeout, what is our timeout time is
+                          * seconds */
+    int authTransact;    /* allow multiple authentications off one password if
+                          * they are all part of the same transaction */
+    PRTime authTime;     /* when were we last authenticated */
+    int minPassword;     /* smallest legal password */
+    int maxPassword;     /* largest legal password */
+    PRUint16 series;     /* break up the slot info into various groups of
+                          * inserted tokens so that keys and certs can be
+                          * invalidated */
+    PRUint16 flagSeries; /* record the last series for the last event
+                          * returned for this slot */
+    PRBool flagState;    /* record the state of the last event returned for this
+                          * slot. */
+    PRUint16 wrapKey;    /* current wrapping key for SSL master secrets */
+    CK_MECHANISM_TYPE wrapMechanism;
+    /* current wrapping mechanism for current wrapKey */
+    CK_OBJECT_HANDLE refKeys[1];      /* array of existing wrapping keys for */
+    CK_MECHANISM_TYPE *mechanismList; /* list of mechanism supported by this
+                                       * token */
+    int mechanismCount;
+    /* cache the certificates stored on the token of this slot */
+    void **cert_array;
+    int array_size;
+    int cert_count;
+    char serial[16];
+    /* since these are odd sizes, keep them last. They are odd sizes to
+     * allow them to become null terminated strings */
+    char slot_name[65];
+    char token_name[33];
+    PRBool hasRootCerts;
+    PRBool hasRootTrust;
+    PRBool hasRSAInfo;
+    CK_FLAGS RSAInfoFlags;
+    PRBool protectedAuthPath;
+    PRBool isActiveCard;
+    PRIntervalTime lastLoginCheck;
+    unsigned int lastState;
+    /* for Stan */
+    void *nssToken;
+    /* the tokeninfo struct */
+    CK_TOKEN_INFO tokenInfo;
+    /* fast mechanism lookup */
+    char mechanismBits[256];
+    CK_PROFILE_ID *profileList;
+    int profileCount;
+};
+
+// Defined in NSS's secmodt.h header
 struct SECMODModuleStr {
-    void        *v1;
-    PRBool      internal;       /* true of internally linked modules, false
-                                 * for the loaded modules */
-    PRBool      loaded;         /* Set to true if module has been loaded */
-    PRBool      isFIPS;         /* Set to true if module is finst internal */
-    char        *dllName;       /* name of the shared library which implements
-                                 * this module */
-    char        *commonName;    /* name of the module to display to the user */
-    void        *library;       /* pointer to the library. opaque. used only by
-                                 * pk11load.c */
+    void         *v1;
+    PRBool       internal;       /* true of internally linked modules, false
+                                  * for the loaded modules */
+    PRBool       loaded;         /* Set to true if module has been loaded */
+    PRBool       isFIPS;         /* Set to true if module is finst internal */
+    char         *dllName;       /* name of the shared library which implements
+                                  * this module */
+    char         *commonName;    /* name of the module to display to the user */
+    void         *library;       /* pointer to the library. opaque. used only by
+                                  * pk11load.c */
 
-    void        *functionList; /* The PKCS #11 function table */
-    void        *refLock;       /* only used pk11db.c */
-    int         refCount;       /* Module reference count */
-    void        **slots;        /* array of slot points attached to this mod*/
-    int         slotCount;      /* count of slot in above array */
-    void        *slotInfo;      /* special info about slots default settings */
-    int         slotInfoCount;  /* count */
+    void         *functionList; /* The PKCS #11 function table */
+    void         *refLock;       /* only used pk11db.c */
+    int          refCount;       /* Module reference count */
+    PK11SlotInfo **slots;        /* array of slot points attached to this mod*/
+    int          slotCount;      /* count of slot in above array */
+    void         *slotInfo;      /* special info about slots default settings */
+    int          slotInfoCount;  /* count */
     // incomplete, sizeof() is wrong
 };
 
+// Defined in NSS's secmodt.h header
 struct SECMODModuleListStr {
     SECMODModuleList    *next;
     SECMODModule        *module;
--- a/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h	Wed May 26 18:02:22 2021 +0100
+++ b/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h	Tue May 18 22:34:27 2021 +0000
@@ -1998,5 +1998,7 @@
 typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \
                                         CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR;
 
+typedef CK_ULONG CK_PROFILE_ID;
+
 #endif /* _PKCS11T_H_ */