PageRenderTime 106ms CodeModel.GetById 13ms app.highlight 78ms RepoModel.GetById 1ms app.codeStats 1ms

/security/nss/lib/softoken/pkcs11.c

http://github.com/zpao/v8monkey
C | 4638 lines | 3412 code | 548 blank | 678 comment | 892 complexity | aeb4ec02f6831187d84fd2a682ca0239 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* ***** BEGIN LICENSE BLOCK *****
   2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
   3 *
   4 * The contents of this file are subject to the Mozilla Public License Version
   5 * 1.1 (the "License"); you may not use this file except in compliance with
   6 * the License. You may obtain a copy of the License at
   7 * http://www.mozilla.org/MPL/
   8 *
   9 * Software distributed under the License is distributed on an "AS IS" basis,
  10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11 * for the specific language governing rights and limitations under the
  12 * License.
  13 *
  14 * The Original Code is the Netscape security libraries.
  15 *
  16 * The Initial Developer of the Original Code is
  17 * Netscape Communications Corporation.
  18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
  19 * the Initial Developer. All Rights Reserved.
  20 *
  21 * Contributor(s):
  22 *   Dr Stephen Henson <stephen.henson@gemplus.com>
  23 *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
  24 *
  25 * Alternatively, the contents of this file may be used under the terms of
  26 * either the GNU General Public License Version 2 or later (the "GPL"), or
  27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28 * in which case the provisions of the GPL or the LGPL are applicable instead
  29 * of those above. If you wish to allow use of your version of this file only
  30 * under the terms of either the GPL or the LGPL, and not to allow others to
  31 * use your version of this file under the terms of the MPL, indicate your
  32 * decision by deleting the provisions above and replace them with the notice
  33 * and other provisions required by the GPL or the LGPL. If you do not delete
  34 * the provisions above, a recipient may use your version of this file under
  35 * the terms of any one of the MPL, the GPL or the LGPL.
  36 *
  37 * ***** END LICENSE BLOCK ***** */
  38/*
  39 * This file implements PKCS 11 on top of our existing security modules
  40 *
  41 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
  42 *   This implementation has two slots:
  43 *	slot 1 is our generic crypto support. It does not require login.
  44 *   It supports Public Key ops, and all they bulk ciphers and hashes. 
  45 *   It can also support Private Key ops for imported Private keys. It does 
  46 *   not have any token storage.
  47 *	slot 2 is our private key support. It requires a login before use. It
  48 *   can store Private Keys and Certs as token objects. Currently only private
  49 *   keys and their associated Certificates are saved on the token.
  50 *
  51 *   In this implementation, session objects are only visible to the session
  52 *   that created or generated them.
  53 */
  54#include "seccomon.h"
  55#include "secitem.h"
  56#include "pkcs11.h"
  57#include "pkcs11i.h"
  58#include "softoken.h"
  59#include "lowkeyi.h"
  60#include "blapi.h"
  61#include "secder.h"
  62#include "secport.h"
  63#include "secrng.h"
  64#include "prtypes.h"
  65#include "nspr.h"
  66#include "softkver.h"
  67#include "secoid.h"
  68#include "sftkdb.h"
  69#include "sftkpars.h"
  70#include "ec.h"
  71#include "secasn1.h"
  72
  73PRBool parentForkedAfterC_Initialize;
  74
  75#ifndef NO_FORK_CHECK
  76
  77PRBool sftkForkCheckDisabled;
  78
  79#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
  80PRBool forked = PR_FALSE;
  81#endif
  82
  83#if defined(CHECK_FORK_GETPID) || defined(CHECK_FORK_MIXED)
  84#include <unistd.h>
  85pid_t myPid;
  86#endif
  87
  88#ifdef CHECK_FORK_MIXED
  89#include <sys/systeminfo.h>
  90PRBool usePthread_atfork;
  91#endif
  92
  93#endif
  94
  95/*
  96 * ******************** Static data *******************************
  97 */
  98
  99/* The next three strings must be exactly 32 characters long */
 100static char *manufacturerID      = "Mozilla Foundation              ";
 101static char manufacturerID_space[33];
 102static char *libraryDescription  = "NSS Internal Crypto Services    ";
 103static char libraryDescription_space[33];
 104
 105/*
 106 * In FIPS mode, we disallow login attempts for 1 second after a login
 107 * failure so that there are at most 60 login attempts per minute.
 108 */
 109static PRIntervalTime loginWaitTime;
 110static PRUint32	      minSessionObjectHandle = 1U;
 111
 112#define __PASTE(x,y)    x##y
 113
 114/*
 115 * we renamed all our internal functions, get the correct
 116 * definitions for them...
 117 */ 
 118#undef CK_PKCS11_FUNCTION_INFO
 119#undef CK_NEED_ARG_LIST
 120
 121#define CK_EXTERN extern
 122#define CK_PKCS11_FUNCTION_INFO(func) \
 123		CK_RV __PASTE(NS,func)
 124#define CK_NEED_ARG_LIST	1
 125 
 126#include "pkcs11f.h"
 127 
 128 
 129 
 130/* build the crypto module table */
 131static const CK_FUNCTION_LIST sftk_funcList = {
 132    { 1, 10 },
 133 
 134#undef CK_PKCS11_FUNCTION_INFO
 135#undef CK_NEED_ARG_LIST
 136 
 137#define CK_PKCS11_FUNCTION_INFO(func) \
 138				__PASTE(NS,func),
 139#include "pkcs11f.h"
 140 
 141};
 142 
 143#undef CK_PKCS11_FUNCTION_INFO
 144#undef CK_NEED_ARG_LIST
 145 
 146 
 147#undef __PASTE
 148
 149/* List of DES Weak Keys */ 
 150typedef unsigned char desKey[8];
 151static const desKey  sftk_desWeakTable[] = {
 152#ifdef noParity
 153    /* weak */
 154    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 155    { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },
 156    { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 },
 157    { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
 158    /* semi-weak */
 159    { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },
 160    { 0xfe, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0xfe },
 161
 162    { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },
 163    { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
 164
 165    { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x0f, 0x00, 0x0f },
 166    { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
 167
 168    { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
 169    { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
 170
 171    { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },
 172    { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },
 173
 174    { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },
 175    { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
 176#else
 177    /* weak */
 178    { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
 179    { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e },
 180    { 0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1 },
 181    { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
 182
 183    /* semi-weak */
 184    { 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe },
 185    { 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01 },
 186
 187    { 0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1 },
 188    { 0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e },
 189
 190    { 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1 },
 191    { 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01 },
 192
 193    { 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
 194    { 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e },
 195
 196    { 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e },
 197    { 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 },
 198
 199    { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe }, 
 200    { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1 }
 201#endif
 202};
 203
 204    
 205static const int sftk_desWeakTableSize = sizeof(sftk_desWeakTable)/
 206						sizeof(sftk_desWeakTable[0]);
 207
 208/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
 209 * that byte with the proper parity bit set */
 210static const unsigned char parityTable[256] = {
 211/* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
 212/* E */   0x01,0x02,0x04,0x07,0x08,0x0b,0x0d,0x0e,
 213/* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
 214/* O */   0x10,0x13,0x15,0x16,0x19,0x1a,0x1c,0x1f,
 215/* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */
 216/* O */   0x20,0x23,0x25,0x26,0x29,0x2a,0x2c,0x2f,
 217/* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */
 218/* E */   0x31,0x32,0x34,0x37,0x38,0x3b,0x3d,0x3e,
 219/* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */
 220/* O */   0x40,0x43,0x45,0x46,0x49,0x4a,0x4c,0x4f,
 221/* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */
 222/* E */   0x51,0x52,0x54,0x57,0x58,0x5b,0x5d,0x5e,
 223/* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */
 224/* E */   0x61,0x62,0x64,0x67,0x68,0x6b,0x6d,0x6e,
 225/* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */
 226/* O */   0x70,0x73,0x75,0x76,0x79,0x7a,0x7c,0x7f,
 227/* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */
 228/* O */   0x80,0x83,0x85,0x86,0x89,0x8a,0x8c,0x8f,
 229/* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */
 230/* E */   0x91,0x92,0x94,0x97,0x98,0x9b,0x9d,0x9e,
 231/* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */
 232/* E */   0xa1,0xa2,0xa4,0xa7,0xa8,0xab,0xad,0xae,
 233/* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */
 234/* O */   0xb0,0xb3,0xb5,0xb6,0xb9,0xba,0xbc,0xbf,
 235/* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */
 236/* E */   0xc1,0xc2,0xc4,0xc7,0xc8,0xcb,0xcd,0xce,
 237/* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */
 238/* O */   0xd0,0xd3,0xd5,0xd6,0xd9,0xda,0xdc,0xdf,
 239/* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */
 240/* O */   0xe0,0xe3,0xe5,0xe6,0xe9,0xea,0xec,0xef,
 241/* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */
 242/* E */   0xf1,0xf2,0xf4,0xf7,0xf8,0xfb,0xfd,0xfe,
 243};
 244
 245/* Mechanisms */
 246struct mechanismList {
 247    CK_MECHANISM_TYPE	type;
 248    CK_MECHANISM_INFO	info;
 249    PRBool		privkey;
 250};
 251
 252/*
 253 * the following table includes a complete list of mechanism defined by
 254 * PKCS #11 version 2.01. Those Mechanisms not supported by this PKCS #11
 255 * module are ifdef'ed out.
 256 */
 257#define CKF_EN_DE		CKF_ENCRYPT      | CKF_DECRYPT
 258#define CKF_WR_UN		CKF_WRAP         | CKF_UNWRAP
 259#define CKF_SN_VR		CKF_SIGN         | CKF_VERIFY
 260#define CKF_SN_RE		CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER
 261
 262#define CKF_EN_DE_WR_UN 	CKF_EN_DE       | CKF_WR_UN
 263#define CKF_SN_VR_RE		CKF_SN_VR       | CKF_SN_RE
 264#define CKF_DUZ_IT_ALL		CKF_EN_DE_WR_UN | CKF_SN_VR_RE
 265
 266#define CKF_EC_PNU		CKF_EC_FP | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS
 267
 268#define CKF_EC_BPNU		CKF_EC_F_2M | CKF_EC_PNU
 269
 270#define CK_MAX 0xffffffff
 271
 272static const struct mechanismList mechanisms[] = {
 273
 274     /*
 275      * PKCS #11 Mechanism List.
 276      *
 277      * The first argument is the PKCS #11 Mechanism we support.
 278      * The second argument is Mechanism info structure. It includes:
 279      *    The minimum key size,
 280      *       in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
 281      *       in bytes for RC5, AES, Camellia, and CAST*
 282      *       ignored for DES*, IDEA and FORTEZZA based
 283      *    The maximum key size,
 284      *       in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
 285      *       in bytes for RC5, AES, Camellia, and CAST*
 286      *       ignored for DES*, IDEA and FORTEZZA based
 287      *     Flags
 288      *	      What operations are supported by this mechanism.
 289      *  The third argument is a bool which tells if this mechanism is 
 290      *    supported in the database token.
 291      *
 292      */
 293
 294     /* ------------------------- RSA Operations ---------------------------*/
 295     {CKM_RSA_PKCS_KEY_PAIR_GEN,{RSA_MIN_MODULUS_BITS,CK_MAX,
 296				 CKF_GENERATE_KEY_PAIR},PR_TRUE},
 297     {CKM_RSA_PKCS,             {RSA_MIN_MODULUS_BITS,CK_MAX,
 298				 CKF_DUZ_IT_ALL},       PR_TRUE},
 299     {CKM_RSA_PKCS_PSS,         {RSA_MIN_MODULUS_BITS,CK_MAX,
 300				 CKF_SN_VR},            PR_TRUE},
 301#ifdef SFTK_RSA9796_SUPPORTED
 302     {CKM_RSA_9796,		{RSA_MIN_MODULUS_BITS,CK_MAX,
 303				 CKF_DUZ_IT_ALL},       PR_TRUE},
 304#endif
 305     {CKM_RSA_X_509,		{RSA_MIN_MODULUS_BITS,CK_MAX,
 306				 CKF_DUZ_IT_ALL},       PR_TRUE},
 307     /* -------------- RSA Multipart Signing Operations -------------------- */
 308     {CKM_MD2_RSA_PKCS,		{RSA_MIN_MODULUS_BITS,CK_MAX,
 309				 CKF_SN_VR}, 	PR_TRUE},
 310     {CKM_MD5_RSA_PKCS,		{RSA_MIN_MODULUS_BITS,CK_MAX,
 311				 CKF_SN_VR}, 	PR_TRUE},
 312     {CKM_SHA1_RSA_PKCS,	{RSA_MIN_MODULUS_BITS,CK_MAX,
 313				 CKF_SN_VR}, 	PR_TRUE},
 314     {CKM_SHA224_RSA_PKCS,	{RSA_MIN_MODULUS_BITS,CK_MAX,
 315				 CKF_SN_VR}, 	PR_TRUE},
 316     {CKM_SHA256_RSA_PKCS,	{RSA_MIN_MODULUS_BITS,CK_MAX,
 317				 CKF_SN_VR}, 	PR_TRUE},
 318     {CKM_SHA384_RSA_PKCS,	{RSA_MIN_MODULUS_BITS,CK_MAX,
 319				 CKF_SN_VR}, 	PR_TRUE},
 320     {CKM_SHA512_RSA_PKCS,	{RSA_MIN_MODULUS_BITS,CK_MAX,
 321				 CKF_SN_VR}, 	PR_TRUE},
 322     /* ------------------------- DSA Operations --------------------------- */
 323     {CKM_DSA_KEY_PAIR_GEN,	{DSA_MIN_P_BITS, DSA_MAX_P_BITS,
 324				 CKF_GENERATE_KEY_PAIR}, PR_TRUE},
 325     {CKM_DSA,			{DSA_MIN_P_BITS, DSA_MAX_P_BITS, 
 326				 CKF_SN_VR},              PR_TRUE},
 327     {CKM_DSA_SHA1,		{DSA_MIN_P_BITS, DSA_MAX_P_BITS,
 328				 CKF_SN_VR},              PR_TRUE},
 329     /* -------------------- Diffie Hellman Operations --------------------- */
 330     /* no diffie hellman yet */
 331     {CKM_DH_PKCS_KEY_PAIR_GEN,	{DH_MIN_P_BITS, DH_MAX_P_BITS, 
 332				 CKF_GENERATE_KEY_PAIR}, PR_TRUE}, 
 333     {CKM_DH_PKCS_DERIVE,	{DH_MIN_P_BITS, DH_MAX_P_BITS,
 334				 CKF_DERIVE}, 	PR_TRUE}, 
 335#ifdef NSS_ENABLE_ECC
 336     /* -------------------- Elliptic Curve Operations --------------------- */
 337     {CKM_EC_KEY_PAIR_GEN,      {112, 571, CKF_GENERATE_KEY_PAIR|CKF_EC_BPNU}, PR_TRUE}, 
 338     {CKM_ECDH1_DERIVE,         {112, 571, CKF_DERIVE|CKF_EC_BPNU}, PR_TRUE}, 
 339     {CKM_ECDSA,                {112, 571, CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE}, 
 340     {CKM_ECDSA_SHA1,           {112, 571, CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE}, 
 341#endif /* NSS_ENABLE_ECC */
 342     /* ------------------------- RC2 Operations --------------------------- */
 343     {CKM_RC2_KEY_GEN,		{1, 128, CKF_GENERATE},		PR_TRUE},
 344     {CKM_RC2_ECB,		{1, 128, CKF_EN_DE_WR_UN},	PR_TRUE},
 345     {CKM_RC2_CBC,		{1, 128, CKF_EN_DE_WR_UN},	PR_TRUE},
 346     {CKM_RC2_MAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 347     {CKM_RC2_MAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 348     {CKM_RC2_CBC_PAD,		{1, 128, CKF_EN_DE_WR_UN},	PR_TRUE},
 349     /* ------------------------- RC4 Operations --------------------------- */
 350     {CKM_RC4_KEY_GEN,		{1, 256, CKF_GENERATE},		PR_FALSE},
 351     {CKM_RC4,			{1, 256, CKF_EN_DE_WR_UN},	PR_FALSE},
 352     /* ------------------------- DES Operations --------------------------- */
 353     {CKM_DES_KEY_GEN,		{ 8,  8, CKF_GENERATE},		PR_TRUE},
 354     {CKM_DES_ECB,		{ 8,  8, CKF_EN_DE_WR_UN},	PR_TRUE},
 355     {CKM_DES_CBC,		{ 8,  8, CKF_EN_DE_WR_UN},	PR_TRUE},
 356     {CKM_DES_MAC,		{ 8,  8, CKF_SN_VR},		PR_TRUE},
 357     {CKM_DES_MAC_GENERAL,	{ 8,  8, CKF_SN_VR},		PR_TRUE},
 358     {CKM_DES_CBC_PAD,		{ 8,  8, CKF_EN_DE_WR_UN},	PR_TRUE},
 359     {CKM_DES2_KEY_GEN,		{24, 24, CKF_GENERATE},		PR_TRUE},
 360     {CKM_DES3_KEY_GEN,		{24, 24, CKF_GENERATE},		PR_TRUE },
 361     {CKM_DES3_ECB,		{24, 24, CKF_EN_DE_WR_UN},	PR_TRUE },
 362     {CKM_DES3_CBC,		{24, 24, CKF_EN_DE_WR_UN},	PR_TRUE },
 363     {CKM_DES3_MAC,		{24, 24, CKF_SN_VR},		PR_TRUE },
 364     {CKM_DES3_MAC_GENERAL,	{24, 24, CKF_SN_VR},		PR_TRUE },
 365     {CKM_DES3_CBC_PAD,		{24, 24, CKF_EN_DE_WR_UN},	PR_TRUE },
 366     /* ------------------------- CDMF Operations --------------------------- */
 367     {CKM_CDMF_KEY_GEN,		{8,  8, CKF_GENERATE},		PR_TRUE},
 368     {CKM_CDMF_ECB,		{8,  8, CKF_EN_DE_WR_UN},	PR_TRUE},
 369     {CKM_CDMF_CBC,		{8,  8, CKF_EN_DE_WR_UN},	PR_TRUE},
 370     {CKM_CDMF_MAC,		{8,  8, CKF_SN_VR},		PR_TRUE},
 371     {CKM_CDMF_MAC_GENERAL,	{8,  8, CKF_SN_VR},		PR_TRUE},
 372     {CKM_CDMF_CBC_PAD,		{8,  8, CKF_EN_DE_WR_UN},	PR_TRUE},
 373     /* ------------------------- AES Operations --------------------------- */
 374     {CKM_AES_KEY_GEN,		{16, 32, CKF_GENERATE},		PR_TRUE},
 375     {CKM_AES_ECB,		{16, 32, CKF_EN_DE_WR_UN},	PR_TRUE},
 376     {CKM_AES_CBC,		{16, 32, CKF_EN_DE_WR_UN},	PR_TRUE},
 377     {CKM_AES_MAC,		{16, 32, CKF_SN_VR},		PR_TRUE},
 378     {CKM_AES_MAC_GENERAL,	{16, 32, CKF_SN_VR},		PR_TRUE},
 379     {CKM_AES_CBC_PAD,		{16, 32, CKF_EN_DE_WR_UN},	PR_TRUE},
 380     /* ------------------------- Camellia Operations --------------------- */
 381     {CKM_CAMELLIA_KEY_GEN,	{16, 32, CKF_GENERATE},         PR_TRUE},
 382     {CKM_CAMELLIA_ECB,  	{16, 32, CKF_EN_DE_WR_UN},      PR_TRUE},
 383     {CKM_CAMELLIA_CBC, 	{16, 32, CKF_EN_DE_WR_UN},      PR_TRUE},
 384     {CKM_CAMELLIA_MAC, 	{16, 32, CKF_SN_VR},            PR_TRUE},
 385     {CKM_CAMELLIA_MAC_GENERAL,	{16, 32, CKF_SN_VR},            PR_TRUE},
 386     {CKM_CAMELLIA_CBC_PAD,	{16, 32, CKF_EN_DE_WR_UN},      PR_TRUE},
 387     /* ------------------------- SEED Operations --------------------------- */
 388     {CKM_SEED_KEY_GEN,		{16, 16, CKF_GENERATE},		PR_TRUE},
 389     {CKM_SEED_ECB,		{16, 16, CKF_EN_DE_WR_UN},	PR_TRUE},
 390     {CKM_SEED_CBC,		{16, 16, CKF_EN_DE_WR_UN},	PR_TRUE},
 391     {CKM_SEED_MAC,		{16, 16, CKF_SN_VR},		PR_TRUE},
 392     {CKM_SEED_MAC_GENERAL,	{16, 16, CKF_SN_VR},		PR_TRUE},
 393     {CKM_SEED_CBC_PAD,		{16, 16, CKF_EN_DE_WR_UN},	PR_TRUE},
 394     /* ------------------------- Hashing Operations ----------------------- */
 395     {CKM_MD2,			{0,   0, CKF_DIGEST},		PR_FALSE},
 396     {CKM_MD2_HMAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 397     {CKM_MD2_HMAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 398     {CKM_MD5,			{0,   0, CKF_DIGEST},		PR_FALSE},
 399     {CKM_MD5_HMAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 400     {CKM_MD5_HMAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 401     {CKM_SHA_1,		{0,   0, CKF_DIGEST},		PR_FALSE},
 402     {CKM_SHA_1_HMAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 403     {CKM_SHA_1_HMAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 404     {CKM_SHA224,		{0,   0, CKF_DIGEST},		PR_FALSE},
 405     {CKM_SHA224_HMAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 406     {CKM_SHA224_HMAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 407     {CKM_SHA256,		{0,   0, CKF_DIGEST},		PR_FALSE},
 408     {CKM_SHA256_HMAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 409     {CKM_SHA256_HMAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 410     {CKM_SHA384,		{0,   0, CKF_DIGEST},		PR_FALSE},
 411     {CKM_SHA384_HMAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 412     {CKM_SHA384_HMAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 413     {CKM_SHA512,		{0,   0, CKF_DIGEST},		PR_FALSE},
 414     {CKM_SHA512_HMAC,		{1, 128, CKF_SN_VR},		PR_TRUE},
 415     {CKM_SHA512_HMAC_GENERAL,	{1, 128, CKF_SN_VR},		PR_TRUE},
 416     {CKM_TLS_PRF_GENERAL,	{0, 512, CKF_SN_VR},		PR_FALSE},
 417     /* ------------------------- HKDF Operations -------------------------- */
 418     {CKM_NSS_HKDF_SHA1,        {1, 128, CKF_DERIVE},           PR_TRUE},
 419     {CKM_NSS_HKDF_SHA256,      {1, 128, CKF_DERIVE},           PR_TRUE},
 420     {CKM_NSS_HKDF_SHA384,      {1, 128, CKF_DERIVE},           PR_TRUE},
 421     {CKM_NSS_HKDF_SHA512,      {1, 128, CKF_DERIVE},           PR_TRUE},
 422     /* ------------------------- CAST Operations --------------------------- */
 423#ifdef NSS_SOFTOKEN_DOES_CAST
 424     /* Cast operations are not supported ( yet? ) */
 425     {CKM_CAST_KEY_GEN,		{1,  8, CKF_GENERATE},		PR_TRUE}, 
 426     {CKM_CAST_ECB,		{1,  8, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 427     {CKM_CAST_CBC,		{1,  8, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 428     {CKM_CAST_MAC,		{1,  8, CKF_SN_VR},		PR_TRUE}, 
 429     {CKM_CAST_MAC_GENERAL,	{1,  8, CKF_SN_VR},		PR_TRUE}, 
 430     {CKM_CAST_CBC_PAD,		{1,  8, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 431     {CKM_CAST3_KEY_GEN,	{1, 16, CKF_GENERATE},		PR_TRUE}, 
 432     {CKM_CAST3_ECB,		{1, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 433     {CKM_CAST3_CBC,		{1, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 434     {CKM_CAST3_MAC,		{1, 16, CKF_SN_VR},		PR_TRUE}, 
 435     {CKM_CAST3_MAC_GENERAL,	{1, 16, CKF_SN_VR},		PR_TRUE}, 
 436     {CKM_CAST3_CBC_PAD,	{1, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 437     {CKM_CAST5_KEY_GEN,	{1, 16, CKF_GENERATE},		PR_TRUE}, 
 438     {CKM_CAST5_ECB,		{1, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 439     {CKM_CAST5_CBC,		{1, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 440     {CKM_CAST5_MAC,		{1, 16, CKF_SN_VR},		PR_TRUE}, 
 441     {CKM_CAST5_MAC_GENERAL,	{1, 16, CKF_SN_VR},		PR_TRUE}, 
 442     {CKM_CAST5_CBC_PAD,	{1, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 443#endif
 444#if NSS_SOFTOKEN_DOES_RC5
 445     /* ------------------------- RC5 Operations --------------------------- */
 446     {CKM_RC5_KEY_GEN,		{1, 32, CKF_GENERATE},          PR_TRUE},
 447     {CKM_RC5_ECB,		{1, 32, CKF_EN_DE_WR_UN},	PR_TRUE},
 448     {CKM_RC5_CBC,		{1, 32, CKF_EN_DE_WR_UN},	PR_TRUE},
 449     {CKM_RC5_MAC,		{1, 32, CKF_SN_VR},  		PR_TRUE},
 450     {CKM_RC5_MAC_GENERAL,	{1, 32, CKF_SN_VR},  		PR_TRUE},
 451     {CKM_RC5_CBC_PAD,		{1, 32, CKF_EN_DE_WR_UN}, 	PR_TRUE},
 452#endif
 453#ifdef NSS_SOFTOKEN_DOES_IDEA
 454     /* ------------------------- IDEA Operations -------------------------- */
 455     {CKM_IDEA_KEY_GEN,		{16, 16, CKF_GENERATE}, 	PR_TRUE}, 
 456     {CKM_IDEA_ECB,		{16, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 457     {CKM_IDEA_CBC,		{16, 16, CKF_EN_DE_WR_UN},	PR_TRUE}, 
 458     {CKM_IDEA_MAC,		{16, 16, CKF_SN_VR},		PR_TRUE}, 
 459     {CKM_IDEA_MAC_GENERAL,	{16, 16, CKF_SN_VR},		PR_TRUE}, 
 460     {CKM_IDEA_CBC_PAD,		{16, 16, CKF_EN_DE_WR_UN}, 	PR_TRUE}, 
 461#endif
 462     /* --------------------- Secret Key Operations ------------------------ */
 463     {CKM_GENERIC_SECRET_KEY_GEN,	{1, 32, CKF_GENERATE}, PR_TRUE}, 
 464     {CKM_CONCATENATE_BASE_AND_KEY,	{1, 32, CKF_GENERATE}, PR_FALSE}, 
 465     {CKM_CONCATENATE_BASE_AND_DATA,	{1, 32, CKF_GENERATE}, PR_FALSE}, 
 466     {CKM_CONCATENATE_DATA_AND_BASE,	{1, 32, CKF_GENERATE}, PR_FALSE}, 
 467     {CKM_XOR_BASE_AND_DATA,		{1, 32, CKF_GENERATE}, PR_FALSE}, 
 468     {CKM_EXTRACT_KEY_FROM_KEY,		{1, 32, CKF_DERIVE},   PR_FALSE}, 
 469     /* ---------------------- SSL Key Derivations ------------------------- */
 470     {CKM_SSL3_PRE_MASTER_KEY_GEN,	{48, 48, CKF_GENERATE}, PR_FALSE}, 
 471     {CKM_SSL3_MASTER_KEY_DERIVE,	{48, 48, CKF_DERIVE},   PR_FALSE}, 
 472     {CKM_SSL3_MASTER_KEY_DERIVE_DH,	{8, 128, CKF_DERIVE},   PR_FALSE}, 
 473     {CKM_SSL3_KEY_AND_MAC_DERIVE,	{48, 48, CKF_DERIVE},   PR_FALSE}, 
 474     {CKM_SSL3_MD5_MAC,			{ 0, 16, CKF_DERIVE},   PR_FALSE}, 
 475     {CKM_SSL3_SHA1_MAC,		{ 0, 20, CKF_DERIVE},   PR_FALSE}, 
 476     {CKM_MD5_KEY_DERIVATION,		{ 0, 16, CKF_DERIVE},   PR_FALSE}, 
 477     {CKM_MD2_KEY_DERIVATION,		{ 0, 16, CKF_DERIVE},   PR_FALSE}, 
 478     {CKM_SHA1_KEY_DERIVATION,		{ 0, 20, CKF_DERIVE},   PR_FALSE}, 
 479     {CKM_TLS_MASTER_KEY_DERIVE,	{48, 48, CKF_DERIVE},   PR_FALSE}, 
 480     {CKM_TLS_MASTER_KEY_DERIVE_DH,	{8, 128, CKF_DERIVE},   PR_FALSE}, 
 481     {CKM_TLS_KEY_AND_MAC_DERIVE,	{48, 48, CKF_DERIVE},   PR_FALSE}, 
 482     /* ---------------------- PBE Key Derivations  ------------------------ */
 483     {CKM_PBE_MD2_DES_CBC,		{8, 8, CKF_DERIVE},   PR_TRUE},
 484     {CKM_PBE_MD5_DES_CBC,		{8, 8, CKF_DERIVE},   PR_TRUE},
 485     /* ------------------ NETSCAPE PBE Key Derivations  ------------------- */
 486     {CKM_NETSCAPE_PBE_SHA1_DES_CBC,	     { 8, 8, CKF_GENERATE}, PR_TRUE},
 487     {CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
 488     {CKM_PBE_SHA1_DES3_EDE_CBC,	     {24,24, CKF_GENERATE}, PR_TRUE},
 489     {CKM_PBE_SHA1_DES2_EDE_CBC,	     {24,24, CKF_GENERATE}, PR_TRUE},
 490     {CKM_PBE_SHA1_RC2_40_CBC,		     {40,40, CKF_GENERATE}, PR_TRUE},
 491     {CKM_PBE_SHA1_RC2_128_CBC,		     {128,128, CKF_GENERATE}, PR_TRUE},
 492     {CKM_PBE_SHA1_RC4_40,		     {40,40, CKF_GENERATE}, PR_TRUE},
 493     {CKM_PBE_SHA1_RC4_128,		     {128,128, CKF_GENERATE}, PR_TRUE},
 494     {CKM_PBA_SHA1_WITH_SHA1_HMAC,	     {20,20, CKF_GENERATE}, PR_TRUE},
 495     {CKM_PKCS5_PBKD2,   		     {1,256, CKF_GENERATE}, PR_TRUE},
 496     {CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN,    {20,20, CKF_GENERATE}, PR_TRUE},
 497     {CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN,     {16,16, CKF_GENERATE}, PR_TRUE},
 498     {CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN,     {16,16, CKF_GENERATE}, PR_TRUE},
 499     /* ------------------ AES Key Wrap (also encrypt)  ------------------- */
 500     {CKM_NETSCAPE_AES_KEY_WRAP,	{16, 32, CKF_EN_DE_WR_UN},  PR_TRUE},
 501     {CKM_NETSCAPE_AES_KEY_WRAP_PAD,	{16, 32, CKF_EN_DE_WR_UN},  PR_TRUE},
 502     /* --------------------------- J-PAKE -------------------------------- */
 503     {CKM_NSS_JPAKE_ROUND1_SHA1,        {0, 0, CKF_GENERATE}, PR_TRUE},
 504     {CKM_NSS_JPAKE_ROUND1_SHA256,      {0, 0, CKF_GENERATE}, PR_TRUE},
 505     {CKM_NSS_JPAKE_ROUND1_SHA384,      {0, 0, CKF_GENERATE}, PR_TRUE},
 506     {CKM_NSS_JPAKE_ROUND1_SHA512,      {0, 0, CKF_GENERATE}, PR_TRUE},
 507     {CKM_NSS_JPAKE_ROUND2_SHA1,        {0, 0, CKF_DERIVE}, PR_TRUE},
 508     {CKM_NSS_JPAKE_ROUND2_SHA256,      {0, 0, CKF_DERIVE}, PR_TRUE},
 509     {CKM_NSS_JPAKE_ROUND2_SHA384,      {0, 0, CKF_DERIVE}, PR_TRUE},
 510     {CKM_NSS_JPAKE_ROUND2_SHA512,      {0, 0, CKF_DERIVE}, PR_TRUE},
 511     {CKM_NSS_JPAKE_FINAL_SHA1,         {0, 0, CKF_DERIVE}, PR_TRUE},
 512     {CKM_NSS_JPAKE_FINAL_SHA256,       {0, 0, CKF_DERIVE}, PR_TRUE},
 513     {CKM_NSS_JPAKE_FINAL_SHA384,       {0, 0, CKF_DERIVE}, PR_TRUE},
 514     {CKM_NSS_JPAKE_FINAL_SHA512,       {0, 0, CKF_DERIVE}, PR_TRUE}
 515};
 516static const CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
 517
 518/* sigh global so fipstokn can read it */
 519PRBool nsc_init = PR_FALSE;
 520
 521#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
 522
 523#include <pthread.h>
 524
 525static void ForkedChild(void)
 526{
 527    if (nsc_init || nsf_init) {
 528        forked = PR_TRUE;
 529    }
 530}
 531
 532#endif
 533
 534static char *
 535sftk_setStringName(const char *inString, char *buffer, int buffer_length, 		PRBool nullTerminate)
 536{
 537    int full_length, string_length;
 538
 539    full_length = nullTerminate ? buffer_length -1 : buffer_length;
 540    string_length = PORT_Strlen(inString);
 541    /* 
 542     *  shorten the string, respecting utf8 encoding
 543     *  to do so, we work backward from the end 
 544     *  bytes looking from the end are either:
 545     *    - ascii [0x00,0x7f]
 546     *    - the [2-n]th byte of a multibyte sequence 
 547     *        [0x3F,0xBF], i.e, most significant 2 bits are '10'
 548     *    - the first byte of a multibyte sequence [0xC0,0xFD],
 549     *        i.e, most significant 2 bits are '11'
 550     *
 551     *    When the string is too long, we lop off any trailing '10' bytes,
 552     *  if any. When these are all eliminated we lop off
 553     *  one additional byte. Thus if we lopped any '10'
 554     *  we'll be lopping a '11' byte (the first byte of the multibyte sequence),
 555     *  otherwise we're lopping off an ascii character.
 556     *
 557     *    To test for '10' bytes, we first AND it with 
 558     *  11000000 (0xc0) so that we get 10000000 (0x80) if and only if
 559     *  the byte starts with 10. We test for equality.
 560     */
 561    while ( string_length > full_length ) {
 562	/* need to shorten */
 563	while ( string_length > 0 && 
 564	      ((inString[string_length-1]&(char)0xc0) == (char)0x80)) {
 565	    /* lop off '10' byte */
 566	    string_length--;
 567	}
 568	/* 
 569	 * test string_length in case bad data is received
 570	 * and string consisted of all '10' bytes,
 571	 * avoiding any infinite loop
 572         */
 573	if ( string_length ) {
 574	    /* remove either '11' byte or an asci byte */
 575	    string_length--;
 576	}
 577    }
 578    PORT_Memset(buffer,' ',full_length);
 579    if (nullTerminate) {
 580	buffer[full_length] = 0;
 581    }
 582    PORT_Memcpy(buffer,inString,string_length);
 583    return buffer;
 584}
 585/*
 586 * Configuration utils
 587 */
 588static CK_RV
 589sftk_configure(const char *man, const char *libdes)
 590{
 591
 592    /* make sure the internationalization was done correctly... */
 593    if (man) {
 594	manufacturerID = sftk_setStringName(man,manufacturerID_space,
 595					sizeof(manufacturerID_space), PR_TRUE);
 596    }
 597    if (libdes) {
 598	libraryDescription = sftk_setStringName(libdes,
 599		libraryDescription_space, sizeof(libraryDescription_space), 
 600		PR_TRUE);
 601    }
 602
 603    return CKR_OK;
 604}
 605
 606/*
 607 * ******************** Password Utilities *******************************
 608 */
 609
 610/*
 611 * see if the key DB password is enabled
 612 */
 613static PRBool
 614sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb)
 615{
 616    PRBool pwenabled;
 617   
 618    pwenabled = PR_FALSE;
 619    if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
 620	PRBool tokenRemoved = PR_FALSE;
 621    	SECStatus rv = sftkdb_CheckPassword(keydb, "", &tokenRemoved);
 622	if (tokenRemoved) {
 623	    sftk_CloseAllSessions(slot, PR_FALSE);
 624	}
 625	return (rv  == SECSuccess);
 626    }
 627
 628    return pwenabled;
 629}
 630
 631/*
 632 * ******************** Object Creation Utilities ***************************
 633 */
 634
 635
 636/* Make sure a given attribute exists. If it doesn't, initialize it to
 637 * value and len
 638 */
 639CK_RV
 640sftk_defaultAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,void *value,
 641							unsigned int len)
 642{
 643    if ( !sftk_hasAttribute(object, type)) {
 644	return sftk_AddAttributeType(object,type,value,len);
 645    }
 646    return CKR_OK;
 647}
 648
 649/*
 650 * check the consistancy and initialize a Data Object 
 651 */
 652static CK_RV
 653sftk_handleDataObject(SFTKSession *session,SFTKObject *object)
 654{
 655    CK_RV crv;
 656
 657    /* first reject private and token data objects */
 658    if (sftk_isTrue(object,CKA_PRIVATE) || sftk_isTrue(object,CKA_TOKEN)) {
 659	return CKR_ATTRIBUTE_VALUE_INVALID;
 660    }
 661
 662    /* now just verify the required date fields */
 663    crv = sftk_defaultAttribute(object,CKA_APPLICATION,NULL,0);
 664    if (crv != CKR_OK) return crv;
 665    crv = sftk_defaultAttribute(object,CKA_VALUE,NULL,0);
 666    if (crv != CKR_OK) return crv;
 667
 668    return CKR_OK;
 669}
 670
 671/*
 672 * check the consistancy and initialize a Certificate Object 
 673 */
 674static CK_RV
 675sftk_handleCertObject(SFTKSession *session,SFTKObject *object)
 676{
 677    CK_CERTIFICATE_TYPE type;
 678    SFTKAttribute *attribute;
 679    CK_RV crv;
 680
 681    /* certificates must have a type */
 682    if ( !sftk_hasAttribute(object,CKA_CERTIFICATE_TYPE) ) {
 683	return CKR_TEMPLATE_INCOMPLETE;
 684    }
 685
 686    /* we can't store any certs private */
 687    if (sftk_isTrue(object,CKA_PRIVATE)) {
 688	return CKR_ATTRIBUTE_VALUE_INVALID;
 689    }
 690	
 691    /* We only support X.509 Certs for now */
 692    attribute = sftk_FindAttribute(object,CKA_CERTIFICATE_TYPE);
 693    if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
 694    type = *(CK_CERTIFICATE_TYPE *)attribute->attrib.pValue;
 695    sftk_FreeAttribute(attribute);
 696
 697    if (type != CKC_X_509) {
 698	return CKR_ATTRIBUTE_VALUE_INVALID;
 699    }
 700
 701    /* X.509 Certificate */
 702
 703    /* make sure we have a cert */
 704    if ( !sftk_hasAttribute(object,CKA_VALUE) ) {
 705	return CKR_TEMPLATE_INCOMPLETE;
 706    }
 707
 708    /* in PKCS #11, Subject is a required field */
 709    if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) {
 710	return CKR_TEMPLATE_INCOMPLETE;
 711    }
 712
 713    /* in PKCS #11, Issuer is a required field */
 714    if ( !sftk_hasAttribute(object,CKA_ISSUER) ) {
 715	return CKR_TEMPLATE_INCOMPLETE;
 716    }
 717
 718    /* in PKCS #11, Serial is a required field */
 719    if ( !sftk_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
 720	return CKR_TEMPLATE_INCOMPLETE;
 721    }
 722
 723    /* add it to the object */
 724    object->objectInfo = NULL;
 725    object->infoFree = (SFTKFree) NULL;
 726    
 727    /* now just verify the required date fields */
 728    crv = sftk_defaultAttribute(object, CKA_ID, NULL, 0);
 729    if (crv != CKR_OK) { return crv; }
 730
 731    if (sftk_isTrue(object,CKA_TOKEN)) {
 732	SFTKSlot *slot = session->slot;
 733	SFTKDBHandle *certHandle = sftk_getCertDB(slot);
 734
 735	if (certHandle == NULL) {
 736	    return CKR_TOKEN_WRITE_PROTECTED;
 737	}
 738
 739	crv = sftkdb_write(certHandle, object, &object->handle);
 740	sftk_freeDB(certHandle);
 741	return crv;
 742    }
 743
 744    return CKR_OK;
 745}
 746	
 747/*
 748 * check the consistancy and initialize a Trust Object 
 749 */
 750static CK_RV
 751sftk_handleTrustObject(SFTKSession *session,SFTKObject *object)
 752{
 753    /* we can't store any certs private */
 754    if (sftk_isTrue(object,CKA_PRIVATE)) {
 755	return CKR_ATTRIBUTE_VALUE_INVALID;
 756    }
 757
 758    /* certificates must have a type */
 759    if ( !sftk_hasAttribute(object,CKA_ISSUER) ) {
 760	return CKR_TEMPLATE_INCOMPLETE;
 761    }
 762    if ( !sftk_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
 763	return CKR_TEMPLATE_INCOMPLETE;
 764    }
 765    if ( !sftk_hasAttribute(object,CKA_CERT_SHA1_HASH) ) {
 766	return CKR_TEMPLATE_INCOMPLETE;
 767    }
 768    if ( !sftk_hasAttribute(object,CKA_CERT_MD5_HASH) ) {
 769	return CKR_TEMPLATE_INCOMPLETE;
 770    }
 771
 772    if (sftk_isTrue(object,CKA_TOKEN)) {
 773	SFTKSlot *slot = session->slot;
 774	SFTKDBHandle *certHandle = sftk_getCertDB(slot);
 775	CK_RV crv;
 776
 777	if (certHandle == NULL) {
 778	    return CKR_TOKEN_WRITE_PROTECTED;
 779	}
 780
 781	crv = sftkdb_write(certHandle, object, &object->handle);
 782	sftk_freeDB(certHandle);
 783	return crv;
 784    }
 785
 786    return CKR_OK;
 787}
 788
 789/*
 790 * check the consistancy and initialize a Trust Object 
 791 */
 792static CK_RV
 793sftk_handleSMimeObject(SFTKSession *session,SFTKObject *object)
 794{
 795
 796    /* we can't store any certs private */
 797    if (sftk_isTrue(object,CKA_PRIVATE)) {
 798	return CKR_ATTRIBUTE_VALUE_INVALID;
 799    }
 800
 801    /* certificates must have a type */
 802    if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) {
 803	return CKR_TEMPLATE_INCOMPLETE;
 804    }
 805    if ( !sftk_hasAttribute(object,CKA_NETSCAPE_EMAIL) ) {
 806	return CKR_TEMPLATE_INCOMPLETE;
 807    }
 808
 809    if (sftk_isTrue(object,CKA_TOKEN)) {
 810	SFTKSlot *slot = session->slot;
 811	SFTKDBHandle *certHandle;
 812	CK_RV crv;
 813
 814	PORT_Assert(slot);
 815	if (slot == NULL) {
 816	    return CKR_SESSION_HANDLE_INVALID;
 817	}
 818
 819	certHandle = sftk_getCertDB(slot);
 820	if (certHandle == NULL) {
 821	    return CKR_TOKEN_WRITE_PROTECTED;
 822	}
 823
 824	crv = sftkdb_write(certHandle, object, &object->handle);
 825	sftk_freeDB(certHandle);
 826	return crv;
 827    }
 828
 829    return CKR_OK;
 830}
 831
 832/*
 833 * check the consistancy and initialize a Trust Object 
 834 */
 835static CK_RV
 836sftk_handleCrlObject(SFTKSession *session,SFTKObject *object)
 837{
 838
 839    /* we can't store any certs private */
 840    if (sftk_isTrue(object,CKA_PRIVATE)) {
 841	return CKR_ATTRIBUTE_VALUE_INVALID;
 842    }
 843
 844    /* certificates must have a type */
 845    if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) {
 846	return CKR_TEMPLATE_INCOMPLETE;
 847    }
 848    if ( !sftk_hasAttribute(object,CKA_VALUE) ) {
 849	return CKR_TEMPLATE_INCOMPLETE;
 850    }
 851
 852    if (sftk_isTrue(object,CKA_TOKEN)) {
 853	SFTKSlot *slot = session->slot;
 854	SFTKDBHandle *certHandle = sftk_getCertDB(slot);
 855	CK_RV crv;
 856
 857	if (certHandle == NULL) {
 858	    return CKR_TOKEN_WRITE_PROTECTED;
 859	}
 860
 861	crv = sftkdb_write(certHandle, object, &object->handle);
 862	sftk_freeDB(certHandle);
 863	return crv;
 864    }
 865
 866    return CKR_OK;
 867}
 868
 869/*
 870 * check the consistancy and initialize a Public Key Object 
 871 */
 872static CK_RV
 873sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
 874							 CK_KEY_TYPE key_type)
 875{
 876    CK_BBOOL encrypt = CK_TRUE;
 877    CK_BBOOL recover = CK_TRUE;
 878    CK_BBOOL wrap = CK_TRUE;
 879    CK_BBOOL derive = CK_FALSE;
 880    CK_BBOOL verify = CK_TRUE;
 881    CK_RV crv;
 882
 883    switch (key_type) {
 884    case CKK_RSA:
 885	crv = sftk_ConstrainAttribute(object, CKA_MODULUS,
 886						 RSA_MIN_MODULUS_BITS, 0, 0);
 887	if (crv != CKR_OK) {
 888	    return crv;
 889	}
 890	crv = sftk_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT, 2, 0, 0);
 891	if (crv != CKR_OK) {
 892	    return crv;
 893	}
 894	break;
 895    case CKK_DSA:
 896	crv = sftk_ConstrainAttribute(object, CKA_SUBPRIME, 
 897						DSA_Q_BITS, DSA_Q_BITS, 0);
 898	if (crv != CKR_OK) {
 899	    return crv;
 900	}
 901	crv = sftk_ConstrainAttribute(object, CKA_PRIME, 
 902					DSA_MIN_P_BITS, DSA_MAX_P_BITS, 64);
 903	if (crv != CKR_OK) {
 904	    return crv;
 905	}
 906	crv = sftk_ConstrainAttribute(object, CKA_BASE, 1, DSA_MAX_P_BITS, 0);
 907	if (crv != CKR_OK) {
 908	    return crv;
 909	}
 910	crv = sftk_ConstrainAttribute(object, CKA_VALUE, 1, DSA_MAX_P_BITS, 0);
 911	if (crv != CKR_OK) {
 912	    return crv;
 913	}
 914	encrypt = CK_FALSE;
 915	recover = CK_FALSE;
 916	wrap = CK_FALSE;
 917	break;
 918    case CKK_DH:
 919	crv = sftk_ConstrainAttribute(object, CKA_PRIME, 
 920					DH_MIN_P_BITS, DH_MAX_P_BITS, 0);
 921	if (crv != CKR_OK) {
 922	    return crv;
 923	}
 924	crv = sftk_ConstrainAttribute(object, CKA_BASE, 1, DH_MAX_P_BITS, 0);
 925	if (crv != CKR_OK) {
 926	    return crv;
 927	}
 928	crv = sftk_ConstrainAttribute(object, CKA_VALUE, 1, DH_MAX_P_BITS, 0);
 929	if (crv != CKR_OK) {
 930	    return crv;
 931	}
 932	verify = CK_FALSE;
 933	derive = CK_TRUE;
 934	encrypt = CK_FALSE;
 935	recover = CK_FALSE;
 936	wrap = CK_FALSE;
 937	break;
 938#ifdef NSS_ENABLE_ECC
 939    case CKK_EC:
 940	if ( !sftk_hasAttribute(object, CKA_EC_PARAMS)) {
 941	    return CKR_TEMPLATE_INCOMPLETE;
 942	}
 943	if ( !sftk_hasAttribute(object, CKA_EC_POINT)) {
 944	    return CKR_TEMPLATE_INCOMPLETE;
 945	}
 946	derive = CK_TRUE;    /* for ECDH */
 947	verify = CK_TRUE;    /* for ECDSA */
 948	encrypt = CK_FALSE;
 949	recover = CK_FALSE;
 950	wrap = CK_FALSE;
 951	break;
 952#endif /* NSS_ENABLE_ECC */
 953    default:
 954	return CKR_ATTRIBUTE_VALUE_INVALID;
 955    }
 956
 957    /* make sure the required fields exist */
 958    crv = sftk_defaultAttribute(object,CKA_SUBJECT,NULL,0);
 959    if (crv != CKR_OK)  return crv; 
 960    crv = sftk_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL));
 961    if (crv != CKR_OK)  return crv; 
 962    crv = sftk_defaultAttribute(object,CKA_VERIFY,&verify,sizeof(CK_BBOOL));
 963    if (crv != CKR_OK)  return crv; 
 964    crv = sftk_defaultAttribute(object,CKA_VERIFY_RECOVER,
 965						&recover,sizeof(CK_BBOOL));
 966    if (crv != CKR_OK)  return crv; 
 967    crv = sftk_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL));
 968    if (crv != CKR_OK)  return crv; 
 969    crv = sftk_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));
 970    if (crv != CKR_OK)  return crv; 
 971
 972    object->objectInfo = sftk_GetPubKey(object,key_type, &crv);
 973    if (object->objectInfo == NULL) {
 974	return crv;
 975    }
 976    object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey;
 977
 978    if (sftk_isTrue(object,CKA_TOKEN)) {
 979	SFTKSlot *slot = session->slot;
 980	SFTKDBHandle *certHandle = sftk_getCertDB(slot);
 981
 982	if (certHandle == NULL) {
 983	    return CKR_TOKEN_WRITE_PROTECTED;
 984	}
 985
 986	crv = sftkdb_write(certHandle, object, &object->handle);
 987	sftk_freeDB(certHandle);
 988	return crv;
 989    }
 990
 991    return CKR_OK;
 992}
 993
 994static NSSLOWKEYPrivateKey * 
 995sftk_mkPrivKey(SFTKObject *object,CK_KEY_TYPE key, CK_RV *rvp);
 996
 997static SECStatus
 998sftk_fillRSAPrivateKey(SFTKObject *object);
 999
1000/*
1001 * check the consistancy and initialize a Private Key Object 
1002 */
1003static CK_RV
1004sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE key_type)
1005{
1006    CK_BBOOL cktrue = CK_TRUE;
1007    CK_BBOOL encrypt = CK_TRUE;
1008    CK_BBOOL sign = CK_FALSE;
1009    CK_BBOOL recover = CK_TRUE;
1010    CK_BBOOL wrap = CK_TRUE;
1011    CK_BBOOL derive = CK_TRUE;
1012    CK_BBOOL ckfalse = CK_FALSE;
1013    PRBool createObjectInfo = PR_TRUE;
1014    int missing_rsa_mod_component = 0;
1015    int missing_rsa_exp_component = 0;
1016    int missing_rsa_crt_component = 0;
1017    
1018    SECItem mod;
1019    CK_RV crv;
1020
1021    switch (key_type) {
1022    case CKK_RSA:
1023	if ( !sftk_hasAttribute(object, CKA_MODULUS)) {
1024	    missing_rsa_mod_component++;
1025	}
1026	if ( !sftk_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
1027	    missing_rsa_exp_component++;
1028	}
1029	if ( !sftk_hasAttribute(object, CKA_PRIVATE_EXPONENT)) {
1030	    missing_rsa_exp_component++;
1031	}
1032	if ( !sftk_hasAttribute(object, CKA_PRIME_1)) {
1033	    missing_rsa_mod_component++;
1034	}
1035	if ( !sftk_hasAttribute(object, CKA_PRIME_2)) {
1036	    missing_rsa_mod_component++;
1037	}
1038	if ( !sftk_hasAttribute(object, CKA_EXPONENT_1)) {
1039	    missing_rsa_crt_component++;
1040	}
1041	if ( !sftk_hasAttribute(object, CKA_EXPONENT_2)) {
1042	    missing_rsa_crt_component++;
1043	}
1044	if ( !sftk_hasAttribute(object, CKA_COEFFICIENT)) {
1045	    missing_rsa_crt_component++;
1046	}
1047	if (missing_rsa_mod_component || missing_rsa_exp_component || 
1048					 missing_rsa_crt_component) {
1049	    /* we are missing a component, see if we have enough to rebuild
1050	     * the rest */
1051	    int have_exp = 2- missing_rsa_exp_component;
1052	    int have_component = 5- 
1053		(missing_rsa_exp_component+missing_rsa_mod_component);
1054	    SECStatus rv;
1055
1056	    if ((have_exp == 0) || (have_component < 3)) {
1057		/* nope, not enough to reconstruct the private key */
1058		return CKR_TEMPLATE_INCOMPLETE;
1059	    }
1060	    /*fill in the missing parameters */
1061	    rv = sftk_fillRSAPrivateKey(object);
1062	    if (rv != SECSuccess) {
1063		return CKR_TEMPLATE_INCOMPLETE;
1064	    }
1065	}
1066		
1067	/* make sure Netscape DB attribute is set correctly */
1068	crv = sftk_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS);
1069	if (crv != CKR_OK) return crv;
1070	crv = sftk_forceAttribute(object, CKA_NETSCAPE_DB, 
1071						sftk_item_expand(&mod));
1072	if (mod.data) PORT_Free(mod.data);
1073	if (crv != CKR_OK) return crv;
1074
1075	sign = CK_TRUE;
1076	derive = CK_FALSE;
1077	break;
1078    case CKK_DSA:
1079	if ( !sftk_hasAttribute(object, CKA_SUBPRIME)) {
1080	    return CKR_TEMPLATE_INCOMPLETE;
1081	}
1082	sign = CK_TRUE;
1083	derive = CK_FALSE;
1084	/* fall through */
1085    case CKK_DH:
1086	if ( !sftk_hasAttribute(object, CKA_PRIME)) {
1087	    return CKR_TEMPLATE_INCOMPLETE;
1088	}
1089	if ( !sftk_hasAttribute(object, CKA_BASE)) {
1090	    return CKR_TEMPLATE_INCOMPLETE;
1091	}
1092	if ( !sftk_hasAttribute(object, CKA_VALUE)) {
1093	    return CKR_TEMPLATE_INCOMPLETE;
1094	}
1095	encrypt = CK_FALSE;
1096	recover = CK_FALSE;
1097	wrap = CK_FALSE;
1098	break;
1099#ifdef NSS_ENABLE_ECC
1100    case CKK_EC:
1101	if ( !sftk_hasAttribute(object, CKA_EC_PARAMS)) {
1102	    return CKR_TEMPLATE_INCOMPLETE;
1103	}
1104	if ( !sftk_hasAttribute(object, CKA_VALUE)) {
1105	    return CKR_TEMPLATE_INCOMPLETE;
1106	}
1107	encrypt = CK_FALSE;
1108	sign = CK_TRUE;
1109	recover = CK_FALSE;
1110	wrap = CK_FALSE;
1111	break;
1112#endif /* NSS_ENABLE_ECC */
1113    case CKK_NSS_JPAKE_ROUND1:
1114        if (!sftk_hasAttribute(object, CKA_PRIME ||
1115            !sftk_hasAttribute(object, CKA_SUBPRIME) ||
1116            !sftk_hasAttribute(object, CKA_BASE))) {
1117            return CKR_TEMPLATE_INCOMPLETE;
1118        }
1119        /* fall through */
1120    case CKK_NSS_JPAKE_ROUND2:
1121        /* CKA_NSS_JPAKE_SIGNERID and CKA_NSS_JPAKE_PEERID are checked in
1122           the J-PAKE code. */
1123        encrypt = sign = recover = wrap = CK_FALSE;
1124        derive = CK_TRUE;
1125        createObjectInfo = PR_FALSE;
1126        break;
1127    default:
1128	return CKR_ATTRIBUTE_VALUE_INVALID;
1129    }
1130    crv = sftk_defaultAttribute(object,CKA_SUBJECT,NULL,0);
1131    if (crv != CKR_OK)  return crv; 
1132    crv = sftk_defaultAttribute(object,CKA_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
1133    if (crv != CKR_OK)  return crv; 
1134    crv = sftk_defaultAttribute(object,CKA_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
1135    if (crv != CKR_OK)  return crv; 
1136    crv = sftk_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL));
1137    if (crv != CKR_OK)  return crv; 
1138    crv = sftk_defaultAttribute(object,CKA_SIGN,&sign,sizeof(CK_BBOOL));
1139    if (crv != CKR_OK)  return crv; 
1140    crv = sftk_defaultAttribute(object,CKA_SIGN_RECOVER,&recover,
1141							     sizeof(CK_BBOOL));
1142    if (crv != CKR_OK)  return crv; 
1143    crv = sftk_defaultAttribute(object,CKA_UNWRAP,&wrap,sizeof(CK_BBOOL));
1144    if (crv != CKR_OK)  return crv; 
1145    crv = sftk_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));
1146    if (crv != CKR_OK)  return crv; 
1147    /* the next two bits get modified only in the key gen and token cases */
1148    crv = sftk_forceAttribute(object,CKA_ALWAYS_SENSITIVE,
1149						&ckfalse,sizeof(CK_BBOOL));
1150    if (crv != CKR_OK)  return crv; 
1151    crv = sftk_forceAttribute(object,CKA_NEVER_EXTRACTABLE,
1152						&ckfalse,sizeof(CK_BBOOL));
1153    if (crv != CKR_OK)  return crv; 
1154
1155    /* should we check the non-token RSA private keys? */
1156
1157    if (sftk_isTrue(object,CKA_TOKEN)) {
1158	SFTKSlot *slot = session->slot;
1159	SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
1160	CK_RV crv;
1161
1162	if (keyHandle == NULL) {
1163	    return CKR_TOKEN_WRITE_PROTECTED;
1164	}
1165
1166	crv = sftkdb_write(keyHandle, object, &object->handle);
1167	sftk_freeDB(keyHandle);
1168	return crv;
1169    } else if (createObjectInfo) {
1170	object->objectInfo = sftk_mkPrivKey(object,key_type,&crv);
1171	if (object->objectInfo == NULL) return crv;
1172	object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey;
1173    }
1174    return CKR_OK;
1175}
1176
1177/* forward declare the DES formating function for handleSecretKey */
1178void sftk_FormatDESKey(unsigned char *key, int length);
1179
1180/* Validate secret key data, and set defaults */
1181static CK_RV
1182validateSecretKey(SFTKSession *session, SFTKObject *object, 
1183					CK_KEY_TYPE key_type, PRBool isFIPS)
1184{
1185    CK_RV crv;
1186    CK_BBOOL cktrue = CK_TRUE;
1187    CK_BBOOL ckfalse = CK_FALSE;
1188    SFTKAttribute *attribute = NULL;
1189    unsigned long requiredLen;
1190
1191    crv = sftk_defaultAttribute(object,CKA_SENSITIVE,
1192				isFIPS?&cktrue:&ckfalse,sizeof(CK_BBOOL));
1193    if (crv != CKR_OK)  return crv; 
1194    crv = sftk_defaultAttribute(object,CKA_EXTRACTABLE,
1195						&cktrue,sizeof(CK_BBOOL));
1196    if (crv != CKR_OK)  return crv; 
1197    crv = sftk_defaultAttribute(object,CKA_ENCRYPT,&cktrue,sizeof(CK_BBOOL));
1198    if (crv != CKR_OK)  return crv; 
1199    crv = sftk_defaultAttribute(object,CKA_DECRYPT,&cktrue,sizeof(CK_BBOOL));
1200    if (crv != CKR_OK)  return crv; 
1201    crv = sftk_defaultAttribute(object,CKA_SIGN,&ckfalse,sizeof(CK_BBOOL));
1202    if (crv != CKR_OK)  return crv; 
1203    crv = sftk_defaultAttribute(object,CKA_VERIFY,&ckfalse,sizeof(CK_BBOOL));
1204    if (crv != CKR_OK)  return crv; 
1205    crv = sftk_defaultAttribute(object,CKA_WRAP,&cktrue,sizeof(CK_BBOOL));
1206    if (crv != CKR_OK)  return crv; 
1207    crv = sftk_defaultAttribute(object,CKA_UNWRAP,&cktrue,sizeof(CK_BBOOL));
1208    if (crv != CKR_OK)  return crv; 
1209
1210    if ( !sftk_hasAttribute(object, CKA_VALUE)) {
1211	return CKR_TEMPLATE_INCOMPLETE;
1212    }
1213    /* the next two bits get modified only in the key gen and token cases */
1214    crv = sftk_forceAttribute(object,CKA_ALWAYS_SENSITIVE,
1215						&ckfalse,sizeof(CK_BBOOL));
1216    if (crv != CKR_OK)  return crv; 
1217    crv = sftk_forceAttribute(object,CKA_NEVER_EXTRACTABLE,
1218						&ckfalse,sizeof(CK_BBOOL));
1219    if (crv != CKR_OK)  return crv; 
1220
1221    /* some types of keys have a value length */
1222    crv = CKR_OK;
1223    switch (key_type) {
1224    /* force CKA_VALUE_LEN to be set */
1225    case CKK_GENERIC_SECRET:
1226    case CKK_RC2:
1227    case CKK_RC4:
1228#if NSS_SOFTOKEN_DOES_RC5
1229    case CKK_RC5:
1230#endif
1231#ifdef NSS_SOFTOKEN_DOES_CAST
1232    case CKK_CAST:
1233    case CKK_CAST3:
1234    case CKK_CAST5:
1235#endif
1236#if NSS_SOFTOKEN_DOES_IDEA
1237    case CKK_IDEA:
1238#endif
1239	attribute = sftk_FindAttribute(object,CKA_VALUE);
1240	/* shouldn't happen */
1241	if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
1242	crv = sftk_forceAttribute(object, CKA_VALUE_LEN, 
1243			&attribute->attrib.ulValueLen, sizeof(CK_ULONG));
1244	sftk_FreeAttribute(attribute);
1245	break;
1246    /* force the value to have the correct parity */
1247    case CKK_DES:
1248    case CKK_DES2:
1249    case CKK_DES3:
1250    case CKK_CDMF:
1251	attribute = sftk_FindAttribute(object,CKA_VALUE);
1252	/* shouldn't happen */
1253	if (attribute == NULL) 
1254	    return CKR_TEMPLATE_INCOMPLETE;
1255	requiredLen = sftk_MapKeySize(key_type);
1256	if (attribute->attrib.ulValueLen != requiredLen) {
1257	    sftk_FreeAttribute(attribute);
1258	    return CKR_KEY_SIZE_RANGE;
1259	}
1260	sftk_FormatDESKey((unsigned char*)attribute->attrib.pValue,
1261						 attribute->attrib.ulValueLen);
1262	sftk_FreeAttribute(attribute);
1263	break;
1264    case CKK_AES:
1265	attribute = sftk_FindAttribute(object,CKA_VALUE);
1266	/* shouldn't happen */
1267	if (attribute == NULL) 
1268	    return CKR_TEMPLATE_INCOMPLETE;
1269	if (attribute->attrib.ulValueLen != 16 &&
1270	    attribute->attrib.ulValueLen != 24 &&
1271	    attribute->attrib.ulValueLen != 32) {
1272	    sftk_FreeAttribute(attribute);
1273	    return CKR_KEY_SIZE_RANGE;
1274	}
1275	crv = sftk_forceAttribute(object, CKA_VALUE_LEN, 
1276			&attribute->attrib.ulValueLen, sizeof(CK_ULONG));
1277	sftk_FreeAttribute(attribute);
1278	break;
1279    default:
1280	break;
1281    }
1282
1283    return crv;
1284}
1285
1286/*
1287 * check the consistancy and initialize a Secret Key Object 
1288 */
1289static CK_RV
1290sftk_handleSecretKeyObject(SFTKSession *session,SFTKObject *object,
1291					CK_KEY_TYPE key_type, PRBool isFIPS)
1292{
1293    CK_RV crv;
1294
1295    /* First validate and set defaults */
1296    crv = validateSecretKey(session, object, key_type, isFIPS);
1297    if (crv != CKR_OK) goto loser;
1298
1299    /* If the object is a TOKEN object, store in the database */
1300    if (sftk_isTrue(object,CKA_TOKEN)) {
1301	SFTKSlot *slot = session->slot;
1302	SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
1303	CK_RV crv;
1304
1305	if (keyHandle == NULL) {
1306	    return CKR_TOKEN_WRITE_PROTECTED;
1307	}
1308
1309	crv = sftkdb_write(keyHandle, object, &object->handle);
1310	sftk_freeDB(keyHandle);
1311	return crv;
1312    }
1313
1314loser:
1315
1316    return crv;
1317}
1318
1319/*
1320 * check the consistancy and initialize a Key Object 
1321 */
1322static CK_RV
1323sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
1324{
1325    SFTKAttribute *attribute;
1326    CK_KEY_TYPE key_type;
1327    CK_BBOOL ckfalse = CK_FALSE;
1328    CK_RV crv;
1329
1330    /* verify the required fields */
1331    if ( !sftk_hasAttribute(object,CKA_KEY_TYPE) ) {
1332	return CKR_TEMPLATE_INCOMPLETE;
1333    }
1334
1335    /* now verify the common fields */
1336    crv = sftk_defaultAttribute(object,CKA_ID,NULL,0);
1337    if (crv != CKR_OK)  return crv; 
1338    crv = sftk_defaultAttribute(object,CKA_START_DATE,NULL,0);
1339    if (crv != CKR_OK)  return crv; 
1340    crv = sftk_defaultAttribute(object,CKA_END_DATE,NULL,0);
1341    if (crv != CKR_OK)  return crv; 
1342    /* CKA_DERIVE is common to all keys, but it's default value is
1343     * key dependent */
1344    crv = sftk_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL));
1345    if (crv != CKR_OK)  return crv; 
1346
1347    /* get the key type */
1348    attribute = sftk_FindAttribute(object,CKA_KEY_TYPE);
1349    if (!attribute) {
1350        return CKR_ATTRIBUTE_VALUE_INVALID;
1351    }
1352    key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
1353    sftk_FreeAttribute(attribute);
1354
1355    switch (object->objclass) {
1356    case CKO_PUBLIC_KEY:
1357	return sftk_handlePublicKeyObject(session,object,key_type);
1358    case CKO_PRIVATE_KEY:
1359	return sftk_handlePrivateKeyObject(session,object,key_type);
1360    case CKO_SECRET_KEY:
1361	/* make sure the required fields exist */
1362	return sftk_handleSecretKeyObject(session,object,key_type,
1363			     (PRBool)(session->slot->slotID == FIPS_SLOT_ID));
1364    default:
1365	break;
1366    }
1367    return CKR_ATTRIBUTE_VALUE_INVALID;
1368}
1369
1370/*
1371 * check the consistancy and Verify a DSA Parameter Object 
1372 */
1373static CK_RV
1374sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
1375{
1376    SFTKAttribute *primeAttr = NULL;
1377    SFTKAttribute *subPrimeAttr = NULL;
1378    SFTKAttribute *baseAttr = NULL;
1379    SFTKAttribute *seedAttr = NULL;
1380    SFTKAttribute *hAttr = NULL;
1381    SFTKAttribute *attribute;
1382    CK_RV crv = CKR_TEMPLATE_INCOMPLETE;
1383    PQGParams params;
1384    PQGVerify vfy, *verify = NULL;
1385    SECStatus result,rv;
1386
1387    primeAttr = sftk_FindAttribute(object,CKA_PRIME);
1388    if (primeAttr == NULL) goto loser;
1389    params.prime.data = primeAttr->attrib.pValue;
1390    params.prime.len = primeAttr->attrib.ulValueLen;
1391
1392    subPrimeAttr = sftk_FindAttribute(object,CKA_SUBPRIME);
1393    if (subPrimeAttr == NULL) goto loser;
1394    params.subPrime.data = subPrimeAttr->attrib.pValue;
1395    params.subPrime.len = subPrimeAttr->attrib.ulValueLen;
1396
1397    baseAttr = sftk_FindAttribute(object,CKA_BASE);
1398    if (baseAttr == NULL) goto loser;
1399    params.base.data = baseAttr->attrib.pValue;
1400    params.base.len = baseAttr->attrib.ulValueLen;
1401
1402    attribute = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_COUNTER);
1403    if (attribute != NULL) {
1404	vfy.counter = *(CK_ULONG *) attribute->attrib.pValue;
1405	sftk_FreeAttribute(attribute);
1406
1407	seedAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_SEED);
1408	if (seedAttr == NULL) goto loser;
1409	vfy.seed.data = seedAttr->attrib.pValue;
1410	vfy.seed.len = seedAttr->attrib.ulValueLen;
1411
1412	hAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_H);
1413	if (hAttr == NULL) goto loser;
1414	vfy.h.data = hAttr->attrib.pValue;
1415	vfy.h.len = hAttr->attrib.ulValueLen;
1416
1417	verify = &vfy;
1418    }
1419
1420    crv = CKR_FUNCTION_FAILED;
1421    rv = PQG_VerifyParams(&params,verify,&result);
1422    if (rv == SECSuccess) {
1423	crv = (result== SECSuccess) ? CKR_OK : CKR_ATTRIBUTE_VALUE_INVALID;
1424    }
1425
1426loser:
1427    if (hAttr) sftk_FreeAttribute(hAttr);
1428    if (seedAttr) sftk_FreeAttribute(seedAttr);
1429    if (baseAttr) sftk_FreeAttribute(baseAttr);
1430    if (subPrimeAttr) sftk_FreeAttribute(subPrimeAttr);
1431    if (primeAttr) sftk_FreeAttribute(primeAttr);
1432
1433    return crv;
1434}
1435
1436/*
1437 * check the consistancy and initialize a Key Parameter Object 
1438 */
1439static CK_RV
1440sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
1441{
1442    SFTKAttribute *attribute;
1443

Large files files are truncated, but you can click here to view the full file