diff options
Diffstat (limited to 'security/nss/lib/softoken')
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_ */ |