Back to index

lightning-sunbird  0.9+nobinonly
fipstokn.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 /*
00037  * This file implements PKCS 11 on top of our existing security modules
00038  *
00039  * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
00040  *   This implementation has two slots:
00041  *     slot 1 is our generic crypto support. It does not require login
00042  *   (unless you've enabled FIPS). It supports Public Key ops, and all they
00043  *   bulk ciphers and hashes. It can also support Private Key ops for imported
00044  *   Private keys. It does not have any token storage.
00045  *     slot 2 is our private key support. It requires a login before use. It
00046  *   can store Private Keys and Certs as token objects. Currently only private
00047  *   keys and their associated Certificates are saved on the token.
00048  *
00049  *   In this implementation, session objects are only visible to the session
00050  *   that created or generated them.
00051  */
00052 #include "seccomon.h"
00053 #include "softoken.h"
00054 #include "lowkeyi.h"
00055 #include "pcert.h"
00056 #include "pkcs11.h"
00057 #include "pkcs11i.h"
00058 #include "prenv.h"
00059 #include "prprf.h"
00060 
00061 #include <ctype.h>
00062 
00063 #ifdef XP_UNIX
00064 #define NSS_AUDIT_WITH_SYSLOG 1
00065 #include <syslog.h>
00066 #include <unistd.h>
00067 #endif
00068 
00069 #ifdef SOLARIS
00070 #include <bsm/libbsm.h>
00071 #define AUE_FIPS_AUDIT 34444
00072 #endif
00073 
00074 #ifdef LINUX
00075 #include <pthread.h>
00076 #include <dlfcn.h>
00077 #define LIBAUDIT_NAME "libaudit.so.0"
00078 #ifndef AUDIT_USER
00079 #define AUDIT_USER 1005  /* message type: message from userspace */
00080 #endif
00081 static void *libaudit_handle;
00082 static int (*audit_open_func)(void);
00083 static void (*audit_close_func)(int fd);
00084 static int (*audit_log_user_message_func)(int audit_fd, int type,
00085     const char *message, const char *hostname, const char *addr,
00086     const char *tty, int result);
00087 static int (*audit_send_user_message_func)(int fd, int type,
00088     const char *message);
00089 
00090 static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT;
00091 
00092 static void
00093 libaudit_init(void)
00094 {
00095     libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY);
00096     if (!libaudit_handle) {
00097        return;
00098     }
00099     audit_open_func = dlsym(libaudit_handle, "audit_open");
00100     audit_close_func = dlsym(libaudit_handle, "audit_close");
00101     /*
00102      * audit_send_user_message is the older function.
00103      * audit_log_user_message, if available, is preferred.
00104      */
00105     audit_log_user_message_func = dlsym(libaudit_handle,
00106                                    "audit_log_user_message");
00107     if (!audit_log_user_message_func) {
00108        audit_send_user_message_func = dlsym(libaudit_handle,
00109                                         "audit_send_user_message");
00110     }
00111     if (!audit_open_func || !audit_close_func ||
00112        (!audit_log_user_message_func && !audit_send_user_message_func)) {
00113        dlclose(libaudit_handle);
00114        libaudit_handle = NULL;
00115        audit_open_func = NULL;
00116        audit_close_func = NULL;
00117        audit_log_user_message_func = NULL;
00118        audit_send_user_message_func = NULL;
00119     }
00120 }
00121 #endif /* LINUX */
00122 
00123 
00124 /*
00125  * ******************** Password Utilities *******************************
00126  */
00127 static PRBool isLoggedIn = PR_FALSE;
00128 PRBool sftk_fatalError = PR_FALSE;
00129 
00130 /*
00131  * This function returns
00132  *   - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string
00133  *   - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not
00134  *     consist of characters from three or more character classes.
00135  *   - CKR_OK otherwise
00136  *
00137  * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters.
00138  * We define five character classes: digits (0-9), ASCII lowercase letters,
00139  * ASCII uppercase letters, ASCII non-alphanumeric characters (such as
00140  * space and punctuation marks), and non-ASCII characters.  If an ASCII
00141  * uppercase letter is the first character of the password/PIN, the
00142  * uppercase letter is not counted toward its character class.  Similarly,
00143  * if a digit is the last character of the password/PIN, the digit is not
00144  * counted toward its character class.
00145  *
00146  * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum
00147  * password/PIN length checks, they check the length in bytes as opposed
00148  * to characters.  To meet the minimum password/PIN guessing probability
00149  * requirements in FIPS 140-2, we need to check the length in characters.
00150  */
00151 static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
00152     unsigned int i;
00153     int nchar = 0;      /* number of characters */
00154     int ntrail = 0;     /* number of trailing bytes to follow */
00155     int ndigit = 0;     /* number of decimal digits */
00156     int nlower = 0;     /* number of ASCII lowercase letters */
00157     int nupper = 0;     /* number of ASCII uppercase letters */
00158     int nnonalnum = 0;  /* number of ASCII non-alphanumeric characters */
00159     int nnonascii = 0;  /* number of non-ASCII characters */
00160     int nclass;         /* number of character classes */
00161 
00162     for (i = 0; i < ulPinLen; i++) {
00163        unsigned int byte = pPin[i];
00164 
00165        if (ntrail) {
00166            if ((byte & 0xc0) != 0x80) {
00167               /* illegal */
00168               nchar = -1;
00169               break;
00170            }
00171            if (--ntrail == 0) {
00172               nchar++;
00173               nnonascii++;
00174            }
00175            continue;
00176        }
00177        if ((byte & 0x80) == 0x00) {
00178            /* single-byte (ASCII) character */
00179            nchar++;
00180            if (isdigit(byte)) {
00181               if (i < ulPinLen - 1) {
00182                   ndigit++;
00183               }
00184            } else if (islower(byte)) {
00185               nlower++;
00186            } else if (isupper(byte)) {
00187               if (i > 0) {
00188                   nupper++;
00189               }
00190            } else {
00191               nnonalnum++;
00192            }
00193        } else if ((byte & 0xe0) == 0xc0) {
00194            /* leading byte of two-byte character */
00195            ntrail = 1;
00196        } else if ((byte & 0xf0) == 0xe0) {
00197            /* leading byte of three-byte character */
00198            ntrail = 2;
00199        } else if ((byte & 0xf8) == 0xf0) {
00200            /* leading byte of four-byte character */
00201            ntrail = 3;
00202        } else {
00203            /* illegal */
00204            nchar = -1;
00205            break;
00206        }
00207     }
00208     if (nchar == -1) {
00209        /* illegal UTF8 string */
00210        return CKR_PIN_INVALID;
00211     }
00212     if (nchar < FIPS_MIN_PIN) {
00213        return CKR_PIN_LEN_RANGE;
00214     }
00215     nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
00216             (nnonalnum != 0) + (nnonascii != 0);
00217     if (nclass < 3) {
00218        return CKR_PIN_LEN_RANGE;
00219     }
00220     return CKR_OK;
00221 }
00222 
00223 
00224 /* FIPS required checks before any useful cryptographic services */
00225 static CK_RV sftk_fipsCheck(void) {
00226     if (sftk_fatalError) 
00227        return CKR_DEVICE_ERROR;
00228     if (!isLoggedIn) 
00229        return CKR_USER_NOT_LOGGED_IN;
00230     return CKR_OK;
00231 }
00232 
00233 
00234 #define SFTK_FIPSCHECK() \
00235     CK_RV rv; \
00236     if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
00237 
00238 #define SFTK_FIPSFATALCHECK() \
00239     if (sftk_fatalError) return CKR_DEVICE_ERROR;
00240 
00241 
00242 /* grab an attribute out of a raw template */
00243 void *
00244 fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate, 
00245                             CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type)
00246 {
00247     int i;
00248 
00249     for (i=0; i < (int) ulCount; i++) {
00250        if (pTemplate[i].type == type) {
00251            return pTemplate[i].pValue;
00252        }
00253     }
00254     return NULL;
00255 }
00256 
00257 
00258 #define __PASTE(x,y) x##y
00259 
00260 /* ------------- forward declare all the NSC_ functions ------------- */
00261 #undef CK_NEED_ARG_LIST
00262 #undef CK_PKCS11_FUNCTION_INFO
00263 
00264 #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name)
00265 #define CK_NEED_ARG_LIST 1
00266 
00267 #include "pkcs11f.h"
00268 
00269 /* ------------- forward declare all the FIPS functions ------------- */
00270 #undef CK_NEED_ARG_LIST
00271 #undef CK_PKCS11_FUNCTION_INFO
00272 
00273 #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name)
00274 #define CK_NEED_ARG_LIST 1
00275 
00276 #include "pkcs11f.h"
00277 
00278 /* ------------- build the CK_CRYPTO_TABLE ------------------------- */
00279 static CK_FUNCTION_LIST sftk_fipsTable = {
00280     { 1, 10 },
00281 
00282 #undef CK_NEED_ARG_LIST
00283 #undef CK_PKCS11_FUNCTION_INFO
00284 
00285 #define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name),
00286 
00287 
00288 #include "pkcs11f.h"
00289 
00290 };
00291 
00292 #undef CK_NEED_ARG_LIST
00293 #undef CK_PKCS11_FUNCTION_INFO
00294 
00295 
00296 #undef __PASTE
00297 
00298 /* CKO_NOT_A_KEY can be any object class that's not a key object. */
00299 #define CKO_NOT_A_KEY CKO_DATA
00300 
00301 #define SFTK_IS_KEY_OBJECT(objClass) \
00302     (((objClass) == CKO_PUBLIC_KEY) || \
00303     ((objClass) == CKO_PRIVATE_KEY) || \
00304     ((objClass) == CKO_SECRET_KEY))
00305 
00306 #define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \
00307     (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY))
00308 
00309 static CK_RV
00310 sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession,
00311     CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass)
00312 {
00313     CK_RV rv;
00314     CK_ATTRIBUTE class; 
00315     class.type = CKA_CLASS;
00316     class.pValue = pObjClass;
00317     class.ulValueLen = sizeof(*pObjClass);
00318     rv = NSC_GetAttributeValue(hSession, hObject, &class, 1);
00319     if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) {
00320        rv = sftk_fipsCheck();
00321     }
00322     return rv;
00323 }
00324 
00325 /**********************************************************************
00326  *
00327  *     FIPS 140 auditable event logging
00328  *
00329  **********************************************************************/
00330 
00331 PRBool sftk_audit_enabled = PR_FALSE;
00332 
00333 /*
00334  * Each audit record must have the following information:
00335  * - Date and time of the event
00336  * - Type of event
00337  * - user (subject) identity
00338  * - outcome (success or failure) of the event
00339  * - process ID
00340  * - name (ID) of the object
00341  * - for changes to data (except for authentication data and CSPs), the new
00342  *   and old values of the data
00343  * - for authentication attempts, the origin of the attempt (e.g., terminal
00344  *   identifier)
00345  * - for assuming a role, the type of role, and the location of the request
00346  */
00347 void
00348 sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg)
00349 {
00350 #ifdef NSS_AUDIT_WITH_SYSLOG
00351     int level;
00352 
00353     switch (severity) {
00354     case NSS_AUDIT_ERROR:
00355        level = LOG_ERR;
00356        break;
00357     case NSS_AUDIT_WARNING:
00358        level = LOG_WARNING;
00359        break;
00360     default:
00361        level = LOG_INFO;
00362        break;
00363     }
00364     /* timestamp is provided by syslog in the message header */
00365     syslog(level | LOG_USER /* facility */,
00366           "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s",
00367           (int)getpid(), (int)getuid(), msg);
00368 #ifdef LINUX
00369     if (pthread_once(&libaudit_once_control, libaudit_init) != 0) {
00370        return;
00371     }
00372     if (libaudit_handle) {
00373        int audit_fd;
00374        int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */
00375        char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
00376        if (!message) {
00377            return;
00378        }
00379        audit_fd = audit_open_func();
00380        if (audit_fd < 0) {
00381            PR_smprintf_free(message);
00382            return;
00383        }
00384        if (audit_log_user_message_func) {
00385            audit_log_user_message_func(audit_fd, AUDIT_USER, message,
00386                                    NULL, NULL, NULL, result);
00387        } else {
00388            audit_send_user_message_func(audit_fd, AUDIT_USER, message);
00389        }
00390        audit_close_func(audit_fd);
00391        PR_smprintf_free(message);
00392     }
00393 #endif /* LINUX */
00394 #ifdef SOLARIS
00395     {
00396         int rd;
00397         char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
00398 
00399         if (!message) {
00400             return;
00401         }
00402 
00403         /* open the record descriptor */
00404         if ((rd = au_open()) == -1) {
00405             PR_smprintf_free(message);
00406             return;
00407         }
00408 
00409         /* write the audit tokens to the audit record */
00410         if (au_write(rd, au_to_text(message))) {
00411             (void)au_close(rd, AU_TO_NO_WRITE, AUE_FIPS_AUDIT);
00412             PR_smprintf_free(message);
00413             return;
00414         }
00415 
00416         /* close the record and send it to the audit trail */
00417         (void)au_close(rd, AU_TO_WRITE, AUE_FIPS_AUDIT);
00418 
00419         PR_smprintf_free(message);
00420     }
00421 #endif /* SOLARIS */
00422 #else
00423     /* do nothing */
00424 #endif
00425 }
00426 
00427 
00428 /**********************************************************************
00429  *
00430  *     Start of PKCS 11 functions 
00431  *
00432  **********************************************************************/
00433 /* return the function list */
00434 CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
00435     *pFunctionList = &sftk_fipsTable;
00436     return CKR_OK;
00437 }
00438 
00439 /* sigh global so pkcs11 can read it */
00440 PRBool nsf_init = PR_FALSE;
00441 
00442 /* FC_Initialize initializes the PKCS #11 library. */
00443 CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
00444     const char *envp;
00445     CK_RV crv;
00446 
00447     if (nsf_init) {
00448        return CKR_CRYPTOKI_ALREADY_INITIALIZED;
00449     }
00450 
00451     if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
00452        sftk_audit_enabled = (atoi(envp) == 1);
00453     }
00454 
00455     crv = nsc_CommonInitialize(pReserved, PR_TRUE);
00456 
00457     /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
00458     if (crv != CKR_OK) {
00459        sftk_fatalError = PR_TRUE;
00460        return crv;
00461     }
00462 
00463     sftk_fatalError = PR_FALSE; /* any error has been reset */
00464 
00465     crv = sftk_fipsPowerUpSelfTest();
00466     if (crv != CKR_OK) {
00467         nsc_CommonFinalize(NULL, PR_TRUE);
00468        sftk_fatalError = PR_TRUE;
00469        if (sftk_audit_enabled) {
00470            char msg[128];
00471            PR_snprintf(msg,sizeof msg,
00472                      "C_Initialize()=0x%08lX "
00473                      "power-up self-tests failed",
00474                      (PRUint32)crv);
00475            sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
00476        }
00477        return crv;
00478     }
00479     nsf_init = PR_TRUE;
00480 
00481     return CKR_OK;
00482 }
00483 
00484 /*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
00485 CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
00486    CK_RV crv;
00487    if (!nsf_init) {
00488       return CKR_OK;
00489    }
00490    crv = nsc_CommonFinalize (pReserved, PR_TRUE);
00491    nsf_init = (PRBool) !(crv == CKR_OK);
00492    return crv;
00493 }
00494 
00495 
00496 /* FC_GetInfo returns general information about PKCS #11. */
00497 CK_RV  FC_GetInfo(CK_INFO_PTR pInfo) {
00498     return NSC_GetInfo(pInfo);
00499 }
00500 
00501 /* FC_GetSlotList obtains a list of slots in the system. */
00502 CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
00503                      CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
00504     return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount,
00505                                                   NSC_FIPS_MODULE);
00506 }
00507        
00508 /* FC_GetSlotInfo obtains information about a particular slot in the system. */
00509 CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
00510     return NSC_GetSlotInfo(slotID,pInfo);
00511 }
00512 
00513 
00514 /*FC_GetTokenInfo obtains information about a particular token in the system.*/
00515  CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
00516     CK_RV crv;
00517 
00518     crv = NSC_GetTokenInfo(slotID,pInfo);
00519     if (crv == CKR_OK) 
00520        pInfo->flags |= CKF_LOGIN_REQUIRED;
00521     return crv;
00522 
00523 }
00524 
00525 
00526 
00527 /*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/
00528  CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
00529        CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
00530     SFTK_FIPSFATALCHECK();
00531     if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
00532     /* FIPS Slot supports all functions */
00533     return NSC_GetMechanismList(slotID,pMechanismList,pusCount);
00534 }
00535 
00536 
00537 /* FC_GetMechanismInfo obtains information about a particular mechanism 
00538  * possibly supported by a token. */
00539  CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
00540                                    CK_MECHANISM_INFO_PTR pInfo) {
00541     SFTK_FIPSFATALCHECK();
00542     if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
00543     /* FIPS Slot supports all functions */
00544     return NSC_GetMechanismInfo(slotID,type,pInfo);
00545 }
00546 
00547 
00548 /* FC_InitToken initializes a token. */
00549  CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
00550                             CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
00551     CK_RV crv;
00552 
00553     crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel);
00554     if (sftk_audit_enabled) {
00555        char msg[128];
00556        NSSAuditSeverity severity = (crv == CKR_OK) ?
00557               NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
00558        /* pLabel points to a 32-byte label, which is not null-terminated */
00559        PR_snprintf(msg,sizeof msg,
00560               "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX",
00561               (PRUint32)slotID,pLabel,(PRUint32)crv);
00562        sftk_LogAuditMessage(severity, msg);
00563     }
00564     return crv;
00565 }
00566 
00567 
00568 /* FC_InitPIN initializes the normal user's PIN. */
00569  CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
00570                                    CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
00571     CK_RV rv;
00572     if (sftk_fatalError) return CKR_DEVICE_ERROR;
00573     if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
00574        rv = NSC_InitPIN(hSession,pPin,ulPinLen);
00575     }
00576     if (sftk_audit_enabled) {
00577        char msg[128];
00578        NSSAuditSeverity severity = (rv == CKR_OK) ?
00579               NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
00580        PR_snprintf(msg,sizeof msg,
00581               "C_InitPIN(hSession=0x%08lX)=0x%08lX",
00582               (PRUint32)hSession,(PRUint32)rv);
00583        sftk_LogAuditMessage(severity, msg);
00584     }
00585     return rv;
00586 }
00587 
00588 
00589 /* FC_SetPIN modifies the PIN of user that is currently logged in. */
00590 /* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
00591  CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
00592     CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
00593     CK_RV rv;
00594     if ((rv = sftk_fipsCheck()) == CKR_OK &&
00595        (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) {
00596        rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
00597     }
00598     if (sftk_audit_enabled) {
00599        char msg[128];
00600        NSSAuditSeverity severity = (rv == CKR_OK) ?
00601               NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
00602        PR_snprintf(msg,sizeof msg,
00603               "C_SetPIN(hSession=0x%08lX)=0x%08lX",
00604               (PRUint32)hSession,(PRUint32)rv);
00605        sftk_LogAuditMessage(severity, msg);
00606     }
00607     return rv;
00608 }
00609 
00610 /* FC_OpenSession opens a session between an application and a token. */
00611  CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
00612    CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) {
00613     SFTK_FIPSFATALCHECK();
00614     return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession);
00615 }
00616 
00617 
00618 /* FC_CloseSession closes a session between an application and a token. */
00619  CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) {
00620     return NSC_CloseSession(hSession);
00621 }
00622 
00623 
00624 /* FC_CloseAllSessions closes all sessions with a token. */
00625  CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) {
00626     return NSC_CloseAllSessions (slotID);
00627 }
00628 
00629 
00630 /* FC_GetSessionInfo obtains information about the session. */
00631  CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
00632                                           CK_SESSION_INFO_PTR pInfo) {
00633     CK_RV rv;
00634     SFTK_FIPSFATALCHECK();
00635 
00636     rv = NSC_GetSessionInfo(hSession,pInfo);
00637     if (rv == CKR_OK) {
00638        if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) {
00639               pInfo->state = CKS_RO_USER_FUNCTIONS;
00640        }
00641        if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) {
00642               pInfo->state = CKS_RW_USER_FUNCTIONS;
00643        }
00644     }
00645     return rv;
00646 }
00647 
00648 /* FC_Login logs a user into a token. */
00649  CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
00650                                 CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
00651     CK_RV rv;
00652     PRBool successful;
00653     if (sftk_fatalError) return CKR_DEVICE_ERROR;
00654     rv = NSC_Login(hSession,userType,pPin,usPinLen);
00655     successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN);
00656     if (successful)
00657        isLoggedIn = PR_TRUE;
00658     if (sftk_audit_enabled) {
00659        char msg[128];
00660        NSSAuditSeverity severity;
00661        severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
00662        PR_snprintf(msg,sizeof msg,
00663                   "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX",
00664                   (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
00665        sftk_LogAuditMessage(severity, msg);
00666     }
00667     return rv;
00668 }
00669 
00670 /* FC_Logout logs a user out from a token. */
00671  CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
00672     CK_RV rv;
00673     if ((rv = sftk_fipsCheck()) == CKR_OK) {
00674        rv = NSC_Logout(hSession);
00675        isLoggedIn = PR_FALSE;
00676     }
00677     if (sftk_audit_enabled) {
00678        char msg[128];
00679        NSSAuditSeverity severity = (rv == CKR_OK) ?
00680               NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
00681        PR_snprintf(msg,sizeof msg,
00682                   "C_Logout(hSession=0x%08lX)=0x%08lX",
00683                   (PRUint32)hSession,(PRUint32)rv);
00684        sftk_LogAuditMessage(severity, msg);
00685     }
00686     return rv;
00687 }
00688 
00689 
00690 /* FC_CreateObject creates a new object. */
00691  CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession,
00692               CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 
00693                                    CK_OBJECT_HANDLE_PTR phObject) {
00694     CK_OBJECT_CLASS * classptr;
00695     SFTK_FIPSCHECK();
00696     classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS);
00697     if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
00698 
00699     /* FIPS can't create keys from raw key material */
00700     if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) {
00701        rv = CKR_ATTRIBUTE_VALUE_INVALID;
00702     } else {
00703        rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
00704     }
00705     if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) {
00706        sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv);
00707     }
00708     return rv;
00709 }
00710 
00711 
00712 
00713 
00714 
00715 /* FC_CopyObject copies an object, creating a new object for the copy. */
00716  CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession,
00717        CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
00718                                    CK_OBJECT_HANDLE_PTR phNewObject) {
00719     CK_RV rv;
00720     CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
00721     SFTK_FIPSFATALCHECK();
00722     rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
00723     if (rv == CKR_OK) {
00724        rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject);
00725     }
00726     if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
00727        sftk_AuditCopyObject(hSession,
00728            hObject,pTemplate,ulCount,phNewObject,rv);
00729     }
00730     return rv;
00731 }
00732 
00733 
00734 /* FC_DestroyObject destroys an object. */
00735  CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession,
00736                                           CK_OBJECT_HANDLE hObject) {
00737     CK_RV rv;
00738     CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
00739     SFTK_FIPSFATALCHECK();
00740     rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
00741     if (rv == CKR_OK) {
00742        rv = NSC_DestroyObject(hSession,hObject);
00743     }
00744     if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
00745        sftk_AuditDestroyObject(hSession,hObject,rv);
00746     }
00747     return rv;
00748 }
00749 
00750 
00751 /* FC_GetObjectSize gets the size of an object in bytes. */
00752  CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession,
00753                      CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) {
00754     CK_RV rv;
00755     CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
00756     SFTK_FIPSFATALCHECK();
00757     rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
00758     if (rv == CKR_OK) {
00759        rv = NSC_GetObjectSize(hSession, hObject, pulSize);
00760     }
00761     if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
00762        sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv);
00763     }
00764     return rv;
00765 }
00766 
00767 
00768 /* FC_GetAttributeValue obtains the value of one or more object attributes. */
00769  CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession,
00770  CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
00771     CK_RV rv;
00772     CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
00773     SFTK_FIPSFATALCHECK();
00774     rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
00775     if (rv == CKR_OK) {
00776        rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount);
00777     }
00778     if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
00779        sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
00780     }
00781     return rv;
00782 }
00783 
00784 
00785 /* FC_SetAttributeValue modifies the value of one or more object attributes */
00786  CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession,
00787  CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
00788     CK_RV rv;
00789     CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
00790     SFTK_FIPSFATALCHECK();
00791     rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
00792     if (rv == CKR_OK) {
00793        rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount);
00794     }
00795     if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
00796        sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
00797     }
00798     return rv;
00799 }
00800 
00801 
00802 
00803 /* FC_FindObjectsInit initializes a search for token and session objects 
00804  * that match a template. */
00805  CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
00806                      CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
00807     /* let publically readable object be found */
00808     unsigned int i;
00809     CK_RV rv;
00810     PRBool needLogin = PR_FALSE;
00811 
00812     SFTK_FIPSFATALCHECK();
00813 
00814     for (i=0; i < usCount; i++) {
00815        CK_OBJECT_CLASS class;
00816        if (pTemplate[i].type != CKA_CLASS) {
00817            continue;
00818        }
00819        if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
00820            continue;
00821        }
00822        if (pTemplate[i].pValue == NULL) {
00823            continue;
00824        }
00825        class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
00826        if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) {
00827            needLogin = PR_TRUE;
00828            break;
00829        }
00830     }
00831     if (needLogin) {
00832        if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
00833     }
00834     return NSC_FindObjectsInit(hSession,pTemplate,usCount);
00835 }
00836 
00837 
00838 /* FC_FindObjects continues a search for token and session objects 
00839  * that match a template, obtaining additional object handles. */
00840  CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession,
00841     CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount,
00842                                    CK_ULONG_PTR pusObjectCount) {
00843     /* let publically readable object be found */
00844     SFTK_FIPSFATALCHECK();
00845     return NSC_FindObjects(hSession,phObject,usMaxObjectCount,
00846                                                  pusObjectCount);
00847 }
00848 
00849 
00850 /*
00851  ************** Crypto Functions:     Encrypt ************************
00852  */
00853 
00854 /* FC_EncryptInit initializes an encryption operation. */
00855  CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
00856                CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
00857     SFTK_FIPSCHECK();
00858     rv = NSC_EncryptInit(hSession,pMechanism,hKey);
00859     if (sftk_audit_enabled) {
00860        sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv);
00861     }
00862     return rv;
00863 }
00864 
00865 /* FC_Encrypt encrypts single-part data. */
00866  CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
00867               CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData,
00868                                     CK_ULONG_PTR pusEncryptedDataLen) {
00869     SFTK_FIPSCHECK();
00870     return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData,
00871                                                  pusEncryptedDataLen);
00872 }
00873 
00874 
00875 /* FC_EncryptUpdate continues a multiple-part encryption operation. */
00876  CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession,
00877     CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart,       
00878                                    CK_ULONG_PTR pusEncryptedPartLen) {
00879     SFTK_FIPSCHECK();
00880     return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart,
00881                                           pusEncryptedPartLen);
00882 }
00883 
00884 
00885 /* FC_EncryptFinal finishes a multiple-part encryption operation. */
00886  CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession,
00887     CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) {
00888 
00889     SFTK_FIPSCHECK();
00890     return NSC_EncryptFinal(hSession,pLastEncryptedPart,
00891                                           pusLastEncryptedPartLen);
00892 }
00893 
00894 /*
00895  ************** Crypto Functions:     Decrypt ************************
00896  */
00897 
00898 
00899 /* FC_DecryptInit initializes a decryption operation. */
00900  CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession,
00901                       CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
00902     SFTK_FIPSCHECK();
00903     rv = NSC_DecryptInit(hSession,pMechanism,hKey);
00904     if (sftk_audit_enabled) {
00905        sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv);
00906     }
00907     return rv;
00908 }
00909 
00910 /* FC_Decrypt decrypts encrypted data in a single part. */
00911  CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession,
00912     CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData,
00913                                           CK_ULONG_PTR pusDataLen) {
00914     SFTK_FIPSCHECK();
00915     return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData,
00916                                                         pusDataLen);
00917 }
00918 
00919 
00920 /* FC_DecryptUpdate continues a multiple-part decryption operation. */
00921  CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession,
00922     CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen,
00923                             CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) {
00924     SFTK_FIPSCHECK();
00925     return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen,
00926                                                  pPart,pusPartLen);
00927 }
00928 
00929 
00930 /* FC_DecryptFinal finishes a multiple-part decryption operation. */
00931  CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession,
00932     CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) {
00933     SFTK_FIPSCHECK();
00934     return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen);
00935 }
00936 
00937 
00938 /*
00939  ************** Crypto Functions:     Digest (HASH)  ************************
00940  */
00941 
00942 /* FC_DigestInit initializes a message-digesting operation. */
00943  CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession,
00944                                    CK_MECHANISM_PTR pMechanism) {
00945     SFTK_FIPSFATALCHECK();
00946     return NSC_DigestInit(hSession, pMechanism);
00947 }
00948 
00949 
00950 /* FC_Digest digests data in a single part. */
00951  CK_RV FC_Digest(CK_SESSION_HANDLE hSession,
00952     CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest,
00953                                           CK_ULONG_PTR pusDigestLen) {
00954     SFTK_FIPSFATALCHECK();
00955     return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen);
00956 }
00957 
00958 
00959 /* FC_DigestUpdate continues a multiple-part message-digesting operation. */
00960  CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
00961                                        CK_ULONG usPartLen) {
00962     SFTK_FIPSFATALCHECK();
00963     return NSC_DigestUpdate(hSession,pPart,usPartLen);
00964 }
00965 
00966 
00967 /* FC_DigestFinal finishes a multiple-part message-digesting operation. */
00968  CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
00969                                           CK_ULONG_PTR pusDigestLen) {
00970     SFTK_FIPSFATALCHECK();
00971     return NSC_DigestFinal(hSession,pDigest,pusDigestLen);
00972 }
00973 
00974 
00975 /*
00976  ************** Crypto Functions:     Sign  ************************
00977  */
00978 
00979 /* FC_SignInit initializes a signature (private key encryption) operation,
00980  * where the signature is (will be) an appendix to the data, 
00981  * and plaintext cannot be recovered from the signature */
00982  CK_RV FC_SignInit(CK_SESSION_HANDLE hSession,
00983                CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
00984     SFTK_FIPSCHECK();
00985     rv = NSC_SignInit(hSession,pMechanism,hKey);
00986     if (sftk_audit_enabled) {
00987        sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv);
00988     }
00989     return rv;
00990 }
00991 
00992 
00993 /* FC_Sign signs (encrypts with private key) data in a single part,
00994  * where the signature is (will be) an appendix to the data, 
00995  * and plaintext cannot be recovered from the signature */
00996  CK_RV FC_Sign(CK_SESSION_HANDLE hSession,
00997     CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature,
00998                                    CK_ULONG_PTR pusSignatureLen) {
00999     SFTK_FIPSCHECK();
01000     return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen);
01001 }
01002 
01003 
01004 /* FC_SignUpdate continues a multiple-part signature operation,
01005  * where the signature is (will be) an appendix to the data, 
01006  * and plaintext cannot be recovered from the signature */
01007  CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
01008                                                  CK_ULONG usPartLen) {
01009     SFTK_FIPSCHECK();
01010     return NSC_SignUpdate(hSession,pPart,usPartLen);
01011 }
01012 
01013 
01014 /* FC_SignFinal finishes a multiple-part signature operation, 
01015  * returning the signature. */
01016  CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
01017                                        CK_ULONG_PTR pusSignatureLen) {
01018     SFTK_FIPSCHECK();
01019     return NSC_SignFinal(hSession,pSignature,pusSignatureLen);
01020 }
01021 
01022 /*
01023  ************** Crypto Functions:     Sign Recover  ************************
01024  */
01025 /* FC_SignRecoverInit initializes a signature operation,
01026  * where the (digest) data can be recovered from the signature. 
01027  * E.g. encryption with the user's private key */
01028  CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
01029                       CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
01030     SFTK_FIPSCHECK();
01031     rv = NSC_SignRecoverInit(hSession,pMechanism,hKey);
01032     if (sftk_audit_enabled) {
01033        sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv);
01034     }
01035     return rv;
01036 }
01037 
01038 
01039 /* FC_SignRecover signs data in a single operation
01040  * where the (digest) data can be recovered from the signature. 
01041  * E.g. encryption with the user's private key */
01042  CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
01043   CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) {
01044     SFTK_FIPSCHECK();
01045     return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen);
01046 }
01047 
01048 /*
01049  ************** Crypto Functions:     verify  ************************
01050  */
01051 
01052 /* FC_VerifyInit initializes a verification operation, 
01053  * where the signature is an appendix to the data, 
01054  * and plaintext cannot be recovered from the signature (e.g. DSA) */
01055  CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession,
01056                         CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
01057     SFTK_FIPSCHECK();
01058     rv = NSC_VerifyInit(hSession,pMechanism,hKey);
01059     if (sftk_audit_enabled) {
01060        sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv);
01061     }
01062     return rv;
01063 }
01064 
01065 
01066 /* FC_Verify verifies a signature in a single-part operation, 
01067  * where the signature is an appendix to the data, 
01068  * and plaintext cannot be recovered from the signature */
01069  CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
01070     CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) {
01071     /* make sure we're legal */
01072     SFTK_FIPSCHECK();
01073     return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen);
01074 }
01075 
01076 
01077 /* FC_VerifyUpdate continues a multiple-part verification operation, 
01078  * where the signature is an appendix to the data, 
01079  * and plaintext cannot be recovered from the signature */
01080  CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
01081                                           CK_ULONG usPartLen) {
01082     SFTK_FIPSCHECK();
01083     return NSC_VerifyUpdate(hSession,pPart,usPartLen);
01084 }
01085 
01086 
01087 /* FC_VerifyFinal finishes a multiple-part verification operation, 
01088  * checking the signature. */
01089  CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession,
01090                      CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) {
01091     SFTK_FIPSCHECK();
01092     return NSC_VerifyFinal(hSession,pSignature,usSignatureLen);
01093 }
01094 
01095 /*
01096  ************** Crypto Functions:     Verify  Recover ************************
01097  */
01098 
01099 /* FC_VerifyRecoverInit initializes a signature verification operation, 
01100  * where the data is recovered from the signature. 
01101  * E.g. Decryption with the user's public key */
01102  CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
01103                      CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
01104     SFTK_FIPSCHECK();
01105     rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
01106     if (sftk_audit_enabled) {
01107        sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv);
01108     }
01109     return rv;
01110 }
01111 
01112 
01113 /* FC_VerifyRecover verifies a signature in a single-part operation, 
01114  * where the data is recovered from the signature. 
01115  * E.g. Decryption with the user's public key */
01116  CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession,
01117                CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen,
01118                             CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) {
01119     SFTK_FIPSCHECK();
01120     return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData,
01121                                                         pusDataLen);
01122 }
01123 
01124 /*
01125  **************************** Key Functions:  ************************
01126  */
01127 
01128 /* FC_GenerateKey generates a secret key, creating a new key object. */
01129  CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession,
01130     CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
01131                                           CK_OBJECT_HANDLE_PTR phKey) {
01132     CK_BBOOL *boolptr;
01133 
01134     SFTK_FIPSCHECK();
01135 
01136     /* all secret keys must be sensitive, if the upper level code tries to say
01137      * otherwise, reject it. */
01138     boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE);
01139     if (boolptr != NULL) {
01140        if (!(*boolptr)) {
01141            return CKR_ATTRIBUTE_VALUE_INVALID;
01142        }
01143     }
01144 
01145     rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
01146     if (sftk_audit_enabled) {
01147        sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv);
01148     }
01149     return rv;
01150 }
01151 
01152 
01153 /* FC_GenerateKeyPair generates a public-key/private-key pair, 
01154  * creating new key objects. */
01155  CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
01156     CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
01157     CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
01158     CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
01159                                    CK_OBJECT_HANDLE_PTR phPrivateKey) {
01160     CK_BBOOL *boolptr;
01161     CK_RV crv;
01162 
01163     SFTK_FIPSCHECK();
01164 
01165     /* all private keys must be sensitive, if the upper level code tries to say
01166      * otherwise, reject it. */
01167     boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate, 
01168                             usPrivateKeyAttributeCount, CKA_SENSITIVE);
01169     if (boolptr != NULL) {
01170        if (!(*boolptr)) {
01171            return CKR_ATTRIBUTE_VALUE_INVALID;
01172        }
01173     }
01174     crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
01175               usPublicKeyAttributeCount,pPrivateKeyTemplate,
01176               usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
01177     if (crv == CKR_GENERAL_ERROR) {
01178        /* pairwise consistency check failed. */
01179        sftk_fatalError = PR_TRUE;
01180     }
01181     if (sftk_audit_enabled) {
01182        sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate,
01183               usPublicKeyAttributeCount,pPrivateKeyTemplate,
01184               usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv);
01185     }
01186     return crv;
01187 }
01188 
01189 
01190 /* FC_WrapKey wraps (i.e., encrypts) a key. */
01191  CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
01192     CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
01193     CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
01194                                     CK_ULONG_PTR pulWrappedKeyLen) {
01195     SFTK_FIPSCHECK();
01196     rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
01197                                                  pulWrappedKeyLen);
01198     if (sftk_audit_enabled) {
01199        sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
01200                                                  pulWrappedKeyLen,rv);
01201     }
01202     return rv;
01203 }
01204 
01205 
01206 /* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
01207  CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession,
01208     CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
01209     CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
01210     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
01211                                            CK_OBJECT_HANDLE_PTR phKey) {
01212     CK_BBOOL *boolptr;
01213 
01214     SFTK_FIPSCHECK();
01215 
01216     /* all secret keys must be sensitive, if the upper level code tries to say
01217      * otherwise, reject it. */
01218     boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, 
01219                                    ulAttributeCount, CKA_SENSITIVE);
01220     if (boolptr != NULL) {
01221        if (!(*boolptr)) {
01222            return CKR_ATTRIBUTE_VALUE_INVALID;
01223        }
01224     }
01225     rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
01226                      ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey);
01227     if (sftk_audit_enabled) {
01228        sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
01229                      ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv);
01230     }
01231     return rv;
01232 }
01233 
01234 
01235 /* FC_DeriveKey derives a key from a base key, creating a new key object. */
01236  CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession,
01237         CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
01238         CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 
01239                                           CK_OBJECT_HANDLE_PTR phKey) {
01240     CK_BBOOL *boolptr;
01241 
01242     SFTK_FIPSCHECK();
01243 
01244     /* all secret keys must be sensitive, if the upper level code tries to say
01245      * otherwise, reject it. */
01246     boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, 
01247                                    ulAttributeCount, CKA_SENSITIVE);
01248     if (boolptr != NULL) {
01249        if (!(*boolptr)) {
01250            return CKR_ATTRIBUTE_VALUE_INVALID;
01251        }
01252     }
01253     rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
01254                      ulAttributeCount, phKey);
01255     if (sftk_audit_enabled) {
01256        sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
01257                      ulAttributeCount,phKey,rv);
01258     }
01259     return rv;
01260 }
01261 
01262 /*
01263  **************************** Radom Functions:  ************************
01264  */
01265 
01266 /* FC_SeedRandom mixes additional seed material into the token's random number 
01267  * generator. */
01268  CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
01269     CK_ULONG usSeedLen) {
01270     CK_RV crv;
01271 
01272     SFTK_FIPSFATALCHECK();
01273     crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
01274     if (crv != CKR_OK) {
01275        sftk_fatalError = PR_TRUE;
01276     }
01277     return crv;
01278 }
01279 
01280 
01281 /* FC_GenerateRandom generates random data. */
01282  CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
01283     CK_BYTE_PTR      pRandomData, CK_ULONG ulRandomLen) {
01284     CK_RV crv;
01285 
01286     SFTK_FIPSFATALCHECK();
01287     crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen);
01288     if (crv != CKR_OK) {
01289        sftk_fatalError = PR_TRUE;
01290        if (sftk_audit_enabled) {
01291            char msg[128];
01292            PR_snprintf(msg,sizeof msg,
01293                      "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, "
01294                      "ulRandomLen=%lu)=0x%08lX "
01295                      "self-test: continuous RNG test failed",
01296                      (PRUint32)hSession,pRandomData,
01297                      (PRUint32)ulRandomLen,(PRUint32)crv);
01298            sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
01299        }
01300     }
01301     return crv;
01302 }
01303 
01304 
01305 /* FC_GetFunctionStatus obtains an updated status of a function running 
01306  * in parallel with an application. */
01307  CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
01308     SFTK_FIPSCHECK();
01309     return NSC_GetFunctionStatus(hSession);
01310 }
01311 
01312 
01313 /* FC_CancelFunction cancels a function running in parallel */
01314  CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) {
01315     SFTK_FIPSCHECK();
01316     return NSC_CancelFunction(hSession);
01317 }
01318 
01319 /*
01320  ****************************  Version 1.1 Functions:  ************************
01321  */
01322 
01323 /* FC_GetOperationState saves the state of the cryptographic 
01324  *operation in a session. */
01325 CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession, 
01326        CK_BYTE_PTR  pOperationState, CK_ULONG_PTR pulOperationStateLen) {
01327     SFTK_FIPSFATALCHECK();
01328     return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen);
01329 }
01330 
01331 
01332 /* FC_SetOperationState restores the state of the cryptographic operation 
01333  * in a session. */
01334 CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession, 
01335        CK_BYTE_PTR  pOperationState, CK_ULONG  ulOperationStateLen,
01336         CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) {
01337     SFTK_FIPSFATALCHECK();
01338     return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen,
01339                                    hEncryptionKey,hAuthenticationKey);
01340 }
01341 
01342 /* FC_FindObjectsFinal finishes a search for token and session objects. */
01343 CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
01344     /* let publically readable object be found */
01345     SFTK_FIPSFATALCHECK();
01346     return NSC_FindObjectsFinal(hSession);
01347 }
01348 
01349 
01350 /* Dual-function cryptographic operations */
01351 
01352 /* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption 
01353  * operation. */
01354 CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR  pPart,
01355     CK_ULONG  ulPartLen, CK_BYTE_PTR  pEncryptedPart,
01356                                     CK_ULONG_PTR pulEncryptedPartLen) {
01357     SFTK_FIPSCHECK();
01358     return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
01359                                     pulEncryptedPartLen);
01360 }
01361 
01362 
01363 /* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting 
01364  * operation. */
01365 CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
01366      CK_BYTE_PTR  pEncryptedPart, CK_ULONG  ulEncryptedPartLen,
01367                             CK_BYTE_PTR  pPart, CK_ULONG_PTR pulPartLen) {
01368 
01369     SFTK_FIPSCHECK();
01370     return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen,
01371                             pPart,pulPartLen);
01372 }
01373 
01374 /* FC_SignEncryptUpdate continues a multiple-part signing and encryption 
01375  * operation. */
01376 CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR  pPart,
01377         CK_ULONG  ulPartLen, CK_BYTE_PTR  pEncryptedPart,
01378                                     CK_ULONG_PTR pulEncryptedPartLen) {
01379 
01380     SFTK_FIPSCHECK();
01381     return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
01382                                     pulEncryptedPartLen);
01383 }
01384 
01385 /* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify 
01386  * operation. */
01387 CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, 
01388        CK_BYTE_PTR  pEncryptedData, CK_ULONG  ulEncryptedDataLen, 
01389                             CK_BYTE_PTR  pData, CK_ULONG_PTR pulDataLen) {
01390 
01391     SFTK_FIPSCHECK();
01392     return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen, 
01393                             pData,pulDataLen);
01394 }
01395 
01396 
01397 /* FC_DigestKey continues a multi-part message-digesting operation,
01398  * by digesting the value of a secret key as part of the data already digested.
01399  */
01400 CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
01401     SFTK_FIPSCHECK();
01402     rv = NSC_DigestKey(hSession,hKey);
01403     if (sftk_audit_enabled) {
01404        sftk_AuditDigestKey(hSession,hKey,rv);
01405     }
01406     return rv;
01407 }
01408 
01409 
01410 CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
01411                                                   CK_VOID_PTR pReserved)
01412 {
01413     return NSC_WaitForSlotEvent(flags, pSlot, pReserved);
01414 }