summaryrefslogtreecommitdiff
path: root/security/nss/lib/softoken
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/softoken')
-rw-r--r--security/nss/lib/softoken/Makefile77
-rw-r--r--security/nss/lib/softoken/alghmac.c169
-rw-r--r--security/nss/lib/softoken/alghmac.h90
-rw-r--r--security/nss/lib/softoken/config.mk44
-rw-r--r--security/nss/lib/softoken/fipstest.c1093
-rw-r--r--security/nss/lib/softoken/fipstokn.c951
-rw-r--r--security/nss/lib/softoken/keydb.c2308
-rw-r--r--security/nss/lib/softoken/keydbt.h89
-rw-r--r--security/nss/lib/softoken/keylow.h251
-rw-r--r--security/nss/lib/softoken/keytboth.h99
-rw-r--r--security/nss/lib/softoken/keytlow.h100
-rw-r--r--security/nss/lib/softoken/lowkey.c330
-rw-r--r--security/nss/lib/softoken/manifest.mn77
-rw-r--r--security/nss/lib/softoken/padbuf.c77
-rw-r--r--security/nss/lib/softoken/pkcs11.c4031
-rw-r--r--security/nss/lib/softoken/pkcs11.h316
-rw-r--r--security/nss/lib/softoken/pkcs11c.c5323
-rw-r--r--security/nss/lib/softoken/pkcs11f.h933
-rw-r--r--security/nss/lib/softoken/pkcs11i.h428
-rw-r--r--security/nss/lib/softoken/pkcs11p.h49
-rw-r--r--security/nss/lib/softoken/pkcs11t.h1115
-rw-r--r--security/nss/lib/softoken/pkcs11u.c1270
-rw-r--r--security/nss/lib/softoken/pkcs11u.h48
-rw-r--r--security/nss/lib/softoken/private.h78
-rw-r--r--security/nss/lib/softoken/rawhash.c111
-rw-r--r--security/nss/lib/softoken/rsawrapr.c1049
-rw-r--r--security/nss/lib/softoken/secpkcs5.c1827
-rw-r--r--security/nss/lib/softoken/secpkcs5.h185
-rw-r--r--security/nss/lib/softoken/softoken.h167
-rw-r--r--security/nss/lib/softoken/softoknt.h61
30 files changed, 0 insertions, 22746 deletions
diff --git a/security/nss/lib/softoken/Makefile b/security/nss/lib/softoken/Makefile
deleted file mode 100644
index ad4d0cc4d..000000000
--- a/security/nss/lib/softoken/Makefile
+++ /dev/null
@@ -1,77 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Netscape security libraries.
-#
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation. Portions created by Netscape are
-# Copyright (C) 1994-2000 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable
-# instead of those above. If you wish to allow use of your
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL. If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-
diff --git a/security/nss/lib/softoken/alghmac.c b/security/nss/lib/softoken/alghmac.c
deleted file mode 100644
index ff320da09..000000000
--- a/security/nss/lib/softoken/alghmac.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#include "alghmac.h"
-#include "sechash.h"
-#include "secoid.h"
-#include "secport.h"
-
-#define HMAC_PAD_SIZE 64
-
-struct HMACContextStr {
- void *hash;
- SECHashObject *hashobj;
- unsigned char ipad[HMAC_PAD_SIZE];
- unsigned char opad[HMAC_PAD_SIZE];
-};
-
-void
-HMAC_Destroy(HMACContext *cx)
-{
- if (cx == NULL)
- return;
-
- if (cx->hash != NULL)
- cx->hashobj->destroy(cx->hash, PR_TRUE);
- PORT_ZFree(cx, sizeof(HMACContext));
-}
-
-HMACContext *
-HMAC_Create(SECOidTag hash_alg,
- const unsigned char *secret,
- unsigned int secret_len)
-{
- HMACContext *cx;
- int i;
- unsigned char hashed_secret[SHA1_LENGTH];
-
- cx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
- if (cx == NULL)
- return NULL;
-
- switch (hash_alg) {
- case SEC_OID_MD5:
- cx->hashobj = &SECRawHashObjects[HASH_AlgMD5];
- break;
- case SEC_OID_MD2:
- cx->hashobj = &SECRawHashObjects[HASH_AlgMD2];
- break;
- case SEC_OID_SHA1:
- cx->hashobj = &SECRawHashObjects[HASH_AlgSHA1];
- break;
- default:
- goto loser;
- }
-
- cx->hash = cx->hashobj->create();
- if (cx->hash == NULL)
- goto loser;
-
- if (secret_len > HMAC_PAD_SIZE) {
- cx->hashobj->begin( cx->hash);
- cx->hashobj->update(cx->hash, secret, secret_len);
- cx->hashobj->end( cx->hash, hashed_secret, &secret_len,
- sizeof hashed_secret);
- if (secret_len != cx->hashobj->length)
- goto loser;
- secret = (const unsigned char *)&hashed_secret[0];
- }
-
- PORT_Memset(cx->ipad, 0x36, sizeof cx->ipad);
- PORT_Memset(cx->opad, 0x5c, sizeof cx->opad);
-
- /* fold secret into padding */
- for (i = 0; i < secret_len; i++) {
- cx->ipad[i] ^= secret[i];
- cx->opad[i] ^= secret[i];
- }
- PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
- return cx;
-
-loser:
- PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
- HMAC_Destroy(cx);
- return NULL;
-}
-
-void
-HMAC_Begin(HMACContext *cx)
-{
- /* start inner hash */
- cx->hashobj->begin(cx->hash);
- cx->hashobj->update(cx->hash, cx->ipad, sizeof(cx->ipad));
-}
-
-void
-HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
-{
- cx->hashobj->update(cx->hash, data, data_len);
-}
-
-SECStatus
-HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
- unsigned int max_result_len)
-{
- if (max_result_len < cx->hashobj->length)
- return SECFailure;
-
- cx->hashobj->end(cx->hash, result, result_len, max_result_len);
- if (*result_len != cx->hashobj->length)
- return SECFailure;
-
- cx->hashobj->begin(cx->hash);
- cx->hashobj->update(cx->hash, cx->opad, sizeof(cx->opad));
- cx->hashobj->update(cx->hash, result, *result_len);
- cx->hashobj->end(cx->hash, result, result_len, max_result_len);
- return SECSuccess;
-}
-
-HMACContext *
-HMAC_Clone(HMACContext *cx)
-{
- HMACContext *newcx;
-
- newcx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
- if (newcx == NULL)
- goto loser;
-
- newcx->hashobj = cx->hashobj;
- newcx->hash = cx->hashobj->clone(cx->hash);
- if (newcx->hash == NULL)
- goto loser;
- PORT_Memcpy(newcx->ipad, cx->ipad, sizeof(cx->ipad));
- PORT_Memcpy(newcx->opad, cx->opad, sizeof(cx->opad));
- return newcx;
-
-loser:
- HMAC_Destroy(newcx);
- return NULL;
-}
diff --git a/security/nss/lib/softoken/alghmac.h b/security/nss/lib/softoken/alghmac.h
deleted file mode 100644
index 10d598267..000000000
--- a/security/nss/lib/softoken/alghmac.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#ifndef _ALGHMAC_H_
-#define _ALGHMAC_H_
-
-#include "secoid.h"
-
-typedef struct HMACContextStr HMACContext;
-
-SEC_BEGIN_PROTOS
-
-/* destroy HMAC context */
-extern void
-HMAC_Destroy(HMACContext *cx);
-
-/* create HMAC context
- * hash_alg the algorithm with which the HMAC is performed. This
- * should be, SEC_OID_MD5, SEC_OID_SHA1, or SEC_OID_MD2.
- * secret the secret with which the HMAC is performed.
- * secret_len the length of the secret, limited to at most 64 bytes.
- *
- * NULL is returned if an error occurs or the secret is > 64 bytes.
- */
-extern HMACContext *
-HMAC_Create(SECOidTag hash_alg, const unsigned char *secret,
- unsigned int secret_len);
-
-/* reset HMAC for a fresh round */
-extern void
-HMAC_Begin(HMACContext *cx);
-
-/* update HMAC
- * cx HMAC Context
- * data the data to perform HMAC on
- * data_len the length of the data to process
- */
-extern void
-HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len);
-
-/* Finish HMAC -- place the results within result
- * cx HMAC context
- * result buffer for resulting hmac'd data
- * result_len where the resultant hmac length is stored
- * max_result_len maximum possible length that can be stored in result
- */
-extern SECStatus
-HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
- unsigned int max_result_len);
-
-/* clone a copy of the HMAC state. this is usefult when you would
- * need to keep a running hmac but also need to extract portions
- * partway through the process.
- */
-extern HMACContext *
-HMAC_Clone(HMACContext *cx);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk
deleted file mode 100644
index a73a1086e..000000000
--- a/security/nss/lib/softoken/config.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Netscape security libraries.
-#
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation. Portions created by Netscape are
-# Copyright (C) 1994-2000 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable
-# instead of those above. If you wish to allow use of your
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL. If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PURE_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c
deleted file mode 100644
index a96a70959..000000000
--- a/security/nss/lib/softoken/fipstest.c
+++ /dev/null
@@ -1,1093 +0,0 @@
-/*
- * PKCS #11 FIPS Power-Up Self Test.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "softoken.h" /* Required for RC2-ECB, RC2-CBC, RC4, DES-ECB, */
- /* DES-CBC, DES3-ECB, DES3-CBC, RSA */
- /* and DSA. */
-#include "seccomon.h" /* Required for RSA and DSA. */
-#include "keylow.h" /* Required for RSA and DSA. */
-#include "pkcs11.h" /* Required for PKCS #11. */
-#include "secerr.h"
-
-/* FIPS preprocessor directives for RC2-ECB and RC2-CBC. */
-#define FIPS_RC2_KEY_LENGTH 5 /* 40-bits */
-#define FIPS_RC2_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_RC2_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for RC4. */
-#define FIPS_RC4_KEY_LENGTH 5 /* 40-bits */
-#define FIPS_RC4_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_RC4_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for DES-ECB and DES-CBC. */
-#define FIPS_DES_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_DES_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for DES3-CBC and DES3-ECB. */
-#define FIPS_DES3_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_DES3_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for MD2. */
-#define FIPS_MD2_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-
-
-/* FIPS preprocessor directives for MD5. */
-#define FIPS_MD5_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-
-
-/* FIPS preprocessor directives for SHA-1. */
-#define FIPS_SHA1_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-
-
-/* FIPS preprocessor directives for RSA. */
-#define FIPS_RSA_TYPE siBuffer
-#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 1 /* 8-bits */
-#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */
-#define FIPS_RSA_MESSAGE_LENGTH 16 /* 128-bits */
-#define FIPS_RSA_COEFFICIENT_LENGTH 32 /* 256-bits */
-#define FIPS_RSA_PRIME0_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_PRIME1_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_EXPONENT0_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_EXPONENT1_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_ENCRYPT_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_DECRYPT_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_CRYPTO_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_SIGNATURE_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_MODULUS_LENGTH 65 /* 520-bits */
-
-
-/* FIPS preprocessor directives for DSA. */
-#define FIPS_DSA_TYPE siBuffer
-#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */
-#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */
-#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */
-#define FIPS_DSA_PRIME_LENGTH 64 /* 512-bits */
-#define FIPS_DSA_BASE_LENGTH 64 /* 512-bits */
-
-static CK_RV
-pk11_fips_RC2_PowerUpSelfTest( void )
-{
- /* RC2 Known Key (40-bits). */
- static PRUint8 rc2_known_key[] = { "RSARC" };
-
- /* RC2-CBC Known Initialization Vector (64-bits). */
- static PRUint8 rc2_cbc_known_initialization_vector[] = {"Security"};
-
- /* RC2 Known Plaintext (64-bits). */
- static PRUint8 rc2_ecb_known_plaintext[] = {"Netscape"};
- static PRUint8 rc2_cbc_known_plaintext[] = {"Netscape"};
-
- /* RC2 Known Ciphertext (64-bits). */
- static PRUint8 rc2_ecb_known_ciphertext[] = {
- 0x1a,0x71,0x33,0x54,0x8d,0x5c,0xd2,0x30};
- static PRUint8 rc2_cbc_known_ciphertext[] = {
- 0xff,0x41,0xdb,0x94,0x8a,0x4c,0x33,0xb3};
-
- /* RC2 variables. */
- PRUint8 rc2_computed_ciphertext[FIPS_RC2_ENCRYPT_LENGTH];
- PRUint8 rc2_computed_plaintext[FIPS_RC2_DECRYPT_LENGTH];
- RC2Context * rc2_context;
- unsigned int rc2_bytes_encrypted;
- unsigned int rc2_bytes_decrypted;
- SECStatus rc2_status;
-
-
- /******************************************************/
- /* RC2-ECB Single-Round Known Answer Encryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- NULL, NSS_RC2,
- FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Encrypt( rc2_context, rc2_computed_ciphertext,
- &rc2_bytes_encrypted, FIPS_RC2_ENCRYPT_LENGTH,
- rc2_ecb_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_encrypted != FIPS_RC2_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_ciphertext, rc2_ecb_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* RC2-ECB Single-Round Known Answer Decryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- NULL, NSS_RC2,
- FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Decrypt( rc2_context, rc2_computed_plaintext,
- &rc2_bytes_decrypted, FIPS_RC2_DECRYPT_LENGTH,
- rc2_ecb_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_decrypted != FIPS_RC2_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_plaintext, rc2_ecb_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* RC2-CBC Single-Round Known Answer Encryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- rc2_cbc_known_initialization_vector,
- NSS_RC2_CBC, FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Encrypt( rc2_context, rc2_computed_ciphertext,
- &rc2_bytes_encrypted, FIPS_RC2_ENCRYPT_LENGTH,
- rc2_cbc_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_encrypted != FIPS_RC2_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_ciphertext, rc2_cbc_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* RC2-CBC Single-Round Known Answer Decryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- rc2_cbc_known_initialization_vector,
- NSS_RC2_CBC, FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Decrypt( rc2_context, rc2_computed_plaintext,
- &rc2_bytes_decrypted, FIPS_RC2_DECRYPT_LENGTH,
- rc2_cbc_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_decrypted != FIPS_RC2_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_plaintext, rc2_ecb_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-pk11_fips_RC4_PowerUpSelfTest( void )
-{
- /* RC4 Known Key (40-bits). */
- static PRUint8 rc4_known_key[] = { "RSARC" };
-
- /* RC4 Known Plaintext (64-bits). */
- static PRUint8 rc4_known_plaintext[] = { "Netscape" };
-
- /* RC4 Known Ciphertext (64-bits). */
- static PRUint8 rc4_known_ciphertext[] = {
- 0x29,0x33,0xc7,0x9a,0x9d,0x6c,0x09,0xdd};
-
- /* RC4 variables. */
- PRUint8 rc4_computed_ciphertext[FIPS_RC4_ENCRYPT_LENGTH];
- PRUint8 rc4_computed_plaintext[FIPS_RC4_DECRYPT_LENGTH];
- RC4Context * rc4_context;
- unsigned int rc4_bytes_encrypted;
- unsigned int rc4_bytes_decrypted;
- SECStatus rc4_status;
-
-
- /**************************************************/
- /* RC4 Single-Round Known Answer Encryption Test: */
- /**************************************************/
-
- rc4_context = RC4_CreateContext( rc4_known_key, FIPS_RC4_KEY_LENGTH );
-
- if( rc4_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc4_status = RC4_Encrypt( rc4_context, rc4_computed_ciphertext,
- &rc4_bytes_encrypted, FIPS_RC4_ENCRYPT_LENGTH,
- rc4_known_plaintext, FIPS_RC4_DECRYPT_LENGTH );
-
- RC4_DestroyContext( rc4_context, PR_TRUE );
-
- if( ( rc4_status != SECSuccess ) ||
- ( rc4_bytes_encrypted != FIPS_RC4_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc4_computed_ciphertext, rc4_known_ciphertext,
- FIPS_RC4_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /**************************************************/
- /* RC4 Single-Round Known Answer Decryption Test: */
- /**************************************************/
-
- rc4_context = RC4_CreateContext( rc4_known_key, FIPS_RC4_KEY_LENGTH );
-
- if( rc4_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc4_status = RC4_Decrypt( rc4_context, rc4_computed_plaintext,
- &rc4_bytes_decrypted, FIPS_RC4_DECRYPT_LENGTH,
- rc4_known_ciphertext, FIPS_RC4_ENCRYPT_LENGTH );
-
- RC4_DestroyContext( rc4_context, PR_TRUE );
-
- if( ( rc4_status != SECSuccess ) ||
- ( rc4_bytes_decrypted != FIPS_RC4_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc4_computed_plaintext, rc4_known_plaintext,
- FIPS_RC4_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-pk11_fips_DES_PowerUpSelfTest( void )
-{
- /* DES Known Key (56-bits). */
- static PRUint8 des_known_key[] = { "ANSI DES" };
-
- /* DES-CBC Known Initialization Vector (64-bits). */
- static PRUint8 des_cbc_known_initialization_vector[] = { "Security" };
-
- /* DES Known Plaintext (64-bits). */
- static PRUint8 des_ecb_known_plaintext[] = { "Netscape" };
- static PRUint8 des_cbc_known_plaintext[] = { "Netscape" };
-
- /* DES Known Ciphertext (64-bits). */
- static PRUint8 des_ecb_known_ciphertext[] = {
- 0x26,0x14,0xe9,0xc3,0x28,0x80,0x50,0xb0};
- static PRUint8 des_cbc_known_ciphertext[] = {
- 0x5e,0x95,0x94,0x5d,0x76,0xa2,0xd3,0x7d};
-
- /* DES variables. */
- PRUint8 des_computed_ciphertext[FIPS_DES_ENCRYPT_LENGTH];
- PRUint8 des_computed_plaintext[FIPS_DES_DECRYPT_LENGTH];
- DESContext * des_context;
- unsigned int des_bytes_encrypted;
- unsigned int des_bytes_decrypted;
- SECStatus des_status;
-
-
- /******************************************************/
- /* DES-ECB Single-Round Known Answer Encryption Test: */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key, NULL, NSS_DES, PR_TRUE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Encrypt( des_context, des_computed_ciphertext,
- &des_bytes_encrypted, FIPS_DES_ENCRYPT_LENGTH,
- des_ecb_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_encrypted != FIPS_DES_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_ciphertext, des_ecb_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* DES-ECB Single-Round Known Answer Decryption Test: */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key, NULL, NSS_DES, PR_FALSE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Decrypt( des_context, des_computed_plaintext,
- &des_bytes_decrypted, FIPS_DES_DECRYPT_LENGTH,
- des_ecb_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_decrypted != FIPS_DES_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_plaintext, des_ecb_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* DES-CBC Single-Round Known Answer Encryption Test. */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key,
- des_cbc_known_initialization_vector,
- NSS_DES_CBC, PR_TRUE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Encrypt( des_context, des_computed_ciphertext,
- &des_bytes_encrypted, FIPS_DES_ENCRYPT_LENGTH,
- des_cbc_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_encrypted != FIPS_DES_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_ciphertext, des_cbc_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* DES-CBC Single-Round Known Answer Decryption Test. */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key,
- des_cbc_known_initialization_vector,
- NSS_DES_CBC, PR_FALSE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Decrypt( des_context, des_computed_plaintext,
- &des_bytes_decrypted, FIPS_DES_DECRYPT_LENGTH,
- des_cbc_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_decrypted != FIPS_DES_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_plaintext, des_cbc_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-pk11_fips_DES3_PowerUpSelfTest( void )
-{
- /* DES3 Known Key (56-bits). */
- static PRUint8 des3_known_key[] = { "ANSI Triple-DES Key Data" };
-
- /* DES3-CBC Known Initialization Vector (64-bits). */
- static PRUint8 des3_cbc_known_initialization_vector[] = { "Security" };
-
- /* DES3 Known Plaintext (64-bits). */
- static PRUint8 des3_ecb_known_plaintext[] = { "Netscape" };
- static PRUint8 des3_cbc_known_plaintext[] = { "Netscape" };
-
- /* DES3 Known Ciphertext (64-bits). */
- static PRUint8 des3_ecb_known_ciphertext[] = {
- 0x55,0x8e,0xad,0x3c,0xee,0x49,0x69,0xbe};
- static PRUint8 des3_cbc_known_ciphertext[] = {
- 0x43,0xdc,0x6a,0xc1,0xaf,0xa6,0x32,0xf5};
-
- /* DES3 variables. */
- PRUint8 des3_computed_ciphertext[FIPS_DES3_ENCRYPT_LENGTH];
- PRUint8 des3_computed_plaintext[FIPS_DES3_DECRYPT_LENGTH];
- DESContext * des3_context;
- unsigned int des3_bytes_encrypted;
- unsigned int des3_bytes_decrypted;
- SECStatus des3_status;
-
-
- /*******************************************************/
- /* DES3-ECB Single-Round Known Answer Encryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key, NULL,
- NSS_DES_EDE3, PR_TRUE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Encrypt( des3_context, des3_computed_ciphertext,
- &des3_bytes_encrypted, FIPS_DES3_ENCRYPT_LENGTH,
- des3_ecb_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_ciphertext, des3_ecb_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /*******************************************************/
- /* DES3-ECB Single-Round Known Answer Decryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key, NULL,
- NSS_DES_EDE3, PR_FALSE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Decrypt( des3_context, des3_computed_plaintext,
- &des3_bytes_decrypted, FIPS_DES3_DECRYPT_LENGTH,
- des3_ecb_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_plaintext, des3_ecb_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /*******************************************************/
- /* DES3-CBC Single-Round Known Answer Encryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key,
- des3_cbc_known_initialization_vector,
- NSS_DES_EDE3_CBC, PR_TRUE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Encrypt( des3_context, des3_computed_ciphertext,
- &des3_bytes_encrypted, FIPS_DES3_ENCRYPT_LENGTH,
- des3_cbc_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_ciphertext, des3_cbc_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /*******************************************************/
- /* DES3-CBC Single-Round Known Answer Decryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key,
- des3_cbc_known_initialization_vector,
- NSS_DES_EDE3_CBC, PR_FALSE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Decrypt( des3_context, des3_computed_plaintext,
- &des3_bytes_decrypted, FIPS_DES3_DECRYPT_LENGTH,
- des3_cbc_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_plaintext, des3_cbc_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-pk11_fips_MD2_PowerUpSelfTest( void )
-{
- /* MD2 Known Hash Message (512-bits). */
- static PRUint8 md2_known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
-
- /* MD2 Known Digest Message (128-bits). */
- static PRUint8 md2_known_digest[] = {
- 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
- 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
-
- /* MD2 variables. */
- MD2Context * md2_context;
- unsigned int md2_bytes_hashed;
- PRUint8 md2_computed_digest[MD2_LENGTH];
-
-
- /***********************************************/
- /* MD2 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md2_context = MD2_NewContext();
-
- if( md2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- MD2_Begin( md2_context );
-
- MD2_Update( md2_context, md2_known_hash_message,
- FIPS_MD2_HASH_MESSAGE_LENGTH );
-
- MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
-
- MD2_DestroyContext( md2_context , PR_TRUE );
-
- if( ( md2_bytes_hashed != MD2_LENGTH ) ||
- ( PORT_Memcmp( md2_computed_digest, md2_known_digest,
- MD2_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-pk11_fips_MD5_PowerUpSelfTest( void )
-{
- /* MD5 Known Hash Message (512-bits). */
- static PRUint8 md5_known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
-
- /* MD5 Known Digest Message (128-bits). */
- static PRUint8 md5_known_digest[] = {
- 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
- 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
-
- /* MD5 variables. */
- PRUint8 md5_computed_digest[MD5_LENGTH];
- SECStatus md5_status;
-
-
- /***********************************************/
- /* MD5 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md5_status = MD5_HashBuf( md5_computed_digest, md5_known_hash_message,
- FIPS_MD5_HASH_MESSAGE_LENGTH );
-
- if( ( md5_status != SECSuccess ) ||
- ( PORT_Memcmp( md5_computed_digest, md5_known_digest,
- MD5_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-pk11_fips_SHA1_PowerUpSelfTest( void )
-{
- /* SHA-1 Known Hash Message (512-bits). */
- static PRUint8 sha1_known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
-
- /* SHA-1 Known Digest Message (160-bits). */
- static PRUint8 sha1_known_digest[] = {
- 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
- 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
- 0xe0,0x68,0x47,0x7a};
-
- /* SHA-1 variables. */
- PRUint8 sha1_computed_digest[SHA1_LENGTH];
- SECStatus sha1_status;
-
-
- /*************************************************/
- /* SHA-1 Single-Round Known Answer Hashing Test. */
- /*************************************************/
-
- sha1_status = SHA1_HashBuf( sha1_computed_digest, sha1_known_hash_message,
- FIPS_SHA1_HASH_MESSAGE_LENGTH );
-
- if( ( sha1_status != SECSuccess ) ||
- ( PORT_Memcmp( sha1_computed_digest, sha1_known_digest,
- SHA1_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-pk11_fips_RSA_PowerUpSelfTest( void )
-{
- /* RSA Known Modulus used in both Public/Private Key Values (520-bits). */
- static PRUint8 rsa_modulus[FIPS_RSA_MODULUS_LENGTH] = {
- 0x00,0xa1,0xe9,0x5e,0x66,0x88,0xe2,0xf2,
- 0x2b,0xe7,0x70,0x36,0x33,0xbc,0xeb,0x55,
- 0x55,0xf1,0x60,0x18,0x3c,0xfb,0xd2,0x79,
- 0xf6,0xc4,0xb8,0x09,0xe3,0x12,0xf6,0x63,
- 0x6d,0xc7,0x8e,0x19,0xc0,0x0e,0x10,0x78,
- 0xc1,0xfe,0x2a,0x41,0x74,0x2d,0xf7,0xc4,
- 0x69,0xa7,0x3c,0xbc,0x8a,0xc8,0x31,0x2b,
- 0x4f,0x60,0xf0,0xf1,0xec,0x5a,0x29,0xec,
- 0x6b};
-
- /* RSA Known Public Key Values (8-bits). */
- static PRUint8 rsa_public_exponent[] = { 0x03 };
-
- /* RSA Known Private Key Values (version is 8-bits), */
- /* (private exponent is 512-bits), */
- /* (private prime0 is 264-bits), */
- /* (private prime1 is 264-bits), */
- /* (private prime exponent0 is 264-bits), */
- /* (private prime exponent1 is 264-bits), */
- /* and (private coefficient is 256-bits). */
- static PRUint8 rsa_version[] = { 0x00 };
- static PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH] = {
- 0x6b,0xf0,0xe9,0x99,0xb0,0x97,0x4c,0x1d,
- 0x44,0xf5,0x79,0x77,0xd3,0x47,0x8e,0x39,
- 0x4b,0x95,0x65,0x7d,0xfd,0x36,0xfb,0xf9,
- 0xd8,0x7a,0xb1,0x42,0x0c,0xa4,0x42,0x48,
- 0x20,0x1c,0x6b,0x7d,0x5d,0xa3,0x58,0xd6,
- 0x95,0xd6,0x41,0xe3,0xd6,0x73,0xad,0xdb,
- 0x3b,0x89,0x00,0x8a,0xcd,0x1d,0xb9,0x06,
- 0xac,0xac,0x0e,0x02,0x72,0x1c,0xf8,0xab };
- static PRUint8 rsa_prime0[FIPS_RSA_PRIME0_LENGTH] = {
- 0x00,0xd2,0x2c,0x9d,0xef,0x7c,0x8f,0x58,
- 0x93,0x19,0xa1,0x77,0x0e,0x38,0x3e,0x85,
- 0xb4,0xaf,0xcc,0x99,0xa5,0x43,0xbf,0x97,
- 0xdc,0x46,0xb8,0x3f,0x6e,0x85,0x18,0x00,
- 0x81};
- static PRUint8 rsa_prime1[FIPS_RSA_PRIME1_LENGTH] = {
- 0x00,0xc5,0x36,0xda,0x94,0x85,0x0c,0x1a,
- 0xed,0x03,0xc7,0x67,0x90,0x34,0x0b,0xb9,
- 0xec,0x1e,0x22,0xa2,0x15,0x50,0xc4,0xfd,
- 0xe9,0x17,0x36,0x9d,0x7a,0x29,0xe6,0x76,
- 0xeb};
- static PRUint8 rsa_exponent0[FIPS_RSA_EXPONENT0_LENGTH] = {
- 0x00,0x8c,0x1d,0xbe,0x9f,0xa8,
- 0x5f,0x90,0x62,0x11,0x16,0x4f,
- 0x5e,0xd0,0x29,0xae,0x78,0x75,
- 0x33,0x11,0x18,0xd7,0xd5,0x0f,
- 0xe8,0x2f,0x25,0x7f,0x9f,0x03,
- 0x65,0x55,0xab};
- static PRUint8 rsa_exponent1[FIPS_RSA_EXPONENT1_LENGTH] = {
- 0x00,0x83,0x79,0xe7,0x0d,0xae,
- 0x08,0x11,0xf3,0x57,0xda,0x45,
- 0x0a,0xcd,0x5d,0x26,0x9d,0x69,
- 0x6c,0x6c,0x0e,0x35,0xd8,0xa9,
- 0x46,0x0f,0x79,0xbe,0x51,0x71,
- 0x44,0x4f,0x47};
- static PRUint8 rsa_coefficient[FIPS_RSA_COEFFICIENT_LENGTH] = {
- 0x54,0x8d,0xb8,0xdc,0x8b,0xde,0xbb,
- 0x08,0xc9,0x67,0xb7,0xa9,0x5f,0xa5,
- 0xc4,0x5e,0x67,0xaa,0xfe,0x1a,0x08,
- 0xeb,0x48,0x43,0xcb,0xb0,0xb9,0x38,
- 0x3a,0x31,0x39,0xde};
-
-
- /* RSA Known Plaintext (512-bits). */
- static PRUint8 rsa_known_plaintext[] = {
- "Known plaintext utilized for RSA"
- " Encryption and Decryption test." };
-
- /* RSA Known Ciphertext (512-bits). */
- static PRUint8 rsa_known_ciphertext[] = {
- 0x12,0x80,0x3a,0x53,0xee,0x93,0x81,0xa5,
- 0xf7,0x40,0xc5,0xb1,0xef,0xd9,0x27,0xaf,
- 0xef,0x4b,0x87,0x44,0x00,0xd0,0xda,0xcf,
- 0x10,0x57,0x4c,0xd5,0xc3,0xed,0x84,0xdc,
- 0x74,0x03,0x19,0x69,0x2c,0xd6,0x54,0x3e,
- 0xd2,0xe3,0x90,0xb6,0x67,0x91,0x2f,0x1f,
- 0x54,0x13,0x99,0x00,0x0b,0xfd,0x52,0x7f,
- 0xd8,0xc6,0xdb,0x8a,0xfe,0x06,0xf3,0xb1};
-
- /* RSA Known Message (128-bits). */
- static PRUint8 rsa_known_message[] = { "Netscape Forever" };
-
- /* RSA Known Signed Hash (512-bits). */
- static PRUint8 rsa_known_signature[] = {
- 0x27,0x23,0xa6,0x71,0x57,0xc8,0x70,0x5f,
- 0x70,0x0e,0x06,0x7b,0x96,0x6a,0xaa,0x41,
- 0x6e,0xab,0x67,0x4b,0x5f,0x76,0xc4,0x53,
- 0x23,0xd7,0x57,0x7a,0x3a,0xbc,0x4c,0x27,
- 0x65,0xca,0xde,0x9f,0xd3,0x1d,0xa4,0x5a,
- 0xf9,0x8f,0xb2,0x05,0xa3,0x86,0xf9,0x66,
- 0x55,0x4c,0x68,0x50,0x66,0xa4,0xe9,0x17,
- 0x45,0x11,0xb8,0x1a,0xfc,0xbc,0x79,0x3b};
-
-
- static RSAPublicKey bl_public_key = { NULL,
- { FIPS_RSA_TYPE, rsa_modulus, FIPS_RSA_MODULUS_LENGTH },
- { FIPS_RSA_TYPE, rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH }
- };
- static RSAPrivateKey bl_private_key = { NULL,
- { FIPS_RSA_TYPE, rsa_version, FIPS_RSA_PRIVATE_VERSION_LENGTH },
- { FIPS_RSA_TYPE, rsa_modulus, FIPS_RSA_MODULUS_LENGTH },
- { FIPS_RSA_TYPE, rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH },
- { FIPS_RSA_TYPE, rsa_private_exponent, FIPS_RSA_PRIVATE_EXPONENT_LENGTH },
- { FIPS_RSA_TYPE, rsa_prime0, FIPS_RSA_PRIME0_LENGTH },
- { FIPS_RSA_TYPE, rsa_prime1, FIPS_RSA_PRIME1_LENGTH },
- { FIPS_RSA_TYPE, rsa_exponent0, FIPS_RSA_EXPONENT0_LENGTH },
- { FIPS_RSA_TYPE, rsa_exponent1, FIPS_RSA_EXPONENT1_LENGTH },
- { FIPS_RSA_TYPE, rsa_coefficient, FIPS_RSA_COEFFICIENT_LENGTH }
- };
-
- /* RSA variables. */
-#ifdef CREATE_TEMP_ARENAS
- PLArenaPool * rsa_public_arena;
- PLArenaPool * rsa_private_arena;
-#endif
- SECKEYLowPublicKey * rsa_public_key;
- SECKEYLowPrivateKey * rsa_private_key;
- unsigned int rsa_bytes_signed;
- SECStatus rsa_status;
-
- SECKEYLowPublicKey low_public_key = { NULL, rsaKey, };
- SECKEYLowPrivateKey low_private_key = { NULL, rsaKey, };
- PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH];
- PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH];
- PRUint8 rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH];
-
- /****************************************/
- /* Compose RSA Public/Private Key Pair. */
- /****************************************/
-
- low_public_key.u.rsa = bl_public_key;
- low_private_key.u.rsa = bl_private_key;
-
- rsa_public_key = &low_public_key;
- rsa_private_key = &low_private_key;
-
-#ifdef CREATE_TEMP_ARENAS
- /* Create some space for the RSA public key. */
- rsa_public_arena = PORT_NewArena( NSS_SOFTOKEN_DEFAULT_CHUNKSIZE );
-
- if( rsa_public_arena == NULL ) {
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- return( CKR_HOST_MEMORY );
- }
-
- /* Create some space for the RSA private key. */
- rsa_private_arena = PORT_NewArena( NSS_SOFTOKEN_DEFAULT_CHUNKSIZE );
-
- if( rsa_private_arena == NULL ) {
- PORT_FreeArena( rsa_public_arena, PR_TRUE );
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- return( CKR_HOST_MEMORY );
- }
-
- rsa_public_key->arena = rsa_public_arena;
- rsa_private_key->arena = rsa_private_arena;
-#endif
-
- /**************************************************/
- /* RSA Single-Round Known Answer Encryption Test. */
- /**************************************************/
-
- /* Perform RSA Public Key Encryption. */
- rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa,
- rsa_computed_ciphertext, rsa_known_plaintext);
-
- if( ( rsa_status != SECSuccess ) ||
- ( PORT_Memcmp( rsa_computed_ciphertext, rsa_known_ciphertext,
- FIPS_RSA_ENCRYPT_LENGTH ) != 0 ) )
- goto rsa_loser;
-
- /**************************************************/
- /* RSA Single-Round Known Answer Decryption Test. */
- /**************************************************/
-
- /* Perform RSA Private Key Decryption. */
- rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa,
- rsa_computed_plaintext, rsa_known_ciphertext);
-
- if( ( rsa_status != SECSuccess ) ||
- ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext,
- FIPS_RSA_DECRYPT_LENGTH ) != 0 ) )
- goto rsa_loser;
-
-
- /*************************************************/
- /* RSA Single-Round Known Answer Signature Test. */
- /*************************************************/
-
- /* Perform RSA signature with the RSA private key. */
- rsa_status = RSA_Sign( rsa_private_key, rsa_computed_signature,
- &rsa_bytes_signed,
- FIPS_RSA_SIGNATURE_LENGTH, rsa_known_message,
- FIPS_RSA_MESSAGE_LENGTH );
-
- if( ( rsa_status != SECSuccess ) ||
- ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) ||
- ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature,
- FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) )
- goto rsa_loser;
-
-
- /****************************************************/
- /* RSA Single-Round Known Answer Verification Test. */
- /****************************************************/
-
- /* Perform RSA verification with the RSA public key. */
- rsa_status = RSA_CheckSign( rsa_public_key,
- rsa_computed_signature,
- FIPS_RSA_SIGNATURE_LENGTH,
- rsa_known_message,
- FIPS_RSA_MESSAGE_LENGTH );
-
- if( rsa_status != SECSuccess )
- goto rsa_loser;
-
- /* Dispose of all RSA key material. */
- SECKEY_LowDestroyPublicKey( rsa_public_key );
- SECKEY_LowDestroyPrivateKey( rsa_private_key );
-
- return( CKR_OK );
-
-
-rsa_loser:
-
- SECKEY_LowDestroyPublicKey( rsa_public_key );
- SECKEY_LowDestroyPrivateKey( rsa_private_key );
-
- return( CKR_DEVICE_ERROR );
-}
-
-
-static CK_RV
-pk11_fips_DSA_PowerUpSelfTest( void )
-{
- /* DSA Known P (512-bits), Q (160-bits), and G (512-bits) Values. */
- static PRUint8 dsa_P[] = {
- 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
- 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
- 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
- 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
- 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
- 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
- 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
- 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91};
- static PRUint8 dsa_Q[] = {
- 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
- 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
- 0xda,0xce,0x91,0x5f};
- static PRUint8 dsa_G[] = {
- 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
- 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
- 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
- 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
- 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
- 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
- 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
- 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02};
-
- /* DSA Known Random Values (known random key block is 160-bits) */
- /* and (known random signature block is 160-bits). */
- static PRUint8 dsa_known_random_key_block[] = {
- "Mozilla Rules World!"};
- static PRUint8 dsa_known_random_signature_block[] = {
- "Random DSA Signature"};
-
- /* DSA Known Digest (160-bits) */
- static PRUint8 dsa_known_digest[] = { "DSA Signature Digest" };
-
- /* DSA Known Signature (320-bits). */
- static PRUint8 dsa_known_signature[] = {
- 0x39,0x0d,0x84,0xb1,0xf7,0x52,0x89,0xba,
- 0xec,0x1e,0xa8,0xe2,0x00,0x8e,0x37,0x8f,
- 0xc2,0xf5,0xf8,0x70,0x11,0xa8,0xc7,0x02,
- 0x0e,0x75,0xcf,0x6b,0x54,0x4a,0x52,0xe8,
- 0xd8,0x6d,0x4a,0xe8,0xee,0x56,0x8e,0x59};
-
- /* DSA variables. */
- DSAPrivateKey * dsa_private_key;
- SECStatus dsa_status;
- SECItem dsa_signature_item;
- SECItem dsa_digest_item;
- DSAPublicKey dsa_public_key;
- PRUint8 dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH];
- static PQGParams dsa_pqg = { NULL,
- { FIPS_DSA_TYPE, dsa_P, FIPS_DSA_PRIME_LENGTH },
- { FIPS_DSA_TYPE, dsa_Q, FIPS_DSA_SUBPRIME_LENGTH },
- { FIPS_DSA_TYPE, dsa_G, FIPS_DSA_BASE_LENGTH }};
-
- /*******************************************/
- /* Generate a DSA public/private key pair. */
- /*******************************************/
-
- /* Generate a DSA public/private key pair. */
-
- dsa_status = DSA_NewKeyFromSeed(&dsa_pqg, dsa_known_random_key_block,
- &dsa_private_key);
-
- if( dsa_status != SECSuccess )
- return( CKR_HOST_MEMORY );
-
- /* construct public key from private key. */
- dsa_public_key.params = dsa_private_key->params;
- dsa_public_key.publicValue = dsa_private_key->publicValue;
-
- /*************************************************/
- /* DSA Single-Round Known Answer Signature Test. */
- /*************************************************/
-
- dsa_signature_item.data = dsa_computed_signature;
- dsa_signature_item.len = sizeof dsa_computed_signature;
-
- dsa_digest_item.data = dsa_known_digest;
- dsa_digest_item.len = SHA1_LENGTH;
-
- /* Perform DSA signature process. */
- dsa_status = DSA_SignDigestWithSeed( dsa_private_key,
- &dsa_signature_item,
- &dsa_digest_item,
- dsa_known_random_signature_block );
-
- if( ( dsa_status != SECSuccess ) ||
- ( dsa_signature_item.len != FIPS_DSA_SIGNATURE_LENGTH ) ||
- ( PORT_Memcmp( dsa_computed_signature, dsa_known_signature,
- FIPS_DSA_SIGNATURE_LENGTH ) != 0 ) ) {
- dsa_status = SECFailure;
- } else {
-
- /****************************************************/
- /* DSA Single-Round Known Answer Verification Test. */
- /****************************************************/
-
- /* Perform DSA verification process. */
- dsa_status = DSA_VerifyDigest( &dsa_public_key,
- &dsa_signature_item,
- &dsa_digest_item);
- }
-
- PORT_FreeArena(dsa_private_key->params.arena, PR_TRUE);
- /* Don't free public key, it uses same arena as private key */
-
- /* Verify DSA signature. */
- if( dsa_status != SECSuccess )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-
-
-}
-
-
-CK_RV
-pk11_fipsPowerUpSelfTest( void )
-{
- CK_RV rv;
-
- /* RC2 Power-Up SelfTest(s). */
- rv = pk11_fips_RC2_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* RC4 Power-Up SelfTest(s). */
- rv = pk11_fips_RC4_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* DES Power-Up SelfTest(s). */
- rv = pk11_fips_DES_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* DES3 Power-Up SelfTest(s). */
- rv = pk11_fips_DES3_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* MD2 Power-Up SelfTest(s). */
- rv = pk11_fips_MD2_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* MD5 Power-Up SelfTest(s). */
- rv = pk11_fips_MD5_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* SHA-1 Power-Up SelfTest(s). */
- rv = pk11_fips_SHA1_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* RSA Power-Up SelfTest(s). */
- rv = pk11_fips_RSA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* DSA Power-Up SelfTest(s). */
- rv = pk11_fips_DSA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* Passed Power-Up SelfTest(s). */
- return( CKR_OK );
-}
-
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
deleted file mode 100644
index e72a9965a..000000000
--- a/security/nss/lib/softoken/fipstokn.c
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login
- * (unless you've enabled FIPS). It supports Public Key ops, and all they
- * bulk ciphers and hashes. It can also support Private Key ops for imported
- * Private keys. It does not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-#include "seccomon.h"
-#include "softoken.h"
-#include "key.h"
-#include "pkcs11.h"
-#include "pkcs11i.h"
-
-/* The next two strings must be exactly 64 characters long, with the
- first 32 characters meaningful */
-static char *slotDescription =
- "Netscape Internal FIPS-140-1 Cryptographic Services ";
-static char *privSlotDescription =
- "Netscape FIPS-140-1 User Private Key Services ";
-
-
-/*
- * Configuration utils
- */
-void
-PK11_ConfigureFIPS(char *slotdes, char *pslotdes)
-{
- if (slotdes && (PORT_Strlen(slotdes) == 65)) {
- slotDescription = slotdes;
- }
- if (pslotdes && (PORT_Strlen(pslotdes) == 65)) {
- privSlotDescription = pslotdes;
- }
- return;
-}
-
-/*
- * ******************** Password Utilities *******************************
- */
-static PRBool isLoggedIn = PR_FALSE;
-static PRBool fatalError = PR_FALSE;
-
-/* Fips required checks before any useful crypto graphic services */
-static CK_RV pk11_fipsCheck(void) {
- if (isLoggedIn != PR_TRUE)
- return CKR_USER_NOT_LOGGED_IN;
- if (fatalError)
- return CKR_DEVICE_ERROR;
- return CKR_OK;
-}
-
-
-#define PK11_FIPSCHECK() \
- CK_RV rv; \
- if ((rv = pk11_fipsCheck()) != CKR_OK) return rv;
-
-#define PK11_FIPSFATALCHECK() \
- if (fatalError) return CKR_DEVICE_ERROR;
-
-
-/* grab an attribute out of a raw template */
-void *
-fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type)
-{
- int i;
-
- for (i=0; i < (int) ulCount; i++) {
- if (pTemplate[i].type == type) {
- return pTemplate[i].pValue;
- }
- }
- return NULL;
-}
-
-
-#define __PASTE(x,y) x##y
-
-/* ------------- forward declare all the NSC_ functions ------------- */
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-/* ------------- forward declare all the FIPS functions ------------- */
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-/* ------------- build the CK_CRYPTO_TABLE ------------------------- */
-static CK_FUNCTION_LIST pk11_fipsTable = {
- { 1, 10 },
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-#define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name),
-
-
-#include "pkcs11f.h"
-
-};
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-
-/**********************************************************************
- *
- * Start of PKCS 11 functions
- *
- **********************************************************************/
-/* return the function list */
-CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
- *pFunctionList = &pk11_fipsTable;
- return CKR_OK;
-}
-
-
-/* FC_Initialize initializes the PKCS #11 library. */
-CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
- CK_RV rv;
- static PRBool init= PR_FALSE;
-
-
- rv = PK11_LowInitialize(pReserved);
-
- if (rv == CKR_OK && !init) {
- init = PR_TRUE;
- rv = PK11_SlotInit(FIPS_SLOT_ID,PR_TRUE);
- /* fall through to check below */
- }
-
- /* not an 'else' rv can be set by either PK11_LowInit or PK11_SlotInit*/
- if (rv != CKR_OK) {
- fatalError = PR_TRUE;
- return rv;
- }
-
- fatalError = PR_FALSE; /* any error has been reset */
-
- rv = pk11_fipsPowerUpSelfTest();
- if (rv != CKR_OK) {
- fatalError = PR_TRUE;
- return rv;
- }
-
- return CKR_OK;
-}
-
-/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
-CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
- /* this should free up FIPS Slot */
- return NSC_Finalize (pReserved);
-}
-
-
-/* FC_GetInfo returns general information about PKCS #11. */
-CK_RV FC_GetInfo(CK_INFO_PTR pInfo) {
- return NSC_GetInfo(pInfo);
-}
-
-/* FC_GetSlotList obtains a list of slots in the system. */
-CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
- *pulCount = 1;
- if (pSlotList != NULL) {
- pSlotList[0] = FIPS_SLOT_ID;
- }
- return CKR_OK;
-}
-
-/* FC_GetSlotInfo obtains information about a particular slot in the system. */
-CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
-
- CK_RV crv;
-
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
-
- /* Use NETSCAPE_SLOT_ID as a basis so that we get Library version number,
- * not key_DB version number */
- crv = NSC_GetSlotInfo(NETSCAPE_SLOT_ID,pInfo);
- if (crv != CKR_OK) {
- return crv;
- }
-
- PORT_Memcpy(pInfo->slotDescription,slotDescription,64);
- return CKR_OK;
-}
-
-
-/*FC_GetTokenInfo obtains information about a particular token in the system.*/
- CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
- CK_RV crv;
-
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
-
- /* use PRIVATE_KEY_SLOT_ID so we get the correct
- Authentication information */
- crv = NSC_GetTokenInfo(PRIVATE_KEY_SLOT_ID,pInfo);
- pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED;
- /* yes virginia, FIPS can do random number generation:) */
- return crv;
-
-}
-
-
-
-/*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/
- CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
- PK11_FIPSFATALCHECK();
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
- /* FIPS Slot supports all functions */
- return NSC_GetMechanismList(NETSCAPE_SLOT_ID,pMechanismList,pusCount);
-}
-
-
-/* FC_GetMechanismInfo obtains information about a particular mechanism
- * possibly supported by a token. */
- CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo) {
- PK11_FIPSFATALCHECK();
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
- /* FIPS Slot supports all functions */
- return NSC_GetMechanismInfo(NETSCAPE_SLOT_ID,type,pInfo);
-}
-
-
-/* FC_InitToken initializes a token. */
- CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
- CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
- return CKR_HOST_MEMORY; /*is this the right function for not implemented*/
-}
-
-
-/* FC_InitPIN initializes the normal user's PIN. */
- CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
- return NSC_InitPIN(hSession,pPin,ulPinLen);
-}
-
-
-/* FC_SetPIN modifies the PIN of user that is currently logged in. */
-/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
- CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
- CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
- CK_RV rv;
- if ((rv = pk11_fipsCheck()) != CKR_OK) return rv;
- return NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
-}
-
-/* FC_OpenSession opens a session between an application and a token. */
- CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
- CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) {
- PK11_FIPSFATALCHECK();
- return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession);
-}
-
-
-/* FC_CloseSession closes a session between an application and a token. */
- CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) {
- return NSC_CloseSession(hSession);
-}
-
-
-/* FC_CloseAllSessions closes all sessions with a token. */
- CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) {
- return NSC_CloseAllSessions (slotID);
-}
-
-
-/* FC_GetSessionInfo obtains information about the session. */
- CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo) {
- CK_RV rv;
- PK11_FIPSFATALCHECK();
-
- rv = NSC_GetSessionInfo(hSession,pInfo);
- if (rv == CKR_OK) {
- if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) {
- pInfo->state = CKS_RO_USER_FUNCTIONS;
- }
- if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) {
- pInfo->state = CKS_RW_USER_FUNCTIONS;
- }
- }
- return rv;
-}
-
-/* FC_Login logs a user into a token. */
- CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
- CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
- CK_RV rv;
- PK11_FIPSFATALCHECK();
- rv = NSC_Login(hSession,userType,pPin,usPinLen);
- if (rv == CKR_OK)
- isLoggedIn = PR_TRUE;
- else if (rv == CKR_USER_ALREADY_LOGGED_IN)
- {
- isLoggedIn = PR_TRUE;
-
- /* Provide FIPS PUB 140-1 power-up self-tests on demand. */
- rv = pk11_fipsPowerUpSelfTest();
- if (rv == CKR_OK)
- return CKR_USER_ALREADY_LOGGED_IN;
- else
- fatalError = PR_TRUE;
- }
- return rv;
-}
-
-/* FC_Logout logs a user out from a token. */
- CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
- PK11_FIPSCHECK();
-
- rv = NSC_Logout(hSession);
- isLoggedIn = PR_FALSE;
- return rv;
-}
-
-
-/* FC_CreateObject creates a new object. */
- CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject) {
- CK_OBJECT_CLASS * classptr;
- PK11_FIPSCHECK();
- classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS);
- if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- /* FIPS can't create keys from raw key material */
- if ((*classptr == CKO_SECRET_KEY) || (*classptr == CKO_PRIVATE_KEY)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- return NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
-}
-
-
-
-
-
-/* FC_CopyObject copies an object, creating a new object for the copy. */
- CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount,
- CK_OBJECT_HANDLE_PTR phNewObject) {
- PK11_FIPSCHECK();
- return NSC_CopyObject(hSession,hObject,pTemplate,usCount,phNewObject);
-}
-
-
-/* FC_DestroyObject destroys an object. */
- CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject) {
- PK11_FIPSCHECK();
- return NSC_DestroyObject(hSession,hObject);
-}
-
-
-/* FC_GetObjectSize gets the size of an object in bytes. */
- CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize) {
- PK11_FIPSCHECK();
- return NSC_GetObjectSize(hSession, hObject, pusSize);
-}
-
-
-/* FC_GetAttributeValue obtains the value of one or more object attributes. */
- CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
- PK11_FIPSCHECK();
- return NSC_GetAttributeValue(hSession,hObject,pTemplate,usCount);
-}
-
-
-/* FC_SetAttributeValue modifies the value of one or more object attributes */
- CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
- PK11_FIPSCHECK();
- return NSC_SetAttributeValue(hSession,hObject,pTemplate,usCount);
-}
-
-
-
-/* FC_FindObjectsInit initializes a search for token and session objects
- * that match a template. */
- CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
- PK11_FIPSCHECK();
- return NSC_FindObjectsInit(hSession,pTemplate,usCount);
-}
-
-
-/* FC_FindObjects continues a search for token and session objects
- * that match a template, obtaining additional object handles. */
- CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount,
- CK_ULONG_PTR pusObjectCount) {
- PK11_FIPSCHECK();
- return NSC_FindObjects(hSession,phObject,usMaxObjectCount,
- pusObjectCount);
-}
-
-
-/*
- ************** Crypto Functions: Encrypt ************************
- */
-
-/* FC_EncryptInit initializes an encryption operation. */
- CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
- PK11_FIPSCHECK();
- return NSC_EncryptInit(hSession,pMechanism,hKey);
-}
-
-/* FC_Encrypt encrypts single-part data. */
- CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pusEncryptedDataLen) {
- PK11_FIPSCHECK();
- return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData,
- pusEncryptedDataLen);
-}
-
-
-/* FC_EncryptUpdate continues a multiple-part encryption operation. */
- CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pusEncryptedPartLen) {
- PK11_FIPSCHECK();
- return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart,
- pusEncryptedPartLen);
-}
-
-
-/* FC_EncryptFinal finishes a multiple-part encryption operation. */
- CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) {
-
- PK11_FIPSCHECK();
- return NSC_EncryptFinal(hSession,pLastEncryptedPart,
- pusLastEncryptedPartLen);
-}
-
-/*
- ************** Crypto Functions: Decrypt ************************
- */
-
-
-/* FC_DecryptInit initializes a decryption operation. */
- CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
- PK11_FIPSCHECK();
- return NSC_DecryptInit(hSession,pMechanism,hKey);
-}
-
-/* FC_Decrypt decrypts encrypted data in a single part. */
- CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData,
- CK_ULONG_PTR pusDataLen) {
- PK11_FIPSCHECK();
- return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData,
- pusDataLen);
-}
-
-
-/* FC_DecryptUpdate continues a multiple-part decryption operation. */
- CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) {
- PK11_FIPSCHECK();
- return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen,
- pPart,pusPartLen);
-}
-
-
-/* FC_DecryptFinal finishes a multiple-part decryption operation. */
- CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) {
- PK11_FIPSCHECK();
- return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen);
-}
-
-
-/*
- ************** Crypto Functions: Digest (HASH) ************************
- */
-
-/* FC_DigestInit initializes a message-digesting operation. */
- CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism) {
- PK11_FIPSFATALCHECK();
- return NSC_DigestInit(hSession, pMechanism);
-}
-
-
-/* FC_Digest digests data in a single part. */
- CK_RV FC_Digest(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pusDigestLen) {
- PK11_FIPSFATALCHECK();
- return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen);
-}
-
-
-/* FC_DigestUpdate continues a multiple-part message-digesting operation. */
- CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG usPartLen) {
- PK11_FIPSFATALCHECK();
- return NSC_DigestUpdate(hSession,pPart,usPartLen);
-}
-
-
-/* FC_DigestFinal finishes a multiple-part message-digesting operation. */
- CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pusDigestLen) {
- PK11_FIPSFATALCHECK();
- return NSC_DigestFinal(hSession,pDigest,pusDigestLen);
-}
-
-
-/*
- ************** Crypto Functions: Sign ************************
- */
-
-/* FC_SignInit initializes a signature (private key encryption) operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_SignInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
- PK11_FIPSCHECK();
- return NSC_SignInit(hSession,pMechanism,hKey);
-}
-
-
-/* FC_Sign signs (encrypts with private key) data in a single part,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_Sign(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pusSignatureLen) {
- PK11_FIPSCHECK();
- return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen);
-}
-
-
-/* FC_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG usPartLen) {
- PK11_FIPSCHECK();
- return NSC_SignUpdate(hSession,pPart,usPartLen);
-}
-
-
-/* FC_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
- CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pusSignatureLen) {
- PK11_FIPSCHECK();
- return NSC_SignFinal(hSession,pSignature,pusSignatureLen);
-}
-
-/*
- ************** Crypto Functions: Sign Recover ************************
- */
-/* FC_SignRecoverInit initializes a signature operation,
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
- CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
- PK11_FIPSCHECK();
- return NSC_SignRecoverInit(hSession,pMechanism,hKey);
-}
-
-
-/* FC_SignRecover signs data in a single operation
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
- CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) {
- PK11_FIPSCHECK();
- return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen);
-}
-
-/*
- ************** Crypto Functions: verify ************************
- */
-
-/* FC_VerifyInit initializes a verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature (e.g. DSA) */
- CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
- PK11_FIPSCHECK();
- return NSC_VerifyInit(hSession,pMechanism,hKey);
-}
-
-
-/* FC_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) {
- /* make sure we're legal */
- PK11_FIPSCHECK();
- return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen);
-}
-
-
-/* FC_VerifyUpdate continues a multiple-part verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG usPartLen) {
- PK11_FIPSCHECK();
- return NSC_VerifyUpdate(hSession,pPart,usPartLen);
-}
-
-
-/* FC_VerifyFinal finishes a multiple-part verification operation,
- * checking the signature. */
- CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) {
- PK11_FIPSCHECK();
- return NSC_VerifyFinal(hSession,pSignature,usSignatureLen);
-}
-
-/*
- ************** Crypto Functions: Verify Recover ************************
- */
-
-/* FC_VerifyRecoverInit initializes a signature verification operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
- CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
- PK11_FIPSCHECK();
- return NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
-}
-
-
-/* FC_VerifyRecover verifies a signature in a single-part operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
- CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen,
- CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) {
- PK11_FIPSCHECK();
- return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData,
- pusDataLen);
-}
-
-/*
- **************************** Key Functions: ************************
- */
-
-/* FC_GenerateKey generates a secret key, creating a new key object. */
- CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- CK_BBOOL *boolptr;
-
- PK11_FIPSCHECK();
-
- /* all secret keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
-
- return NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
-}
-
-
-/* FC_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
- CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey) {
- CK_BBOOL *boolptr;
-
- PK11_FIPSCHECK();
-
- /* all private keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate,
- usPrivateKeyAttributeCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- return NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
- usPublicKeyAttributeCount,pPrivateKeyTemplate,
- usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
-}
-
-
-/* FC_WrapKey wraps (i.e., encrypts) a key. */
- CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pusWrappedKeyLen) {
- PK11_FIPSCHECK();
- return NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
- pusWrappedKeyLen);
-}
-
-
-/* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
- CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- CK_BBOOL *boolptr;
-
- PK11_FIPSCHECK();
-
- /* all secret keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
- usAttributeCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- return NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
- usWrappedKeyLen,pTemplate,usAttributeCount,phKey);
-}
-
-
-/* FC_DeriveKey derives a key from a base key, creating a new key object. */
- CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- CK_BBOOL *boolptr;
-
- PK11_FIPSCHECK();
-
- /* all secret keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
- usAttributeCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- return NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
- usAttributeCount, phKey);
-}
-
-/*
- **************************** Radom Functions: ************************
- */
-
-/* FC_SeedRandom mixes additional seed material into the token's random number
- * generator. */
- CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
- CK_ULONG usSeedLen) {
- CK_RV crv;
-
- PK11_FIPSFATALCHECK();
- crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
- if (crv != CKR_OK) {
- fatalError = PR_TRUE;
- }
- return crv;
-}
-
-
-/* FC_GenerateRandom generates random data. */
- CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen) {
- CK_RV crv;
-
- PK11_FIPSFATALCHECK();
- crv = NSC_GenerateRandom(hSession,pRandomData,usRandomLen);
- if (crv != CKR_OK) {
- fatalError = PR_TRUE;
- }
- return crv;
-}
-
-
-/* FC_GetFunctionStatus obtains an updated status of a function running
- * in parallel with an application. */
- CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
- PK11_FIPSCHECK();
- return NSC_GetFunctionStatus(hSession);
-}
-
-
-/* FC_CancelFunction cancels a function running in parallel */
- CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) {
- PK11_FIPSCHECK();
- return NSC_CancelFunction(hSession);
-}
-
-/*
- **************************** Version 1.1 Functions: ************************
- */
-
-/* FC_GetOperationState saves the state of the cryptographic
- *operation in a session. */
-CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) {
- PK11_FIPSFATALCHECK();
- return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen);
-}
-
-
-/* FC_SetOperationState restores the state of the cryptographic operation
- * in a session. */
-CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) {
- PK11_FIPSFATALCHECK();
- return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen,
- hEncryptionKey,hAuthenticationKey);
-}
-
-/* FC_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
- PK11_FIPSCHECK();
- return NSC_FindObjectsFinal(hSession);
-}
-
-
-/* Dual-function cryptographic operations */
-
-/* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption
- * operation. */
-CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen) {
- PK11_FIPSCHECK();
- return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
- pulEncryptedPartLen);
-}
-
-
-/* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting
- * operation. */
-CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) {
-
- PK11_FIPSCHECK();
- return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen,
- pPart,pulPartLen);
-}
-
-/* FC_SignEncryptUpdate continues a multiple-part signing and encryption
- * operation. */
-CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen) {
-
- PK11_FIPSCHECK();
- return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
- pulEncryptedPartLen);
-}
-
-/* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify
- * operation. */
-CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) {
-
- PK11_FIPSCHECK();
- return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
- pData,pulDataLen);
-}
-
-
-/* FC_DigestKey continues a multi-part message-digesting operation,
- * by digesting the value of a secret key as part of the data already digested.
- */
-CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
- PK11_FIPSCHECK();
- return NSC_DigestKey(hSession,hKey);
-}
-
-
-CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved)
-{
- return NSC_WaitForSlotEvent(flags, pSlot, pReserved);
-}
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
deleted file mode 100644
index e224c18d9..000000000
--- a/security/nss/lib/softoken/keydb.c
+++ /dev/null
@@ -1,2308 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * Private Key Database code
- *
- * $Id$
- */
-
-#include "keylow.h"
-#include "keydbt.h"
-#include "seccomon.h"
-#include "sechash.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "blapi.h"
-#include "secitem.h"
-#include "cert.h"
-#include "mcom_db.h"
-#include "secpkcs5.h"
-#include "secerr.h"
-
-#include "private.h"
-
-/*
- * Record keys for keydb
- */
-#define SALT_STRING "global-salt"
-#define VERSION_STRING "Version"
-#define KEYDB_PW_CHECK_STRING "password-check"
-#define KEYDB_PW_CHECK_LEN 14
-
-/* Size of the global salt for key database */
-#define SALT_LENGTH 16
-
-/* ASN1 Templates for new decoder/encoder */
-/*
- * Attribute value for PKCS8 entries (static?)
- */
-const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECKEYAttribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
- { SEC_ASN1_SET_OF, offsetof(SECKEYAttribute, attrValue),
- SEC_AnyTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
-};
-
-const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(SECKEYPrivateKeyInfo,version) },
- { SEC_ASN1_INLINE,
- offsetof(SECKEYPrivateKeyInfo,algorithm),
- SECOID_AlgorithmIDTemplate },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SECKEYPrivateKeyInfo,privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SECKEYPrivateKeyInfo,attributes),
- SECKEY_SetOfAttributeTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
-};
-
-const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
- { SEC_ASN1_INLINE,
- offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm),
- SECOID_AlgorithmIDTemplate },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
-};
-
-/* ====== Default key databse encryption algorithm ====== */
-
-static SECOidTag defaultKeyDBAlg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
-
-/*
- * Default algorithm for encrypting data in the key database
- */
-SECOidTag
-SECKEY_GetDefaultKeyDBAlg(void)
-{
- return(defaultKeyDBAlg);
-}
-
-void
-SECKEY_SetDefaultKeyDBAlg(SECOidTag alg)
-{
- defaultKeyDBAlg = alg;
-
- return;
-}
-
-static void
-sec_destroy_dbkey(SECKEYDBKey *dbkey)
-{
- if ( dbkey && dbkey->arena ) {
- PORT_FreeArena(dbkey->arena, PR_FALSE);
- }
-}
-
-static void
-free_dbt(DBT *dbt)
-{
- if ( dbt ) {
- PORT_Free(dbt->data);
- PORT_Free(dbt);
- }
-
- return;
-}
-
-/*
- * format of key database entries for version 3 of database:
- * byte offset field
- * ----------- -----
- * 0 version
- * 1 salt-len
- * 2 nn-len
- * 3.. salt-data
- * ... nickname
- * ... encrypted-key-data
- */
-static DBT *
-encode_dbkey(SECKEYDBKey *dbkey)
-{
- DBT *bufitem = NULL;
- unsigned char *buf;
- int nnlen;
- char *nn;
-
- bufitem = (DBT *)PORT_ZAlloc(sizeof(DBT));
- if ( bufitem == NULL ) {
- goto loser;
- }
-
- if ( dbkey->nickname ) {
- nn = dbkey->nickname;
- nnlen = PORT_Strlen(nn) + 1;
- } else {
- nn = "";
- nnlen = 1;
- }
-
- /* compute the length of the record */
- /* 1 + 1 + 1 == version number header + salt length + nn len */
- bufitem->size = dbkey->salt.len + nnlen + dbkey->derPK.len + 1 + 1 + 1;
-
- bufitem->data = (void *)PORT_ZAlloc(bufitem->size);
- if ( bufitem->data == NULL ) {
- goto loser;
- }
-
- buf = (unsigned char *)bufitem->data;
-
- /* set version number */
- buf[0] = PRIVATE_KEY_DB_FILE_VERSION;
-
- /* set length of salt */
- PORT_Assert(dbkey->salt.len < 256);
- buf[1] = dbkey->salt.len;
-
- /* set length of nickname */
- PORT_Assert(nnlen < 256);
- buf[2] = nnlen;
-
- /* copy salt */
- PORT_Memcpy(&buf[3], dbkey->salt.data, dbkey->salt.len);
-
- /* copy nickname */
- PORT_Memcpy(&buf[3 + dbkey->salt.len], nn, nnlen);
-
- /* copy encrypted key */
- PORT_Memcpy(&buf[3 + dbkey->salt.len + nnlen], dbkey->derPK.data,
- dbkey->derPK.len);
-
- return(bufitem);
-
-loser:
- if ( bufitem ) {
- free_dbt(bufitem);
- }
-
- return(NULL);
-}
-
-static SECKEYDBKey *
-decode_dbkey(DBT *bufitem, int expectedVersion)
-{
- SECKEYDBKey *dbkey;
- PLArenaPool *arena = NULL;
- unsigned char *buf;
- int version;
- int keyoff;
- int nnlen;
- int saltoff;
-
- buf = (unsigned char *)bufitem->data;
-
- version = buf[0];
-
- if ( version != expectedVersion ) {
- goto loser;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- dbkey = (SECKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYDBKey));
- if ( dbkey == NULL ) {
- goto loser;
- }
-
- dbkey->arena = arena;
- dbkey->salt.data = NULL;
- dbkey->derPK.data = NULL;
-
- dbkey->salt.len = buf[1];
- dbkey->salt.data = (unsigned char *)PORT_ArenaZAlloc(arena, dbkey->salt.len);
- if ( dbkey->salt.data == NULL ) {
- goto loser;
- }
-
- saltoff = 2;
- keyoff = 2 + dbkey->salt.len;
-
- if ( expectedVersion == PRIVATE_KEY_DB_FILE_VERSION ) {
- nnlen = buf[2];
- if ( nnlen ) {
- dbkey->nickname = (char *)PORT_ArenaZAlloc(arena, nnlen + 1);
- if ( dbkey->nickname ) {
- PORT_Memcpy(dbkey->nickname, &buf[keyoff+1], nnlen);
- }
- }
- keyoff += ( nnlen + 1 );
- saltoff = 3;
- }
-
- PORT_Memcpy(dbkey->salt.data, &buf[saltoff], dbkey->salt.len);
-
- dbkey->derPK.len = bufitem->size - keyoff;
- dbkey->derPK.data = (unsigned char *)PORT_ArenaZAlloc(arena,dbkey->derPK.len);
- if ( dbkey->derPK.data == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(dbkey->derPK.data, &buf[keyoff], dbkey->derPK.len);
-
- return(dbkey);
-
-loser:
-
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-static SECKEYDBKey *
-get_dbkey(SECKEYKeyDBHandle *handle, DBT *index)
-{
- SECKEYDBKey *dbkey;
- DBT entry;
- SECStatus rv;
-
- /* get it from the database */
- rv = (SECStatus)(* handle->db->get)(handle->db, index, &entry, 0);
- if ( rv ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return NULL;
- }
-
- /* set up dbkey struct */
-
- dbkey = decode_dbkey(&entry, PRIVATE_KEY_DB_FILE_VERSION);
-
- return(dbkey);
-}
-
-static SECStatus
-put_dbkey(SECKEYKeyDBHandle *handle, DBT *index, SECKEYDBKey *dbkey, PRBool update)
-{
- DBT *keydata = NULL;
- int status;
-
- keydata = encode_dbkey(dbkey);
- if ( keydata == NULL ) {
- goto loser;
- }
-
- /* put it in the database */
- if ( update ) {
- status = (* handle->db->put)(handle->db, index, keydata, 0);
- } else {
- status = (* handle->db->put)(handle->db, index, keydata,
- R_NOOVERWRITE);
- }
-
- if ( status ) {
- goto loser;
- }
-
- /* sync the database */
- status = (* handle->db->sync)(handle->db, 0);
- if ( status ) {
- goto loser;
- }
-
- free_dbt(keydata);
- return(SECSuccess);
-
-loser:
- if ( keydata ) {
- free_dbt(keydata);
- }
-
- return(SECFailure);
-}
-
-SECStatus
-SECKEY_TraverseKeys(SECKEYKeyDBHandle *handle,
- SECStatus (* keyfunc)(DBT *k, DBT *d, void *pdata),
- void *udata )
-{
- DBT data;
- DBT key;
- SECStatus status;
- int rv;
-
- if (handle == NULL) {
- return(SECFailure);
- }
-
- rv = (* handle->db->seq)(handle->db, &key, &data, R_FIRST);
- if ( rv ) {
- return(SECFailure);
- }
-
- do {
- /* skip version record */
- if ( data.size > 1 ) {
- if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) {
- if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) {
- continue;
- }
- }
-
- /* skip password check */
- if ( key.size == KEYDB_PW_CHECK_LEN ) {
- if ( PORT_Memcmp(key.data, KEYDB_PW_CHECK_STRING,
- KEYDB_PW_CHECK_LEN) == 0 ) {
- continue;
- }
- }
-
- status = (* keyfunc)(&key, &data, udata);
- if (status != SECSuccess) {
- return(status);
- }
- }
- } while ( (* handle->db->seq)(handle->db, &key, &data, R_NEXT) == 0 );
-
- return(SECSuccess);
-}
-
-typedef struct keyNode {
- struct keyNode *next;
- DBT key;
-} keyNode;
-
-typedef struct {
- PLArenaPool *arena;
- keyNode *head;
-} keyList;
-
-static SECStatus
-sec_add_key_to_list(DBT *key, DBT *data, void *arg)
-{
- keyList *keylist;
- keyNode *node;
- void *keydata;
-
- keylist = (keyList *)arg;
-
- /* allocate the node struct */
- node = (keyNode*)PORT_ArenaZAlloc(keylist->arena, sizeof(keyNode));
- if ( node == NULL ) {
- return(SECFailure);
- }
-
- /* allocate room for key data */
- keydata = PORT_ArenaZAlloc(keylist->arena, key->size);
- if ( keydata == NULL ) {
- return(SECFailure);
- }
-
- /* link node into list */
- node->next = keylist->head;
- keylist->head = node;
-
- /* copy key into node */
- PORT_Memcpy(keydata, key->data, key->size);
- node->key.size = key->size;
- node->key.data = keydata;
-
- return(SECSuccess);
-}
-
-static SECItem *
-decodeKeyDBGlobalSalt(DBT *saltData)
-{
- SECItem *saltitem;
-
- saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if ( saltitem == NULL ) {
- return(NULL);
- }
-
- saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size);
- if ( saltitem->data == NULL ) {
- PORT_Free(saltitem);
- return(NULL);
- }
-
- saltitem->len = saltData->size;
- PORT_Memcpy(saltitem->data, saltData->data, saltitem->len);
-
- return(saltitem);
-}
-
-static SECItem *
-GetKeyDBGlobalSalt(SECKEYKeyDBHandle *handle)
-{
- DBT saltKey;
- DBT saltData;
- int ret;
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- ret = (* handle->db->get)(handle->db, &saltKey, &saltData, 0);
- if ( ret ) {
- return(NULL);
- }
-
- return(decodeKeyDBGlobalSalt(&saltData));
-}
-
-static SECStatus
-makeGlobalVersion(SECKEYKeyDBHandle *handle)
-{
- unsigned char version;
- DBT versionData;
- DBT versionKey;
- int status;
-
- version = PRIVATE_KEY_DB_FILE_VERSION;
- versionData.data = &version;
- versionData.size = 1;
- versionKey.data = VERSION_STRING;
- versionKey.size = sizeof(VERSION_STRING)-1;
-
- /* put version string into the database now */
- status = (* handle->db->put)(handle->db, &versionKey, &versionData, 0);
- if ( status ) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-
-static SECStatus
-makeGlobalSalt(SECKEYKeyDBHandle *handle)
-{
- DBT saltKey;
- DBT saltData;
- unsigned char saltbuf[16];
- int status;
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- saltData.data = (void *)saltbuf;
- saltData.size = sizeof(saltbuf);
- RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
-
- /* put global salt into the database now */
- status = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
- if ( status ) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-static char *
-keyDBFilenameCallback(void *arg, int dbVersion)
-{
- return((char *)arg);
-}
-
-SECKEYKeyDBHandle *
-SECKEY_OpenKeyDBFilename(char *dbname, PRBool readOnly)
-{
- return(SECKEY_OpenKeyDB(readOnly, keyDBFilenameCallback,
- (void *)dbname));
-}
-
-SECKEYKeyDBHandle *
-SECKEY_OpenKeyDB(PRBool readOnly, SECKEYDBNameFunc namecb, void *cbarg)
-{
- SECKEYKeyDBHandle *handle;
- DBT versionKey;
- DBT versionData;
- int rv;
- int openflags;
- char *dbname = NULL;
- PRBool updated = PR_FALSE;
-
- handle = (SECKEYKeyDBHandle *)PORT_ZAlloc (sizeof(SECKEYKeyDBHandle));
- if (handle == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- versionKey.data = VERSION_STRING;
- versionKey.size = sizeof(VERSION_STRING)-1;
-
- if ( readOnly ) {
- openflags = O_RDONLY;
- } else {
- openflags = O_RDWR;
- }
-
- dbname = (*namecb)(cbarg, PRIVATE_KEY_DB_FILE_VERSION);
- if ( dbname == NULL ) {
- goto loser;
- }
-
- handle->db = dbopen( dbname, openflags, 0600, DB_HASH, 0 );
-
- /* check for correct version number */
- if (handle->db != NULL) {
- /* lookup version string in database */
- rv = (* handle->db->get)( handle->db, &versionKey, &versionData, 0 );
-
- /* error accessing the database */
- if ( rv < 0 ) {
- goto loser;
- }
-
- if ( rv == 1 ) {
- /* no version number record, reset the database */
- (* handle->db->close)( handle->db );
- handle->db = NULL;
-
- goto newdb;
-
- }
-
- handle->version = *( (unsigned char *)versionData.data);
-
- if (handle->version != PRIVATE_KEY_DB_FILE_VERSION ) {
- /* bogus version number record, reset the database */
- (* handle->db->close)( handle->db );
- handle->db = NULL;
-
- goto newdb;
- }
-
- }
-
-newdb:
-
- /* if first open fails, try to create a new DB */
- if ( handle->db == NULL ) {
- if ( readOnly ) {
- goto loser;
- }
-
- handle->db = dbopen( dbname,
- O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
-
- PORT_Free( dbname );
- dbname = NULL;
-
- /* if create fails then we lose */
- if ( handle->db == NULL ) {
- goto loser;
- }
-
- rv = makeGlobalVersion(handle);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /*
- * try to update from v2 db
- */
- dbname = (*namecb)(cbarg, 2);
- if ( dbname != NULL ) {
- handle->updatedb = dbopen( dbname, O_RDONLY, 0600, DB_HASH, 0 );
-
- if ( handle->updatedb ) {
-
-
- /*
- * Try to update the db using a null password. If the db
- * doesn't have a password, then this will work. If it does
- * have a password, then this will fail and we will do the
- * update later
- */
- rv = SECKEY_UpdateKeyDBPass1(handle);
- if ( rv == SECSuccess ) {
- updated = PR_TRUE;
- }
- }
-
- PORT_Free( dbname );
- dbname = NULL;
- }
-
- /* we are using the old salt if we updated from an old db */
- if ( ! updated ) {
- rv = makeGlobalSalt(handle);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- /* sync the database */
- rv = (* handle->db->sync)(handle->db, 0);
- if ( rv ) {
- goto loser;
- }
- }
-
- handle->global_salt = GetKeyDBGlobalSalt(handle);
- return handle;
-
-loser:
-
- if ( dbname )
- PORT_Free( dbname );
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
-
- if ( handle->db ) {
- (* handle->db->close)(handle->db);
- }
- if ( handle->updatedb ) {
- (* handle->updatedb->close)(handle->updatedb);
- }
- PORT_Free(handle);
- return NULL;
-}
-
-/*
- * Close the database
- */
-void
-SECKEY_CloseKeyDB(SECKEYKeyDBHandle *handle)
-{
- if (handle != NULL) {
- if (handle == SECKEY_GetDefaultKeyDB()) {
- SECKEY_SetDefaultKeyDB(NULL);
- }
- if (handle->db != NULL) {
- (* handle->db->close)(handle->db);
- }
- PORT_Free(handle);
- }
-}
-
-/* Get the key database version */
-int
-SECKEY_GetKeyDBVersion(SECKEYKeyDBHandle *handle)
-{
- PORT_Assert(handle != NULL);
-
- return handle->version;
-}
-
-/*
- * Allow use of default key database, so that apps (such as mozilla) do
- * not have to pass the handle all over the place.
- */
-
-static SECKEYKeyDBHandle *sec_default_key_db = NULL;
-
-void
-SECKEY_SetDefaultKeyDB(SECKEYKeyDBHandle *handle)
-{
- sec_default_key_db = handle;
-}
-
-SECKEYKeyDBHandle *
-SECKEY_GetDefaultKeyDB(void)
-{
- return sec_default_key_db;
-}
-
-/*
- * Delete a private key that was stored in the database
- */
-SECStatus
-SECKEY_DeleteKey(SECKEYKeyDBHandle *handle, SECItem *pubkey)
-{
- DBT namekey;
- int rv;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- /* set up db key and data */
- namekey.data = pubkey->data;
- namekey.size = pubkey->len;
-
- /* delete it from the database */
- rv = (* handle->db->del)(handle->db, &namekey, 0);
- if ( rv ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- /* sync the database */
- rv = (* handle->db->sync)(handle->db, 0);
- if ( rv ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-/*
- * Store a key in the database, indexed by its public key modulus.(value!)
- */
-SECStatus
-SECKEY_StoreKeyByPublicKey(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SECKEYGetPasswordKey f, void *arg)
-{
- return SECKEY_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData, nickname,
- f, arg, SECKEY_GetDefaultKeyDBAlg());
-}
-
-/* see if the public key for this cert is in the database filed
- * by modulus
- */
-SECStatus
-SECKEY_KeyForCertExists(SECKEYKeyDBHandle *handle, CERTCertificate *cert)
-{
- SECKEYPublicKey *pubkey = NULL;
- DBT namekey;
- DBT dummy;
- int status;
-
- /* get cert's public key */
- pubkey = CERT_ExtractPublicKey(cert);
- if ( pubkey == NULL ) {
- return SECFailure;
- }
-
- /* TNH - make key from SECKEYPublicKey */
- switch (pubkey->keyType) {
- case rsaKey:
- namekey.data = pubkey->u.rsa.modulus.data;
- namekey.size = pubkey->u.rsa.modulus.len;
- break;
- case dsaKey:
- namekey.data = pubkey->u.dsa.publicValue.data;
- namekey.size = pubkey->u.dsa.publicValue.len;
- break;
- case dhKey:
- namekey.data = pubkey->u.dh.publicValue.data;
- namekey.size = pubkey->u.dh.publicValue.len;
- break;
- default:
- /* XXX We don't do Fortezza or DH yet. */
- return SECFailure;
- }
-
- status = (* handle->db->get)(handle->db, &namekey, &dummy, 0);
- SECKEY_DestroyPublicKey(pubkey);
- if ( status ) {
- /* TNH - should this really set an error? */
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-/*
- * find the private key for a cert
- */
-SECKEYLowPrivateKey *
-SECKEY_FindKeyByCert(SECKEYKeyDBHandle *handle, CERTCertificate *cert,
- SECKEYGetPasswordKey f, void *arg)
-{
- SECKEYPublicKey *pubkey = NULL;
- SECItem *keyItem;
- SECKEYLowPrivateKey *privKey = NULL;
-
- /* get cert's public key */
- pubkey = CERT_ExtractPublicKey(cert);
- if ( !pubkey ) {
- goto loser;
- }
-
- /* TNH - make record key from SECKEYPublicKey (again) */
- switch (pubkey->keyType) {
- case rsaKey:
- keyItem = &pubkey->u.rsa.modulus;
- break;
- case dsaKey:
- keyItem = &pubkey->u.dsa.publicValue;
- break;
- case dhKey:
- keyItem = &pubkey->u.dh.publicValue;
- break;
- /* fortezza an NULL keys are not stored in the data base */
- case fortezzaKey:
- case nullKey:
- goto loser;
- }
-
- privKey = SECKEY_FindKeyByPublicKey(handle, keyItem, f, arg);
-
- /* success falls through */
-loser:
- SECKEY_DestroyPublicKey(pubkey);
- return(privKey);
-}
-
-/*
- * check to see if the user has a password
- */
-SECStatus
-SECKEY_HasKeyDBPassword(SECKEYKeyDBHandle *handle)
-{
- DBT checkkey, checkdata;
- int rv;
-
- if (handle == NULL) {
- return(SECFailure);
- }
-
- checkkey.data = KEYDB_PW_CHECK_STRING;
- checkkey.size = KEYDB_PW_CHECK_LEN;
-
- rv = (* handle->db->get)(handle->db, &checkkey, &checkdata, 0 );
- if ( rv ) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-/*
- * Set up the password checker in the key database.
- * This is done by encrypting a known plaintext with the user's key.
- */
-SECStatus
-SECKEY_SetKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
-{
- return SECKEY_SetKeyDBPasswordAlg(handle, pwitem,
- SECKEY_GetDefaultKeyDBAlg());
-}
-
-/*
- * Re-encrypt the entire key database with a new password.
- * NOTE: This really should create a new database rather than doing it
- * in place in the original
- */
-SECStatus
-SECKEY_ChangeKeyDBPassword(SECKEYKeyDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem)
-{
- return SECKEY_ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem,
- SECKEY_GetDefaultKeyDBAlg());
-}
-
-static SECStatus
-HashPassword(unsigned char *hashresult, char *pw, SECItem *salt)
-{
- SHA1Context *cx;
- unsigned int outlen;
- cx = SHA1_NewContext();
- if ( cx == NULL ) {
- return(SECFailure);
- }
-
- SHA1_Begin(cx);
- if ( ( salt != NULL ) && ( salt->data != NULL ) ) {
- SHA1_Update(cx, salt->data, salt->len);
- }
-
- SHA1_Update(cx, (unsigned char *)pw, PORT_Strlen(pw));
- SHA1_End(cx, hashresult, &outlen, SHA1_LENGTH);
-
- SHA1_DestroyContext(cx, PR_TRUE);
-
- return(SECSuccess);
-}
-
-SECItem *
-SECKEY_HashPassword(char *pw, SECItem *salt)
-{
- SECItem *pwitem;
- SECStatus rv;
-
- pwitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if ( pwitem == NULL ) {
- return(NULL);
- }
- pwitem->len = SHA1_LENGTH;
- pwitem->data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
- if ( pwitem->data == NULL ) {
- PORT_Free(pwitem);
- return(NULL);
- }
- if ( pw ) {
- rv = HashPassword(pwitem->data, pw, salt);
- if ( rv != SECSuccess ) {
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
- return(NULL);
- }
- }
-
- return(pwitem);
-}
-
-/* Derive the actual password value for the database from a pw string */
-SECItem *
-SECKEY_DeriveKeyDBPassword(SECKEYKeyDBHandle *keydb, char *pw)
-{
- PORT_Assert(keydb != NULL);
- PORT_Assert(pw != NULL);
- if (keydb == NULL || pw == NULL) return(NULL);
-
- return SECKEY_HashPassword(pw, keydb->global_salt);
-}
-
-#if 0
-/* Appears obsolete - TNH */
-/* get the algorithm with which a private key
- * is encrypted.
- */
-SECOidTag
-seckey_get_private_key_algorithm(SECKEYKeyDBHandle *keydb, DBT *index)
-{
- SECKEYDBKey *dbkey = NULL;
- SECOidTag algorithm = SEC_OID_UNKNOWN;
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- PLArenaPool *poolp = NULL;
- SECStatus rv;
-
- poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(poolp == NULL)
- return (SECOidTag)SECFailure; /* TNH - this is bad */
-
- dbkey = get_dbkey(keydb, index);
- if(dbkey == NULL)
- return (SECOidTag)SECFailure;
-
- epki = (SECKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(poolp,
- sizeof(SECKEYEncryptedPrivateKeyInfo));
- if(epki == NULL)
- goto loser;
- rv = SEC_ASN1DecodeItem(poolp, epki,
- SECKEY_EncryptedPrivateKeyInfoTemplate, &dbkey->derPK);
- if(rv == SECFailure)
- goto loser;
-
- algorithm = SECOID_GetAlgorithmTag(&epki->algorithm);
-
- /* let success fall through */
-loser:
- if(poolp != NULL)
- PORT_FreeArena(poolp, PR_TRUE);\
- if(dbkey != NULL)
- sec_destroy_dbkey(dbkey);
-
- return algorithm;
-}
-#endif
-
-/*
- * Derive an RC4 key from a password key and a salt. This
- * was the method to used to encrypt keys in the version 2?
- * database
- */
-SECItem *
-seckey_create_rc4_key(SECItem *pwitem, SECItem *salt)
-{
- MD5Context *md5 = NULL;
- unsigned int part;
- SECStatus rv = SECFailure;
- SECItem *key = NULL;
-
- key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(key != NULL)
- {
- key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- MD5_LENGTH);
- key->len = MD5_LENGTH;
- if(key->data != NULL)
- {
- md5 = MD5_NewContext();
- if ( md5 != NULL )
- {
- MD5_Begin(md5);
- MD5_Update(md5, salt->data, salt->len);
- MD5_Update(md5, pwitem->data, pwitem->len);
- MD5_End(md5, key->data, &part, MD5_LENGTH);
- MD5_DestroyContext(md5, PR_TRUE);
- rv = SECSuccess;
- }
- }
-
- if(rv != SECSuccess)
- {
- SECITEM_FreeItem(key, PR_TRUE);
- key = NULL;
- }
- }
-
- return key;
-}
-
-SECItem *
-seckey_create_rc4_salt(void)
-{
- SECItem *salt = NULL;
- SECStatus rv = SECFailure;
-
- salt = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(salt == NULL)
- return NULL;
-
- salt->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- SALT_LENGTH);
- if(salt->data != NULL)
- {
- salt->len = SALT_LENGTH;
- RNG_GenerateGlobalRandomBytes(salt->data, salt->len);
- rv = SECSuccess;
- }
-
- if(rv == SECFailure)
- {
- SECITEM_FreeItem(salt, PR_TRUE);
- salt = NULL;
- }
-
- return salt;
-}
-
-SECItem *
-seckey_rc4_cipher(SECItem *key, SECItem *src, PRBool encrypt)
-{
- SECItem *dest = NULL;
- RC4Context *ctxt = NULL;
- SECStatus rv = SECFailure;
-
- if((key == NULL) || (src == NULL))
- return NULL;
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest == NULL)
- return NULL;
-
- dest->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- (src->len + 64)); /* TNH - padding? */
- if(dest->data != NULL)
- {
- ctxt = RC4_CreateContext(key->data, key->len);
- if(ctxt != NULL)
- {
- if(encrypt == PR_TRUE)
- rv = RC4_Encrypt(ctxt, dest->data, &dest->len,
- src->len + 64, src->data, src->len);
- else
- rv = RC4_Decrypt(ctxt, dest->data, &dest->len,
- src->len + 64, src->data, src->len);
- RC4_DestroyContext(ctxt, PR_TRUE);
- }
- }
-
- if(rv == SECFailure)
- if(dest != NULL)
- {
- SECITEM_FreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- return dest;
-}
-
-/* TNH - keydb is unused */
-/* TNH - the pwitem should be the derived key for RC4 */
-SECKEYEncryptedPrivateKeyInfo *
-seckey_encrypt_private_key(
- SECKEYLowPrivateKey *pk, SECItem *pwitem, SECKEYKeyDBHandle *keydb,
- SECOidTag algorithm)
-{
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- SECKEYPrivateKeyInfo *pki = NULL;
- SECStatus rv = SECFailure;
- SECAlgorithmID *algid = NULL;
- PLArenaPool *temparena = NULL, *permarena = NULL;
- SECItem *key = NULL, *salt = NULL, *der_item = NULL;
- SECItem *dummy = NULL, *dest = NULL;
-
- permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(permarena == NULL)
- return NULL;
-
- temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(temparena == NULL)
- goto loser;
-
- /* allocate structures */
- epki = (SECKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(permarena,
- sizeof(SECKEYEncryptedPrivateKeyInfo));
- pki = (SECKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(SECKEYPrivateKeyInfo));
- der_item = (SECItem *)PORT_ArenaZAlloc(temparena, sizeof(SECItem));
- if((epki == NULL) || (pki == NULL) || (der_item == NULL))
- goto loser;
-
- epki->arena = permarena;
-
- /* setup private key info */
- dummy = SEC_ASN1EncodeInteger(temparena, &(pki->version),
- SEC_PRIVATE_KEY_INFO_VERSION);
- if(dummy == NULL)
- goto loser;
-
- /* Encode the key, and set the algorithm (with params) */
- switch (pk->keyType) {
- case rsaKey:
- dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- SECKEY_RSAPrivateKeyTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
- SEC_OID_PKCS1_RSA_ENCRYPTION, 0);
- if (rv == SECFailure) {
- goto loser;
- }
-
- break;
- case dsaKey:
- dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- SECKEY_DSAPrivateKeyTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- dummy = SEC_ASN1EncodeItem(temparena, NULL, &pk->u.dsa.params,
- SECKEY_PQGParamsTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
- SEC_OID_ANSIX9_DSA_SIGNATURE, dummy);
- if (rv == SECFailure) {
- goto loser;
- }
-
- break;
- case dhKey:
- dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- SECKEY_DHPrivateKeyTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
- SEC_OID_X942_DIFFIE_HELMAN_KEY, dummy);
- if (rv == SECFailure) {
- goto loser;
- }
- break;
- default:
- /* We don't support DH or Fortezza private keys yet */
- PORT_Assert(PR_FALSE);
- break;
- }
-
- /* setup encrypted private key info */
- dummy = SEC_ASN1EncodeItem(temparena, der_item, pki,
- SECKEY_PrivateKeyInfoTemplate);
- if(dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECFailure; /* assume failure */
- switch(algorithm)
- {
- case SEC_OID_RC4:
- salt = seckey_create_rc4_salt();
- if(salt != NULL)
- {
- key = seckey_create_rc4_key(pwitem, salt);
- if(key != NULL)
- {
- dest = seckey_rc4_cipher(key, der_item, PR_TRUE);
- if(dest != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &epki->encryptedData,
- dest);
- if(rv == SECSuccess)
- rv = SECOID_SetAlgorithmID(permarena,
- &epki->algorithm, SEC_OID_RC4, salt);
- }
- }
- }
- if(dest != NULL)
- SECITEM_FreeItem(dest, PR_TRUE);
- if(key != NULL)
- SECITEM_ZfreeItem(key, PR_TRUE);
- break;
- default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm, NULL, 1);
- if(algid != NULL)
- {
- dest = SEC_PKCS5CipherData(algid, pwitem,
- der_item, PR_TRUE, NULL);
- if(dest != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &epki->encryptedData,
- dest);
- if(rv == SECSuccess)
- rv = SECOID_CopyAlgorithmID(permarena,
- &epki->algorithm, algid);
- }
- }
- if(dest != NULL)
- SECITEM_FreeItem(dest, PR_TRUE);
- if(algid != NULL)
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
- break;
- }
-
- /* let success fall through */
-loser:
-
- if(rv == SECFailure)
- {
- PORT_FreeArena(permarena, PR_TRUE);
- epki = NULL;
- }
-
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
-
- if(salt != NULL)
- SECITEM_FreeItem(salt, PR_TRUE);
-
- return epki;
-}
-
-SECStatus
-seckey_put_private_key(SECKEYKeyDBHandle *keydb, DBT *index, SECItem *pwitem,
- SECKEYLowPrivateKey *pk, char *nickname, PRBool update,
- SECOidTag algorithm)
-{
- SECKEYDBKey *dbkey = NULL;
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- PLArenaPool *temparena = NULL, *permarena = NULL;
- SECItem *dummy = NULL;
- SECItem *salt = NULL;
- SECStatus rv = SECFailure;
-
- if((keydb == NULL) || (index == NULL) || (pwitem == NULL) ||
- (pk == NULL))
- return SECFailure;
-
- permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(permarena == NULL)
- return SECFailure;
-
- dbkey = (SECKEYDBKey *)PORT_ArenaZAlloc(permarena, sizeof(SECKEYDBKey));
- if(dbkey == NULL)
- goto loser;
- dbkey->arena = permarena;
- dbkey->nickname = nickname;
-
- /* TNH - for RC4, the salt should be created here */
-
- epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm);
- if(epki == NULL)
- goto loser;
- temparena = epki->arena;
-
- /* extract salt for db key */
- switch(algorithm)
- {
- case SEC_OID_RC4:
- rv = SECITEM_CopyItem(permarena, &(dbkey->salt),
- &(epki->algorithm.parameters));
- epki->algorithm.parameters.len = 0;
- epki->algorithm.parameters.data = NULL;
- break;
- default:
- /* TNH - this should not be necessary */
- salt = SEC_PKCS5GetSalt(&epki->algorithm);
- if(salt != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt);
- SECITEM_ZfreeItem(salt, PR_TRUE);
- }
- break;
- }
-
- dummy = SEC_ASN1EncodeItem(permarena, &(dbkey->derPK), epki,
- SECKEY_EncryptedPrivateKeyInfoTemplate);
- if(dummy == NULL)
- rv = SECFailure;
- else
- rv = put_dbkey(keydb, index, dbkey, update);
-
- /* let success fall through */
-loser:
- if(rv != SECSuccess)
- if(permarena != NULL)
- PORT_FreeArena(permarena, PR_TRUE);
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
-
- return rv;
-}
-
-/*
- * Store a key in the database, indexed by its public key modulus.
- * Note that the nickname is optional. It was only used by keyutil.
- */
-SECStatus
-SECKEY_StoreKeyByPublicKeyAlg(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SECKEYGetPasswordKey f, void *arg,
- SECOidTag algorithm)
-{
- DBT namekey;
- SECItem *pwitem = NULL;
- SECStatus rv;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- /* set up db key and data */
- namekey.data = pubKeyData->data;
- namekey.size = pubKeyData->len;
-
- pwitem = (*f )(arg, handle);
- if ( pwitem == NULL ) {
- return(SECFailure);
- }
-
- /* encrypt the private key */
- rv = seckey_put_private_key(handle, &namekey, pwitem, privkey, nickname,
- PR_FALSE, algorithm);
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
-
- return(rv);
-}
-
-SECKEYLowPrivateKey *
-seckey_decrypt_private_key(SECKEYEncryptedPrivateKeyInfo *epki,
- SECItem *pwitem)
-{
- SECKEYLowPrivateKey *pk = NULL;
- SECKEYPrivateKeyInfo *pki = NULL;
- SECStatus rv = SECFailure;
- SECOidTag algorithm;
- PLArenaPool *temparena = NULL, *permarena = NULL;
- SECItem *salt = NULL, *dest = NULL, *key = NULL;
-
- if((epki == NULL) || (pwitem == NULL))
- goto loser;
-
- temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if((temparena == NULL) || (permarena == NULL))
- goto loser;
-
- /* allocate temporary items */
- pki = (SECKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(SECKEYPrivateKeyInfo));
-
- /* allocate permanent arena items */
- pk = (SECKEYLowPrivateKey *)PORT_ArenaZAlloc(permarena,
- sizeof(SECKEYLowPrivateKey));
-
- if((pk == NULL) || (pki == NULL))
- goto loser;
-
- pk->arena = permarena;
-
- algorithm = SECOID_GetAlgorithmTag(&(epki->algorithm));
- switch(algorithm)
- {
- case SEC_OID_RC4:
- salt = SECITEM_DupItem(&epki->algorithm.parameters);
- if(salt != NULL)
- {
- key = seckey_create_rc4_key(pwitem, salt);
- if(key != NULL)
- {
- dest = seckey_rc4_cipher(key, &epki->encryptedData,
- PR_FALSE);
- }
- }
- if(salt != NULL)
- SECITEM_ZfreeItem(salt, PR_TRUE);
- if(key != NULL)
- SECITEM_ZfreeItem(key, PR_TRUE);
- break;
- default:
- /* we depend on the fact that if this key was encoded with
- * DES, that the pw was also encoded with DES, so we don't have
- * to do the update here, the password code will handle it. */
- dest = SEC_PKCS5CipherData(&epki->algorithm, pwitem,
- &epki->encryptedData, PR_FALSE, NULL);
- break;
- }
-
- if(dest != NULL)
- {
- rv = SEC_ASN1DecodeItem(temparena, pki,
- SECKEY_PrivateKeyInfoTemplate, dest);
- if(rv == SECSuccess)
- {
- switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- pk->keyType = rsaKey;
- rv = SEC_ASN1DecodeItem(permarena, pk,
- SECKEY_RSAPrivateKeyTemplate,
- &pki->privateKey);
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- pk->keyType = dsaKey;
- rv = SEC_ASN1DecodeItem(permarena, pk,
- SECKEY_DSAPrivateKeyTemplate,
- &pki->privateKey);
- if (rv != SECSuccess)
- goto loser;
- rv = SEC_ASN1DecodeItem(permarena, &pk->u.dsa.params,
- SECKEY_PQGParamsTemplate,
- &pki->algorithm.parameters);
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- pk->keyType = dhKey;
- rv = SEC_ASN1DecodeItem(permarena, pk,
- SECKEY_DHPrivateKeyTemplate,
- &pki->privateKey);
- break;
- default:
- rv = SECFailure;
- break;
- }
- }
- else if(PORT_GetError() == SEC_ERROR_BAD_DER)
- {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- goto loser;
- }
- }
-
- /* let success fall through */
-loser:
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
- if(dest != NULL)
- SECITEM_ZfreeItem(dest, PR_TRUE);
-
- if(rv != SECSuccess)
- {
- if(permarena != NULL)
- PORT_FreeArena(permarena, PR_TRUE);
- pk = NULL;
- }
-
- return pk;
-}
-
-static SECKEYLowPrivateKey *
-seckey_decode_encrypted_private_key(SECKEYDBKey *dbkey, SECItem *pwitem)
-{
- SECKEYLowPrivateKey *pk = NULL;
- SECKEYEncryptedPrivateKeyInfo *epki;
- PLArenaPool *temparena = NULL;
- SECStatus rv;
- SECOidTag algorithm;
-
- if( ( dbkey == NULL ) || ( pwitem == NULL ) ) {
- return NULL;
- }
-
- temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(temparena == NULL) {
- return NULL;
- }
-
- epki = (SECKEYEncryptedPrivateKeyInfo *)
- PORT_ArenaZAlloc(temparena, sizeof(SECKEYEncryptedPrivateKeyInfo));
-
- if(epki == NULL) {
- goto loser;
- }
-
- rv = SEC_ASN1DecodeItem(temparena, epki,
- SECKEY_EncryptedPrivateKeyInfoTemplate,
- &(dbkey->derPK));
- if(rv != SECSuccess) {
- goto loser;
- }
-
- algorithm = SECOID_GetAlgorithmTag(&(epki->algorithm));
- switch(algorithm)
- {
- case SEC_OID_RC4:
- /* TNH - this code should derive the actual RC4 key from salt and
- pwitem */
- rv = SECITEM_CopyItem(temparena, &(epki->algorithm.parameters),
- &(dbkey->salt));
- break;
- default:
- break;
- }
-
- pk = seckey_decrypt_private_key(epki, pwitem);
-
- /* let success fall through */
-loser:
-
- PORT_FreeArena(temparena, PR_TRUE);
- return pk;
-}
-
-SECKEYLowPrivateKey *
-seckey_get_private_key(SECKEYKeyDBHandle *keydb, DBT *index, char **nickname,
- SECItem *pwitem)
-{
- SECKEYDBKey *dbkey = NULL;
- SECKEYLowPrivateKey *pk = NULL;
-
- if( ( keydb == NULL ) || ( index == NULL ) || ( pwitem == NULL ) ) {
- return NULL;
- }
-
- dbkey = get_dbkey(keydb, index);
- if(dbkey == NULL) {
- goto loser;
- }
-
- if ( nickname ) {
- if ( dbkey->nickname && ( dbkey->nickname[0] != 0 ) ) {
- *nickname = PORT_Strdup(dbkey->nickname);
- } else {
- *nickname = NULL;
- }
- }
-
- pk = seckey_decode_encrypted_private_key(dbkey, pwitem);
-
- /* let success fall through */
-loser:
-
- if ( dbkey != NULL ) {
- sec_destroy_dbkey(dbkey);
- }
-
- return pk;
-}
-
-/*
- * used by pkcs11 to import keys into it's object format... In the future
- * we really need a better way to tie in...
- */
-SECKEYLowPrivateKey *
-SECKEY_DecryptKey(DBT *key, SECItem *pwitem,
- SECKEYKeyDBHandle *handle) {
- return seckey_get_private_key(handle,key,NULL,pwitem);
-}
-
-/*
- * Find a key in the database, indexed by its public key modulus
- * This is used to find keys that have been stored before their
- * certificate arrives. Once the certificate arrives the key
- * is looked up by the public modulus in the certificate, and the
- * re-stored by its nickname.
- */
-SECKEYLowPrivateKey *
-SECKEY_FindKeyByPublicKey(SECKEYKeyDBHandle *handle, SECItem *modulus,
- SECKEYGetPasswordKey f, void *arg)
-{
- DBT namekey;
- SECKEYLowPrivateKey *pk = NULL;
- SECItem *pwitem = NULL;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return NULL;
- }
-
- /* set up db key */
- namekey.data = modulus->data;
- namekey.size = modulus->len;
-
- pwitem = (*f )(arg, handle);
- if ( pwitem == NULL ) {
- return(NULL);
- }
-
- pk = seckey_get_private_key(handle, &namekey, NULL, pwitem);
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
-
- /* no need to free dbkey, since its on the stack, and the data it
- * points to is owned by the database
- */
- return(pk);
-}
-
-/* ===== ENCODING ROUTINES ===== */
-
-static SECStatus
-encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
- SECItem *encCheck)
-{
- SECOidData *oidData;
- SECStatus rv;
-
- oidData = SECOID_FindOIDByTag(alg);
- if ( oidData == NULL ) {
- rv = SECFailure;
- goto loser;
- }
-
- entry->len = 1 + oidData->oid.len + encCheck->len;
- if ( arena ) {
- entry->data = (unsigned char *)PORT_ArenaAlloc(arena, entry->len);
- } else {
- entry->data = (unsigned char *)PORT_Alloc(entry->len);
- }
-
- if ( entry->data == NULL ) {
- goto loser;
- }
-
- /* first length of oid */
- entry->data[0] = (unsigned char)oidData->oid.len;
- /* next oid itself */
- PORT_Memcpy(&entry->data[1], oidData->oid.data, oidData->oid.len);
- /* finally the encrypted check string */
- PORT_Memcpy(&entry->data[1+oidData->oid.len], encCheck->data,
- encCheck->len);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Set up the password checker in the key database.
- * This is done by encrypting a known plaintext with the user's key.
- */
-SECStatus
-SECKEY_SetKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
- SECItem *pwitem, SECOidTag algorithm)
-{
- DBT checkkey;
- SECAlgorithmID *algid = NULL;
- SECStatus rv = SECFailure;
- SECKEYDBKey *dbkey = NULL;
- PLArenaPool *arena;
- SECItem *key = NULL, *salt = NULL;
- SECItem *dest = NULL, test_key;
-
- if (handle == NULL) {
- return(SECFailure);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- rv = SECFailure;
- goto loser;
- }
-
- dbkey = (SECKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYDBKey));
- if ( dbkey == NULL ) {
- rv = SECFailure;
- goto loser;
- }
-
- dbkey->arena = arena;
-
- /* encrypt key */
- checkkey.data = test_key.data = (unsigned char *)KEYDB_PW_CHECK_STRING;
- checkkey.size = test_key.len = KEYDB_PW_CHECK_LEN;
-
- salt = seckey_create_rc4_salt();
- if(salt == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- switch(algorithm)
- {
- case SEC_OID_RC4:
- key = seckey_create_rc4_key(pwitem, salt);
- if(key != NULL)
- {
- dest = seckey_rc4_cipher(key, &test_key, PR_TRUE);
- SECITEM_FreeItem(key, PR_TRUE);
- }
- break;
- default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, 1);
- if(algid != NULL)
- dest = SEC_PKCS5CipherData(algid, pwitem, &test_key,
- PR_TRUE, NULL);
- break;
- }
-
- if(dest != NULL)
- {
- rv = SECITEM_CopyItem(arena, &dbkey->salt, salt);
- if(rv == SECFailure)
- goto loser;
-
- rv = encodePWCheckEntry(arena, &dbkey->derPK, algorithm, dest);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
- } else {
- rv = SECFailure;
- }
-
- /* let success fall through */
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- if ( dest != NULL ) {
- SECITEM_ZfreeItem(dest, PR_TRUE);
- }
-
- if ( salt != NULL ) {
- SECITEM_ZfreeItem(salt, PR_TRUE);
- }
-
- return(rv);
-}
-
-/*
- * check to see if the user has typed the right password
- */
-SECStatus
-SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
-{
- DBT checkkey;
- SECAlgorithmID *algid = NULL;
- SECStatus rv = SECFailure;
- SECKEYDBKey *dbkey = NULL;
- SECItem *key = NULL;
- SECItem *dest = NULL;
- SECOidTag algorithm;
- SECItem oid;
- SECItem encstring;
- PRBool update = PR_FALSE;
-
- if (handle == NULL) {
- goto loser;
- }
-
- checkkey.data = KEYDB_PW_CHECK_STRING;
- checkkey.size = KEYDB_PW_CHECK_LEN;
-
- dbkey = get_dbkey(handle, &checkkey);
-
- if ( dbkey == NULL ) {
- goto loser;
- }
-
- /* build the oid item */
- oid.len = dbkey->derPK.data[0];
- oid.data = &dbkey->derPK.data[1];
-
- /* make sure entry is the correct length
- * since we are probably using a block cipher, the block will be
- * padded, so we may get a bit more than the exact size we need.
- */
- if ( dbkey->derPK.len < (KEYDB_PW_CHECK_LEN + 1 + oid.len ) ) {
- goto loser;
- }
-
- /* find the algorithm tag */
- algorithm = SECOID_FindOIDTag(&oid);
-
- /* make a secitem of the encrypted check string */
- encstring.len = dbkey->derPK.len - ( oid.len + 1 );
- encstring.data = &dbkey->derPK.data[oid.len+1];
-
- switch(algorithm)
- {
- case SEC_OID_RC4:
- key = seckey_create_rc4_key(pwitem, &dbkey->salt);
- if(key != NULL) {
- dest = seckey_rc4_cipher(key, &encstring, PR_FALSE);
- SECITEM_FreeItem(key, PR_TRUE);
- }
- break;
- default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm,
- &dbkey->salt, 1);
- if(algid != NULL) {
- /* Decrypt - this function implements a workaround for
- * a previous coding error. It will decrypt values using
- * DES rather than 3DES, if the initial try at 3DES
- * decryption fails. In this case, the update flag is
- * set to TRUE. This indication is used later to force
- * an update of the database to "real" 3DES encryption.
- */
- dest = SEC_PKCS5CipherData(algid, pwitem,
- &encstring, PR_FALSE, &update);
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
- }
- break;
- }
-
- if(dest == NULL) {
- goto loser;
- }
-
- if ((dest->len == KEYDB_PW_CHECK_LEN) &&
- (PORT_Memcmp(dest->data,
- KEYDB_PW_CHECK_STRING, KEYDB_PW_CHECK_LEN) == 0)) {
- rv = SECSuccess;
- /* we succeeded */
- if ( algorithm == SEC_OID_RC4 ) {
- /* partially updated database */
- SECKEY_UpdateKeyDBPass2(handle, pwitem);
- }
- /* Force an update of the password to remove the incorrect DES
- * encryption (see the note above)
- */
- if (update &&
- (algorithm == SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC)) {
- /* data base was encoded with DES not triple des, fix it */
- SECKEY_UpdateKeyDBPass2(handle,pwitem);
- }
- }
-
-loser:
- sec_destroy_dbkey(dbkey);
- if(dest != NULL) {
- SECITEM_ZfreeItem(dest, PR_TRUE);
- }
-
- return(rv);
-}
-
-/*
- * Change the database password and/or algorithm. This internal
- * routine does not check the old password. That must be done by
- * the caller.
- */
-static SECStatus
-ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem,
- SECOidTag new_algorithm)
-{
- SECStatus rv;
- keyList keylist;
- keyNode *node = NULL;
- SECKEYLowPrivateKey *privkey = NULL;
- char *nickname;
- DBT newkey;
- int ret;
-
- /* traverse the database, collecting the keys of all records */
- keylist.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( keylist.arena == NULL )
- {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(SECFailure);
- }
- keylist.head = NULL;
-
- /* TNH - TraverseKeys should not be public, since it exposes
- the underlying DBT data type. */
- rv = SECKEY_TraverseKeys(handle, sec_add_key_to_list, (void *)&keylist);
- if ( rv != SECSuccess )
- goto loser;
-
- /* walk the list, re-encrypting each entry */
- node = keylist.head;
- while ( node != NULL )
- {
- privkey = seckey_get_private_key(handle, &node->key, &nickname,
- oldpwitem);
-
- if (privkey == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- rv = SECFailure;
- goto loser;
- }
-
- /* delete the old record */
- ret = (* handle->db->del)(handle->db, &node->key, 0);
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- rv = SECFailure;
- goto loser;
- }
-
- /* get the public key, which we use as the database index */
-
- switch (privkey->keyType) {
- case rsaKey:
- newkey.data = privkey->u.rsa.modulus.data;
- newkey.size = privkey->u.rsa.modulus.len;
- break;
- case dsaKey:
- newkey.data = privkey->u.dsa.publicValue.data;
- newkey.size = privkey->u.dsa.publicValue.len;
- break;
- case dhKey:
- newkey.data = privkey->u.dh.publicValue.data;
- newkey.size = privkey->u.dh.publicValue.len;
- break;
- default:
- /* XXX We don't do Fortezza. */
- return SECFailure;
- }
-
- rv = seckey_put_private_key(handle, &newkey, newpwitem, privkey,
- nickname, PR_TRUE, new_algorithm);
-
- if ( rv != SECSuccess )
- {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- rv = SECFailure;
- goto loser;
- }
-
- /* next node */
- node = node->next;
- }
-
- rv = SECKEY_SetKeyDBPasswordAlg(handle, newpwitem, new_algorithm);
-
-loser:
-
- /* free the arena */
- if ( keylist.arena ) {
- PORT_FreeArena(keylist.arena, PR_FALSE);
- }
-
- return(rv);
-}
-
-/*
- * Re-encrypt the entire key database with a new password.
- * NOTE: The really should create a new database rather than doing it
- * in place in the original
- */
-SECStatus
-SECKEY_ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem,
- SECOidTag new_algorithm)
-{
- SECStatus rv;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECKEY_CheckKeyDBPassword(handle, oldpwitem);
- if ( rv != SECSuccess ) {
- return(SECFailure); /* return rv? */
- }
-
- rv = ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem, new_algorithm);
-
-loser:
- return(rv);
-}
-
-/*
- * Second pass of updating the key db. This time we have a password.
- */
-SECStatus
-SECKEY_UpdateKeyDBPass2(SECKEYKeyDBHandle *handle, SECItem *pwitem)
-{
- SECStatus rv;
-
- rv = ChangeKeyDBPasswordAlg(handle, pwitem, pwitem,
- SECKEY_GetDefaultKeyDBAlg());
-
- return(rv);
-}
-
-/*
- * currently updates key database from v2 to v3
- */
-SECStatus
-SECKEY_UpdateKeyDBPass1(SECKEYKeyDBHandle *handle)
-{
- SECStatus rv;
- DBT versionKey;
- DBT versionData;
- DBT checkKey;
- DBT checkData;
- DBT saltKey;
- DBT saltData;
- DBT key;
- DBT data;
- SECItem *rc4key = NULL;
- SECKEYDBKey *dbkey = NULL;
- SECItem *oldSalt = NULL;
- int ret;
- SECItem checkitem;
-
- if ( handle->updatedb == NULL ) {
- return(SECSuccess);
- }
-
- /*
- * check the version record
- */
- versionKey.data = VERSION_STRING;
- versionKey.size = sizeof(VERSION_STRING)-1;
-
- ret = (* handle->updatedb->get)(handle->updatedb, &versionKey,
- &versionData, 0 );
-
- if (ret) {
- /* no version record, so old db never used */
- goto done;
- }
-
- if ( ( versionData.size != 1 ) ||
- ( *((unsigned char *)versionData.data) != 2 ) ) {
- /* corrupt or wrong version number so don't update */
- goto done;
- }
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- ret = (* handle->updatedb->get)(handle->updatedb, &saltKey, &saltData, 0);
- if ( ret ) {
- /* no salt in old db, so it is corrupted */
- goto done;
- }
-
- oldSalt = decodeKeyDBGlobalSalt(&saltData);
- if ( oldSalt == NULL ) {
- /* bad salt in old db, so it is corrupted */
- goto done;
- }
-
- /*
- * look for a pw check entry
- */
- checkKey.data = KEYDB_PW_CHECK_STRING;
- checkKey.size = KEYDB_PW_CHECK_LEN;
-
- rv = (SECStatus)(* handle->updatedb->get)(handle->updatedb, &checkKey,
- &checkData, 0 );
- if (rv) {
- /* no pw check, so old db never used */
- goto done;
- }
-
- dbkey = decode_dbkey(&checkData, 2);
- if ( dbkey == NULL ) {
- goto done;
- }
-
- /* put global salt into the new database now */
- ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
- if ( ret ) {
- goto done;
- }
-
- checkitem = dbkey->derPK;
- dbkey->derPK.data = NULL;
-
- /* format the new pw check entry */
- rv = encodePWCheckEntry(NULL, &dbkey->derPK, SEC_OID_RC4, &checkitem);
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- rv = put_dbkey(handle, &checkKey, dbkey, PR_TRUE);
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- /* free the dbkey */
- sec_destroy_dbkey(dbkey);
- dbkey = NULL;
-
- /* now traverse the database */
- ret = (* handle->updatedb->seq)(handle->updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- goto done;
- }
-
- do {
- /* skip version record */
- if ( data.size > 1 ) {
- /* skip salt */
- if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) {
- if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) {
- continue;
- }
- }
- /* skip pw check entry */
- if ( key.size == checkKey.size ) {
- if ( PORT_Memcmp(key.data, checkKey.data, key.size) == 0 ) {
- continue;
- }
- }
-
- /* keys stored by nickname will have 0 as the last byte of the
- * db key. Other keys must be stored by modulus. We will not
- * update those because they are left over from a keygen that
- * never resulted in a cert.
- */
- if ( ((unsigned char *)key.data)[key.size-1] != 0 ) {
- continue;
- }
-
- dbkey = decode_dbkey(&data, 2);
- if ( dbkey == NULL ) {
- continue;
- }
-
- /* This puts the key into the new database with the same
- * index (nickname) that it had before. The second pass
- * of the update will have the password. It will decrypt
- * and re-encrypt the entries using a new algorithm.
- */
- dbkey->nickname = (char *)key.data;
- rv = put_dbkey(handle, &key, dbkey, PR_FALSE);
- dbkey->nickname = NULL;
-
- sec_destroy_dbkey(dbkey);
- }
- } while ( (* handle->updatedb->seq)(handle->updatedb, &key, &data,
- R_NEXT) == 0 );
-
- dbkey = NULL;
-
-done:
- /* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
-
- (* handle->updatedb->close)(handle->updatedb);
- handle->updatedb = NULL;
-
- if ( rc4key ) {
- SECITEM_FreeItem(rc4key, PR_TRUE);
- }
-
- if ( oldSalt ) {
- SECITEM_FreeItem(oldSalt, PR_TRUE);
- }
-
- if ( dbkey ) {
- sec_destroy_dbkey(dbkey);
- }
-
- return(SECSuccess);
-}
-
-/*
- * Clear out all the keys in the existing database
- */
-SECStatus
-SECKEY_ResetKeyDB(SECKEYKeyDBHandle *handle)
-{
- SECStatus rv;
- DBT key;
- DBT data;
- int ret;
- int errors = 0;
-
- if ( handle->db == NULL ) {
- return(SECSuccess);
- }
-
-
- /* now traverse the database */
- ret = (* handle->db->seq)(handle->db, &key, &data, R_FIRST);
- if ( ret ) {
- goto done;
- }
-
- do {
- /* delete each entry */
- ret = (* handle->db->del)(handle->db, &key, 0);
- if ( ret ) errors++;
-
- } while ( (* handle->db->seq)(handle->db, &key, &data,
- R_NEXT) == 0 );
- rv = makeGlobalVersion(handle);
- if ( rv != SECSuccess ) {
- errors++;
- goto done;
- }
-
- rv = makeGlobalSalt(handle);
- if ( rv != SECSuccess ) {
- errors++;
- goto done;
- }
-
- if (handle->global_salt) {
- SECITEM_FreeItem(handle->global_salt,PR_TRUE);
- }
- handle->global_salt = GetKeyDBGlobalSalt(handle);
-
-done:
- /* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
-
- return (errors == 0 ? SECSuccess : SECFailure);
-}
diff --git a/security/nss/lib/softoken/keydbt.h b/security/nss/lib/softoken/keydbt.h
deleted file mode 100644
index 1b781b939..000000000
--- a/security/nss/lib/softoken/keydbt.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * keydbt.h - private data structures for the private key library
- *
- * $Id$
- */
-
-#ifndef _KEYDBT_H_
-#define _KEYDBT_H_
-
-#include "prtypes.h"
-#include "plarena.h"
-#include "secitem.h"
-#include "secasn1t.h"
-#include "secmodt.h"
-#include "pkcs11t.h"
-
-
-/*
- * a key in/for the data base
- */
-struct SECKEYDBKeyStr {
- PLArenaPool *arena;
- int version;
- char *nickname;
- SECItem salt;
- SECItem derPK;
-};
-typedef struct SECKEYDBKeyStr SECKEYDBKey;
-
-typedef struct SECKEYKeyDBHandleStr SECKEYKeyDBHandle;
-
-#define PRIVATE_KEY_DB_FILE_VERSION 3
-
-#define SEC_PRIVATE_KEY_VERSION 0 /* what we *create* */
-
-/*
-** Typedef for callback to get a password "key".
-*/
-typedef SECItem * (* SECKEYGetPasswordKey)(void *arg,
- SECKEYKeyDBHandle *handle);
-
-extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_RSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_DSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[];
-extern const SEC_ASN1Template SECKEY_DHPrivateKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[];
-extern const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_DHParamKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template SECKEY_PQGParamsTemplate[];
-extern const SEC_ASN1Template SECKEY_AttributeTemplate[];
-
-#endif /* _KEYDBT_H_ */
diff --git a/security/nss/lib/softoken/keylow.h b/security/nss/lib/softoken/keylow.h
deleted file mode 100644
index dc84ed426..000000000
--- a/security/nss/lib/softoken/keylow.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * key.h - public data structures and prototypes for the private key library
- *
- * $Id$
- */
-
-#ifndef _KEYLOW_H_
-#define _KEYLOW_H_
-
-#include "prtypes.h"
-#include "seccomon.h"
-#include "keydbt.h"
-#include "secoidt.h"
-#include "certt.h"
-#include "keythi.h"
-
-SEC_BEGIN_PROTOS
-
-typedef char * (* SECKEYDBNameFunc)(void *arg, int dbVersion);
-
-/*
-** Open a key database.
-*/
-extern SECKEYKeyDBHandle *SECKEY_OpenKeyDB(PRBool readOnly,
- SECKEYDBNameFunc namecb,
- void *cbarg);
-
-extern SECKEYKeyDBHandle *SECKEY_OpenKeyDBFilename(char *filename,
- PRBool readOnly);
-
-/*
-** Update the database
-*/
-extern SECStatus SECKEY_UpdateKeyDBPass1(SECKEYKeyDBHandle *handle);
-extern SECStatus SECKEY_UpdateKeyDBPass2(SECKEYKeyDBHandle *handle,
- SECItem *pwitem);
-
-/*
- * Clear out all the keys in the existing database
- */
-extern SECStatus SECKEY_ResetKeyDB(SECKEYKeyDBHandle *handle);
-
-/*
-** Close the specified key database.
-*/
-extern void SECKEY_CloseKeyDB(SECKEYKeyDBHandle *handle);
-
-/*
- * Get the version number of the database
- */
-extern int SECKEY_GetKeyDBVersion(SECKEYKeyDBHandle *handle);
-
-/*
-** Support a default key database.
-*/
-extern void SECKEY_SetDefaultKeyDB(SECKEYKeyDBHandle *handle);
-extern SECKEYKeyDBHandle *SECKEY_GetDefaultKeyDB(void);
-
-/* set the alg id of the key encryption algorithm */
-extern void SECKEY_SetDefaultKeyDBAlg(SECOidTag alg);
-
-/*
- * given a password and salt, produce a hash of the password
- */
-extern SECItem *SECKEY_HashPassword(char *pw, SECItem *salt);
-
-/*
- * Derive the actual password value for a key database from the
- * password string value. The derivation uses global salt value
- * stored in the key database.
- */
-extern SECItem *
-SECKEY_DeriveKeyDBPassword(SECKEYKeyDBHandle *handle, char *pw);
-
-/*
-** Delete a key from the database
-*/
-extern SECStatus SECKEY_DeleteKey(SECKEYKeyDBHandle *handle,
- SECItem *pubkey);
-
-/*
-** Store a key in the database, indexed by its public key modulus.
-** "pk" is the private key to store
-** "f" is a the callback function for getting the password
-** "arg" is the argument for the callback
-*/
-extern SECStatus SECKEY_StoreKeyByPublicKey(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *pk,
- SECItem *pubKeyData,
- char *nickname,
- SECKEYGetPasswordKey f, void *arg);
-
-/* does the key for this cert exist in the database filed by modulus */
-extern SECStatus SECKEY_KeyForCertExists(SECKEYKeyDBHandle *handle,
- CERTCertificate *cert);
-
-SECKEYLowPrivateKey *
-SECKEY_FindKeyByCert(SECKEYKeyDBHandle *handle, CERTCertificate *cert,
- SECKEYGetPasswordKey f, void *arg);
-
-extern SECStatus SECKEY_HasKeyDBPassword(SECKEYKeyDBHandle *handle);
-extern SECStatus SECKEY_SetKeyDBPassword(SECKEYKeyDBHandle *handle,
- SECItem *pwitem);
-extern SECStatus SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle,
- SECItem *pwitem);
-extern SECStatus SECKEY_ChangeKeyDBPassword(SECKEYKeyDBHandle *handle,
- SECItem *oldpwitem,
- SECItem *newpwitem);
-
-/*
-** Destroy a private key object.
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void SECKEY_LowDestroyPrivateKey(SECKEYLowPrivateKey *key);
-
-/*
-** Destroy a public key object.
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void SECKEY_LowDestroyPublicKey(SECKEYLowPublicKey *key);
-
-/*
-** Return the modulus length of "pubKey".
-*/
-extern unsigned int SECKEY_LowPublicModulusLen(SECKEYLowPublicKey *pubKey);
-
-
-/*
-** Return the modulus length of "privKey".
-*/
-extern unsigned int SECKEY_LowPrivateModulusLen(SECKEYLowPrivateKey *privKey);
-
-
-/*
-** Convert a low private key "privateKey" into a public low key
-*/
-extern SECKEYLowPublicKey
- *SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privateKey);
-
-/*
- * Set the Key Database password.
- * handle is a handle to the key database
- * pwitem is the new password
- * algorithm is the algorithm by which the key database
- * password is to be encrypted.
- * On failure, SECFailure is returned, otherwise SECSuccess is
- * returned.
- */
-extern SECStatus
-SECKEY_SetKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
- SECItem *pwitem,
- SECOidTag algorithm);
-
-/* Check the key database password.
- * handle is a handle to the key database
- * pwitem is the suspect password
- * algorithm is the algorithm by which the key database
- * password is to be encrypted.
- * The password is checked against plaintext to see if it is the
- * actual password. If it is not, SECFailure is returned.
- */
-extern SECStatus
-SECKEY_CheckKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
- SECItem *pwitem,
- SECOidTag algorithm);
-
-/* Change the key database password and/or algorithm by which
- * the password is stored with.
- * handle is a handle to the key database
- * old_pwitem is the current password
- * new_pwitem is the new password
- * old_algorithm is the algorithm by which the key database
- * password is currently encrypted.
- * new_algorithm is the algorithm with which the new password
- * is to be encrypted.
- * A return of anything but SECSuccess indicates failure.
- */
-extern SECStatus
-SECKEY_ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem,
- SECOidTag old_algorithm);
-
-/* Store key by modulus and specify an encryption algorithm to use.
- * handle is the pointer to the key database,
- * privkey is the private key to be stored,
- * f and arg are the function and arguments to the callback
- * to get a password,
- * algorithm is the algorithm which the privKey is to be stored.
- * A return of anything but SECSuccess indicates failure.
- */
-extern SECStatus
-SECKEY_StoreKeyByPublicKeyAlg(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SECKEYGetPasswordKey f, void *arg,
- SECOidTag algorithm);
-
-/* Find key by modulus. This function is the inverse of store key
- * by modulus. An attempt to locate the key with "modulus" is
- * performed. If the key is found, the private key is returned,
- * else NULL is returned.
- * modulus is the modulus to locate
- */
-extern SECKEYLowPrivateKey *
-SECKEY_FindKeyByPublicKey(SECKEYKeyDBHandle *handle, SECItem *modulus,
- SECKEYGetPasswordKey f, void *arg);
-
-/* Make a copy of a low private key in it's own arena.
- * a return of NULL indicates an error.
- */
-extern SECKEYLowPrivateKey *
-SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey);
-
-
-SEC_END_PROTOS
-
-#endif /* _KEYLOW_H_ */
diff --git a/security/nss/lib/softoken/keytboth.h b/security/nss/lib/softoken/keytboth.h
deleted file mode 100644
index 50f6b0ebe..000000000
--- a/security/nss/lib/softoken/keytboth.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-#ifndef _KEYTBOTH_H_
-#define _KEYTBOTH_H_ 1
-
-#include "blapit.h"
-#include "secoidt.h"
-
-/*
-** Attributes
-*/
-struct SECKEYAttributeStr {
- SECItem attrType;
- SECItem **attrValue;
-};
-typedef struct SECKEYAttributeStr SECKEYAttribute;
-
-/*
-** A PKCS#8 private key info object
-*/
-struct SECKEYPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID algorithm;
- SECItem privateKey;
- SECKEYAttribute **attributes;
-};
-typedef struct SECKEYPrivateKeyInfoStr SECKEYPrivateKeyInfo;
-#define SEC_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
-
-/*
-** A PKCS#8 private key info object
-*/
-struct SECKEYEncryptedPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECAlgorithmID algorithm;
- SECItem encryptedData;
-};
-typedef struct SECKEYEncryptedPrivateKeyInfoStr SECKEYEncryptedPrivateKeyInfo;
-
-
-struct DiffPQGParamsStr {
- PQGParams DiffKEAParams;
- PQGParams DiffDSAParams;
-};
-typedef struct DiffPQGParamsStr DiffPQGParams;
-
-struct PQGDualParamsStr {
- PQGParams CommParams;
- DiffPQGParams DiffParams;
-};
-typedef struct PQGDualParamsStr PQGDualParams;
-
-
-struct KEAParamsStr {
- PLArenaPool *arena;
- SECItem hash;
-};
-typedef struct KEAParamsStr KEAParams;
-
-struct KEAPublicKeyStr {
- KEAParams params;
- SECItem publicValue;
-};
-typedef struct KEAPublicKeyStr KEAPublicKey;
-
-
-
-#endif /* _KEYT_H_ */
diff --git a/security/nss/lib/softoken/keytlow.h b/security/nss/lib/softoken/keytlow.h
deleted file mode 100644
index 0b47ceb99..000000000
--- a/security/nss/lib/softoken/keytlow.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-#ifndef _KEYTLOW_H_
-#define _KEYTLOW_H_ 1
-
-#include "blapit.h"
-
-typedef enum {
- nullKey,
- rsaKey,
- dsaKey,
- fortezzaKey,
- dhKey,
- keaKey
-} KeyType;
-
-struct FortezzaPublicKeyStr {
- int KEAversion;
- int DSSversion;
- unsigned char KMID[8];
- SECItem clearance;
- SECItem KEApriviledge;
- SECItem DSSpriviledge;
- SECItem KEAKey;
- SECItem DSSKey;
- PQGParams params;
- PQGParams keaParams;
-};
-typedef struct FortezzaPublicKeyStr FortezzaPublicKey;
-
-struct FortezzaPrivateKeyStr {
- int certificate;
- unsigned char serial[8];
- int socket;
-};
-typedef struct FortezzaPrivateKeyStr FortezzaPrivateKey;
-
-/*
-** An RSA public key object.
-*/
-struct SECKEYLowPublicKeyStr {
- PLArenaPool *arena;
- KeyType keyType ;
- union {
- RSAPublicKey rsa;
- DSAPublicKey dsa;
- DHPublicKey dh;
- } u;
-};
-typedef struct SECKEYLowPublicKeyStr SECKEYLowPublicKey;
-
-/*
-** Low Level private key object
-** This is only used by the raw Crypto engines (crypto), keydb (keydb),
-** and PKCS #11. Everyone else uses the high level key structure.
-*/
-struct SECKEYLowPrivateKeyStr {
- PLArenaPool *arena;
- KeyType keyType;
- union {
- RSAPrivateKey rsa;
- DSAPrivateKey dsa;
- DHPrivateKey dh;
- FortezzaPrivateKey fortezza; /* includes DSA and KEA private
- keys used with fortezza */
- } u;
-};
-typedef struct SECKEYLowPrivateKeyStr SECKEYLowPrivateKey;
-
-#endif /* _KEYTLOW_H_ */
diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c
deleted file mode 100644
index 653b18785..000000000
--- a/security/nss/lib/softoken/lowkey.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-#include "keylow.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "secder.h"
-#include "base64.h"
-#include "secasn1.h"
-#include "cert.h"
-#include "secerr.h"
-
-
-const SEC_ASN1Template SECKEY_RSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.version) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.modulus) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.prime1) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.prime2) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.exponent1) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.exponent2) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.coefficient) },
- { 0 }
-};
-
-
-const SEC_ASN1Template SECKEY_DSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYLowPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dsa.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dsa.privateValue) },
- { 0, }
-};
-
-const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dsa.privateValue) },
-};
-
-const SEC_ASN1Template SECKEY_DHPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYLowPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.privateValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.base) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.prime) },
- { 0, }
-};
-
-const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.privateValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.base) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.prime) },
-};
-
-void
-SECKEY_LowDestroyPrivateKey(SECKEYLowPrivateKey *privk)
-{
- if (privk && privk->arena) {
- PORT_FreeArena(privk->arena, PR_TRUE);
- }
-}
-
-void
-SECKEY_LowDestroyPublicKey(SECKEYLowPublicKey *pubk)
-{
- if (pubk && pubk->arena) {
- PORT_FreeArena(pubk->arena, PR_FALSE);
- }
-}
-unsigned
-SECKEY_LowPublicModulusLen(SECKEYLowPublicKey *pubk)
-{
- unsigned char b0;
-
- /* interpret modulus length as key strength... in
- * fortezza that's the public key length */
-
- switch (pubk->keyType) {
- case rsaKey:
- b0 = pubk->u.rsa.modulus.data[0];
- return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
- default:
- break;
- }
- return 0;
-}
-
-unsigned
-SECKEY_LowPrivateModulusLen(SECKEYLowPrivateKey *privk)
-{
-
- unsigned char b0;
-
- switch (privk->keyType) {
- case rsaKey:
- b0 = privk->u.rsa.modulus.data[0];
- return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1;
- default:
- break;
- }
- return 0;
-}
-
-SECKEYLowPublicKey *
-SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privk)
-{
- SECKEYLowPublicKey *pubk;
- PLArenaPool *arena;
-
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- switch(privk->keyType) {
- case rsaKey:
- case nullKey:
- pubk = (SECKEYLowPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof (SECKEYLowPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- if (privk->keyType == nullKey) return pubk;
- rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
- &privk->u.rsa.modulus);
- if (rv == SECSuccess) {
- rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent,
- &privk->u.rsa.publicExponent);
- if (rv == SECSuccess)
- return pubk;
- }
- SECKEY_LowDestroyPublicKey (pubk);
- } else {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- }
- break;
- case dsaKey:
- pubk = (SECKEYLowPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYLowPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
- &privk->u.dsa.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
- &privk->u.dsa.params.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
- &privk->u.dsa.params.subPrime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
- &privk->u.dsa.params.base);
- if (rv == SECSuccess) return pubk;
- }
- break;
- case dhKey:
- pubk = (SECKEYLowPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYLowPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
- &privk->u.dh.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime,
- &privk->u.dh.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.base,
- &privk->u.dh.base);
- if (rv == SECSuccess) return pubk;
- }
- break;
- /* No Fortezza in Low Key implementations (Fortezza keys aren't
- * stored in our data base */
- default:
- break;
- }
-
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
-}
-
-SECKEYLowPrivateKey *
-SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey)
-{
- SECKEYLowPrivateKey *returnKey = NULL;
- SECStatus rv = SECFailure;
- PLArenaPool *poolp;
-
- if(!privKey) {
- return NULL;
- }
-
- poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!poolp) {
- return NULL;
- }
-
- returnKey = (SECKEYLowPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(SECKEYLowPrivateKey));
- if(!returnKey) {
- rv = SECFailure;
- goto loser;
- }
-
- returnKey->keyType = privKey->keyType;
- returnKey->arena = poolp;
-
- switch(privKey->keyType) {
- case rsaKey:
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus),
- &(privKey->u.rsa.modulus));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version),
- &(privKey->u.rsa.version));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent),
- &(privKey->u.rsa.publicExponent));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent),
- &(privKey->u.rsa.privateExponent));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1),
- &(privKey->u.rsa.prime1));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2),
- &(privKey->u.rsa.prime2));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1),
- &(privKey->u.rsa.exponent1));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2),
- &(privKey->u.rsa.exponent2));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient),
- &(privKey->u.rsa.coefficient));
- if(rv != SECSuccess) break;
- break;
- case dsaKey:
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue),
- &(privKey->u.dsa.publicValue));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue),
- &(privKey->u.dsa.privateValue));
- if(rv != SECSuccess) break;
- returnKey->u.dsa.params.arena = poolp;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime),
- &(privKey->u.dsa.params.prime));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime),
- &(privKey->u.dsa.params.subPrime));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base),
- &(privKey->u.dsa.params.base));
- if(rv != SECSuccess) break;
- break;
- case dhKey:
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue),
- &(privKey->u.dh.publicValue));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue),
- &(privKey->u.dh.privateValue));
- if(rv != SECSuccess) break;
- returnKey->u.dsa.params.arena = poolp;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime),
- &(privKey->u.dh.prime));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base),
- &(privKey->u.dh.base));
- if(rv != SECSuccess) break;
- break;
- case fortezzaKey:
- returnKey->u.fortezza.certificate =
- privKey->u.fortezza.certificate;
- returnKey->u.fortezza.socket =
- privKey->u.fortezza.socket;
- PORT_Memcpy(returnKey->u.fortezza.serial,
- privKey->u.fortezza.serial, 8);
- rv = SECSuccess;
- break;
- default:
- rv = SECFailure;
- }
-
-loser:
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_TRUE);
- returnKey = NULL;
- }
-
- return returnKey;
-}
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
deleted file mode 100644
index 75d5e9fc2..000000000
--- a/security/nss/lib/softoken/manifest.mn
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Netscape security libraries.
-#
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation. Portions created by Netscape are
-# Copyright (C) 1994-2000 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable
-# instead of those above. If you wish to allow use of your
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL. If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-CORE_DEPTH = ../../..
-
-MODULE = security
-
-REQUIRES = dbm
-
-LIBRARY_NAME = softoken
-
-
-EXPORTS = \
- keydbt.h \
- keylow.h \
- keytboth.h \
- keytlow.h \
- secpkcs5.h \
- pkcs11.h \
- pkcs11f.h \
- pkcs11p.h \
- pkcs11t.h \
- pkcs11u.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- alghmac.h \
- pkcs11i.h \
- softoken.h \
- softoknt.h \
- $(NULL)
-
-CSRCS = \
- alghmac.c \
- rsawrapr.c \
- pkcs11.c \
- pkcs11c.c \
- pkcs11u.c \
- secpkcs5.c \
- keydb.c \
- lowkey.c \
- padbuf.c \
- fipstest.c \
- fipstokn.c \
- rawhash.c \
- $(NULL)
-
-
diff --git a/security/nss/lib/softoken/padbuf.c b/security/nss/lib/softoken/padbuf.c
deleted file mode 100644
index a4e28947a..000000000
--- a/security/nss/lib/softoken/padbuf.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-#include "blapit.h"
-#include "secport.h"
-#include "secerr.h"
-
-/*
- * Prepare a buffer for DES encryption, growing to the appropriate boundary,
- * filling with the appropriate padding.
- *
- * NOTE: If arena is non-NULL, we re-allocate from there, otherwise
- * we assume (and use) XP memory (re)allocation.
- */
-unsigned char *
-DES_PadBuffer(PRArenaPool *arena, unsigned char *inbuf, unsigned int inlen,
- unsigned int *outlen)
-{
- unsigned char *outbuf;
- unsigned int des_len;
- unsigned int i;
- unsigned char des_pad_len;
-
- /*
- * We need from 1 to DES_KEY_LENGTH bytes -- we *always* grow.
- * The extra bytes contain the value of the length of the padding:
- * if we have 2 bytes of padding, then the padding is "0x02, 0x02".
- */
- des_len = (inlen + DES_KEY_LENGTH) & ~(DES_KEY_LENGTH - 1);
-
- if (arena != NULL) {
- outbuf = (unsigned char*)PORT_ArenaGrow (arena, inbuf, inlen, des_len);
- } else {
- outbuf = (unsigned char*)PORT_Realloc (inbuf, des_len);
- }
-
- if (outbuf == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- des_pad_len = des_len - inlen;
- for (i = inlen; i < des_len; i++)
- outbuf[i] = des_pad_len;
-
- *outlen = des_len;
- return outbuf;
-}
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
deleted file mode 100644
index fc70b782a..000000000
--- a/security/nss/lib/softoken/pkcs11.c
+++ /dev/null
@@ -1,4031 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login.
- * It supports Public Key ops, and all they bulk ciphers and hashes.
- * It can also support Private Key ops for imported Private keys. It does
- * not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-#include "seccomon.h"
-#include "secitem.h"
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "softoken.h"
-#include "cert.h"
-#include "keylow.h"
-#include "blapi.h"
-#include "secder.h"
-#include "secport.h"
-#include "certdb.h"
-
-#include "private.h"
-
-
-/*
- * ******************** Static data *******************************
- */
-
-/* The next three strings must be exactly 32 characters long */
-static char *manufacturerID = "Netscape Communications Corp ";
-static char *libraryDescription = "Communicator Internal Crypto Svc";
-static char *tokDescription = "Communicator Generic Crypto Svcs";
-static char *privTokDescription = "Communicator Certificate DB ";
-/* The next two strings must be exactly 64 characters long, with the
- first 32 characters meaningful */
-static char *slotDescription =
- "Communicator Internal Cryptographic Services Version 4.0 ";
-static char *privSlotDescription =
- "Communicator User Private Key and Certificate Services ";
-static int minimumPinLen = 0;
-
-#define __PASTE(x,y) x##y
-
-/*
- * we renamed all our internal functions, get the correct
- * definitions for them...
- */
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-#define CK_EXTERN extern
-#define CK_PKCS11_FUNCTION_INFO(func) \
- CK_RV __PASTE(NS,func)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-
-
-/* build the crypto module table */
-static CK_FUNCTION_LIST pk11_funcList = {
- { 1, 10 },
-
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-#define CK_PKCS11_FUNCTION_INFO(func) \
- __PASTE(NS,func),
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-
-#undef __PASTE
-
-/* List of DES Weak Keys */
-typedef unsigned char desKey[8];
-static desKey pk11_desWeakTable[] = {
-#ifdef noParity
- /* weak */
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },
- { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 },
- { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
- /* semi-weak */
- { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },
- { 0xfe, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0xfe },
-
- { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },
- { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
-
- { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x0f, 0x00, 0x0f },
- { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
-
- { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
- { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
-
- { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },
- { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },
-
- { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },
- { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
-#else
- /* weak */
- { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
- { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e },
- { 0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1 },
- { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
-
- /* semi-weak */
- { 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe },
- { 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01 },
-
- { 0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1 },
- { 0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e },
-
- { 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1 },
- { 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01 },
-
- { 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
- { 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e },
-
- { 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e },
- { 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 },
-
- { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe },
- { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1 }
-#endif
-};
-
-
-static int pk11_desWeakTableSize = sizeof(pk11_desWeakTable)/
- sizeof(pk11_desWeakTable[0]);
-
-/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
- * that byte with the proper parity bit set */
-static unsigned char parityTable[256] = {
-/* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
-/* E */ 0x01,0x02,0x04,0x07,0x08,0x0b,0x0d,0x0e,
-/* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
-/* O */ 0x10,0x13,0x15,0x16,0x19,0x1a,0x1c,0x1f,
-/* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */
-/* O */ 0x20,0x23,0x25,0x26,0x29,0x2a,0x2c,0x2f,
-/* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */
-/* E */ 0x31,0x32,0x34,0x37,0x38,0x3b,0x3d,0x3e,
-/* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */
-/* O */ 0x40,0x43,0x45,0x46,0x49,0x4a,0x4c,0x4f,
-/* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */
-/* E */ 0x51,0x52,0x54,0x57,0x58,0x5b,0x5d,0x5e,
-/* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */
-/* E */ 0x61,0x62,0x64,0x67,0x68,0x6b,0x6d,0x6e,
-/* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */
-/* O */ 0x70,0x73,0x75,0x76,0x79,0x7a,0x7c,0x7f,
-/* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */
-/* O */ 0x80,0x83,0x85,0x86,0x89,0x8a,0x8c,0x8f,
-/* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */
-/* E */ 0x91,0x92,0x94,0x97,0x98,0x9b,0x9d,0x9e,
-/* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */
-/* E */ 0xa1,0xa2,0xa4,0xa7,0xa8,0xab,0xad,0xae,
-/* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */
-/* O */ 0xb0,0xb3,0xb5,0xb6,0xb9,0xba,0xbc,0xbf,
-/* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */
-/* E */ 0xc1,0xc2,0xc4,0xc7,0xc8,0xcb,0xcd,0xce,
-/* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */
-/* O */ 0xd0,0xd3,0xd5,0xd6,0xd9,0xda,0xdc,0xdf,
-/* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */
-/* O */ 0xe0,0xe3,0xe5,0xe6,0xe9,0xea,0xec,0xef,
-/* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */
-/* E */ 0xf1,0xf2,0xf4,0xf7,0xf8,0xfb,0xfd,0xfe,
-};
-
-/* Mechanisms */
-struct mechanismList {
- CK_MECHANISM_TYPE type;
- CK_MECHANISM_INFO domestic;
- PRBool privkey;
-};
-
-/*
- * the following table includes a complete list of mechanism defined by
- * PKCS #11 version 2.01. Those Mechanisms not supported by this PKCS #11
- * module are ifdef'ed out.
- */
-#define CKF_EN_DE CKF_ENCRYPT | CKF_DECRYPT
-#define CKF_WR_UN CKF_WRAP | CKF_UNWRAP
-#define CKF_SN_VR CKF_SIGN | CKF_VERIFY
-#define CKF_SN_RE CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER
-
-#define CKF_EN_DE_WR_UN CKF_EN_DE | CKF_WR_UN
-#define CKF_SN_VR_RE CKF_SN_VR | CKF_SN_RE
-#define CKF_DUZ_IT_ALL CKF_EN_DE_WR_UN | CKF_SN_VR_RE
-
-static struct mechanismList mechanisms[] = {
- /* ------------------------- RSA Operations ---------------------------*/
- {CKM_RSA_PKCS_KEY_PAIR_GEN,{128, 2048, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
- {CKM_RSA_PKCS, { 16, 256, CKF_DUZ_IT_ALL}, PR_TRUE},
-#ifdef PK11_RSA9796_SUPPORTED
- {CKM_RSA_9796, { 16, 256, CKF_DUZ_IT_ALL}, PR_TRUE},
-#endif
- {CKM_RSA_X_509, { 16, 256, CKF_DUZ_IT_ALL}, PR_TRUE},
- /* -------------- RSA Multipart Signing Operations -------------------- */
- {CKM_MD2_RSA_PKCS, {16, 256, CKF_SN_VR}, PR_TRUE},
- {CKM_MD5_RSA_PKCS, {16, 256, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA1_RSA_PKCS, {16, 256, CKF_SN_VR}, PR_TRUE},
- /* ------------------------- DSA Operations --------------------------- */
- {CKM_DSA_KEY_PAIR_GEN, {64, 128, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
- {CKM_DSA, {64, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_DSA_SHA1, {64, 128, CKF_SN_VR}, PR_TRUE},
- /* -------------------- Diffie Hellman Operations --------------------- */
- /* no diffie hellman yet */
- {CKM_DH_PKCS_KEY_PAIR_GEN, {16, 128, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
- {CKM_DH_PKCS_DERIVE, {16, 128, CKF_DERIVE}, PR_TRUE},
- /* ------------------------- RC2 Operations --------------------------- */
- {CKM_RC2_KEY_GEN, {1, 128, CKF_GENERATE}, PR_FALSE},
- {CKM_RC2_ECB, {1, 128, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_RC2_CBC, {1, 128, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_RC2_MAC, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_RC2_MAC_GENERAL, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_RC2_CBC_PAD, {1, 128, CKF_EN_DE_WR_UN}, PR_FALSE},
- /* ------------------------- RC4 Operations --------------------------- */
- {CKM_RC4_KEY_GEN, {1, 256, CKF_GENERATE}, PR_FALSE},
- {CKM_RC4, {1, 256, CKF_EN_DE_WR_UN}, PR_FALSE},
- /* ------------------------- DES Operations --------------------------- */
- {CKM_DES_KEY_GEN, { 8, 8, CKF_GENERATE}, PR_FALSE},
- {CKM_DES_ECB, { 8, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_DES_CBC, { 8, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_DES_MAC, { 8, 8, CKF_SN_VR}, PR_FALSE},
- {CKM_DES_MAC_GENERAL, { 8, 8, CKF_SN_VR}, PR_FALSE},
- {CKM_DES_CBC_PAD, { 8, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_DES2_KEY_GEN, {24, 24, CKF_GENERATE}, PR_FALSE},
- {CKM_DES3_KEY_GEN, {24, 24, CKF_GENERATE}, PR_TRUE },
- {CKM_DES3_ECB, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE },
- {CKM_DES3_CBC, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE },
- {CKM_DES3_MAC, {24, 24, CKF_SN_VR}, PR_TRUE },
- {CKM_DES3_MAC_GENERAL, {24, 24, CKF_SN_VR}, PR_TRUE },
- {CKM_DES3_CBC_PAD, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE },
- /* ------------------------- CDMF Operations --------------------------- */
- {CKM_CDMF_KEY_GEN, {8, 8, CKF_GENERATE}, PR_FALSE},
- {CKM_CDMF_ECB, {8, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CDMF_CBC, {8, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CDMF_MAC, {8, 8, CKF_SN_VR}, PR_FALSE},
- {CKM_CDMF_MAC_GENERAL, {8, 8, CKF_SN_VR}, PR_FALSE},
- {CKM_CDMF_CBC_PAD, {8, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- /* ------------------------- Hashing Operations ----------------------- */
- {CKM_MD2, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_MD2_HMAC, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_MD2_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_MD5, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_MD5_HMAC, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_MD5_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_SHA_1, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_SHA_1_HMAC, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_SHA_1_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_FALSE},
- {CKM_TLS_PRF_GENERAL, {0, 512, CKF_SN_VR}, PR_FALSE},
- /* ------------------------- CAST Operations --------------------------- */
-#ifdef PK11_CAST_SUPPORTED
- /* Cast operations are not supported ( yet? ) */
- {CKM_CAST_KEY_GEN, {1, 8, CKF_GENERATE}, PR_FALSE},
- {CKM_CAST_ECB, {1, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST_CBC, {1, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST_MAC, {1, 8, CKF_SN_VR}, PR_FALSE},
- {CKM_CAST_MAC_GENERAL, {1, 8, CKF_SN_VR}, PR_FALSE},
- {CKM_CAST_CBC_PAD, {1, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST3_KEY_GEN, {1, 16, CKF_GENERATE}, PR_FALSE},
- {CKM_CAST3_ECB, {1, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST3_CBC, {1, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST3_MAC, {1, 16, CKF_SN_VR}, PR_FALSE},
- {CKM_CAST3_MAC_GENERAL, {1, 16, CKF_SN_VR}, PR_FALSE},
- {CKM_CAST3_CBC_PAD, {1, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST5_KEY_GEN, {1, 16, CKF_GENERATE}, PR_FALSE},
- {CKM_CAST5_ECB, {1, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST5_CBC, {1, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_CAST5_MAC, {1, 16, CKF_SN_VR}, PR_FALSE},
- {CKM_CAST5_MAC_GENERAL, {1, 16, CKF_SN_VR}, PR_FALSE},
- {CKM_CAST5_CBC_PAD, {1, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
-#endif
- /* ------------------------- RC5 Operations --------------------------- */
- {CKM_RC5_KEY_GEN, {1, 255, CKF_GENERATE}, PR_FALSE},
- {CKM_RC5_ECB, {1, 255, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_RC5_CBC, {1, 255, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_RC5_MAC, {1, 255, CKF_SN_VR}, PR_FALSE},
- {CKM_RC5_MAC_GENERAL, {1, 255, CKF_SN_VR}, PR_FALSE},
- {CKM_RC5_CBC_PAD, {1, 255, CKF_EN_DE_WR_UN}, PR_FALSE},
- /* ------------------------- IDEA Operations -------------------------- */
-#ifdef PK11_IDEA_SUPPORTED
- {CKM_IDEA_KEY_GEN, {16, 16, CKF_GENERATE}, PR_FALSE},
- {CKM_IDEA_ECB, {16, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_IDEA_CBC, {16, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
- {CKM_IDEA_MAC, {16, 16, CKF_SN_VR}, PR_FALSE},
- {CKM_IDEA_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_FALSE},
- {CKM_IDEA_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
-#endif
- /* --------------------- Secret Key Operations ------------------------ */
- {CKM_GENERIC_SECRET_KEY_GEN, {1, 256, CKF_GENERATE}, PR_FALSE},
- {CKM_CONCATENATE_BASE_AND_KEY, {1, 256, CKF_GENERATE}, PR_FALSE},
- {CKM_CONCATENATE_BASE_AND_DATA, {1, 256, CKF_GENERATE}, PR_FALSE},
- {CKM_CONCATENATE_DATA_AND_BASE, {1, 256, CKF_GENERATE}, PR_FALSE},
- {CKM_XOR_BASE_AND_DATA, {1, 256, CKF_GENERATE}, PR_FALSE},
- {CKM_EXTRACT_KEY_FROM_KEY, {1, 256, CKF_DERIVE}, PR_FALSE},
- /* ---------------------- SSL Key Derivations ------------------------- */
- {CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_GENERATE}, PR_FALSE},
- {CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_SSL3_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_SSL3_MD5_MAC, { 0, 16, CKF_DERIVE}, PR_FALSE},
- {CKM_SSL3_SHA1_MAC, { 0, 20, CKF_DERIVE}, PR_FALSE},
- {CKM_MD5_KEY_DERIVATION, { 0, 16, CKF_DERIVE}, PR_FALSE},
- {CKM_MD2_KEY_DERIVATION, { 0, 16, CKF_DERIVE}, PR_FALSE},
- {CKM_SHA1_KEY_DERIVATION, { 0, 20, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- /* ---------------------- PBE Key Derivations ------------------------ */
- {CKM_PBE_MD2_DES_CBC, {64, 64, CKF_DERIVE}, PR_TRUE},
- {CKM_PBE_MD5_DES_CBC, {64, 64, CKF_DERIVE}, PR_TRUE},
- /* ------------------ NETSCAPE PBE Key Derivations ------------------- */
- {CKM_NETSCAPE_PBE_SHA1_DES_CBC, { 64, 64, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, {192, 192, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, {192, 192, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC, { 40, 40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC, {128, 128, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4, { 40, 40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4, {128, 128, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_DES3_EDE_CBC, {192, 192, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_DES2_EDE_CBC, {192, 192, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC2_40_CBC, { 40, 40, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC2_128_CBC, {128, 128, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC4_40, { 40, 40, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC4_128, {128, 128, CKF_GENERATE}, PR_TRUE},
-};
-static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
-/* load up our token database */
-static CK_RV pk11_importKeyDB(PK11Slot *slot);
-
-/*
- * Configuration utils
- */
-void
-PK11_ConfigurePKCS11(char *man, char *libdes, char *tokdes, char *ptokdes,
- char *slotdes, char *pslotdes, char *fslotdes, char *fpslotdes,
- int minPwd, int pwRequired)
-{
-
- /* make sure the internationalization was done correctly... */
- if (man && (PORT_Strlen(man) == 33)) {
- manufacturerID = man;
- }
- if (libdes && (PORT_Strlen(libdes) == 33)) {
- libraryDescription = libdes;
- }
- if (tokdes && (PORT_Strlen(tokdes) == 33)) {
- tokDescription = tokdes;
- }
- if (ptokdes && (PORT_Strlen(ptokdes) == 33)) {
- privTokDescription = ptokdes;
- }
- if (slotdes && (PORT_Strlen(slotdes) == 65)) {
- slotDescription = slotdes;
- }
- if (pslotdes && (PORT_Strlen(pslotdes) == 65)) {
- privSlotDescription = pslotdes;
- }
-
- if (minimumPinLen <= PK11_MAX_PIN) {
- minimumPinLen = minPwd;
- }
- if ((minimumPinLen == 0) && (pwRequired) &&
- (minimumPinLen <= PK11_MAX_PIN)) {
- minimumPinLen = 1;
- }
-
- PK11_ConfigureFIPS(fslotdes,fpslotdes);
-
- return;
-}
-
-/*
- * ******************** Password Utilities *******************************
- */
-
-/* Handle to give the password to the database. user arg should be a pointer
- * to the slot. */
-static SECItem *pk11_givePass(void *sp,SECKEYKeyDBHandle *handle)
-{
- PK11Slot *slot = (PK11Slot *)sp;
-
- if (slot->password == NULL) return NULL;
-
- return SECITEM_DupItem(slot->password);
-}
-
-/*
- * see if the key DB password is enabled
- */
-PRBool
-pk11_hasNullPassword(SECItem **pwitem)
-{
- PRBool pwenabled;
- SECKEYKeyDBHandle *keydb;
-
- keydb = SECKEY_GetDefaultKeyDB();
- pwenabled = PR_FALSE;
- *pwitem = NULL;
- if (SECKEY_HasKeyDBPassword (keydb) == SECSuccess) {
- *pwitem = SECKEY_HashPassword("", keydb->global_salt);
- if ( *pwitem ) {
- if (SECKEY_CheckKeyDBPassword (keydb, *pwitem) == SECSuccess) {
- pwenabled = PR_TRUE;
- } else {
- SECITEM_ZfreeItem(*pwitem, PR_TRUE);
- *pwitem = NULL;
- }
- }
- }
-
- return pwenabled;
-}
-
-/*
- * ******************** Object Creation Utilities ***************************
- */
-
-
-/* Make sure a given attribute exists. If it doesn't, initialize it to
- * value and len
- */
-CK_RV
-pk11_defaultAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *value,
- unsigned int len)
-{
- if ( !pk11_hasAttribute(object, type)) {
- return pk11_AddAttributeType(object,type,value,len);
- }
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Data Object
- */
-static CK_RV
-pk11_handleDataObject(PK11Session *session,PK11Object *object)
-{
- CK_RV crv;
-
- /* first reject private and token data objects */
- if (pk11_isTrue(object,CKA_PRIVATE) || pk11_isTrue(object,CKA_TOKEN)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* now just verify the required date fields */
- crv = pk11_defaultAttribute(object,CKA_APPLICATION,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_VALUE,NULL,0);
- if (crv != CKR_OK) return crv;
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Certificate Object
- */
-static CK_RV
-pk11_handleCertObject(PK11Session *session,PK11Object *object)
-{
- PK11Attribute *attribute;
- CK_CERTIFICATE_TYPE type;
- SECItem derCert;
- char *label;
- CERTCertDBHandle *handle;
- CERTCertificate *cert;
- CK_RV crv;
-
- /* certificates must have a type */
- if ( !pk11_hasAttribute(object,CKA_CERTIFICATE_TYPE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* we can't store any certs private */
- if (pk11_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* We only support X.509 Certs for now */
- attribute = pk11_FindAttribute(object,CKA_CERTIFICATE_TYPE);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- type = *(CK_CERTIFICATE_TYPE *)attribute->attrib.pValue;
- pk11_FreeAttribute(attribute);
-
- if (type != CKC_X_509) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* X.509 Certificate */
-
- /* make sure we have a cert */
- if ( !pk11_hasAttribute(object,CKA_VALUE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* in PKCS #11, Subject is a required field */
- if ( !pk11_hasAttribute(object,CKA_SUBJECT) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /*
- * now parse the certificate
- */
- handle = CERT_GetDefaultCertDB();
-
- /* get the nickname */
- label = pk11_getString(object,CKA_LABEL);
- object->label = label;
- if (label == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /* get the der cert */
- attribute = pk11_FindAttribute(object,CKA_VALUE);
- derCert.data = (unsigned char *)attribute->attrib.pValue;
- derCert.len = attribute->attrib.ulValueLen ;
-
- cert = CERT_NewTempCertificate(handle, &derCert, label, PR_FALSE, PR_TRUE);
- pk11_FreeAttribute(attribute);
- if (cert == NULL) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* add it to the object */
- object->objectInfo = cert;
- object->infoFree = (PK11Free) CERT_DestroyCertificate;
-
- /* now just verify the required date fields */
- crv = pk11_defaultAttribute(object, CKA_ID, NULL, 0);
- if (crv != CKR_OK) { return crv; }
- crv = pk11_defaultAttribute(object,CKA_ISSUER,
- pk11_item_expand(&cert->derIssuer));
- if (crv != CKR_OK) { return crv; }
- crv = pk11_defaultAttribute(object,CKA_SERIAL_NUMBER,
- pk11_item_expand(&cert->serialNumber));
- if (crv != CKR_OK) { return crv; }
-
-
- if (pk11_isTrue(object,CKA_TOKEN)) {
- SECCertUsage *certUsage = NULL;
- CERTCertTrust trust = { CERTDB_USER, CERTDB_USER, CERTDB_USER };
-
- attribute = pk11_FindAttribute(object,CKA_NETSCAPE_TRUST);
- if(attribute) {
- certUsage = (SECCertUsage*)attribute->attrib.pValue;
- pk11_FreeAttribute(attribute);
- }
-
- /* Temporary for PKCS 12 */
- if(cert->nickname == NULL) {
- /* use the arena so we at least don't leak memory */
- cert->nickname = (char *)PORT_ArenaAlloc(cert->arena,
- PORT_Strlen(label)+1);
- if(cert->nickname == NULL) {
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(cert->nickname, label, PORT_Strlen(label));
- }
-
- /* only add certs that have a private key */
- if (SECKEY_KeyForCertExists(SECKEY_GetDefaultKeyDB(),cert)
- != SECSuccess) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- if (CERT_AddTempCertToPerm(cert, label, &trust) != SECSuccess) {
- return CKR_HOST_MEMORY;
- }
- if(certUsage) {
- if(CERT_ChangeCertTrustByUsage(CERT_GetDefaultCertDB(),
- cert, *certUsage) != SECSuccess) {
- return CKR_HOST_MEMORY;
- }
- }
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
- object->inDB = PR_TRUE;
- }
-
- /* label has been adopted by object->label */
- /*PORT_Free(label); */
-
- return CKR_OK;
-}
-
-SECKEYLowPublicKey * pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key);
-/*
- * check the consistancy and initialize a Public Key Object
- */
-static CK_RV
-pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL encrypt = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL wrap = CK_TRUE;
- CK_RV crv;
-
- switch (key_type) {
- case CKK_RSA:
- if ( !pk11_hasAttribute(object, CKA_MODULUS)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- break;
- case CKK_DSA:
- if ( !pk11_hasAttribute(object, CKA_PRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_SUBPRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_BASE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_VALUE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- wrap = CK_FALSE;
- break;
- case CKK_DH:
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* make sure the required fields exist */
- crv = pk11_defaultAttribute(object,CKA_SUBJECT,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_VERIFY_RECOVER,
- &recover,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- object->objectInfo = pk11_GetPubKey(object,key_type);
- object->infoFree = (PK11Free) SECKEY_LowDestroyPublicKey;
-
- if (pk11_isTrue(object,CKA_TOKEN)) {
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB);
- }
-
- return CKR_OK;
-}
-/* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
-static SECItem *
-pk11_GetPubItem(SECKEYPublicKey *pubKey) {
- SECItem *pubItem = NULL;
- /* get value to compare from the cert's public key */
- switch ( pubKey->keyType ) {
- case rsaKey:
- pubItem = &pubKey->u.rsa.modulus;
- break;
- case dsaKey:
- pubItem = &pubKey->u.dsa.publicValue;
- break;
- default:
- break;
- }
- return pubItem;
-}
-
-typedef struct {
- CERTCertificate *cert;
- SECItem *pubKey;
-} find_cert_callback_arg;
-
-static SECStatus
-find_cert_by_pub_key(CERTCertificate *cert, SECItem *k, void *arg)
-{
- find_cert_callback_arg *cbarg;
- SECKEYPublicKey *pubKey = NULL;
- SECItem *pubItem;
-
- if((cert == NULL) || (arg == NULL)) {
- return SECFailure;
- }
-
- /* if this cert doesn't look like a user cert, we aren't interested */
- if (!((cert->isperm) && (cert->trust) &&
- (( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER )) &&
- ( cert->nickname != NULL ) ) ) {
- goto done;
- }
-
- /* get cert's public key */
- pubKey = CERT_ExtractPublicKey(cert);
- if ( pubKey == NULL ) {
- goto done;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
- pubItem = pk11_GetPubItem(pubKey);
- if (pubItem == NULL) goto done;
-
- cbarg = (find_cert_callback_arg *)arg;
-
- if(SECITEM_CompareItem(pubItem, cbarg->pubKey) == SECEqual) {
- cbarg->cert = CERT_DupCertificate(cert);
- return SECFailure;
- }
-
-done:
- if ( pubKey ) {
- SECKEY_DestroyPublicKey(pubKey);
- }
-
- return (SECSuccess);
-}
-
-static PK11Object *pk11_importCertificate(PK11Slot *slot,CERTCertificate *cert,
- unsigned char *data, unsigned int size, PRBool needCert);
-/*
- * find a cert associated with the key and load it.
- */
-static SECStatus
-reload_existing_certificate(PK11Object *privKeyObject,SECItem *pubKey)
-{
- find_cert_callback_arg cbarg;
- SECItem nickName;
- CERTCertificate *cert = NULL;
- CK_RV crv;
- SECStatus rv;
-
- cbarg.pubKey = pubKey;
- cbarg.cert = NULL;
- SEC_TraversePermCerts(CERT_GetDefaultCertDB(),
- find_cert_by_pub_key, (void *)&cbarg);
- if (cbarg.cert != NULL) {
- CERTCertificate *cert = NULL;
- /* can anyone tell me why this is call is necessary? rjr */
- cert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),
- &cbarg.cert->derCert);
-
- /* does the certificate in the database have a
- * nickname? if not, it probably was inserted
- * through SMIME and a nickname needs to be
- * set.
- */
- if (cert && !cert->nickname) {
- crv=pk11_Attribute2SecItem(NULL,&nickName,privKeyObject,CKA_LABEL);
- if (crv != CKR_OK) {
- goto loser;
- }
- rv = CERT_AddPermNickname(cert, (char *)nickName.data);
- SECITEM_ZfreeItem(&nickName, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- /* associate the certificate with the key */
- pk11_importCertificate(privKeyObject->slot, cert, pubKey->data,
- pubKey->len, PR_FALSE);
- }
-
- return SECSuccess;
-loser:
- if (cert) CERT_DestroyCertificate(cert);
- if (cbarg.cert) CERT_DestroyCertificate(cbarg.cert);
- return SECFailure;
-}
-
-static SECKEYLowPrivateKey * pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key);
-/*
- * check the consistancy and initialize a Private Key Object
- */
-static CK_RV
-pk11_handlePrivateKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL encrypt = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL wrap = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- SECItem mod;
- CK_RV crv;
-
- switch (key_type) {
- case CKK_RSA:
- if ( !pk11_hasAttribute(object, CKA_MODULUS)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_PRIVATE_EXPONENT)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_PRIME_1)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_PRIME_2)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_EXPONENT_1)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_EXPONENT_2)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_COEFFICIENT)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- /* make sure Netscape DB attribute is set correctly */
- crv = pk11_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS);
- if (crv != CKR_OK) return crv;
- crv = pk11_forceAttribute(object, CKA_NETSCAPE_DB,
- pk11_item_expand(&mod));
- if (mod.data) PORT_Free(mod.data);
- if (crv != CKR_OK) return crv;
-
- break;
- case CKK_DSA:
- if ( !pk11_hasAttribute(object, CKA_PRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_SUBPRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_BASE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_VALUE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !pk11_hasAttribute(object, CKA_NETSCAPE_DB)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- wrap = CK_FALSE;
- break;
- case CKK_DH:
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- crv = pk11_defaultAttribute(object,CKA_SUBJECT,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_SIGN_RECOVER,&recover,
- sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_UNWRAP,&wrap,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- /* the next two bits get modified only in the key gen and token cases */
- crv = pk11_forceAttribute(object,CKA_ALWAYS_SENSITIVE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_forceAttribute(object,CKA_NEVER_EXTRACTABLE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- if (pk11_isTrue(object,CKA_TOKEN)) {
- SECKEYLowPrivateKey *privKey;
- char *label;
- SECStatus rv = SECSuccess;
- SECItem pubKey;
-
- privKey=pk11_mkPrivKey(object,key_type);
- if (privKey == NULL) return CKR_HOST_MEMORY;
- label = object->label = pk11_getString(object,CKA_LABEL);
-
- crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv == CKR_OK) {
- rv = SECKEY_StoreKeyByPublicKey(SECKEY_GetDefaultKeyDB(),
- privKey, &pubKey, label,
- (SECKEYGetPasswordKey) pk11_givePass, object->slot);
-
- /* check for the existance of an existing certificate and activate
- * it if necessary */
- if (rv == SECSuccess) {
- reload_existing_certificate(object,&pubKey);
- }
-
- if (pubKey.data) PORT_Free(pubKey.data);
- } else {
- rv = SECFailure;
- }
-
- SECKEY_LowDestroyPrivateKey(privKey);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
- object->inDB = PR_TRUE;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- } else {
- object->objectInfo = pk11_mkPrivKey(object,key_type);
- if (object->objectInfo == NULL) return CKR_HOST_MEMORY;
- object->infoFree = (PK11Free) SECKEY_LowDestroyPrivateKey;
- }
- /* now NULL out the sensitive attributes */
- if (pk11_isTrue(object,CKA_SENSITIVE)) {
- pk11_nullAttribute(object,CKA_PRIVATE_EXPONENT);
- pk11_nullAttribute(object,CKA_PRIME_1);
- pk11_nullAttribute(object,CKA_PRIME_2);
- pk11_nullAttribute(object,CKA_EXPONENT_1);
- pk11_nullAttribute(object,CKA_EXPONENT_2);
- pk11_nullAttribute(object,CKA_COEFFICIENT);
- }
- return CKR_OK;
-}
-
-/* forward delcare the DES formating function for handleSecretKey */
-void pk11_FormatDESKey(unsigned char *key, int length);
-static SECKEYLowPrivateKey *pk11_mkSecretKeyRep(PK11Object *object);
-
-/* Validate secret key data, and set defaults */
-static CK_RV
-validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
-{
- CK_RV crv;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- PK11Attribute *attribute = NULL;
- crv = pk11_defaultAttribute(object,CKA_SENSITIVE,
- isFIPS?&cktrue:&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_EXTRACTABLE,
- &cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_ENCRYPT,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_DECRYPT,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_SIGN,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_VERIFY,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_WRAP,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_UNWRAP,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- if ( !pk11_hasAttribute(object, CKA_VALUE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- /* the next two bits get modified only in the key gen and token cases */
- crv = pk11_forceAttribute(object,CKA_ALWAYS_SENSITIVE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_forceAttribute(object,CKA_NEVER_EXTRACTABLE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* some types of keys have a value length */
- crv = CKR_OK;
- switch (key_type) {
- /* force CKA_VALUE_LEN to be set */
- case CKK_GENERIC_SECRET:
- case CKK_RC2:
- case CKK_RC4:
- case CKK_RC5:
- case CKK_CAST:
- case CKK_CAST3:
- case CKK_CAST5:
- attribute = pk11_FindAttribute(object,CKA_VALUE);
- /* shouldn't happen */
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- crv = pk11_forceAttribute(object, CKA_VALUE_LEN,
- &attribute->attrib.ulValueLen, sizeof(CK_ULONG));
- pk11_FreeAttribute(attribute);
- break;
- /* force the value to have the correct parity */
- case CKK_DES:
- case CKK_DES2:
- case CKK_DES3:
- case CKK_CDMF:
- attribute = pk11_FindAttribute(object,CKA_VALUE);
- /* shouldn't happen */
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- pk11_FormatDESKey((unsigned char*)attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- pk11_FreeAttribute(attribute);
- break;
- default:
- break;
- }
-
- return crv;
-}
-/*
- * check the consistancy and initialize a Secret Key Object
- */
-static CK_RV
-pk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,
- PRBool isFIPS)
-{
- CK_RV crv;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- PK11Attribute *attribute = NULL;
- SECKEYLowPrivateKey *privKey = NULL;
- SECItem pubKey;
-
- pubKey.data = 0;
-
- /* First validate and set defaults */
- crv = validateSecretKey(object, key_type, isFIPS);
- if (crv != CKR_OK) goto loser;
-
- /* If the object is a TOKEN object, store in the database */
- if (pk11_isTrue(object,CKA_TOKEN)) {
- char *label;
- SECStatus rv = SECSuccess;
-
- privKey=pk11_mkSecretKeyRep(object);
- if (privKey == NULL) return CKR_HOST_MEMORY;
-
- label = object->label = pk11_getString(object,CKA_LABEL);
-
- crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_ID); /* Should this be ID? */
- if (crv != CKR_OK) goto loser;
-
- rv = SECKEY_StoreKeyByPublicKey(SECKEY_GetDefaultKeyDB(),
- privKey, &pubKey, label,
- (SECKEYGetPasswordKey) pk11_givePass, object->slot);
-
- object->inDB = PR_TRUE;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- }
-
-loser:
- if (privKey) SECKEY_LowDestroyPrivateKey(privKey);
- if (pubKey.data) PORT_Free(pubKey.data);
-
- return crv;
-}
-
-/*
- * check the consistancy and initialize a Key Object
- */
-static CK_RV
-pk11_handleKeyObject(PK11Session *session, PK11Object *object)
-{
- PK11Attribute *attribute;
- CK_KEY_TYPE key_type;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_RV crv;
-
- /* verify the required fields */
- if ( !pk11_hasAttribute(object,CKA_KEY_TYPE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* now verify the common fields */
- crv = pk11_defaultAttribute(object,CKA_ID,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_START_DATE,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_END_DATE,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* get the key type */
- attribute = pk11_FindAttribute(object,CKA_KEY_TYPE);
- key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
- pk11_FreeAttribute(attribute);
-
- switch (object->objclass) {
- case CKO_PUBLIC_KEY:
- return pk11_handlePublicKeyObject(object,key_type);
- case CKO_PRIVATE_KEY:
- return pk11_handlePrivateKeyObject(object,key_type);
- case CKO_SECRET_KEY:
- /* make sure the required fields exist */
- return pk11_handleSecretKeyObject(object,key_type,
- (PRBool)(session->slot->slotID == FIPS_SLOT_ID));
- default:
- break;
- }
- return CKR_ATTRIBUTE_VALUE_INVALID;
-}
-
-/*
- * Handle Object does all the object consistancy checks, automatic attribute
- * generation, attribute defaulting, etc. If handleObject succeeds, the object
- * will be assigned an object handle, and the object pointer will be adopted
- * by the session. (that is don't free object).
- */
-CK_RV
-pk11_handleObject(PK11Object *object, PK11Session *session)
-{
- PK11Slot *slot = session->slot;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL cktrue = CK_TRUE;
- PK11Attribute *attribute;
- CK_RV crv;
-
- /* make sure all the base object types are defined. If not set the
- * defaults */
- crv = pk11_defaultAttribute(object,CKA_TOKEN,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_PRIVATE,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_LABEL,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_MODIFIABLE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* don't create a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (pk11_isTrue(object,CKA_PRIVATE))) {
- return CKR_USER_NOT_LOGGED_IN;
- }
-
-
- if (((session->info.flags & CKF_RW_SESSION) == 0) &&
- (pk11_isTrue(object,CKA_TOKEN))) {
- return CKR_SESSION_READ_ONLY;
- }
-
- if (pk11_isTrue(object, CKA_TOKEN)) {
- if (slot->DB_loaded == PR_FALSE) {
- /* we are creating a token object, make sure we load the database
- * first so we don't get duplicates....
- * ... NOTE: This assumes we are logged in as well!
- */
- pk11_importKeyDB(slot);
- slot->DB_loaded = PR_TRUE;
- }
- }
-
- /* PKCS #11 object ID's are unique for all objects on a
- * token */
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- object->handle = slot->tokenIDCount++;
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
-
- /* get the object class */
- attribute = pk11_FindAttribute(object,CKA_CLASS);
- if (attribute == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- object->objclass = *(CK_OBJECT_CLASS *)attribute->attrib.pValue;
- pk11_FreeAttribute(attribute);
-
- /* now handle the specific. Get a session handle for these functions
- * to use */
- switch (object->objclass) {
- case CKO_DATA:
- crv = pk11_handleDataObject(session,object);
- case CKO_CERTIFICATE:
- crv = pk11_handleCertObject(session,object);
- break;
- case CKO_PRIVATE_KEY:
- case CKO_PUBLIC_KEY:
- case CKO_SECRET_KEY:
- crv = pk11_handleKeyObject(session,object);
- break;
- default:
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- break;
- }
-
- /* can't fail from here on out unless the pk_handlXXX functions have
- * failed the request */
- if (crv != CKR_OK) {
- return crv;
- }
-
- /* now link the object into the slot and session structures */
- object->slot = slot;
- pk11_AddObject(session,object);
-
- return CKR_OK;
-}
-
-/* import a private key as an object. We don't call handle object.
- * because we the private key came from the key DB and we don't want to
- * write back out again */
-static PK11Object *
-pk11_importPrivateKey(PK11Slot *slot,SECKEYLowPrivateKey *lowPriv,
- SECItem *dbKey)
-{
- PK11Object *privateKey;
- CK_KEY_TYPE key_type;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL sign = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL decrypt = CK_TRUE;
- CK_BBOOL derive = CK_FALSE;
- CK_RV crv = CKR_OK;
- CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
- unsigned char cka_id[SHA1_LENGTH];
-
- /*
- * now lets create an object to hang the attributes off of
- */
- privateKey = pk11_NewObject(slot); /* fill in the handle later */
- if (privateKey == NULL) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* Netscape Private Attribute for dealing with database storeage */
- if (pk11_AddAttributeType(privateKey, CKA_NETSCAPE_DB,
- pk11_item_expand(dbKey)) ) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* now force the CKA_ID */
- SHA1_HashBuf(cka_id, (unsigned char *)dbKey->data, (uint32)dbKey->len);
- if (pk11_AddAttributeType(privateKey, CKA_ID, cka_id, sizeof(cka_id))) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
-
- /* Fill in the common Default values */
- if (pk11_AddAttributeType(privateKey,CKA_CLASS, &privClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_PRIVATE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_LABEL, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DERIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- /* local: well we really don't know for sure... it could have been an
- * imported key, but it's not a useful attribute anyway. */
- if (pk11_AddAttributeType(privateKey,CKA_LOCAL, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SENSITIVE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_EXTRACTABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- /* is this really true? Maybe we should just say false here? */
- if (pk11_AddAttributeType(privateKey,CKA_ALWAYS_SENSITIVE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_NEVER_EXTRACTABLE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- /* NOTE: for safety sake we *DO NOT* remember critical attributes. PKCS #11
- * will look them up again from the database when it needs them.
- */
- switch (lowPriv->keyType) {
- case rsaKey:
- /* format the keys */
- key_type = CKK_RSA;
- sign = CK_TRUE;
- recover = CK_TRUE;
- decrypt = CK_TRUE;
- derive = CK_FALSE;
- /* now fill in the RSA dependent parameters in the public key */
- crv = pk11_AddAttributeType(privateKey,CKA_MODULUS,
- pk11_item_expand(&lowPriv->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&lowPriv->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_1,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_2,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_1,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_2,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_COEFFICIENT,NULL,0);
- break;
- case dsaKey:
- key_type = CKK_DSA;
- sign = CK_TRUE;
- recover = CK_FALSE;
- decrypt = CK_FALSE;
- derive = CK_FALSE;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_SUBPRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_VALUE,NULL,0);
- if (crv != CKR_OK) break;
- break;
- case dhKey:
- key_type = CKK_DH;
- sign = CK_FALSE;
- decrypt = CK_FALSE;
- recover = CK_FALSE;
- derive = CK_TRUE;
- crv = CKR_MECHANISM_INVALID;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (crv != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
-
- if (pk11_AddAttributeType(privateKey,CKA_SIGN, &sign,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SIGN_RECOVER, &recover,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DECRYPT, &decrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_UNWRAP, &decrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DERIVE, &derive,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- privateKey->handle = slot->tokenIDCount++;
- privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
- privateKey->objclass = privClass;
- privateKey->slot = slot;
- privateKey->inDB = PR_TRUE;
-
- return privateKey;
-}
-
-/* import a private key or cert as a public key object.*/
-static PK11Object *
-pk11_importPublicKey(PK11Slot *slot,
- SECKEYLowPrivateKey *lowPriv, CERTCertificate *cert, SECItem *dbKey)
-{
- PK11Object *publicKey = NULL;
- CK_KEY_TYPE key_type;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL verify = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL encrypt = CK_TRUE;
- CK_BBOOL derive = CK_FALSE;
- CK_RV crv = CKR_OK;
- CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
- unsigned char cka_id[SHA1_LENGTH];
- KeyType keyType = nullKey;
- SECKEYPublicKey *pubKey = NULL;
- CK_ATTRIBUTE theTemplate[2];
- PK11ObjectListElement *objectList = NULL;
-
- if (lowPriv == NULL) {
- pubKey = CERT_ExtractPublicKey(cert);
- if (pubKey == NULL) {
- goto failed;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
- dbKey = pk11_GetPubItem(pubKey);
- if (dbKey == NULL) {
- goto failed;
- }
- }
- SHA1_HashBuf(cka_id, (unsigned char *)dbKey->data, (uint32)dbKey->len);
- theTemplate[0].type = CKA_ID;
- theTemplate[0].pValue = cka_id;
- theTemplate[0].ulValueLen = sizeof(cka_id);
- theTemplate[1].type = CKA_CLASS;
- theTemplate[1].pValue = &pubClass;
- theTemplate[1].ulValueLen = sizeof(CK_OBJECT_CLASS);
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, theTemplate, 2, slot->isLoggedIn);
- if ((crv == CKR_OK) && (objectList != NULL)) {
- goto failed;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- publicKey = pk11_NewObject(slot); /* fill in the handle later */
- if (publicKey == NULL) {
- goto failed;
- }
-
- /* now force the CKA_ID */
- if (pk11_AddAttributeType(publicKey, CKA_ID, cka_id, sizeof(cka_id))) {
- goto failed;
- }
-
- /* Fill in the common Default values */
- if (pk11_AddAttributeType(publicKey,CKA_CLASS,&pubClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_LABEL, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
- goto failed;
- }
- /* local: well we really don't know for sure... it could have been an
- * imported key, but it's not a useful attribute anyway. */
- if (pk11_AddAttributeType(publicKey,CKA_LOCAL, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_SENSITIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_EXTRACTABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_ALWAYS_SENSITIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_NEVER_EXTRACTABLE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- if (lowPriv == NULL) {
-
- keyType = pubKey->keyType;
- } else {
- keyType = lowPriv->keyType;
- }
-
-
- switch (keyType) {
- case rsaKey:
- /* format the keys */
- key_type = CKK_RSA;
- verify = CK_TRUE;
- recover = CK_TRUE;
- encrypt = CK_TRUE;
- derive = CK_FALSE;
- /* now fill in the RSA dependent parameters in the public key */
- if (lowPriv) {
- crv = pk11_AddAttributeType(publicKey,CKA_MODULUS,
- pk11_item_expand(&lowPriv->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&lowPriv->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- } else {
- crv = pk11_AddAttributeType(publicKey,CKA_MODULUS,
- pk11_item_expand(&pubKey->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&pubKey->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- }
- break;
- case dsaKey:
- key_type = CKK_DSA;
- verify = CK_TRUE;
- recover = CK_FALSE;
- encrypt = CK_FALSE;
- derive = CK_FALSE;
- if (lowPriv) {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&lowPriv->u.dsa.publicValue));
- if (crv != CKR_OK) break;
- } else {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&pubKey->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME,
- pk11_item_expand(&pubKey->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&pubKey->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&pubKey->u.dsa.publicValue));
- if (crv != CKR_OK) break;
- }
- break;
- case dhKey:
- key_type = CKK_DH;
- verify = CK_FALSE;
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- derive = CK_TRUE;
- crv = CKR_MECHANISM_INVALID;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (pubKey) {
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
- }
-
- if (crv != CKR_OK) {
- goto failed;
- }
-
- if (pk11_AddAttributeType(publicKey,CKA_VERIFY, &verify,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_VERIFY_RECOVER, &recover,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_ENCRYPT, &encrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_WRAP, &encrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_DERIVE, &derive,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE)) != CKR_OK) {
- goto failed;
- }
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- publicKey->handle = slot->tokenIDCount++;
- publicKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB);
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
- publicKey->objclass = pubClass;
- publicKey->slot = slot;
- publicKey->inDB = PR_FALSE; /* not really in the Database */
-
- return publicKey;
-failed:
- if (pubKey) SECKEY_DestroyPublicKey(pubKey);
- if (publicKey) pk11_FreeObject(publicKey);
- return NULL;
-}
-
-/*
- * Question.. Why doesn't import Cert call pk11_handleObject, or
- * pk11 handleCertObject? Answer: because they will try to write
- * this cert back out to the Database, even though it is already in
- * the database.
- */
-static PK11Object *
-pk11_importCertificate(PK11Slot *slot, CERTCertificate *cert,
- unsigned char *data, unsigned int size, PRBool needObject)
-{
- PK11Object *certObject = NULL;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_CERTIFICATE_TYPE certType = CKC_X_509;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- unsigned char cka_id[SHA1_LENGTH];
- CK_ATTRIBUTE theTemplate;
- PK11ObjectListElement *objectList = NULL;
- CK_RV crv;
-
-
- /*
- * first make sure that no object for this cert already exists.
- */
- theTemplate.type = CKA_VALUE;
- theTemplate.pValue = cert->derCert.data;
- theTemplate.ulValueLen = cert->derCert.len;
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, &theTemplate, 1, slot->isLoggedIn);
- if ((crv == CKR_OK) && (objectList != NULL)) {
- if (needObject) {
- pk11_ReferenceObject(objectList->object);
- certObject = objectList->object;
- }
- pk11_FreeObjectList(objectList);
- return certObject;
- }
-
- /*
- * now lets create an object to hang the attributes off of
- */
- certObject = pk11_NewObject(slot); /* fill in the handle later */
- if (certObject == NULL) {
- return NULL;
- }
-
- /* First set the CKA_ID */
- if (data == NULL) {
- SECKEYPublicKey *pubKey = CERT_ExtractPublicKey(cert);
- SECItem *pubItem;
- if (pubKey == NULL) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise.
- */
- pubItem =pk11_GetPubItem(pubKey);
- if (pubItem == NULL) {
- SECKEY_DestroyPublicKey(pubKey);
- pk11_FreeObject(certObject);
- return NULL;
- }
- SHA1_HashBuf(cka_id, (unsigned char *)pubItem->data,
- (uint32)pubItem->len);
- SECKEY_DestroyPublicKey(pubKey);
- } else {
- SHA1_HashBuf(cka_id, (unsigned char *)data, (uint32)size);
- }
- if (pk11_AddAttributeType(certObject, CKA_ID, cka_id, sizeof(cka_id))) {
- pk11_FreeObject(certObject);
- return NULL;
- }
-
- /* initalize the certificate attributes */
- if (pk11_AddAttributeType(certObject, CKA_CLASS, &certClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_LABEL, cert->nickname,
- PORT_Strlen(cert->nickname))
- != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_CERTIFICATE_TYPE, &certType,
- sizeof(CK_CERTIFICATE_TYPE))!=CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_VALUE,
- pk11_item_expand(&cert->derCert)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_ISSUER,
- pk11_item_expand(&cert->derIssuer)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_SUBJECT,
- pk11_item_expand(&cert->derSubject)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_SERIAL_NUMBER,
- pk11_item_expand(&cert->serialNumber)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
-
-
- certObject->objectInfo = CERT_DupCertificate(cert);
- certObject->infoFree = (PK11Free) CERT_DestroyCertificate;
-
- /* now just verify the required date fields */
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- certObject->handle = slot->tokenIDCount++;
- certObject->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
- certObject->objclass = certClass;
- certObject->slot = slot;
- certObject->inDB = PR_TRUE;
- pk11_AddSlotObject(slot, certObject);
- if (needObject) {
- pk11_ReferenceObject(certObject);
- } else {
- certObject = NULL;
- }
-
- return certObject;
-}
-
-/*
- * ******************** Public Key Utilities ***************************
- */
-/* Generate a low public key structure from an object */
-SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
-{
- SECKEYLowPublicKey *pubKey;
- PLArenaPool *arena;
- CK_RV crv;
-
- if (object->objclass != CKO_PUBLIC_KEY) {
- return NULL;
- }
-
- /* If we already have a key, use it */
- if (object->objectInfo) {
- return (SECKEYLowPublicKey *)object->objectInfo;
- }
-
- /* allocate the structure */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return NULL;
-
- pubKey = (SECKEYLowPublicKey *)
- PORT_ArenaAlloc(arena,sizeof(SECKEYLowPublicKey));
- if (pubKey == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
-
- /* fill in the structure */
- pubKey->arena = arena;
- switch (key_type) {
- case CKK_RSA:
- pubKey->keyType = rsaKey;
- crv = pk11_Attribute2SSecItem(arena,&pubKey->u.rsa.modulus,
- object,CKA_MODULUS);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&pubKey->u.rsa.publicExponent,
- object,CKA_PUBLIC_EXPONENT);
- break;
- case CKK_DSA:
- pubKey->keyType = dsaKey;
- crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.params.prime,
- object,CKA_PRIME);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.params.subPrime,
- object,CKA_SUBPRIME);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.params.base,
- object,CKA_BASE);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.publicValue,
- object,CKA_VALUE);
- break;
- case CKK_DH:
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
-
- object->objectInfo = pubKey;
- object->infoFree = (PK11Free) SECKEY_LowDestroyPublicKey;
- return pubKey;
-}
-
-/* make a private key from a verified object */
-static SECKEYLowPrivateKey *
-pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
-{
- SECKEYLowPrivateKey *privKey;
- PLArenaPool *arena;
- CK_RV crv = CKR_OK;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return NULL;
-
- privKey = (SECKEYLowPrivateKey *)
- PORT_ArenaAlloc(arena,sizeof(SECKEYLowPrivateKey));
- if (privKey == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
-
- /* in future this would be a switch on key_type */
- privKey->arena = arena;
- switch (key_type) {
- case CKK_RSA:
- privKey->keyType = rsaKey;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.modulus,
- object,CKA_MODULUS);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.publicExponent,object,
- CKA_PUBLIC_EXPONENT);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.privateExponent,object,
- CKA_PRIVATE_EXPONENT);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.prime1,object,
- CKA_PRIME_1);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.prime2,object,
- CKA_PRIME_2);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.exponent1,
- object, CKA_EXPONENT_1);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.exponent2,
- object, CKA_EXPONENT_2);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.coefficient,object,
- CKA_COEFFICIENT);
- if (crv != CKR_OK) break;
- rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
- SEC_PRIVATE_KEY_VERSION);
- if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
- break;
-
- case CKK_DSA:
- privKey->keyType = dsaKey;
- crv = pk11_Attribute2SSecItem(arena,&privKey->u.dsa.params.prime,
- object,CKA_PRIME);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&privKey->u.dsa.params.subPrime,
- object,CKA_SUBPRIME);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&privKey->u.dsa.params.base,
- object,CKA_BASE);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&privKey->u.dsa.privateValue,
- object,CKA_VALUE);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(arena,&privKey->u.dsa.publicValue,
- object,CKA_NETSCAPE_DB);
- /* can't set the public value.... */
- break;
- case CKK_DH:
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- return privKey;
-}
-
-
-/* Generate a low private key structure from an object */
-SECKEYLowPrivateKey *
-pk11_GetPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
-{
- SECKEYLowPrivateKey *priv = NULL;
-
- if (object->objclass != CKO_PRIVATE_KEY) {
- return NULL;
- }
- if (object->objectInfo) {
- return (SECKEYLowPrivateKey *)object->objectInfo;
- }
-
- if (pk11_isTrue(object,CKA_TOKEN)) {
- /* grab it from the data base */
- char *label = pk11_getString(object,CKA_LABEL);
- SECItem pubKey;
- CK_RV crv;
-
- /* KEYID is the public KEY for DSA and DH, and the MODULUS for
- * RSA */
- crv=pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) return NULL;
-
- priv=SECKEY_FindKeyByPublicKey(SECKEY_GetDefaultKeyDB(),&pubKey,
- (SECKEYGetPasswordKey) pk11_givePass,
- object->slot);
- if (pubKey.data) PORT_Free(pubKey.data);
-
- /* don't 'cache' DB private keys */
- return priv;
- }
-
- priv = pk11_mkPrivKey(object, key_type);
- object->objectInfo = priv;
- object->infoFree = (PK11Free) SECKEY_LowDestroyPrivateKey;
- return priv;
-}
-
-/*
- **************************** Symetric Key utils ************************
- */
-/*
- * set the DES key with parity bits correctly
- */
-void
-pk11_FormatDESKey(unsigned char *key, int length)
-{
- int i;
-
- /* format the des key */
- for (i=0; i < length; i++) {
- key[i] = parityTable[key[i]>>1];
- }
-}
-
-/*
- * check a des key (des2 or des3 subkey) for weak keys.
- */
-PRBool
-pk11_CheckDESKey(unsigned char *key)
-{
- int i;
-
- /* format the des key with parity */
- pk11_FormatDESKey(key, 8);
-
- for (i=0; i < pk11_desWeakTableSize; i++) {
- if (PORT_Memcmp(key,pk11_desWeakTable[i],8) == 0) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
-/*
- * check if a des or triple des key is weak.
- */
-PRBool
-pk11_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type)
-{
-
- switch(key_type) {
- case CKK_DES:
- return pk11_CheckDESKey(key);
- case CKM_DES2_KEY_GEN:
- if (pk11_CheckDESKey(key)) return PR_TRUE;
- return pk11_CheckDESKey(&key[8]);
- case CKM_DES3_KEY_GEN:
- if (pk11_CheckDESKey(key)) return PR_TRUE;
- if (pk11_CheckDESKey(&key[8])) return PR_TRUE;
- return pk11_CheckDESKey(&key[16]);
- default:
- break;
- }
- return PR_FALSE;
-}
-
-
-/* make a fake private key representing a symmetric key */
-static SECKEYLowPrivateKey *
-pk11_mkSecretKeyRep(PK11Object *object)
-{
- SECKEYLowPrivateKey *privKey;
- PLArenaPool *arena = 0;
- CK_RV crv;
- SECStatus rv;
- static unsigned char derZero[1] = { 0 };
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
-
- privKey = (SECKEYLowPrivateKey *)
- PORT_ArenaAlloc(arena,sizeof(SECKEYLowPrivateKey));
- if (privKey == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
-
- privKey->arena = arena;
-
- /* Secret keys are represented in the database as "fake" RSA keys. The RSA key
- * is marked as a secret key representation by setting the public exponent field
- * to 0, which is an invalid RSA exponent. The other fields are set as follows:
- * modulus - CKA_ID value for the secret key
- * private exponent - CKA_VALUE (the key itself)
- * coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm
- * is used for the key.
- * all others - set to integer 0
- */
- privKey->keyType = rsaKey;
-
- /* The modulus is set to the key id of the symmetric key */
- crv=pk11_Attribute2SecItem(arena,&privKey->u.rsa.modulus,object,CKA_ID);
- if (crv != CKR_OK) goto loser;
-
- /* The public exponent is set to 0 length to indicate a special key */
- privKey->u.rsa.publicExponent.len = sizeof derZero;
- privKey->u.rsa.publicExponent.data = derZero;
-
- /* The private exponent is the actual key value */
- crv=pk11_Attribute2SecItem(arena,&privKey->u.rsa.privateExponent,object,CKA_VALUE);
- if (crv != CKR_OK) goto loser;
-
- /* All other fields empty - needs testing */
- privKey->u.rsa.prime1.len = sizeof derZero;
- privKey->u.rsa.prime1.data = derZero;
-
- privKey->u.rsa.prime2.len = sizeof derZero;
- privKey->u.rsa.prime2.data = derZero;
-
- privKey->u.rsa.exponent1.len = sizeof derZero;
- privKey->u.rsa.exponent1.data = derZero;
-
- privKey->u.rsa.exponent2.len = sizeof derZero;
- privKey->u.rsa.exponent2.data = derZero;
-
- /* Coeficient set to KEY_TYPE */
- crv=pk11_Attribute2SecItem(arena,&privKey->u.rsa.coefficient,object,CKA_KEY_TYPE);
- if (crv != CKR_OK) goto loser;
-
- /* Private key version field set normally for compatibility */
- rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,SEC_PRIVATE_KEY_VERSION);
- if (rv != SECSuccess) { crv = CKR_HOST_MEMORY; goto loser; }
-
-loser:
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- privKey = 0;
- }
-
- return privKey;
-}
-
-static PRBool
-isSecretKey(SECKEYLowPrivateKey *privKey)
-{
- if (privKey->keyType == rsaKey && privKey->u.rsa.publicExponent.len == 1 &&
- privKey->u.rsa.publicExponent.data[0] == 0)
- return PR_TRUE;
-
- return PR_FALSE;
-}
-
-/* Import a Secret Key */
-static PRBool
-importSecretKey(PK11Slot *slot, SECKEYLowPrivateKey *priv)
-{
- PK11Object *object;
- CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_KEY_TYPE key_type;
-
- /* Check for secret key representation, return if it isn't one */
- if (!isSecretKey(priv))
- return PR_FALSE;
-
- /*
- * now lets create an object to hang the attributes off of
- */
- object = pk11_NewObject(slot); /* fill in the handle later */
- if (object == NULL) {
- goto loser;
- }
-
- /* Set the ID value */
- if (pk11_AddAttributeType(object, CKA_ID,
- priv->u.rsa.modulus.data, priv->u.rsa.modulus.len)) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- /* initalize the object attributes */
- if (pk11_AddAttributeType(object, CKA_CLASS, &secretClass,
- sizeof(secretClass)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_TOKEN, &cktrue,
- sizeof(cktrue)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_VALUE,
- pk11_item_expand(&priv->u.rsa.privateExponent)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_KEY_TYPE,
- pk11_item_expand(&priv->u.rsa.coefficient)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
- key_type = *(CK_KEY_TYPE*)priv->u.rsa.coefficient.data;
-
- /* Validate and add default attributes */
- validateSecretKey(object, key_type, (PRBool)(slot->slotID == FIPS_SLOT_ID));
-
- /* now just verify the required date fields */
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- object->handle = slot->tokenIDCount++;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
-
- object->objclass = secretClass;
- object->slot = slot;
- object->inDB = PR_TRUE;
- pk11_AddSlotObject(slot, object);
-
-loser:
- return PR_TRUE;
-}
-
-
-/**********************************************************************
- *
- * Start of PKCS 11 functions
- *
- **********************************************************************/
-
-
-/* return the function list */
-CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
-{
- *pFunctionList = &pk11_funcList;
- return CKR_OK;
-}
-
-/*
- * initialize one of the slot structures. figure out which by the ID
- */
-CK_RV
-PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin)
-{
- int i;
- PK11Slot *slot = pk11_SlotFromID(slotID);
-#ifdef PKCS11_USE_THREADS
- slot->sessionLock = PR_NewLock();
- if (slot->sessionLock == NULL) return CKR_HOST_MEMORY;
- slot->objectLock = PR_NewLock();
- if (slot->objectLock == NULL) return CKR_HOST_MEMORY;
-#else
- slot->sessionLock = NULL;
- slot->objectLock = NULL;
-#endif
- for(i=0; i < SESSION_HASH_SIZE; i++) {
- slot->head[i] = NULL;
- }
- for(i=0; i < TOKEN_OBJECT_HASH_SIZE; i++) {
- slot->tokObjects[i] = NULL;
- }
- slot->password = NULL;
- slot->hasTokens = PR_FALSE;
- slot->sessionIDCount = 1;
- slot->sessionCount = 0;
- slot->rwSessionCount = 0;
- slot->tokenIDCount = 1;
- slot->needLogin = PR_FALSE;
- slot->isLoggedIn = PR_FALSE;
- slot->ssoLoggedIn = PR_FALSE;
- slot->DB_loaded = PR_FALSE;
- slot->slotID = slotID;
- if (needLogin) {
- /* if the data base is initialized with a null password,remember that */
- slot->needLogin = (PRBool)!pk11_hasNullPassword(&slot->password);
- }
- return CKR_OK;
-}
-
-/*
- * common initialization routines between PKCS #11 and FIPS
- */
-CK_RV PK11_LowInitialize(CK_VOID_PTR pReserved)
-{
- SECStatus rv = SECSuccess;
-
- /* initialize the Random number generater */
- rv = RNG_RNGInit();
-
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
- }
-
- SECKEY_SetDefaultKeyDBAlg(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
- return CKR_OK;
-}
-
-/* NSC_Initialize initializes the Cryptoki library. */
-CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
-{
- static PRBool init = PR_FALSE;
- CK_RV crv = CKR_OK;
-
- crv = PK11_LowInitialize(pReserved);
- if (crv != CKR_OK) return crv;
-
- /* intialize all the slots */
- if (!init) {
- crv = PK11_SlotInit(NETSCAPE_SLOT_ID,PR_FALSE);
- if (crv != CKR_OK) return crv;
- crv = PK11_SlotInit(PRIVATE_KEY_SLOT_ID,PR_TRUE);
- init = PR_TRUE;
- }
-
- return crv;
-}
-
-/* NSC_Finalize indicates that an application is done with the
- * Cryptoki library.*/
-CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
-{
- return CKR_OK;
-}
-
-
-/* NSC_GetInfo returns general information about Cryptoki. */
-CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
-{
- pInfo->cryptokiVersion.major = 2;
- pInfo->cryptokiVersion.minor = 1;
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- pInfo->libraryVersion.major = 4;
- pInfo->libraryVersion.minor = 0;
- PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32);
- pInfo->flags = 0;
- return CKR_OK;
-}
-
-/* NSC_GetSlotList obtains a list of slots in the system. */
-CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
-{
- *pulCount = 2;
- if (pSlotList != NULL) {
- pSlotList[0] = NETSCAPE_SLOT_ID;
- pSlotList[1] = PRIVATE_KEY_SLOT_ID;
- }
- return CKR_OK;
-}
-
-/* NSC_GetSlotInfo obtains information about a particular slot in the system. */
-CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
-{
- pInfo->firmwareVersion.major = 0;
- pInfo->firmwareVersion.minor = 0;
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->slotDescription,slotDescription,64);
- pInfo->flags = CKF_TOKEN_PRESENT;
- pInfo->hardwareVersion.major = 4;
- pInfo->hardwareVersion.minor = 1;
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->slotDescription,privSlotDescription,64);
- pInfo->flags = CKF_TOKEN_PRESENT;
- /* ok we really should read it out of the keydb file. */
- pInfo->hardwareVersion.major = PRIVATE_KEY_DB_FILE_VERSION;
- pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- default:
- break;
- }
- return CKR_SLOT_ID_INVALID;
-}
-
-#define CKF_THREAD_SAFE 0x8000 /* for now */
-
-/* NSC_GetTokenInfo obtains information about a particular token in
- * the system. */
-CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
-{
- PK11Slot *slot = pk11_SlotFromID(slotID);
- SECKEYKeyDBHandle *handle;
-
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->model,"Libsec 4.0 ",16);
- PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16);
- pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
- pInfo->ulSessionCount = slot->sessionCount;
- pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */
- pInfo->ulRwSessionCount = slot->rwSessionCount;
- pInfo->firmwareVersion.major = 0;
- pInfo->firmwareVersion.minor = 0;
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- PORT_Memcpy(pInfo->label,tokDescription,32);
- pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE;
- pInfo->ulMaxPinLen = 0;
- pInfo->ulMinPinLen = 0;
- pInfo->ulTotalPublicMemory = 0;
- pInfo->ulFreePublicMemory = 0;
- pInfo->ulTotalPrivateMemory = 0;
- pInfo->ulFreePrivateMemory = 0;
- pInfo->hardwareVersion.major = 4;
- pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
- PORT_Memcpy(pInfo->label,privTokDescription,32);
- handle = SECKEY_GetDefaultKeyDB();
- /*
- * we have three possible states which we may be in:
- * (1) No DB password has been initialized. This also means we
- * have no keys in the key db.
- * (2) Password initialized to NULL. This means we have keys, but
- * the user has chosen not use a password.
- * (3) Finally we have an initialized password whicn is not NULL, and
- * we will need to prompt for it.
- */
- if (SECKEY_HasKeyDBPassword(handle) == SECFailure) {
- pInfo->flags = CKF_THREAD_SAFE | CKF_LOGIN_REQUIRED;
- } else if (!slot->needLogin) {
- pInfo->flags = CKF_THREAD_SAFE | CKF_USER_PIN_INITIALIZED;
- } else {
- pInfo->flags = CKF_THREAD_SAFE |
- CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
- }
- pInfo->ulMaxPinLen = PK11_MAX_PIN;
- pInfo->ulMinPinLen = 0;
- if (minimumPinLen > 0) {
- pInfo->ulMinPinLen = (CK_ULONG)minimumPinLen;
- }
- pInfo->ulTotalPublicMemory = 1;
- pInfo->ulFreePublicMemory = 1;
- pInfo->ulTotalPrivateMemory = 1;
- pInfo->ulFreePrivateMemory = 1;
- pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
- pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- default:
- break;
- }
- return CKR_SLOT_ID_INVALID;
-}
-
-
-
-/* NSC_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
-{
- int i;
-
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- *pulCount = mechanismCount;
- if (pMechanismList != NULL) {
- for (i=0; i < (int) mechanismCount; i++) {
- pMechanismList[i] = mechanisms[i].type;
- }
- }
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
- *pulCount = 0;
- for (i=0; i < (int) mechanismCount; i++) {
- if (mechanisms[i].privkey) {
- (*pulCount)++;
- if (pMechanismList != NULL) {
- *pMechanismList++ = mechanisms[i].type;
- }
- }
- }
- return CKR_OK;
- default:
- break;
- }
- return CKR_SLOT_ID_INVALID;
-}
-
-
-/* NSC_GetMechanismInfo obtains information about a particular mechanism
- * possibly supported by a token. */
-CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo)
-{
- PRBool isPrivateKey;
- int i;
-
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- isPrivateKey = PR_FALSE;
- break;
- case PRIVATE_KEY_SLOT_ID:
- isPrivateKey = PR_TRUE;
- break;
- default:
- return CKR_SLOT_ID_INVALID;
- }
- for (i=0; i < (int) mechanismCount; i++) {
- if (type == mechanisms[i].type) {
- if (isPrivateKey && !mechanisms[i].privkey) {
- return CKR_MECHANISM_INVALID;
- }
- PORT_Memcpy(pInfo,&mechanisms[i].domestic,
- sizeof(CK_MECHANISM_INFO));
- return CKR_OK;
- }
- }
- return CKR_MECHANISM_INVALID;
-}
-
-static SECStatus
-pk11_TurnOffUser(CERTCertificate *cert, SECItem *k, void *arg)
-{
- CERTCertTrust trust;
- SECStatus rv;
-
- rv = CERT_GetCertTrust(cert,&trust);
- if (rv == SECSuccess && ((trust.emailFlags & CERTDB_USER) ||
- (trust.sslFlags & CERTDB_USER) ||
- (trust.objectSigningFlags & CERTDB_USER))) {
- trust.emailFlags &= ~CERTDB_USER;
- trust.sslFlags &= ~CERTDB_USER;
- trust.objectSigningFlags &= ~CERTDB_USER;
- CERT_ChangeCertTrust(cert->dbhandle,cert,&trust);
- }
- return SECSuccess;
-}
-
-/* NSC_InitToken initializes a token. */
-CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,CK_CHAR_PTR pLabel) {
- PK11Slot *slot = pk11_SlotFromID(slotID);
- SECKEYKeyDBHandle *handle;
- CERTCertDBHandle *certHandle;
- SECStatus rv;
- int i;
- PK11Object *object;
-
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- /* don't initialize the database if we aren't talking to a token
- * that uses the key database.
- */
- if (slotID == NETSCAPE_SLOT_ID) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* first, delete all our loaded key and cert objects from our
- * internal list. */
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- for (i=0; i < TOKEN_OBJECT_HASH_SIZE; i++) {
- do {
- object = slot->tokObjects[i];
- /* hand deque */
- /* this duplicates function of NSC_close session functions, but
- * because we know that we are freeing all the sessions, we can
- * do more efficient processing */
- if (object) {
- slot->tokObjects[i] = object->next;
-
- if (object->next) object->next->prev = NULL;
- object->next = object->prev = NULL;
- }
- if (object) pk11_FreeObject(object);
- } while (object != NULL);
- }
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
-
- /* then clear out the key database */
- handle = SECKEY_GetDefaultKeyDB();
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* what to do on an error here? */
- rv = SECKEY_ResetKeyDB(handle);
-
- /* finally mark all the user certs as non-user certs */
- certHandle = CERT_GetDefaultCertDB();
- if (certHandle == NULL) return CKR_OK;
-
- SEC_TraversePermCerts(certHandle,pk11_TurnOffUser, NULL);
-
- return CKR_OK; /*is this the right function for not implemented*/
-}
-
-
-/* NSC_InitPIN initializes the normal user's PIN. */
-CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
-{
- PK11Session *sp;
- PK11Slot *slot;
- SECKEYKeyDBHandle *handle;
- SECItem *newPin;
- char newPinStr[256];
- SECStatus rv;
-
-
- sp = pk11_SessionFromHandle(hSession);
- if (sp == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- if (sp->info.slotID == NETSCAPE_SLOT_ID) {
- pk11_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
- }
-
- /* should be an assert */
- if (!((sp->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (sp->info.slotID == FIPS_SLOT_ID)) ) {
- pk11_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
- }
-
- if (sp->info.state != CKS_RW_SO_FUNCTIONS) {
- pk11_FreeSession(sp);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- slot = pk11_SlotFromSession(sp);
- pk11_FreeSession(sp);
-
- /* make sure the pins aren't too long */
- if (ulPinLen > 255) {
- return CKR_PIN_LEN_RANGE;
- }
-
- handle = SECKEY_GetDefaultKeyDB();
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- if (SECKEY_HasKeyDBPassword(handle) != SECFailure) {
- return CKR_DEVICE_ERROR;
- }
-
- /* convert to null terminated string */
- PORT_Memcpy(newPinStr,pPin,ulPinLen);
- newPinStr[ulPinLen] = 0;
-
- /* build the hashed pins which we pass around */
- newPin = SECKEY_HashPassword(newPinStr,handle->global_salt);
- PORT_Memset(newPinStr,0,sizeof(newPinStr));
-
- /* change the data base */
- rv = SECKEY_SetKeyDBPassword(handle,newPin);
-
- /* Now update our local copy of the pin */
- if (rv == SECSuccess) {
- if (slot->password) {
- SECITEM_ZfreeItem(slot->password, PR_TRUE);
- }
- slot->password = newPin;
- if (ulPinLen == 0) slot->needLogin = PR_FALSE;
- return CKR_OK;
- }
- SECITEM_ZfreeItem(newPin, PR_TRUE);
- return CKR_PIN_INCORRECT;
-}
-
-
-/* NSC_SetPIN modifies the PIN of user that is currently logged in. */
-/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
-CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
-{
- PK11Session *sp;
- PK11Slot *slot;
- SECKEYKeyDBHandle *handle;
- SECItem *newPin;
- SECItem *oldPin;
- char newPinStr[256],oldPinStr[256];
- SECStatus rv;
-
-
- sp = pk11_SessionFromHandle(hSession);
- if (sp == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- if (sp->info.slotID == NETSCAPE_SLOT_ID) {
- pk11_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
- }
-
- /* should be an assert */
- /* should be an assert */
- if (!((sp->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (sp->info.slotID == FIPS_SLOT_ID)) ) {
- pk11_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
- }
-
- slot = pk11_SlotFromSession(sp);
- if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
- pk11_FreeSession(sp);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- pk11_FreeSession(sp);
-
- /* make sure the pins aren't too long */
- if ((ulNewLen > 255) || (ulOldLen > 255)) {
- return CKR_PIN_LEN_RANGE;
- }
-
-
- handle = SECKEY_GetDefaultKeyDB();
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* convert to null terminated string */
- PORT_Memcpy(newPinStr,pNewPin,ulNewLen);
- newPinStr[ulNewLen] = 0;
- PORT_Memcpy(oldPinStr,pOldPin,ulOldLen);
- oldPinStr[ulOldLen] = 0;
-
- /* build the hashed pins which we pass around */
- newPin = SECKEY_HashPassword(newPinStr,handle->global_salt);
- oldPin = SECKEY_HashPassword(oldPinStr,handle->global_salt);
- PORT_Memset(newPinStr,0,sizeof(newPinStr));
- PORT_Memset(oldPinStr,0,sizeof(oldPinStr));
-
- /* change the data base */
- rv = SECKEY_ChangeKeyDBPassword(handle,oldPin,newPin);
-
- /* Now update our local copy of the pin */
- SECITEM_ZfreeItem(oldPin, PR_TRUE);
- if (rv == SECSuccess) {
- if (slot->password) {
- SECITEM_ZfreeItem(slot->password, PR_TRUE);
- }
- slot->password = newPin;
- slot->needLogin = (PRBool)(ulNewLen != 0);
- return CKR_OK;
- }
- SECITEM_ZfreeItem(newPin, PR_TRUE);
- return CKR_PIN_INCORRECT;
-}
-
-/* NSC_OpenSession opens a session between an application and a token. */
-CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
- CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession)
-{
- PK11Slot *slot;
- CK_SESSION_HANDLE sessionID;
- PK11Session *session;
-
- slot = pk11_SlotFromID(slotID);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- /* new session (we only have serial sessions) */
- session = pk11_NewSession(slotID, Notify, pApplication,
- flags | CKF_SERIAL_SESSION);
- if (session == NULL) return CKR_HOST_MEMORY;
-
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- sessionID = slot->sessionIDCount++;
- if (slotID == PRIVATE_KEY_SLOT_ID) {
- sessionID |= PK11_PRIVATE_KEY_FLAG;
- } else if (slotID == FIPS_SLOT_ID) {
- sessionID |= PK11_FIPS_FLAG;
- } else if (flags & CKF_RW_SESSION) {
- /* NETSCAPE_SLOT_ID is Read ONLY */
- session->info.flags &= ~CKF_RW_SESSION;
- }
-
- session->handle = sessionID;
- pk11_update_state(slot, session);
- pk11queue_add(session, sessionID, slot->head, SESSION_HASH_SIZE);
- slot->sessionCount++;
- if (session->info.flags & CKF_RW_SESSION) {
- slot->rwSessionCount++;
- }
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
-
- *phSession = sessionID;
- return CKR_OK;
-}
-
-
-/* NSC_CloseSession closes a session between an application and a token. */
-CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
-{
- PK11Slot *slot;
- PK11Session *session;
- SECItem *pw = NULL;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- slot = pk11_SlotFromSession(session);
-
- /* lock */
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- if (pk11queue_is_queued(session,hSession,slot->head,SESSION_HASH_SIZE)) {
- pk11queue_delete(session,hSession,slot->head,SESSION_HASH_SIZE);
- session->refCount--; /* can't go to zero while we hold the reference */
- slot->sessionCount--;
- if (session->info.flags & CKF_RW_SESSION) {
- slot->rwSessionCount--;
- }
- }
- if (slot->sessionCount == 0) {
- pw = slot->password;
- slot->isLoggedIn = PR_FALSE;
- slot->password = NULL;
- }
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
-
- pk11_FreeSession(session);
- if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
- return CKR_OK;
-}
-
-
-/* NSC_CloseAllSessions closes all sessions with a token. */
-CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
-{
- PK11Slot *slot;
- SECItem *pw = NULL;
- PK11Session *session;
- int i;
-
- slot = pk11_SlotFromID(slotID);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- /* first log out the card */
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- pw = slot->password;
- slot->isLoggedIn = PR_FALSE;
- slot->password = NULL;
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
- if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
-
- /* now close all the current sessions */
- /* NOTE: If you try to open new sessions before NSC_CloseAllSessions
- * completes, some of those new sessions may or may not be closed by
- * NSC_CloseAllSessions... but any session running when this code starts
- * will guarrenteed be close, and no session will be partially closed */
- for (i=0; i < SESSION_HASH_SIZE; i++) {
- do {
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- session = slot->head[i];
- /* hand deque */
- /* this duplicates function of NSC_close session functions, but
- * because we know that we are freeing all the sessions, we can
- * do more efficient processing */
- if (session) {
- slot->head[i] = session->next;
- if (session->next) session->next->prev = NULL;
- session->next = session->prev = NULL;
- slot->sessionCount--;
- if (session->info.flags & CKF_RW_SESSION) {
- slot->rwSessionCount--;
- }
- }
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
- if (session) pk11_FreeSession(session);
- } while (session != NULL);
- }
- return CKR_OK;
-}
-
-
-/* NSC_GetSessionInfo obtains information about the session. */
-CK_RV NSC_GetSessionInfo(CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo)
-{
- PK11Session *session;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- PORT_Memcpy(pInfo,&session->info,sizeof(CK_SESSION_INFO));
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_Login logs a user into a token. */
-CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
- CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
-{
- PK11Slot *slot;
- PK11Session *session;
- SECKEYKeyDBHandle *handle;
- SECItem *pin;
- char pinStr[256];
-
-
- /* get the slot */
- slot = pk11_SlotFromSessionHandle(hSession);
-
- /* make sure the session is valid */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- }
- pk11_FreeSession(session);
-
- /* can't log into the Netscape Slot */
- if (slot->slotID == NETSCAPE_SLOT_ID)
- return CKR_USER_TYPE_INVALID;
-
- if (slot->isLoggedIn) return CKR_USER_ALREADY_LOGGED_IN;
- slot->ssoLoggedIn = PR_FALSE;
-
- if (ulPinLen > 255) return CKR_PIN_LEN_RANGE;
-
- /* convert to null terminated string */
- PORT_Memcpy(pinStr,pPin,ulPinLen);
- pinStr[ulPinLen] = 0;
-
- handle = SECKEY_GetDefaultKeyDB();
-
- /*
- * Deal with bootstrap. We allow the SSO to login in with a NULL
- * password if and only if we haven't initialized the KEY DB yet.
- * We only allow this on a RW session.
- */
- if (SECKEY_HasKeyDBPassword(handle) == SECFailure) {
- /* allow SSO's to log in only if there is not password on the
- * key database */
- if (((userType == CKU_SO) && (session->info.flags & CKF_RW_SESSION))
- /* fips always needs to authenticate, even if there isn't a db */
- || (slot->slotID == FIPS_SLOT_ID)) {
- /* should this be a fixed password? */
- if (ulPinLen == 0) {
- SECItem *pw;
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- pw = slot->password;
- slot->password = NULL;
- slot->isLoggedIn = PR_TRUE;
- slot->ssoLoggedIn = (PRBool)(userType == CKU_SO);
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
- pk11_update_all_states(slot);
- SECITEM_ZfreeItem(pw,PR_TRUE);
- return CKR_OK;
- }
- return CKR_PIN_INCORRECT;
- }
- return CKR_USER_TYPE_INVALID;
- }
-
- /* don't allow the SSO to log in if the user is already initialized */
- if (userType != CKU_USER) { return CKR_USER_TYPE_INVALID; }
-
-
- /* build the hashed pins which we pass around */
- pin = SECKEY_HashPassword(pinStr,handle->global_salt);
- if (pin == NULL) return CKR_HOST_MEMORY;
-
- if (SECKEY_CheckKeyDBPassword(handle,pin) == SECSuccess) {
- SECItem *tmp;
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- tmp = slot->password;
- slot->isLoggedIn = PR_TRUE;
- slot->password = pin;
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
- if (tmp) SECITEM_ZfreeItem(tmp, PR_TRUE);
-
- /* update all sessions */
- pk11_update_all_states(slot);
- return CKR_OK;
- }
-
- SECITEM_ZfreeItem(pin, PR_TRUE);
- return CKR_PIN_INCORRECT;
-}
-
-/* NSC_Logout logs a user out from a token. */
-CK_RV NSC_Logout(CK_SESSION_HANDLE hSession)
-{
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- SECItem *pw = NULL;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- }
-
- if (!slot->isLoggedIn) return CKR_USER_NOT_LOGGED_IN;
-
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- pw = slot->password;
- slot->isLoggedIn = PR_FALSE;
- slot->ssoLoggedIn = PR_FALSE;
- slot->password = NULL;
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
- if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
-
- pk11_update_all_states(slot);
- return CKR_OK;
-}
-
-
-/* NSC_CreateObject creates a new object. */
-CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject)
-{
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- PK11Object *object;
- CK_RV crv;
- int i;
-
-
- /*
- * now lets create an object to hang the attributes off of
- */
- object = pk11_NewObject(slot); /* fill in the handle later */
- if (object == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulCount; i++) {
- crv = pk11_AddAttributeType(object,pk11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) {
- pk11_FreeObject(object);
- return crv;
- }
- }
-
- /* get the session */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- pk11_FreeObject(object);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /*
- * handle the base object stuff
- */
- crv = pk11_handleObject(object,session);
- pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(object);
- return crv;
- }
-
- *phObject = object->handle;
- return CKR_OK;
-}
-
-
-/* NSC_CopyObject copies an object, creating a new object for the copy. */
-CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject)
-{
- PK11Object *destObject,*srcObject;
- PK11Session *session;
- CK_RV crv = CKR_OK;
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- int i;
-
- /* Get srcObject so we can find the class */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- srcObject = pk11_ObjectFromHandle(hObject,session);
- if (srcObject == NULL) {
- pk11_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
- /*
- * create an object to hang the attributes off of
- */
- destObject = pk11_NewObject(slot); /* fill in the handle later */
- if (destObject == NULL) {
- pk11_FreeSession(session);
- pk11_FreeObject(srcObject);
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulCount; i++) {
- if (pk11_modifyType(pTemplate[i].type,srcObject->objclass) == PK11_NEVER) {
- crv = CKR_ATTRIBUTE_READ_ONLY;
- break;
- }
- crv = pk11_AddAttributeType(destObject,pk11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) { break; }
- }
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- pk11_FreeObject(srcObject);
- pk11_FreeObject(destObject);
- return crv;
- }
-
- /* sensitive can only be changed to CK_TRUE */
- if (pk11_hasAttribute(destObject,CKA_SENSITIVE)) {
- if (!pk11_isTrue(destObject,CKA_SENSITIVE)) {
- pk11_FreeSession(session);
- pk11_FreeObject(srcObject);
- pk11_FreeObject(destObject);
- return CKR_ATTRIBUTE_READ_ONLY;
- }
- }
-
- /*
- * now copy the old attributes from the new attributes
- */
- /* don't create a token object if we aren't in a rw session */
- /* we need to hold the lock to copy a consistant version of
- * the object. */
- crv = pk11_CopyObject(destObject,srcObject);
-
- destObject->objclass = srcObject->objclass;
- pk11_FreeObject(srcObject);
- if (crv != CKR_OK) {
- pk11_FreeObject(destObject);
- pk11_FreeSession(session);
- }
-
- crv = pk11_handleObject(destObject,session);
- *phNewObject = destObject->handle;
- pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(destObject);
- return crv;
- }
-
- return CKR_OK;
-}
-
-
-/* NSC_GetObjectSize gets the size of an object in bytes. */
-CK_RV NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) {
- *pulSize = 0;
- return CKR_OK;
-}
-
-
-/* NSC_GetAttributeValue obtains the value of one or more object attributes. */
-CK_RV NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- PK11Object *object;
- PK11Attribute *attribute;
- PRBool sensitive;
- int i;
-
- /*
- * make sure we're allowed
- */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- object = pk11_ObjectFromHandle(hObject,session);
- pk11_FreeSession(session);
- if (object == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- /* don't read a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (pk11_isTrue(object,CKA_PRIVATE))) {
- pk11_FreeObject(object);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- sensitive = pk11_isTrue(object,CKA_SENSITIVE);
- for (i=0; i < (int) ulCount; i++) {
- /* Make sure that this attribute is retrievable */
- if (sensitive && pk11_isSensitive(pTemplate[i].type,object->objclass)) {
- pk11_FreeObject(object);
- return CKR_ATTRIBUTE_SENSITIVE;
- }
- attribute = pk11_FindAttribute(object,pTemplate[i].type);
- if (attribute == NULL) {
- pk11_FreeObject(object);
- return CKR_ATTRIBUTE_TYPE_INVALID;
- }
- if (pTemplate[i].pValue != NULL) {
- PORT_Memcpy(pTemplate[i].pValue,attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- }
- pTemplate[i].ulValueLen = attribute->attrib.ulValueLen;
- pk11_FreeAttribute(attribute);
- }
-
- pk11_FreeObject(object);
- return CKR_OK;
-}
-
-/* NSC_SetAttributeValue modifies the value of one or more object attributes */
-CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- PK11Attribute *attribute;
- PK11Object *object;
- PRBool isToken;
- CK_RV crv = CKR_OK;
- CK_BBOOL legal;
- int i;
-
- /*
- * make sure we're allowed
- */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- object = pk11_ObjectFromHandle(hObject,session);
- if (object == NULL) {
- pk11_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- /* don't modify a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (pk11_isTrue(object,CKA_PRIVATE))) {
- pk11_FreeSession(session);
- pk11_FreeObject(object);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- /* don't modify a token object if we aren't in a rw session */
- isToken = pk11_isTrue(object,CKA_TOKEN);
- if (((session->info.flags & CKF_RW_SESSION) == 0) && isToken) {
- pk11_FreeSession(session);
- pk11_FreeObject(object);
- return CKR_SESSION_READ_ONLY;
- }
- pk11_FreeSession(session);
-
- /* only change modifiable objects */
- if (!pk11_isTrue(object,CKA_MODIFIABLE)) {
- pk11_FreeObject(object);
- return CKR_ATTRIBUTE_READ_ONLY;
- }
-
- for (i=0; i < (int) ulCount; i++) {
- /* Make sure that this attribute is changeable */
- switch (pk11_modifyType(pTemplate[i].type,object->objclass)) {
- case PK11_NEVER:
- case PK11_ONCOPY:
- default:
- crv = CKR_ATTRIBUTE_READ_ONLY;
- break;
-
- case PK11_SENSITIVE:
- legal = (pTemplate[i].type == CKA_EXTRACTABLE) ? CK_FALSE : CK_TRUE;
- if ((*(CK_BBOOL *)pTemplate[i].pValue) != legal) {
- crv = CKR_ATTRIBUTE_READ_ONLY;
- }
- break;
- case PK11_ALWAYS:
- break;
- }
- if (crv != CKR_OK) break;
-
- /* find the old attribute */
- attribute = pk11_FindAttribute(object,pTemplate[i].type);
- if (attribute == NULL) {
- crv =CKR_ATTRIBUTE_TYPE_INVALID;
- break;
- }
- pk11_FreeAttribute(attribute);
- crv = pk11_forceAttribute(object,pk11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
-
- }
-
- pk11_FreeObject(object);
- return CKR_OK;
-}
-
-/* stolen from keydb.c */
-#define KEYDB_PW_CHECK_STRING "password-check"
-#define KEYDB_PW_CHECK_LEN 14
-
-SECKEYLowPrivateKey * SECKEY_DecryptKey(DBT *key, SECItem *pwitem,
- SECKEYKeyDBHandle *handle);
-typedef struct pk11keyNodeStr {
- struct pk11keyNodeStr *next;
- SECKEYLowPrivateKey *privKey;
- CERTCertificate *cert;
- SECItem *pubItem;
-} pk11keyNode;
-
-typedef struct {
- PLArenaPool *arena;
- pk11keyNode *head;
- PK11Slot *slot;
-} keyList;
-
-static SECStatus
-add_key_to_list(DBT *key, DBT *data, void *arg)
-{
- keyList *keylist;
- pk11keyNode *node;
- void *keydata;
- SECKEYLowPrivateKey *privKey = NULL;
-
- keylist = (keyList *)arg;
-
- privKey = SECKEY_DecryptKey(key, keylist->slot->password,
- SECKEY_GetDefaultKeyDB());
- if ( privKey == NULL ) {
- goto loser;
- }
-
- /* allocate the node struct */
- node = (pk11keyNode*)PORT_ArenaZAlloc(keylist->arena, sizeof(pk11keyNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- /* allocate room for key data */
- keydata = PORT_ArenaZAlloc(keylist->arena, key->size);
- if ( keydata == NULL ) {
- goto loser;
- }
-
- /* link node into list */
- node->next = keylist->head;
- keylist->head = node;
-
- node->privKey = privKey;
- switch (privKey->keyType) {
- case rsaKey:
- node->pubItem = &privKey->u.rsa.modulus;
- break;
- case dsaKey:
- node->pubItem = &privKey->u.dsa.publicValue;
- break;
- default:
- break;
- }
-
- return(SECSuccess);
-loser:
- if ( privKey ) {
- SECKEY_LowDestroyPrivateKey(privKey);
- }
- return(SECSuccess);
-}
-
-/*
- * If the cert is a user cert, then try to match it to a key on the
- * linked list of private keys built earlier.
- * If the cert matches one on the list, then save it.
- */
-static SECStatus
-add_cert_to_list(CERTCertificate *cert, SECItem *k, void *pdata)
-{
- keyList *keylist;
- pk11keyNode *node;
- SECKEYPublicKey *pubKey = NULL;
- SECItem *pubItem;
- CERTCertificate *oldcert;
-
- keylist = (keyList *)pdata;
-
- /* only if it is a user cert and has a nickname!! */
- if ( ( ( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER ) ) &&
- ( cert->nickname != NULL ) ) {
-
- /* get cert's public key */
- pubKey = CERT_ExtractPublicKey(cert);
- if ( pubKey == NULL ) {
- goto done;
- }
-
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise.
- */
- pubItem = pk11_GetPubItem(pubKey);
- if (pubItem == NULL) goto done;
-
- node = keylist->head;
- while ( node ) {
- /* if key type is different, then there is no match */
- if ( node->privKey->keyType == pubKey->keyType ) {
-
- /* compare public value from cert with public value from
- * the key
- */
- if ( SECITEM_CompareItem(pubItem, node->pubItem) == SECEqual ){
- /* this is a match */
-
- /* if no cert has yet been found for this key, or this
- * cert is newer, then save this cert
- */
- if ( ( node->cert == NULL ) ||
- CERT_IsNewer(cert, node->cert ) ) {
-
- oldcert = node->cert;
-
- /* get a real DB copy of the cert, since the one
- * passed in here is not properly recorded in the
- * temp database
- */
-
- /* We need a better way to deal with this */
- node->cert =
- CERT_FindCertByKeyNoLocking(CERT_GetDefaultCertDB(),
- &cert->certKey);
-
- /* free the old cert if there was one */
- if ( oldcert ) {
- CERT_DestroyCertificate(oldcert);
- }
- }
- }
- }
-
- node = node->next;
- }
- }
-done:
- if ( pubKey ) {
- SECKEY_DestroyPublicKey(pubKey);
- }
-
- return(SECSuccess);
-}
-
-#if 0
-/* This appears to be obsolete - TNH */
-static SECItem *
-decodeKeyDBGlobalSalt(DBT *saltData)
-{
- SECItem *saltitem;
-
- saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if ( saltitem == NULL ) {
- return(NULL);
- }
-
- saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size);
- if ( saltitem->data == NULL ) {
- PORT_Free(saltitem);
- return(NULL);
- }
-
- saltitem->len = saltData->size;
- PORT_Memcpy(saltitem->data, saltData->data, saltitem->len);
-
- return(saltitem);
-}
-#endif
-
-#if 0
-/*
- * Create a (fixed) DES3 key [ testing ]
- */
-static unsigned char keyValue[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
-};
-
-static SECItem keyItem = {
- 0,
- keyValue,
- sizeof keyValue
-};
-
-static unsigned char keyID[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static SECItem keyIDItem = {
- 0,
- keyID,
- sizeof keyID
-};
-/* +AAA */
-static CK_RV
-pk11_createFixedDES3Key(PK11Slot *slot)
-{
- CK_RV rv = CKR_OK;
- PK11Object *keyObject;
- CK_BBOOL true = CK_TRUE;
- CK_OBJECT_CLASS class = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_DES3;
-
- /*
- * Create the object
- */
- keyObject = pk11_NewObject(slot); /* fill in the handle later */
- if (keyObject == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /* Add attributes to the object */
- rv = pk11_AddAttributeType(keyObject, CKA_ID, keyID, sizeof keyID);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
-
- rv = pk11_AddAttributeType(keyObject, CKA_VALUE, keyValue, sizeof keyValue);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
-
- rv = pk11_AddAttributeType(keyObject, CKA_TOKEN, &true, sizeof true);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
-
- rv = pk11_AddAttributeType(keyObject, CKA_CLASS, &class, sizeof class);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
-
- rv = pk11_AddAttributeType(keyObject, CKA_KEY_TYPE, &keyType, sizeof keyType);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
-
- pk11_handleSecretKeyObject(keyObject, keyType, PR_TRUE);
-
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- keyObject->handle = slot->tokenIDCount++;
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
- keyObject->slot = slot;
- keyObject->objclass = CKO_SECRET_KEY;
- pk11_AddSlotObject(slot, keyObject);
-
- return rv;
-}
-#endif /* Fixed DES key */
-
-/*
- * load up our token database
- */
-static CK_RV
-pk11_importKeyDB(PK11Slot *slot)
-{
- keyList keylist;
- pk11keyNode *node;
- CK_RV crv;
- SECStatus rv;
- PK11Object *privateKeyObject;
- PK11Object *publicKeyObject;
- PK11Object *certObject;
-
- /* traverse the database, collecting the index keys of all
- * records into a linked list
- */
- keylist.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( keylist.arena == NULL ) {
- return CKR_HOST_MEMORY;
- }
- keylist.head = NULL;
- keylist.slot = slot;
-
- /* collect all of the keys */
- rv = SECKEY_TraverseKeys(SECKEY_GetDefaultKeyDB(),
- add_key_to_list, (void *)&keylist);
- if (rv != SECSuccess) {
- PORT_FreeArena(keylist.arena, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
-
- /* find certs that match any of the keys */
- crv = SEC_TraversePermCerts(CERT_GetDefaultCertDB(),
- add_cert_to_list, (void *)&keylist);
- if ( crv != SECSuccess ) {
- PORT_FreeArena(keylist.arena, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
-
- /* now traverse the list and entry certs/keys into the
- * pkcs11 world
- */
- for (node = keylist.head; node != NULL; node=node->next ) {
- /* Check for "special" private key that wraps a symmetric key */
- if (isSecretKey(node->privKey)) {
- importSecretKey(slot, node->privKey);
- goto end_loop;
- }
-
- /* create the private key object */
- privateKeyObject = pk11_importPrivateKey(slot, node->privKey,
- node->pubItem);
- if ( privateKeyObject == NULL ) {
- goto end_loop;
- }
-
- publicKeyObject = pk11_importPublicKey(slot, node->privKey, NULL,
- node->pubItem);
- if ( node->cert ) {
- /* Now import the Cert */
- certObject = pk11_importCertificate(slot, node->cert,
- node->pubItem->data,
- node->pubItem->len, PR_TRUE);
-
- /* Copy the subject */
- if ( certObject ) {
- /* NOTE: cert has been adopted */
- PK11Attribute *attribute;
-
- /* Copy the Subject */
- attribute = pk11_FindAttribute(certObject,CKA_SUBJECT);
- if (attribute) {
- pk11_forceAttribute(privateKeyObject,
- pk11_attr_expand(&attribute->attrib));
- if (publicKeyObject) {
- pk11_forceAttribute(publicKeyObject,
- pk11_attr_expand(&attribute->attrib));
- }
- pk11_FreeAttribute(attribute);
- }
- pk11_FreeObject(certObject);
- }
- }
-
- if ( publicKeyObject != NULL ) {
- pk11_AddSlotObject(slot, publicKeyObject);
- }
-
- pk11_AddSlotObject(slot, privateKeyObject);
-
-end_loop:
- SECKEY_LowDestroyPrivateKey(node->privKey);
- if ( node->cert ) {
- CERT_DestroyCertificate(node->cert);
- }
-
- }
- PORT_FreeArena(keylist.arena, PR_FALSE);
-
- return CKR_OK;
-}
-
-/*
- * structure to collect certs into
- */
-typedef struct pk11CertDataStr {
- int cert_count;
- int max_cert_count;
- CERTCertificate **certs;
-} pk11CertData;
-
-/*
- * collect all the certs from the traverse call.
- */
-static SECStatus
-pk11_cert_collect(CERTCertificate *cert,void *arg) {
- pk11CertData *cd = (pk11CertData *)arg;
-
- /* shouldn't happen, but don't crash if it does */
- if (cd->cert_count >= cd->max_cert_count) {
- PORT_Assert(0);
- return SECFailure;
- }
-
- cd->certs[cd->cert_count++] = CERT_DupCertificate(cert);
- return SECSuccess;
-}
-
-/*
- * find any certs that may match the template and load them.
- */
-static void
-pk11_searchCerts(PK11Slot *slot, CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) {
- int i;
- SECItem derCert = { siBuffer, NULL, 0 };
- SECItem derSubject = { siBuffer, NULL, 0 };
- SECItem name = { siBuffer, NULL, 0 };
- CERTIssuerAndSN issuerSN = {
- { siBuffer, NULL, 0 },
- { NULL, NULL },
- { siBuffer, NULL, 0 }
- };
- SECItem *copy = NULL;
- CERTCertDBHandle *handle = NULL;
- SECKEYKeyDBHandle *keyHandle = NULL;
- pk11CertData certData;
-
-
- /*
- * These should be stored in the slot some day in the future
- */
- handle = CERT_GetDefaultCertDB();
- if (handle == NULL) return;
- keyHandle = SECKEY_GetDefaultKeyDB();
- if (keyHandle == NULL) return;
-
- /*
- * look for things to search on certs for. We only need one of these
- * items. If we find all the certs that match that item, import them
- * (as long as they are user certs). We'll let find objects filter out
- * the ones that don't apply.
- */
- for (i=0 ;i < (int)ulCount; i++) {
-
- switch (pTemplate[i].type) {
- case CKA_SUBJECT: copy = &derSubject; break;
- case CKA_ISSUER: copy = &issuerSN.derIssuer; break;
- case CKA_SERIAL_NUMBER: copy = &issuerSN.serialNumber; break;
- case CKA_VALUE: copy = &derCert; break;
- case CKA_LABEL: copy = &name; break;
- case CKA_CLASS:
- if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
- return;
- }
- if (*((CK_OBJECT_CLASS *)pTemplate[i].pValue) != CKO_CERTIFICATE) {
- return;
- }
- copy = NULL; break;
- case CKA_PRIVATE:
- if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- return;
- }
- if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_FALSE) {
- return;
- }
- copy = NULL; break;
- case CKA_TOKEN:
- if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- return;
- }
- if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) {
- return;
- }
- copy = NULL; break;
- case CKA_CERTIFICATE_TYPE:
- case CKA_ID:
- case CKA_MODIFIABLE:
- copy = NULL; break;
- /* can't be a certificate if it doesn't match one of the above
- * attributes */
- default: return;
- }
- if (copy) {
- copy->data = (unsigned char*)pTemplate[i].pValue;
- copy->len = pTemplate[i].ulValueLen;
- }
- }
-
- certData.max_cert_count = 0;
- certData.certs = NULL;
- certData.cert_count = 0;
-
- if (derCert.data != NULL) {
- CERTCertificate *cert = CERT_FindCertByDERCert(handle,&derCert);
- if (cert != NULL) {
- certData.certs =
- (CERTCertificate **) PORT_Alloc(sizeof (CERTCertificate *));
- if (certData.certs) {
- certData.certs[0] = cert;
- certData.cert_count = 1;
- } else CERT_DestroyCertificate(cert);
- }
- } else if (name.data != NULL) {
- char *tmp_name = (char*)PORT_Alloc(name.len+1);
-
- if (tmp_name == NULL) {
- return;
- }
- PORT_Memcpy(tmp_name,name.data,name.len);
- tmp_name[name.len] = 0;
-
- certData.max_cert_count=CERT_NumPermCertsForNickname(handle,tmp_name);
- if (certData.max_cert_count > 0) {
- certData.certs = (CERTCertificate **)
- PORT_Alloc(certData.max_cert_count *sizeof(CERTCertificate *));
- if (certData.certs) {
- CERT_TraversePermCertsForNickname(handle,tmp_name,
- pk11_cert_collect, &certData);
- }
-
- }
-
- PORT_Free(tmp_name);
- } else if (derSubject.data != NULL) {
- certData.max_cert_count=CERT_NumPermCertsForSubject(handle,&derSubject);
- if (certData.max_cert_count > 0) {
- certData.certs = (CERTCertificate **)
- PORT_Alloc(certData.max_cert_count *sizeof(CERTCertificate *));
- if (certData.certs) {
- CERT_TraversePermCertsForSubject(handle,&derSubject,
- pk11_cert_collect, &certData);
- }
- }
- } else if ((issuerSN.derIssuer.data != NULL) &&
- (issuerSN.serialNumber.data != NULL)) {
- CERTCertificate *cert = CERT_FindCertByIssuerAndSN(handle,&issuerSN);
-
- if (cert != NULL) {
- certData.certs =
- (CERTCertificate **) PORT_Alloc(sizeof (CERTCertificate *));
- if (certData.certs) {
- certData.certs[0] = cert;
- certData.cert_count = 1;
- } else CERT_DestroyCertificate(cert);
- }
- } else {
- /* PORT_Assert(0); may get called when not looking for certs */
- /* look up all the certs sometime, and get rid of the assert */;
- }
-
-
- for (i=0 ; i < certData.cert_count ; i++) {
- CERTCertificate *cert = certData.certs[i];
-
- /* we are only interested in permanment user certs here */
- if ((cert->isperm) && (cert->trust) &&
- (( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER )) &&
- ( cert->nickname != NULL ) &&
- (SECKEY_KeyForCertExists(keyHandle, cert) == SECSuccess)) {
- PK11Object *obj;
- pk11_importCertificate(slot, cert, NULL, 0, PR_FALSE);
- obj = pk11_importPublicKey(slot, NULL, cert, NULL);
- if (obj) pk11_AddSlotObject(slot, obj);
- }
- CERT_DestroyCertificate(cert);
- }
- if (certData.certs) PORT_Free(certData.certs);
-
- return;
-}
-
-
-/* NSC_FindObjectsInit initializes a search for token and session objects
- * that match a template. */
-CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
- PK11ObjectListElement *objectList = NULL;
- PK11ObjectListElement *olp;
- PK11SearchResults *search,*freeSearch;
- PK11Session *session;
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- int count, i;
- CK_RV crv;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /* resync token objects with the data base */
- if ((session->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (session->info.slotID == FIPS_SLOT_ID)) {
- if (slot->DB_loaded == PR_FALSE) {
- /* if we aren't logged in, we can't unload all key keys
- * and certs. Just unload those certs we need for this search
- */
- if ((!slot->isLoggedIn) && (slot->needLogin)) {
- pk11_searchCerts(slot,pTemplate,ulCount);
- } else {
- pk11_importKeyDB(slot);
- slot->DB_loaded = PR_TRUE;
- }
- }
- }
-
-
- /* build list of found objects in the session */
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, pTemplate, ulCount, (PRBool)((!slot->needLogin) ||
- slot->isLoggedIn));
- if (crv != CKR_OK) {
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return crv;
- }
-
-
- /* copy list to session */
- count = 0;
- for (olp = objectList; olp != NULL; olp = olp->next) {
- count++;
- }
- search = (PK11SearchResults *)PORT_Alloc(sizeof(PK11SearchResults));
- if (search == NULL) {
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return CKR_HOST_MEMORY;
- }
- search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * count);
- if (search->handles == NULL) {
- PORT_Free(search);
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return CKR_HOST_MEMORY;
- }
- for (i=0; i < count; i++) {
- search->handles[i] = objectList->object->handle;
- objectList = pk11_FreeObjectListElement(objectList);
- }
-
- /* store the search info */
- search->index = 0;
- search->size = count;
- if ((freeSearch = session->search) != NULL) {
- session->search = NULL;
- pk11_FreeSearch(freeSearch);
- }
- session->search = search;
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_FindObjects continues a search for token and session objects
- * that match a template, obtaining additional object handles. */
-CK_RV NSC_FindObjects(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount)
-{
- PK11Session *session;
- PK11SearchResults *search;
- int transfer;
- int left;
-
- *pulObjectCount = 0;
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- if (session->search == NULL) {
- pk11_FreeSession(session);
- return CKR_OK;
- }
- search = session->search;
- left = session->search->size - session->search->index;
- transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount;
- PORT_Memcpy(phObject,&search->handles[search->index],
- transfer*sizeof(CK_OBJECT_HANDLE_PTR));
- search->index += transfer;
- if (search->index == search->size) {
- session->search = NULL;
- pk11_FreeSearch(search);
- }
- *pulObjectCount = transfer;
- return CKR_OK;
-}
-
-/* NSC_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
-{
- PK11Session *session;
- PK11SearchResults *search;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- search = session->search;
- session->search = NULL;
- if (search == NULL) {
- pk11_FreeSession(session);
- return CKR_OK;
- }
- pk11_FreeSearch(search);
- return CKR_OK;
-}
-
-
-
-CK_RV NSC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved)
-{
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
diff --git a/security/nss/lib/softoken/pkcs11.h b/security/nss/lib/softoken/pkcs11.h
deleted file mode 100644
index 28fd0cd8e..000000000
--- a/security/nss/lib/softoken/pkcs11.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-#ifndef _PKCS11_H_
-#define _PKCS11_H_ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Before including this file (pkcs11.h) (or pkcs11t.h by
- * itself), 6 platform-specific macros must be defined. These
- * macros are described below, and typical definitions for them
- * are also given. Be advised that these definitions can depend
- * on both the platform and the compiler used (and possibly also
- * on whether a PKCS #11 library is linked statically or
- * dynamically).
- *
- * In addition to defining these 6 macros, the packing convention
- * for PKCS #11 structures should be set. The PKCS #11
- * convention on packing is that structures should be 1-byte
- * aligned.
- *
- * In a Win32 environment, this might be done by using the
- * following preprocessor directive before including pkcs11.h
- * or pkcs11t.h:
- *
- * #pragma pack(push, cryptoki, 1)
- *
- * and using the following preprocessor directive after including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(pop, cryptoki)
- *
- * In a Win16 environment, this might be done by using the
- * following preprocessor directive before including pkcs11.h
- * or pkcs11t.h:
- *
- * #pragma pack(1)
- *
- * In a UNIX environment, you're on your own here. You might
- * not need to do anything.
- *
- *
- * Now for the macros:
- *
- *
- * 1. CK_PTR: The indirection string for making a pointer to an
- * object. It can be used like this:
- *
- * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
- *
- * In a Win32 environment, it might be defined by
- *
- * #define CK_PTR *
- *
- * In a Win16 environment, it might be defined by
- *
- * #define CK_PTR far *
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_PTR *
- *
- *
- * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
- * an exportable PKCS #11 library function definition out of a
- * return type and a function name. It should be used in the
- * following fashion to define the exposed PKCS #11 functions in
- * a PKCS #11 library:
- *
- * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
- * CK_VOID_PTR pReserved
- * )
- * {
- * ...
- * }
- *
- * For defining a function in a Win32 PKCS #11 .dll, it might be
- * defined by
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType __declspec(dllexport) name
- *
- * For defining a function in a Win16 PKCS #11 .dll, it might be
- * defined by
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType name
- *
- *
- * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
- * an importable PKCS #11 library function declaration out of a
- * return type and a function name. It should be used in the
- * following fashion:
- *
- * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
- * CK_VOID_PTR pReserved
- * );
- *
- * For declaring a function in a Win32 PKCS #11 .dll, it might
- * be defined by
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType __declspec(dllimport) name
- *
- * For declaring a function in a Win16 PKCS #11 .dll, it might
- * be defined by
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType name
- *
- *
- * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
- * which makes a PKCS #11 API function pointer declaration or
- * function pointer type declaration out of a return type and a
- * function name. It should be used in the following fashion:
- *
- * // Define funcPtr to be a pointer to a PKCS #11 API function
- * // taking arguments args and returning CK_RV.
- * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
- *
- * or
- *
- * // Define funcPtrType to be the type of a pointer to a
- * // PKCS #11 API function taking arguments args and returning
- * // CK_RV, and then define funcPtr to be a variable of type
- * // funcPtrType.
- * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
- * funcPtrType funcPtr;
- *
- * For accessing functions in a Win32 PKCS #11 .dll, in might be
- * defined by
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType __declspec(dllimport) (* name)
- *
- * For accessing functions in a Win16 PKCS #11 .dll, it might be
- * defined by
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType __export _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType (* name)
- *
- *
- * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
- * a function pointer type for an application callback out of
- * a return type for the callback and a name for the callback.
- * It should be used in the following fashion:
- *
- * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
- *
- * to declare a function pointer, myCallback, to a callback
- * which takes arguments args and returns a CK_RV. It can also
- * be used like this:
- *
- * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
- * myCallbackType myCallback;
- *
- * In a Win32 environment, it might be defined by
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType (* name)
- *
- * In a Win16 environment, it might be defined by
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType (* name)
- *
- *
- * 6. NULL_PTR: This macro is the value of a NULL pointer.
- *
- * In any ANSI/ISO C environment (and in many others as well),
- * this should be defined by
- *
- * #ifndef NULL_PTR
- * #define NULL_PTR 0
- * #endif
- */
-
-
-/* All the various PKCS #11 types and #define'd values are in the
- * file pkcs11t.h. */
-#include "pkcs11t.h"
-
-#define __PASTE(x,y) x##y
-
-
-/* packing defines */
-#include "pkcs11p.h"
-/* ==============================================================
- * Define the "extern" form of all the entry points.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST 1
-#define CK_PKCS11_FUNCTION_INFO(name) \
- CK_DECLARE_FUNCTION(CK_RV, name)
-
-/* pkcs11f.h has all the information about the PKCS #11
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define the typedef form of all the entry points. That is, for
- * each PKCS #11 function C_XXX, define a type CK_C_XXX which is
- * a pointer to that kind of function.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST 1
-#define CK_PKCS11_FUNCTION_INFO(name) \
- typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
-
-/* pkcs11f.h has all the information about the PKCS #11
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define structed vector of entry points. A CK_FUNCTION_LIST
- * contains a CK_VERSION indicating a library's PKCS #11 version
- * and then a whole slew of function pointers to the routines in
- * the library. This type was declared, but not defined, in
- * pkcs11t.h.
- * ==============================================================
- */
-
-#define CK_PKCS11_FUNCTION_INFO(name) \
- __PASTE(CK_,name) name;
-
-struct CK_FUNCTION_LIST {
-
- CK_VERSION version; /* PKCS #11 version */
-
-/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-/* pkcs11f.h has all the information about the PKCS #11
- * function prototypes. */
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-/* unpack */
-#include "pkcs11u.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
deleted file mode 100644
index 9689982ba..000000000
--- a/security/nss/lib/softoken/pkcs11c.c
+++ /dev/null
@@ -1,5323 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login.
- * It supports Public Key ops, and all they bulk ciphers and hashes.
- * It can also support Private Key ops for imported Private keys. It does
- * not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-#include "seccomon.h"
-#include "secitem.h"
-#include "secport.h"
-#include "blapi.h"
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "keylow.h"
-#include "cert.h"
-#include "sechash.h"
-#include "secder.h"
-#include "secdig.h"
-#include "secpkcs5.h" /* We do PBE below */
-#include "pkcs11t.h"
-#include "secoid.h"
-#include "alghmac.h"
-#include "softoken.h"
-#include "secasn1.h"
-#include "secmodi.h"
-
-#include "certdb.h"
-#include "ssl3prot.h" /* for SSL3_RANDOM_LENGTH */
-
-#define __PASTE(x,y) x##y
-
-/*
- * we renamed all our internal functions, get the correct
- * definitions for them...
- */
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-#define CK_EXTERN extern
-#define CK_PKCS11_FUNCTION_INFO(func) \
- CK_RV __PASTE(NS,func)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-
-/* forward static declaration. */
-static SECStatus pk11_PRF(const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result);
-
-#define PK11_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
-
-static void pk11_Null(void *data, PRBool freeit)
-{
- return;
-}
-
-/*
- * free routines.... Free local type allocated data, and convert
- * other free routines to the destroy signature.
- */
-static void
-pk11_FreePrivKey(SECKEYLowPrivateKey *key, PRBool freeit)
-{
- SECKEY_LowDestroyPrivateKey(key);
-}
-
-static void
-pk11_HMAC_Destroy(HMACContext *context, PRBool freeit)
-{
- HMAC_Destroy(context);
-}
-
-static void
-pk11_Space(void *data, PRBool freeit)
-{
- PORT_Free(data);
-}
-
-static void pk11_FreeSignInfo(PK11HashSignInfo *data, PRBool freeit)
-{
- SECKEY_LowDestroyPrivateKey(data->key);
- PORT_Free(data);
-}
-
-static DSAPublicKey *
-DSA_CreateVerifyContext(SECKEYLowPublicKey *pubKey)
-{
- PLArenaPool * arena;
- DSAPublicKey * dsaKey;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) goto loser;
- dsaKey = (DSAPublicKey *)PORT_ArenaZAlloc(arena, sizeof (DSAPublicKey));
- if (!dsaKey) goto loser;
- dsaKey->params.arena = arena;
-
-#define COPY_DSA_ITEM(item) \
- rv = SECITEM_CopyItem(arena, &dsaKey->item, &pubKey->u.dsa.item); \
- if (rv != SECSuccess) goto loser;
-
- COPY_DSA_ITEM(params.prime);
- COPY_DSA_ITEM(params.subPrime);
- COPY_DSA_ITEM(params.base);
- COPY_DSA_ITEM(publicValue);
- return dsaKey;
-
-loser:
- if (arena)
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
-
-#undef COPY_DSA_ITEM
-}
-
-static void
-DSA_DestroyVerifyContext(DSAPublicKey * key)
-{
- if (key && key->params.arena)
- PORT_FreeArena(key->params.arena, PR_TRUE);
-}
-
-static DSAPrivateKey *
-DSA_CreateSignContext(SECKEYLowPrivateKey *privKey)
-{
- PLArenaPool * arena;
- DSAPrivateKey * dsaKey;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) goto loser;
- dsaKey = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof (DSAPrivateKey));
- if (!dsaKey) goto loser;
- dsaKey->params.arena = arena;
-
-#define COPY_DSA_ITEM(item) \
- rv = SECITEM_CopyItem(arena, &dsaKey->item, &privKey->u.dsa.item); \
- if (rv != SECSuccess) goto loser;
-
- COPY_DSA_ITEM(params.prime);
- COPY_DSA_ITEM(params.subPrime);
- COPY_DSA_ITEM(params.base);
- COPY_DSA_ITEM(publicValue);
- COPY_DSA_ITEM(privateValue);
- return dsaKey;
-
-loser:
- if (arena)
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
-
-#undef COPY_DSA_ITEM
-}
-
-static void
-DSA_DestroySignContext(DSAPrivateKey * key)
-{
- if (key && key->params.arena)
- PORT_FreeArena(key->params.arena, PR_TRUE);
-}
-
-/*
- * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
- * Deprecating a full des key to 40 bit key strenth.
- */
-static CK_RV
-pk11_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
-{
- unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae };
- unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 };
- unsigned char enc_src[8];
- unsigned char enc_dest[8];
- unsigned int leng,i;
- DESContext *descx;
- SECStatus rv;
-
-
- /* zero the parity bits */
- for (i=0; i < 8; i++) {
- enc_src[i] = cdmfkey[i] & 0xfe;
- }
-
- /* encrypt with key 1 */
- descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE);
- if (descx == NULL) return CKR_HOST_MEMORY;
- rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8);
- DES_DestroyContext(descx,PR_TRUE);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
-
- /* xor source with des, zero the parity bits and depricate the key*/
- for (i=0; i < 8; i++) {
- if (i & 1) {
- enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe;
- } else {
- enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e;
- }
- }
-
- /* encrypt with key 2 */
- descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE);
- if (descx == NULL) return CKR_HOST_MEMORY;
- rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8);
- DES_DestroyContext(descx,PR_TRUE);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
-
- /* set the corret parity on our new des key */
- pk11_FormatDESKey(deskey, 8);
- return CKR_OK;
-}
-
-
-static CK_RV
-pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype,
- PK11ContextType contextType);
-/*
- * Calculate a Lynx checksum for CKM_LYNX_WRAP mechanism.
- */
-static CK_RV
-pk11_calcLynxChecksum(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hWrapKey,
- unsigned char *checksum, unsigned char *key, CK_ULONG len)
-{
-
- CK_BYTE E[10];
- CK_ULONG Elen = sizeof (E);
- CK_BYTE C[8];
- CK_ULONG Clen = sizeof (C);
- unsigned short sum1 = 0, sum2 = 0;
- CK_MECHANISM mech = { CKM_DES_ECB, NULL, 0 };
- int i;
- CK_RV crv;
-
- if (len != 8) return CKR_WRAPPED_KEY_LEN_RANGE;
-
- /* zero the parity bits */
- for (i=0; i < 8; i++) {
- sum1 = sum1 + key[i];
- sum2 = sum2 + sum1;
- }
-
- /* encrypt with key 1 */
-
- crv = pk11_EncryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT);
- if (crv != CKR_OK) return crv;
-
- crv = NSC_Encrypt(hSession,key,len,E,&Elen);
- if (crv != CKR_OK) return crv;
-
- E[8] = (sum2 >> 8) & 0xff;
- E[9] = sum2 & 0xff;
-
- crv = pk11_EncryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT);
- if (crv != CKR_OK) return crv;
-
- crv = NSC_Encrypt(hSession,&E[2],len,C,&Clen);
- if (crv != CKR_OK) return crv;
-
- checksum[0] = C[6];
- checksum[1] = C[7];
-
- return CKR_OK;
-}
-/* NSC_DestroyObject destroys an object. */
-CK_RV
-NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
-{
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- PK11Object *object;
- PK11FreeStatus status;
-
- /*
- * This whole block just makes sure we really can destroy the
- * requested object.
- */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- object = pk11_ObjectFromHandle(hObject,session);
- if (object == NULL) {
- pk11_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- /* don't destroy a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (pk11_isTrue(object,CKA_PRIVATE))) {
- pk11_FreeSession(session);
- pk11_FreeObject(object);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- /* don't destroy a token object if we aren't in a rw session */
-
- if (((session->info.flags & CKF_RW_SESSION) == 0) &&
- (pk11_isTrue(object,CKA_TOKEN))) {
- pk11_FreeSession(session);
- pk11_FreeObject(object);
- return CKR_SESSION_READ_ONLY;
- }
-
- pk11_DeleteObject(session,object);
-
- pk11_FreeSession(session);
-
- /*
- * get some indication if the object is destroyed. Note: this is not
- * 100%. Someone may have an object reference outstanding (though that
- * should not be the case by here. Also note that the object is "half"
- * destroyed. Our internal representation is destroyed, but it may still
- * be in the data base.
- */
- status = pk11_FreeObject(object);
-
- return (status != PK11_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-
-/*
- ************** Crypto Functions: Utilities ************************
- */
-
-
-/*
- * return a context based on the PK11Context type.
- */
-PK11SessionContext *
-pk11_ReturnContextByType(PK11Session *session, PK11ContextType type)
-{
- switch (type) {
- case PK11_ENCRYPT:
- case PK11_DECRYPT:
- return session->enc_context;
- case PK11_HASH:
- return session->hash_context;
- case PK11_SIGN:
- case PK11_SIGN_RECOVER:
- case PK11_VERIFY:
- case PK11_VERIFY_RECOVER:
- return session->hash_context;
- }
- return NULL;
-}
-
-/*
- * change a context based on the PK11Context type.
- */
-void
-pk11_SetContextByType(PK11Session *session, PK11ContextType type,
- PK11SessionContext *context)
-{
- switch (type) {
- case PK11_ENCRYPT:
- case PK11_DECRYPT:
- session->enc_context = context;
- break;
- case PK11_HASH:
- session->hash_context = context;
- break;
- case PK11_SIGN:
- case PK11_SIGN_RECOVER:
- case PK11_VERIFY:
- case PK11_VERIFY_RECOVER:
- session->hash_context = context;
- break;
- }
- return;
-}
-
-/*
- * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal,
- * and C_XXX function. The function takes a session handle, the context type,
- * and wether or not the session needs to be multipart. It returns the context,
- * and optionally returns the session pointer (if sessionPtr != NULL) if session
- * pointer is returned, the caller is responsible for freeing it.
- */
-static CK_RV
-pk11_GetContext(CK_SESSION_HANDLE handle,PK11SessionContext **contextPtr,
- PK11ContextType type, PRBool needMulti, PK11Session **sessionPtr)
-{
- PK11Session *session;
- PK11SessionContext *context;
-
- session = pk11_SessionFromHandle(handle);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- context = pk11_ReturnContextByType(session,type);
- /* make sure the context is valid */
- if((context==NULL)||(context->type!=type)||(needMulti&&!(context->multi))){
- pk11_FreeSession(session);
- return CKR_OPERATION_NOT_INITIALIZED;
- }
- *contextPtr = context;
- if (sessionPtr != NULL) {
- *sessionPtr = session;
- } else {
- pk11_FreeSession(session);
- }
- return CKR_OK;
-}
-
-/*
- ************** Crypto Functions: Encrypt ************************
- */
-
-/*
- * All the NSC_InitXXX functions have a set of common checks and processing they
- * all need to do at the beginning. This is done here.
- */
-static CK_RV
-pk11_InitGeneric(PK11Session *session,PK11SessionContext **contextPtr,
- PK11ContextType ctype,PK11Object **keyPtr,
- CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr,
- CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation)
-{
- PK11Object *key = NULL;
- PK11Attribute *att;
- PK11SessionContext *context;
-
- /* We can only init if there is not current context active */
- if (pk11_ReturnContextByType(session,ctype) != NULL) {
- return CKR_OPERATION_ACTIVE;
- }
-
- /* find the key */
- if (keyPtr) {
- key = pk11_ObjectFromHandle(hKey,session);
- if (key == NULL) {
- return CKR_KEY_HANDLE_INVALID;
- }
-
- /* make sure it's a valid key for this operation */
- if (((key->objclass != CKO_SECRET_KEY) && (key->objclass != pubKeyType))
- || !pk11_isTrue(key,operation)) {
- pk11_FreeObject(key);
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- /* get the key type */
- att = pk11_FindAttribute(key,CKA_KEY_TYPE);
- PORT_Assert(att != NULL);
- *keyTypePtr = *(CK_KEY_TYPE *)att->attrib.pValue;
- pk11_FreeAttribute(att);
- *keyPtr = key;
- }
-
- /* allocate the context structure */
- context = (PK11SessionContext *)PORT_Alloc(sizeof(PK11SessionContext));
- if (context == NULL) {
- if (key) pk11_FreeObject(key);
- return CKR_HOST_MEMORY;
- }
- context->type = ctype;
- context->multi = PR_TRUE;
- context->cipherInfo = NULL;
- context->hashInfo = NULL;
- context->doPad = PR_FALSE;
- context->padDataLength = 0;
-
- *contextPtr = context;
- return CKR_OK;
-}
-
-/* NSC_EncryptInit initializes an encryption operation. */
-/* This function is used by NSC_EncryptInit and NSC_WrapKey. The only difference
- * in their uses if whether or not etype is CKA_ENCRYPT or CKA_WRAP */
-static CK_RV
-pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype,
- PK11ContextType contextType)
-{
- PK11Session *session;
- PK11Object *key;
- PK11SessionContext *context;
- PK11Attribute *att;
- CK_RC2_CBC_PARAMS *rc2_param;
- CK_RC5_CBC_PARAMS *rc5_param;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- SECKEYLowPublicKey *pubKey;
- unsigned effectiveKeyLength;
- unsigned char newdeskey[8];
- PRBool useNewKey=PR_FALSE;
- SECItem rc5Key;
- int t;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- crv = pk11_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
- CKO_PUBLIC_KEY, etype);
-
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- context->doPad = PR_FALSE;
- switch(pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- pubKey = pk11_GetPubKey(key,CKK_RSA);
- if (pubKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = pubKey;
- context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_EncryptRaw : RSA_EncryptBlock);
- context->destroy = pk11_Null;
- break;
- case CKM_RC2_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- if (key_type != CKK_RC2) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
- effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8;
- context->cipherInfo =
- RC2_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen, rc2_param->iv,
- pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 :
- NSS_RC2_CBC,effectiveKeyLength);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC2_Encrypt;
- context->destroy = (PK11Destroy) RC2_DestroyContext;
- break;
- case CKM_RC5_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_RC5_ECB:
- case CKM_RC5_CBC:
- if (key_type != CKK_RC5) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
- if (context->doPad) {
- context->blockSize = rc5_param->ulWordsize*2;
- }
- rc5Key.data = (unsigned char*)att->attrib.pValue;
- rc5Key.len = att->attrib.ulValueLen;
- context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds,
- rc5_param->ulWordsize,rc5_param->pIv,
- pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC5_Encrypt;
- context->destroy = (PK11Destroy) RC5_DestroyContext;
- break;
- case CKM_RC4:
- if (key_type != CKK_RC4) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo =
- RC4_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY; /* WRONG !!! */
- break;
- }
- context->update = (PK11Cipher) RC4_Encrypt;
- context->destroy = (PK11Destroy) RC4_DestroyContext;
- break;
- case CKM_CDMF_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_CDMF_ECB:
- case CKM_CDMF_CBC:
- if (key_type != CKK_CDMF) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
- useNewKey=PR_TRUE;
- if (crv != CKR_OK) break;
- goto finish_des;
- case CKM_DES_ECB:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES;
- goto finish_des;
- case CKM_DES_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES_CBC:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_CBC;
- goto finish_des;
- case CKM_DES3_ECB:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3;
- goto finish_des;
- case CKM_DES3_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES3_CBC:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3_CBC;
-finish_des:
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- if (useNewKey) {
- crv = pk11_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey);
- if (crv != CKR_OK) {
- pk11_FreeAttribute(att);
- break;
- }
- }
- context->cipherInfo = DES_CreateContext(
- useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,t, PR_TRUE);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) DES_Encrypt;
- context->destroy = (PK11Destroy) DES_DestroyContext;
-
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- pk11_FreeObject(key);
- if (crv != CKR_OK) {
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, contextType, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_EncryptInit initializes an encryption operation. */
-CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
-{
- return pk11_EncryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT,
- PK11_ENCRYPT);
-}
-
-/* NSC_EncryptUpdate continues a multiple-part encryption operation. */
-CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen)
-{
- PK11SessionContext *context;
- unsigned int outlen,i;
- unsigned int padoutlen = 0;
- unsigned int maxout = *pulEncryptedPartLen;
- CK_RV crv;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
-
- /* do padding */
- if (context->doPad) {
- /* deal with previous buffered data */
- if (context->padDataLength != 0) {
- /* fill in the padded to a full block size */
- for (i=context->padDataLength;
- (ulPartLen != 0) && i < context->blockSize; i++) {
- context->padBuf[i] = *pPart++;
- ulPartLen--;
- context->padDataLength++;
- }
-
- /* not enough data to encrypt yet? then return */
- if (context->padDataLength != context->blockSize) {
- *pulEncryptedPartLen = 0;
- return CKR_OK;
- }
- /* encrypt the current padded data */
- rv = (*context->update)(context->cipherInfo,pEncryptedPart,
- &outlen,context->blockSize,context->padBuf,context->blockSize);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
- pEncryptedPart += padoutlen;
- maxout -= padoutlen;
- }
- /* save the residual */
- context->padDataLength = ulPartLen % context->blockSize;
- if (context->padDataLength) {
- PORT_Memcpy(context->padBuf,
- &pPart[ulPartLen-context->padDataLength],
- context->padDataLength);
- ulPartLen -= context->padDataLength;
- }
- /* if we've exhausted our new buffer, we're done */
- if (ulPartLen == 0) {
- *pulEncryptedPartLen = padoutlen;
- return CKR_OK;
- }
- }
-
-
-
- /* do it: NOTE: this assumes buf size in is >= buf size out! */
- rv = (*context->update)(context->cipherInfo,pEncryptedPart,
- &outlen, maxout, pPart, ulPartLen);
- *pulEncryptedPartLen = (CK_ULONG) (outlen + padoutlen);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-
-/* NSC_EncryptFinal finishes a multiple-part encryption operation. */
-CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen,i;
- unsigned int maxout = *pulLastEncryptedPartLen;
- CK_RV crv;
- SECStatus rv = SECSuccess;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
-
- *pulLastEncryptedPartLen = 0;
-
- /* do padding */
- if (context->doPad) {
- unsigned char padbyte = (unsigned char)
- (context->blockSize - context->padDataLength);
- /* fill out rest of pad buffer with pad magic*/
- for (i=context->padDataLength; i < context->blockSize; i++) {
- context->padBuf[i] = padbyte;
- }
- rv = (*context->update)(context->cipherInfo,pLastEncryptedPart,
- &outlen, maxout, context->padBuf, context->blockSize);
- if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen;
- }
-
- /* do it */
- pk11_SetContextByType(session, PK11_ENCRYPT, NULL);
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-/* NSC_Encrypt encrypts single-part data. */
-CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulEncryptedDataLen;
- CK_RV crv;
- CK_RV crv2;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- if (context->doPad) {
- CK_ULONG finalLen;
- /* padding is fairly complicated, have the update and final
- * code deal with it */
- pk11_FreeSession(session);
- crv = NSC_EncryptUpdate(hSession,pData,ulDataLen,pEncryptedData,
- pulEncryptedDataLen);
- if (crv != CKR_OK) *pulEncryptedDataLen = 0;
- maxoutlen -= *pulEncryptedDataLen;
- pEncryptedData += *pulEncryptedDataLen;
- finalLen = maxoutlen;
- crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
- if (crv2 == CKR_OK) { *pulEncryptedDataLen += finalLen; }
- return crv == CKR_OK ? crv2 :crv;
- }
-
-
- /* do it: NOTE: this assumes buf size is big enough. */
- rv = (*context->update)(context->cipherInfo, pEncryptedData,
- &outlen, maxoutlen, pData, ulDataLen);
- *pulEncryptedDataLen = (CK_ULONG) outlen;
- pk11_FreeContext(context);
- pk11_SetContextByType(session, PK11_ENCRYPT, NULL);
- pk11_FreeSession(session);
-
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-
-/*
- ************** Crypto Functions: Decrypt ************************
- */
-
-/* NSC_DecryptInit initializes a decryption operation. */
-static CK_RV pk11_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE dtype,
- PK11ContextType contextType)
-{
- PK11Session *session;
- PK11Object *key;
- PK11Attribute *att;
- PK11SessionContext *context;
- CK_RC2_CBC_PARAMS *rc2_param;
- CK_RC5_CBC_PARAMS *rc5_param;
- SECItem rc5Key;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- unsigned effectiveKeyLength;
- SECKEYLowPrivateKey *privKey;
- unsigned char newdeskey[8];
- PRBool useNewKey=PR_FALSE;
- int t;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- crv = pk11_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
- CKO_PRIVATE_KEY,dtype);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- /*
- * now handle each mechanism
- */
- switch(pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- privKey = pk11_GetPrivKey(key,CKK_RSA);
- if (privKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = privKey;
- context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_DecryptRaw : RSA_DecryptBlock);
- context->destroy = (context->cipherInfo == key->objectInfo) ?
- (PK11Destroy) pk11_Null : (PK11Destroy) pk11_FreePrivKey;
- break;
- case CKM_RC2_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- if (key_type != CKK_RC2) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
- effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8;
- context->cipherInfo = RC2_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen, rc2_param->iv,
- pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 :
- NSS_RC2_CBC, effectiveKeyLength);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC2_Decrypt;
- context->destroy = (PK11Destroy) RC2_DestroyContext;
- break;
- case CKM_RC5_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_RC5_ECB:
- case CKM_RC5_CBC:
- if (key_type != CKK_RC5) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
- if (context->doPad) {
- context->blockSize = rc5_param->ulWordsize*2;
- }
- rc5Key.data = (unsigned char*)att->attrib.pValue;
- rc5Key.len = att->attrib.ulValueLen;
- context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds,
- rc5_param->ulWordsize,rc5_param->pIv,
- pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC5_Decrypt;
- context->destroy = (PK11Destroy) RC5_DestroyContext;
- break;
- case CKM_RC4:
- if (key_type != CKK_RC4) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- context->cipherInfo =
- RC4_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC4_Decrypt;
- context->destroy = (PK11Destroy) RC4_DestroyContext;
- break;
- case CKM_CDMF_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_CDMF_ECB:
- case CKM_CDMF_CBC:
- if (key_type != CKK_CDMF) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
- useNewKey = PR_TRUE;
- if (crv != CKR_OK) break;
- goto finish_des;
- case CKM_DES_ECB:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES;
- goto finish_des;
- case CKM_DES_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES_CBC:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_CBC;
- goto finish_des;
- case CKM_DES3_ECB:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3;
- goto finish_des;
- case CKM_DES3_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES3_CBC:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3_CBC;
-finish_des:
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- if (useNewKey) {
- crv = pk11_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey);
- if (crv != CKR_OK) {
- pk11_FreeAttribute(att);
- break;
- }
- }
- context->cipherInfo = DES_CreateContext(
- useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,t, PR_FALSE);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) DES_Decrypt;
- context->destroy = (PK11Destroy) DES_DestroyContext;
-
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- pk11_FreeObject(key);
- if (crv != CKR_OK) {
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, contextType, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_DecryptInit initializes a decryption operation. */
-CK_RV NSC_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
-{
- return pk11_DecryptInit(hSession,pMechanism,hKey,CKA_DECRYPT,PK11_DECRYPT);
-}
-
-/* NSC_DecryptUpdate continues a multiple-part decryption operation. */
-CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
-{
- PK11SessionContext *context;
- unsigned int padoutlen = 0;
- unsigned int outlen;
- unsigned int maxout = *pulPartLen;
- CK_RV crv;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
-
- if (context->doPad) {
- /* first decrypt our saved buffer */
- if (context->padDataLength != 0) {
- rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
- maxout, context->padBuf, context->blockSize);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
- pPart += padoutlen;
- maxout -= padoutlen;
- }
- /* now save the final block for the next decrypt or the final */
- PORT_Memcpy(context->padBuf,&pEncryptedPart[ulEncryptedPartLen -
- context->blockSize], context->blockSize);
- context->padDataLength = context->blockSize;
- ulEncryptedPartLen -= context->padDataLength;
- }
-
- /* do it: NOTE: this assumes buf size in is >= buf size out! */
- rv = (*context->update)(context->cipherInfo,pPart, &outlen,
- maxout, pEncryptedPart, ulEncryptedPartLen);
- *pulPartLen = (CK_ULONG) (outlen + padoutlen);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-
-/* NSC_DecryptFinal finishes a multiple-part decryption operation. */
-CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen;
- unsigned int maxout = *pulLastPartLen;
- CK_RV crv;
- SECStatus rv = SECSuccess;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
-
- *pulLastPartLen = 0;
- if (context->doPad) {
- /* decrypt our saved buffer */
- if (context->padDataLength != 0) {
- /* this assumes that pLastPart is big enough to hold the *whole*
- * buffer!!! */
- rv = (*context->update)(context->cipherInfo, pLastPart, &outlen,
- maxout, context->padBuf, context->blockSize);
- if (rv == SECSuccess) {
- unsigned int padSize =
- (unsigned int) pLastPart[context->blockSize-1];
-
- *pulLastPartLen = outlen - padSize;
- }
- }
- }
-
- /* do it */
- pk11_SetContextByType(session, PK11_DECRYPT, NULL);
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-/* NSC_Decrypt decrypts encrypted data in a single part. */
-CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulDataLen;
- CK_RV crv;
- CK_RV crv2;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- if (context->doPad) {
- CK_ULONG finalLen;
- /* padding is fairly complicated, have the update and final
- * code deal with it */
- pk11_FreeSession(session);
- crv = NSC_DecryptUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
- pData, pulDataLen);
- if (crv != CKR_OK) *pulDataLen = 0;
- maxoutlen -= *pulDataLen;
- pData += *pulDataLen;
- finalLen = maxoutlen;
- crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
- if (crv2 == CKR_OK) { *pulDataLen += finalLen; }
- return crv == CKR_OK ? crv2 :crv;
- }
-
- rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
- pEncryptedData, ulEncryptedDataLen);
- *pulDataLen = (CK_ULONG) outlen;
- pk11_FreeContext(context);
- pk11_SetContextByType(session, PK11_DECRYPT, NULL);
- pk11_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-
-
-/*
- ************** Crypto Functions: Digest (HASH) ************************
- */
-
-/* NSC_DigestInit initializes a message-digesting operation. */
-CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism)
-{
- PK11Session *session;
- PK11SessionContext *context;
- MD2Context *md2_context;
- MD5Context *md5_context;
- SHA1Context *sha1_context;
- CK_RV crv = CKR_OK;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- crv = pk11_InitGeneric(session,&context,PK11_HASH,NULL,0,NULL, 0, 0);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- switch(pMechanism->mechanism) {
- case CKM_MD2:
- md2_context = MD2_NewContext();
- context->cipherInfo = (void *)md2_context;
- context->cipherInfoLen = MD2_FlattenSize(md2_context);
- context->currentMech = CKM_MD2;
- if (context->cipherInfo == NULL) {
- crv= CKR_HOST_MEMORY;
-
- }
- context->hashUpdate = (PK11Hash) MD2_Update;
- context->end = (PK11End) MD2_End;
- context->destroy = (PK11Destroy) MD2_DestroyContext;
- MD2_Begin(md2_context);
- break;
- case CKM_MD5:
- md5_context = MD5_NewContext();
- context->cipherInfo = (void *)md5_context;
- context->cipherInfoLen = MD5_FlattenSize(md5_context);
- context->currentMech = CKM_MD5;
- if (context->cipherInfo == NULL) {
- crv= CKR_HOST_MEMORY;
-
- }
- context->hashUpdate = (PK11Hash) MD5_Update;
- context->end = (PK11End) MD5_End;
- context->destroy = (PK11Destroy) MD5_DestroyContext;
- MD5_Begin(md5_context);
- break;
- case CKM_SHA_1:
- sha1_context = SHA1_NewContext();
- context->cipherInfo = (void *)sha1_context;
- context->cipherInfoLen = SHA1_FlattenSize(sha1_context);
- context->currentMech = CKM_SHA_1;
- if (context->cipherInfo == NULL) {
- crv= CKR_HOST_MEMORY;
- break;
- }
- context->hashUpdate = (PK11Hash) SHA1_Update;
- context->end = (PK11End) SHA1_End;
- context->destroy = (PK11Destroy) SHA1_DestroyContext;
- SHA1_Begin(sha1_context);
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- if (crv != CKR_OK) {
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, PK11_HASH, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_Digest digests data in a single part. */
-CK_RV NSC_Digest(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int digestLen;
- unsigned int maxout = *pulDigestLen;
- CK_RV crv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_HASH,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- /* do it: */
- (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen);
- /* NOTE: this assumes buf size is bigenough for the algorithm */
- (*context->end)(context->cipherInfo, pDigest, &digestLen,maxout);
- *pulDigestLen = digestLen;
-
- pk11_SetContextByType(session, PK11_HASH, NULL);
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_DigestUpdate continues a multiple-part message-digesting operation. */
-CK_RV NSC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- PK11SessionContext *context;
- CK_RV crv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_HASH,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
- /* do it: */
- (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen);
- return CKR_OK;
-}
-
-
-/* NSC_DigestFinal finishes a multiple-part message-digesting operation. */
-CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int maxout = *pulDigestLen;
- unsigned int digestLen;
- CK_RV crv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession, &context, PK11_HASH, PR_TRUE, &session);
- if (crv != CKR_OK) return crv;
-
- if (pDigest != NULL) {
- (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
- *pulDigestLen = digestLen;
- } else {
- *pulDigestLen = 0;
- }
-
- pk11_SetContextByType(session, PK11_HASH, NULL);
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-/*
- * this helper functions are used by Generic Macing and Signing functions
- * that use hashes as part of their operations.
- */
-static CK_RV
-pk11_doSubMD2(PK11SessionContext *context) {
- MD2Context *md2_context = MD2_NewContext();
- context->hashInfo = (void *)md2_context;
- if (context->hashInfo == NULL) {
- return CKR_HOST_MEMORY;
- }
- context->hashUpdate = (PK11Hash) MD2_Update;
- context->end = (PK11End) MD2_End;
- context->hashdestroy = (PK11Destroy) MD2_DestroyContext;
- MD2_Begin(md2_context);
- return CKR_OK;
-}
-
-static CK_RV
-pk11_doSubMD5(PK11SessionContext *context) {
- MD5Context *md5_context = MD5_NewContext();
- context->hashInfo = (void *)md5_context;
- if (context->hashInfo == NULL) {
- return CKR_HOST_MEMORY;
- }
- context->hashUpdate = (PK11Hash) MD5_Update;
- context->end = (PK11End) MD5_End;
- context->hashdestroy = (PK11Destroy) MD5_DestroyContext;
- MD5_Begin(md5_context);
- return CKR_OK;
-}
-
-static CK_RV
-pk11_doSubSHA1(PK11SessionContext *context) {
- SHA1Context *sha1_context = SHA1_NewContext();
- context->hashInfo = (void *)sha1_context;
- if (context->hashInfo == NULL) {
- return CKR_HOST_MEMORY;
- }
- context->hashUpdate = (PK11Hash) SHA1_Update;
- context->end = (PK11End) SHA1_End;
- context->hashdestroy = (PK11Destroy) SHA1_DestroyContext;
- SHA1_Begin(sha1_context);
- return CKR_OK;
-}
-
-/*
- * HMAC General copies only a portion of the result. This update routine likes
- * the final HMAC output with the signature.
- */
-static SECStatus
-pk11_HMACCopy(CK_ULONG *copyLen,unsigned char *sig,unsigned int *sigLen,
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
-{
- if (maxLen < *copyLen) return SECFailure;
- PORT_Memcpy(sig,hash,*copyLen);
- *sigLen = *copyLen;
- return SECSuccess;
-}
-
-/* Verify is just a compare for HMAC */
-static SECStatus
-pk11_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen,
- unsigned char *hash, unsigned int hashLen)
-{
- return PORT_Memcmp(sig,hash,*copyLen) ? SECSuccess : SECFailure ;
-}
-
-/*
- * common HMAC initalization routine
- */
-static CK_RV
-pk11_doHMACInit(PK11SessionContext *context,SECOidTag oid,
- PK11Object *key, CK_ULONG mac_size)
-{
- PK11Attribute *keyval;
- HMACContext *HMACcontext;
- CK_ULONG *intpointer;
-
- keyval = pk11_FindAttribute(key,CKA_VALUE);
- if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
-
- HMACcontext = HMAC_Create(oid, (const unsigned char*)keyval->attrib.pValue,
- keyval->attrib.ulValueLen);
- context->hashInfo = HMACcontext;
- context->multi = PR_TRUE;
- pk11_FreeAttribute(keyval);
- if (context->hashInfo == NULL) {
- return CKR_HOST_MEMORY;
- }
- context->hashUpdate = (PK11Hash) HMAC_Update;
- context->end = (PK11End) HMAC_Finish;
-
- context->hashdestroy = (PK11Destroy) pk11_HMAC_Destroy;
- intpointer = (CK_ULONG *) PORT_Alloc(sizeof(CK_ULONG));
- if (intpointer == NULL) {
- return CKR_HOST_MEMORY;
- }
- *intpointer = mac_size;
- context->cipherInfo = (void *) intpointer;
- context->destroy = (PK11Destroy) pk11_Space;
- context->update = (PK11Cipher) pk11_HMACCopy;
- context->verify = (PK11Verify) pk11_HMACCmp;
- HMAC_Begin(HMACcontext);
- return CKR_OK;
-}
-
-/*
- * SSL Macing support. SSL Macs are inited, then update with the base
- * hashing algorithm, then finalized in sign and verify
- */
-
-/*
- * FROM SSL:
- * 60 bytes is 3 times the maximum length MAC size that is supported.
- * We probably should have one copy of this table. We still need this table
- * in ssl to 'sign' the handshake hashes.
- */
-static unsigned char ssl_pad_1 [60] = {
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36
-};
-static unsigned char ssl_pad_2 [60] = {
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c
-};
-
-static SECStatus
-pk11_SSLMACSign(PK11SSLMACInfo *info,unsigned char *sig,unsigned int *sigLen,
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
-{
- unsigned char tmpBuf[PK11_MAX_MAC_LENGTH];
- unsigned int out;
-
- info->begin(info->hashContext);
- info->update(info->hashContext,info->key,info->keySize);
- info->update(info->hashContext,ssl_pad_2,info->padSize);
- info->update(info->hashContext,hash,hashLen);
- info->end(info->hashContext,tmpBuf,&out,PK11_MAX_MAC_LENGTH);
- PORT_Memcpy(sig,tmpBuf,info->macSize);
- *sigLen = info->macSize;
- return SECSuccess;
-}
-
-static SECStatus
-pk11_SSLMACVerify(PK11SSLMACInfo *info,unsigned char *sig,unsigned int sigLen,
- unsigned char *hash, unsigned int hashLen)
-{
- unsigned char tmpBuf[PK11_MAX_MAC_LENGTH];
- unsigned int out;
-
- info->begin(info->hashContext);
- info->update(info->hashContext,info->key,info->keySize);
- info->update(info->hashContext,ssl_pad_2,info->padSize);
- info->update(info->hashContext,hash,hashLen);
- info->end(info->hashContext,tmpBuf,&out,PK11_MAX_MAC_LENGTH);
- return (PORT_Memcmp(sig,tmpBuf,info->macSize) == 0) ?
- SECSuccess : SECFailure;
-}
-
-/*
- * common HMAC initalization routine
- */
-static CK_RV
-pk11_doSSLMACInit(PK11SessionContext *context,SECOidTag oid,
- PK11Object *key, CK_ULONG mac_size)
-{
- PK11Attribute *keyval;
- PK11Begin begin;
- int padSize;
- PK11SSLMACInfo *sslmacinfo;
- CK_RV crv = CKR_MECHANISM_INVALID;
-
- if (oid == SEC_OID_SHA1) {
- crv = pk11_doSubSHA1(context);
- begin = (PK11Begin) SHA1_Begin;
- if (crv != CKR_OK) return crv;
- padSize = 40;
- } else {
- crv = pk11_doSubMD5(context);
- if (crv != CKR_OK) return crv;
- begin = (PK11Begin) MD5_Begin;
- padSize = 48;
- }
- context->multi = PR_TRUE;
-
- keyval = pk11_FindAttribute(key,CKA_VALUE);
- if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
-
- context->hashUpdate(context->hashInfo,keyval->attrib.pValue,
- keyval->attrib.ulValueLen);
- context->hashUpdate(context->hashInfo,ssl_pad_1,padSize);
- sslmacinfo = (PK11SSLMACInfo *) PORT_Alloc(sizeof(PK11SSLMACInfo));
- if (sslmacinfo == NULL) {
- pk11_FreeAttribute(keyval);
- return CKR_HOST_MEMORY;
- }
- sslmacinfo->macSize = mac_size;
- sslmacinfo->hashContext = context->hashInfo;
- PORT_Memcpy(sslmacinfo->key,keyval->attrib.pValue,
- keyval->attrib.ulValueLen);
- sslmacinfo->keySize = keyval->attrib.ulValueLen;
- sslmacinfo->begin = begin;
- sslmacinfo->end = context->end;
- sslmacinfo->update = context->hashUpdate;
- sslmacinfo->padSize = padSize;
- pk11_FreeAttribute(keyval);
- context->cipherInfo = (void *) sslmacinfo;
- context->destroy = (PK11Destroy) pk11_Space;
- context->update = (PK11Cipher) pk11_SSLMACSign;
- context->verify = (PK11Verify) pk11_SSLMACVerify;
- return CKR_OK;
-}
-
-typedef struct {
- PRUint32 cxSize; /* size of allocated block, in bytes. */
- PRUint32 cxKeyLen; /* number of bytes of cxBuf containing key. */
- PRUint32 cxDataLen; /* number of bytes of cxBuf containing data. */
- SECStatus cxRv; /* records failure of void functions. */
- unsigned char cxBuf[512]; /* actual size may be larger than 512. */
-} TLSPRFContext;
-
-static void
-pk11_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data,
- unsigned int data_len)
-{
- PRUint32 bytesUsed = PK11_OFFSETOF(TLSPRFContext, cxBuf) +
- cx->cxKeyLen + cx->cxDataLen;
-
- if (cx->cxRv != SECSuccess) /* function has previously failed. */
- return;
- if (bytesUsed + data_len > cx->cxSize) {
- /* We don't use realloc here because
- ** (a) realloc doesn't zero out the old block, and
- ** (b) if realloc fails, we lose the old block.
- */
- PRUint32 blockSize = bytesUsed + data_len + 512;
- TLSPRFContext *new_cx = (TLSPRFContext *)PORT_Alloc(blockSize);
- if (!new_cx) {
- cx->cxRv = SECFailure;
- return;
- }
- PORT_Memcpy(new_cx, cx, cx->cxSize);
- new_cx->cxSize = blockSize;
-
- PORT_ZFree(cx, cx->cxSize);
- cx = new_cx;
- }
- PORT_Memcpy(cx->cxBuf + cx->cxKeyLen + cx->cxDataLen, data, data_len);
- cx->cxDataLen += data_len;
-}
-
-static void
-pk11_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout,
- unsigned int *pDigestLen, unsigned int maxDigestLen)
-{
- *pDigestLen = 0; /* tells Verify that no data has been input yet. */
-}
-
-/* Compute the PRF values from the data previously input. */
-static SECStatus
-pk11_TLSPRFUpdate(TLSPRFContext *cx,
- unsigned char *sig, /* output goes here. */
- unsigned int * sigLen, /* how much output. */
- unsigned int maxLen, /* output buffer size */
- unsigned char *hash, /* unused. */
- unsigned int hashLen) /* unused. */
-{
- SECStatus rv;
- SECItem sigItem;
- SECItem seedItem;
- SECItem secretItem;
-
- if (cx->cxRv != SECSuccess)
- return cx->cxRv;
-
- secretItem.data = cx->cxBuf;
- secretItem.len = cx->cxKeyLen;
-
- seedItem.data = cx->cxBuf + cx->cxKeyLen;
- seedItem.len = cx->cxDataLen;
-
- sigItem.data = sig;
- sigItem.len = maxLen;
-
- rv = pk11_PRF(&secretItem, NULL, &seedItem, &sigItem);
- if (rv == SECSuccess && sigLen != NULL)
- *sigLen = sigItem.len;
- return rv;
-
-}
-
-static SECStatus
-pk11_TLSPRFVerify(TLSPRFContext *cx,
- unsigned char *sig, /* input, for comparison. */
- unsigned int sigLen, /* length of sig. */
- unsigned char *hash, /* data to be verified. */
- unsigned int hashLen) /* size of hash data. */
-{
- unsigned char * tmp = (unsigned char *)PORT_Alloc(sigLen);
- unsigned int tmpLen = sigLen;
- SECStatus rv;
-
- if (!tmp)
- return SECFailure;
- if (hashLen) {
- /* hashLen is non-zero when the user does a one-step verify.
- ** In this case, none of the data has been input yet.
- */
- pk11_TLSPRFHashUpdate(cx, hash, hashLen);
- }
- rv = pk11_TLSPRFUpdate(cx, tmp, &tmpLen, sigLen, NULL, 0);
- if (rv == SECSuccess) {
- rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen));
- }
- PORT_ZFree(tmp, sigLen);
- return rv;
-}
-
-static void
-pk11_TLSPRFHashDestroy(TLSPRFContext *cx, PRBool freeit)
-{
- if (freeit)
- PORT_ZFree(cx, cx->cxSize);
-}
-
-static CK_RV
-pk11_TLSPRFInit(PK11SessionContext *context,
- PK11Object * key,
- CK_KEY_TYPE key_type)
-{
- PK11Attribute * keyVal;
- TLSPRFContext * prf_cx;
- CK_RV crv = CKR_HOST_MEMORY;
- PRUint32 keySize;
- PRUint32 blockSize;
-
- if (key_type != CKK_GENERIC_SECRET)
- return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */
-
- context->multi = PR_TRUE;
-
- keyVal = pk11_FindAttribute(key, CKA_VALUE);
- keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen;
- blockSize = keySize + sizeof(TLSPRFContext);
- prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize);
- if (!prf_cx)
- goto done;
- prf_cx->cxSize = blockSize;
- prf_cx->cxKeyLen = keySize;
- prf_cx->cxDataLen = 0;
- prf_cx->cxRv = SECSuccess;
- if (keySize)
- PORT_Memcpy(prf_cx->cxBuf, keyVal->attrib.pValue, keySize);
-
- context->hashInfo = (void *) prf_cx;
- context->cipherInfo = (void *) prf_cx;
- context->hashUpdate = (PK11Hash) pk11_TLSPRFHashUpdate;
- context->end = (PK11End) pk11_TLSPRFEnd;
- context->update = (PK11Cipher) pk11_TLSPRFUpdate;
- context->verify = (PK11Verify) pk11_TLSPRFVerify;
- context->destroy = (PK11Destroy) pk11_Null;
- context->hashdestroy = (PK11Destroy) pk11_TLSPRFHashDestroy;
- crv = CKR_OK;
-
-done:
- if (keyVal)
- pk11_FreeAttribute(keyVal);
- return crv;
-}
-
-/*
- ************** Crypto Functions: Sign ************************
- */
-
-/*
- * Check if We're using CBCMacing and initialize the session context if we are.
- */
-static CK_RV
-pk11_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage,
- PK11ContextType contextType)
-
-{
- CK_MECHANISM cbc_mechanism;
- CK_ULONG mac_bytes = PK11_INVALID_MAC_SIZE;
- CK_RC2_CBC_PARAMS rc2_params;
- CK_RC5_CBC_PARAMS rc5_params;
- CK_RC5_MAC_GENERAL_PARAMS *rc5_mac;
- unsigned char ivBlock[PK11_MAX_BLOCK_SIZE];
- PK11SessionContext *context;
- CK_RV crv;
- int blockSize;
-
- switch (pMechanism->mechanism) {
- case CKM_RC2_MAC_GENERAL:
- mac_bytes =
- ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
- /* fall through */
- case CKM_RC2_MAC:
- /* this works because ulEffectiveBits is in the same place in both the
- * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */
- rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *)
- pMechanism->pParameter)->ulEffectiveBits;
- PORT_Memset(rc2_params.iv,0,sizeof(rc2_params.iv));
- cbc_mechanism.mechanism = CKM_RC2_CBC;
- cbc_mechanism.pParameter = &rc2_params;
- cbc_mechanism.ulParameterLen = sizeof(rc2_params);
- blockSize = 8;
- break;
- case CKM_RC5_MAC_GENERAL:
- mac_bytes =
- ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
- /* fall through */
- case CKM_RC5_MAC:
- /* this works because ulEffectiveBits is in the same place in both the
- * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */
- rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter;
- rc5_params.ulWordsize = rc5_mac->ulWordsize;
- rc5_params.ulRounds = rc5_mac->ulRounds;
- rc5_params.pIv = ivBlock;
- blockSize = rc5_mac->ulWordsize*2;
- rc5_params.ulIvLen = blockSize;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_RC5_CBC;
- cbc_mechanism.pParameter = &rc5_params;
- cbc_mechanism.ulParameterLen = sizeof(rc5_params);
- break;
- /* add cast and idea later */
- case CKM_DES_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_DES_MAC:
- blockSize = 8;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_DES_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- case CKM_DES3_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_DES3_MAC:
- blockSize = 8;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_DES3_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- case CKM_CDMF_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_CDMF_MAC:
- blockSize = 8;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_CDMF_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- default:
- return CKR_FUNCTION_NOT_SUPPORTED;
- }
-
- crv = pk11_EncryptInit(hSession, &cbc_mechanism, hKey, keyUsage,
- contextType);
- if (crv != CKR_OK) return crv;
- crv = pk11_GetContext(hSession,&context,contextType,PR_TRUE,NULL);
-
- /* this shouldn't happen! */
- PORT_Assert(crv == CKR_OK);
- if (crv != CKR_OK) return crv;
- context->blockSize = blockSize;
- if (mac_bytes == PK11_INVALID_MAC_SIZE) mac_bytes = blockSize/2;
- context->macSize = mac_bytes;
- return CKR_OK;
-}
-
-/*
- * encode RSA PKCS #1 Signature data before signing...
- */
-static SECStatus
-pk11_HashSign(PK11HashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
-{
-
- SECStatus rv = SECFailure;
- SECItem digder;
- PLArenaPool *arena = NULL;
- SGNDigestInfo *di = NULL;
-
- digder.data = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) { goto loser; }
-
- /* Construct digest info */
- di = SGN_CreateDigestInfo(info->hashOid, hash, hashLen);
- if (!di) { goto loser; }
-
- /* Der encode the digest as a DigestInfo */
- rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /*
- ** Encrypt signature after constructing appropriate PKCS#1 signature
- ** block
- */
- rv = RSA_Sign(info->key,sig,sigLen,maxLen,digder.data,digder.len);
-
- loser:
- SGN_DestroyDigestInfo(di);
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return rv;
-}
-
-static SECStatus
-nsc_DSA_Verify_Stub(void *ctx, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData, CK_ULONG ulDataLen)
-{
- SECItem signature, digest;
-
- signature.data = pSignature;
- signature.len = ulSignatureLen;
- digest.data = pData;
- digest.len = ulDataLen;
- return DSA_VerifyDigest((DSAPublicKey *)ctx, &signature, &digest);
-}
-
-static SECStatus
-nsc_DSA_Sign_Stub(void *ctx, CK_BYTE_PTR pSignature,
- CK_ULONG_PTR ulSignatureLen, CK_ULONG maxulSignatureLen,
- CK_BYTE_PTR pData, CK_ULONG ulDataLen)
-{
- SECItem signature = { 0 }, digest;
- SECStatus rv;
-
- (void)SECITEM_AllocItem(NULL, &signature, maxulSignatureLen);
- digest.data = pData;
- digest.len = ulDataLen;
- rv = DSA_SignDigest((DSAPrivateKey *)ctx, &signature, &digest);
- *ulSignatureLen = signature.len;
- PORT_Memcpy(pSignature, signature.data, signature.len);
- SECITEM_FreeItem(&signature, PR_FALSE);
- return rv;
-}
-
-/* NSC_SignInit setups up the signing operations. There are three basic
- * types of signing:
- * (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
- * to data in a single Sign operation (which often looks a lot like an
- * encrypt, with data coming in and data going out).
- * (2) Hash based signing, where we continually hash the data, then apply
- * some sort of signature to the end.
- * (3) Block Encryption CBC MAC's, where the Data is encrypted with a key,
- * and only the final block is part of the mac.
- *
- * For case number 3, we initialize a context much like the Encryption Context
- * (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and
- * C_Final by the following method... if it's not multi-part, and it's doesn't
- * have a hash context, it must be a block Encryption CBC MAC.
- *
- * For case number 2, we initialize a hash structure, as well as make it
- * multi-part. Updates are simple calls to the hash update function. Final
- * calls the hashend, then passes the result to the 'update' function (which
- * operates as a final signature function). In some hash based MAC'ing (as
- * opposed to hash base signatures), the update function is can be simply a
- * copy (as is the case with HMAC).
- */
-CK_RV NSC_SignInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
-{
- PK11Session *session;
- PK11Object *key;
- PK11SessionContext *context;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- SECKEYLowPrivateKey *privKey;
- PK11HashSignInfo *info = NULL;
-
- /* Block Cipher MACing Algorithms use a different Context init method..*/
- crv = pk11_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, PK11_SIGN);
- if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;
-
- /* we're not using a block cipher mac */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- crv = pk11_InitGeneric(session,&context,PK11_SIGN,&key,hKey,&key_type,
- CKO_PRIVATE_KEY,CKA_SIGN);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- context->multi = PR_FALSE;
-
- switch(pMechanism->mechanism) {
- case CKM_MD5_RSA_PKCS:
- context->multi = PR_TRUE;
- crv = pk11_doSubMD2(context);
- if (crv != CKR_OK) break;
- context->update = (PK11Cipher) pk11_HashSign;
- info = (PK11HashSignInfo *)PORT_Alloc(sizeof(PK11HashSignInfo));
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->hashOid = SEC_OID_MD5;
- goto finish_rsa;
- case CKM_MD2_RSA_PKCS:
- context->multi = PR_TRUE;
- crv = pk11_doSubMD2(context);
- if (crv != CKR_OK) break;
- context->update = (PK11Cipher) pk11_HashSign;
- info = (PK11HashSignInfo *)PORT_Alloc(sizeof(PK11HashSignInfo));
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->hashOid = SEC_OID_MD2;
- goto finish_rsa;
- case CKM_SHA1_RSA_PKCS:
- context->multi = PR_TRUE;
- crv = pk11_doSubSHA1(context);
- if (crv != CKR_OK) break;
- context->update = (PK11Cipher) pk11_HashSign;
- info = (PK11HashSignInfo *)PORT_Alloc(sizeof(PK11HashSignInfo));
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->hashOid = SEC_OID_SHA1;
- goto finish_rsa;
- case CKM_RSA_PKCS:
- context->update = (PK11Cipher) RSA_Sign;
- goto finish_rsa;
- case CKM_RSA_X_509:
- context->update = (PK11Cipher) RSA_SignRaw;
-finish_rsa:
- if (key_type != CKK_RSA) {
- if (info) PORT_Free(info);
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- privKey = pk11_GetPrivKey(key,CKK_RSA);
- if (privKey == NULL) {
- if (info) PORT_Free(info);
- crv = CKR_HOST_MEMORY;
- break;
- }
- /* OK, info is allocated only if we're doing hash and sign mechanism.
- * It's necessary to be able to set the correct OID in the final
- * signature.
- * Second, what's special about privKey == key->objectInfo?
- * Well we don't 'cache' token versions
- * of private keys because (1) it's sensitive data, and (2) it never
- * gets destroyed. Instead we grab the key out of the database as
- * necessary, but now the key is our context, and we need to free
- * it when we are done. Non-token private keys will get freed when
- * the user destroys the session object (or the session the session
- * object lives in) */
- if (info) {
- info->key = privKey;
- context->cipherInfo = info;
- context->destroy = (privKey == key->objectInfo) ?
- (PK11Destroy)pk11_Space:(PK11Destroy)pk11_FreeSignInfo;
- } else {
- context->cipherInfo = privKey;
- context->destroy = (privKey == key->objectInfo) ?
- (PK11Destroy)pk11_Null:(PK11Destroy)pk11_FreePrivKey;
- }
- break;
-
- case CKM_DSA_SHA1:
- context->multi = PR_TRUE;
- crv = pk11_doSubSHA1(context);
- if (crv != CKR_OK) break;
- /* fall through */
- case CKM_DSA:
- if (key_type != CKK_DSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- privKey = pk11_GetPrivKey(key,CKK_DSA);
- if (privKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = &(privKey->u.dsa);
- context->update = (PK11Cipher) nsc_DSA_Sign_Stub;
- context->destroy = pk11_Null;
-
- if (key->objectInfo != privKey) SECKEY_LowDestroyPrivateKey(privKey);
- break;
- case CKM_MD2_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_MD2_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,MD2_LENGTH);
- break;
- case CKM_MD5_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_MD5_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,MD5_LENGTH);
- break;
- case CKM_SHA_1_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SHA_1_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,SHA1_LENGTH);
- break;
- case CKM_SSL3_MD5_MAC:
- crv = pk11_doSSLMACInit(context,SEC_OID_MD5,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SSL3_SHA1_MAC:
- crv = pk11_doSSLMACInit(context,SEC_OID_SHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_TLS_PRF_GENERAL:
- crv = pk11_TLSPRFInit(context, key, key_type);
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- pk11_FreeObject(key);
- if (crv != CKR_OK) {
- PORT_Free(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, PK11_SIGN, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* MACUpdate is the common implementation for SignUpdate and VerifyUpdate.
- * (sign and verify only very in their setup and final operations) */
-static CK_RV
-pk11_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,PK11ContextType type)
-{
- unsigned int outlen;
- PK11SessionContext *context;
- CK_RV crv;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,type,PR_FALSE,NULL);
- if (crv != CKR_OK) return crv;
-
- if (context->hashInfo) {
- (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen);
- return CKR_OK;
- }
-
- /* must be block cipher macing */
-
- /* deal with previous buffered data */
- if (context->padDataLength != 0) {
- int i;
- /* fill in the padded to a full block size */
- for (i=context->padDataLength; (ulPartLen != 0) &&
- i < (int)context->blockSize; i++) {
- context->padBuf[i] = *pPart++;
- ulPartLen--;
- context->padDataLength++;
- }
-
- /* not enough data to encrypt yet? then return */
- if (context->padDataLength != context->blockSize) return CKR_OK;
- /* encrypt the current padded data */
- rv = (*context->update)(context->cipherInfo,context->macBuf,&outlen,
- PK11_MAX_BLOCK_SIZE,context->padBuf,context->blockSize);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
- }
-
- /* save the residual */
- context->padDataLength = ulPartLen % context->blockSize;
- if (context->padDataLength) {
- PORT_Memcpy(context->padBuf,
- &pPart[ulPartLen-context->padDataLength],
- context->padDataLength);
- ulPartLen -= context->padDataLength;
- }
-
- /* if we've exhausted our new buffer, we're done */
- if (ulPartLen == 0) { return CKR_OK; }
-
- /* run the data through out encrypter */
- while (ulPartLen) {
- rv = (*context->update)(context->cipherInfo, context->padBuf, &outlen,
- PK11_MAX_BLOCK_SIZE, pPart, context->blockSize);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
- /* paranoia.. make sure we exit the loop */
- PORT_Assert(ulPartLen >= context->blockSize);
- if (ulPartLen < context->blockSize) break;
- ulPartLen -= context->blockSize;
- }
-
- return CKR_OK;
-
-}
-
-/* NSC_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-CK_RV NSC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- return pk11_MACUpdate(hSession, pPart, ulPartLen, PK11_SIGN);
-}
-
-
-/* NSC_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
-CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen;
- unsigned int digestLen;
- unsigned int maxoutlen = *pulSignatureLen;
- unsigned char tmpbuf[PK11_MAX_MAC_LENGTH];
- CK_RV crv;
- SECStatus rv = SECSuccess;
-
- /* make sure we're legal */
- *pulSignatureLen = 0;
- crv = pk11_GetContext(hSession,&context,PK11_SIGN,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
-
- if (context->hashInfo) {
- (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
- rv = (*context->update)(context->cipherInfo, pSignature,
- &outlen, maxoutlen, tmpbuf, digestLen);
- *pulSignatureLen = (CK_ULONG) outlen;
- } else {
- /* deal with the last block if any residual */
- if (context->padDataLength) {
- /* fill out rest of pad buffer with pad magic*/
- int i;
- for (i=context->padDataLength; i < (int)context->blockSize; i++) {
- context->padBuf[i] = 0;
- }
- rv = (*context->update)(context->cipherInfo,context->macBuf,
- &outlen,PK11_MAX_BLOCK_SIZE,context->padBuf,context->blockSize);
- }
- if (rv == SECSuccess) {
- PORT_Memcpy(pSignature,context->macBuf,context->macSize);
- *pulSignatureLen = context->macSize;
- }
- }
-
- pk11_FreeContext(context);
- pk11_SetContextByType(session, PK11_SIGN, NULL);
- pk11_FreeSession(session);
-
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-/* NSC_Sign signs (encrypts with private key) data in a single part,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-CK_RV NSC_Sign(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulSignatureLen;
- CK_RV crv,crv2;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_SIGN,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- /* multi part Signing are completely implemented by SignUpdate and
- * sign Final */
- if (context->multi) {
- pk11_FreeSession(session);
- crv = NSC_SignUpdate(hSession,pData,ulDataLen);
- if (crv != CKR_OK) *pulSignatureLen = 0;
- crv2 = NSC_SignFinal(hSession, pSignature, pulSignatureLen);
- return crv == CKR_OK ? crv2 :crv;
- }
-
- rv = (*context->update)(context->cipherInfo, pSignature,
- &outlen, maxoutlen, pData, ulDataLen);
- *pulSignatureLen = (CK_ULONG) outlen;
- pk11_FreeContext(context);
- pk11_SetContextByType(session, PK11_SIGN, NULL);
- pk11_FreeSession(session);
-
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-
-/*
- ************** Crypto Functions: Sign Recover ************************
- */
-/* NSC_SignRecoverInit initializes a signature operation,
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
-CK_RV NSC_SignRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
- switch (pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- return NSC_SignInit(hSession,pMechanism,hKey);
- default:
- break;
- }
- return CKR_MECHANISM_INVALID;
-}
-
-
-/* NSC_SignRecover signs data in a single operation
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
-CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
-{
- return NSC_Sign(hSession,pData,ulDataLen,pSignature,pulSignatureLen);
-}
-
-/*
- ************** Crypto Functions: verify ************************
- */
-
-/* Handle RSA Signature formating */
-static SECStatus
-pk11_hashCheckSign(PK11HashVerifyInfo *info, unsigned char *sig,
- unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
-{
-
- SECItem it;
- SGNDigestInfo *di = NULL;
- SECStatus rv = SECSuccess;
-
- it.data = NULL;
-
- if (info->key == NULL) goto loser;
-
- it.len = SECKEY_LowPublicModulusLen(info->key);
- if (!it.len) goto loser;
-
- it.data = (unsigned char *) PORT_Alloc(it.len);
- if (it.data == NULL) goto loser;
-
- /* decrypt the block */
- rv = RSA_CheckSignRecover(info->key, it.data, &it.len, it.len, sig, sigLen);
- if (rv != SECSuccess) goto loser;
-
- di = SGN_DecodeDigestInfo(&it);
- if (di == NULL) goto loser;
- if (di->digest.len != digestLen) goto loser;
-
- /* make sure the tag is OK */
- if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != info->hashOid) {
- goto loser;
- }
- /* Now check the signature */
- if (PORT_Memcmp(digest, di->digest.data, di->digest.len) == 0) {
- goto done;
- }
-
- loser:
- rv = SECFailure;
-
- done:
- if (it.data != NULL) PORT_Free(it.data);
- if (di != NULL) SGN_DestroyDigestInfo(di);
-
- return rv;
-}
-
-/* NSC_VerifyInit initializes a verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature (e.g. DSA) */
-CK_RV NSC_VerifyInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
- PK11Session *session;
- PK11Object *key;
- PK11SessionContext *context;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- SECKEYLowPublicKey *pubKey;
- PK11HashVerifyInfo *info = NULL;
-
- /* Block Cipher MACing Algorithms use a different Context init method..*/
- crv = pk11_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY, PK11_VERIFY);
- if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- crv = pk11_InitGeneric(session,&context,PK11_VERIFY,&key,hKey,&key_type,
- CKO_PUBLIC_KEY,CKA_VERIFY);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- context->multi = PR_FALSE;
-
- switch(pMechanism->mechanism) {
- case CKM_MD5_RSA_PKCS:
- context->multi = PR_TRUE;
- crv = pk11_doSubMD5(context);
- if (crv != CKR_OK) break;
- context->verify = (PK11Verify) pk11_hashCheckSign;
- info = (PK11HashVerifyInfo *)PORT_Alloc(sizeof(PK11HashVerifyInfo));
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->hashOid = SEC_OID_MD5;
- goto finish_rsa;
- case CKM_MD2_RSA_PKCS:
- context->multi = PR_TRUE;
- crv = pk11_doSubMD2(context);
- if (crv != CKR_OK) break;
- context->verify = (PK11Verify) pk11_hashCheckSign;
- info = (PK11HashVerifyInfo *)PORT_Alloc(sizeof(PK11HashVerifyInfo));
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->hashOid = SEC_OID_MD2;
- goto finish_rsa;
- case CKM_SHA1_RSA_PKCS:
- context->multi = PR_TRUE;
- crv = pk11_doSubSHA1(context);
- if (crv != CKR_OK) break;
- context->verify = (PK11Verify) pk11_hashCheckSign;
- info = (PK11HashVerifyInfo *)PORT_Alloc(sizeof(PK11HashVerifyInfo));
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->hashOid = SEC_OID_SHA1;
- goto finish_rsa;
- case CKM_RSA_PKCS:
- context->verify = (PK11Verify) RSA_CheckSign;
- goto finish_rsa;
- case CKM_RSA_X_509:
- context->verify = (PK11Verify) RSA_CheckSignRaw;
-finish_rsa:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- pubKey = pk11_GetPubKey(key,CKK_RSA);
- if (pubKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- if (info) {
- info->key = pubKey;
- context->cipherInfo = info;
- context->destroy = pk11_Space;
- } else {
- context->cipherInfo = pubKey;
- context->destroy = pk11_Null;
- }
- break;
- case CKM_DSA_SHA1:
- context->multi = PR_TRUE;
- crv = pk11_doSubSHA1(context);
- if (crv != CKR_OK) break;
- /* fall through */
- case CKM_DSA:
- if (key_type != CKK_DSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- pubKey = pk11_GetPubKey(key,CKK_DSA);
- if (pubKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = &(pubKey->u.dsa);
- context->verify = (PK11Verify) nsc_DSA_Verify_Stub;
- context->destroy = pk11_Null;
- break;
-
- case CKM_MD2_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_MD2_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,MD2_LENGTH);
- break;
- case CKM_MD5_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_MD5_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,MD5_LENGTH);
- break;
- case CKM_SHA_1_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SHA_1_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,SHA1_LENGTH);
- break;
- case CKM_SSL3_MD5_MAC:
- crv = pk11_doSSLMACInit(context,SEC_OID_MD5,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SSL3_SHA1_MAC:
- crv = pk11_doSSLMACInit(context,SEC_OID_SHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_TLS_PRF_GENERAL:
- crv = pk11_TLSPRFInit(context, key, key_type);
-
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- pk11_FreeObject(key);
- if (crv != CKR_OK) {
- PORT_Free(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, PK11_VERIFY, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- CK_RV crv;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_VERIFY,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- rv = (*context->verify)(context->cipherInfo,pSignature, ulSignatureLen,
- pData, ulDataLen);
- pk11_FreeContext(context);
- pk11_SetContextByType(session, PK11_VERIFY, NULL);
- pk11_FreeSession(session);
-
- return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;
-
-}
-
-
-/* NSC_VerifyUpdate continues a multiple-part verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-CK_RV NSC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- return pk11_MACUpdate(hSession, pPart, ulPartLen, PK11_VERIFY);
-}
-
-
-/* NSC_VerifyFinal finishes a multiple-part verification operation,
- * checking the signature. */
-CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen;
- unsigned int digestLen;
- unsigned char tmpbuf[PK11_MAX_MAC_LENGTH];
- CK_RV crv;
- SECStatus rv = SECSuccess;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_VERIFY,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
-
- if (context->hashInfo) {
- (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
- rv = (*context->verify)(context->cipherInfo, pSignature,
- ulSignatureLen, tmpbuf, digestLen);
- } else {
- if (context->padDataLength) {
- /* fill out rest of pad buffer with pad magic*/
- int i;
- for (i=context->padDataLength; i < (int)context->blockSize; i++) {
- context->padBuf[i] = 0;
- }
- rv = (*context->update)(context->cipherInfo,context->macBuf,
- &outlen,PK11_MAX_BLOCK_SIZE,context->padBuf,context->blockSize);
- }
- if (rv == SECSuccess) {
- rv =(PORT_Memcmp(pSignature,context->macBuf,context->macSize) == 0)
- ? SECSuccess : SECFailure;
- }
- }
-
- pk11_FreeContext(context);
- pk11_SetContextByType(session, PK11_VERIFY, NULL);
- pk11_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;
-
-}
-
-/*
- ************** Crypto Functions: Verify Recover ************************
- */
-
-/* NSC_VerifyRecoverInit initializes a signature verification operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
-CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
- PK11Session *session;
- PK11Object *key;
- PK11SessionContext *context;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- SECKEYLowPublicKey *pubKey;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- crv = pk11_InitGeneric(session,&context,PK11_VERIFY_RECOVER,
- &key,hKey,&key_type,CKO_PUBLIC_KEY,CKA_VERIFY_RECOVER);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- context->multi = PR_TRUE;
-
- switch(pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- pubKey = pk11_GetPubKey(key,CKK_RSA);
- if (pubKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = pubKey;
- context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_CheckSignRecoverRaw : RSA_CheckSignRecover);
- context->destroy = pk11_Null;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- pk11_FreeObject(key);
- if (crv != CKR_OK) {
- PORT_Free(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, PK11_VERIFY_RECOVER, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_VerifyRecover verifies a signature in a single-part operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
-CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)
-{
- PK11Session *session;
- PK11SessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulDataLen;
- CK_RV crv;
- SECStatus rv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession,&context,PK11_VERIFY_RECOVER,
- PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
- pSignature, ulSignatureLen);
- *pulDataLen = (CK_ULONG) outlen;
- pk11_FreeContext(context);
- pk11_SetContextByType(session, PK11_VERIFY_RECOVER, NULL);
- pk11_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-/*
- **************************** Random Functions: ************************
- */
-
-/* NSC_SeedRandom mixes additional seed material into the token's random number
- * generator. */
-CK_RV NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen)
-{
- SECStatus rv;
-
- rv = RNG_RandomUpdate(pSeed, ulSeedLen);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-/* NSC_GenerateRandom generates random data. */
-CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
-{
- SECStatus rv;
-
- rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-/*
- **************************** Key Functions: ************************
- */
-
-/*
- * generate a password based encryption key. This code uses
- * PKCS5 to do the work. Note that it calls PBE_PK11ParamToAlgid, which is
- * a utility function in secpkcs5.c. This function is used in here
- * and in PK11_ParamToAlgid.
- */
-CK_RV
-pk11_pbe_key_gen(SECOidTag algtag,CK_MECHANISM_PTR pMechanism,
- char *buf,int *key_length, PRBool faulty3DES)
-{
- SECAlgorithmID algid;
- SECItem *pbe_key = NULL, mech;
- CK_PBE_PARAMS *pbe_params = NULL;
- SECStatus pbe_rv;
-
- *key_length = 0;
-
- mech.data = (unsigned char *)pMechanism->pParameter;
- mech.len = (unsigned int)pMechanism->ulParameterLen;
-
- /* A common routine to map from Params to AlgIDs for PBE
- * algorithms was created in secpkcs5.c. This function is
- * called both by PK11_ParamToAlgid and this function.
- */
- pbe_rv = PBE_PK11ParamToAlgid(algtag, &mech, NULL, &algid);
- if (pbe_rv != SECSuccess) {
- return CKR_DATA_INVALID;
- }
- pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- mech.data = (unsigned char *)pbe_params->pPassword;
- mech.len = (unsigned int)pbe_params->ulPasswordLen;
- pbe_key = SEC_PKCS5GetKey(&algid, &mech, faulty3DES);
- if (pbe_key == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
- *key_length = pbe_key->len;
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- pbe_key = NULL;
-
- if (pbe_params->pInitVector == NULL) {
- pbe_key = SEC_PKCS5GetIV(&algid, &mech, faulty3DES);
- if (pbe_key == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- return CKR_HOST_MEMORY;
- }
- pbe_params->pInitVector = (CK_CHAR_PTR)PORT_ZAlloc(pbe_key->len);
- if (pbe_params->pInitVector == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(pbe_params->pInitVector, pbe_key->data, pbe_key->len);
- }
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- return CKR_OK;
-}
-
-/* NSC_GenerateKey generates a secret key, creating a new key object. */
-CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey)
-{
- PK11Object *key;
- PK11Session *session;
- PRBool checkWeak = PR_FALSE;
- int key_length = 0;
- CK_KEY_TYPE key_type;
- CK_OBJECT_CLASS objclass = CKO_SECRET_KEY;
- CK_RV crv = CKR_OK;
- CK_BBOOL cktrue = CK_TRUE;
- int i;
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- char buf[MAX_KEY_LEN];
- enum {pk11_pbe, pk11_ssl, pk11_bulk} key_gen_type;
- SECOidTag algtag = SEC_OID_UNKNOWN;
- SSL3RSAPreMasterSecret *rsa_pms;
- CK_VERSION *version;
- /* in very old versions of NSS, there were implementation errors with key
- * generation methods. We want to beable to read these, but not
- * produce them any more. The affected algorithm was 3DES.
- */
- PRBool faultyPBE3DES = PR_FALSE;
-
- /*
- * now lets create an object to hang the attributes off of
- */
- key = pk11_NewObject(slot); /* fill in the handle later */
- if (key == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulCount; i++) {
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- key_length = *(CK_ULONG *)pTemplate[i].pValue;
- continue;
- }
-
- crv = pk11_AddAttributeType(key,pk11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
- }
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
-
- /* make sure we don't have any class, key_type, or value fields */
- pk11_DeleteAttributeType(key,CKA_CLASS);
- pk11_DeleteAttributeType(key,CKA_KEY_TYPE);
- pk11_DeleteAttributeType(key,CKA_VALUE);
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- key_gen_type = pk11_bulk; /* bulk key by default */
- switch (pMechanism->mechanism) {
- case CKM_RC2_KEY_GEN:
- key_type = CKK_RC2;
- if (key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- case CKM_RC5_KEY_GEN:
- key_type = CKK_RC5;
- if (key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- case CKM_RC4_KEY_GEN:
- key_type = CKK_RC4;
- if (key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- case CKM_GENERIC_SECRET_KEY_GEN:
- key_type = CKK_GENERIC_SECRET;
- if (key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- case CKM_CDMF_KEY_GEN:
- key_type = CKK_CDMF;
- key_length = 8;
- checkWeak = PR_TRUE;
- break;
- case CKM_DES_KEY_GEN:
- key_type = CKK_DES;
- key_length = 8;
- checkWeak = PR_TRUE;
- break;
- case CKM_DES2_KEY_GEN:
- key_type = CKK_DES2;
- key_length = 16;
- checkWeak = PR_TRUE;
- break;
- case CKM_DES3_KEY_GEN:
- key_type = CKK_DES3;
- key_length = 24;
- checkWeak = PR_TRUE;
- break;
- case CKM_SSL3_PRE_MASTER_KEY_GEN:
- key_type = CKK_GENERIC_SECRET;
- key_length = 48;
- key_gen_type = pk11_ssl;
- break;
- case CKM_PBE_MD2_DES_CBC:
- algtag = SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC;
- key_type = CKK_DES;
- goto have_key_type;
- case CKM_PBE_MD5_DES_CBC:
- algtag = SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC;
- key_type = CKK_DES;
- goto have_key_type;
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- algtag = SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
- key_type = CKK_DES;
- goto have_key_type;
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- faultyPBE3DES = PR_TRUE;
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
- key_type = CKK_DES3;
- goto have_key_type;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- key_type = CKK_RC2;
- goto have_key_type;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- key_type = CKK_RC2;
- goto have_key_type;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4;
- key_type = CKK_RC4;
- goto have_key_type;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4;
- key_type = CKK_RC4;
- goto have_key_type;
- case CKM_PBE_SHA1_RC4_40:
- algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- key_length = 5;
- key_type = CKK_RC4;
- goto have_key_type;
- case CKM_PBE_SHA1_RC4_128:
- algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- key_length = 16;
- key_type = CKK_RC4;
- goto have_key_type;
- case CKM_PBE_SHA1_RC2_40_CBC:
- algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- key_length = 5;
- key_type = CKK_RC2;
- goto have_key_type;
- case CKM_PBE_SHA1_RC2_128_CBC:
- algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- key_length = 16;
- key_type = CKK_RC2;
- goto have_key_type;
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- key_length = 24;
- key_type = CKK_DES3;
- goto have_key_type;
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- key_length = 16;
- key_type = CKK_DES2;
- checkWeak = PR_FALSE;
-have_key_type:
- key_gen_type = pk11_pbe;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- }
- /* make sure we aren't going to overflow the buffer */
- if (sizeof(buf) < key_length) {
- /* someone is getting pretty optimistic about how big their key can
- * be... */
- crv = CKR_TEMPLATE_INCONSISTENT;
- }
-
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
-
- /*
- * now to the actual key gen.
- */
- switch (key_gen_type) {
- case pk11_pbe:
- crv = pk11_pbe_key_gen(algtag, pMechanism, buf, &key_length,
- faultyPBE3DES);
- break;
- case pk11_ssl:
- rsa_pms = (SSL3RSAPreMasterSecret *)buf;
- version = (CK_VERSION *)pMechanism->pParameter;
- rsa_pms->client_version[0] = version->major;
- rsa_pms->client_version[1] = version->minor;
- crv =
- NSC_GenerateRandom(0,&rsa_pms->random[0], sizeof(rsa_pms->random));
- break;
- case pk11_bulk:
- /* get the key, check for weak keys and repeat if found */
- do {
- crv = NSC_GenerateRandom(0, (unsigned char *)buf, key_length);
- } while (crv == CKR_OK && checkWeak &&
- pk11_IsWeakKey((unsigned char *)buf,key_type));
- break;
- }
-
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
-
- /* Add the class, key_type, and value */
- crv = pk11_AddAttributeType(key,CKA_CLASS,&objclass,sizeof(CK_OBJECT_CLASS));
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
- crv = pk11_AddAttributeType(key,CKA_KEY_TYPE,&key_type,sizeof(CK_KEY_TYPE));
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
- crv = pk11_AddAttributeType(key,CKA_CLASS,&objclass,sizeof(CK_OBJECT_CLASS));
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
- crv = pk11_AddAttributeType(key,CKA_VALUE,buf,key_length);
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
-
- /* get the session */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- pk11_FreeObject(key);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /*
- * handle the base object stuff
- */
- crv = pk11_handleObject(key,session);
- pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
- if (pk11_isTrue(key,CKA_SENSITIVE)) {
- pk11_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
- }
- if (!pk11_isTrue(key,CKA_EXTRACTABLE)) {
- pk11_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
- }
-
- *phKey = key->handle;
- return CKR_OK;
-}
-
-
-
-/* NSC_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey,
- CK_OBJECT_HANDLE_PTR phPublicKey)
-{
- PK11Object * publicKey,*privateKey;
- PK11Session * session;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- CK_BBOOL cktrue = CK_TRUE;
- SECStatus rv;
- CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
- CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
- int i;
- PK11Slot * slot = pk11_SlotFromSessionHandle(hSession);
-
- /* RSA */
- int public_modulus_bits = 0;
- SECItem pubExp;
- RSAPrivateKey * rsaPriv;
-
- /* DSA */
- PQGParams pqgParam;
- DHParams dhParam;
- DSAPrivateKey * dsaPriv;
-
- /* Diffie Hellman */
- int private_value_bits = 0;
- DHPrivateKey * dhPriv;
-
- /*
- * now lets create an object to hang the attributes off of
- */
- publicKey = pk11_NewObject(slot); /* fill in the handle later */
- if (publicKey == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the publicKey
- */
- for (i=0; i < (int) ulPublicKeyAttributeCount; i++) {
- if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS) {
- public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue;
- continue;
- }
-
- crv = pk11_AddAttributeType(publicKey,
- pk11_attr_expand(&pPublicKeyTemplate[i]));
- if (crv != CKR_OK) break;
- }
-
- if (crv != CKR_OK) {
- pk11_FreeObject(publicKey);
- return CKR_HOST_MEMORY;
- }
-
- privateKey = pk11_NewObject(slot); /* fill in the handle later */
- if (privateKey == NULL) {
- pk11_FreeObject(publicKey);
- return CKR_HOST_MEMORY;
- }
- /*
- * now load the private key template
- */
- for (i=0; i < (int) ulPrivateKeyAttributeCount; i++) {
- if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) {
- private_value_bits = *(CK_ULONG *)pPrivateKeyTemplate[i].pValue;
- continue;
- }
-
- crv = pk11_AddAttributeType(privateKey,
- pk11_attr_expand(&pPrivateKeyTemplate[i]));
- if (crv != CKR_OK) break;
- }
-
- if (crv != CKR_OK) {
- pk11_FreeObject(publicKey);
- pk11_FreeObject(privateKey);
- return CKR_HOST_MEMORY;
- }
- pk11_DeleteAttributeType(privateKey,CKA_CLASS);
- pk11_DeleteAttributeType(privateKey,CKA_KEY_TYPE);
- pk11_DeleteAttributeType(privateKey,CKA_VALUE);
- pk11_DeleteAttributeType(publicKey,CKA_CLASS);
- pk11_DeleteAttributeType(publicKey,CKA_KEY_TYPE);
- pk11_DeleteAttributeType(publicKey,CKA_VALUE);
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- switch (pMechanism->mechanism) {
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- /* format the keys */
- pk11_DeleteAttributeType(publicKey,CKA_MODULUS);
- pk11_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
- pk11_DeleteAttributeType(privateKey,CKA_MODULUS);
- pk11_DeleteAttributeType(privateKey,CKA_PRIVATE_EXPONENT);
- pk11_DeleteAttributeType(privateKey,CKA_PUBLIC_EXPONENT);
- pk11_DeleteAttributeType(privateKey,CKA_PRIME_1);
- pk11_DeleteAttributeType(privateKey,CKA_PRIME_2);
- pk11_DeleteAttributeType(privateKey,CKA_EXPONENT_1);
- pk11_DeleteAttributeType(privateKey,CKA_EXPONENT_2);
- pk11_DeleteAttributeType(privateKey,CKA_COEFFICIENT);
- key_type = CKK_RSA;
- if (public_modulus_bits == 0) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
-
- /* extract the exponent */
- crv=pk11_Attribute2SSecItem(NULL,&pubExp,publicKey,CKA_PUBLIC_EXPONENT);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&pubExp));
- if (crv != CKR_OK) {
- PORT_Free(pubExp.data);
- break;
- }
-
- rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
- PORT_Free(pubExp.data);
- if (rsaPriv == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- /* now fill in the RSA dependent paramenters in the public key */
- crv = pk11_AddAttributeType(publicKey,CKA_MODULUS,
- pk11_item_expand(&rsaPriv->modulus));
- if (crv != CKR_OK) goto kpg_done;
- /* now fill in the RSA dependent paramenters in the private key */
- crv = pk11_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
- pk11_item_expand(&rsaPriv->modulus));
- if (crv != CKR_OK) goto kpg_done;
- crv = pk11_AddAttributeType(privateKey,CKA_MODULUS,
- pk11_item_expand(&rsaPriv->modulus));
- if (crv != CKR_OK) goto kpg_done;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT,
- pk11_item_expand(&rsaPriv->privateExponent));
- if (crv != CKR_OK) goto kpg_done;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_1,
- pk11_item_expand(&rsaPriv->prime1));
- if (crv != CKR_OK) goto kpg_done;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_2,
- pk11_item_expand(&rsaPriv->prime2));
- if (crv != CKR_OK) goto kpg_done;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_1,
- pk11_item_expand(&rsaPriv->exponent1));
- if (crv != CKR_OK) goto kpg_done;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_2,
- pk11_item_expand(&rsaPriv->exponent2));
- if (crv != CKR_OK) goto kpg_done;
- crv = pk11_AddAttributeType(privateKey,CKA_COEFFICIENT,
- pk11_item_expand(&rsaPriv->coefficient));
-kpg_done:
- /* Should zeroize the contents first, since this func doesn't. */
- PORT_FreeArena(rsaPriv->arena, PR_TRUE);
- break;
- case CKM_DSA_KEY_PAIR_GEN:
- pk11_DeleteAttributeType(publicKey,CKA_VALUE);
- pk11_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
- pk11_DeleteAttributeType(privateKey,CKA_PRIME);
- pk11_DeleteAttributeType(privateKey,CKA_SUBPRIME);
- pk11_DeleteAttributeType(privateKey,CKA_BASE);
- key_type = CKK_DSA;
-
- /* extract the necessary paramters and copy them to the private key */
- crv=pk11_Attribute2SSecItem(NULL,&pqgParam.prime,publicKey,CKA_PRIME);
- if (crv != CKR_OK) break;
- crv=pk11_Attribute2SSecItem(NULL,&pqgParam.subPrime,publicKey,
- CKA_SUBPRIME);
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- break;
- }
- crv=pk11_Attribute2SSecItem(NULL,&pqgParam.base,publicKey,CKA_BASE);
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- break;
- }
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME,
- pk11_item_expand(&pqgParam.prime));
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
- crv = pk11_AddAttributeType(privateKey,CKA_SUBPRIME,
- pk11_item_expand(&pqgParam.subPrime));
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
- crv = pk11_AddAttributeType(privateKey,CKA_BASE,
- pk11_item_expand(&pqgParam.base));
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
-
- /* Generate the key */
- rv = DSA_NewKey(&pqgParam, &dsaPriv);
-
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
-
- if (rv != SECSuccess) { crv = CKR_HOST_MEMORY; break; }
-
- /* store the generated key into the attributes */
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&dsaPriv->publicValue));
- if (crv != CKR_OK) goto dsagn_done;
-
- /* now fill in the RSA dependent paramenters in the private key */
- crv = pk11_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
- pk11_item_expand(&dsaPriv->publicValue));
- if (crv != CKR_OK) goto dsagn_done;
- crv = pk11_AddAttributeType(privateKey,CKA_VALUE,
- pk11_item_expand(&dsaPriv->privateValue));
-
-dsagn_done:
- /* should zeroize, since this function doesn't. */
- PORT_FreeArena(dsaPriv->params.arena, PR_TRUE);
- break;
-
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- pk11_DeleteAttributeType(privateKey,CKA_PRIME);
- pk11_DeleteAttributeType(privateKey,CKA_BASE);
- pk11_DeleteAttributeType(privateKey,CKA_VALUE);
- key_type = CKK_DH;
-
- /* extract the necessary parameters and copy them to private keys */
- crv = pk11_Attribute2SSecItem(NULL, &dhParam.prime, publicKey,
- CKA_PRIME);
- if (crv != CKR_OK) break;
- crv = pk11_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE);
- if (crv != CKR_OK) {
- PORT_Free(dhParam.prime.data);
- break;
- }
- crv = pk11_AddAttributeType(privateKey, CKA_PRIME,
- pk11_item_expand(&dhParam.prime));
- if (crv != CKR_OK) {
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- break;
- }
- crv = pk11_AddAttributeType(privateKey, CKA_BASE,
- pk11_item_expand(&dhParam.base));
- if (crv != CKR_OK) goto dhgn_done;
-
- rv = DH_NewKey(&dhParam, &dhPriv);
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- if (rv != SECSuccess) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- crv=pk11_AddAttributeType(publicKey, CKA_VALUE,
- pk11_item_expand(&dhPriv->publicValue));
- if (crv != CKR_OK) goto dhgn_done;
-
- crv=pk11_AddAttributeType(privateKey, CKA_VALUE,
- pk11_item_expand(&dhPriv->privateValue));
-
-dhgn_done:
- /* should zeroize, since this function doesn't. */
- PORT_FreeArena(dhPriv->arena, PR_TRUE);
- break;
-
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (crv != CKR_OK) {
- pk11_FreeObject(privateKey);
- pk11_FreeObject(publicKey);
- return crv;
- }
-
-
- /* Add the class, key_type The loop lets us check errors blow out
- * on errors and clean up at the bottom */
- session = NULL; /* make pedtantic happy... session cannot leave the*/
- /* loop below NULL unless an error is set... */
- do {
- crv = pk11_AddAttributeType(privateKey,CKA_CLASS,&privClass,
- sizeof(CK_OBJECT_CLASS));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_CLASS,&pubClass,
- sizeof(CK_OBJECT_CLASS));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE));
- if (crv != CKR_OK) break;
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) crv = CKR_SESSION_HANDLE_INVALID;
- } while (0);
-
- if (crv != CKR_OK) {
- pk11_FreeObject(privateKey);
- pk11_FreeObject(publicKey);
- return crv;
- }
-
- /*
- * handle the base object cleanup for the public Key
- */
- crv = pk11_handleObject(publicKey,session);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- pk11_FreeObject(privateKey);
- pk11_FreeObject(publicKey);
- return crv;
- }
-
- /*
- * handle the base object cleanup for the private Key
- * If we have any problems, we destroy the public Key we've
- * created and linked.
- */
- crv = pk11_handleObject(privateKey,session);
- pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(privateKey);
- NSC_DestroyObject(hSession,publicKey->handle);
- return crv;
- }
- if (pk11_isTrue(privateKey,CKA_SENSITIVE)) {
- pk11_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
- &cktrue,sizeof(CK_BBOOL));
- }
- if (pk11_isTrue(publicKey,CKA_SENSITIVE)) {
- pk11_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
- &cktrue,sizeof(CK_BBOOL));
- }
- if (!pk11_isTrue(privateKey,CKA_EXTRACTABLE)) {
- pk11_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
- &cktrue,sizeof(CK_BBOOL));
- }
- if (!pk11_isTrue(publicKey,CKA_EXTRACTABLE)) {
- pk11_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
- &cktrue,sizeof(CK_BBOOL));
- }
- *phPrivateKey = privateKey->handle;
- *phPublicKey = publicKey->handle;
-
- return CKR_OK;
-}
-
-static SECItem *pk11_PackagePrivateKey(PK11Object *key)
-{
- SECKEYLowPrivateKey *lk = NULL;
- SECKEYPrivateKeyInfo *pki = NULL;
- PK11Attribute *attribute = NULL;
- PLArenaPool *arena = NULL;
- SECOidTag algorithm = SEC_OID_UNKNOWN;
- void *dummy, *param = NULL;
- SECStatus rv = SECSuccess;
- SECItem *encodedKey = NULL;
-
- if(!key) {
- return NULL;
- }
-
- attribute = pk11_FindAttribute(key, CKA_KEY_TYPE);
- if(!attribute) {
- return NULL;
- }
-
- lk = pk11_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue);
- pk11_FreeAttribute(attribute);
- if(!lk) {
- return NULL;
- }
-
- arena = PORT_NewArena(2048); /* XXX different size? */
- if(!arena) {
- rv = SECFailure;
- goto loser;
- }
-
- pki = (SECKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYPrivateKeyInfo));
- if(!pki) {
- rv = SECFailure;
- goto loser;
- }
- pki->arena = arena;
-
- param = NULL;
- switch(lk->keyType) {
- case rsaKey:
- dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- SECKEY_RSAPrivateKeyTemplate);
- algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
- break;
- case dsaKey:
- dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- SECKEY_DSAPrivateKeyExportTemplate);
- param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
- SECKEY_PQGParamsTemplate);
- algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
- break;
- case fortezzaKey:
- case dhKey:
- default:
- dummy = NULL;
- break;
- }
-
- if(!dummy || ((lk->keyType == dsaKey) && !param)) {
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm,
- (SECItem*)param);
- if(rv != SECSuccess) {
- rv = SECFailure;
- goto loser;
- }
-
- dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
- SEC_PRIVATE_KEY_INFO_VERSION);
- if(!dummy) {
- rv = SECFailure;
- goto loser;
- }
-
- encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
- SECKEY_PrivateKeyInfoTemplate);
-
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- if(lk && (lk != key->objectInfo)) {
- SECKEY_LowDestroyPrivateKey(lk);
- }
-
- if(param) {
- SECITEM_ZfreeItem((SECItem*)param, PR_TRUE);
- }
-
- if(rv != SECSuccess) {
- return NULL;
- }
-
- return encodedKey;
-}
-
-/* it doesn't matter yet, since we colapse error conditions in the
- * level above, but we really should map those few key error differences */
-CK_RV pk11_mapWrap(CK_RV crv) { return crv; }
-
-/* NSC_WrapKey wraps (i.e., encrypts) a key. */
-CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen)
-{
- PK11Session *session;
- PK11Attribute *attribute;
- PK11Object *key;
- CK_RV crv;
- PRBool isLynks = PR_FALSE;
- CK_ULONG len = 0;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- key = pk11_ObjectFromHandle(hKey,session);
- pk11_FreeSession(session);
- if (key == NULL) {
- return CKR_KEY_HANDLE_INVALID;
- }
-
- switch(key->objclass) {
- case CKO_SECRET_KEY:
- attribute = pk11_FindAttribute(key,CKA_VALUE);
-
- if (attribute == NULL) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- if (pMechanism->mechanism == CKM_KEY_WRAP_LYNKS) {
- isLynks = PR_TRUE;
- pMechanism->mechanism = CKM_DES_ECB;
- len = *pulWrappedKeyLen;
- }
-
- crv = pk11_EncryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, PK11_ENCRYPT);
- if (crv != CKR_OK) {
- pk11_FreeAttribute(attribute);
- break;
- }
- crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)attribute->attrib.pValue,
- attribute->attrib.ulValueLen,pWrappedKey,pulWrappedKeyLen);
-
- if (isLynks && (crv == CKR_OK)) {
- unsigned char buf[2];
- crv = pk11_calcLynxChecksum(hSession,hWrappingKey,buf,
- (unsigned char*)attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- if (len >= 10) {
- pWrappedKey[8] = buf[0];
- pWrappedKey[9] = buf[1];
- *pulWrappedKeyLen = 10;
- }
- }
- pk11_FreeAttribute(attribute);
- break;
-
- case CKO_PRIVATE_KEY:
- {
- SECItem *bpki = pk11_PackagePrivateKey(key);
-
- if(!bpki) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
-
- crv = pk11_EncryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, PK11_ENCRYPT);
- if(crv != CKR_OK) {
- SECITEM_ZfreeItem(bpki, PR_TRUE);
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
-
- crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
- pWrappedKey, pulWrappedKeyLen);
- SECITEM_ZfreeItem(bpki, PR_TRUE);
- break;
- }
-
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- pk11_FreeObject(key);
-
- return pk11_mapWrap(crv);
-}
-
-/*
- * import a pprivate key info into the desired slot
- */
-static SECStatus
-pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_KEY_TYPE keyType = CKK_RSA;
- SECStatus rv = SECFailure;
- const SEC_ASN1Template *keyTemplate, *paramTemplate;
- void *paramDest = NULL;
- PLArenaPool *arena;
- SECKEYLowPrivateKey *lpk = NULL;
- SECKEYPrivateKeyInfo *pki = NULL;
- SECItem *ck_id = NULL;
- CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
-
- arena = PORT_NewArena(2048);
- if(!arena) {
- return SECFailure;
- }
-
- pki = (SECKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYPrivateKeyInfo));
- if(!pki) {
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
-
- if(SEC_ASN1DecodeItem(arena, pki, SECKEY_PrivateKeyInfoTemplate, bpki)
- != SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
- return SECFailure;
- }
-
- lpk = (SECKEYLowPrivateKey *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYLowPrivateKey));
- if(lpk == NULL) {
- goto loser;
- }
- lpk->arena = arena;
-
- switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- keyTemplate = SECKEY_RSAPrivateKeyTemplate;
- paramTemplate = NULL;
- paramDest = NULL;
- lpk->keyType = rsaKey;
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
- paramTemplate = SECKEY_PQGParamsTemplate;
- paramDest = &(lpk->u.dsa.params);
- lpk->keyType = dsaKey;
- break;
- /* case dhKey: */
- /* case fortezzaKey: */
- default:
- keyTemplate = NULL;
- paramTemplate = NULL;
- paramDest = NULL;
- break;
- }
-
- if(!keyTemplate) {
- goto loser;
- }
-
- /* decode the private key and any algorithm parameters */
- rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
- if(rv != SECSuccess) {
- goto loser;
- }
- if(paramDest && paramTemplate) {
- rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
- &(pki->algorithm.parameters));
- if(rv != SECSuccess) {
- goto loser;
- }
- }
-
- rv = SECFailure;
-
- switch (lpk->keyType) {
- case rsaKey:
- keyType = CKK_RSA;
- if(pk11_hasAttribute(key, CKA_NETSCAPE_DB)) {
- pk11_DeleteAttributeType(key, CKA_NETSCAPE_DB);
- }
- crv = pk11_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
- sizeof(keyType));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_UNWRAP, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_DECRYPT, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_SIGN, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_MODULUS,
- pk11_item_expand(&lpk->u.rsa.modulus));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&lpk->u.rsa.publicExponent));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_PRIVATE_EXPONENT,
- pk11_item_expand(&lpk->u.rsa.privateExponent));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_PRIME_1,
- pk11_item_expand(&lpk->u.rsa.prime1));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_PRIME_2,
- pk11_item_expand(&lpk->u.rsa.prime2));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_EXPONENT_1,
- pk11_item_expand(&lpk->u.rsa.exponent1));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_EXPONENT_2,
- pk11_item_expand(&lpk->u.rsa.exponent2));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_COEFFICIENT,
- pk11_item_expand(&lpk->u.rsa.coefficient));
- break;
- case dsaKey:
- keyType = CKK_DSA;
- crv = (pk11_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK :
- CKR_KEY_TYPE_INCONSISTENT;
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
- sizeof(keyType));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_SIGN, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_PRIME,
- pk11_item_expand(&lpk->u.dsa.params.prime));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_SUBPRIME,
- pk11_item_expand(&lpk->u.dsa.params.subPrime));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_BASE,
- pk11_item_expand(&lpk->u.dsa.params.base));
- if(crv != CKR_OK) break;
- crv = pk11_AddAttributeType(key, CKA_VALUE,
- pk11_item_expand(&lpk->u.dsa.privateValue));
- if(crv != CKR_OK) break;
- break;
-#ifdef notdef
- case dhKey:
- template = dhTemplate;
- templateCount = sizeof(dhTemplate)/sizeof(CK_ATTRIBUTE);
- keyType = CKK_DH;
- break;
-#endif
- /* what about fortezza??? */
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
-
-loser:
- if(ck_id) {
- SECITEM_ZfreeItem(ck_id, PR_TRUE);
- }
-
- if(lpk) {
- SECKEY_LowDestroyPrivateKey(lpk);
- }
-
- if(crv != CKR_OK) {
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-
-/* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
-CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey)
-{
- PK11Object *key = NULL;
- PK11Session *session;
- int key_length = 0;
- unsigned char * buf = NULL;
- CK_RV crv = CKR_OK;
- int i;
- CK_ULONG bsize = ulWrappedKeyLen;
- PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- PK11Attribute *attr = NULL;
- SECItem bpki;
- CK_OBJECT_CLASS target_type = CKO_SECRET_KEY;
- PRBool isLynks = PR_FALSE;
-
- /*
- * now lets create an object to hang the attributes off of
- */
- key = pk11_NewObject(slot); /* fill in the handle later */
- if (key == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulAttributeCount; i++) {
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- key_length = *(CK_ULONG *)pTemplate[i].pValue;
- continue;
- }
- if (pTemplate[i].type == CKA_CLASS) {
- target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
- }
- crv = pk11_AddAttributeType(key,pk11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
- }
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
-
- /* LYNKS is a special key wrapping mechanism */
- if (pMechanism->mechanism == CKM_KEY_WRAP_LYNKS) {
- isLynks = PR_TRUE;
- pMechanism->mechanism = CKM_DES_ECB;
- ulWrappedKeyLen -= 2; /* don't decrypt the checksum */
- }
-
- crv = pk11_DecryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
- PK11_DECRYPT);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return pk11_mapWrap(crv);
- }
-
- /* allocate the buffer to decrypt into
- * this assumes the unwrapped key is never larger than the
- * wrapped key. For all the mechanisms we support this is true */
- buf = (unsigned char *)PORT_Alloc( ulWrappedKeyLen);
- bsize = ulWrappedKeyLen;
-
- crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- PORT_Free(buf);
- return pk11_mapWrap(crv);
- }
-
- switch(target_type) {
- case CKO_SECRET_KEY:
- if (!pk11_hasAttribute(key,CKA_KEY_TYPE)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
-
- /* verify the Lynx checksum */
- if (isLynks) {
- unsigned char checkSum[2];
- crv = pk11_calcLynxChecksum(hSession,hUnwrappingKey,checkSum,
- buf,bsize);
- if (crv != CKR_OK) break;
- if ((ulWrappedKeyLen != 8) || (pWrappedKey[8] != checkSum[0])
- || (pWrappedKey[9] != checkSum[1])) {
- crv = CKR_WRAPPED_KEY_INVALID;
- break;
- }
- }
-
- if(key_length == 0) {
- key_length = bsize;
- }
- if (key_length > MAX_KEY_LEN) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
-
- /* add the value */
- crv = pk11_AddAttributeType(key,CKA_VALUE,buf,key_length);
- break;
- case CKO_PRIVATE_KEY:
- bpki.data = (unsigned char *)buf;
- bpki.len = bsize;
- crv = CKR_OK;
- if(pk11_unwrapPrivateKey(key, &bpki) != SECSuccess) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- }
- break;
- default:
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
-
- PORT_ZFree(buf, bsize);
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
-
- /* get the session */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- pk11_FreeObject(key);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /*
- * handle the base object stuff
- */
- crv = pk11_handleObject(key,session);
- pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
-
- *phKey = key->handle;
- return CKR_OK;
-
-}
-
-/*
- * The SSL key gen mechanism create's lots of keys. This function handles the
- * details of each of these key creation.
- */
-static CK_RV
-pk11_buildSSLKey(CK_SESSION_HANDLE hSession, PK11Object *baseKey,
- PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize,
- CK_OBJECT_HANDLE *keyHandle)
-{
- PK11Object *key;
- PK11Session *session;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_RV crv = CKR_HOST_MEMORY;
-
- /*
- * now lets create an object to hang the attributes off of
- */
- *keyHandle = CK_INVALID_KEY;
- key = pk11_NewObject(baseKey->slot);
- if (key == NULL) return CKR_HOST_MEMORY;
- key->wasDerived = PR_TRUE;
-
- crv = pk11_CopyObject(key,baseKey);
- if (crv != CKR_OK) goto loser;
- if (isMacKey) {
- crv = pk11_forceAttribute(key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
- if (crv != CKR_OK) goto loser;
- crv = pk11_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = pk11_forceAttribute(key,CKA_ENCRYPT,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = pk11_forceAttribute(key,CKA_DECRYPT,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = pk11_forceAttribute(key,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = pk11_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = pk11_forceAttribute(key,CKA_WRAP,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = pk11_forceAttribute(key,CKA_UNWRAP,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- }
- crv = pk11_forceAttribute(key,CKA_VALUE,keyBlock,keySize);
- if (crv != CKR_OK) goto loser;
-
- /* get the session */
- crv = CKR_HOST_MEMORY;
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) { goto loser; }
-
- crv = pk11_handleObject(key,session);
- pk11_FreeSession(session);
- if (crv == CKR_OK) {
- *keyHandle = key->handle;
- return crv;
- }
-loser:
- if (key) pk11_FreeObject(key);
- return crv;
-}
-
-/*
- * if there is an error, we need to free the keys we already created in SSL
- * This is the routine that will do it..
- */
-static void
-pk11_freeSSLKeys(CK_SESSION_HANDLE session,
- CK_SSL3_KEY_MAT_OUT *returnedMaterial ) {
- if (returnedMaterial->hClientMacSecret != CK_INVALID_KEY) {
- NSC_DestroyObject(session,returnedMaterial->hClientMacSecret);
- }
- if (returnedMaterial->hServerMacSecret != CK_INVALID_KEY) {
- NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
- }
- if (returnedMaterial->hClientKey != CK_INVALID_KEY) {
- NSC_DestroyObject(session, returnedMaterial->hClientKey);
- }
- if (returnedMaterial->hServerKey != CK_INVALID_KEY) {
- NSC_DestroyObject(session, returnedMaterial->hServerKey);
- }
-}
-
-/*
- * when deriving from sensitive and extractable keys, we need to preserve some
- * of the semantics in the derived key. This helper routine maintains these
- * semantics.
- */
-static CK_RV
-pk11_DeriveSensitiveCheck(PK11Object *baseKey,PK11Object *destKey) {
- PRBool hasSensitive;
- PRBool sensitive;
- PRBool hasExtractable;
- PRBool extractable;
- CK_RV crv = PR_TRUE;
- PK11Attribute *att;
-
- hasSensitive = PR_FALSE;
- att = pk11_FindAttribute(destKey,CKA_SENSITIVE);
- if (att) {
- hasSensitive = PR_FALSE;
- sensitive = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
- pk11_FreeAttribute(att);
- }
-
- hasExtractable = PR_FALSE;
- att = pk11_FindAttribute(destKey,CKA_EXTRACTABLE);
- if (att) {
- hasExtractable = PR_FALSE;
- extractable = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
- pk11_FreeAttribute(att);
- }
-
-
- /* don't make a key more accessible */
- if (pk11_isTrue(baseKey,CKA_SENSITIVE) && hasSensitive &&
- (sensitive == PR_FALSE)) {
- return CKR_KEY_FUNCTION_NOT_PERMITTED;
- }
- if (!pk11_isTrue(baseKey,CKA_EXTRACTABLE) && hasExtractable &&
- (extractable == PR_TRUE)) {
- return CKR_KEY_FUNCTION_NOT_PERMITTED;
- }
-
- /* inherit parent's sensitivity */
- if (!hasSensitive) {
- att = pk11_FindAttribute(baseKey,CKA_SENSITIVE);
- if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
- crv = pk11_defaultAttribute(destKey,pk11_attr_expand(&att->attrib));
- pk11_FreeAttribute(att);
- if (crv != CKR_OK) return crv;
- }
- if (!hasExtractable) {
- att = pk11_FindAttribute(baseKey,CKA_EXTRACTABLE);
- if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
- crv = pk11_defaultAttribute(destKey,pk11_attr_expand(&att->attrib));
- pk11_FreeAttribute(att);
- if (crv != CKR_OK) return crv;
- }
-
- /* we should inherit the parent's always extractable/ never sensitive info,
- * but handleObject always forces this attributes, so we would need to do
- * something special. */
- return CKR_OK;
-}
-
-/*
- * make known fixed PKCS #11 key types to their sizes in bytes
- */
-static unsigned long
-pk11_MapKeySize(CK_KEY_TYPE keyType) {
- switch (keyType) {
- case CKK_CDMF:
- return 8;
- case CKK_DES:
- return 8;
- case CKK_DES2:
- return 16;
- case CKK_DES3:
- return 24;
- /* IDEA and CAST need to be added */
- default:
- break;
- }
- return 0;
-}
-
-#define PHASH_STATE_MAX_LEN 20
-
-/* TLS P_hash function */
-static SECStatus
-pk11_P_hash(SECOidTag alg, const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result)
-{
- unsigned char state[PHASH_STATE_MAX_LEN];
- unsigned char outbuf[PHASH_STATE_MAX_LEN];
- unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
- unsigned int remaining;
- unsigned char *res;
- SECStatus status;
- HMACContext *cx;
- SECStatus rv = SECFailure;
-
- PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
- PORT_Assert((seed != NULL) && (seed->data != NULL));
- PORT_Assert((result != NULL) && (result->data != NULL));
-
- remaining = result->len;
- res = result->data;
-
- if (label != NULL)
- label_len = PORT_Strlen(label);
-
- cx = HMAC_Create(alg, secret->data, secret->len);
- if (cx == NULL)
- goto loser;
-
- /* initialize the state = A(1) = HMAC_hash(secret, seed) */
- HMAC_Begin(cx);
- HMAC_Update(cx, (unsigned char *)label, label_len);
- HMAC_Update(cx, seed->data, seed->len);
- status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
- if (status != SECSuccess)
- goto loser;
-
- /* generate a block at a time until we're done */
- while (remaining > 0) {
-
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- if (label_len)
- HMAC_Update(cx, (unsigned char *)label, label_len);
- HMAC_Update(cx, seed->data, seed->len);
- status = HMAC_Finish(cx, outbuf, &outbuf_len, PHASH_STATE_MAX_LEN);
- if (status != SECSuccess)
- goto loser;
-
- /* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
- if (status != SECSuccess)
- goto loser;
-
- chunk_size = PR_MIN(outbuf_len, remaining);
- PORT_Memcpy(res, &outbuf, chunk_size);
- res += chunk_size;
- remaining -= chunk_size;
- }
-
- rv = SECSuccess;
-
-loser:
- /* if (cx) HMAC_Destroy(cx); */
- /* clear out state so it's not left on the stack */
- if (cx) HMAC_Destroy(cx);
- PORT_Memset(state, 0, sizeof(state));
- PORT_Memset(outbuf, 0, sizeof(outbuf));
- return rv;
-}
-
-static SECStatus
-pk11_PRF(const SECItem *secret, const char *label, SECItem *seed,
- SECItem *result)
-{
- SECStatus rv = SECFailure, status;
- unsigned int i;
- SECItem tmp = { siBuffer, NULL, 0};
- SECItem S1;
- SECItem S2;
-
- PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
- PORT_Assert((seed != NULL) && (seed->data != NULL));
- PORT_Assert((result != NULL) && (result->data != NULL));
-
- S1.type = siBuffer;
- S1.len = (secret->len / 2) + (secret->len & 1);
- S1.data = secret->data;
-
- S2.type = siBuffer;
- S2.len = S1.len;
- S2.data = secret->data + (secret->len - S2.len);
-
- tmp.data = (unsigned char*)PORT_Alloc(result->len);
- if (tmp.data == NULL)
- goto loser;
- tmp.len = result->len;
-
- status = pk11_P_hash(SEC_OID_MD5, &S1, label, seed, result);
- if (status != SECSuccess)
- goto loser;
-
- status = pk11_P_hash(SEC_OID_SHA1, &S2, label, seed, &tmp);
- if (status != SECSuccess)
- goto loser;
-
- for (i = 0; i < result->len; i++)
- result->data[i] ^= tmp.data[i];
-
- rv = SECSuccess;
-
-loser:
- if (tmp.data != NULL)
- PORT_ZFree(tmp.data, tmp.len);
- return rv;
-}
-
-/*
- * SSL Key generation given pre master secret
- */
-static char *mixers[] = { "A", "BB", "CCC", "DDDD", "EEEEE", "FFFFFF", "GGGGGGG"};
-#define NUM_MIXERS 7
-#define SSL3_PMS_LENGTH 48
-#define SSL3_MASTER_SECRET_LENGTH 48
-
-
-/* NSC_DeriveKey derives a key from a base key, creating a new key object. */
-CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey)
-{
- PK11Session * session;
- PK11Slot * slot = pk11_SlotFromSessionHandle(hSession);
- PK11Object * key;
- PK11Object * sourceKey;
- PK11Attribute * att;
- PK11Attribute * att2;
- unsigned char * buf;
- SHA1Context * sha;
- MD5Context * md5;
- MD2Context * md2;
- CK_ULONG macSize;
- CK_ULONG tmpKeySize;
- CK_ULONG IVSize;
- CK_ULONG keySize = 0;
- CK_RV crv = CKR_OK;
- CK_BBOOL cktrue = CK_TRUE;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
- CK_KEY_DERIVATION_STRING_DATA *stringPtr;
- PRBool isTLS = PR_FALSE;
- SECStatus rv;
- int i;
- unsigned int outLen;
- unsigned char sha_out[SHA1_LENGTH];
- unsigned char key_block[NUM_MIXERS * MD5_LENGTH];
- unsigned char key_block2[MD5_LENGTH];
-
- /*
- * now lets create an object to hang the attributes off of
- */
- if (phKey) *phKey = CK_INVALID_KEY;
-
- key = pk11_NewObject(slot); /* fill in the handle later */
- if (key == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulAttributeCount; i++) {
- crv = pk11_AddAttributeType(key,pk11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
-
- if (pTemplate[i].type == CKA_KEY_TYPE) {
- keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue;
- }
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- keySize = *(CK_ULONG *)pTemplate[i].pValue;
- }
- }
- if (crv != CKR_OK) { pk11_FreeObject(key); return crv; }
-
- if (keySize == 0) {
- keySize = pk11_MapKeySize(keyType);
- }
-
- /* Derive can only create SECRET KEY's currently... */
- classType = CKO_SECRET_KEY;
- crv = pk11_forceAttribute (key,CKA_CLASS,&classType,sizeof(classType));
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
-
- /* look up the base key we're deriving with */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- pk11_FreeObject(key);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- sourceKey = pk11_ObjectFromHandle(hBaseKey,session);
- pk11_FreeSession(session);
- if (sourceKey == NULL) {
- pk11_FreeObject(key);
- return CKR_KEY_HANDLE_INVALID;
- }
-
- /* don't use key derive to expose sensitive keys */
- crv = pk11_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- pk11_FreeObject(sourceKey);
- return crv;
- }
-
- /* get the value of the base key */
- att = pk11_FindAttribute(sourceKey,CKA_VALUE);
- if (att == NULL) {
- pk11_FreeObject(key);
- pk11_FreeObject(sourceKey);
- return CKR_KEY_HANDLE_INVALID;
- }
-
- switch (pMechanism->mechanism) {
- /*
- * generate the master secret
- */
- case CKM_TLS_MASTER_KEY_DERIVE:
- isTLS = PR_TRUE;
- /* fall thru */
- case CKM_SSL3_MASTER_KEY_DERIVE:
- {
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
- SSL3RSAPreMasterSecret *rsa_pms;
-
- /* first do the consistancy checkes */
- if (att->attrib.ulValueLen != SSL3_PMS_LENGTH) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att2 = pk11_FindAttribute(sourceKey,CKA_KEY_TYPE);
- if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
- CKK_GENERIC_SECRET)) {
- if (att2) pk11_FreeAttribute(att2);
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- pk11_FreeAttribute(att2);
- if (keyType != CKK_GENERIC_SECRET) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
-
-
- /* finally do the key gen */
- ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
- pMechanism->pParameter;
- if (ssl3_master->pVersion) {
- rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
- /* don't leak more key material then necessary for SSL to work */
- if (key->wasDerived) {
- ssl3_master->pVersion->major = 0xff;
- ssl3_master->pVersion->minor = 0xff;
- } else {
- ssl3_master->pVersion->major = rsa_pms->client_version[0];
- ssl3_master->pVersion->minor = rsa_pms->client_version[1];
- }
- }
- if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
-
- if (isTLS) {
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
- SECItem crsr = { siBuffer, NULL, 0 };
- SECItem master = { siBuffer, NULL, 0 };
- SECItem pms = { siBuffer, NULL, 0 };
- SECStatus status;
-
- pms.data = (unsigned char*)att->attrib.pValue;
- pms.len = att->attrib.ulValueLen;
- master.data = key_block;
- master.len = SSL3_MASTER_SECRET_LENGTH;
- crsr.data = crsrdata;
- crsr.len = sizeof(crsrdata);
-
- PORT_Memcpy(crsrdata, ssl3_master->RandomInfo.pClientRandom,
- SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
- ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
-
- status = pk11_PRF(&pms, "master secret", &crsr, &master);
- if (status != SECSuccess) {
- crv = CKR_FUNCTION_FAILED;
- break;
- }
- } else {
- /* now allocate the hash contexts */
- md5 = MD5_NewContext();
- if (md5 == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- sha = SHA1_NewContext();
- if (sha == NULL) {
- PORT_Free(md5);
- crv = CKR_HOST_MEMORY;
- break;
- }
- for (i = 0; i < 3; i++) {
- SHA1_Begin(sha);
- SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
- SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- SHA1_Update(sha, ssl3_master->RandomInfo.pClientRandom,
- ssl3_master->RandomInfo.ulClientRandomLen);
- SHA1_Update(sha, ssl3_master->RandomInfo.pServerRandom,
- ssl3_master->RandomInfo.ulServerRandomLen);
- SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
- PORT_Assert(outLen == SHA1_LENGTH);
- MD5_Begin(md5);
- MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- MD5_Update(md5, sha_out, outLen);
- MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
- PORT_Assert(outLen == MD5_LENGTH);
- }
- PORT_Free(md5);
- PORT_Free(sha);
- }
-
- /* store the results */
- crv = pk11_forceAttribute
- (key,CKA_VALUE,key_block,SSL3_MASTER_SECRET_LENGTH);
- if (crv != CKR_OK) break;
- keyType = CKK_GENERIC_SECRET;
- crv = pk11_forceAttribute (key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
- if (isTLS) {
- /* TLS's master secret is used to "sign" finished msgs with PRF. */
- /* XXX This seems like a hack. But PK11_Derive only accepts
- * one "operation" argument. */
- crv = pk11_forceAttribute(key,CKA_SIGN, &cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) break;
- crv = pk11_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) break;
- /* While we're here, we might as well force this, too. */
- crv = pk11_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) break;
- }
- break;
- }
-
- case CKM_TLS_KEY_AND_MAC_DERIVE:
- isTLS = PR_TRUE;
- /* fall thru */
- case CKM_SSL3_KEY_AND_MAC_DERIVE:
- {
- CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
- CK_SSL3_KEY_MAT_OUT * ssl3_keys_out;
- CK_ULONG effKeySize;
-
- crv = pk11_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- att2 = pk11_FindAttribute(sourceKey,CKA_KEY_TYPE);
- if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
- CKK_GENERIC_SECRET)) {
- if (att2) pk11_FreeAttribute(att2);
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- pk11_FreeAttribute(att2);
- md5 = MD5_NewContext();
- if (md5 == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- sha = SHA1_NewContext();
- if (sha == NULL) {
- PORT_Free(md5);
- crv = CKR_HOST_MEMORY;
- break;
- }
- ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter;
- /*
- * clear out our returned keys so we can recover on failure
- */
- ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
- ssl3_keys_out->hClientMacSecret = CK_INVALID_KEY;
- ssl3_keys_out->hServerMacSecret = CK_INVALID_KEY;
- ssl3_keys_out->hClientKey = CK_INVALID_KEY;
- ssl3_keys_out->hServerKey = CK_INVALID_KEY;
-
- /*
- * generate the key material: This looks amazingly similar to the
- * PMS code, and is clearly crying out for a function to provide it.
- */
- if (isTLS) {
- SECStatus status;
- SECItem master = { siBuffer, NULL, 0 };
- SECItem srcr = { siBuffer, NULL, 0 };
- SECItem keyblk = { siBuffer, NULL, 0 };
- unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
-
- master.data = (unsigned char*)att->attrib.pValue;
- master.len = att->attrib.ulValueLen;
- srcr.data = srcrdata;
- srcr.len = sizeof srcrdata;
- keyblk.data = key_block;
- keyblk.len = sizeof key_block;
-
- PORT_Memcpy(srcrdata,
- ssl3_keys->RandomInfo.pServerRandom,
- SSL3_RANDOM_LENGTH);
- PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH,
- ssl3_keys->RandomInfo.pClientRandom,
- SSL3_RANDOM_LENGTH);
-
- status = pk11_PRF(&master, "key expansion", &srcr, &keyblk);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- } else {
- /* key_block =
- * MD5(master_secret + SHA('A' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * MD5(master_secret + SHA('BB' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * MD5(master_secret + SHA('CCC' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * [...];
- */
- for (i = 0; i < NUM_MIXERS; i++) {
- SHA1_Begin(sha);
- SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
- SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- SHA1_Update(sha, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- SHA1_Update(sha, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
- SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
- PORT_Assert(outLen == SHA1_LENGTH);
- MD5_Begin(md5);
- MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- MD5_Update(md5, sha_out, outLen);
- MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
- PORT_Assert(outLen == MD5_LENGTH);
- }
- }
-
- /*
- * Put the key material where it goes.
- */
- i = 0; /* now shows how much consumed */
- macSize = ssl3_keys->ulMacSizeInBits/8;
- effKeySize = ssl3_keys->ulKeySizeInBits/8;
- IVSize = ssl3_keys->ulIVSizeInBits/8;
- if (keySize == 0) {
- effKeySize = keySize;
- }
-
- /*
- * The key_block is partitioned as follows:
- * client_write_MAC_secret[CipherSpec.hash_size]
- */
- crv = pk11_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
- &ssl3_keys_out->hClientMacSecret);
- if (crv != CKR_OK)
- goto key_and_mac_derive_fail;
-
- i += macSize;
-
- /*
- * server_write_MAC_secret[CipherSpec.hash_size]
- */
- crv = pk11_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
- &ssl3_keys_out->hServerMacSecret);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
- i += macSize;
-
- if (keySize) {
- if (!ssl3_keys->bIsExport) {
- /*
- ** Generate Domestic write keys and IVs.
- ** client_write_key[CipherSpec.key_material]
- */
- crv = pk11_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
- keySize, &ssl3_keys_out->hClientKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
- i += keySize;
-
- /*
- ** server_write_key[CipherSpec.key_material]
- */
- crv = pk11_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
- keySize, &ssl3_keys_out->hServerKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
- i += keySize;
-
- /*
- ** client_write_IV[CipherSpec.IV_size]
- */
- PORT_Memcpy(ssl3_keys_out->pIVClient, &key_block[i], IVSize);
- i += IVSize;
-
- /*
- ** server_write_IV[CipherSpec.IV_size]
- */
- PORT_Memcpy(ssl3_keys_out->pIVServer, &key_block[i], IVSize);
- i += IVSize;
-
- } else if (!isTLS) {
-
- /*
- ** Generate SSL3 Export write keys and IVs.
- ** client_write_key[CipherSpec.key_material]
- ** final_client_write_key = MD5(client_write_key +
- ** ClientHello.random + ServerHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, &key_block[i], effKeySize);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- i += effKeySize;
- crv = pk11_buildSSLKey(hSession,key,PR_FALSE,key_block2,
- keySize,&ssl3_keys_out->hClientKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** server_write_key[CipherSpec.key_material]
- ** final_server_write_key = MD5(server_write_key +
- ** ServerHello.random + ClientHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, &key_block[i], effKeySize);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- i += effKeySize;
- crv = pk11_buildSSLKey(hSession,key,PR_FALSE,key_block2,
- keySize,&ssl3_keys_out->hServerKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** client_write_IV =
- ** MD5(ClientHello.random + ServerHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize);
-
- /*
- ** server_write_IV =
- ** MD5(ServerHello.random + ClientHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize);
-
- } else {
-
- /*
- ** Generate TLS Export write keys and IVs.
- */
- SECStatus status;
- SECItem secret = { siBuffer, NULL, 0 };
- SECItem crsr = { siBuffer, NULL, 0 };
- SECItem keyblk = { siBuffer, NULL, 0 };
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
-
- crsr.data = crsrdata;
- crsr.len = sizeof crsrdata;
-
- PORT_Memcpy(crsrdata,
- ssl3_keys->RandomInfo.pClientRandom,
- SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
- ssl3_keys->RandomInfo.pServerRandom,
- SSL3_RANDOM_LENGTH);
-
-
- /*
- ** client_write_key[CipherSpec.key_material]
- ** final_client_write_key = PRF(client_write_key,
- ** "client write key",
- ** client_random + server_random);
- */
- secret.data = &key_block[i];
- secret.len = effKeySize;
- i += effKeySize;
- keyblk.data = key_block2;
- keyblk.len = sizeof key_block2;
- status = pk11_PRF(&secret, "client write key", &crsr, &keyblk);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- crv = pk11_buildSSLKey(hSession, key, PR_FALSE, key_block2,
- keySize, &ssl3_keys_out->hClientKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** server_write_key[CipherSpec.key_material]
- ** final_server_write_key = PRF(server_write_key,
- ** "server write key",
- ** client_random + server_random);
- */
- secret.data = &key_block[i];
- secret.len = effKeySize;
- i += effKeySize;
- keyblk.data = key_block2;
- keyblk.len = sizeof key_block2;
- status = pk11_PRF(&secret, "server write key", &crsr, &keyblk);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- crv = pk11_buildSSLKey(hSession, key, PR_FALSE, key_block2,
- keySize, &ssl3_keys_out->hServerKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** iv_block = PRF("", "IV block",
- ** client_random + server_random);
- ** client_write_IV[SecurityParameters.IV_size]
- ** server_write_IV[SecurityParameters.IV_size]
- */
- if (IVSize) {
- secret.data = NULL;
- secret.len = 0;
- keyblk.data = &key_block[i];
- keyblk.len = 2 * IVSize;
- status = pk11_PRF(&secret, "IV block", &crsr, &keyblk);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- PORT_Memcpy(ssl3_keys_out->pIVClient, keyblk.data, IVSize);
- PORT_Memcpy(ssl3_keys_out->pIVServer, keyblk.data + IVSize,
- IVSize);
- }
- }
- }
-
- crv = CKR_OK;
-
- if (0) {
-key_and_mac_derive_fail:
- if (crv == CKR_OK)
- crv = CKR_FUNCTION_FAILED;
- pk11_freeSSLKeys(hSession, ssl3_keys_out);
- }
- MD5_DestroyContext(md5, PR_TRUE);
- SHA1_DestroyContext(sha, PR_TRUE);
- pk11_FreeObject(key);
- key = NULL;
- break;
- }
-
- case CKM_CONCATENATE_BASE_AND_KEY:
- {
- PK11Object *newKey;
-
- crv = pk11_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- crv = CKR_SESSION_HANDLE_INVALID;
- break;
- }
-
- newKey = pk11_ObjectFromHandle(*(CK_OBJECT_HANDLE *)
- pMechanism->pParameter,session);
- pk11_FreeSession(session);
- if ( newKey == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
-
- if (pk11_isTrue(newKey,CKA_SENSITIVE)) {
- crv = pk11_forceAttribute(newKey,CKA_SENSITIVE,&cktrue,
- sizeof(CK_BBOOL));
- if (crv != CKR_OK) {
- pk11_FreeObject(newKey);
- break;
- }
- }
-
- att2 = pk11_FindAttribute(newKey,CKA_VALUE);
- if (att2 == NULL) {
- pk11_FreeObject(newKey);
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- tmpKeySize = att->attrib.ulValueLen+att2->attrib.ulValueLen;
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- pk11_FreeObject(newKey);
- pk11_FreeAttribute(att2);
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(tmpKeySize);
- if (buf == NULL) {
- pk11_FreeAttribute(att2);
- pk11_FreeObject(newKey);
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
- PORT_Memcpy(buf+att->attrib.ulValueLen,
- att2->attrib.pValue,att2->attrib.ulValueLen);
-
- crv = pk11_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,tmpKeySize);
- pk11_FreeAttribute(att2);
- pk11_FreeObject(newKey);
- break;
- }
-
- case CKM_CONCATENATE_BASE_AND_DATA:
- stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter;
- tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(tmpKeySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
- PORT_Memcpy(buf+att->attrib.ulValueLen,stringPtr->pData,
- stringPtr->ulLen);
-
- crv = pk11_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,tmpKeySize);
- break;
- case CKM_CONCATENATE_DATA_AND_BASE:
- stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
- tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(tmpKeySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- PORT_Memcpy(buf,stringPtr->pData,stringPtr->ulLen);
- PORT_Memcpy(buf+stringPtr->ulLen,att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = pk11_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,tmpKeySize);
- break;
- case CKM_XOR_BASE_AND_DATA:
- stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
- tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen);
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(keySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
-
- PORT_Memcpy(buf,att->attrib.pValue,keySize);
- for (i=0; i < (int)keySize; i++) {
- buf[i] ^= stringPtr->pData[i];
- }
-
- crv = pk11_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,keySize);
- break;
-
- case CKM_EXTRACT_KEY_FROM_KEY:
- {
- /* the following assumes 8 bits per byte */
- CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
- CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */
- CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */
-
- if (keySize == 0) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
- /* make sure we have enough bits in the original key */
- if (att->attrib.ulValueLen <
- (offset + keySize + ((shift != 0)? 1 :0)) ) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(keySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- /* copy the bits we need into the new key */
- for (i=0; i < (int)keySize; i++) {
- unsigned char *value =
- ((unsigned char *)att->attrib.pValue)+offset+i;
- if (shift) {
- buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift));
- } else {
- buf[i] = value[0];
- }
- }
-
- crv = pk11_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,keySize);
- break;
- }
- case CKM_MD2_KEY_DERIVATION:
- if (keySize == 0) keySize = MD2_LENGTH;
- if (keySize > MD2_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- /* now allocate the hash contexts */
- md2 = MD2_NewContext();
- if (md2 == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- MD2_Begin(md2);
- MD2_Update(md2,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- MD2_End(md2,key_block,&outLen,MD2_LENGTH);
- MD2_DestroyContext(md2, PR_TRUE);
-
- crv = pk11_forceAttribute (key,CKA_VALUE,key_block,keySize);
- break;
- case CKM_MD5_KEY_DERIVATION:
- if (keySize == 0) keySize = MD5_LENGTH;
- if (keySize > MD5_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- /* now allocate the hash contexts */
- md5 = MD5_NewContext();
- if (md5 == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- MD5_Begin(md5);
- MD5_Update(md5,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- MD5_End(md5,key_block,&outLen,MD5_LENGTH);
- MD5_DestroyContext(md5, PR_TRUE);
-
- crv = pk11_forceAttribute (key,CKA_VALUE,key_block,keySize);
- break;
- case CKM_SHA1_KEY_DERIVATION:
- if (keySize == 0) keySize = SHA1_LENGTH;
- if (keySize > SHA1_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- /* now allocate the hash contexts */
- sha = SHA1_NewContext();
- if (sha == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- SHA1_Begin(sha);
- SHA1_Update(sha,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- SHA1_End(sha,key_block,&outLen,SHA1_LENGTH);
- SHA1_DestroyContext(sha, PR_TRUE);
-
- crv = pk11_forceAttribute(key,CKA_VALUE,key_block,keySize);
- break;
-
- case CKM_DH_PKCS_DERIVE:
- {
- SECItem derived, dhPublic;
- SECItem dhPrime, dhValue;
- /* sourceKey - values for the local existing low key */
- /* get prime and value attributes */
- crv = pk11_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME);
- if (crv != SECSuccess) break;
- crv = pk11_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE);
- if (crv != SECSuccess) {
- PORT_Free(dhPrime.data);
- break;
- }
-
- dhPublic.data = pMechanism->pParameter;
- dhPublic.len = pMechanism->ulParameterLen;
-
- /* calculate private value - oct */
- rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
-
- PORT_Free(dhPrime.data);
- PORT_Free(dhValue.data);
-
- if (rv == SECSuccess) {
- pk11_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
- PORT_ZFree(derived.data, derived.len);
- } else
- crv = CKR_HOST_MEMORY;
-
- break;
- }
-
- default:
- crv = CKR_MECHANISM_INVALID;
- }
- pk11_FreeAttribute(att);
- pk11_FreeObject(sourceKey);
- if (crv != CKR_OK) {
- if (key) pk11_FreeObject(key);
- return crv;
- }
-
- /* link the key object into the list */
- if (key) {
- /* get the session */
- key->wasDerived = PR_TRUE;
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) {
- pk11_FreeObject(key);
- return CKR_HOST_MEMORY;
- }
-
- crv = pk11_handleObject(key,session);
- pk11_FreeSession(session);
- if (crv == CKR_OK) {
- *phKey = key->handle;
- return crv;
- }
- pk11_FreeObject(key);
- }
- return crv;
-}
-
-
-/* NSC_GetFunctionStatus obtains an updated status of a function running
- * in parallel with an application. */
-CK_RV NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
-{
- return CKR_FUNCTION_NOT_PARALLEL;
-}
-
-/* NSC_CancelFunction cancels a function running in parallel */
-CK_RV NSC_CancelFunction(CK_SESSION_HANDLE hSession)
-{
- return CKR_FUNCTION_NOT_PARALLEL;
-}
-
-/* NSC_GetOperationState saves the state of the cryptographic
- *operation in a session.
- * NOTE: This code only works for digest functions for now. eventually need
- * to add full flatten/resurect to our state stuff so that all types of state
- * can be saved */
-CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
-{
- PK11SessionContext *context;
- PK11Session *session;
- CK_RV crv;
-
- /* make sure we're legal */
- crv = pk11_GetContext(hSession, &context, PK11_HASH, PR_TRUE, &session);
- if (crv != CKR_OK) return crv;
-
- *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE)
- + sizeof(PK11ContextType);
- if (pOperationState == NULL) {
- pk11_FreeSession(session);
- return CKR_OK;
- }
- PORT_Memcpy(pOperationState,&context->type,sizeof(PK11ContextType));
- pOperationState += sizeof(PK11ContextType);
- PORT_Memcpy(pOperationState,&context->currentMech,
- sizeof(CK_MECHANISM_TYPE));
- pOperationState += sizeof(CK_MECHANISM_TYPE);
- PORT_Memcpy(pOperationState,context->cipherInfo,context->cipherInfoLen);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-
-#define pk11_Decrement(stateSize,len) \
- stateSize = ((stateSize) > (CK_ULONG)(len)) ? \
- ((stateSize) - (CK_ULONG)(len)) : 0;
-
-/* NSC_SetOperationState restores the state of the cryptographic
- * operation in a session. This is coded like it can restore lots of
- * states, but it only works for truly flat cipher structures. */
-CK_RV NSC_SetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
-{
- PK11SessionContext *context;
- PK11Session *session;
- PK11ContextType type;
- CK_MECHANISM mech;
- CK_RV crv = CKR_OK;
-
- while (ulOperationStateLen != 0) {
- /* get what type of state we're dealing with... */
- PORT_Memcpy(&type,pOperationState, sizeof(PK11ContextType));
-
- /* fix up session contexts based on type */
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- context = pk11_ReturnContextByType(session, type);
- pk11_SetContextByType(session, type, NULL);
- if (context) {
- pk11_FreeContext(context);
- }
- pOperationState += sizeof(PK11ContextType);
- pk11_Decrement(ulOperationStateLen,sizeof(PK11ContextType));
-
-
- /* get the mechanism structure */
- PORT_Memcpy(&mech.mechanism,pOperationState,sizeof(CK_MECHANISM_TYPE));
- pOperationState += sizeof(CK_MECHANISM_TYPE);
- pk11_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE));
- /* should be filled in... but not necessary for hash */
- mech.pParameter = NULL;
- mech.ulParameterLen = 0;
- switch (type) {
- case PK11_HASH:
- crv = NSC_DigestInit(hSession,&mech);
- if (crv != CKR_OK) break;
- crv = pk11_GetContext(hSession, &context, PK11_HASH, PR_TRUE,
- NULL);
- if (crv != CKR_OK) break;
- PORT_Memcpy(context->cipherInfo,pOperationState,
- context->cipherInfoLen);
- pOperationState += context->cipherInfoLen;
- pk11_Decrement(ulOperationStateLen,context->cipherInfoLen);
- break;
- default:
- /* do sign/encrypt/decrypt later */
- crv = CKR_SAVED_STATE_INVALID;
- }
- pk11_FreeSession(session);
- if (crv != CKR_OK) break;
- }
- return crv;
-}
-
-/* Dual-function cryptographic operations */
-
-/* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption
- * operation. */
-CK_RV NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen)
-{
- CK_RV crv;
-
- crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart,
- pulEncryptedPartLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_DigestUpdate(hSession,pPart,ulPartLen);
-
- return crv;
-}
-
-
-/* NSC_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_RV NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
-{
- CK_RV crv;
-
- crv = NSC_DecryptUpdate(hSession,pEncryptedPart, ulEncryptedPartLen,
- pPart, pulPartLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_DigestUpdate(hSession,pPart,*pulPartLen);
-
- return crv;
-}
-
-
-/* NSC_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_RV NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen)
-{
- CK_RV crv;
-
- crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart,
- pulEncryptedPartLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_SignUpdate(hSession,pPart,ulPartLen);
-
- return crv;
-}
-
-
-/* NSC_DecryptVerifyUpdate continues a multiple-part decryption
- * and verify operation. */
-CK_RV NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
-{
- CK_RV crv;
-
- crv = NSC_DecryptUpdate(hSession,pEncryptedData, ulEncryptedDataLen,
- pData, pulDataLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);
-
- return crv;
-}
-
-/* NSC_DigestKey continues a multi-part message-digesting operation,
- * by digesting the value of a secret key as part of the data already digested.
- */
-CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
-{
- PK11Session *session = NULL;
- PK11Object *key = NULL;
- PK11Attribute *att;
- CK_RV crv;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- key = pk11_ObjectFromHandle(hKey,session);
- pk11_FreeSession(session);
- if (key == NULL) return CKR_KEY_HANDLE_INVALID;
-
- /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */
-
- /* make sure it's a valid key for this operation */
- if (key->objclass != CKO_SECRET_KEY) {
- pk11_FreeObject(key);
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- /* get the key value */
- att = pk11_FindAttribute(key,CKA_VALUE);
- pk11_FreeObject(key);
-
- crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue,
- att->attrib.ulValueLen);
- pk11_FreeAttribute(att);
- return crv;
-}
-
-
diff --git a/security/nss/lib/softoken/pkcs11f.h b/security/nss/lib/softoken/pkcs11f.h
deleted file mode 100644
index 71ee2676a..000000000
--- a/security/nss/lib/softoken/pkcs11f.h
+++ /dev/null
@@ -1,933 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/* This function contains pretty much everything about all the */
-/* PKCS #11 function prototypes. Because this information is */
-/* used for more than just declaring function prototypes, the */
-/* order of the functions appearing herein is important, and */
-/* should not be altered. */
-
-
-
-/* General-purpose */
-
-/* C_Initialize initializes the PKCS #11 library. */
-CK_PKCS11_FUNCTION_INFO(C_Initialize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
- * cast to CK_C_INITIALIZE_ARGS_PTR
- * and dereferenced */
-);
-#endif
-
-
-/* C_Finalize indicates that an application is done with the
- * PKCS #11 library. */
-CK_PKCS11_FUNCTION_INFO(C_Finalize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
-);
-#endif
-
-
-/* C_GetInfo returns general information about PKCS #11. */
-CK_PKCS11_FUNCTION_INFO(C_GetInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_INFO_PTR pInfo /* location that receives information */
-);
-#endif
-
-
-/* C_GetFunctionList returns the function list. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
- * function list */
-);
-#endif
-
-
-
-/* Slot and token management */
-
-/* C_GetSlotList obtains a list of slots in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_BBOOL tokenPresent, /* only slots with tokens? */
- CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
- CK_ULONG_PTR pulCount /* receives number of slots */
-);
-#endif
-
-
-/* C_GetSlotInfo obtains information about a particular slot in
- * the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* the ID of the slot */
- CK_SLOT_INFO_PTR pInfo /* receives the slot information */
-);
-#endif
-
-
-/* C_GetTokenInfo obtains information about a particular token
- * in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_TOKEN_INFO_PTR pInfo /* receives the token information */
-);
-#endif
-
-
-/* C_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of token's slot */
- CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
- CK_ULONG_PTR pulCount /* gets # of mechs. */
-);
-#endif
-
-
-/* C_GetMechanismInfo obtains information about a particular
- * mechanism possibly supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_MECHANISM_TYPE type, /* type of mechanism */
- CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
-);
-#endif
-
-
-/* C_InitToken initializes a token. */
-CK_PKCS11_FUNCTION_INFO(C_InitToken)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_CHAR_PTR pPin, /* the SO's initial PIN */
- CK_ULONG ulPinLen, /* length in bytes of the PIN */
- CK_CHAR_PTR pLabel /* 32-byte token label (blank padded) */
-);
-#endif
-
-
-/* C_InitPIN initializes the normal user's PIN. */
-CK_PKCS11_FUNCTION_INFO(C_InitPIN)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_CHAR_PTR pPin, /* the normal user's PIN */
- CK_ULONG ulPinLen /* length in bytes of the PIN */
-);
-#endif
-
-
-/* C_SetPIN modifies the PIN of the user who is logged in. */
-CK_PKCS11_FUNCTION_INFO(C_SetPIN)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_CHAR_PTR pOldPin, /* the old PIN */
- CK_ULONG ulOldLen, /* length of the old PIN */
- CK_CHAR_PTR pNewPin, /* the new PIN */
- CK_ULONG ulNewLen /* length of the new PIN */
-);
-#endif
-
-
-
-/* Session management */
-
-/* C_OpenSession opens a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_OpenSession)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* the slot's ID */
- CK_FLAGS flags, /* from CK_SESSION_INFO */
- CK_VOID_PTR pApplication, /* passed to callback */
- CK_NOTIFY Notify, /* callback function */
- CK_SESSION_HANDLE_PTR phSession /* gets session handle */
-);
-#endif
-
-
-/* C_CloseSession closes a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseSession)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-/* C_CloseAllSessions closes all sessions with a token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID /* the token's slot */
-);
-#endif
-
-
-/* C_GetSessionInfo obtains information about the session. */
-CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_SESSION_INFO_PTR pInfo /* receives session info */
-);
-#endif
-
-
-/* C_GetOperationState obtains the state of the cryptographic operation
- * in a session. */
-CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pOperationState, /* gets state */
- CK_ULONG_PTR pulOperationStateLen /* gets state length */
-);
-#endif
-
-
-/* C_SetOperationState restores the state of the cryptographic
- * operation in a session. */
-CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pOperationState, /* holds state */
- CK_ULONG ulOperationStateLen, /* holds state length */
- CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
- CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
-);
-#endif
-
-
-/* C_Login logs a user into a token. */
-CK_PKCS11_FUNCTION_INFO(C_Login)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_USER_TYPE userType, /* the user type */
- CK_CHAR_PTR pPin, /* the user's PIN */
- CK_ULONG ulPinLen /* the length of the PIN */
-);
-#endif
-
-
-/* C_Logout logs a user out from a token. */
-CK_PKCS11_FUNCTION_INFO(C_Logout)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Object management */
-
-/* C_CreateObject creates a new object. */
-CK_PKCS11_FUNCTION_INFO(C_CreateObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
- CK_ULONG ulCount, /* attributes in template */
- CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
-);
-#endif
-
-
-/* C_CopyObject copies an object, creating a new object for the
- * copy. */
-CK_PKCS11_FUNCTION_INFO(C_CopyObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
- CK_ULONG ulCount, /* attributes in template */
- CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
-);
-#endif
-
-
-/* C_DestroyObject destroys an object. */
-CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject /* the object's handle */
-);
-#endif
-
-
-/* C_GetObjectSize gets the size of an object in bytes. */
-CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ULONG_PTR pulSize /* receives size of object */
-);
-#endif
-
-
-/* C_GetAttributeValue obtains the value of one or more object
- * attributes. */
-CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
- CK_ULONG ulCount /* attributes in template */
-);
-#endif
-
-
-/* C_SetAttributeValue modifies the value of one or more object
- * attributes */
-CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
- CK_ULONG ulCount /* attributes in template */
-);
-#endif
-
-
-/* C_FindObjectsInit initializes a search for token and session
- * objects that match a template. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
- CK_ULONG ulCount /* attrs in search template */
-);
-#endif
-
-
-/* C_FindObjects continues a search for token and session
- * objects that match a template, obtaining additional object
- * handles. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjects)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
- CK_ULONG ulMaxObjectCount, /* max handles to get */
- CK_ULONG_PTR pulObjectCount /* actual # returned */
-);
-#endif
-
-
-/* C_FindObjectsFinal finishes a search for token and session
- * objects. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Encryption and decryption */
-
-/* C_EncryptInit initializes an encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
- CK_OBJECT_HANDLE hKey /* handle of encryption key */
-);
-#endif
-
-
-/* C_Encrypt encrypts single-part data. */
-CK_PKCS11_FUNCTION_INFO(C_Encrypt)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pData, /* the plaintext data */
- CK_ULONG ulDataLen, /* bytes of plaintext */
- CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptUpdate continues a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext data len */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptFinal finishes a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session handle */
- CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
- CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
-);
-#endif
-
-
-/* C_DecryptInit initializes a decryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
- CK_OBJECT_HANDLE hKey /* handle of decryption key */
-);
-#endif
-
-
-/* C_Decrypt decrypts encrypted data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Decrypt)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedData, /* ciphertext */
- CK_ULONG ulEncryptedDataLen, /* ciphertext length */
- CK_BYTE_PTR pData, /* gets plaintext */
- CK_ULONG_PTR pulDataLen /* gets p-text size */
-);
-#endif
-
-
-/* C_DecryptUpdate continues a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* encrypted data */
- CK_ULONG ulEncryptedPartLen, /* input length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* p-text size */
-);
-#endif
-
-
-/* C_DecryptFinal finishes a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pLastPart, /* gets plaintext */
- CK_ULONG_PTR pulLastPartLen /* p-text size */
-);
-#endif
-
-
-
-/* Message digesting */
-
-/* C_DigestInit initializes a message-digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
-);
-#endif
-
-
-/* C_Digest digests data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Digest)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* data to be digested */
- CK_ULONG ulDataLen, /* bytes of data to digest */
- CK_BYTE_PTR pDigest, /* gets the message digest */
- CK_ULONG_PTR pulDigestLen /* gets digest length */
-);
-#endif
-
-
-/* C_DigestUpdate continues a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* data to be digested */
- CK_ULONG ulPartLen /* bytes of data to be digested */
-);
-#endif
-
-
-/* C_DigestKey continues a multi-part message-digesting
- * operation, by digesting the value of a secret key as part of
- * the data already digested. */
-CK_PKCS11_FUNCTION_INFO(C_DigestKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hKey /* secret key to digest */
-);
-#endif
-
-
-/* C_DigestFinal finishes a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pDigest, /* gets the message digest */
- CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
-);
-#endif
-
-
-
-/* Signing and MACing */
-
-/* C_SignInit initializes a signature (private key encryption)
- * operation, where the signature is (will be) an appendix to
- * the data, and plaintext cannot be recovered from the
- *signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
- CK_OBJECT_HANDLE hKey /* handle of signature key */
-);
-#endif
-
-
-/* C_Sign signs (encrypts with private key) data in a single
- * part, where the signature is (will be) an appendix to the
- * data, and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Sign)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* the data to sign */
- CK_ULONG ulDataLen, /* count of bytes to sign */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-/* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* the data to sign */
- CK_ULONG ulPartLen /* count of bytes to sign */
-);
-#endif
-
-
-/* C_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-/* C_SignRecoverInit initializes a signature operation, where
- * the data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
- CK_OBJECT_HANDLE hKey /* handle of the signature key */
-);
-#endif
-
-
-/* C_SignRecover signs data in a single operation, where the
- * data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecover)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* the data to sign */
- CK_ULONG ulDataLen, /* count of bytes to sign */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-
-/* Verifying signatures and MACs */
-
-/* C_VerifyInit initializes a verification operation, where the
- * signature is an appendix to the data, and plaintext cannot
- * cannot be recovered from the signature (e.g. DSA). */
-CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
- CK_OBJECT_HANDLE hKey /* verification key */
-);
-#endif
-
-
-/* C_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data, and plaintext
- * cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Verify)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* signed data */
- CK_ULONG ulDataLen, /* length of signed data */
- CK_BYTE_PTR pSignature, /* signature */
- CK_ULONG ulSignatureLen /* signature length*/
-);
-#endif
-
-
-/* C_VerifyUpdate continues a multiple-part verification
- * operation, where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* signed data */
- CK_ULONG ulPartLen /* length of signed data */
-);
-#endif
-
-
-/* C_VerifyFinal finishes a multiple-part verification
- * operation, checking the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* signature to verify */
- CK_ULONG ulSignatureLen /* signature length */
-);
-#endif
-
-
-/* C_VerifyRecoverInit initializes a signature verification
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
- CK_OBJECT_HANDLE hKey /* verification key */
-);
-#endif
-
-
-/* C_VerifyRecover verifies a signature in a single-part
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* signature to verify */
- CK_ULONG ulSignatureLen, /* signature length */
- CK_BYTE_PTR pData, /* gets signed data */
- CK_ULONG_PTR pulDataLen /* gets signed data len */
-);
-#endif
-
-
-
-/* Dual-function cryptographic operations */
-
-/* C_DigestEncryptUpdate continues a multiple-part digesting
- * and encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext length */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* ciphertext */
- CK_ULONG ulEncryptedPartLen, /* ciphertext length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* gets plaintext len */
-);
-#endif
-
-
-/* C_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext length */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptVerifyUpdate continues a multiple-part decryption and
- * verify operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* ciphertext */
- CK_ULONG ulEncryptedPartLen, /* ciphertext length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* gets p-text length */
-);
-#endif
-
-
-
-/* Key management */
-
-/* C_GenerateKey generates a secret key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* key generation mech. */
- CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
- CK_ULONG ulCount, /* # of attrs in template */
- CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
-);
-#endif
-
-
-/* C_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session
- * handle */
- CK_MECHANISM_PTR pMechanism, /* key-gen
- * mech. */
- CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
- * for pub.
- * key */
- CK_ULONG ulPublicKeyAttributeCount, /* # pub.
- * attrs. */
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
- * for priv.
- * key */
- CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
- * attrs. */
- CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
- * key
- * handle */
- CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
- * priv. key
- * handle */
-);
-#endif
-
-
-/* C_WrapKey wraps (i.e., encrypts) a key. */
-CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
- CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
- CK_OBJECT_HANDLE hKey, /* key to be wrapped */
- CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
- CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
-);
-#endif
-
-
-/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
- * key object. */
-CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
- CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
- CK_BYTE_PTR pWrappedKey, /* the wrapped key */
- CK_ULONG ulWrappedKeyLen, /* wrapped key len */
- CK_ATTRIBUTE_PTR pTemplate, /* new key template */
- CK_ULONG ulAttributeCount, /* template length */
- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-);
-#endif
-
-
-/* C_DeriveKey derives a key from a base key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
- CK_OBJECT_HANDLE hBaseKey, /* base key */
- CK_ATTRIBUTE_PTR pTemplate, /* new key template */
- CK_ULONG ulAttributeCount, /* template length */
- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-);
-#endif
-
-
-
-/* Random number generation */
-
-/* C_SeedRandom mixes additional seed material into the token's
- * random number generator. */
-CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSeed, /* the seed material */
- CK_ULONG ulSeedLen /* length of seed material */
-);
-#endif
-
-
-/* C_GenerateRandom generates random data. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR RandomData, /* receives the random data */
- CK_ULONG ulRandomLen /* # of bytes to generate */
-);
-#endif
-
-
-
-/* Parallel function management */
-
-/* C_GetFunctionStatus is a legacy function; it obtains an
- * updated status of a function running in parallel with an
- * application. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-/* C_CancelFunction is a legacy function; it cancels a function
- * running in parallel. */
-CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Functions added in for PKCS #11 Version 2.01 or later */
-
-/* C_WaitForSlotEvent waits for a slot event (token insertion,
- * removal, etc.) to occur. */
-CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_FLAGS flags, /* blocking/nonblocking flag */
- CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
- CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
-);
-#endif
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
deleted file mode 100644
index 495817aef..000000000
--- a/security/nss/lib/softoken/pkcs11i.h
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * Internal data structures and functions used by pkcs11.c
- */
-#ifndef _PKCS11I_H_
-#define _PKCS11I_H_ 1
-
-#include "prlock.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "keytlow.h"
-#include "pkcs11t.h"
-
-#define PKCS11_USE_THREADS
-
-#define NO_ARENA
-#define MAX_OBJS_ATTRS 45
-#define ATTR_SPACE 50 /* hold up to a SSL premaster secret */
-
-
-#ifdef PKCS11_USE_THREADS
-#define PK11_USE_THREADS(x) x
-#else
-#define PK11_USE_THREADS(x)
-#endif
-
-/* define typedefs, double as forward declarations as well */
-typedef struct PK11AttributeStr PK11Attribute;
-typedef struct PK11ObjectListStr PK11ObjectList;
-typedef struct PK11ObjectListElementStr PK11ObjectListElement;
-typedef struct PK11ObjectStr PK11Object;
-typedef struct PK11SessionStr PK11Session;
-typedef struct PK11SlotStr PK11Slot;
-typedef struct PK11SessionContextStr PK11SessionContext;
-typedef struct PK11SearchResultsStr PK11SearchResults;
-typedef struct PK11HashVerifyInfoStr PK11HashVerifyInfo;
-typedef struct PK11HashSignInfoStr PK11HashSignInfo;
-typedef struct PK11SSLMACInfoStr PK11SSLMACInfo;
-
-/* define function pointer typdefs for pointer tables */
-typedef void (*PK11Destroy)(void *, PRBool);
-typedef void (*PK11Begin)(void *);
-typedef SECStatus (*PK11Cipher)(void *,void *,unsigned int *,unsigned int,
- void *, unsigned int);
-typedef SECStatus (*PK11Verify)(void *,void *,unsigned int,void *,unsigned int);
-typedef void (*PK11Hash)(void *,void *,unsigned int);
-typedef void (*PK11End)(void *,void *,unsigned int *,unsigned int);
-typedef void (*PK11Free)(void *);
-
-/*
- * these are data base storage hashes, not cryptographic hashes.. The define
- * the effective size of the various object hash tables
- */
-#define ATTRIBUTE_HASH_SIZE 32
-#define SESSION_OBJECT_HASH_SIZE 32
-#define TOKEN_OBJECT_HASH_SIZE 1024
-#define SESSION_HASH_SIZE 512
-#define MAX_KEY_LEN 256
-#define MAX_OBJECT_LIST_SIZE 800
-
-/* Value to tell if an attribute is modifiable or not.
- * NEVER: attribute is only set on creation.
- * ONCOPY: attribute is set on creation and can only be changed on copy.
- * SENSITIVE: attribute can only be changed to TRUE.
- * ALWAYS: attribute can always be changed.
- */
-typedef enum {
- PK11_NEVER = 0,
- PK11_ONCOPY = 1,
- PK11_SENSITIVE = 2,
- PK11_ALWAYS = 3
-} PK11ModifyType;
-
-/*
- * Free Status Enum... tell us more information when we think we're
- * deleting an object.
- */
-typedef enum {
- PK11_DestroyFailure,
- PK11_Destroyed,
- PK11_Busy
-} PK11FreeStatus;
-
-/*
- * attribute values of an object.
- */
-struct PK11AttributeStr {
- PK11Attribute *next;
- PK11Attribute *prev;
-#ifdef REF_COUNT_ATTRIBUTE
- int refCount;
- PRLock *refLock;
-#endif
- /*must be called handle to make pk11queue_find work */
- CK_ATTRIBUTE_TYPE handle;
- CK_ATTRIBUTE attrib;
-#ifdef NO_ARENA
- unsigned char space[ATTR_SPACE];
-#endif
-};
-
-
-/*
- * doubly link list of objects
- */
-struct PK11ObjectListStr {
- PK11ObjectList *next;
- PK11ObjectList *prev;
- PK11Object *parent;
-};
-
-/*
- * PKCS 11 crypto object structure
- */
-struct PK11ObjectStr {
- PK11Object *next;
- PK11Object *prev;
- PK11ObjectList sessionList;
- CK_OBJECT_HANDLE handle;
-#ifdef NO_ARENA
- int nextAttr;
-#else
- PLArenaPool *arena;
-#endif
- int refCount;
- PRLock *refLock;
- PRLock *attributeLock;
- PK11Session *session;
- PK11Slot *slot;
- CK_OBJECT_CLASS objclass;
- void *objectInfo;
- PK11Free infoFree;
- char *label;
- PRBool inDB;
- PRBool wasDerived;
- PK11Attribute *head[ATTRIBUTE_HASH_SIZE];
-#ifdef NO_ARENA
- PK11Attribute attrList[MAX_OBJS_ATTRS];
-#endif
-};
-
-/*
- * struct to deal with a temparary list of objects
- */
-struct PK11ObjectListElementStr {
- PK11ObjectListElement *next;
- PK11Object *object;
-};
-
-/*
- * Area to hold Search results
- */
-struct PK11SearchResultsStr {
- CK_OBJECT_HANDLE *handles;
- int size;
- int index;
-};
-
-
-/*
- * the universal crypto/hash/sign/verify context structure
- */
-typedef enum {
- PK11_ENCRYPT,
- PK11_DECRYPT,
- PK11_HASH,
- PK11_SIGN,
- PK11_SIGN_RECOVER,
- PK11_VERIFY,
- PK11_VERIFY_RECOVER
-} PK11ContextType;
-
-
-#define PK11_MAX_BLOCK_SIZE 16
-/* currently SHA1 is the biggest hash length */
-#define PK11_MAX_MAC_LENGTH 20
-#define PK11_INVALID_MAC_SIZE 0xffffffff
-
-struct PK11SessionContextStr {
- PK11ContextType type;
- PRBool multi; /* is multipart */
- PRBool doPad; /* use PKCS padding for block ciphers */
- unsigned int blockSize; /* blocksize for padding */
- unsigned int padDataLength; /* length of the valid data in padbuf */
- unsigned char padBuf[PK11_MAX_BLOCK_SIZE];
- unsigned char macBuf[PK11_MAX_BLOCK_SIZE];
- CK_ULONG macSize; /* size of a general block cipher mac*/
- void *cipherInfo;
- void *hashInfo;
- unsigned int cipherInfoLen;
- CK_MECHANISM_TYPE currentMech;
- PK11Cipher update;
- PK11Hash hashUpdate;
- PK11End end;
- PK11Destroy destroy;
- PK11Destroy hashdestroy;
- PK11Verify verify;
- unsigned int maxLen;
-};
-
-/*
- * Sessions (have objects)
- */
-struct PK11SessionStr {
- PK11Session *next;
- PK11Session *prev;
- CK_SESSION_HANDLE handle;
- int refCount;
- PRLock *refLock;
- PRLock *objectLock;
- int objectIDCount;
- CK_SESSION_INFO info;
- CK_NOTIFY notify;
- CK_VOID_PTR appData;
- PK11Slot *slot;
- PK11SearchResults *search;
- PK11SessionContext *enc_context;
- PK11SessionContext *hash_context;
- PK11SessionContext *sign_context;
- PK11ObjectList *objects[1];
-};
-
-/*
- * slots (have sessions and objects)
- */
-struct PK11SlotStr {
- CK_SLOT_ID slotID;
- PRLock *sessionLock;
- PRLock *objectLock;
- SECItem *password;
- PRBool hasTokens;
- PRBool isLoggedIn;
- PRBool ssoLoggedIn;
- PRBool needLogin;
- PRBool DB_loaded;
- int sessionIDCount;
- int sessionCount;
- int rwSessionCount;
- int tokenIDCount;
- PK11Object *tokObjects[TOKEN_OBJECT_HASH_SIZE];
- PK11Session *head[SESSION_HASH_SIZE];
-};
-
-/*
- * special joint operations Contexts
- */
-struct PK11HashVerifyInfoStr {
- SECOidTag hashOid;
- SECKEYLowPublicKey *key;
-};
-
-struct PK11HashSignInfoStr {
- SECOidTag hashOid;
- SECKEYLowPrivateKey *key;
-};
-
-/* context for the Final SSLMAC message */
-struct PK11SSLMACInfoStr {
- void *hashContext;
- PK11Begin begin;
- PK11Hash update;
- PK11End end;
- CK_ULONG macSize;
- int padSize;
- unsigned char key[MAX_KEY_LEN];
- unsigned int keySize;
-};
-
-/*
- * session handle modifiers
- */
-#define PK11_PRIVATE_KEY_FLAG 0x80000000L
-#define PK11_FIPS_FLAG 0x40000000L
-
-/*
- * object handle modifiers
- */
-#define PK11_TOKEN_MASK 0x80000000L
-#define PK11_TOKEN_MAGIC 0x80000000L
-#define PK11_TOKEN_TYPE_MASK 0x70000000L
-#define PK11_TOKEN_TYPE_CERT 0x00000000L
-#define PK11_TOKEN_TYPE_PRIV 0x10000000L
-#define PK11_TOKEN_TYPE_PUB 0x20000000L
-
-/* how big a password/pin we can deal with */
-#define PK11_MAX_PIN 255
-
-/* slot ID's */
-#define NETSCAPE_SLOT_ID 1
-#define PRIVATE_KEY_SLOT_ID 2
-#define FIPS_SLOT_ID 3
-
-/* slot helper macros */
-#define pk11_SlotFromSession(sp) ((sp)->slot)
-#define pk11_isToken(id) (((id) & PK11_TOKEN_MASK) == PK11_TOKEN_MAGIC)
-
-/* queueing helper macros */
-#define pk11_hash(value,size) ((value) & (size-1))/*size must be a power of 2*/
-#define pk11queue_add(element,id,head,hash_size) \
- { int tmp = pk11_hash(id,hash_size); \
- (element)->next = (head)[tmp]; \
- (element)->prev = NULL; \
- if ((head)[tmp]) (head)[tmp]->prev = (element); \
- (head)[tmp] = (element); }
-#define pk11queue_find(element,id,head,hash_size) \
- for( (element) = (head)[pk11_hash(id,hash_size)]; (element) != NULL; \
- (element) = (element)->next) { \
- if ((element)->handle == (id)) { break; } }
-#define pk11queue_is_queued(element,id,head,hash_size) \
- ( ((element)->next) || ((element)->prev) || \
- ((head)[pk11_hash(id,hash_size)] == (element)) )
-#define pk11queue_delete(element,id,head,hash_size) \
- if ((element)->next) (element)->next->prev = (element)->prev; \
- if ((element)->prev) (element)->prev->next = (element)->next; \
- else (head)[pk11_hash(id,hash_size)] = ((element)->next); \
- (element)->next = NULL; \
- (element)->prev = NULL; \
-
-/* expand an attribute & secitem structures out */
-#define pk11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
-#define pk11_item_expand(ip) (ip)->data,(ip)->len
-
-SEC_BEGIN_PROTOS
-
-/* shared functions between PKCS11.c and PK11FIPS.c */
-extern CK_RV PK11_LowInitialize(CK_VOID_PTR pReserved);
-extern CK_RV PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin);
-
-/* internal utility functions used by pkcs11.c */
-extern PK11Attribute *pk11_FindAttribute(PK11Object *object,
- CK_ATTRIBUTE_TYPE type);
-extern void pk11_FreeAttribute(PK11Attribute *attribute);
-extern CK_RV pk11_AddAttributeType(PK11Object *object, CK_ATTRIBUTE_TYPE type,
- void *valPtr,
- CK_ULONG length);
-extern CK_RV pk11_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
- PK11Object *object, CK_ATTRIBUTE_TYPE type);
-extern PRBool pk11_hasAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type);
-extern PRBool pk11_isTrue(PK11Object *object, CK_ATTRIBUTE_TYPE type);
-extern void pk11_DeleteAttributeType(PK11Object *object,
- CK_ATTRIBUTE_TYPE type);
-extern CK_RV pk11_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
- PK11Object *object, CK_ATTRIBUTE_TYPE type);
-extern CK_RV pk11_Attribute2SSecItem(PLArenaPool *arena, SECItem *item,
- PK11Object *object,
- CK_ATTRIBUTE_TYPE type);
-extern PK11ModifyType pk11_modifyType(CK_ATTRIBUTE_TYPE type,
- CK_OBJECT_CLASS inClass);
-extern PRBool pk11_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass);
-extern char *pk11_getString(PK11Object *object, CK_ATTRIBUTE_TYPE type);
-extern void pk11_nullAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type);
-extern CK_RV pk11_forceAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
- void *value, unsigned int len);
-extern CK_RV pk11_defaultAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
- void *value, unsigned int len);
-
-extern PK11Object *pk11_NewObject(PK11Slot *slot);
-extern CK_RV pk11_CopyObject(PK11Object *destObject, PK11Object *srcObject);
-extern PK11FreeStatus pk11_FreeObject(PK11Object *object);
-extern void pk11_DeleteObject(PK11Session *session, PK11Object *object);
-extern void pk11_ReferenceObject(PK11Object *object);
-extern PK11Object *pk11_ObjectFromHandle(CK_OBJECT_HANDLE handle,
- PK11Session *session);
-extern void pk11_AddSlotObject(PK11Slot *slot, PK11Object *object);
-extern void pk11_AddObject(PK11Session *session, PK11Object *object);
-
-extern CK_RV pk11_searchObjectList(PK11ObjectListElement **objectList,
- PK11Object **head, PRLock *lock,
- CK_ATTRIBUTE_PTR inTemplate, int count,
- PRBool isLoggedIn);
-extern PK11ObjectListElement *pk11_FreeObjectListElement(
- PK11ObjectListElement *objectList);
-extern void pk11_FreeObjectList(PK11ObjectListElement *objectList);
-extern void pk11_FreeSearch(PK11SearchResults *search);
-extern CK_RV pk11_handleObject(PK11Object *object, PK11Session *session);
-
-extern PK11Slot *pk11_SlotFromID(CK_SLOT_ID slotID);
-extern PK11Slot *pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle);
-extern PK11Session *pk11_SessionFromHandle(CK_SESSION_HANDLE handle);
-extern void pk11_FreeSession(PK11Session *session);
-extern PK11Session *pk11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify,
- CK_VOID_PTR pApplication, CK_FLAGS flags);
-extern void pk11_update_state(PK11Slot *slot,PK11Session *session);
-extern void pk11_update_all_states(PK11Slot *slot);
-extern void pk11_FreeContext(PK11SessionContext *context);
-
-extern SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,
- CK_KEY_TYPE key_type);
-extern SECKEYLowPrivateKey *pk11_GetPrivKey(PK11Object *object,
- CK_KEY_TYPE key_type);
-extern void pk11_FormatDESKey(unsigned char *key, int length);
-extern PRBool pk11_CheckDESKey(unsigned char *key);
-extern PRBool pk11_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type);
-
-SEC_END_PROTOS
-
-#endif /* _PKCS11I_H_ */
diff --git a/security/nss/lib/softoken/pkcs11p.h b/security/nss/lib/softoken/pkcs11p.h
deleted file mode 100644
index 9876ad3ac..000000000
--- a/security/nss/lib/softoken/pkcs11p.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/* these data types are platform/implementation dependent. */
-/*
- * Packing was removed from the shipped RSA header files, even
- * though it's still needed. put in a central file to help merging..
- */
-#if defined(XP_WIN)
-#if defined(_WIN32)
-#pragma warning(disable:4103)
-#pragma pack(push, cryptoki, 1)
-#endif
-#endif
diff --git a/security/nss/lib/softoken/pkcs11t.h b/security/nss/lib/softoken/pkcs11t.h
deleted file mode 100644
index 254b6dd1e..000000000
--- a/security/nss/lib/softoken/pkcs11t.h
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/* See top of pkcs11.h for information about the macros that
- * must be defined and the structure-packing conventions that
- * must be set before including this file.
- */
-
-#ifndef _PKCS11T_H_
-#define _PKCS11T_H_ 1
-
-#ifndef CK_FALSE
-#define CK_FALSE 0
-#endif
-
-#ifndef CK_TRUE
-#define CK_TRUE (!CK_FALSE)
-#endif
-
-#include "prtypes.h"
-
-#define CK_PTR *
-#define CK_NULL_PTR 0
-#define CK_CALLBACK_FUNCTION(rv,func) rv (PR_CALLBACK * func)
-#define CK_DECLARE_FUNCTION(rv,func) PR_EXTERN(rv) func
-#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (PR_CALLBACK * func)
-
-/* an unsigned 8-bit value */
-typedef unsigned char CK_BYTE;
-
-/* an unsigned 8-bit character */
-typedef CK_BYTE CK_CHAR;
-
-/* a BYTE-sized Boolean flag */
-typedef CK_BYTE CK_BBOOL;
-
-/* an unsigned value, at least 32 bits long */
-typedef unsigned long int CK_ULONG;
-
-/* a signed value, the same size as a CK_ULONG */
-/* CK_LONG is new for v2.0 */
-typedef long int CK_LONG;
-
-/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG CK_FLAGS;
-
-
-/* some special values for certain CK_ULONG variables */
-#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE 0
-
-
-typedef CK_BYTE CK_PTR CK_BYTE_PTR;
-typedef CK_CHAR CK_PTR CK_CHAR_PTR;
-typedef CK_ULONG CK_PTR CK_ULONG_PTR;
-typedef void CK_PTR CK_VOID_PTR;
-
-/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-
-
-/* The following value is always invalid if used as a session */
-/* handle or object handle */
-#define CK_INVALID_HANDLE 0
-
-
-/* pack */
-#include "pkcs11p.h"
-
-typedef struct CK_VERSION {
- CK_BYTE major; /* integer portion of version number */
- CK_BYTE minor; /* 1/100ths portion of version number */
-} CK_VERSION;
-
-typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-
-
-typedef struct CK_INFO {
- CK_VERSION cryptokiVersion; /* PKCS #11 interface ver */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags; /* must be zero */
-
- /* libraryDescription and libraryVersion are new for v2.0 */
- CK_CHAR libraryDescription[32]; /* blank padded */
- CK_VERSION libraryVersion; /* version of library */
-} CK_INFO;
-
-typedef CK_INFO CK_PTR CK_INFO_PTR;
-
-
-/* CK_NOTIFICATION enumerates the types of notifications that
- * PKCS #11 provides to an application */
-/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_NOTIFICATION;
-#define CKN_SURRENDER 0
-
-
-typedef CK_ULONG CK_SLOT_ID;
-
-typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-
-
-/* CK_SLOT_INFO provides information about a slot */
-typedef struct CK_SLOT_INFO {
- CK_CHAR slotDescription[64]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags;
-
- /* hardwareVersion and firmwareVersion are new for v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
-} CK_SLOT_INFO;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
-#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
-#define CKF_HW_SLOT 0x00000004 /* hardware slot */
-
-typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-
-
-/* CK_TOKEN_INFO provides information about a token */
-typedef struct CK_TOKEN_INFO {
- CK_CHAR label[32]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_CHAR model[16]; /* blank padded */
- CK_CHAR serialNumber[16]; /* blank padded */
- CK_FLAGS flags; /* see below */
-
- /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
- * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
- * changed from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulMaxSessionCount; /* max open sessions */
- CK_ULONG ulSessionCount; /* sess. now open */
- CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
- CK_ULONG ulRwSessionCount; /* R/W sess. now open */
- CK_ULONG ulMaxPinLen; /* in bytes */
- CK_ULONG ulMinPinLen; /* in bytes */
- CK_ULONG ulTotalPublicMemory; /* in bytes */
- CK_ULONG ulFreePublicMemory; /* in bytes */
- CK_ULONG ulTotalPrivateMemory; /* in bytes */
- CK_ULONG ulFreePrivateMemory; /* in bytes */
-
- /* hardwareVersion, firmwareVersion, and time are new for
- * v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
- CK_CHAR utcTime[16]; /* time */
-} CK_TOKEN_INFO;
-
-/* The flags parameter is defined as follows:
- * Bit Flag Mask Meaning
- */
-#define CKF_RNG 0x00000001 /* has random #
- * generator */
-#define CKF_WRITE_PROTECTED 0x00000002 /* token is
- * write-
- * protected */
-#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
- * login */
-#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
- * PIN is set */
-
-/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
- * that means that *every* time the state of cryptographic
- * operations of a session is successfully saved, all keys
- * needed to continue those operations are stored in the state */
-#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
-
-/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
- * that the token has some sort of clock. The time on that
- * clock is returned in the token info structure */
-#define CKF_CLOCK_ON_TOKEN 0x00000040
-
-/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
- * set, that means that there is some way for the user to login
- * without sending a PIN through the PKCS #11 library itself */
-#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-
-/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
- * that means that a single session with the token can perform
- * dual simultaneous cryptographic operations (digest and
- * encrypt; decrypt and digest; sign and encrypt; and decrypt
- * and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
-
-typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-
-
-/* CK_SESSION_HANDLE is a PKCS #11-assigned value that
- * identifies a session */
-typedef CK_ULONG CK_SESSION_HANDLE;
-
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-
-
-/* CK_USER_TYPE enumerates the types of PKCS #11 users */
-/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_USER_TYPE;
-/* Security Officer */
-#define CKU_SO 0
-/* Normal user */
-#define CKU_USER 1
-
-
-/* CK_STATE enumerates the session states */
-/* CK_STATE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_STATE;
-#define CKS_RO_PUBLIC_SESSION 0
-#define CKS_RO_USER_FUNCTIONS 1
-#define CKS_RW_PUBLIC_SESSION 2
-#define CKS_RW_USER_FUNCTIONS 3
-#define CKS_RW_SO_FUNCTIONS 4
-
-
-/* CK_SESSION_INFO provides information about a session */
-typedef struct CK_SESSION_INFO {
- CK_SLOT_ID slotID;
- CK_STATE state;
- CK_FLAGS flags; /* see below */
-
- /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulDeviceError; /* device-dependent error code */
-} CK_SESSION_INFO;
-
-/* The flags are defined in the following table:
- * Bit Flag Mask Meaning
- */
-#define CKF_RW_SESSION 0x00000002 /* session is r/w */
-#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
-
-typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-
-
-/* CK_OBJECT_HANDLE is a token-specific identifier for an
- * object */
-typedef CK_ULONG CK_OBJECT_HANDLE;
-
-typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-
-
-/* CK_OBJECT_CLASS is a value that identifies the classes (or
- * types) of objects that PKCS #11 recognizes. It is defined
- * as follows: */
-/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_OBJECT_CLASS;
-
-/* The following classes of objects are defined: */
-#define CKO_DATA 0x00000000
-#define CKO_CERTIFICATE 0x00000001
-#define CKO_PUBLIC_KEY 0x00000002
-#define CKO_PRIVATE_KEY 0x00000003
-#define CKO_SECRET_KEY 0x00000004
-#define CKO_VENDOR_DEFINED 0x80000000
-
-typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-
-
-/* CK_KEY_TYPE is a value that identifies a key type */
-/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_KEY_TYPE;
-
-/* the following key types are defined: */
-#define CKK_RSA 0x00000000
-#define CKK_DSA 0x00000001
-#define CKK_DH 0x00000002
-
-/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-
-/* PKCS #11 V2.01 probably won't actually have ECDSA in it */
-#define CKK_ECDSA 0x00000003
-
-#define CKK_KEA 0x00000005
-
-#define CKK_GENERIC_SECRET 0x00000010
-#define CKK_RC2 0x00000011
-#define CKK_RC4 0x00000012
-#define CKK_DES 0x00000013
-#define CKK_DES2 0x00000014
-#define CKK_DES3 0x00000015
-
-/* all these key types are new for v2.0 */
-#define CKK_CAST 0x00000016
-#define CKK_CAST3 0x00000017
-#define CKK_CAST5 0x00000018
-#define CKK_CAST128 0x00000018 /* CAST128=CAST5 */
-#define CKK_RC5 0x00000019
-#define CKK_IDEA 0x0000001A
-#define CKK_SKIPJACK 0x0000001B
-#define CKK_BATON 0x0000001C
-#define CKK_JUNIPER 0x0000001D
-#define CKK_CDMF 0x0000001E
-
-#define CKK_VENDOR_DEFINED 0x80000000
-
-
-/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
- * type */
-/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_CERTIFICATE_TYPE;
-
-/* The following certificate types are defined: */
-#define CKC_X_509 0x00000000
-#define CKC_VENDOR_DEFINED 0x80000000
-
-
-/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
- * type */
-/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_ATTRIBUTE_TYPE;
-
-/* The following attribute types are defined: */
-#define CKA_CLASS 0x00000000
-#define CKA_TOKEN 0x00000001
-#define CKA_PRIVATE 0x00000002
-#define CKA_LABEL 0x00000003
-#define CKA_APPLICATION 0x00000010
-#define CKA_VALUE 0x00000011
-#define CKA_CERTIFICATE_TYPE 0x00000080
-#define CKA_ISSUER 0x00000081
-#define CKA_SERIAL_NUMBER 0x00000082
-#define CKA_KEY_TYPE 0x00000100
-#define CKA_SUBJECT 0x00000101
-#define CKA_ID 0x00000102
-#define CKA_SENSITIVE 0x00000103
-#define CKA_ENCRYPT 0x00000104
-#define CKA_DECRYPT 0x00000105
-#define CKA_WRAP 0x00000106
-#define CKA_UNWRAP 0x00000107
-#define CKA_SIGN 0x00000108
-#define CKA_SIGN_RECOVER 0x00000109
-#define CKA_VERIFY 0x0000010A
-#define CKA_VERIFY_RECOVER 0x0000010B
-#define CKA_DERIVE 0x0000010C
-#define CKA_START_DATE 0x00000110
-#define CKA_END_DATE 0x00000111
-#define CKA_MODULUS 0x00000120
-#define CKA_MODULUS_BITS 0x00000121
-#define CKA_PUBLIC_EXPONENT 0x00000122
-#define CKA_PRIVATE_EXPONENT 0x00000123
-#define CKA_PRIME_1 0x00000124
-#define CKA_PRIME_2 0x00000125
-#define CKA_EXPONENT_1 0x00000126
-#define CKA_EXPONENT_2 0x00000127
-#define CKA_COEFFICIENT 0x00000128
-#define CKA_PRIME 0x00000130
-#define CKA_SUBPRIME 0x00000131
-#define CKA_BASE 0x00000132
-#define CKA_VALUE_BITS 0x00000160
-#define CKA_VALUE_LEN 0x00000161
-
-/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, and CKA_MODIFIABLE are new for v2.0 */
-#define CKA_EXTRACTABLE 0x00000162
-#define CKA_LOCAL 0x00000163
-#define CKA_NEVER_EXTRACTABLE 0x00000164
-#define CKA_ALWAYS_SENSITIVE 0x00000165
-#define CKA_MODIFIABLE 0x00000170
-
-#define CKA_VENDOR_DEFINED 0x80000000
-
-
-/* CK_ATTRIBUTE is a structure that includes the type, length
- * and value of an attribute */
-typedef struct CK_ATTRIBUTE {
- CK_ATTRIBUTE_TYPE type;
- CK_VOID_PTR pValue;
-
- /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulValueLen; /* in bytes */
-} CK_ATTRIBUTE;
-
-typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-
-
-/* CK_DATE is a structure that defines a date */
-typedef struct CK_DATE{
- CK_CHAR year[4]; /* the year ("1900" - "9999") */
- CK_CHAR month[2]; /* the month ("01" - "12") */
- CK_CHAR day[2]; /* the day ("01" - "31") */
-} CK_DATE;
-
-
-/* CK_MECHANISM_TYPE is a value that identifies a mechanism
- * type */
-/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_MECHANISM_TYPE;
-
-/* the following mechanism types are defined: */
-#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
-#define CKM_RSA_PKCS 0x00000001
-#define CKM_RSA_9796 0x00000002
-#define CKM_RSA_X_509 0x00000003
-
-/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
- * are new for v2.0. They are mechanisms which hash and sign */
-#define CKM_MD2_RSA_PKCS 0x00000004
-#define CKM_MD5_RSA_PKCS 0x00000005
-#define CKM_SHA1_RSA_PKCS 0x00000006
-
-#define CKM_DSA_KEY_PAIR_GEN 0x00000010
-#define CKM_DSA 0x00000011
-#define CKM_DSA_SHA1 0x00000012
-#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
-#define CKM_DH_PKCS_DERIVE 0x00000021
-#define CKM_RC2_KEY_GEN 0x00000100
-#define CKM_RC2_ECB 0x00000101
-#define CKM_RC2_CBC 0x00000102
-#define CKM_RC2_MAC 0x00000103
-
-/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-#define CKM_RC2_MAC_GENERAL 0x00000104
-#define CKM_RC2_CBC_PAD 0x00000105
-
-#define CKM_RC4_KEY_GEN 0x00000110
-#define CKM_RC4 0x00000111
-#define CKM_DES_KEY_GEN 0x00000120
-#define CKM_DES_ECB 0x00000121
-#define CKM_DES_CBC 0x00000122
-#define CKM_DES_MAC 0x00000123
-
-/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-#define CKM_DES_MAC_GENERAL 0x00000124
-#define CKM_DES_CBC_PAD 0x00000125
-
-#define CKM_DES2_KEY_GEN 0x00000130
-#define CKM_DES3_KEY_GEN 0x00000131
-#define CKM_DES3_ECB 0x00000132
-#define CKM_DES3_CBC 0x00000133
-#define CKM_DES3_MAC 0x00000134
-
-/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
- * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
- * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-#define CKM_DES3_MAC_GENERAL 0x00000135
-#define CKM_DES3_CBC_PAD 0x00000136
-#define CKM_CDMF_KEY_GEN 0x00000140
-#define CKM_CDMF_ECB 0x00000141
-#define CKM_CDMF_CBC 0x00000142
-#define CKM_CDMF_MAC 0x00000143
-#define CKM_CDMF_MAC_GENERAL 0x00000144
-#define CKM_CDMF_CBC_PAD 0x00000145
-
-#define CKM_MD2 0x00000200
-
-/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD2_HMAC 0x00000201
-#define CKM_MD2_HMAC_GENERAL 0x00000202
-
-#define CKM_MD5 0x00000210
-
-/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD5_HMAC 0x00000211
-#define CKM_MD5_HMAC_GENERAL 0x00000212
-
-#define CKM_SHA_1 0x00000220
-
-/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-#define CKM_SHA_1_HMAC 0x00000221
-#define CKM_SHA_1_HMAC_GENERAL 0x00000222
-
-/* All of the following mechanisms are new for v2.0 */
-/* Note that CAST128 and CAST5 are the same algorithm */
-#define CKM_CAST_KEY_GEN 0x00000300
-#define CKM_CAST_ECB 0x00000301
-#define CKM_CAST_CBC 0x00000302
-#define CKM_CAST_MAC 0x00000303
-#define CKM_CAST_MAC_GENERAL 0x00000304
-#define CKM_CAST_CBC_PAD 0x00000305
-#define CKM_CAST3_KEY_GEN 0x00000310
-#define CKM_CAST3_ECB 0x00000311
-#define CKM_CAST3_CBC 0x00000312
-#define CKM_CAST3_MAC 0x00000313
-#define CKM_CAST3_MAC_GENERAL 0x00000314
-#define CKM_CAST3_CBC_PAD 0x00000315
-#define CKM_CAST5_KEY_GEN 0x00000320
-#define CKM_CAST128_KEY_GEN 0x00000320
-#define CKM_CAST5_ECB 0x00000321
-#define CKM_CAST128_ECB 0x00000321
-#define CKM_CAST5_CBC 0x00000322
-#define CKM_CAST128_CBC 0x00000322
-#define CKM_CAST5_MAC 0x00000323
-#define CKM_CAST128_MAC 0x00000323
-#define CKM_CAST5_MAC_GENERAL 0x00000324
-#define CKM_CAST128_MAC_GENERAL 0x00000324
-#define CKM_CAST5_CBC_PAD 0x00000325
-#define CKM_CAST128_CBC_PAD 0x00000325
-#define CKM_RC5_KEY_GEN 0x00000330
-#define CKM_RC5_ECB 0x00000331
-#define CKM_RC5_CBC 0x00000332
-#define CKM_RC5_MAC 0x00000333
-#define CKM_RC5_MAC_GENERAL 0x00000334
-#define CKM_RC5_CBC_PAD 0x00000335
-#define CKM_IDEA_KEY_GEN 0x00000340
-#define CKM_IDEA_ECB 0x00000341
-#define CKM_IDEA_CBC 0x00000342
-#define CKM_IDEA_MAC 0x00000343
-#define CKM_IDEA_MAC_GENERAL 0x00000344
-#define CKM_IDEA_CBC_PAD 0x00000345
-#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
-#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
-#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
-#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
-#define CKM_XOR_BASE_AND_DATA 0x00000364
-#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
-#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
-#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
-#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
-#define CKM_SSL3_MD5_MAC 0x00000380
-#define CKM_SSL3_SHA1_MAC 0x00000381
-#define CKM_MD5_KEY_DERIVATION 0x00000390
-#define CKM_MD2_KEY_DERIVATION 0x00000391
-#define CKM_SHA1_KEY_DERIVATION 0x00000392
-#define CKM_PBE_MD2_DES_CBC 0x000003A0
-#define CKM_PBE_MD5_DES_CBC 0x000003A1
-#define CKM_PBE_MD5_CAST_CBC 0x000003A2
-#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
-#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
-#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
-#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
-#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
-#define CKM_PBE_SHA1_RC4_128 0x000003A6
-#define CKM_PBE_SHA1_RC4_40 0x000003A7
-#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
-#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
-#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
-#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
-#define CKM_KEY_WRAP_LYNKS 0x00000400
-#define CKM_KEY_WRAP_SET_OAEP 0x00000401
-
-/* Fortezza mechanisms */
-#define CKM_SKIPJACK_KEY_GEN 0x00001000
-#define CKM_SKIPJACK_ECB64 0x00001001
-#define CKM_SKIPJACK_CBC64 0x00001002
-#define CKM_SKIPJACK_OFB64 0x00001003
-#define CKM_SKIPJACK_CFB64 0x00001004
-#define CKM_SKIPJACK_CFB32 0x00001005
-#define CKM_SKIPJACK_CFB16 0x00001006
-#define CKM_SKIPJACK_CFB8 0x00001007
-#define CKM_SKIPJACK_WRAP 0x00001008
-#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
-#define CKM_SKIPJACK_RELAYX 0x0000100a
-#define CKM_KEA_KEY_PAIR_GEN 0x00001010
-#define CKM_KEA_KEY_DERIVE 0x00001011
-#define CKM_FORTEZZA_TIMESTAMP 0x00001020
-#define CKM_BATON_KEY_GEN 0x00001030
-#define CKM_BATON_ECB128 0x00001031
-#define CKM_BATON_ECB96 0x00001032
-#define CKM_BATON_CBC128 0x00001033
-#define CKM_BATON_COUNTER 0x00001034
-#define CKM_BATON_SHUFFLE 0x00001035
-#define CKM_BATON_WRAP 0x00001036
-
-/* PKCS #11 V2.01 probably won't actually have ECDSA in it */
-#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
-#define CKM_ECDSA 0x00001041
-#define CKM_ECDSA_SHA1 0x00001042
-
-#define CKM_JUNIPER_KEY_GEN 0x00001060
-#define CKM_JUNIPER_ECB128 0x00001061
-#define CKM_JUNIPER_CBC128 0x00001062
-#define CKM_JUNIPER_COUNTER 0x00001063
-#define CKM_JUNIPER_SHUFFLE 0x00001064
-#define CKM_JUNIPER_WRAP 0x00001065
-#define CKM_FASTHASH 0x00001070
-
-#define CKM_VENDOR_DEFINED 0x80000000
-
-typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-
-
-/* CK_MECHANISM is a structure that specifies a particular
- * mechanism */
-typedef struct CK_MECHANISM {
- CK_MECHANISM_TYPE mechanism;
- CK_VOID_PTR pParameter;
-
- /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulParameterLen; /* in bytes */
-} CK_MECHANISM;
-
-typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-
-
-/* CK_MECHANISM_INFO provides information about a particular
- * mechanism */
-typedef struct CK_MECHANISM_INFO {
- CK_ULONG ulMinKeySize;
- CK_ULONG ulMaxKeySize;
- CK_FLAGS flags;
-} CK_MECHANISM_INFO;
-
-/* The flags are defined as follows:
- * Bit Flag Mask Meaning */
-#define CKF_HW 0x00000001 /* performed by HW */
-
-/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
- * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
- * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
- * and CKF_DERIVE are new for v2.0. They specify whether or not
- * a mechanism can be used for a particular task */
-#define CKF_ENCRYPT 0x00000100
-#define CKF_DECRYPT 0x00000200
-#define CKF_DIGEST 0x00000400
-#define CKF_SIGN 0x00000800
-#define CKF_SIGN_RECOVER 0x00001000
-#define CKF_VERIFY 0x00002000
-#define CKF_VERIFY_RECOVER 0x00004000
-#define CKF_GENERATE 0x00008000
-#define CKF_GENERATE_KEY_PAIR 0x00010000
-#define CKF_WRAP 0x00020000
-#define CKF_UNWRAP 0x00040000
-#define CKF_DERIVE 0x00080000
-
-#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
-
-typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-
-
-/* CK_RV is a value that identifies the return value of a
- * PKCS #11 function */
-/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_RV;
-
-#define CKR_OK 0x00000000
-#define CKR_CANCEL 0x00000001
-#define CKR_HOST_MEMORY 0x00000002
-#define CKR_SLOT_ID_INVALID 0x00000003
-
-/* CKR_FLAGS_INVALID was removed for v2.0 */
-
-/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-#define CKR_GENERAL_ERROR 0x00000005
-#define CKR_FUNCTION_FAILED 0x00000006
-
-/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
- * and CKR_CANT_LOCK are new for v2.01 */
-#define CKR_ARGUMENTS_BAD 0x00000007
-#define CKR_NO_EVENT 0x00000008
-#define CKR_NEED_TO_CREATE_THREADS 0x00000009
-#define CKR_CANT_LOCK 0x0000000A
-
-#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
-#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
-#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
-#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
-#define CKR_DATA_INVALID 0x00000020
-#define CKR_DATA_LEN_RANGE 0x00000021
-#define CKR_DEVICE_ERROR 0x00000030
-#define CKR_DEVICE_MEMORY 0x00000031
-#define CKR_DEVICE_REMOVED 0x00000032
-#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
-#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
-#define CKR_FUNCTION_CANCELED 0x00000050
-#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
-
-/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
-
-#define CKR_KEY_HANDLE_INVALID 0x00000060
-
-/* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-#define CKR_KEY_SIZE_RANGE 0x00000062
-#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
-
-/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
- * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
- * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
- * v2.0 */
-#define CKR_KEY_NOT_NEEDED 0x00000064
-#define CKR_KEY_CHANGED 0x00000065
-#define CKR_KEY_NEEDED 0x00000066
-#define CKR_KEY_INDIGESTIBLE 0x00000067
-#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
-#define CKR_KEY_NOT_WRAPPABLE 0x00000069
-#define CKR_KEY_UNEXTRACTABLE 0x0000006A
-
-#define CKR_MECHANISM_INVALID 0x00000070
-#define CKR_MECHANISM_PARAM_INVALID 0x00000071
-
-/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
- * were removed for v2.0 */
-#define CKR_OBJECT_HANDLE_INVALID 0x00000082
-#define CKR_OPERATION_ACTIVE 0x00000090
-#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
-#define CKR_PIN_INCORRECT 0x000000A0
-#define CKR_PIN_INVALID 0x000000A1
-#define CKR_PIN_LEN_RANGE 0x000000A2
-
-/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-#define CKR_PIN_EXPIRED 0x000000A3
-#define CKR_PIN_LOCKED 0x000000A4
-
-#define CKR_SESSION_CLOSED 0x000000B0
-#define CKR_SESSION_COUNT 0x000000B1
-#define CKR_SESSION_HANDLE_INVALID 0x000000B3
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
-#define CKR_SESSION_READ_ONLY 0x000000B5
-#define CKR_SESSION_EXISTS 0x000000B6
-
-/* CKR_SESSION_READ_ONLY_EXISTS and
- * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
-#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
-
-#define CKR_SIGNATURE_INVALID 0x000000C0
-#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
-#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
-#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
-#define CKR_TOKEN_NOT_PRESENT 0x000000E0
-#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
-#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
-#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
-#define CKR_USER_NOT_LOGGED_IN 0x00000101
-#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
-#define CKR_USER_TYPE_INVALID 0x00000103
-
-/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
- * are new to v2.01 */
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
-#define CKR_USER_TOO_MANY_TYPES 0x00000105
-
-#define CKR_WRAPPED_KEY_INVALID 0x00000110
-#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
-#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
-#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
-#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-
-/* These are new to v2.0 */
-#define CKR_RANDOM_NO_RNG 0x00000121
-#define CKR_BUFFER_TOO_SMALL 0x00000150
-#define CKR_SAVED_STATE_INVALID 0x00000160
-#define CKR_INFORMATION_SENSITIVE 0x00000170
-#define CKR_STATE_UNSAVEABLE 0x00000180
-
-/* These are new to v2.01 */
-#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
-#define CKR_MUTEX_BAD 0x000001A0
-#define CKR_MUTEX_NOT_LOCKED 0x000001A1
-
-#define CKR_VENDOR_DEFINED 0x80000000
-
-
-/* CK_NOTIFY is an application callback that processes events */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_NOTIFICATION event,
- CK_VOID_PTR pApplication /* passed to C_OpenSession */
-);
-
-
-/* CK_FUNCTION_LIST is a structure holding a PKCS #11 spec
- * version and pointers of appropriate types to all the
- * PKCS #11 functions */
-/* CK_FUNCTION_LIST is new for v2.0 */
-typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-
-typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-
-typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-
-
-/* CK_CREATEMUTEX is an application callback for creating a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
- CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
-);
-
-
-/* CK_DESTROYMUTEX is an application callback for destroying a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_LOCKMUTEX is an application callback for locking a mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_UNLOCKMUTEX is an application callback for unlocking a
- * mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_C_INITIALIZE_ARGS provides the optional arguments to
- * C_Initialize */
-typedef struct CK_C_INITIALIZE_ARGS {
- CK_CREATEMUTEX CreateMutex;
- CK_DESTROYMUTEX DestroyMutex;
- CK_LOCKMUTEX LockMutex;
- CK_UNLOCKMUTEX UnlockMutex;
- CK_FLAGS flags;
- CK_VOID_PTR pReserved;
-} CK_C_INITIALIZE_ARGS;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-#define CKF_OS_LOCKING_OK 0x00000002
-
-typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-
-
-/* additional flags for parameters to functions */
-
-/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-#define CKF_DONT_BLOCK 1
-
-
-/* CK_KEA_DERIVE_PARAMS provides the parameters to the
- * CKM_KEA_DERIVE mechanism */
-/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-typedef struct CK_KEA_DERIVE_PARAMS {
- CK_BBOOL isSender;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pRandomB;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_KEA_DERIVE_PARAMS;
-
-typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-
-
-/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
- * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
- * holds the effective keysize */
-typedef CK_ULONG CK_RC2_PARAMS;
-
-typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-
-
-/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
- * mechanism */
-typedef struct CK_RC2_CBC_PARAMS {
- /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
-
- CK_BYTE iv[8]; /* IV for CBC mode */
-} CK_RC2_CBC_PARAMS;
-
-typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-
-
-/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC2_MAC_GENERAL mechanism */
-/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC2_MAC_GENERAL_PARAMS {
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC2_MAC_GENERAL_PARAMS;
-
-typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC2_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
- * CKM_RC5_MAC mechanisms */
-/* CK_RC5_PARAMS is new for v2.0 */
-typedef struct CK_RC5_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
-} CK_RC5_PARAMS;
-
-typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-
-
-/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
- * mechanism */
-/* CK_RC5_CBC_PARAMS is new for v2.0 */
-typedef struct CK_RC5_CBC_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_BYTE_PTR pIv; /* pointer to IV */
- CK_ULONG ulIvLen; /* length of IV in bytes */
-} CK_RC5_CBC_PARAMS;
-
-typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-
-
-/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC5_MAC_GENERAL mechanism */
-/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC5_MAC_GENERAL_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC5_MAC_GENERAL_PARAMS;
-
-typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC5_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
- * ciphers' MAC_GENERAL mechanisms. Its value is the length of
- * the MAC */
-/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
-
-typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
- * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
- CK_ULONG ulPasswordLen;
- CK_BYTE_PTR pPassword;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPAndGLen;
- CK_ULONG ulQLen;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pPrimeP;
- CK_BYTE_PTR pBaseG;
- CK_BYTE_PTR pSubprimeQ;
-} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-
-typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
- CK_SKIPJACK_PRIVATE_WRAP_PTR;
-
-
-/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
- * CKM_SKIPJACK_RELAYX mechanism */
-/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_RELAYX_PARAMS {
- CK_ULONG ulOldWrappedXLen;
- CK_BYTE_PTR pOldWrappedX;
- CK_ULONG ulOldPasswordLen;
- CK_BYTE_PTR pOldPassword;
- CK_ULONG ulOldPublicDataLen;
- CK_BYTE_PTR pOldPublicData;
- CK_ULONG ulOldRandomLen;
- CK_BYTE_PTR pOldRandomA;
- CK_ULONG ulNewPasswordLen;
- CK_BYTE_PTR pNewPassword;
- CK_ULONG ulNewPublicDataLen;
- CK_BYTE_PTR pNewPublicData;
- CK_ULONG ulNewRandomLen;
- CK_BYTE_PTR pNewRandomA;
-} CK_SKIPJACK_RELAYX_PARAMS;
-
-typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
- CK_SKIPJACK_RELAYX_PARAMS_PTR;
-
-
-typedef struct CK_PBE_PARAMS {
- CK_CHAR_PTR pInitVector;
- CK_CHAR_PTR pPassword;
- CK_ULONG ulPasswordLen;
- CK_CHAR_PTR pSalt;
- CK_ULONG ulSaltLen;
- CK_ULONG ulIteration;
-} CK_PBE_PARAMS;
-
-typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-
-
-/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
- * CKM_KEY_WRAP_SET_OAEP mechanism */
-/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
- CK_BYTE bBC; /* block contents byte */
- CK_BYTE_PTR pX; /* extra data */
- CK_ULONG ulXLen; /* length of extra data in bytes */
-} CK_KEY_WRAP_SET_OAEP_PARAMS;
-
-typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
- CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_RANDOM_DATA {
- CK_BYTE_PTR pClientRandom;
- CK_ULONG ulClientRandomLen;
- CK_BYTE_PTR pServerRandom;
- CK_ULONG ulServerRandomLen;
-} CK_SSL3_RANDOM_DATA;
-
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_VERSION_PTR pVersion;
-} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_OUT {
- CK_OBJECT_HANDLE hClientMacSecret;
- CK_OBJECT_HANDLE hServerMacSecret;
- CK_OBJECT_HANDLE hClientKey;
- CK_OBJECT_HANDLE hServerKey;
- CK_BYTE_PTR pIVClient;
- CK_BYTE_PTR pIVServer;
-} CK_SSL3_KEY_MAT_OUT;
-
-typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_PARAMS {
- CK_ULONG ulMacSizeInBits;
- CK_ULONG ulKeySizeInBits;
- CK_ULONG ulIVSizeInBits;
- CK_BBOOL bIsExport;
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_SSL3_KEY_MAT_PARAMS;
-
-typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-
-
-typedef struct CK_KEY_DERIVATION_STRING_DATA {
- CK_BYTE_PTR pData;
- CK_ULONG ulLen;
-} CK_KEY_DERIVATION_STRING_DATA;
-
-typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
- CK_KEY_DERIVATION_STRING_DATA_PTR;
-
-
-/* The CK_EXTRACT_PARAMS is used for the
- * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
- * of the base key should be used as the first bit of the
- * derived key */
-/* CK_EXTRACT_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_EXTRACT_PARAMS;
-
-typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-
-/* Do not attempt to use these. They are only used by NETSCAPE's internal
- * PKCS #11 interface. Most of these are place holders for other mechanism
- * and will change in the future.
- */
-#define CKM_NETSCAPE_PBE_KEY_GEN 0x80000001L
-#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L
-#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
-#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
-#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
-#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
-#define CKM_TLS_PRF_GENERAL 0x80000373L
-
-/* define used to pass in the database key for DSA private keys */
-#define CKA_NETSCAPE_DB 0xD5A0DB00L
-#define CKA_NETSCAPE_TRUST 0x80000001L
-
-/* undo packing */
-#include "pkcs11u.h"
-
-#endif
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
deleted file mode 100644
index fdb03a543..000000000
--- a/security/nss/lib/softoken/pkcs11u.c
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * Internal PKCS #11 functions. Should only be called by pkcs11.c
- */
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "key.h"
-#include "certdb.h"
-
-
-/* declare the internal pkcs11 slot structures:
- * There are threee:
- * slot 0 is the generic crypto service token.
- * slot 1 is the Database service token.
- * slot 2 is the FIPS token (both generic and database).
- */
-static PK11Slot pk11_slot[3];
-
-/*
- * ******************** Attribute Utilities *******************************
- */
-
-/*
- * create a new attribute with type, value, and length. Space is allocated
- * to hold value.
- */
-static PK11Attribute *
-pk11_NewAttribute(PK11Object *object,
- CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value, CK_ULONG len)
-{
- PK11Attribute *attribute;
-
-#ifdef NO_ARENA
- int index;
- /*
- * NO_ARENA attempts to keep down contention on Malloc and Arena locks
- * by limiting the number of these calls on high traversed paths. this
- * is done for attributes by 'allocating' them from a pool already allocated
- * by the parent object.
- */
- PK11_USE_THREADS(PR_Lock(object->attributeLock);)
- index = object->nextAttr++;
- PK11_USE_THREADS(PR_Unlock(object->attributeLock);)
- PORT_Assert(index < MAX_OBJS_ATTRS);
- if (index >= MAX_OBJS_ATTRS) return NULL;
-
- attribute = &object->attrList[index];
- attribute->attrib.type = type;
- if (value) {
- if (len <= ATTR_SPACE) {
- attribute->attrib.pValue = attribute->space;
- } else {
- attribute->attrib.pValue = PORT_Alloc(len);
- }
- if (attribute->attrib.pValue == NULL) {
- return NULL;
- }
- PORT_Memcpy(attribute->attrib.pValue,value,len);
- attribute->attrib.ulValueLen = len;
- } else {
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
-#else
-#ifdef REF_COUNT_ATTRIBUTE
- attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
-#else
- attribute = (PK11Attribute*)PORT_ArenaAlloc(object->arena,sizeof(PK11Attribute));
-#endif /* REF_COUNT_ATTRIBUTE */
- if (attribute == NULL) return NULL;
-
- if (value) {
-#ifdef REF_COUNT_ATTRIBUTE
- attribute->attrib.pValue = PORT_Alloc(len);
-#else
- attribute->attrib.pValue = PORT_ArenaAlloc(object->arena,len);
-#endif /* REF_COUNT_ATTRIBUTE */
- if (attribute->attrib.pValue == NULL) {
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Free(attribute);
-#endif /* REF_COUNT_ATTRIBUTE */
- return NULL;
- }
- PORT_Memcpy(attribute->attrib.pValue,value,len);
- attribute->attrib.ulValueLen = len;
- } else {
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
-#endif /* NO_ARENA */
- attribute->attrib.type = type;
- attribute->handle = type;
- attribute->next = attribute->prev = NULL;
-#ifdef REF_COUNT_ATTRIBUTE
- attribute->refCount = 1;
-#ifdef PKCS11_USE_THREADS
- attribute->refLock = PR_NewLock();
- if (attribute->refLock == NULL) {
- if (attribute->attrib.pValue) PORT_Free(attribute->attrib.pValue);
- PORT_Free(attribute);
- return NULL;
- }
-#else
- attribute->refLock = NULL;
-#endif
-#endif /* REF_COUNT_ATTRIBUTE */
- return attribute;
-}
-
-/*
- * Free up all the memory associated with an attribute. Reference count
- * must be zero to call this.
- */
-static void
-pk11_DestroyAttribute(PK11Attribute *attribute)
-{
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Assert(attribute->refCount == 0);
- PK11_USE_THREADS(PR_DestroyLock(attribute->refLock);)
- if (attribute->attrib.pValue) {
- /* clear out the data in the attribute value... it may have been
- * sensitive data */
- PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
- PORT_Free(attribute->attrib.pValue);
- }
- PORT_Free(attribute);
-#endif
-}
-
-
-/*
- * look up and attribute structure from a type and Object structure.
- * The returned attribute is referenced and needs to be freed when
- * it is no longer needed.
- */
-PK11Attribute *
-pk11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
-{
- PK11Attribute *attribute;
-
- PK11_USE_THREADS(PR_Lock(object->attributeLock);)
- pk11queue_find(attribute,type,object->head,ATTRIBUTE_HASH_SIZE);
-#ifdef REF_COUNT_ATTRIBUTE
- if (attribute) {
- /* atomic increment would be nice here */
- PK11_USE_THREADS(PR_Lock(attribute->refLock);)
- attribute->refCount++;
- PK11_USE_THREADS(PR_Unlock(attribute->refLock);)
- }
-#endif
- PK11_USE_THREADS(PR_Unlock(object->attributeLock);)
-
- return(attribute);
-}
-
-
-/*
- * release a reference to an attribute structure
- */
-void
-pk11_FreeAttribute(PK11Attribute *attribute)
-{
-#ifdef REF_COUNT_ATTRIBUTE
- PRBool destroy = PR_FALSE;
-
- PK11_USE_THREADS(PR_Lock(attribute->refLock);)
- if (attribute->refCount == 1) destroy = PR_TRUE;
- attribute->refCount--;
- PK11_USE_THREADS(PR_Unlock(attribute->refLock);)
-
- if (destroy) pk11_DestroyAttribute(attribute);
-#endif
-}
-
-
-/*
- * return true if object has attribute
- */
-PRBool
-pk11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
-{
- PK11Attribute *attribute;
-
- PK11_USE_THREADS(PR_Lock(object->attributeLock);)
- pk11queue_find(attribute,type,object->head,ATTRIBUTE_HASH_SIZE);
- PK11_USE_THREADS(PR_Unlock(object->attributeLock);)
-
- return (PRBool)(attribute != NULL);
-}
-
-/*
- * add an attribute to an object
- */
-static
-void pk11_AddAttribute(PK11Object *object,PK11Attribute *attribute)
-{
- PK11_USE_THREADS(PR_Lock(object->attributeLock);)
- pk11queue_add(attribute,attribute->handle,object->head,ATTRIBUTE_HASH_SIZE);
- PK11_USE_THREADS(PR_Unlock(object->attributeLock);)
-}
-
-/*
- * copy an unsigned attribute into a 'signed' SECItem. Secitem is allocated in
- * the specified arena.
- */
-CK_RV
-pk11_Attribute2SSecItem(PLArenaPool *arena,SECItem *item,PK11Object *object,
- CK_ATTRIBUTE_TYPE type)
-{
- int len;
- PK11Attribute *attribute;
- unsigned char *start;
- int real_len;
-
- attribute = pk11_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- real_len = len = attribute->attrib.ulValueLen;
- if ((*((unsigned char *)attribute->attrib.pValue) & 0x80) != 0) {
- real_len++;
- }
-
- if (arena) {
- start = item->data = (unsigned char *) PORT_ArenaAlloc(arena,real_len);
- } else {
- start = item->data = (unsigned char *) PORT_Alloc(real_len);
- }
- if (item->data == NULL) {
- pk11_FreeAttribute(attribute);
- return CKR_HOST_MEMORY;
- }
- item->len = real_len;
- if (real_len != len) {
- *start = 0;
- start++;
- }
- PORT_Memcpy(start, attribute->attrib.pValue, len);
- pk11_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-
-/*
- * delete an attribute from an object
- */
-static void
-pk11_DeleteAttribute(PK11Object *object, PK11Attribute *attribute)
-{
- PK11_USE_THREADS(PR_Lock(object->attributeLock);)
- if (pk11queue_is_queued(attribute,attribute->handle,
- object->head,ATTRIBUTE_HASH_SIZE)) {
- pk11queue_delete(attribute,attribute->handle,
- object->head,ATTRIBUTE_HASH_SIZE);
- }
- PK11_USE_THREADS(PR_Unlock(object->attributeLock);)
- pk11_FreeAttribute(attribute);
-}
-
-/*
- * this is only valid for CK_BBOOL type attributes. Return the state
- * of that attribute.
- */
-PRBool
-pk11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type)
-{
- PK11Attribute *attribute;
- PRBool tok = PR_FALSE;
-
- attribute=pk11_FindAttribute(object,type);
- if (attribute == NULL) { return PR_FALSE; }
- tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
- pk11_FreeAttribute(attribute);
-
- return tok;
-}
-
-/*
- * force an attribute to null.
- * this is for sensitive keys which are stored in the database, we don't
- * want to keep this info around in memory in the clear.
- */
-void
-pk11_nullAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
-{
- PK11Attribute *attribute;
-
- attribute=pk11_FindAttribute(object,type);
- if (attribute == NULL) return;
-
- if (attribute->attrib.pValue != NULL) {
- PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Free(attribute->attrib.pValue);
-#endif /* REF_COUNT_ATTRIBUTE */
-#ifdef NO_ARENA
- if (attribute->attrib.pValue != attribute->space) {
- PORT_Free(attribute->attrib.pValue);
- }
-#endif /* NO_ARENA */
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- pk11_FreeAttribute(attribute);
-}
-
-/*
- * force an attribute to a spaecif value.
- */
-CK_RV
-pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
- unsigned int len)
-{
- PK11Attribute *attribute;
- void *att_val = NULL;
-
- attribute=pk11_FindAttribute(object,type);
- if (attribute == NULL) return pk11_AddAttributeType(object,type,value,len);
-
-
- if (value) {
-#ifdef NO_ARENA
- if (len <= ATTR_SPACE) {
- att_val = attribute->space;
- } else {
- att_val = PORT_Alloc(len);
- }
-#else
-#ifdef REF_COUNT_ATTRIBUTE
- att_val = PORT_Alloc(len);
-#else
- att_val = PORT_ArenaAlloc(object->arena,len);
-#endif /* REF_COUNT_ATTRIBUTE */
-#endif /* NO_ARENA */
- if (att_val == NULL) {
- return CKR_HOST_MEMORY;
- }
- if (attribute->attrib.pValue == att_val) {
- PORT_Memset(attribute->attrib.pValue,0,
- attribute->attrib.ulValueLen);
- }
- PORT_Memcpy(att_val,value,len);
- }
- if (attribute->attrib.pValue != NULL) {
- if (attribute->attrib.pValue != att_val) {
- PORT_Memset(attribute->attrib.pValue,0,
- attribute->attrib.ulValueLen);
- }
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Free(attribute->attrib.pValue);
-#endif /* REF_COUNT_ATTRIBUTE */
-#ifdef NO_ARENA
- if (attribute->attrib.pValue != attribute->space) {
- PORT_Free(attribute->attrib.pValue);
- }
-#endif /* NO_ARENA */
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- if (att_val) {
- attribute->attrib.pValue = att_val;
- attribute->attrib.ulValueLen = len;
- }
- return CKR_OK;
-}
-
-/*
- * return a null terminated string from attribute 'type'. This string
- * is allocated and needs to be freed with PORT_Free() When complete.
- */
-char *
-pk11_getString(PK11Object *object,CK_ATTRIBUTE_TYPE type)
-{
- PK11Attribute *attribute;
- char *label = NULL;
-
- attribute=pk11_FindAttribute(object,type);
- if (attribute == NULL) return NULL;
-
- if (attribute->attrib.pValue != NULL) {
- label = (char *) PORT_Alloc(attribute->attrib.ulValueLen+1);
- if (label == NULL) {
- pk11_FreeAttribute(attribute);
- return NULL;
- }
-
- PORT_Memcpy(label,attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- label[attribute->attrib.ulValueLen] = 0;
- }
- pk11_FreeAttribute(attribute);
- return label;
-}
-
-/*
- * decode when a particular attribute may be modified
- * PK11_NEVER: This attribute must be set at object creation time and
- * can never be modified.
- * PK11_ONCOPY: This attribute may be modified only when you copy the
- * object.
- * PK11_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
- * CK_FALSE to CK_TRUE.
- * PK11_ALWAYS: This attribute can always be modified.
- * Some attributes vary their modification type based on the class of the
- * object.
- */
-PK11ModifyType
-pk11_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
-{
- /* if we don't know about it, user user defined, always allow modify */
- PK11ModifyType mtype = PK11_ALWAYS;
-
- switch(type) {
- /* NEVER */
- case CKA_CLASS:
- case CKA_CERTIFICATE_TYPE:
- case CKA_KEY_TYPE:
- case CKA_MODULUS:
- case CKA_MODULUS_BITS:
- case CKA_PUBLIC_EXPONENT:
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME:
- case CKA_SUBPRIME:
- case CKA_BASE:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- case CKA_VALUE_LEN:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_NEVER_EXTRACTABLE:
- case CKA_NETSCAPE_DB:
- mtype = PK11_NEVER;
- break;
-
- /* ONCOPY */
- case CKA_TOKEN:
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- mtype = PK11_ONCOPY;
- break;
-
- /* SENSITIVE */
- case CKA_SENSITIVE:
- case CKA_EXTRACTABLE:
- mtype = PK11_SENSITIVE;
- break;
-
- /* ALWAYS */
- case CKA_LABEL:
- case CKA_APPLICATION:
- case CKA_ID:
- case CKA_SERIAL_NUMBER:
- case CKA_START_DATE:
- case CKA_END_DATE:
- case CKA_DERIVE:
- case CKA_ENCRYPT:
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_VERIFY:
- case CKA_SIGN_RECOVER:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- case CKA_UNWRAP:
- mtype = PK11_ALWAYS;
- break;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- mtype = (inClass == CKO_DATA) ? PK11_ALWAYS : PK11_NEVER;
- break;
-
- case CKA_SUBJECT:
- mtype = (inClass == CKO_CERTIFICATE) ? PK11_NEVER : PK11_ALWAYS;
- break;
- default:
- break;
- }
- return mtype;
-}
-
-/* decode if a particular attribute is sensitive (cannot be read
- * back to the user of if the object is set to SENSITIVE) */
-PRBool
-pk11_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
-{
- switch(type) {
- /* ALWAYS */
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- return PR_TRUE;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- /* PRIVATE and SECRET KEYS have SENSITIVE values */
- return (PRBool)((inClass == CKO_PRIVATE_KEY) || (inClass == CKO_SECRET_KEY));
-
- default:
- break;
- }
- return PR_FALSE;
-}
-
-/*
- * copy an attribute into a SECItem. Secitem is allocated in the specified
- * arena.
- */
-CK_RV
-pk11_Attribute2SecItem(PLArenaPool *arena,SECItem *item,PK11Object *object,
- CK_ATTRIBUTE_TYPE type)
-{
- int len;
- PK11Attribute *attribute;
-
- attribute = pk11_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- len = attribute->attrib.ulValueLen;
-
- if (arena) {
- item->data = (unsigned char *) PORT_ArenaAlloc(arena,len);
- } else {
- item->data = (unsigned char *) PORT_Alloc(len);
- }
- if (item->data == NULL) {
- pk11_FreeAttribute(attribute);
- return CKR_HOST_MEMORY;
- }
- item->len = len;
- PORT_Memcpy(item->data,attribute->attrib.pValue, len);
- pk11_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-void
-pk11_DeleteAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type)
-{
- PK11Attribute *attribute;
- attribute = pk11_FindAttribute(object, type);
- if (attribute == NULL) return ;
- pk11_DeleteAttribute(object,attribute);
- pk11_FreeAttribute(attribute);
-}
-
-CK_RV
-pk11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr,
- CK_ULONG length)
-{
- PK11Attribute *attribute;
- attribute = pk11_NewAttribute(object,type,valPtr,length);
- if (attribute == NULL) { return CKR_HOST_MEMORY; }
- pk11_AddAttribute(object,attribute);
- return CKR_OK;
-}
-
-/*
- * ******************** Object Utilities *******************************
- */
-
-/* allocation hooks that allow us to recycle old object structures */
-#ifdef MAX_OBJECT_LIST_SIZE
-static PK11Object * objectFreeList = NULL;
-static PRLock *objectLock = NULL;
-static int object_count = 0;
-#endif
-PK11Object *
-pk11_GetObjectFromList(PRBool *hasLocks) {
- PK11Object *object;
-
-#if MAX_OBJECT_LIST_SIZE
- if (objectLock == NULL) {
- objectLock = PR_NewLock();
- }
-
- PK11_USE_THREADS(PR_Lock(objectLock));
- object = objectFreeList;
- if (object) {
- objectFreeList = object->next;
- object_count--;
- }
- PK11_USE_THREADS(PR_Unlock(objectLock));
- if (object) {
- object->next = object->prev = NULL;
- *hasLocks = PR_TRUE;
- return object;
- }
-#endif
-
- object = (PK11Object*)PORT_ZAlloc(sizeof(PK11Object));
- *hasLocks = PR_FALSE;
- return object;
-}
-
-static void
-pk11_PutObjectToList(PK11Object *object) {
-#ifdef MAX_OBJECT_LIST_SIZE
- if (object_count < MAX_OBJECT_LIST_SIZE) {
- PK11_USE_THREADS(PR_Lock(objectLock));
- object->next = objectFreeList;
- objectFreeList = object;
- object_count++;
- PK11_USE_THREADS(PR_Unlock(objectLock));
- return;
- }
-#endif
- PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);)
- PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
- object->attributeLock = object->refLock = NULL;
- PORT_Free(object);
-}
-
-
-/*
- * Create a new object
- */
-PK11Object *
-pk11_NewObject(PK11Slot *slot)
-{
- PK11Object *object;
- PLArenaPool *arena;
- PRBool hasLocks = PR_FALSE;
- int i;
-
-
-#ifdef NO_ARENA
- object = pk11_GetObjectFromList(&hasLocks);
- if (object == NULL) {
- return NULL;
- }
- object->nextAttr = 0;
-#else
- arena = PORT_NewArena(2048);
- if (arena == NULL) return NULL;
-
- object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11Object));
- if (object == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- object->arena = arena;
-
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- object->attrList[i].attrib.pValue = NULL;
- }
-#endif
-
- object->handle = 0;
- object->next = object->prev = NULL;
- object->sessionList.next = NULL;
- object->sessionList.prev = NULL;
- object->sessionList.parent = object;
- object->inDB = PR_FALSE;
- object->label = NULL;
- object->refCount = 1;
- object->session = NULL;
- object->slot = slot;
- object->objclass = 0xffff;
- object->wasDerived = PR_FALSE;
-#ifdef PKCS11_USE_THREADS
- if (!hasLocks) object->refLock = PR_NewLock();
- if (object->refLock == NULL) {
-#ifdef NO_ARENA
- PORT_Free(object);
-#else
- PORT_FreeArena(arena,PR_FALSE);
-#endif
- return NULL;
- }
- if (!hasLocks) object->attributeLock = PR_NewLock();
- if (object->attributeLock == NULL) {
- PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
-#ifdef NO_ARENA
- PORT_Free(object);
-#else
- PORT_FreeArena(arena,PR_FALSE);
-#endif
- return NULL;
- }
-#else
- object->attributeLock = NULL;
- object->refLock = NULL;
-#endif
- for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- object->head[i] = NULL;
- }
- object->objectInfo = NULL;
- object->infoFree = NULL;
- return object;
-}
-
-/*
- * free all the data associated with an object. Object reference count must
- * be 'zero'.
- */
-static CK_RV
-pk11_DestroyObject(PK11Object *object)
-{
-#if defined(REF_COUNT_ATTRIBUTE) || defined(NO_ARENA)
- int i;
-#endif
- SECItem pubKey;
- CK_RV crv = CKR_OK;
- SECStatus rv;
- PLArenaPool *arena = NULL;
-
- PORT_Assert(object->refCount == 0);
-
- /* delete the database value */
- if (object->inDB) {
- if (pk11_isToken(object->handle)) {
- /* remove the objects from the real data base */
- switch (object->handle & PK11_TOKEN_TYPE_MASK) {
- case PK11_TOKEN_TYPE_PRIV:
- /* KEYID is the public KEY for DSA and DH, and the MODULUS for
- * RSA */
- crv=pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) break;
- rv = SECKEY_DeleteKey(SECKEY_GetDefaultKeyDB(), &pubKey);
- if (rv != SECSuccess) crv= CKR_DEVICE_ERROR;
- break;
- case PK11_TOKEN_TYPE_CERT:
- rv = SEC_DeletePermCertificate((CERTCertificate *)object->objectInfo);
- if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
- break;
- }
- }
- }
- if (object->label) PORT_Free(object->label);
-
- object->inDB = PR_FALSE;
- object->label = NULL;
-
-#ifdef NO_ARENA
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- unsigned char *value = object->attrList[i].attrib.pValue;
- if (value) {
- PORT_Memset(value,0,object->attrList[i].attrib.ulValueLen);
- if (value != object->attrList[i].space) {
- PORT_Free(value);
- }
- object->attrList[i].attrib.pValue = NULL;
- }
- }
-#endif
-
-#ifdef REF_COUNT_ATTRIBUTE
- /* clean out the attributes */
- /* since no one is referencing us, it's safe to walk the chain
- * without a lock */
- for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- PK11Attribute *ap,*next;
- for (ap = object->head[i]; ap != NULL; ap = next) {
- next = ap->next;
- /* paranoia */
- ap->next = ap->prev = NULL;
- pk11_FreeAttribute(ap);
- }
- object->head[i] = NULL;
- }
-#endif
- if (object->objectInfo) {
- (*object->infoFree)(object->objectInfo);
- }
-#ifdef NO_ARENA
- pk11_PutObjectToList(object);
-#else
- PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);)
- PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
- arena = object->arena;
- PORT_FreeArena(arena,PR_FALSE);
-#endif
- return crv;
-}
-
-void
-pk11_ReferenceObject(PK11Object *object)
-{
- PK11_USE_THREADS(PR_Lock(object->refLock);)
- object->refCount++;
- PK11_USE_THREADS(PR_Unlock(object->refLock);)
-}
-
-static PK11Object *
-pk11_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, PK11Slot *slot)
-{
- PK11Object **head;
- PRLock *lock;
- PK11Object *object;
-
- head = slot->tokObjects;
- lock = slot->objectLock;
-
- PK11_USE_THREADS(PR_Lock(lock);)
- pk11queue_find(object,handle,head,TOKEN_OBJECT_HASH_SIZE);
- if (object) {
- pk11_ReferenceObject(object);
- }
- PK11_USE_THREADS(PR_Unlock(lock);)
-
- return(object);
-}
-/*
- * look up and object structure from a handle. OBJECT_Handles only make
- * sense in terms of a given session. make a reference to that object
- * structure returned.
- */
-PK11Object *
-pk11_ObjectFromHandle(CK_OBJECT_HANDLE handle, PK11Session *session)
-{
- PK11Slot *slot = pk11_SlotFromSession(session);
-
- return pk11_ObjectFromHandleOnSlot(handle,slot);
-}
-
-
-/*
- * release a reference to an object handle
- */
-PK11FreeStatus
-pk11_FreeObject(PK11Object *object)
-{
- PRBool destroy = PR_FALSE;
- CK_RV crv;
-
- PK11_USE_THREADS(PR_Lock(object->refLock);)
- if (object->refCount == 1) destroy = PR_TRUE;
- object->refCount--;
- PK11_USE_THREADS(PR_Unlock(object->refLock);)
-
- if (destroy) {
- crv = pk11_DestroyObject(object);
- if (crv != CKR_OK) {
- return PK11_DestroyFailure;
- }
- return PK11_Destroyed;
- }
- return PK11_Busy;
-}
-
-/*
- * add an object to a slot and session queue. These two functions
- * adopt the object.
- */
-void
-pk11_AddSlotObject(PK11Slot *slot, PK11Object *object)
-{
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- pk11queue_add(object,object->handle,slot->tokObjects,TOKEN_OBJECT_HASH_SIZE);
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
-}
-
-void
-pk11_AddObject(PK11Session *session, PK11Object *object)
-{
- PK11Slot *slot = pk11_SlotFromSession(session);
-
- if (!pk11_isToken(object->handle)) {
- PK11_USE_THREADS(PR_Lock(session->objectLock);)
- pk11queue_add(&object->sessionList,0,session->objects,0);
- object->session = session;
- PK11_USE_THREADS(PR_Unlock(session->objectLock);)
- }
- pk11_AddSlotObject(slot,object);
-}
-
-/*
- * add an object to a slot andsession queue
- */
-void
-pk11_DeleteObject(PK11Session *session, PK11Object *object)
-{
- PK11Slot *slot = pk11_SlotFromSession(session);
-
- if (object->session) {
- PK11Session *session = object->session;
- PK11_USE_THREADS(PR_Lock(session->objectLock);)
- pk11queue_delete(&object->sessionList,0,session->objects,0);
- PK11_USE_THREADS(PR_Unlock(session->objectLock);)
- }
- PK11_USE_THREADS(PR_Lock(slot->objectLock);)
- pk11queue_delete(object,object->handle,slot->tokObjects,
- TOKEN_OBJECT_HASH_SIZE);
- PK11_USE_THREADS(PR_Unlock(slot->objectLock);)
- pk11_FreeObject(object);
-}
-
-/*
- * copy the attributes from one object to another. Don't overwrite existing
- * attributes. NOTE: This is a pretty expensive operation since it
- * grabs the attribute locks for the src object for a *long* time.
- */
-CK_RV
-pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
-{
- PK11Attribute *attribute;
- int i;
-
- PK11_USE_THREADS(PR_Lock(srcObject->attributeLock);)
- for(i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- attribute = srcObject->head[i];
- do {
- if (attribute) {
- if (!pk11_hasAttribute(destObject,attribute->handle)) {
- /* we need to copy the attribute since each attribute
- * only has one set of link list pointers */
- PK11Attribute *newAttribute = pk11_NewAttribute(
- destObject,pk11_attr_expand(&attribute->attrib));
- if (newAttribute == NULL) {
- PK11_USE_THREADS(PR_Unlock(srcObject->attributeLock);)
- return CKR_HOST_MEMORY;
- }
- pk11_AddAttribute(destObject,newAttribute);
- }
- attribute=attribute->next;
- }
- } while (attribute != NULL);
- }
- PK11_USE_THREADS(PR_Unlock(srcObject->attributeLock);)
- return CKR_OK;
-}
-
-/*
- * ******************** Search Utilities *******************************
- */
-
-/* add an object to a search list */
-CK_RV
-AddToList(PK11ObjectListElement **list,PK11Object *object)
-{
- PK11ObjectListElement *newElem =
- (PK11ObjectListElement *)PORT_Alloc(sizeof(PK11ObjectListElement));
-
- if (newElem == NULL) return CKR_HOST_MEMORY;
-
- newElem->next = *list;
- newElem->object = object;
- pk11_ReferenceObject(object);
-
- *list = newElem;
- return CKR_OK;
-}
-
-
-/* return true if the object matches the template */
-PRBool
-pk11_objectMatch(PK11Object *object,CK_ATTRIBUTE_PTR theTemplate,int count)
-{
- int i;
-
- for (i=0; i < count; i++) {
- PK11Attribute *attribute = pk11_FindAttribute(object,theTemplate[i].type);
- if (attribute == NULL) {
- return PR_FALSE;
- }
- if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) {
- if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue,
- theTemplate[i].ulValueLen) == 0) {
- pk11_FreeAttribute(attribute);
- continue;
- }
- }
- pk11_FreeAttribute(attribute);
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-/* search through all the objects in the queue and return the template matches
- * in the object list.
- */
-CK_RV
-pk11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head,
- PRLock *lock, CK_ATTRIBUTE_PTR theTemplate, int count, PRBool isLoggedIn)
-{
- int i;
- PK11Object *object;
- CK_RV crv = CKR_OK;
-
- for(i=0; i < TOKEN_OBJECT_HASH_SIZE; i++) {
- /* We need to hold the lock to copy a consistant version of
- * the linked list. */
- PK11_USE_THREADS(PR_Lock(lock);)
- for (object = head[i]; object != NULL; object= object->next) {
- if (pk11_objectMatch(object,theTemplate,count)) {
- /* don't return objects that aren't yet visible */
- if ((!isLoggedIn) && pk11_isTrue(object,CKA_PRIVATE)) continue;
- crv = AddToList(objectList,object);
- if (crv != CKR_OK) {
- break;
- }
- }
- }
- PK11_USE_THREADS(PR_Unlock(lock);)
- }
- return crv;
-}
-
-/*
- * free a single list element. Return the Next object in the list.
- */
-PK11ObjectListElement *
-pk11_FreeObjectListElement(PK11ObjectListElement *objectList)
-{
- PK11ObjectListElement *ol = objectList->next;
-
- pk11_FreeObject(objectList->object);
- PORT_Free(objectList);
- return ol;
-}
-
-/* free an entire object list */
-void
-pk11_FreeObjectList(PK11ObjectListElement *objectList)
-{
- PK11ObjectListElement *ol;
-
- for (ol= objectList; ol != NULL; ol = pk11_FreeObjectListElement(ol)) {}
-}
-
-/*
- * free a search structure
- */
-void
-pk11_FreeSearch(PK11SearchResults *search)
-{
- if (search->handles) {
- PORT_Free(search->handles);
- }
- PORT_Free(search);
-}
-
-/*
- * ******************** Session Utilities *******************************
- */
-
-/* update the sessions state based in it's flags and wether or not it's
- * logged in */
-void
-pk11_update_state(PK11Slot *slot,PK11Session *session)
-{
- if (slot->isLoggedIn) {
- if (slot->ssoLoggedIn) {
- session->info.state = CKS_RW_SO_FUNCTIONS;
- } else if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_USER_FUNCTIONS;
- } else {
- session->info.state = CKS_RO_USER_FUNCTIONS;
- }
- } else {
- if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_PUBLIC_SESSION;
- } else {
- session->info.state = CKS_RO_PUBLIC_SESSION;
- }
- }
-}
-
-/* update the state of all the sessions on a slot */
-void
-pk11_update_all_states(PK11Slot *slot)
-{
- int i;
- PK11Session *session;
-
- for (i=0; i < SESSION_HASH_SIZE; i++) {
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- for (session = slot->head[i]; session; session = session->next) {
- pk11_update_state(slot,session);
- }
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
- }
-}
-
-/*
- * context are cipher and digest contexts that are associated with a session
- */
-void
-pk11_FreeContext(PK11SessionContext *context)
-{
- if (context->cipherInfo) {
- (*context->destroy)(context->cipherInfo,PR_TRUE);
- }
- if (context->hashInfo) {
- (*context->hashdestroy)(context->hashInfo,PR_TRUE);
- }
- PORT_Free(context);
-}
-
-/* look up a slot structure from the ID (used to be a macro when we only
- * had two slots) */
-PK11Slot *
-pk11_SlotFromID(CK_SLOT_ID slotID)
-{
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- return &pk11_slot[0];
- case PRIVATE_KEY_SLOT_ID:
- return &pk11_slot[1];
- case FIPS_SLOT_ID:
- return &pk11_slot[2];
- default:
- break; /* fall through to NULL */
- }
- return NULL;
-}
-
-PK11Slot *
-pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
-{
- if (handle & PK11_PRIVATE_KEY_FLAG) {
- return &pk11_slot[1];
- }
- if (handle & PK11_FIPS_FLAG) {
- return &pk11_slot[2];
- }
- return &pk11_slot[0];
-}
-
-/*
- * create a new nession. NOTE: The session handle is not set, and the
- * session is not added to the slot's session queue.
- */
-PK11Session *
-pk11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
- CK_FLAGS flags)
-{
- PK11Session *session;
- PK11Slot *slot = pk11_SlotFromID(slotID);
-
- if (slot == NULL) return NULL;
-
- session = (PK11Session*)PORT_Alloc(sizeof(PK11Session));
- if (session == NULL) return NULL;
-
- session->next = session->prev = NULL;
- session->refCount = 1;
- session->enc_context = NULL;
- session->hash_context = NULL;
- session->sign_context = NULL;
- session->search = NULL;
- session->objectIDCount = 1;
-#ifdef PKCS11_USE_THREADS
- session->refLock = PR_NewLock();
- if (session->refLock == NULL) {
- PORT_Free(session);
- return NULL;
- }
- session->objectLock = PR_NewLock();
- if (session->objectLock == NULL) {
- PK11_USE_THREADS(PR_DestroyLock(session->refLock);)
- PORT_Free(session);
- return NULL;
- }
-#else
- session->refLock = NULL;
- session->objectLock = NULL;
-#endif
- session->objects[0] = NULL;
-
- session->slot = slot;
- session->notify = notify;
- session->appData = pApplication;
- session->info.flags = flags;
- session->info.slotID = slotID;
- pk11_update_state(slot,session);
- return session;
-}
-
-
-/* free all the data associated with a session. */
-static void
-pk11_DestroySession(PK11Session *session)
-{
- PK11ObjectList *op,*next;
- PORT_Assert(session->refCount == 0);
-
- /* clean out the attributes */
- /* since no one is referencing us, it's safe to walk the chain
- * without a lock */
- for (op = session->objects[0]; op != NULL; op = next) {
- next = op->next;
- /* paranoia */
- op->next = op->prev = NULL;
- pk11_DeleteObject(session,op->parent);
- }
- PK11_USE_THREADS(PR_DestroyLock(session->objectLock);)
- PK11_USE_THREADS(PR_DestroyLock(session->refLock);)
- if (session->enc_context) {
- pk11_FreeContext(session->enc_context);
- }
- if (session->hash_context) {
- pk11_FreeContext(session->hash_context);
- }
- if (session->sign_context) {
- pk11_FreeContext(session->sign_context);
- }
- if (session->search) {
- pk11_FreeSearch(session->search);
- }
- PORT_Free(session);
-}
-
-
-/*
- * look up a session structure from a session handle
- * generate a reference to it.
- */
-PK11Session *
-pk11_SessionFromHandle(CK_SESSION_HANDLE handle)
-{
- PK11Slot *slot = pk11_SlotFromSessionHandle(handle);
- PK11Session *session;
-
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- pk11queue_find(session,handle,slot->head,SESSION_HASH_SIZE);
- if (session) session->refCount++;
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
-
- return (session);
-}
-
-/*
- * release a reference to a session handle
- */
-void
-pk11_FreeSession(PK11Session *session)
-{
- PRBool destroy = PR_FALSE;
- PK11_USE_THREADS(PK11Slot *slot = pk11_SlotFromSession(session);)
-
- PK11_USE_THREADS(PR_Lock(slot->sessionLock);)
- if (session->refCount == 1) destroy = PR_TRUE;
- session->refCount--;
- PK11_USE_THREADS(PR_Unlock(slot->sessionLock);)
-
- if (destroy) pk11_DestroySession(session);
-}
diff --git a/security/nss/lib/softoken/pkcs11u.h b/security/nss/lib/softoken/pkcs11u.h
deleted file mode 100644
index 8b3c6dbd5..000000000
--- a/security/nss/lib/softoken/pkcs11u.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/*
- * reset any packing set by pkcs11p.h
- */
-#if defined(XP_WIN)
-#if defined (_WIN32)
-#pragma warning(disable:4103)
-#pragma pack(pop, cryptoki)
-#endif
-#endif
-
diff --git a/security/nss/lib/softoken/private.h b/security/nss/lib/softoken/private.h
deleted file mode 100644
index b90ceaaea..000000000
--- a/security/nss/lib/softoken/private.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * private.h - Private data structures for the software token library
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#ifndef _PRIVATE_H_
-#define _PRIVATE_H_
-
-#include "nspr.h"
-#include "seccomon.h"
-#include "mcom_db.h"
-
-/*
- * Handle structure for open key databases
- */
-struct SECKEYKeyDBHandleStr {
- DB *db;
- DB *updatedb; /* used when updating an old version */
- SECItem *global_salt; /* password hashing salt for this db */
- int version; /* version of the database */
-};
-
-/*
-** Typedef for callback for traversing key database.
-** "key" is the key used to index the data in the database (nickname)
-** "data" is the key data
-** "pdata" is the user's data
-*/
-typedef SECStatus (* SECKEYTraverseKeysFunc)(DBT *key, DBT *data, void *pdata);
-
-
-SEC_BEGIN_PROTOS
-
-/*
-** Traverse the entire key database, and pass the nicknames and keys to a
-** user supplied function.
-** "f" is the user function to call for each key
-** "udata" is the user's data, which is passed through to "f"
-*/
-extern SECStatus SECKEY_TraverseKeys(SECKEYKeyDBHandle *handle,
- SECKEYTraverseKeysFunc f,
- void *udata);
-
-SEC_END_PROTOS
-
-#endif /* _PRIVATE_H_ */
diff --git a/security/nss/lib/softoken/rawhash.c b/security/nss/lib/softoken/rawhash.c
deleted file mode 100644
index 4d19b3cdb..000000000
--- a/security/nss/lib/softoken/rawhash.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#include "nspr.h"
-#include "sechash.h"
-#include "blapi.h" /* below the line */
-
-
-static void *
-null_hash_new_context(void)
-{
- return NULL;
-}
-
-static void *
-null_hash_clone_context(void *v)
-{
- PORT_Assert(v == NULL);
- return NULL;
-}
-
-static void
-null_hash_begin(void *v)
-{
-}
-
-static void
-null_hash_update(void *v, const unsigned char *input, unsigned int length)
-{
-}
-
-static void
-null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
- unsigned int maxOut)
-{
- *outLen = 0;
-}
-
-static void
-null_hash_destroy_context(void *v, PRBool b)
-{
- PORT_Assert(v == NULL);
-}
-
-
-SECHashObject SECRawHashObjects[] = {
- { 0,
- (void * (*)(void)) null_hash_new_context,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) null_hash_destroy_context,
- (void (*)(void *)) null_hash_begin,
- (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) null_hash_end
- },
- { MD2_LENGTH,
- (void * (*)(void)) MD2_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) MD2_DestroyContext,
- (void (*)(void *)) MD2_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) MD2_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD2_End
- },
- { MD5_LENGTH,
- (void * (*)(void)) MD5_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) MD5_DestroyContext,
- (void (*)(void *)) MD5_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) MD5_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_End
- },
- { SHA1_LENGTH,
- (void * (*)(void)) SHA1_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) SHA1_DestroyContext,
- (void (*)(void *)) SHA1_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) SHA1_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA1_End
- },
-};
-
diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c
deleted file mode 100644
index ca853269d..000000000
--- a/security/nss/lib/softoken/rsawrapr.c
+++ /dev/null
@@ -1,1049 +0,0 @@
-/*
- * PKCS#1 encoding and decoding functions.
- * This file is believed to contain no code licensed from other parties.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#include "blapi.h"
-#include "softoken.h"
-#include "sechash.h"
-
-#include "keylow.h"
-#include "secerr.h"
-
-#define RSA_BLOCK_MIN_PAD_LEN 8
-#define RSA_BLOCK_FIRST_OCTET 0x00
-#define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
-#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
-#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
-
-#define OAEP_SALT_LEN 8
-#define OAEP_PAD_LEN 8
-#define OAEP_PAD_OCTET 0x00
-
-#define FLAT_BUFSIZE 512 /* bytes to hold flattened SHA1Context. */
-
-static SHA1Context *
-SHA1_CloneContext(SHA1Context *original)
-{
- SHA1Context * clone = NULL;
- unsigned char *pBuf;
- int sha1ContextSize = SHA1_FlattenSize(original);
- SECStatus frv;
- unsigned char buf[FLAT_BUFSIZE];
-
- PORT_Assert(sizeof buf >= sha1ContextSize);
- if (sizeof buf >= sha1ContextSize) {
- pBuf = buf;
- } else {
- pBuf = PORT_Alloc(sha1ContextSize);
- if (!pBuf)
- goto done;
- }
-
- frv = SHA1_Flatten(original, pBuf);
- if (frv == SECSuccess) {
- clone = SHA1_Resurrect(pBuf, NULL);
- memset(pBuf, 0, sha1ContextSize);
- }
-done:
- if (pBuf != buf)
- PORT_Free(pBuf);
- return clone;
-}
-
-/*
- * Modify data by XORing it with a special hash of salt.
- */
-static SECStatus
-oaep_xor_with_h1(unsigned char *data, unsigned int datalen,
- unsigned char *salt, unsigned int saltlen)
-{
- SHA1Context *sha1cx;
- unsigned char *dp, *dataend;
- unsigned char end_octet;
-
- sha1cx = SHA1_NewContext();
- if (sha1cx == NULL) {
- return SECFailure;
- }
-
- /*
- * Get a hash of salt started; we will use it several times,
- * adding in a different end octet (x00, x01, x02, ...).
- */
- SHA1_Begin (sha1cx);
- SHA1_Update (sha1cx, salt, saltlen);
- end_octet = 0;
-
- dp = data;
- dataend = data + datalen;
-
- while (dp < dataend) {
- SHA1Context *sha1cx_h1;
- unsigned int sha1len, sha1off;
- unsigned char sha1[SHA1_LENGTH];
-
- /*
- * Create hash of (salt || end_octet)
- */
- sha1cx_h1 = SHA1_CloneContext (sha1cx);
- SHA1_Update (sha1cx_h1, &end_octet, 1);
- SHA1_End (sha1cx_h1, sha1, &sha1len, sizeof(sha1));
- SHA1_DestroyContext (sha1cx_h1, PR_TRUE);
- PORT_Assert (sha1len == SHA1_LENGTH);
-
- /*
- * XOR that hash with the data.
- * When we have fewer than SHA1_LENGTH octets of data
- * left to xor, use just the low-order ones of the hash.
- */
- sha1off = 0;
- if ((dataend - dp) < SHA1_LENGTH)
- sha1off = SHA1_LENGTH - (dataend - dp);
- while (sha1off < SHA1_LENGTH)
- *dp++ ^= sha1[sha1off++];
-
- /*
- * Bump for next hash chunk.
- */
- end_octet++;
- }
-
- return SECSuccess;
-}
-
-/*
- * Modify salt by XORing it with a special hash of data.
- */
-static SECStatus
-oaep_xor_with_h2(unsigned char *salt, unsigned int saltlen,
- unsigned char *data, unsigned int datalen)
-{
- unsigned char sha1[SHA1_LENGTH];
- unsigned char *psalt, *psha1, *saltend;
- SECStatus rv;
-
- /*
- * Create a hash of data.
- */
- rv = SHA1_HashBuf (sha1, data, datalen);
- if (rv != SECSuccess) {
- return rv;
- }
-
- /*
- * XOR the low-order octets of that hash with salt.
- */
- PORT_Assert (saltlen <= SHA1_LENGTH);
- saltend = salt + saltlen;
- psalt = salt;
- psha1 = sha1 + SHA1_LENGTH - saltlen;
- while (psalt < saltend) {
- *psalt++ ^= *psha1++;
- }
-
- return SECSuccess;
-}
-
-/*
- * Format one block of data for public/private key encryption using
- * the rules defined in PKCS #1.
- */
-unsigned char *
-RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
- SECItem *data)
-{
- unsigned char *block;
- unsigned char *bp;
- int padLen;
- int i;
-
- block = (unsigned char *) PORT_Alloc(modulusLen);
- if (block == NULL)
- return NULL;
-
- bp = block;
-
- /*
- * All RSA blocks start with two octets:
- * 0x00 || BlockType
- */
- *bp++ = RSA_BLOCK_FIRST_OCTET;
- *bp++ = (unsigned char) blockType;
-
- switch (blockType) {
-
- /*
- * Blocks intended for private-key operation.
- */
- case RSA_BlockPrivate0: /* essentially unused */
- case RSA_BlockPrivate: /* preferred method */
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- * 1 1 padLen 1 data->len
- * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
- */
- padLen = modulusLen - data->len - 3;
- PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
- PORT_Memset (bp,
- blockType == RSA_BlockPrivate0
- ? RSA_BLOCK_PRIVATE0_PAD_OCTET
- : RSA_BLOCK_PRIVATE_PAD_OCTET,
- padLen);
- bp += padLen;
- *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
- PORT_Memcpy (bp, data->data, data->len);
- break;
-
- /*
- * Blocks intended for public-key operation.
- */
- case RSA_BlockPublic:
-
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- * 1 1 padLen 1 data->len
- * Pad is all non-zero random bytes.
- */
- padLen = modulusLen - data->len - 3;
- PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
- for (i = 0; i < padLen; i++) {
- /* Pad with non-zero random data. */
- do {
- RNG_GenerateGlobalRandomBytes(bp + i, 1);
- } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
- }
- bp += padLen;
- *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
- PORT_Memcpy (bp, data->data, data->len);
-
- break;
-
- /*
- * Blocks intended for public-key operation, using
- * Optimal Asymmetric Encryption Padding (OAEP).
- */
- case RSA_BlockOAEP:
- /*
- * 0x00 || BT || Modified2(Salt) || Modified1(PaddedData)
- * 1 1 OAEP_SALT_LEN OAEP_PAD_LEN + data->len [+ N]
- *
- * where:
- * PaddedData is "Pad1 || ActualData [|| Pad2]"
- * Salt is random data.
- * Pad1 is all zeros.
- * Pad2, if present, is random data.
- * (The "modified" fields are all the same length as the original
- * unmodified values; they are just xor'd with other values.)
- *
- * Modified1 is an XOR of PaddedData with a special octet
- * string constructed of iterated hashing of Salt (see below).
- * Modified2 is an XOR of Salt with the low-order octets of
- * the hash of Modified1 (see farther below ;-).
- *
- * Whew!
- */
-
-
- /*
- * Salt
- */
- RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
- bp += OAEP_SALT_LEN;
-
- /*
- * Pad1
- */
- PORT_Memset (bp, OAEP_PAD_OCTET, OAEP_PAD_LEN);
- bp += OAEP_PAD_LEN;
-
- /*
- * Data
- */
- PORT_Memcpy (bp, data->data, data->len);
- bp += data->len;
-
- /*
- * Pad2
- */
- if (bp < (block + modulusLen))
- RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
-
- /*
- * Now we have the following:
- * 0x00 || BT || Salt || PaddedData
- * (From this point on, "Pad1 || Data [|| Pad2]" is treated
- * as the one entity PaddedData.)
- *
- * We need to turn PaddedData into Modified1.
- */
- if (oaep_xor_with_h1(block + 2 + OAEP_SALT_LEN,
- modulusLen - 2 - OAEP_SALT_LEN,
- block + 2, OAEP_SALT_LEN) != SECSuccess) {
- PORT_Free (block);
- return NULL;
- }
-
- /*
- * Now we have:
- * 0x00 || BT || Salt || Modified1(PaddedData)
- *
- * The remaining task is to turn Salt into Modified2.
- */
- if (oaep_xor_with_h2(block + 2, OAEP_SALT_LEN,
- block + 2 + OAEP_SALT_LEN,
- modulusLen - 2 - OAEP_SALT_LEN) != SECSuccess) {
- PORT_Free (block);
- return NULL;
- }
-
- break;
-
- default:
- PORT_Assert (0);
- PORT_Free (block);
- return NULL;
- }
-
- return block;
-}
-
-SECStatus
-RSA_FormatBlock(SECItem *result, unsigned modulusLen,
- RSA_BlockType blockType, SECItem *data)
-{
- /*
- * XXX For now assume that the data length fits in a single
- * XXX encryption block; the ASSERTs below force this.
- * XXX To fix it, each case will have to loop over chunks whose
- * XXX lengths satisfy the assertions, until all data is handled.
- * XXX (Unless RSA has more to say about how to handle data
- * XXX which does not fit in a single encryption block?)
- * XXX And I do not know what the result is supposed to be,
- * XXX so the interface to this function may need to change
- * XXX to allow for returning multiple blocks, if they are
- * XXX not wanted simply concatenated one after the other.
- */
-
- switch (blockType) {
- case RSA_BlockPrivate0:
- case RSA_BlockPrivate:
- case RSA_BlockPublic:
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- *
- * The "3" below is the first octet + the second octet + the 0x00
- * octet that always comes just before the ActualData.
- */
- PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
-
- result->data = RSA_FormatOneBlock(modulusLen, blockType, data);
- if (result->data == NULL) {
- result->len = 0;
- return SECFailure;
- }
- result->len = modulusLen;
-
- break;
-
- case RSA_BlockOAEP:
- /*
- * 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2])
- *
- * The "2" below is the first octet + the second octet.
- * (The other fields do not contain the clear values, but are
- * the same length as the clear values.)
- */
- PORT_Assert (data->len <= (modulusLen - (2 + OAEP_SALT_LEN
- + OAEP_PAD_LEN)));
-
- result->data = RSA_FormatOneBlock(modulusLen, blockType, data);
- if (result->data == NULL) {
- result->len = 0;
- return SECFailure;
- }
- result->len = modulusLen;
-
- break;
-
- case RSA_BlockRaw:
- /*
- * Pad || ActualData
- * Pad is zeros. The application is responsible for recovering
- * the actual data.
- */
- result->data = (unsigned char*)PORT_ZAlloc(modulusLen);
- result->len = modulusLen;
- PORT_Memcpy(result->data+(modulusLen-data->len),data->data,data->len);
- break;
-
- default:
- PORT_Assert (0);
- result->data = NULL;
- result->len = 0;
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-/*
- * Takes a formatted block and returns the data part.
- * (This is the inverse of RSA_FormatOneBlock().)
- * In some formats the start of the data is ambiguous;
- * if it is non-zero, expectedLen will disambiguate.
- *
- * NOTE: this routine is not yet used/tested! (XXX please
- * remove this comment once that is no longer the case ;-)
- */
-unsigned char *
-RSA_DecodeOneBlock(unsigned char *data,
- unsigned int modulusLen,
- unsigned int expectedLen,
- RSA_BlockType *pResultType,
- unsigned int *pResultLen)
-{
- RSA_BlockType blockType;
- unsigned char *dp, *res;
- unsigned int i, len, padLen;
-
- dp = data;
- if (*dp++ != RSA_BLOCK_FIRST_OCTET) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
-
- blockType = (RSA_BlockType)*dp++;
- switch (blockType) {
- case RSA_BlockPrivate0:
- if (expectedLen) {
- padLen = modulusLen - expectedLen - 3;
- PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
- for (i = 0; i < padLen; i++) {
- if (*dp++ != RSA_BLOCK_PRIVATE0_PAD_OCTET)
- break;
- }
- if ((i != padLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- dp++;
- len = expectedLen;
- } else {
- for (i = 0; i < modulusLen; i++) {
- if (*dp++ != RSA_BLOCK_PRIVATE0_PAD_OCTET)
- break;
- }
- if (i == modulusLen) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- if (RSA_BLOCK_PRIVATE0_PAD_OCTET == RSA_BLOCK_AFTER_PAD_OCTET)
- dp--;
- padLen = dp - data - 2;
- if ((padLen < RSA_BLOCK_MIN_PAD_LEN)
- || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- dp++;
- len = modulusLen - (dp - data);
- }
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- return NULL;
- }
- PORT_Memcpy (res, dp, len);
- break;
-
- case RSA_BlockPrivate:
- for (i = 0; i < modulusLen; i++) {
- if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
- break;
- }
- if ((i == modulusLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- padLen = dp - data - 2;
- dp++;
- len = modulusLen - (dp - data);
- if ((padLen < RSA_BLOCK_MIN_PAD_LEN) || (expectedLen
- && (expectedLen != len))) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- return NULL;
- }
- PORT_Memcpy (res, dp, len);
- break;
-
- case RSA_BlockPublic:
- for (i = 0; i < modulusLen; i++) {
- if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
- break;
- }
- if (i == modulusLen) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- padLen = dp - data - 2;
- dp++;
- len = modulusLen - (dp - data);
- if ((padLen < RSA_BLOCK_MIN_PAD_LEN) || (expectedLen
- && (expectedLen != len))) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- return NULL;
- }
- PORT_Memcpy (res, dp, len);
- break;
-
- case RSA_BlockOAEP:
- {
- unsigned char *salt, *tmp_res;
- SECStatus rv;
-
- len = modulusLen - 2 - OAEP_SALT_LEN;
- /*
- * dp points to:
- * Modified2(Salt) || Modified1(PaddedData)
- * To recover Salt we need to XOR it with the low-order hash
- * of Modified1.
- */
- salt = (unsigned char *) PORT_Alloc(OAEP_SALT_LEN);
- if (salt == NULL) {
- return NULL;
- }
- PORT_Memcpy (salt, dp, OAEP_SALT_LEN);
- dp += OAEP_SALT_LEN;
- rv = oaep_xor_with_h2 (salt, OAEP_SALT_LEN, dp, len);
- if (rv != SECSuccess) {
- PORT_Free (salt);
- return NULL;
- }
- if (expectedLen) {
- PORT_Assert (expectedLen <= len);
- len = expectedLen;
- }
- tmp_res = (unsigned char *) PORT_Alloc(len);
- if (tmp_res == NULL) {
- PORT_Free (salt);
- return NULL;
- }
- PORT_Memcpy (tmp_res, dp, len);
- rv = oaep_xor_with_h1 (tmp_res, len, salt, OAEP_SALT_LEN);
- PORT_Free (salt);
- if (rv != SECSuccess) {
- return NULL;
- }
- for (i = 0; i < OAEP_PAD_LEN; i++) {
- if (tmp_res[i] != OAEP_PAD_OCTET) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- PORT_Free (tmp_res);
- return NULL;
- }
- }
- len -= OAEP_PAD_LEN;
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- PORT_Free (tmp_res);
- return NULL;
- }
- PORT_Memcpy (res, tmp_res + OAEP_PAD_LEN, len);
- PORT_Free (tmp_res);
- }
- break;
-
- default:
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
-
- PORT_Assert (res != NULL);
- *pResultLen = len;
- *pResultType = blockType;
- return res;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_Sign(SECKEYLowPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int maxOutputLen,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv = SECSuccess;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- if (maxOutputLen < modulus_len)
- return SECFailure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- return SECFailure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
- &unformatted);
- if (rv != SECSuccess)
- goto done;
-
- rv = RSA_PrivateKeyOp(&key->u.rsa, output, formatted.data);
- *output_len = modulus_len;
-
- goto done;
-
-done:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return rv;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSign(SECKEYLowPublicKey *key,
- unsigned char * sign,
- unsigned int sign_len,
- unsigned char * hash,
- unsigned int hash_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
- unsigned int i;
- unsigned char * buffer;
-
- modulus_len = SECKEY_LowPublicModulusLen(key);
- if (sign_len != modulus_len)
- goto failure;
- if (hash_len > modulus_len - 8)
- goto failure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * check the padding that was used
- */
- if (buffer[0] != 0 || buffer[1] != 1)
- goto loser;
- for (i = 2; i < modulus_len - hash_len - 1; i++) {
- if (buffer[i] == 0)
- break;
- if (buffer[i] != 0xff)
- goto loser;
- }
-
- /*
- * make sure we get the same results
- */
- if (PORT_Memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0)
- goto loser;
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSignRecover(SECKEYLowPublicKey *key,
- unsigned char * data,
- unsigned int * data_len,
- unsigned int max_output_len,
- unsigned char * sign,
- unsigned int sign_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
- unsigned int i;
- unsigned char * buffer;
-
- if (sign_len != modulus_len)
- goto failure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
- if (rv != SECSuccess)
- goto loser;
- *data_len = 0;
-
- /*
- * check the padding that was used
- */
- if (buffer[0] != 0 || buffer[1] != 1)
- goto loser;
- for (i = 2; i < modulus_len; i++) {
- if (buffer[i] == 0) {
- *data_len = modulus_len - i - 1;
- break;
- }
- if (buffer[i] != 0xff)
- goto loser;
- }
- if (*data_len == 0)
- goto loser;
- if (*data_len > max_output_len)
- goto loser;
-
- /*
- * make sure we get the same results
- */
- PORT_Memcpy(data,buffer + modulus_len - *data_len, *data_len);
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_EncryptBlock(SECKEYLowPublicKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- formatted.data = NULL;
- if (max_output_len < modulus_len)
- goto failure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
- &unformatted);
- if (rv != SECSuccess)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
- if (rv != SECSuccess)
- goto failure;
-
- PORT_ZFree(formatted.data, modulus_len);
- *output_len = modulus_len;
- return SECSuccess;
-
-failure:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_DecryptBlock(SECKEYLowPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
- unsigned int i;
- unsigned char * buffer;
-
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
- if (input_len != modulus_len)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
- if (rv != SECSuccess)
- goto loser;
-
- if (buffer[0] != 0 || buffer[1] != 2)
- goto loser;
- *output_len = 0;
- for (i = 2; i < modulus_len; i++) {
- if (buffer[i] == 0) {
- *output_len = modulus_len - i - 1;
- break;
- }
- }
- if (*output_len == 0)
- goto loser;
- if (*output_len > max_output_len)
- goto loser;
-
- PORT_Memcpy(output, buffer + modulus_len - *output_len, *output_len);
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-/*
- * added to make pkcs #11 happy
- * RAW is RSA_X_509
- */
-SECStatus
-RSA_SignRaw(SECKEYLowPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int maxOutputLen,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv = SECSuccess;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- if (maxOutputLen < modulus_len)
- return SECFailure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- return SECFailure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
- if (rv != SECSuccess)
- goto done;
-
- rv = RSA_PrivateKeyOp(&key->u.rsa, output, formatted.data);
- *output_len = modulus_len;
-
-done:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return rv;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSignRaw(SECKEYLowPublicKey *key,
- unsigned char * sign,
- unsigned int sign_len,
- unsigned char * hash,
- unsigned int hash_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
- unsigned char * buffer;
-
- if (sign_len != modulus_len)
- goto failure;
- if (hash_len > modulus_len)
- goto failure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * make sure we get the same results
- */
- /* NOTE: should we verify the leading zeros? */
- if (PORT_Memcmp(buffer + (modulus_len-hash_len), hash, hash_len) != 0)
- goto loser;
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSignRecoverRaw(SECKEYLowPublicKey *key,
- unsigned char * data,
- unsigned int * data_len,
- unsigned int max_output_len,
- unsigned char * sign,
- unsigned int sign_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
-
- if (sign_len != modulus_len)
- goto failure;
- if (max_output_len < modulus_len)
- goto failure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
- if (rv != SECSuccess)
- goto failure;
-
- *data_len = modulus_len;
- return SECSuccess;
-
-failure:
- return SECFailure;
-}
-
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_EncryptRaw(SECKEYLowPublicKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- formatted.data = NULL;
- if (max_output_len < modulus_len)
- goto failure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
- if (rv != SECSuccess)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
- if (rv != SECSuccess)
- goto failure;
-
- PORT_ZFree(formatted.data, modulus_len);
- *output_len = modulus_len;
- return SECSuccess;
-
-failure:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_DecryptRaw(SECKEYLowPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
-
- if (modulus_len <= 0)
- goto failure;
- if (modulus_len > max_output_len)
- goto failure;
- PORT_Assert(key->keyType == rsaKey);
- if (key->keyType != rsaKey)
- goto failure;
- if (input_len != modulus_len)
- goto failure;
-
- rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
- if (rv != SECSuccess)
- goto failure;
-
- *output_len = modulus_len;
- return SECSuccess;
-
-failure:
- return SECFailure;
-}
diff --git a/security/nss/lib/softoken/secpkcs5.c b/security/nss/lib/softoken/secpkcs5.c
deleted file mode 100644
index 6cc8dd4a4..000000000
--- a/security/nss/lib/softoken/secpkcs5.c
+++ /dev/null
@@ -1,1827 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "secport.h"
-#include "hasht.h"
-#include "pkcs11t.h"
-#include "blapi.h"
-#include "sechash.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "secpkcs5.h"
-#include "secoid.h"
-#include "alghmac.h"
-#include "softoken.h"
-#include "secerr.h"
-
-#define DES_IV_LENGTH 8
-#define RC2_IV_LENGTH 8
-#define MD2_LENGTH 16
-#define MD5_LENGTH 16
-#define SHA1_LENGTH 20
-#define SEED_LENGTH 16
-#define SALT_LENGTH 8
-#define PBE_SALT_LENGTH 16
-
-/* template for PKCS 5 PBE Parameter. This template has been expanded
- * based upon the additions in PKCS 12. This should eventually be moved
- * if RSA updates PKCS 5.
- */
-const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-pbeBitGenParameters pbeHashAlgorithmParams[] = {
- { 0, 0, SEC_OID_UNKNOWN },
- { 128, 512, SEC_OID_MD2 },
- { 128, 512, SEC_OID_MD5 },
- { 160, 512, SEC_OID_SHA1 },
-};
-
-/* generate some random bytes. this is used to generate the
- * salt if it is not specified.
- */
-static SECStatus
-sec_pkcs5_generate_random_bytes(PRArenaPool *poolp,
- SECItem *dest, int len)
-{
- SECStatus rv = SECFailure;
-
- if(dest != NULL)
- {
- void *mark = PORT_ArenaMark(poolp);
- dest->data = (unsigned char *)PORT_ArenaZAlloc(poolp, len);
- if(dest->data != NULL)
- {
- dest->len = len;
- RNG_GenerateGlobalRandomBytes(dest->data, dest->len);
- PORT_ArenaUnmark(poolp, mark);
- rv = SECSuccess;
- } else
- PORT_ArenaRelease(poolp, mark);
- }
-
- return rv;
-}
-
-/* maps hash algorithm from PBE algorithm.
- */
-static SECOidTag
-sec_pkcs5_hash_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_SHA1;
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return SEC_OID_MD5;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- return SEC_OID_MD2;
- default:
- break;
- }
- return SEC_OID_UNKNOWN;
-}
-
-/* get the iv length needed for the PBE algorithm
- */
-static int
-sec_pkcs5_iv_length(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- return DES_IV_LENGTH;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- return RC2_IV_LENGTH;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return 0;
- default:
- break;
- }
- return -1;
-}
-
-/* get the key length needed for the PBE algorithm
- */
-static int
-sec_pkcs5_key_length(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- return 24;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return 8;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return 5;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- return 16;
- default:
- break;
- }
- return -1;
-}
-
-/* the V2 algorithms only encode the salt, there is no iteration
- * count so we need a check for V2 algorithm parameters.
- */
-static PRBool
-sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return PR_TRUE;
- default:
- break;
- }
-
- return PR_FALSE;
-}
-
-/* creates a PBE parameter based on the PBE algorithm. the only required
- * parameters are algorithm and interation. the return is a PBE parameter
- * which conforms to PKCS 5 parameter unless an extended parameter is needed.
- * this is primarily if keyLen and a variable key length algorithm are
- * specified.
- * salt - if null, a salt will be generated from random bytes.
- * iteration - number of iterations to perform hashing.
- * keyLen - only used in variable key length algorithms
- * iv - if null, the IV will be generated based on PKCS 5 when needed.
- * params - optional, currently unsupported additional parameters.
- * once a parameter is allocated, it should be destroyed calling
- * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
- */
-static SEC_PKCS5PBEParameter *
-sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
- SECItem *salt,
- int iteration)
-{
- PRArenaPool *poolp = NULL;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
- SECStatus rv;
- void *dummy = NULL;
-
- if(iteration < 0) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
- return NULL;
-
- pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS5PBEParameter));
- if(!pbe_param) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- pbe_param->poolp = poolp;
- pbe_param->algorithm = algorithm;
-
- /* should we generate the salt? */
- if(!salt || !salt->data) {
- rv = sec_pkcs5_generate_random_bytes(poolp, &pbe_param->salt,
- SALT_LENGTH);
- } else {
- rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt);
- }
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- /* encode the integer */
- dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
- iteration);
- rv = (dummy) ? SECSuccess : SECFailure;
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
-
- return pbe_param;
-}
-
-/* generate bits for key and iv using MD5 hashing
- */
-static SECItem *
-sec_pkcs5_compute_md5_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool dummy)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0)) {
- return NULL;
- }
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if((hash != NULL) && (pre_hash != NULL)) {
- unsigned int i, ph_len;
-
- ph_len = MD5_LENGTH;
- if(ph_len < (salt->len + pwd->len)) {
- ph_len = salt->len + pwd->len;
- }
-
- rv = SECFailure;
- hash->data = (unsigned char *)PORT_ZAlloc(MD5_LENGTH);
- hash->len = MD5_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
- pre_hash->len = salt->len + pwd->len;
-
- if((hash->data != NULL) && (pre_hash->data != NULL)) {
- rv = SECSuccess;
- /* handle 0 length password */
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
- for(i = 0; ((i < (unsigned int)iter) && (rv == SECSuccess)); i++) {
- rv = MD5_HashBuf(hash->data, pre_hash->data, pre_hash->len);
- if(rv != SECFailure) {
- PORT_Memcpy(pre_hash->data, hash->data, MD5_LENGTH);
- pre_hash->len = MD5_LENGTH;
- }
- }
- }
- }
-
- if(pre_hash != NULL)
- SECITEM_FreeItem(pre_hash, PR_TRUE);
-
- if((rv == SECFailure) && (hash)) {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* generate bits for key and iv using MD2 hashing
- */
-static SECItem *
-sec_pkcs5_compute_md2_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool dummy)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0))
- return NULL;
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if((hash != NULL) && (pre_hash != NULL))
- {
- int i, ph_len;
-
- ph_len = MD2_LENGTH;
- if((salt->len + pwd->len) > MD2_LENGTH)
- ph_len = salt->len+pwd->len;
-
- rv = SECFailure;
- hash->data = (unsigned char *)PORT_ZAlloc(MD2_LENGTH);
- hash->len = MD2_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
- pre_hash->len = salt->len + pwd->len;
-
- if((hash->data != NULL) && (pre_hash->data != NULL))
- {
- MD2Context *ctxt;
-
- rv = SECSuccess;
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
-
- for(i = 0; ((i < iter) && (rv == SECSuccess)); i++)
- {
- ctxt = MD2_NewContext();
- if(ctxt == NULL)
- rv = SECFailure;
- else
- {
- MD2_Update(ctxt, pre_hash->data, pre_hash->len);
- MD2_End(ctxt, hash->data, &hash->len, hash->len);
- PORT_Memcpy(pre_hash->data, hash->data, MD2_LENGTH);
- pre_hash->len = MD2_LENGTH;
- MD2_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
- }
-
- if(pre_hash != NULL)
- SECITEM_FreeItem(pre_hash, PR_TRUE);
-
- if(rv != SECSuccess)
- if(hash != NULL)
- {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* generate bits using SHA1 hash
- */
-static SECItem *
-sec_pkcs5_compute_sha1_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool faulty3DES)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0)) {
- return NULL;
- }
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
-
- if((hash != NULL) && (pre_hash != NULL)) {
- int i, ph_len;
-
- ph_len = SHA1_LENGTH;
- if((salt->len + pwd->len) > SHA1_LENGTH) {
- ph_len = salt->len + pwd->len;
- }
-
- rv = SECFailure;
-
- /* allocate buffers */
- hash->data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
- hash->len = SHA1_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
-
- /* in pbeSHA1TripleDESCBC there was an allocation error that made
- * it into the caller. We do not want to propagate those errors
- * further, so we are doing it correctly, but reading the old method.
- */
- if(faulty3DES) {
- pre_hash->len = ph_len;
- } else {
- pre_hash->len = salt->len + pwd->len;
- }
-
- /* preform hash */
- if((hash->data != NULL) && (pre_hash->data != NULL)) {
- rv = SECSuccess;
- /* check for 0 length password */
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
- for(i = 0; ((i < iter) && (rv == SECSuccess)); i++) {
- rv = SHA1_HashBuf(hash->data, pre_hash->data, pre_hash->len);
- if(rv != SECFailure) {
- pre_hash->len = SHA1_LENGTH;
- PORT_Memcpy(pre_hash->data, hash->data, SHA1_LENGTH);
- }
- }
- }
- }
-
- if(pre_hash != NULL) {
- SECITEM_FreeItem(pre_hash, PR_TRUE);
- }
-
- if((rv != SECSuccess) && (hash != NULL)) {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* bit generation/key and iv generation routines. */
-typedef SECItem *(* sec_pkcs5_hash_func)(SECItem *s, SECItem *p,
- int iter, PRBool faulty3DES);
-
-/* generates bits needed for the key and iv based on PKCS 5,
- * be concatenating the password and salt and using the appropriate
- * hash algorithm. This function serves as a front end to the
- * specific hash functions above. a return of NULL indicates an
- * error.
- */
-static SECItem *
-sec_pkcs5_compute_hash(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- sec_pkcs5_hash_func hash_func;
- SECOidTag hash_alg;
- SECItem *hash = NULL;
- SECItem *salt = NULL;
-
- hash_alg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- salt = &(pbe_param->salt);
- switch(hash_alg)
- {
- case SEC_OID_SHA1:
- hash_func = sec_pkcs5_compute_sha1_hash;
- break;
- case SEC_OID_MD2:
- hash_func = sec_pkcs5_compute_md2_hash;
- break;
- case SEC_OID_MD5:
- hash_func = sec_pkcs5_compute_md5_hash;
- break;
- default:
- hash_func = NULL;
- }
-
- if(hash_func) {
- hash = (* hash_func)(salt, pwitem, pbe_param->iter, faulty3DES);
- }
-
- return hash;
-}
-
-/* determines the number of bits needed for key and iv generation
- * based upon the algorithm identifier. if a number of
- * bits greater than the hash algorithm can produce are needed,
- * the bits will be generated based upon the extended PKCS 5
- * described in PKCS 12.
- *
- * a return of -1 indicates an error.
- */
-static int
-sec_pkcs5_bits_needed(SEC_PKCS5PBEParameter *pbe_param)
-{
- int iv_bits;
- int key_bits;
-
- if(pbe_param == NULL) {
- return -1;
- }
-
- iv_bits = sec_pkcs5_iv_length(pbe_param->algorithm) * 8;
- key_bits = sec_pkcs5_key_length(pbe_param->algorithm) * 8;
-
- if(key_bits != 0) {
- return iv_bits + key_bits;
- }
-
- return -1;
-}
-
-/* determines the number of bits generated by each hash algorithm.
- * in case of an error, -1 is returned.
- */
-static int
-sec_pkcs5_hash_bits_generated(SEC_PKCS5PBEParameter *pbe_param)
-{
- if(pbe_param == NULL) {
- return -1;
- }
-
- switch(sec_pkcs5_hash_algorithm(pbe_param->algorithm)) {
- case SEC_OID_SHA1:
- return SHA1_LENGTH * 8;
- case SEC_OID_MD2:
- return MD2_LENGTH * 8;
- case SEC_OID_MD5:
- return MD5_LENGTH * 8;
- default:
- break;
- }
-
- return -1;
-}
-
-/* this bit generation routine is described in PKCS 12 and the proposed
- * extensions to PKCS 5. an initial hash is generated following the
- * instructions laid out in PKCS 5. If the number of bits generated is
- * insufficient, then the method discussed in the proposed extensions to
- * PKCS 5 in PKCS 12 are used. This extension makes use of the HMAC
- * function. And the P_Hash function from the TLS standard.
- */
-static SECItem *
-sec_pkcs5_bit_generator(SEC_PKCS5PBEParameter *pbe_param,
- SECItem *init_hash,
- unsigned int bits_needed)
-{
- SECItem *ret_bits = NULL;
- int hash_size = 0;
- unsigned int i;
- unsigned int hash_iter;
- unsigned int dig_len;
- SECStatus rv = SECFailure;
- unsigned char *state = NULL;
- unsigned int state_len;
- HMACContext *cx = NULL;
-
- hash_size = sec_pkcs5_hash_bits_generated(pbe_param);
- if(hash_size == -1)
- return NULL;
-
- hash_iter = (bits_needed + (unsigned int)hash_size - 1) / hash_size;
- hash_size /= 8;
-
- /* allocate return buffer */
- ret_bits = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(ret_bits == NULL)
- return NULL;
- ret_bits->data = (unsigned char *)PORT_ZAlloc((hash_iter * hash_size) + 1);
- ret_bits->len = (hash_iter * hash_size);
- if(ret_bits->data == NULL) {
- PORT_Free(ret_bits);
- return NULL;
- }
-
- /* allocate intermediate hash buffer. 8 is for the 8 bytes of
- * data which are added based on iteration number
- */
-
- if ((unsigned int)hash_size > pbe_param->salt.len) {
- state_len = hash_size;
- } else {
- state_len = pbe_param->salt.len;
- }
- state = (unsigned char *)PORT_ZAlloc(state_len);
- if(state == NULL) {
- rv = SECFailure;
- goto loser;
- }
- if(pbe_param->salt.len > 0) {
- PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len);
- }
-
- cx = HMAC_Create(sec_pkcs5_hash_algorithm(pbe_param->algorithm),
- init_hash->data, init_hash->len);
- if (cx == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- for(i = 0; i < hash_iter; i++) {
-
- /* generate output bits */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- HMAC_Update(cx, pbe_param->salt.data, pbe_param->salt.len);
- rv = HMAC_Finish(cx, ret_bits->data + (i * hash_size),
- &dig_len, hash_size);
- if (rv != SECSuccess)
- goto loser;
- PORT_Assert((unsigned int)hash_size == dig_len);
-
- /* generate new state */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- rv = HMAC_Finish(cx, state, &state_len, state_len);
- if (rv != SECSuccess)
- goto loser;
- PORT_Assert(state_len == dig_len);
- }
-
-loser:
- if (state != NULL)
- PORT_ZFree(state, state_len);
- HMAC_Destroy(cx);
-
- if(rv != SECSuccess) {
- SECITEM_ZfreeItem(ret_bits, PR_TRUE);
- ret_bits = NULL;
- }
-
- return ret_bits;
-}
-
-/* generate bits for the key and iv determination. if enough bits
- * are not generated using PKCS 5, then we need to generate more bits
- * based on the extension proposed in PKCS 12
- */
-static SECItem *
-sec_pkcs5_generate_bits(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- SECItem * hash = NULL;
- SECItem * newHash = NULL;
- int bits_needed;
- int bits_available;
-
- bits_needed = sec_pkcs5_bits_needed(pbe_param);
- bits_available = sec_pkcs5_hash_bits_generated(pbe_param);
-
- if((bits_needed == -1) || (bits_available == -1)) {
- return NULL;
- }
-
- hash = sec_pkcs5_compute_hash(pbe_param, pwitem, faulty3DES);
- if(hash == NULL) {
- return NULL;
- }
-
- if(bits_needed <= bits_available) {
- return hash;
- }
-
- newHash = sec_pkcs5_bit_generator(pbe_param, hash, bits_needed);
- if (hash != newHash)
- SECITEM_FreeItem(hash, PR_TRUE);
- return newHash;
-}
-
-/* compute the IV as per PKCS 5
- */
-static SECItem *
-sec_pkcs5_compute_iv(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- SECItem *hash = NULL, *iv = NULL;
-
- if((pbe_param == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- /* generate iv */
- iv = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(!iv) {
- return NULL;
- }
-
- iv->len = sec_pkcs5_iv_length(pbe_param->algorithm);
- if(iv->len == -1) {
- PORT_Free(iv);
- return NULL;
- }
-
- iv->data = (unsigned char *)PORT_ZAlloc(iv->len);
- if(iv->data == NULL) {
- PORT_Free(iv);
- return NULL;
- }
-
- if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(pbe_param->algorithm)) {
- SECOidTag hashAlg;
- PBEBitGenContext *ctxt;
- hashAlg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- ctxt = PBE_CreateContext(hashAlg, pbeBitGenCipherIV,
- pwitem, &pbe_param->salt,
- iv->len * 8, pbe_param->iter);
- if(!ctxt) {
- SECITEM_FreeItem(iv, PR_TRUE);
- return NULL;
- }
-
- hash = PBE_GenerateBits(ctxt);
- PBE_DestroyContext(ctxt);
- } else {
- hash = sec_pkcs5_generate_bits(pbe_param, pwitem, faulty3DES);
- }
-
- if(!hash) {
- SECITEM_FreeItem(iv, PR_TRUE);
- return NULL;
- }
-
- PORT_Memcpy(iv->data, (hash->data+(hash->len - iv->len)), iv->len);
- SECITEM_FreeItem(hash, PR_TRUE);
-
- return iv;
-}
-
-/* generate key as per PKCS 5
- */
-static SECItem *
-sec_pkcs5_compute_key(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- SECItem *hash = NULL, *key = NULL;
-
- if((pbe_param == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(!key) {
- return NULL;
- }
-
- key->len = sec_pkcs5_key_length(pbe_param->algorithm);
- if(key->len == -1) {
- PORT_Free(key);
- return NULL;
- }
-
- key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- key->len);
- if(!key->data) {
- PORT_Free(key);
- return NULL;
- }
-
-
- if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(pbe_param->algorithm)) {
- SECOidTag hashAlg;
- PBEBitGenContext *ctxt;
- hashAlg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- ctxt = PBE_CreateContext(hashAlg, pbeBitGenCipherKey,
- pwitem, &pbe_param->salt,
- key->len * 8, pbe_param->iter);
- if(!ctxt) {
- SECITEM_FreeItem(key, PR_TRUE);
- return NULL;
- }
-
- hash = PBE_GenerateBits(ctxt);
- PBE_DestroyContext(ctxt);
- } else {
- hash = sec_pkcs5_generate_bits(pbe_param, pwitem, faulty3DES);
- }
-
- if(!hash) {
- SECITEM_FreeItem(key, PR_TRUE);
- return NULL;
- }
-
- if(pbe_param->algorithm ==
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC) {
- PORT_Memcpy(key->data, hash->data, (key->len * 2) / 3);
- PORT_Memcpy(&(key->data[(key->len * 2) / 3]), key->data,
- key->len / 3);
- } else {
- PORT_Memcpy(key->data, hash->data, key->len);
- }
-
- SECITEM_FreeItem(hash, PR_TRUE);
- return key;
-}
-
-/* decode the algid and generate a PKCS 5 parameter from it
- */
-static SEC_PKCS5PBEParameter *
-sec_pkcs5_convert_algid(SECAlgorithmID *algid)
-{
- PRArenaPool *poolp;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
- SECOidTag algorithm;
- SECStatus rv = SECFailure;
-
- if(algid == NULL)
- return NULL;
-
- algorithm = SECOID_GetAlgorithmTag(algid);
-
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN)
- return NULL;
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
- return NULL;
-
- /* allocate memory for the parameter */
- pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS5PBEParameter));
-
- /* decode parameter */
- if(pbe_param && !sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- pbe_param->poolp = poolp;
- rv = SEC_ASN1DecodeItem(poolp, pbe_param,
- SEC_PKCS5PBEParameterTemplate, &algid->parameters);
- if(rv != SECSuccess) {
- goto loser;
- }
- pbe_param->algorithm = algorithm;
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
- } else if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- pbe_param->algorithm = algorithm;
- pbe_param->poolp = poolp;
- rv = SEC_ASN1DecodeItem(poolp, pbe_param, SEC_V2PKCS12PBEParameterTemplate,
- &algid->parameters);
- if(rv != SECSuccess) {
- goto loser;
- }
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
- }
-
-loser:
- if((pbe_param == NULL) || (rv != SECSuccess)) {
- PORT_FreeArena(poolp, PR_TRUE);
- pbe_param = NULL;
- }
-
- return pbe_param;
-}
-
-/* destroy a pbe parameter. it assumes that the parameter was
- * generated using the appropriate create function and therefor
- * contains an arena pool.
- */
-static void
-sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
-{
- if(pbe_param != NULL)
- PORT_FreeArena(pbe_param->poolp, PR_TRUE);
-}
-
-
-/* crypto routines */
-
-/* function pointer template for crypto functions */
-typedef SECItem *(* pkcs5_crypto_func)(SECItem *key, SECItem *iv,
- SECItem *src, PRBool op1, PRBool op2);
-
-/* map PBE algorithm to crypto algorithm */
-static SECOidTag
-sec_pkcs5_encryption_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- return SEC_OID_DES_EDE3_CBC;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return SEC_OID_DES_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_RC2_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return SEC_OID_RC4;
- default:
- break;
- }
- return SEC_OID_UNKNOWN;
-}
-
-/* perform DES encryption and decryption. these routines are called
- * by SEC_PKCS5CipherData. In the case of an error, NULL is returned.
- */
-static SECItem *
-sec_pkcs5_des(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool triple_des,
- PRBool encrypt)
-{
- SECItem *dest;
- SECItem *dup_src;
- SECStatus rv = SECFailure;
- int pad;
-
- if((src == NULL) || (key == NULL) || (iv == NULL))
- return NULL;
-
- dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
- }
-
- if(encrypt != PR_FALSE) {
- void *dummy;
-
- dummy = DES_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len);
- if(dummy == NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- return NULL;
- }
- dup_src->data = (unsigned char*)dummy;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- /* allocate with over flow */
- dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
- if(dest->data != NULL) {
- DESContext *ctxt;
- ctxt = DES_CreateContext(key->data, iv->data,
- (triple_des ? NSS_DES_EDE3_CBC : NSS_DES_CBC),
- encrypt);
-
- if(ctxt != NULL) {
- rv = ((encrypt != PR_TRUE) ? DES_Decrypt : DES_Encrypt)(
- ctxt, dest->data, &dest->len,
- dup_src->len + 64, dup_src->data, dup_src->len);
-
- /* remove padding -- assumes 64 bit blocks */
- if((encrypt == PR_FALSE) && (rv == SECSuccess)) {
- pad = dest->data[dest->len-1];
- if((pad > 0) && (pad <= 8)) {
- if(dest->data[dest->len-pad] != pad) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- } else {
- dest->len -= pad;
- }
- } else {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- }
- }
- DES_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
-
- if(rv == SECFailure) {
- if(dest != NULL) {
- SECITEM_FreeItem(dest, PR_TRUE);
- }
- dest = NULL;
- }
-
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- }
-
- return dest;
-}
-
-/* perform rc2 encryption/decryption if an error occurs, NULL is returned
- */
-static SECItem *
-sec_pkcs5_rc2(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool cbc_mode,
- PRBool encrypt)
-{
- SECItem *dest;
- SECItem *dup_src;
- SECStatus rv = SECFailure;
- int pad;
-
- if((src == NULL) || (key == NULL) || (iv == NULL)) {
- return NULL;
- }
-
- dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
- }
-
- if(encrypt != PR_FALSE) {
- void *dummy;
-
- dummy = DES_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len);
- if(dummy == NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- return NULL;
- }
- dup_src->data = (unsigned char*)dummy;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
- if(dest->data != NULL) {
- RC2Context *ctxt;
-
- ctxt = RC2_CreateContext(key->data, key->len, iv->data,
- ((cbc_mode != PR_TRUE) ? NSS_RC2 : NSS_RC2_CBC),
- key->len);
-
- if(ctxt != NULL) {
- rv = ((encrypt != PR_TRUE) ? RC2_Decrypt : RC2_Encrypt)(
- ctxt, dest->data, &dest->len,
- dup_src->len + 64, dup_src->data, dup_src->len);
-
- /* assumes 8 byte blocks -- remove padding */
- if((rv == SECSuccess) && (encrypt != PR_TRUE) &&
- (cbc_mode == PR_TRUE)) {
- pad = dest->data[dest->len-1];
- if((pad > 0) && (pad <= 8)) {
- if(dest->data[dest->len-pad] != pad) {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECFailure;
- } else {
- dest->len -= pad;
- }
- } else {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECFailure;
- }
- }
-
- }
- }
- }
-
- if((rv != SECSuccess) && (dest != NULL)) {
- SECITEM_FreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- }
-
- return dest;
-}
-
-/* perform rc4 encryption and decryption */
-static SECItem *
-sec_pkcs5_rc4(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool dummy_op,
- PRBool encrypt)
-{
- SECItem *dest;
- SECStatus rv = SECFailure;
-
- if((src == NULL) || (key == NULL) || (iv == NULL)) {
- return NULL;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- dest->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- (src->len + 64));
- if(dest->data != NULL) {
- RC4Context *ctxt;
-
- ctxt = RC4_CreateContext(key->data, key->len);
- if(ctxt) {
- rv = ((encrypt != PR_FALSE) ? RC4_Decrypt : RC4_Encrypt)(
- ctxt, dest->data, &dest->len,
- src->len + 64, src->data, src->len);
- RC4_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
-
- if((rv != SECSuccess) && (dest)) {
- SECITEM_FreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- return dest;
-}
-
-/* performs the cipher operation on the src and returns the result.
- * if an error occurs, NULL is returned.
- *
- * a null length password is allowed. this corresponds to encrypting
- * the data with ust the salt.
- */
-/* change this to use PKCS 11? */
-SECItem *
-SEC_PKCS5CipherData(SECAlgorithmID *algid,
- SECItem *pwitem,
- SECItem *src,
- PRBool encrypt, PRBool *update)
-{
- SEC_PKCS5PBEParameter *pbe_param;
- SECOidTag enc_alg;
- SECItem *key = NULL, *iv = NULL;
- SECItem *dest = NULL;
- int iv_len;
-
- if (update) {
- *update = PR_FALSE;
- }
-
- if((algid == NULL) || (pwitem == NULL) || (src == NULL)) {
- return NULL;
- }
-
- /* convert algid to pbe parameter */
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL) {
- return NULL;
- }
-
- /* get algorithm, key, and iv */
- enc_alg = sec_pkcs5_encryption_algorithm(pbe_param->algorithm);
- key = sec_pkcs5_compute_key(pbe_param, pwitem, PR_FALSE);
- if(key != NULL) {
- iv_len = sec_pkcs5_iv_length(pbe_param->algorithm);
- iv = sec_pkcs5_compute_iv(pbe_param, pwitem, PR_FALSE);
-
- if((iv != NULL) || (iv_len == 0)) {
- /*perform encryption / decryption */
- PRBool op1 = PR_TRUE;
- pkcs5_crypto_func cryptof;
-
- switch(enc_alg) {
- case SEC_OID_DES_EDE3_CBC:
- cryptof = sec_pkcs5_des;
- break;
- case SEC_OID_DES_CBC:
- cryptof = sec_pkcs5_des;
- op1 = PR_FALSE;
- break;
- case SEC_OID_RC2_CBC:
- cryptof = sec_pkcs5_rc2;
- break;
- case SEC_OID_RC4:
- cryptof = sec_pkcs5_rc4;
- break;
- default:
- cryptof = NULL;
- break;
- }
-
- if(cryptof) {
- dest = (*cryptof)(key, iv, src, op1, encrypt);
- /*
- * it's possible for some keys and keydb's to claim to
- * be triple des when they're really des. In this case
- * we simply try des. If des works we set the update flag
- * so the key db knows it needs to update all it's entries.
- * The case can only happen on decrypted of a
- * SEC_OID_DES_EDE3_CBD.
- */
- if ((dest == NULL) && (encrypt == PR_FALSE) &&
- (enc_alg == SEC_OID_DES_EDE3_CBC)) {
- dest = (*cryptof)(key, iv, src, PR_FALSE, encrypt);
- if (update && (dest != NULL)) *update = PR_TRUE;
- }
- }
- }
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- if(key != NULL) {
- SECITEM_ZfreeItem(key, PR_TRUE);
- }
- if(iv != NULL) {
- SECITEM_ZfreeItem(iv, PR_TRUE);
- }
-
- return dest;
-}
-
-/* creates a algorithm ID containing the PBE algorithm and appropriate
- * parameters. the required parameter is the algorithm. if salt is
- * not specified, it is generated randomly. if IV is specified, it overrides
- * the PKCS 5 generation of the IV.
- *
- * the returned SECAlgorithmID should be destroyed using
- * SECOID_DestroyAlgorithmID
- */
-SECAlgorithmID *
-SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
- SECItem *salt,
- int iteration)
-{
- PRArenaPool *poolp = NULL;
- SECAlgorithmID *algid, *ret_algid;
- SECItem der_param;
- SECStatus rv = SECFailure;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN)
- return NULL;
-
- if(iteration <= 0) {
- return NULL;
- }
-
- der_param.data = NULL;
- der_param.len = 0;
-
- /* generate the parameter */
- pbe_param = sec_pkcs5_create_pbe_parameter(algorithm, salt, iteration);
- if(!pbe_param) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(!poolp) {
- sec_pkcs5_destroy_pbe_param(pbe_param);
- return NULL;
- }
-
- /* generate the algorithm id */
- algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
- if(algid != NULL) {
- void *dummy;
- if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_PKCS5PBEParameterTemplate);
- } else {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_V2PKCS12PBEParameterTemplate);
- }
-
- if(dummy) {
- rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
- }
- }
-
- ret_algid = NULL;
- if(algid != NULL) {
- ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
- if(ret_algid != NULL) {
- rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
- if(rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
- ret_algid = NULL;
- }
- }
- }
-
- if(poolp != NULL) {
- PORT_FreeArena(poolp, PR_TRUE);
- algid = NULL;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return ret_algid;
-}
-
-/* wrapper for converting the algid to a pbe parameter.
- */
-SEC_PKCS5PBEParameter *
-SEC_PKCS5GetPBEParameter(SECAlgorithmID *algid)
-{
- if(algid) {
- return sec_pkcs5_convert_algid(algid);
- }
-
- return NULL;
-}
-
-/* destroy a pbe parameter */
-void
-SEC_PKCS5DestroyPBEParameter(SEC_PKCS5PBEParameter *pbe_param)
-{
- sec_pkcs5_destroy_pbe_param(pbe_param);
-}
-
-/* return the initialization vector either the preset one if it
- * exists or generated based on pkcs 5.
- *
- * a null length password is allowed...but not a null password
- * secitem.
- */
-SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
-{
- SECItem *iv;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if((algid == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(!pbe_param) {
- return NULL;
- }
-
- iv = sec_pkcs5_compute_iv(pbe_param, pwitem, faulty3DES);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return iv;
-}
-
-/* generate the key
- * a 0 length password is allowed. corresponds to a key generated
- * from just the salt.
- */
-SECItem *
-SEC_PKCS5GetKey(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
-{
- SECItem *key;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if((algid == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL) {
- return NULL;
- }
-
- key = sec_pkcs5_compute_key(pbe_param, pwitem, faulty3DES);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return key;
-}
-
-/* retrieve the salt */
-SECItem *
-SEC_PKCS5GetSalt(SECAlgorithmID *algid)
-{
- SECItem *salt;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(algid == NULL)
- return NULL;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return NULL;
-
- if(pbe_param->salt.data) {
- salt = SECITEM_DupItem(&pbe_param->salt);
- } else {
- salt = NULL;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return salt;
-}
-
-/* check to see if an oid is a pbe algorithm
- */
-PRBool
-SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
-{
- SECOidTag algorithm;
-
- algorithm = SECOID_GetAlgorithmTag(algid);
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-int
-SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
-{
- SEC_PKCS5PBEParameter *pbe_param;
- int keyLen = -1;
-
- if(algid == NULL)
- return -1;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return -1;
-
- keyLen = sec_pkcs5_key_length(pbe_param->algorithm);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return keyLen;
-}
-
-/* maps crypto algorithm from PBE algorithm.
- */
-SECOidTag
-SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
-{
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(algid == NULL)
- return SEC_OID_UNKNOWN;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return SEC_OID_UNKNOWN;
-
- switch(pbe_param->algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- return SEC_OID_DES_EDE3_CBC;
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- return SEC_OID_DES_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_RC2_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return SEC_OID_RC4;
- default:
- break;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return SEC_OID_UNKNOWN;
-}
-
-/* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
- */
-SECOidTag
-SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
-{
- switch(algTag)
- {
- case SEC_OID_DES_EDE3_CBC:
- switch(keyLen) {
- case 168:
- case 192:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- case 128:
- case 92:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_DES_CBC:
- return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
- case SEC_OID_RC2_CBC:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- case 128:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_RC4:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- case 128:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- return SEC_OID_UNKNOWN;
-}
-
-/* zero length password and salts are allowed. however, the items
- * containing the salt and password must be non-null.
- */
-PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
-{
- PRArenaPool *arena = NULL;
- PBEBitGenContext *pbeCtxt = NULL;
- HASH_HashType pbeHash;
- int vbytes, ubytes;
-
- unsigned int c;
-
- if(!pwitem || !salt) {
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!arena) {
- return NULL;
- }
-
- pbeCtxt = (PBEBitGenContext*)PORT_ArenaZAlloc(arena, sizeof(PBEBitGenContext));
- if(!pbeCtxt) {
- goto loser;
- }
-
- switch(hashAlgorithm) {
- case SEC_OID_MD2:
- pbeHash = HASH_AlgMD2;
- break;
- case SEC_OID_MD5:
- pbeHash = HASH_AlgMD5;
- break;
- case SEC_OID_SHA1:
- pbeHash = HASH_AlgSHA1;
- break;
- default:
- goto loser;
- }
-
- pbeCtxt->hashObject = &SECRawHashObjects[pbeHash];
- PORT_Memcpy(&pbeCtxt->pbeParams, &pbeHashAlgorithmParams[pbeHash],
- sizeof(pbeBitGenParameters));
- PORT_Assert(pbeCtxt->pbeParams.hashAlgorithm == hashAlgorithm);
-
- vbytes = pbeCtxt->pbeParams.v / 8;
- ubytes = pbeCtxt->pbeParams.u / 8;
-
- c = (bitsNeeded / pbeCtxt->pbeParams.u);
- c += ((bitsNeeded - (pbeCtxt->pbeParams.u * c)) > 0) ? 1 : 0;
- pbeCtxt->c = c;
- pbeCtxt->n = bitsNeeded;
- pbeCtxt->iterations = iterations;
-
- /* allocate buffers */
- pbeCtxt->D.len = vbytes;
- pbeCtxt->S.len = (((salt->len * 8) / pbeCtxt->pbeParams.v) +
- ((((salt->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) *
- vbytes;
- pbeCtxt->P.len = (((pwitem->len * 8) / pbeCtxt->pbeParams.v) +
- ((((pwitem->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) *
- vbytes;
- pbeCtxt->I.len = pbeCtxt->S.len + pbeCtxt->P.len;
- pbeCtxt->A.len = c * ubytes;
- pbeCtxt->B.len = pbeCtxt->D.len;
-
- pbeCtxt->D.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->D.len);
- if(pbeCtxt->S.len) {
- pbeCtxt->S.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->S.len);
- }
- if(pbeCtxt->P.len) {
- pbeCtxt->P.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->P.len);
- }
- if(pbeCtxt->I.len) {
- pbeCtxt->I.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->I.len);
- }
- pbeCtxt->A.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->A.len);
- pbeCtxt->B.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->B.len);
-
- if(!pbeCtxt->D.data || !pbeCtxt->A.data || !pbeCtxt->B.data ||
- (!pbeCtxt->S.data && pbeCtxt->S.len) ||
- (!pbeCtxt->P.data && pbeCtxt->P.len) ||
- (!pbeCtxt->I.data && pbeCtxt->I.len)) {
- goto loser;
- }
-
- PORT_Memset(pbeCtxt->D.data, (char)bitGenPurpose, pbeCtxt->D.len);
- if(pbeCtxt->P.len) {
- unsigned int z = 0;
- while(z < pbeCtxt->P.len) {
- PORT_Memcpy(&(pbeCtxt->P.data[z]), pwitem->data,
- ((z + pwitem->len > pbeCtxt->P.len) ? (pbeCtxt->P.len - z) :
- (pwitem->len)));
- z += pwitem->len;
- }
- }
- if(pbeCtxt->S.len) {
- unsigned int z = 0;
- while(z < pbeCtxt->S.len) {
- PORT_Memcpy(&(pbeCtxt->S.data[z]), salt->data,
- ((z + salt->len > pbeCtxt->S.len) ? (pbeCtxt->S.len - z) :
- (salt->len)));
- z += salt->len;
- }
- }
- if(pbeCtxt->I.len) {
- if(pbeCtxt->S.len) {
- PORT_Memcpy(pbeCtxt->I.data, pbeCtxt->S.data, pbeCtxt->S.len);
- }
- if(pbeCtxt->P.len) {
- PORT_Memcpy(&(pbeCtxt->I.data[pbeCtxt->S.len]), pbeCtxt->P.data,
- pbeCtxt->P.len);
- }
- }
-
- pbeCtxt->arena = arena;
-
- return pbeCtxt;
-
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- return NULL;
-}
-
-SECItem *
-PBE_GenerateBits(PBEBitGenContext *pbeCtxt)
-{
- unsigned int i;
- SECItem *A, *D, *I, *B, *S, *P;
- unsigned int u, v, c, z, hashLen, n, iter;
- unsigned int vbyte, ubyte;
- unsigned char *iterBuf;
- void *hash = NULL;
-
- if(!pbeCtxt) {
- return NULL;
- }
-
- A = &pbeCtxt->A;
- B = &pbeCtxt->B;
- I = &pbeCtxt->I;
- D = &pbeCtxt->D;
- S = &pbeCtxt->S;
- P = &pbeCtxt->P;
- u = pbeCtxt->pbeParams.u;
- v = pbeCtxt->pbeParams.v;
- vbyte = v / 8;
- ubyte = u / 8;
- c = pbeCtxt->c;
- n = pbeCtxt->n;
- z = 0;
-
- iterBuf = (unsigned char*)PORT_Alloc(ubyte);
- if(!iterBuf) {
- goto loser;
- }
-
- for(i = 1; i <= c; i++) {
- unsigned int Bidx;
- unsigned int k, j;
-
-
- for(iter = 1; iter <= pbeCtxt->iterations; iter++) {
- hash = pbeCtxt->hashObject->create();
- if(!hash) {
- goto loser;
- }
-
- pbeCtxt->hashObject->begin(hash);
-
- if(iter == 1) {
- pbeCtxt->hashObject->update(hash, D->data, D->len);
- pbeCtxt->hashObject->update(hash, I->data, I->len);
- } else {
- pbeCtxt->hashObject->update(hash, iterBuf, hashLen);
- }
-
- pbeCtxt->hashObject->end(hash, iterBuf, &hashLen, (ubyte));
- pbeCtxt->hashObject->destroy(hash, PR_TRUE);
- if(hashLen != (ubyte)) {
- goto loser;
- }
- }
-
- PORT_Memcpy(&(A->data[z]), iterBuf, (ubyte));
-
- Bidx = 0;
- while(Bidx < B->len) {
- PORT_Memcpy(&(B->data[Bidx]), &(A->data[z]),
- (((Bidx + (ubyte)) > B->len) ? (B->len - Bidx) :
- (ubyte)));
- Bidx += (ubyte);
- }
-
- k = (S->len / (vbyte)) + (P->len / (vbyte));
- for(j = 0; j < k; j++) {
- unsigned int byteIdx = (vbyte);
- unsigned int q, carryBit = 0;
-
- while(byteIdx > 0) {
- q = (unsigned int)I->data[(j * (vbyte)) + byteIdx - 1];
- q += (unsigned int)B->data[byteIdx - 1];
- q += carryBit;
- if(byteIdx == (vbyte)) {
- q += 1;
- }
-
- carryBit = ((q > 255) ? 1 : 0);
-
- I->data[(j * (vbyte)) + byteIdx - 1] = (unsigned char)(q & 255);
-
- byteIdx--;
- }
- }
-
- z += (ubyte);
- }
-
- A->len = (n / 8);
-
- return SECITEM_DupItem(A);
-
-loser:
- return NULL;
-}
-
-void
-PBE_DestroyContext(PBEBitGenContext *pbeCtxt) {
- if(pbeCtxt) {
- PORT_FreeArena(pbeCtxt->arena, PR_TRUE);
- }
-}
-
-SECStatus
-PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena,
- SECAlgorithmID *algId)
-{
- CK_PBE_PARAMS *pbe_param;
- SECItem pbeSalt;
- SECAlgorithmID *pbeAlgID = NULL;
- SECStatus rv;
-
- if(!param || !algId) {
- return SECFailure;
- }
-
- pbe_param = (CK_PBE_PARAMS *)param->data;
- pbeSalt.data = (unsigned char *)pbe_param->pSalt;
- pbeSalt.len = pbe_param->ulSaltLen;
- pbeAlgID = SEC_PKCS5CreateAlgorithmID(algTag, &pbeSalt,
- (int)pbe_param->ulIteration);
- if(!pbeAlgID) {
- return SECFailure;
- }
-
- rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID);
- SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE);
- return rv;
-}
diff --git a/security/nss/lib/softoken/secpkcs5.h b/security/nss/lib/softoken/secpkcs5.h
deleted file mode 100644
index 4efe99900..000000000
--- a/security/nss/lib/softoken/secpkcs5.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#ifndef _SECPKCS5_H_
-#define _SECPKCS5_H_
-
-#include "plarena.h"
-#include "secitem.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "hasht.h"
-
-typedef SECItem * (* SEC_PKCS5GetPBEPassword)(void *arg);
-
-/* used for V2 PKCS 12 Draft Spec */
-typedef enum {
- pbeBitGenIDNull,
- pbeBitGenCipherKey = 0x01,
- pbeBitGenCipherIV = 0x02,
- pbeBitGenIntegrityKey = 0x03
-} PBEBitGenID;
-
-typedef struct _pbeBitGenParameters {
- unsigned int u, v;
- SECOidTag hashAlgorithm;
-} pbeBitGenParameters;
-
-typedef struct _PBEBitGenContext {
- PRArenaPool *arena;
-
- /* hash algorithm information */
- pbeBitGenParameters pbeParams;
- SECHashObject *hashObject;
- void *hash;
-
- /* buffers used in generation of bits */
- SECItem D, S, P, I, A, B;
- unsigned int c, n;
- unsigned int iterations;
-} PBEBitGenContext;
-
-extern const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[];
-typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
-
-struct SEC_PKCS5PBEParameterStr {
- PRArenaPool *poolp;
- SECItem salt; /* octet string */
- SECItem iteration; /* integer */
-
- /* used locally */
- SECOidTag algorithm;
- int iter;
-};
-
-
-SEC_BEGIN_PROTOS
-/* Create a PKCS5 Algorithm ID
- * The algorithm ID is set up using the PKCS #5 parameter structure
- * algorithm is the PBE algorithm ID for the desired algorithm
- * salt can be specified or can be NULL, if salt is NULL then the
- * salt is generated from random bytes
- * iteration is the number of iterations for which to perform the
- * hash prior to key and iv generation.
- * If an error occurs or the algorithm specified is not supported
- * or is not a password based encryption algorithm, NULL is returned.
- * Otherwise, a pointer to the algorithm id is returned.
- */
-extern SECAlgorithmID *
-SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
- SECItem *salt,
- int iteration);
-
-/* Get the initialization vector. The password is passed in, hashing
- * is performed, and the initialization vector is returned.
- * algid is a pointer to a PBE algorithm ID
- * pwitem is the password
- * If an error occurs or the algorithm id is not a PBE algrithm,
- * NULL is returned. Otherwise, the iv is returned in a secitem.
- */
-extern SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
-
-/* Get the key. The password is passed in, hashing is performed,
- * and the key is returned.
- * algid is a pointer to a PBE algorithm ID
- * pwitem is the password
- * If an error occurs or the algorithm id is not a PBE algrithm,
- * NULL is returned. Otherwise, the key is returned in a secitem.
- */
-extern SECItem *
-SEC_PKCS5GetKey(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
-
-/* Get PBE salt. The salt for the password based algorithm is returned.
- * algid is the PBE algorithm identifier
- * If an error occurs NULL is returned, otherwise the salt is returned
- * in a SECItem.
- */
-extern SECItem *
-SEC_PKCS5GetSalt(SECAlgorithmID *algid);
-
-/* Encrypt/Decrypt data using password based encryption.
- * algid is the PBE algorithm identifier,
- * pwitem is the password,
- * src is the source for encryption/decryption,
- * encrypt is PR_TRUE for encryption, PR_FALSE for decryption.
- * The key and iv are generated based upon PKCS #5 then the src
- * is either encrypted or decrypted. If an error occurs, NULL
- * is returned, otherwise the ciphered contents is returned.
- */
-extern SECItem *
-SEC_PKCS5CipherData(SECAlgorithmID *algid, SECItem *pwitem,
- SECItem *src, PRBool encrypt, PRBool *update);
-
-/* Checks to see if algid algorithm is a PBE algorithm. If
- * so, PR_TRUE is returned, otherwise PR_FALSE is returned.
- */
-extern PRBool
-SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid);
-
-/* Destroys PBE parameter */
-extern void
-SEC_PKCS5DestroyPBEParameter(SEC_PKCS5PBEParameter *param);
-
-/* Convert Algorithm ID to PBE parameter */
-extern SEC_PKCS5PBEParameter *
-SEC_PKCS5GetPBEParameter(SECAlgorithmID *algid);
-
-/* Determine how large the key generated is */
-extern int
-SEC_PKCS5GetKeyLength(SECAlgorithmID *algid);
-
-/* map crypto algorithm to pbe algorithm, assume sha 1 hashing for DES
- */
-extern SECOidTag
-SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen);
-
-/* return the underlying crypto algorithm */
-extern SECOidTag
-SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid);
-
-extern PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int interations);
-
-extern SECItem *
-PBE_GenerateBits(PBEBitGenContext *pbeCtxt);
-
-extern void PBE_DestroyContext(PBEBitGenContext *pbeCtxt);
-
-extern SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param,
- PRArenaPool *arena, SECAlgorithmID *algId);
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h
deleted file mode 100644
index 733fdbede..000000000
--- a/security/nss/lib/softoken/softoken.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * softoken.h - private data structures and prototypes for the softoken lib
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#ifndef _SOFTOKEN_H_
-#define _SOFTOKEN_H_
-
-#include "blapi.h"
-#include "keytlow.h"
-#include "keytboth.h"
-#include "softoknt.h"
-#include "secoidt.h"
-
-#include "pkcs11t.h" /* CK_RV Required for pk11_fipsPowerUpSelfTest(). */
-
-SEC_BEGIN_PROTOS
-
-/*
-** RSA encryption/decryption. When encrypting/decrypting the output
-** buffer must be at least the size of the public key modulus.
-*/
-
-/*
-** Format some data into a PKCS#1 encryption block, preparing the
-** data for RSA encryption.
-** "result" where the formatted block is stored (memory is allocated)
-** "modulusLen" the size of the formatted block
-** "blockType" what block type to use (SEC_RSABlock*)
-** "data" the data to format
-*/
-extern SECStatus RSA_FormatBlock(SECItem *result,
- unsigned int modulusLen,
- RSA_BlockType blockType,
- SECItem *data);
-/*
-** Similar, but just returns a pointer to the allocated memory, *and*
-** will *only* format one block, even if we (in the future) modify
-** RSA_FormatBlock() to loop over multiples of modulusLen.
-*/
-extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen,
- RSA_BlockType blockType,
- SECItem *data);
-
-
-
-/*
- * convenience wrappers for doing single RSA operations. They create the
- * RSA context internally and take care of the formatting
- * requirements. Blinding happens automagically within RSA_SignHash and
- * RSA_DecryptBlock.
- */
-extern
-SECStatus RSA_Sign(SECKEYLowPrivateKey *key, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- unsigned char *input, unsigned int inputLen);
-extern
-SECStatus RSA_CheckSign(SECKEYLowPublicKey *key, unsigned char *sign,
- unsigned int signLength, unsigned char *hash,
- unsigned int hashLength);
-extern
-SECStatus RSA_CheckSignRecover(SECKEYLowPublicKey *key, unsigned char *data,
- unsigned int *data_len,unsigned int max_output_len,
- unsigned char *sign, unsigned int sign_len);
-extern
-SECStatus RSA_EncryptBlock(SECKEYLowPublicKey *key, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- unsigned char *input, unsigned int inputLen);
-extern
-SECStatus RSA_DecryptBlock(SECKEYLowPrivateKey *key, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- unsigned char *input, unsigned int inputLen);
-
-/*
- * added to make pkcs #11 happy
- * RAW is RSA_X_509
- */
-extern
-SECStatus RSA_SignRaw( SECKEYLowPrivateKey *key, unsigned char *output,
- unsigned int *output_len, unsigned int maxOutputLen,
- unsigned char *input, unsigned int input_len);
-extern
-SECStatus RSA_CheckSignRaw( SECKEYLowPublicKey *key, unsigned char *sign,
- unsigned int sign_len, unsigned char *hash,
- unsigned int hash_len);
-extern
-SECStatus RSA_CheckSignRecoverRaw( SECKEYLowPublicKey *key, unsigned char *data,
- unsigned int *data_len, unsigned int max_output_len,
- unsigned char *sign, unsigned int sign_len);
-extern
-SECStatus RSA_EncryptRaw( SECKEYLowPublicKey *key, unsigned char *output,
- unsigned int *output_len,
- unsigned int max_output_len,
- unsigned char *input, unsigned int input_len);
-extern
-SECStatus RSA_DecryptRaw(SECKEYLowPrivateKey *key, unsigned char *output,
- unsigned int *output_len,
- unsigned int max_output_len,
- unsigned char *input, unsigned int input_len);
-
-
-/*
-** Functions called directly by applications to configure the FIPS token.
-*/
-extern void PK11_ConfigurePKCS11(char *man, char *libdes, char *tokdes,
- char *ptokdes, char *slotdes, char *pslotdes, char *fslotdes,
- char *fpslotdes, int minPwd, int pwdRequired);
-extern void PK11_ConfigureFIPS(char *slotdes, char *pslotdes);
-
-/*
-** Prepare a buffer for DES encryption, growing to the appropriate boundary,
-** filling with the appropriate padding.
-** We add from 1 to DES_KEY_LENGTH bytes -- we *always* grow.
-** The extra bytes contain the value of the length of the padding:
-** if we have 2 bytes of padding, then the padding is "0x02, 0x02".
-**
-** NOTE: If arena is non-NULL, we re-allocate from there, otherwise
-** we assume (and use) PR memory (re)allocation.
-** Maybe this belongs in util?
-*/
-extern unsigned char * DES_PadBuffer(PRArenaPool *arena, unsigned char *inbuf,
- unsigned int inlen, unsigned int *outlen);
-
-
-/****************************************/
-/*
-** Power-Up selftests required for FIPS and invoked only
-** under PKCS #11 FIPS mode.
-*/
-extern CK_RV pk11_fipsPowerUpSelfTest( void );
-
-
-SEC_END_PROTOS
-
-#endif /* _SOFTOKEN_H_ */
diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h
deleted file mode 100644
index da66c9042..000000000
--- a/security/nss/lib/softoken/softoknt.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * softoknt.h - public data structures for the software token library
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * $Id$
- */
-
-#ifndef _SOFTOKNT_H_
-#define _SOFTOKNT_H_
-
-/*
- * RSA block types
- *
- * The actual values are important -- they are fixed, *not* arbitrary.
- * The explicit value assignments are not needed (because C would give
- * us those same values anyway) but are included as a reminder...
- */
-typedef enum {
- RSA_BlockPrivate0 = 0, /* unused, really */
- RSA_BlockPrivate = 1, /* pad for a private-key operation */
- RSA_BlockPublic = 2, /* pad for a public-key operation */
- RSA_BlockOAEP = 3, /* use OAEP padding */
- /* XXX is this only for a public-key
- operation? If so, add "Public" */
- RSA_BlockRaw = 4, /* simply justify the block appropriately */
- RSA_BlockTotal
-} RSA_BlockType;
-
-#define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
-
-#endif /* _SOFTOKNT_H_ */