summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/pkcs11-coverage.txt19
-rw-r--r--src/p11-tests.h1
-rw-r--r--src/session.c170
-rw-r--r--src/slot.c23
4 files changed, 208 insertions, 5 deletions
diff --git a/doc/pkcs11-coverage.txt b/doc/pkcs11-coverage.txt
index c58f687..e5e9847 100644
--- a/doc/pkcs11-coverage.txt
+++ b/doc/pkcs11-coverage.txt
@@ -44,6 +44,9 @@ C_GetMechanismList
- Zero count but buffer present
- Low count but buffer present
+C_GetOperationState
+- Not Implemented
+
C_GetSessionInfo
- Invalid session
- NULL arguments
@@ -91,6 +94,19 @@ C_Initialize
- Multiple initialize with C_Finalize between
- Double initialize in a row
+C_Login
+- Login as SO not allowed with RO session
+- Login as SO
+- Login changes all session state
+- Can't open RO session when logged in as SO
+- Logout from SO
+- Logout SO changes goes back to public
+
+C_Logout
+- Invalid session
+- Normal logout
+- Logout changes all session state
+
C_OpenSession
- Invalid slot
- Null arguments
@@ -99,6 +115,9 @@ C_OpenSession
- Valid flags
- Read write session
+C_SetOperationState
+- Not Implemented
+
C_SetPIN
- Not Implemented
diff --git a/src/p11-tests.h b/src/p11-tests.h
index 4792e56..425032d 100644
--- a/src/p11-tests.h
+++ b/src/p11-tests.h
@@ -89,5 +89,6 @@ extern CK_MECHANISM_INFO_PTR* p11t_slot_mech_info;
void p11t_slot_tests(void);
+CK_TOKEN_INFO_PTR p11t_slot_get_token_info(CK_SLOT_ID slot);
#endif /* P11TESTST_H_ */
diff --git a/src/session.c b/src/session.c
index ae20c0c..703227c 100644
--- a/src/session.c
+++ b/src/session.c
@@ -5,7 +5,8 @@
#include <string.h>
-static const char *login_pin = NULL;
+static const char *login_user_pin = NULL;
+static const char *login_so_pin = NULL;
void
session_info(CK_SESSION_HANDLE session, CK_SLOT_ID slot, CK_FLAGS flags, CK_STATE state)
@@ -44,6 +45,150 @@ session_info(CK_SESSION_HANDLE session, CK_SLOT_ID slot, CK_FLAGS flags, CK_STAT
p11t_check_flag("CK_SESSION_INFO.flags", info.flags, flags);
}
+static CK_UTF8CHAR_PTR
+calculate_pin(CK_SLOT_ID slot, CK_USER_TYPE user, CK_ULONG_PTR n_pin)
+{
+ CK_TOKEN_INFO_PTR info;
+ const char *pin;
+
+ *n_pin = 0;
+
+ info = p11t_slot_get_token_info(slot);
+ if(info && info->flags & CKF_PROTECTED_AUTHENTICATION_PATH)
+ return NULL;
+
+ if(user == CKU_USER)
+ pin = login_user_pin;
+ else if(user == CKU_SO)
+ pin = login_so_pin;
+ else
+ pin = NULL;
+
+ if(pin)
+ *n_pin = strlen(pin);
+
+ return (CK_UTF8CHAR_PTR)pin;
+}
+
+void
+session_user_login(CK_SLOT_ID slot)
+{
+ CK_SESSION_HANDLE session_ro = CK_INVALID;
+ CK_SESSION_HANDLE session_rw = CK_INVALID;
+ CK_UTF8CHAR_PTR pin;
+ CK_ULONG n_pin;
+ CK_RV rv;
+
+ pin = calculate_pin(slot, CKU_USER, &n_pin);
+
+ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, &session_ro);
+ p11t_check_returns("C_Login: open RO session", rv, CKR_OK);
+ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session_rw);
+ p11t_check_returns("C_Login: open RW session", rv, CKR_OK);
+
+ /* Check the session state before login */
+ session_info(session_ro, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION);
+ session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION);
+
+ /** C_Login */
+
+ if(p11t_test_unexpected)
+ {
+ /** - Invalid session */
+ rv = (p11t_module_funcs->C_Login)((CK_ULONG)-55, CKU_USER, pin, n_pin);
+ p11t_check_returns("C_Login: invalid session", rv, CKR_SESSION_HANDLE_INVALID);
+
+ /** - Invalid user type */
+ rv = (p11t_module_funcs->C_Login)(session_ro, CK_INVALID, pin, n_pin);
+ p11t_check_returns("C_Login: invalid user type", rv, CKR_USER_TYPE_INVALID);
+ }
+
+ /** - Normal login */
+ rv = (p11t_module_funcs->C_Login)(session_ro, CKU_USER, pin, n_pin);
+ if(rv == CKR_USER_TYPE_INVALID)
+ return;
+ if(!p11t_check_returns("C_Login", rv, CKR_OK))
+ return;
+
+ /** - Login changes all session state */
+ session_info(session_ro, slot, CKF_SERIAL_SESSION, CKS_RO_USER_FUNCTIONS);
+ session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_USER_FUNCTIONS);
+
+ /** C_Logout */
+
+ if(p11t_test_unexpected)
+ {
+ /** - Invalid session */
+ rv = (p11t_module_funcs->C_Logout)((CK_ULONG)-55);
+ p11t_check_returns("C_Logout: invalid session", rv, CKR_SESSION_HANDLE_INVALID);
+ }
+
+ /** - Normal logout */
+ rv = (p11t_module_funcs->C_Logout)(session_rw);
+ p11t_check_returns("C_Logout", rv, CKR_OK);
+
+ /** - Logout changes all session state */
+ session_info(session_ro, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION);
+ session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION);
+}
+
+void
+session_so_login(CK_SLOT_ID slot)
+{
+ CK_SESSION_HANDLE session_ro = CK_INVALID;
+ CK_SESSION_HANDLE session_rw = CK_INVALID;
+ CK_UTF8CHAR_PTR pin;
+ CK_ULONG n_pin;
+ CK_RV rv;
+
+ pin = calculate_pin(slot, CKU_SO, &n_pin);
+
+ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session_rw);
+ p11t_check_returns("C_OpenSession: open RW session", rv, CKR_OK);
+
+ /* Check the session state before login */
+ session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION);
+
+ /** C_Login */
+
+ if(p11t_test_unexpected)
+ {
+ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, &session_ro);
+ p11t_check_returns("C_OpenSession: open RO session because SO", rv, CKR_OK);
+
+ /** - Login as SO not allowed with RO session */
+ rv = (p11t_module_funcs->C_Login)(session_ro, CKU_SO, pin, n_pin);
+ p11t_check_returns("C_Login: with RO as SO", rv, CKR_SESSION_READ_ONLY_EXISTS);
+
+ rv = (p11t_module_funcs->C_CloseSession)(session_ro);
+ p11t_check_returns("C_CloseSession: close RO session because SO", rv, CKR_OK);
+ }
+
+ /** - Login as SO */
+ rv = (p11t_module_funcs->C_Login)(session_rw, CKU_SO, pin, n_pin);
+ if(rv == CKR_USER_TYPE_INVALID)
+ return;
+ if(!p11t_check_returns("C_Login: as SO", rv, CKR_OK))
+ return;
+
+ /** - Login changes all session state */
+ session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_SO_FUNCTIONS);
+
+ if(p11t_test_unexpected)
+ {
+ /** - Can't open RO session when logged in as SO */
+ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, &session_ro);
+ p11t_check_returns("C_OpenSession: open RO when SO logged in", rv, CKR_SESSION_READ_WRITE_SO_EXISTS);
+ }
+
+ /** - Logout from SO */
+ rv = (p11t_module_funcs->C_Logout)(session_rw);
+ p11t_check_returns("C_Logout", rv, CKR_OK);
+
+ /** - Logout SO changes goes back to public */
+ session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION);
+}
+
void
session_main(CK_SLOT_ID slot)
{
@@ -92,8 +237,7 @@ session_main(CK_SLOT_ID slot)
/* Test all the sessions and validate their state */
session_info(session_ro, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION);
session_info(session_ro2, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION);
- if(session_rw)
- session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION);
+ session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION);
/** C_CloseSession */
@@ -173,6 +317,18 @@ session_pin(CK_SLOT_ID slot)
}
void
+session_operation_state(CK_SLOT_ID slot)
+{
+ /** C_GetOperationState */
+
+ /** - Not Implemented */
+
+ /** C_SetOperationState */
+
+ /** - Not Implemented */
+}
+
+void
p11t_session_tests()
{
CK_ULONG i;
@@ -182,12 +338,16 @@ p11t_session_tests()
CK_SLOT_ID slot = p11t_slot_ids[i];
session_pin(slot);
session_main(slot);
+ session_user_login(slot);
+ session_so_login(slot);
}
}
void
p11t_session_config(const char *name, const char *value)
{
- if(strcmp(name, "login-pin") == 0)
- login_pin = value;
+ if(strcmp(name, "login-user-pin") == 0)
+ login_user_pin = value;
+ if(strcmp(name, "login-so-pin") == 0)
+ login_so_pin = value;
}
diff --git a/src/slot.c b/src/slot.c
index e7f8478..6919846 100644
--- a/src/slot.c
+++ b/src/slot.c
@@ -393,3 +393,26 @@ p11t_slot_tests(void)
slot_events();
slot_mechanisms();
}
+
+CK_TOKEN_INFO_PTR
+p11t_slot_get_token_info(CK_SLOT_ID slot)
+{
+ CK_ULONG i;
+
+ for(i = 0; i < p11t_slot_count; ++i)
+ {
+ if(slot == p11t_slot_ids[i])
+ {
+ if(p11t_slot_info[i].flags & CKF_TOKEN_PRESENT)
+ {
+ return &p11t_slot_token_info[i];
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ }
+
+ return NULL;
+}