From e0c53da1d03328ea7aa29116c4452c4632f286a2 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 5 Dec 2008 15:48:39 +0000 Subject: Implement login. --- doc/pkcs11-coverage.txt | 19 ++++++ src/p11-tests.h | 1 + src/session.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++-- src/slot.c | 23 +++++++ 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 -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 */ @@ -172,6 +316,18 @@ session_pin(CK_SLOT_ID slot) /** - Not Implemented */ } +void +session_operation_state(CK_SLOT_ID slot) +{ + /** C_GetOperationState */ + + /** - Not Implemented */ + + /** C_SetOperationState */ + + /** - Not Implemented */ +} + void p11t_session_tests() { @@ -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; +} -- cgit v1.2.3