Initial NSS Open Source Checkin

This commit is contained in:
relyea%netscape.com 2000-03-31 19:16:26 +00:00
parent c7560e3856
commit 8c4b7edd1d
66 changed files with 50361 additions and 0 deletions

View File

@ -0,0 +1,77 @@
#! 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

View File

@ -0,0 +1,44 @@
#
# 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 =

View File

@ -0,0 +1,62 @@
#
# 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 = ../../..
EXPORTS = \
secmod.h \
secmodt.h \
pk11func.h \
$(NULL)
PRIVATE_EXPORTS = \
secmodi.h \
secmodti.h \
$(NULL)
MODULE = security
CSRCS = \
pk11cert.c \
pk11err.c \
pk11load.c \
pk11slot.c \
pk11db.c \
pk11list.c \
pk11skey.c \
pk11kea.c \
pk11util.c \
$(NULL)
REQUIRES = security dbm
LIBRARY_NAME = pk11wrap

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,643 @@
/*
* 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.
*/
/*
* The following code handles the storage of PKCS 11 modules used by the
* NSS. This file is written to abstract away how the modules are
* stored so we can deside that later.
*/
#include "seccomon.h"
#include "secmod.h"
#include "prlock.h"
#include "pkcs11.h"
#include "secmodi.h"
#include "pk11func.h"
#include "mcom_db.h"
/* create a new module */
SECMODModule *SECMOD_NewModule(void) {
SECMODModule *newMod;
PRArenaPool *arena;
/* create an arena in which dllName and commonName can be
* allocated.
*/
arena = PORT_NewArena(512);
if (arena == NULL) {
return NULL;
}
newMod = (SECMODModule *)PORT_ArenaAlloc(arena,sizeof (SECMODModule));
if (newMod == NULL) {
PORT_FreeArena(arena,PR_FALSE);
return NULL;
}
/*
* initialize of the fields of the module
*/
newMod->arena = arena;
newMod->internal = PR_FALSE;
newMod->loaded = PR_FALSE;
newMod->isFIPS = PR_FALSE;
newMod->dllName = NULL;
newMod->commonName = NULL;
newMod->library = NULL;
newMod->functionList = NULL;
newMod->slotCount = 0;
newMod->slots = NULL;
newMod->slotInfo = NULL;
newMod->slotInfoCount = 0;
newMod->refCount = 1;
newMod->ssl[0] = 0;
newMod->ssl[1] = 0;
#ifdef PKCS11_USE_THREADS
newMod->refLock = (void *)PR_NewLock();
if (newMod->refLock == NULL) {
PORT_FreeArena(arena,PR_FALSE);
return NULL;
}
#else
newMod->refLock = NULL;
#endif
return newMod;
}
/* create a new ModuleListElement */
SECMODModuleList *SECMOD_NewModuleListElement(void) {
SECMODModuleList *newModList;
newModList= (SECMODModuleList *) PORT_Alloc(sizeof(SECMODModuleList));
if (newModList) {
newModList->next = NULL;
newModList->module = NULL;
}
return newModList;
}
static unsigned long internalFlags = SECMOD_RSA_FLAG|SECMOD_DSA_FLAG|
SECMOD_RC2_FLAG| SECMOD_RC4_FLAG|SECMOD_DES_FLAG|SECMOD_RANDOM_FLAG|
SECMOD_SHA1_FLAG|SECMOD_MD5_FLAG|SECMOD_MD2_FLAG;
/* create a Internal module */
SECMODModule *SECMOD_NewInternal(void) {
SECMODModule *intern;
static PK11PreSlotInfo internSlotInfo =
{ 1, SECMOD_RSA_FLAG|SECMOD_DSA_FLAG|SECMOD_RC2_FLAG|
SECMOD_RC4_FLAG|SECMOD_DES_FLAG|SECMOD_RANDOM_FLAG|
SECMOD_SHA1_FLAG|SECMOD_MD5_FLAG|SECMOD_MD2_FLAG, -1, 30 };
intern = SECMOD_NewModule();
if (intern == NULL) {
return NULL;
}
/*
* make this module an internal module
*/
intern->commonName = "Netscape Internal PKCS #11 Module";
intern->internal = PR_TRUE;
intern->slotInfoCount = 1;
intern->slotInfo = &internSlotInfo;
return (intern);
}
/* create a FIPS Internal module */
SECMODModule *SECMOD_GetFIPSInternal(void) {
SECMODModule *intern;
intern = SECMOD_NewInternal();
if (intern == NULL) {
return NULL;
}
/*
* make this module a FIPS internal module
*/
intern->slotInfo[0].slotID = 3; /* FIPS slot */
intern->commonName = "Netscape Internal FIPS PKCS #11 Module";
intern->isFIPS = PR_TRUE;
return (intern);
}
SECMODModule *SECMOD_DupModule(SECMODModule *old) {
SECMODModule *newMod;
newMod = SECMOD_NewModule();
if (newMod == NULL) {
return NULL;
}
/*
* initialize of the fields of the module
*/
newMod->dllName = PORT_ArenaStrdup(newMod->arena,old->dllName);
newMod->commonName = PORT_ArenaStrdup(newMod->arena,old->commonName);;
return newMod;
}
/*
* make a new reference to a module so It doesn't go away on us
*/
SECMODModule *
SECMOD_ReferenceModule(SECMODModule *module) {
PK11_USE_THREADS(PR_Lock((PRLock *)module->refLock);)
PORT_Assert(module->refCount > 0);
module->refCount++;
PK11_USE_THREADS(PR_Unlock((PRLock*)module->refLock);)
return module;
}
/* destroy an existing module */
void
SECMOD_DestroyModule(SECMODModule *module) {
PRBool willfree = PR_FALSE;
int slotCount;
int i;
PK11_USE_THREADS(PR_Lock((PRLock *)module->refLock);)
if (module->refCount-- == 1) {
willfree = PR_TRUE;
}
PORT_Assert(willfree || (module->refCount > 0));
PK11_USE_THREADS(PR_Unlock((PRLock *)module->refLock);)
if (!willfree) {
return;
}
/* slots can't really disappear until our module starts freeing them,
* so this check is safe */
slotCount = module->slotCount;
if (slotCount == 0) {
SECMOD_SlotDestroyModule(module,PR_FALSE);
return;
}
/* now free all out slots, when they are done, they will cause the
* module to disappear altogether */
for (i=0 ; i < slotCount; i++) {
if (!module->slots[i]->disabled) {
PK11_ClearSlotList(module->slots[i]);
}
PK11_FreeSlot(module->slots[i]);
}
/* WARNING: once the last slot has been freed is it possible (even likely)
* that module is no more... touching it now is a good way to go south */
}
/* we can only get here if we've destroyed the module, or some one has
* erroneously freed a slot that wasn't referenced. */
void
SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot) {
PRBool willfree = PR_FALSE;
if (fromSlot) {
PORT_Assert(module->refCount == 0);
PK11_USE_THREADS(PR_Lock((PRLock *)module->refLock);)
if (module->slotCount-- == 1) {
willfree = PR_TRUE;
}
PORT_Assert(willfree || (module->slotCount > 0));
PK11_USE_THREADS(PR_Unlock((PRLock *)module->refLock);)
if (!willfree) return;
}
if (module->loaded) {
SECMOD_UnloadModule(module);
}
PK11_USE_THREADS(PR_DestroyLock((PRLock *)module->refLock);)
PORT_FreeArena(module->arena,PR_FALSE);
}
/* destroy a list element
* this destroys a single element, and returns the next element
* on the chain. It makes it easy to implement for loops to delete
* the chain. It also make deleting a single element easy */
SECMODModuleList *
SECMOD_DestroyModuleListElement(SECMODModuleList *element) {
SECMODModuleList *next = element->next;
if (element->module) {
SECMOD_DestroyModule(element->module);
element->module = NULL;
}
PORT_Free(element);
return next;
}
/*
* Destroy an entire module list
*/
void
SECMOD_DestroyModuleList(SECMODModuleList *list) {
SECMODModuleList *lp;
for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ;
}
/* Construct a database key for a given module */
static SECStatus secmod_MakeKey(DBT *key, SECMODModule * module) {
int len = 0;
len = PORT_Strlen(module->commonName);
key->data = module->commonName;
key->size = len;
return SECSuccess;
}
/* free out constructed database key */
static void secmod_FreeKey(DBT *key) {
key->data = NULL;
key->size = 0;
}
typedef struct secmodDataStr secmodData;
typedef struct secmodSlotDataStr secmodSlotData;
struct secmodDataStr {
unsigned char major;
unsigned char minor;
unsigned char nameStart[2];
unsigned char slotOffset[2];
unsigned char internal;
unsigned char fips;
unsigned char ssl[8];
unsigned char names[4]; /* enough space for the length fields */
};
struct secmodSlotDataStr {
unsigned char slotID[4];
unsigned char defaultFlags[4];
unsigned char timeout[4];
unsigned char askpw;
unsigned char reserved[19]; /* this makes it a round 32 bytes */
};
#define SECMOD_DB_VERSION_MAJOR 0
#define SECMOD_DB_VERSION_MINOR 4
#define SECMOD_DB_NOUI_VERSION_MAJOR 0
#define SECMOD_DB_NOUI_VERSION_MINOR 3
#define SECMOD_PUTSHORT(dest,src) \
(dest)[1] = (unsigned char) ((src)&0xff); \
(dest)[0] = (unsigned char) (((src) >> 8) & 0xff);
#define SECMOD_PUTLONG(dest,src) \
(dest)[3] = (unsigned char) ((src)&0xff); \
(dest)[2] = (unsigned char) (((src) >> 8) & 0xff); \
(dest)[1] = (unsigned char) (((src) >> 16) & 0xff); \
(dest)[0] = (unsigned char) (((src) >> 24) & 0xff);
#define SECMOD_GETSHORT(src) \
((unsigned short) (((src)[0] << 8) | (src)[1]))
#define SECMOD_GETLONG(src) \
((unsigned long) (( (unsigned long) (src)[0] << 24) | \
( (unsigned long) (src)[1] << 16) | \
( (unsigned long) (src)[2] << 8) | \
(unsigned long) (src)[3]))
/*
* build a data base entry from a module
*/
static SECStatus secmod_EncodeData(DBT *data, SECMODModule * module) {
secmodData *encoded;
secmodSlotData *slot;
unsigned char *dataPtr;
unsigned short len, len2 = 0,count = 0;
unsigned short offset;
int dataLen, i, si;
len = PORT_Strlen(module->commonName);
if (module->dllName) {
len2 = PORT_Strlen(module->dllName);
}
if (module->slotCount != 0) {
for (i=0; i < module->slotCount; i++) {
if (module->slots[i]->defaultFlags != 0) {
count++;
}
}
} else {
count = module->slotInfoCount;
}
dataLen = sizeof(secmodData) + len + len2 + 2 +
count*sizeof(secmodSlotData);
data->data = (unsigned char *)
PORT_Alloc(dataLen);
encoded = (secmodData *)data->data;
dataPtr = (unsigned char *) data->data;
data->size = dataLen;
if (encoded == NULL) return SECFailure;
encoded->major = SECMOD_DB_VERSION_MAJOR;
encoded->minor = SECMOD_DB_VERSION_MINOR;
encoded->internal = (unsigned char) (module->internal ? 1 : 0);
encoded->fips = (unsigned char) (module->isFIPS ? 1 : 0);
SECMOD_PUTLONG(encoded->ssl,module->ssl[0]);
SECMOD_PUTLONG(&encoded->ssl[4],module->ssl[1]);
offset = (unsigned long) &(((secmodData *)0)->names[0]);
SECMOD_PUTSHORT(encoded->nameStart,offset);
offset = offset +len + len2 + 4;
SECMOD_PUTSHORT(encoded->slotOffset,offset);
SECMOD_PUTSHORT(&dataPtr[offset],count);
slot = (secmodSlotData *)(dataPtr+offset+2);
SECMOD_PUTSHORT(encoded->names,len);
PORT_Memcpy(&encoded->names[2],module->commonName,len);
SECMOD_PUTSHORT(&encoded->names[len+2],len2);
if (len2) PORT_Memcpy(&encoded->names[len+4],module->dllName,len2);
if (module->slotCount) {
for (i=0,si=0; i < module->slotCount; i++) {
if (module->slots[i]->defaultFlags) {
SECMOD_PUTLONG(slot[si].slotID, module->slots[i]->slotID);
SECMOD_PUTLONG(slot[si].defaultFlags,
module->slots[i]->defaultFlags);
SECMOD_PUTLONG(slot[si].timeout,module->slots[i]->timeout);
slot[si].askpw = module->slots[i]->askpw;
PORT_Memset(slot[si].reserved, 0, sizeof(slot[si].reserved));
si++;
}
}
} else {
for (i=0; i < module->slotInfoCount; i++) {
SECMOD_PUTLONG(slot[i].slotID, module->slotInfo[i].slotID);
SECMOD_PUTLONG(slot[i].defaultFlags,
module->slotInfo[i].defaultFlags);
SECMOD_PUTLONG(slot[i].timeout,module->slotInfo[i].timeout);
slot[i].askpw = module->slotInfo[i].askpw;
PORT_Memset(slot[i].reserved, 0, sizeof(slot[i].reserved));
}
}
return SECSuccess;
}
static void secmod_FreeData(DBT *data) {
if (data->data) {
PORT_Free(data->data);
}
}
/*
* build a module from the data base entry.
*/
static SECMODModule *secmod_DecodeData(DBT *data) {
SECMODModule * module;
secmodData *encoded;
secmodSlotData *slots;
unsigned char *names;
unsigned short len,len1;
unsigned long slotCount;
unsigned short offset;
PRBool isOldVersion = PR_FALSE;
int i;
encoded = (secmodData *)data->data;
names = (unsigned char *)data->data;
offset = SECMOD_GETSHORT(encoded->slotOffset);
slots = (secmodSlotData *) (names + offset + 2);
slotCount = SECMOD_GETSHORT(names + offset);
names += SECMOD_GETSHORT(encoded->nameStart);
module = SECMOD_NewModule();
if (module == NULL) return NULL;
module->internal = (encoded->internal != 0) ? PR_TRUE: PR_FALSE;
module->isFIPS = (encoded->fips != 0) ? PR_TRUE: PR_FALSE;
len = SECMOD_GETSHORT(names);
if (module->internal && (encoded->major == SECMOD_DB_NOUI_VERSION_MAJOR) &&
(encoded->minor <= SECMOD_DB_NOUI_VERSION_MINOR)) {
isOldVersion = PR_TRUE;
}
/* decode the common name */
module->commonName = (char*)PORT_ArenaAlloc(module->arena,len+1);
if (module->commonName == NULL) {
SECMOD_DestroyModule(module);
return NULL;
}
PORT_Memcpy(module->commonName,&names[2],len);
module->commonName[len] = 0;
/* decode the DLL name */
len1 = (names[len+2] << 8) | names[len+3];
if (len1) {
module->dllName = (char*)PORT_ArenaAlloc(module->arena,len1 + 1);
if (module->dllName == NULL) {
SECMOD_DestroyModule(module);
return NULL;
}
PORT_Memcpy(module->dllName,&names[len+4],len1);
module->dllName[len1] = 0;
}
module->slotInfoCount = slotCount;
module->slotInfo = (PK11PreSlotInfo *) PORT_ArenaAlloc(module->arena,
slotCount * sizeof(PK11PreSlotInfo));
for (i=0; i < (int) slotCount; i++) {
module->slotInfo[i].slotID = SECMOD_GETLONG(slots[i].slotID);
module->slotInfo[i].defaultFlags =
SECMOD_GETLONG(slots[i].defaultFlags);
if (isOldVersion && module->internal &&
(module->slotInfo[i].slotID != 2)) {
module->slotInfo[i].defaultFlags |= internalFlags;
}
module->slotInfo[i].timeout = SECMOD_GETLONG(slots[i].timeout);
module->slotInfo[i].askpw = slots[i].askpw;
if (module->slotInfo[i].askpw == 0xff) {
module->slotInfo[i].askpw = -1;
}
}
/* decode SSL cipher enable flags */
module->ssl[0] = SECMOD_GETLONG(encoded->ssl);
module->ssl[1] = SECMOD_GETLONG(&encoded->ssl[4]);
return (module);
}
/*
* open the PKCS #11 data base.
*/
static char *pkcs11dbName = NULL;
void SECMOD_InitDB(char *dbname) {
pkcs11dbName = PORT_Strdup(dbname);
}
static DB *secmod_OpenDB(PRBool readOnly) {
DB *pkcs11db = NULL;
char *dbname;
if (pkcs11dbName == NULL) return NULL;
dbname = pkcs11dbName;
/* I'm sure we should do more checks here sometime... */
pkcs11db = dbopen(dbname, readOnly ? O_RDONLY : O_RDWR, 0600, DB_HASH, 0);
/* didn't exist? create it */
if (pkcs11db == NULL) {
if (readOnly) return NULL;
pkcs11db = dbopen( dbname,
O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
if (pkcs11db) (* pkcs11db->sync)(pkcs11db, 0);
}
return pkcs11db;
}
static void secmod_CloseDB(DB *pkcs11db) {
(*pkcs11db->close)(pkcs11db);
}
/*
* Read all the existing modules in
*/
SECMODModuleList *
SECMOD_ReadPermDB(void) {
DBT key,data;
int ret;
DB *pkcs11db = NULL;
SECMODModuleList *newmod = NULL,*mod = NULL;
pkcs11db = secmod_OpenDB(PR_TRUE);
if (pkcs11db == NULL) {
return NULL;
}
/* read and parse the file or data base */
ret = (*pkcs11db->seq)(pkcs11db, &key, &data, R_FIRST);
if (ret) goto done;
do {
/* allocate space for modules */
newmod = SECMOD_NewModuleListElement();
if (newmod == NULL) break;
newmod->module = secmod_DecodeData(&data);
if (newmod->module == NULL) {
SECMOD_DestroyModuleListElement(newmod);
break;
}
newmod->next = mod;
mod = newmod;
} while ( (*pkcs11db->seq)(pkcs11db, &key, &data, R_NEXT) == 0);
done:
secmod_CloseDB(pkcs11db);
return mod;
}
/*
* Delete a module from the Data Base
*/
SECStatus
SECMOD_DeletePermDB(SECMODModule * module) {
DBT key;
SECStatus rv = SECFailure;
DB *pkcs11db = NULL;
int ret;
/* make sure we have a db handle */
pkcs11db = secmod_OpenDB(PR_FALSE);
if (pkcs11db == NULL) {
return SECFailure;
}
rv = secmod_MakeKey(&key,module);
if (rv != SECSuccess) goto done;
rv = SECFailure;
ret = (*pkcs11db->del)(pkcs11db, &key, 0);
secmod_FreeKey(&key);
if (ret != 0) goto done;
ret = (*pkcs11db->sync)(pkcs11db, 0);
if (ret == 0) rv = SECSuccess;
done:
secmod_CloseDB(pkcs11db);
return rv;
}
/*
* Add a module to the Data base
*/
SECStatus
SECMOD_AddPermDB(SECMODModule *module) {
DBT key,data;
SECStatus rv = SECFailure;
DB *pkcs11db = NULL;
int ret;
/* make sure we have a db handle */
pkcs11db = secmod_OpenDB(PR_FALSE);
if (pkcs11db == NULL) {
return SECFailure;
}
rv = secmod_MakeKey(&key,module);
if (rv != SECSuccess) goto done;
rv = secmod_EncodeData(&data,module);
if (rv != SECSuccess) {
secmod_FreeKey(&key);
goto done;
}
rv = SECFailure;
ret = (*pkcs11db->put)(pkcs11db, &key, &data, 0);
secmod_FreeKey(&key);
secmod_FreeData(&data);
if (ret != 0) goto done;
ret = (*pkcs11db->sync)(pkcs11db, 0);
if (ret == 0) rv = SECSuccess;
done:
secmod_CloseDB(pkcs11db);
return rv;
}

View File

@ -0,0 +1,147 @@
/*
* 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 maps PKCS11 Errors into SECErrors
* This is an information reducing process, since most errors are reflected
* back to the user (the user doesn't care about invalid flags, or active
* operations). If any of these errors need more detail in the upper layers
* which call PK11 library functions, we can add more SEC_ERROR_XXX functions
* and change there mappings here.
*/
#include "pkcs11t.h"
#include "pk11func.h"
#include "secerr.h"
#ifdef PK11_ERROR_USE_ARRAY
/*
* build a static array of entries...
*/
static struct {
CK_RV pk11_error;
int sec_error;
} pk11_error_map = {
#define MAPERROR(x,y) {x, y},
#else
/* the default is to use a big switch statement */
int
PK11_MapError(CK_RV rv) {
switch (rv) {
#define MAPERROR(x,y) case x: return y;
#endif
/* the guts mapping */
MAPERROR(CKR_OK, 0)
MAPERROR(CKR_CANCEL, SEC_ERROR_IO)
MAPERROR(CKR_HOST_MEMORY, SEC_ERROR_NO_MEMORY)
MAPERROR(CKR_SLOT_ID_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_ATTRIBUTE_READ_ONLY, SEC_ERROR_READ_ONLY)
MAPERROR(CKR_ATTRIBUTE_SENSITIVE, SEC_ERROR_IO) /* XX SENSITIVE */
MAPERROR(CKR_ATTRIBUTE_TYPE_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_ATTRIBUTE_VALUE_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_DATA_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_DATA_LEN_RANGE, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_DEVICE_ERROR, SEC_ERROR_IO)
MAPERROR(CKR_DEVICE_MEMORY, SEC_ERROR_NO_MEMORY)
MAPERROR(CKR_DEVICE_REMOVED, SEC_ERROR_NO_TOKEN)
MAPERROR(CKR_ENCRYPTED_DATA_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_ENCRYPTED_DATA_LEN_RANGE, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_FUNCTION_CANCELED, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_FUNCTION_NOT_PARALLEL, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_MECHANISM_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_MECHANISM_PARAM_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_OBJECT_HANDLE_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_OPERATION_ACTIVE, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_OPERATION_NOT_INITIALIZED,SEC_ERROR_LIBRARY_FAILURE )
MAPERROR(CKR_PIN_INCORRECT, SEC_ERROR_BAD_PASSWORD)
MAPERROR(CKR_PIN_INVALID, SEC_ERROR_BAD_PASSWORD)
MAPERROR(CKR_PIN_LEN_RANGE, SEC_ERROR_BAD_PASSWORD)
MAPERROR(CKR_SESSION_CLOSED, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_SESSION_COUNT, SEC_ERROR_NO_MEMORY) /* XXXX? */
MAPERROR(CKR_SESSION_HANDLE_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_SESSION_PARALLEL_NOT_SUPPORTED, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_SESSION_READ_ONLY, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_SIGNATURE_INVALID, SEC_ERROR_BAD_SIGNATURE)
MAPERROR(CKR_SIGNATURE_LEN_RANGE, SEC_ERROR_BAD_SIGNATURE)
MAPERROR(CKR_TEMPLATE_INCOMPLETE, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_TEMPLATE_INCONSISTENT, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_TOKEN_NOT_PRESENT, SEC_ERROR_NO_TOKEN)
MAPERROR(CKR_TOKEN_NOT_RECOGNIZED, SEC_ERROR_IO)
MAPERROR(CKR_TOKEN_WRITE_PROTECTED, SEC_ERROR_READ_ONLY)
MAPERROR(CKR_UNWRAPPING_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_UNWRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_USER_ALREADY_LOGGED_IN, 0)
MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_LIBRARY_FAILURE) /* XXXX */
MAPERROR(CKR_USER_PIN_NOT_INITIALIZED, SEC_ERROR_NO_TOKEN)
MAPERROR(CKR_USER_TYPE_INVALID, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_WRAPPED_KEY_INVALID, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_WRAPPED_KEY_LEN_RANGE, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_WRAPPING_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_WRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_WRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_VENDOR_DEFINED, SEC_ERROR_LIBRARY_FAILURE)
#ifdef PK11_ERROR_USE_ARRAY
int
PK11_MapError(CK_RV rv) {
int size = sizeof(pk11_error_map)/sizeof(pk11_error_map[0]);
for (i=0; i < size; i++) {
if (pk11_error_map[i].pk11_error == rv) {
return pk11_error_map[i].sec_error;
}
}
return SEC_ERROR_IO;
}
#else
default:
break;
}
return SEC_ERROR_IO;
}
#endif

View File

@ -0,0 +1,440 @@
/*
* 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.
*
* PKCS #11 Wrapper functions which handles authenticating to the card's
* choosing the best cards, etc.
*/
#ifndef _PK11FUNC_H_
#define _PK11FUNC_H_
#include "plarena.h"
#include "mcom_db.h"
#include "seccomon.h"
#include "secoidt.h"
#include "secdert.h"
#include "keyt.h"
#include "certt.h"
#include "pkcs11t.h"
#include "secmodt.h"
#include "seccomon.h"
#include "pkcs7t.h"
SEC_BEGIN_PROTOS
/************************************************************
* Generic Slot Lists Management
************************************************************/
PK11SlotList * PK11_NewSlotList(void);
void PK11_FreeSlotList(PK11SlotList *list);
SECStatus PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot);
SECStatus PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le);
PK11SlotListElement * PK11_GetFirstSafe(PK11SlotList *list);
PK11SlotListElement *PK11_GetNextSafe(PK11SlotList *list,
PK11SlotListElement *le, PRBool restart);
PK11SlotListElement *PK11_FindSlotElement(PK11SlotList *list,
PK11SlotInfo *slot);
/************************************************************
* Generic Slot Management
************************************************************/
PK11SlotInfo *PK11_ReferenceSlot(PK11SlotInfo *slot);
PK11SlotInfo *PK11_FindSlotByID(SECMODModuleID modID,CK_SLOT_ID slotID);
void PK11_FreeSlot(PK11SlotInfo *slot);
SECStatus PK11_DestroyObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object);
SECStatus PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object);
CK_OBJECT_HANDLE PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject);
SECStatus PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type, PRArenaPool *arena, SECItem *result);
CK_ULONG PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type);
PK11SlotInfo *PK11_GetInternalKeySlot(void);
PK11SlotInfo *PK11_GetInternalSlot(void);
char * PK11_MakeString(PRArenaPool *arena,char *space,char *staticSring,
int stringLen);
int PK11_MapError(CK_RV error);
CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot);
void PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession);
PRBool PK11_RWSessionHasLock(PK11SlotInfo *slot,
CK_SESSION_HANDLE session_handle);
PK11SlotInfo *PK11_NewSlotInfo(void);
SECStatus PK11_Logout(PK11SlotInfo *slot);
void PK11_LogoutAll(void);
void PK11_EnterSlotMonitor(PK11SlotInfo *);
void PK11_ExitSlotMonitor(PK11SlotInfo *);
/************************************************************
* Slot Password Management
************************************************************/
void PK11_SetSlotPWValues(PK11SlotInfo *slot,int askpw, int timeout);
void PK11_GetSlotPWValues(PK11SlotInfo *slot,int *askpw, int *timeout);
SECStatus PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw);
SECStatus PK11_CheckUserPassword(PK11SlotInfo *slot,char *pw);
SECStatus PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx);
PRBool PK11_IsLoggedIn(PK11SlotInfo *slot, void *wincx);
SECStatus PK11_VerifyPW(PK11SlotInfo *slot,char *pw);
SECStatus PK11_InitPin(PK11SlotInfo *slot,char *ssopw, char *pk11_userpwd);
SECStatus PK11_ChangePW(PK11SlotInfo *slot,char *oldpw, char *newpw);
void PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx);
void PK11_SetPasswordFunc(PK11PasswordFunc func);
void PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func);
void PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func);
int PK11_GetMinimumPwdLength(PK11SlotInfo *slot);
SECStatus PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd);
/************************************************************
* Manage the built-In Slot Lists
************************************************************/
SECStatus PK11_InitSlotLists(void);
PK11SlotList *PK11_GetSlotList(CK_MECHANISM_TYPE type);
void PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count);
void PK11_ClearSlotList(PK11SlotInfo *slot);
/******************************************************************
* Slot initialization
******************************************************************/
PRBool PK11_VerifyMechanism(PK11SlotInfo *slot,PK11SlotInfo *intern,
CK_MECHANISM_TYPE mech, SECItem *data, SECItem *iv);
PRBool PK11_VerifySlotMechanisms(PK11SlotInfo *slot);
SECStatus pk11_CheckVerifyTest(PK11SlotInfo *slot);
SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts);
SECStatus PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx);
void PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot);
/******************************************************************
* Slot info functions
******************************************************************/
PK11SlotInfo *PK11_FindSlotByName(char *name);
PK11SlotInfo *PK11_FindSlotBySerial(char *serial);
PRBool PK11_IsReadOnly(PK11SlotInfo *slot);
PRBool PK11_IsInternal(PK11SlotInfo *slot);
char * PK11_GetTokenName(PK11SlotInfo *slot);
char * PK11_GetSlotName(PK11SlotInfo *slot);
PRBool PK11_NeedLogin(PK11SlotInfo *slot);
PRBool PK11_IsFriendly(PK11SlotInfo *slot);
PRBool PK11_IsHW(PK11SlotInfo *slot);
PRBool PK11_NeedUserInit(PK11SlotInfo *slot);
int PK11_GetSlotSeries(PK11SlotInfo *slot);
int PK11_GetCurrentWrapIndex(PK11SlotInfo *slot);
unsigned long PK11_GetDefaultFlags(PK11SlotInfo *slot);
CK_SLOT_ID PK11_GetSlotID(PK11SlotInfo *slot);
SECMODModuleID PK11_GetModuleID(PK11SlotInfo *slot);
SECStatus PK11_GetSlotInfo(PK11SlotInfo *slot, CK_SLOT_INFO *info);
SECStatus PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info);
PRBool PK11_IsDisabled(PK11SlotInfo *slot);
PK11DisableReasons PK11_GetDisabledReason(PK11SlotInfo *slot);
/* Prevents the slot from being used, and set disable reason to user-disable */
/* NOTE: Mechanisms that were ON continue to stay ON */
/* Therefore, when the slot is enabled, it will remember */
/* what mechanisms needs to be turned on */
PRBool PK11_UserDisableSlot(PK11SlotInfo *slot);
/* Allow all mechanisms that are ON before UserDisableSlot() */
/* was called to be available again */
PRBool PK11_UserEnableSlot(PK11SlotInfo *slot);
PRBool PK11_NeedPWInit(void);
PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot);
PRBool PK11_TokenExists(CK_MECHANISM_TYPE);
SECStatus PK11_GetModInfo(SECMODModule *mod, CK_INFO *info);
PRBool PK11_IsFIPS(void);
SECMODModule *PK11_GetModule(PK11SlotInfo *slot);
/*********************************************************************
* Slot mapping utility functions.
*********************************************************************/
PRBool PK11_IsPresent(PK11SlotInfo *slot);
PRBool PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
PK11SlotList * PK11_GetAllTokens(CK_MECHANISM_TYPE type,PRBool needRW,
PRBool loadCerts, void *wincx);
PK11SlotList * PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type,
PRBool needRW,void *wincx);
PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int count,
void *wincx);
PK11SlotInfo *PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx);
CK_MECHANISM_TYPE PK11_GetBestWrapMechanism(PK11SlotInfo *slot);
int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
/*********************************************************************
* Mechanism Mapping functions
*********************************************************************/
void PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
CK_MECHANISM_TYPE keygen, int ivLen, int blocksize);
CK_MECHANISM_TYPE PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len);
CK_MECHANISM_TYPE PK11_GetKeyGen(CK_MECHANISM_TYPE type);
int PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params);
int PK11_GetIVLength(CK_MECHANISM_TYPE type);
SECItem *PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv);
unsigned char *PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len);
SECItem * PK11_BlockData(SECItem *data,unsigned long size);
/* PKCS #11 to DER mapping functions */
SECItem *PK11_ParamFromAlgid(SECAlgorithmID *algid);
SECItem *PK11_GenerateNewParam(CK_MECHANISM_TYPE, PK11SymKey *);
CK_MECHANISM_TYPE PK11_AlgtagToMechanism(SECOidTag algTag);
SECOidTag PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type);
SECOidTag PK11_FortezzaMapSig(SECOidTag algTag);
SECStatus PK11_ParamToAlgid(SECOidTag algtag, SECItem *param,
PRArenaPool *arena, SECAlgorithmID *algid);
SECStatus PK11_SeedRandom(PK11SlotInfo *,unsigned char *data,int len);
SECStatus PK11_RandomUpdate(void *data, size_t bytes);
SECStatus PK11_GenerateRandom(unsigned char *data,int len);
CK_RV PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
CK_MECHANISM_PTR pCryptoMechanism,
SECItem *pbe_pwd, PRBool bad3DES);
CK_MECHANISM_TYPE PK11_GetPadMechanism(CK_MECHANISM_TYPE);
/**********************************************************************
* Symetric, Public, and Private Keys
**********************************************************************/
PK11SymKey *PK11_CreateSymKey(PK11SlotInfo *slot,
CK_MECHANISM_TYPE type, void *wincx);
void PK11_FreeSymKey(PK11SymKey *key);
PK11SymKey *PK11_ReferenceSymKey(PK11SymKey *symKey);
PK11SymKey *PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,void *wincx);
PK11SymKey *PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent,
PK11Origin origin, CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID,
PRBool owner, void *wincx);
PK11SymKey *PK11_GetWrapKey(PK11SlotInfo *slot, int wrap,
CK_MECHANISM_TYPE type,int series, void *wincx);
void PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey);
CK_MECHANISM_TYPE PK11_GetMechanism(PK11SymKey *symKey);
CK_OBJECT_HANDLE PK11_ImportPublicKey(PK11SlotInfo *slot,
SECKEYPublicKey *pubKey, PRBool isToken);
PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
SECItem *param, int keySize,void *wincx);
SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
PK11SymKey *symKey, SECItem *wrappedKey);
SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey);
PK11SymKey *PK11_Derive(PK11SymKey *baseKey, CK_MECHANISM_TYPE mechanism,
SECItem *param, CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation, int keySize);
PK11SymKey *PK11_DeriveWithFlags( PK11SymKey *baseKey,
CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags);
PK11SymKey *PK11_PubDerive( SECKEYPrivateKey *privKey,
SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB,
CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx) ;
PK11SymKey *PK11_UnwrapSymKey(PK11SymKey *key,
CK_MECHANISM_TYPE wraptype, SECItem *param, SECItem *wrapppedKey,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize);
PK11SymKey *PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey,
CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize,
CK_FLAGS flags);
PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize);
PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
SECItem *keyID, void *wincx);
SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey);
SECStatus PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx);
/* size to hold key in bytes */
unsigned int PK11_GetKeyLength(PK11SymKey *key);
/* size of actual secret parts of key in bits */
/* algid is because RC4 strength is determined by the effective bits as well
* as the key bits */
unsigned int PK11_GetKeyStrength(PK11SymKey *key,SECAlgorithmID *algid);
SECStatus PK11_ExtractKeyValue(PK11SymKey *symKey);
SECItem * PK11_GetKeyData(PK11SymKey *symKey);
PK11SlotInfo * PK11_GetSlotFromKey(PK11SymKey *symKey);
void *PK11_GetWindow(PK11SymKey *symKey);
SECKEYPrivateKey *PK11_GenerateKeyPair(PK11SlotInfo *slot,
CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
PRBool isPerm, PRBool isSensitive, void *wincx);
SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx);
SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot,
CERTCertificate *cert, void *wincx);
SECKEYPrivateKey * PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx);
SECKEYPrivateKey * PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID,
void *wincx);
CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert,
void *wincx, PK11SlotInfo **pSlot);
int PK11_GetPrivateModulusLen(SECKEYPrivateKey *key);
SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data,
unsigned *outLen, unsigned int maxLen, unsigned char *enc, unsigned encLen);
/* The encrypt version of the above function */
SECStatus PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc,
unsigned char *data, unsigned dataLen, void *wincx);
SECStatus PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot,
SECKEYPrivateKeyInfo *pki, SECItem *nickname,
SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
unsigned int usage, void *wincx);
SECStatus PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
SECItem *nickname, SECItem *publicValue, PRBool isPerm,
PRBool isPrivate, KeyType type,
unsigned int usage, void *wincx);
SECKEYPrivateKeyInfo *PK11_ExportPrivateKeyInfo(
CERTCertificate *cert, void *wincx);
SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivateKeyInfo(
PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem,
CERTCertificate *cert, int iteration, void *wincx);
SECKEYPrivateKey *PK11_FindKeyByDERCert(PK11SlotInfo *slot,
CERTCertificate *cert, void *wincx);
SECKEYPublicKey *PK11_MakeKEAPubKey(unsigned char *data, int length);
SECStatus PK11_DigestKey(PK11Context *context, PK11SymKey *key);
PRBool PK11_VerifyKeyOK(PK11SymKey *key);
SECKEYPrivateKey *PK11_UnwrapPrivKey(PK11SlotInfo *slot,
PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType,
SECItem *param, SECItem *wrappedKey, SECItem *label,
SECItem *publicValue, PRBool token, PRBool sensitive,
CK_KEY_TYPE keyType, CK_ATTRIBUTE_TYPE *usage, int usageCount,
void *wincx);
SECStatus PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType,
SECItem *param, SECItem *wrappedKey, void *wincx);
PK11SymKey * pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey);
SECItem *PK11_GetKeyIDFromCert(CERTCertificate *cert, void *wincx);
SECItem * PK11_GetKeyIDFromPrivateKey(SECKEYPrivateKey *key, void *wincx);
/**********************************************************************
* Certs
**********************************************************************/
SECItem *PK11_MakeIDFromPubKey(SECItem *pubKeyData);
CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey);
SECStatus PK11_TraverseSlotCerts(
SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
void *arg, void *wincx);
CERTCertificate * PK11_FindCertFromNickname(char *nickname, void *wincx);
CERTCertList * PK11_FindCertsFromNickname(char *nickname, void *wincx);
SECKEYPrivateKey * PK11_FindPrivateKeyFromNickname(char *nickname, void *wincx);
PK11SlotInfo *PK11_ImportCertForKey(CERTCertificate *cert, char *nickname,
void *wincx);
CK_OBJECT_HANDLE * PK11_FindObjectsFromNickname(char *nickname,
PK11SlotInfo **slotptr, CK_OBJECT_CLASS objclass, int *returnCount,
void *wincx);
PK11SlotInfo *PK11_KeyForCertExists(CERTCertificate *cert,
CK_OBJECT_HANDLE *keyPtr, void *wincx);
CK_OBJECT_HANDLE PK11_MatchItem(PK11SlotInfo *slot,CK_OBJECT_HANDLE peer,
CK_OBJECT_CLASS o_class);
CERTCertificate * PK11_FindCertByIssuerAndSN(PK11SlotInfo **slot,
CERTIssuerAndSN *sn, void *wincx);
CERTCertificate * PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slot,
SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip,
SECKEYPrivateKey**privKey, void *wincx);
CK_BBOOL PK11_HasAttributeSet( PK11SlotInfo *slot,
CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type );
CK_RV PK11_GetAttributes(PRArenaPool *arena,PK11SlotInfo *slot,
CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count);
int PK11_NumberCertsForCertSubject(CERTCertificate *cert);
SECStatus PK11_TraverseCertsForSubject(CERTCertificate *cert,
SECStatus(*callback)(CERTCertificate *, void *), void *arg);
SECStatus PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert,
PK11SlotInfo *slot, SECStatus(*callback)(CERTCertificate *, void *),
void *arg);
CERTCertificate *PK11_FindCertFromDERCert(PK11SlotInfo *slot,
CERTCertificate *cert, void *wincx);
CERTCertificate *PK11_FindCertFromDERSubjectAndNickname(
PK11SlotInfo *slot,
CERTCertificate *cert, char *nickname,
void *wincx);
SECStatus PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
char *nickname, PRBool addUsage,
void *wincx);
CERTCertificate *PK11_FindBestKEAMatch(CERTCertificate *serverCert,void *wincx);
SECStatus PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1,
PK11SlotInfo *slot2, CERTCertificate **cert1, CERTCertificate **cert2);
PRBool PK11_FortezzaHasKEA(CERTCertificate *cert);
CK_OBJECT_HANDLE PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert,
void *wincx);
SECStatus PK11_TraverseCertsForNicknameInSlot(SECItem *nickname,
PK11SlotInfo *slot, SECStatus(*callback)(CERTCertificate *, void *),
void *arg);
SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg);
/**********************************************************************
* Sign/Verify
**********************************************************************/
int PK11_SignatureLen(SECKEYPrivateKey *key);
PK11SlotInfo * PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key);
SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, SECItem *hash);
SECStatus PK11_VerifyRecover(SECKEYPublicKey *key, SECItem *sig,
SECItem *dsig, void * wincx);
SECStatus PK11_Verify(SECKEYPublicKey *key, SECItem *sig,
SECItem *hash, void *wincx);
/**********************************************************************
* Crypto Contexts
**********************************************************************/
void PK11_DestroyContext(PK11Context *context, PRBool freeit);
PK11Context * PK11_CreateContextByRawKey(PK11SlotInfo *slot,
CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation,
SECItem *key, SECItem *param, void *wincx);
PK11Context *PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, SECItem *param);
PK11Context *PK11_CreateDigestContext(SECOidTag hashAlg);
PK11Context *PK11_CloneContext(PK11Context *old);
SECStatus PK11_DigestBegin(PK11Context *cx);
SECStatus PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, unsigned char *in,
int32 len);
SECStatus PK11_DigestOp(PK11Context *context, const unsigned char *in,
unsigned len);
SECStatus PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen,
int maxout, unsigned char *in, int inlen);
SECStatus PK11_Finalize(PK11Context *context);
SECStatus PK11_DigestFinal(PK11Context *context, unsigned char *data,
unsigned int *outLen, unsigned int length);
PRBool PK11_HashOK(SECOidTag hashAlg);
SECStatus PK11_SaveContext(PK11Context *cx,unsigned char *save,
int *len, int saveLength);
SECStatus PK11_RestoreContext(PK11Context *cx,unsigned char *save,int len);
SECStatus PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len);
SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot);
void PK11_FreeSlotCerts(PK11SlotInfo *slot);
void PK11_SetFortezzaHack(PK11SymKey *symKey) ;
/**********************************************************************
* PBE functions
**********************************************************************/
SECAlgorithmID *
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt);
PK11SymKey *
PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
PRBool faulty3DES, void *wincx);
SECItem *
PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem);
SEC_END_PROTOS
#endif

View File

@ -0,0 +1,224 @@
/*
* 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 the Symkey wrapper and the PKCS context
* Interfaces.
*/
#include "seccomon.h"
#include "secmod.h"
#include "prlock.h"
#include "secmodi.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "secitem.h"
#include "key.h"
#include "secasn1.h"
#include "sechash.h"
#include "cert.h"
#include "secerr.h"
/*
* find an RSA public key on a card
*/
static CK_OBJECT_HANDLE
pk11_FindRSAPubKey(PK11SlotInfo *slot)
{
CK_KEY_TYPE key_type = CKK_RSA;
CK_OBJECT_CLASS class_type = CKO_PUBLIC_KEY;
CK_ATTRIBUTE theTemplate[2];
int template_count = sizeof(theTemplate)/sizeof(theTemplate[0]);
CK_ATTRIBUTE *attrs = theTemplate;
PK11_SETATTRS(attrs,CKA_CLASS,&class_type,sizeof(class_type)); attrs++;
PK11_SETATTRS(attrs,CKA_KEY_TYPE,&key_type,sizeof(key_type)); attrs++;
template_count = attrs - theTemplate;
PR_ASSERT(template_count <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE));
return pk11_FindObjectByTemplate(slot,theTemplate,template_count);
}
SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType,
CK_OBJECT_HANDLE id);
PK11SymKey *
pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey)
{
PK11SymKey *newSymKey = NULL;
SECStatus rv;
/* performance improvement can go here --- use a generated key to as a
* per startup wrapping key. If it exists, use it, otherwise do a full
* key exchange. */
/* find a common Key Exchange algorithm */
/* RSA */
if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) &&
PK11_DoesMechanism(slot,CKM_RSA_PKCS)) {
CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_KEY;
CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_KEY;
SECKEYPublicKey *pubKey = NULL;
SECKEYPrivateKey *privKey = NULL;
SECItem wrapData;
wrapData.data = NULL;
/* find RSA Public Key on target */
pubKeyHandle = pk11_FindRSAPubKey(slot);
if (pubKeyHandle != CK_INVALID_KEY) {
privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY);
}
/* if no key exits, generate a key pair */
if (privKeyHandle == CK_INVALID_KEY) {
unsigned int keyLength = PK11_GetKeyLength(symKey);
PK11RSAGenParams rsaParams;
rsaParams.keySizeInBits =
((keyLength == 0) || (keyLength > 16)) ? 512 : 256;
rsaParams.pe = 0x10001;
privKey = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN,
&rsaParams, &pubKey,PR_FALSE,PR_TRUE,symKey->cx);
} else {
/* if key's exist, build SECKEY data structures for them */
privKey = PK11_MakePrivKey(slot,nullKey, PR_TRUE, privKeyHandle,
symKey->cx);
if (privKey != NULL) {
pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle);
if (pubKey && pubKey->pkcs11Slot) {
PK11_FreeSlot(pubKey->pkcs11Slot);
pubKey->pkcs11Slot = NULL;
pubKey->pkcs11ID = CK_INVALID_KEY;
}
}
}
if (privKey == NULL) goto rsa_failed;
if (pubKey == NULL) goto rsa_failed;
wrapData.len = SECKEY_PublicKeyStrength(pubKey);
if (!wrapData.len) goto rsa_failed;
wrapData.data = PORT_Alloc(wrapData.len);
if (wrapData.data == NULL) goto rsa_failed;
/* now wrap the keys in and out */
rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, pubKey, symKey, &wrapData);
if (rv == SECSuccess) {
newSymKey = PK11_PubUnwrapSymKey(privKey,&wrapData,type,operation,
symKey->size);
}
rsa_failed:
if (wrapData.data != NULL) PORT_Free(wrapData.data);
if (privKey != NULL) SECKEY_DestroyPrivateKey(privKey);
if (pubKey != NULL) SECKEY_DestroyPublicKey(pubKey);
return newSymKey;
}
/* KEA */
if (PK11_DoesMechanism(symKey->slot, CKM_KEA_KEY_DERIVE) &&
PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) {
CERTCertificate *certSource = NULL;
CERTCertificate *certTarget = NULL;
SECKEYPublicKey *pubKeySource = NULL;
SECKEYPublicKey *pubKeyTarget = NULL;
SECKEYPrivateKey *privKeySource = NULL;
SECKEYPrivateKey *privKeyTarget = NULL;
PK11SymKey *tekSource = NULL;
PK11SymKey *tekTarget = NULL;
SECItem Ra,wrap;
/* can only exchange skipjack keys */
if (type != CKM_SKIPJACK_CBC64) {
PORT_SetError( SEC_ERROR_NO_MODULE );
goto kea_failed;
}
/* find a pair of certs we can use */
rv = PK11_GetKEAMatchedCerts(symKey->slot,slot,&certSource,&certTarget);
if (rv != SECSuccess) goto kea_failed;
/* get all the key pairs */
pubKeyTarget = CERT_ExtractPublicKey(certSource);
pubKeySource = CERT_ExtractPublicKey(certTarget);
privKeySource =
PK11_FindKeyByDERCert(symKey->slot,certSource,symKey->cx);
privKeyTarget =
PK11_FindKeyByDERCert(slot,certTarget,symKey->cx);
if ((pubKeySource == NULL) || (pubKeyTarget == NULL) ||
(privKeySource == NULL) || (privKeyTarget == NULL)) goto kea_failed;
/* generate the wrapping TEK's */
Ra.data = (unsigned char*)PORT_Alloc(128 /* FORTEZZA RA MAGIC */);
Ra.len = 128;
if (Ra.data == NULL) goto kea_failed;
tekSource = PK11_PubDerive(privKeySource,pubKeyTarget,PR_TRUE,&Ra,NULL,
CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx);
tekTarget = PK11_PubDerive(privKeyTarget,pubKeySource,PR_FALSE,&Ra,NULL,
CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx);
PORT_Free(Ra.data);
if ((tekSource == NULL) || (tekTarget == NULL)) { goto kea_failed; }
/* wrap the key out of Source into target */
wrap.data = (unsigned char*)PORT_Alloc(12); /* MAGIC SKIPJACK LEN */
wrap.len = 12;
/* paranoia to prevent infinite recursion on bugs */
PORT_Assert(tekSource->slot == symKey->slot);
if (tekSource->slot != symKey->slot) {
PORT_SetError( SEC_ERROR_NO_MODULE );
goto kea_failed;
}
rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP,NULL,tekSource,symKey,&wrap);
if (rv == SECSuccess) {
newSymKey = PK11_UnwrapSymKey(tekTarget, CKM_SKIPJACK_WRAP, NULL,
&wrap, type, operation, symKey->size);
}
PORT_Free(wrap.data);
kea_failed:
if (certSource == NULL) CERT_DestroyCertificate(certSource);
if (certTarget == NULL) CERT_DestroyCertificate(certTarget);
if (pubKeySource == NULL) SECKEY_DestroyPublicKey(pubKeySource);
if (pubKeyTarget == NULL) SECKEY_DestroyPublicKey(pubKeyTarget);
if (privKeySource == NULL) SECKEY_DestroyPrivateKey(privKeySource);
if (privKeyTarget == NULL) SECKEY_DestroyPrivateKey(privKeyTarget);
if (tekSource == NULL) PK11_FreeSymKey(tekSource);
if (tekTarget == NULL) PK11_FreeSymKey(tekTarget);
return newSymKey;
}
PORT_SetError( SEC_ERROR_NO_MODULE );
return NULL;
}

View File

@ -0,0 +1,165 @@
/*
* 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.
*/
/*
* Locking and queue management primatives
*
*/
#include "seccomon.h"
#include "prlock.h"
#include "prmon.h"
#include "secmod.h"
#include "secmodi.h"
#include "prlong.h"
#define ISREADING 1
#define ISWRITING 2
#define WANTWRITE 4
#define ISLOCKED 3
/*
* create a new lock for a Module List
*/
SECMODListLock *SECMOD_NewListLock() {
SECMODListLock *modLock;
modLock = (SECMODListLock*)PORT_Alloc(sizeof(SECMODListLock));
#ifdef PKCS11_USE_THREADS
modLock->mutex = NULL;
modLock->monitor = PR_NewMonitor();
#else
modLock->mutex = NULL;
modLock->monitor = NULL;
#endif
modLock->state = 0;
modLock->count = 0;
return modLock;
}
/*
* destroy the lock
*/
void SECMOD_DestroyListLock(SECMODListLock *lock) {
PK11_USE_THREADS(PR_DestroyMonitor(lock->monitor);)
PORT_Free(lock);
}
/*
* Lock the List for Read: NOTE: this assumes the reading isn't so common
* the writing will be starved.
*/
void SECMOD_GetReadLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
PR_EnterMonitor(modLock->monitor);
while (modLock->state & ISWRITING) {
PR_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */
}
modLock->state |= ISREADING;
modLock->count++;
PR_ExitMonitor(modLock->monitor);
#endif
}
/*
* Release the Read lock
*/
void SECMOD_ReleaseReadLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
PR_EnterMonitor(modLock->monitor);
modLock->count--;
if (modLock->count == 0) {
modLock->state &= ~ISREADING;
if (modLock->state & WANTWRITE) {
PR_Notify(modLock->monitor); /* only one writer at a time */
}
}
PR_ExitMonitor(modLock->monitor);
#endif
}
/*
* lock the list for Write
*/
void SECMOD_GetWriteLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
PR_EnterMonitor(modLock->monitor);
while (modLock->state & ISLOCKED) {
modLock->state |= WANTWRITE;
PR_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */
}
modLock->state = ISWRITING;
PR_ExitMonitor(modLock->monitor);
#endif
}
/*
* Release the Write Lock: NOTE, this code is pretty inefficient if you have
* lots of write collisions.
*/
void SECMOD_ReleaseWriteLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
PR_EnterMonitor(modLock->monitor);
modLock->state = 0;
PR_NotifyAll(modLock->monitor); /* enable all the readers */
PR_ExitMonitor(modLock->monitor);
#endif
}
/*
* must Hold the Write lock
*/
void
SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child) {
*parent = child->next;
child->next = NULL;
}
/*
* if lock is not specified, it must already be held
*/
void
SECMOD_AddList(SECMODModuleList *parent, SECMODModuleList *child,
SECMODListLock *lock) {
if (lock) { SECMOD_GetWriteLock(lock); }
child->next = parent->next;
parent->next = child;
if (lock) { SECMOD_ReleaseWriteLock(lock); }
}

View File

@ -0,0 +1,239 @@
/*
* 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.
*/
/*
* The following handles the loading, unloading and management of
* various PCKS #11 modules
*/
#include "seccomon.h"
#include "pkcs11.h"
#include "secmod.h"
#include "prlink.h"
#include "pk11func.h"
#include "secmodi.h"
#include "prlock.h"
extern void FC_GetFunctionList(void);
extern void NSC_GetFunctionList(void);
/* build the PKCS #11 2.01 lock files */
CK_RV PR_CALLBACK secmodCreateMutext(CK_VOID_PTR_PTR pmutex) {
*pmutex = (CK_VOID_PTR) PR_NewLock();
if ( *pmutex ) return CKR_OK;
return CKR_HOST_MEMORY;
}
CK_RV PR_CALLBACK secmodDestroyMutext(CK_VOID_PTR mutext) {
PR_DestroyLock((PRLock *)mutext);
return CKR_OK;
}
CK_RV PR_CALLBACK secmodLockMutext(CK_VOID_PTR mutext) {
PR_Lock((PRLock *)mutext);
return CKR_OK;
}
CK_RV PR_CALLBACK secmodUnlockMutext(CK_VOID_PTR mutext) {
PR_Unlock((PRLock *)mutext);
return CKR_OK;
}
static SECMODModuleID nextModuleID = 1;
static CK_C_INITIALIZE_ARGS secmodLockFunctions = {
secmodCreateMutext, secmodDestroyMutext, secmodLockMutext,
secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS|
CKF_OS_LOCKING_OK
,NULL
};
/*
* load a new module into our address space and initialize it.
*/
SECStatus
SECMOD_LoadModule(SECMODModule *mod) {
PRLibrary *library = NULL;
CK_C_GetFunctionList entry;
char * full_name;
CK_INFO info;
CK_ULONG slotCount = 0;
if (mod->loaded) return SECSuccess;
/* intenal modules get loaded from their internal list */
if (mod->internal) {
/* internal, statically get the C_GetFunctionList function */
if (mod->isFIPS) {
entry = (CK_C_GetFunctionList) FC_GetFunctionList;
} else {
entry = (CK_C_GetFunctionList) NSC_GetFunctionList;
}
} else {
/* Not internal, load the DLL and look up C_GetFunctionList */
if (mod->dllName == NULL) {
return SECFailure;
}
#ifdef notdef
/* look up the library name */
full_name = PR_GetLibraryName(PR_GetLibraryPath(),mod->dllName);
if (full_name == NULL) {
return SECFailure;
}
#else
full_name = PORT_Strdup(mod->dllName);
#endif
/* load the library. If this succeeds, then we have to remember to
* unload the library if anything goes wrong from here on out...
*/
library = PR_LoadLibrary(full_name);
mod->library = (void *)library;
PORT_Free(full_name);
if (library == NULL) {
return SECFailure;
}
/*
* now we need to get the entry point to find the function pointers
*/
entry = (CK_C_GetFunctionList)
PR_FindSymbol(library, "C_GetFunctionList");
if (entry == NULL) {
PR_UnloadLibrary(library);
return SECFailure;
}
}
/*
* We need to get the function list
*/
if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
goto fail;
mod->isThreadSafe = PR_TRUE;
/* Now we initialize the module */
if (PK11_GETTAB(mod)->C_Initialize(&secmodLockFunctions) != CKR_OK) {
mod->isThreadSafe = PR_FALSE;
if (PK11_GETTAB(mod)->C_Initialize(NULL) != CKR_OK) goto fail;
}
/* check the version number */
if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2;
if (info.cryptokiVersion.major != 2) goto fail2;
/* all 2.0 are a priori *not* thread safe */
if (info.cryptokiVersion.minor < 1) mod->isThreadSafe = PR_FALSE;
/* If we don't have a common name, get it from the PKCS 11 module */
if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
mod->commonName = PK11_MakeString(mod->arena,NULL,
(char *)info.libraryDescription, sizeof(info.libraryDescription));
if (mod->commonName == NULL) goto fail2;
}
/* initialize the Slots */
if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) {
CK_SLOT_ID *slotIDs;
int i;
CK_RV rv;
mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena,
sizeof(PK11SlotInfo *) * slotCount);
if (mod->slots == NULL) goto fail2;
slotIDs = (CK_SLOT_ID *) PORT_Alloc(sizeof(CK_SLOT_ID)*slotCount);
if (slotIDs == NULL) {
goto fail2;
}
rv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
if (rv != CKR_OK) {
PORT_Free(slotIDs);
goto fail2;
}
/* Initialize each slot */
for (i=0; i < (int)slotCount; i++) {
mod->slots[i] = PK11_NewSlotInfo();
PK11_InitSlot(mod,slotIDs[i],mod->slots[i]);
/* look down the slot info table */
PK11_LoadSlotList(mod->slots[i],mod->slotInfo,mod->slotInfoCount);
}
mod->slotCount = slotCount;
mod->slotInfoCount = 0;
PORT_Free(slotIDs);
}
mod->loaded = PR_TRUE;
mod->moduleID = nextModuleID++;
return SECSuccess;
fail2:
PK11_GETTAB(mod)->C_Finalize(NULL);
fail:
mod->functionList = NULL;
if (library) PR_UnloadLibrary(library);
return SECFailure;
}
SECStatus
SECMOD_UnloadModule(SECMODModule *mod) {
PRLibrary *library;
if (!mod->loaded) {
return SECFailure;
}
PK11_GETTAB(mod)->C_Finalize(NULL);
mod->moduleID = 0;
mod->loaded = PR_FALSE;
/* do we want the semantics to allow unloading the internal library?
* if not, we should change this to SECFailure and move it above the
* mod->loaded = PR_FALSE; */
if (mod->internal) {
return SECSuccess;
}
library = (PRLibrary *)mod->library;
/* paranoia */
if (library == NULL) {
return SECFailure;
}
PR_UnloadLibrary(library);
return SECSuccess;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,518 @@
/*
* 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.
*/
/*
* Initialize the PCKS 11 subsystem
*/
#include "seccomon.h"
#include "secmod.h"
#include "prlock.h"
#include "secmodi.h"
#include "pk11func.h"
/* these are for displaying error messages */
static SECMODModuleList *modules = NULL;
static SECMODModule *internalModule = NULL;
static SECMODListLock *moduleLock = NULL;
extern SECStatus
PK11_UpdateSlotAttribute(PK11SlotInfo *slot, PK11DefaultArrayEntry *entry,
PRBool add);
extern int XP_SEC_MODULE_NO_LIB;
extern PK11DefaultArrayEntry PK11_DefaultArray[];
extern int num_pk11_default_mechanisms;
void SECMOD_init(char *dbname) {
SECMODModuleList *thisModule;
int found=0;
SECStatus rv = SECFailure;
/* don't initialize twice */
if (modules) return;
PK11_InitSlotLists();
SECMOD_InitDB(dbname);
/*
* read in the current modules from the database
*/
modules = SECMOD_ReadPermDB();
/* make sure that the internal module is loaded */
for (thisModule = modules; thisModule ; thisModule = thisModule->next) {
if (thisModule->module->internal) {
found++;
internalModule = SECMOD_ReferenceModule(thisModule->module);
break;
}
}
if (!found) {
thisModule = modules;
modules = SECMOD_NewModuleListElement();
modules->module = SECMOD_NewInternal();
PORT_Assert(modules->module != NULL);
modules->next = thisModule;
SECMOD_AddPermDB(modules->module);
internalModule = SECMOD_ReferenceModule(modules->module);
}
/* load it first... we need it to verify the external modules
* which we are loading.... */
rv = SECMOD_LoadModule(internalModule);
if( rv != SECSuccess )
internalModule = NULL;
/* Load each new module */
for (thisModule = modules; thisModule ; thisModule = thisModule->next) {
if( !( thisModule->module->internal ) )
SECMOD_LoadModule(thisModule->module);
}
moduleLock = SECMOD_NewListLock();
}
/*
* retrieve the internal module
*/
SECMODModule *
SECMOD_GetInternalModule(void) {
return internalModule;
}
/* called from security/cmd/swfort/instinit, which doesn't need a full
* security LIBRARY (it used the swfortezza code, but it does have to verify
* cert chains against it's own list of certs. We need to initialize the
* security code without any database.
*/
void
secmod_GetInternalModule( SECMODModule *mod) {
internalModule = SECMOD_ReferenceModule(mod);
}
/*
* get the list of PKCS11 modules that are available.
*/
SECMODModuleList *SECMOD_GetDefaultModuleList() { return modules; }
SECMODListLock *SECMOD_GetDefaultModuleListLock() { return moduleLock; }
/*
* find a module by name, and add a reference to it.
* return that module.
*/
SECMODModule *SECMOD_FindModule(char *name) {
SECMODModuleList *mlp;
SECMODModule *module = NULL;
SECMOD_GetReadLock(moduleLock);
for(mlp = modules; mlp != NULL; mlp = mlp->next) {
if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
module = mlp->module;
SECMOD_ReferenceModule(module);
break;
}
}
SECMOD_ReleaseReadLock(moduleLock);
return module;
}
/*
* find a module by ID, and add a reference to it.
* return that module.
*/
SECMODModule *SECMOD_FindModuleByID(SECMODModuleID id) {
SECMODModuleList *mlp;
SECMODModule *module = NULL;
SECMOD_GetReadLock(moduleLock);
for(mlp = modules; mlp != NULL; mlp = mlp->next) {
if (id == mlp->module->moduleID) {
module = mlp->module;
SECMOD_ReferenceModule(module);
break;
}
}
SECMOD_ReleaseReadLock(moduleLock);
return module;
}
/*
* lookup the Slot module based on it's module ID and slot ID.
*/
PK11SlotInfo *SECMOD_LookupSlot(SECMODModuleID moduleID,CK_SLOT_ID slotID) {
int i;
SECMODModule *module;
module = SECMOD_FindModuleByID(moduleID);
if (module == NULL) return NULL;
for (i=0; i < module->slotCount; i++) {
PK11SlotInfo *slot = module->slots[i];
if (slot->slotID == slotID) {
SECMOD_DestroyModule(module);
return PK11_ReferenceSlot(slot);
}
}
SECMOD_DestroyModule(module);
return NULL;
}
/*
* find a module by name and delete it of the module list
*/
SECStatus
SECMOD_DeleteModule(char *name, int *type) {
SECMODModuleList *mlp;
SECMODModuleList **mlpp;
SECStatus rv = SECFailure;
*type = SECMOD_EXTERNAL;
SECMOD_GetWriteLock(moduleLock);
for(mlpp = &modules,mlp = modules;
mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
/* don't delete the internal module */
if (!mlp->module->internal) {
SECMOD_RemoveList(mlpp,mlp);
/* delete it after we release the lock */
rv = SECSuccess;
} else if (mlp->module->isFIPS) {
*type = SECMOD_FIPS;
} else {
*type = SECMOD_INTERNAL;
}
break;
}
}
SECMOD_ReleaseWriteLock(moduleLock);
if (rv == SECSuccess) {
SECMOD_DeletePermDB(mlp->module);
SECMOD_DestroyModuleListElement(mlp);
}
return rv;
}
/*
* find a module by name and delete it of the module list
*/
SECStatus
SECMOD_DeleteInternalModule(char *name) {
SECMODModuleList *mlp;
SECMODModuleList **mlpp;
SECStatus rv = SECFailure;
SECMOD_GetWriteLock(moduleLock);
for(mlpp = &modules,mlp = modules;
mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
/* don't delete the internal module */
if (mlp->module->internal) {
rv = SECSuccess;
SECMOD_RemoveList(mlpp,mlp);
}
break;
}
}
SECMOD_ReleaseWriteLock(moduleLock);
if (rv == SECSuccess) {
SECMODModule *newModule,*oldModule;
if (mlp->module->isFIPS) {
newModule = SECMOD_NewInternal();
} else {
newModule = SECMOD_GetFIPSInternal();
}
if (newModule == NULL) {
SECMODModuleList *last,*mlp2;
/* we're in pretty deep trouble if this happens...Security
* not going to work well... try to put the old module back on
* the list */
SECMOD_GetWriteLock(moduleLock);
for(mlp2 = modules; mlp2 != NULL; mlp2 = mlp->next) {
last = mlp2;
}
if (last == NULL) {
modules = mlp;
} else {
SECMOD_AddList(last,mlp,NULL);
}
SECMOD_ReleaseWriteLock(moduleLock);
return SECFailure;
}
oldModule = internalModule;
internalModule = SECMOD_ReferenceModule(newModule);
SECMOD_AddModule(internalModule);
SECMOD_DestroyModule(oldModule);
SECMOD_DeletePermDB(mlp->module);
SECMOD_DestroyModuleListElement(mlp);
}
return rv;
}
SECStatus
SECMOD_AddModule(SECMODModule *newModule) {
SECStatus rv;
SECMODModuleList *mlp, *newListElement, *last = NULL;
/* Test if a module w/ the same name already exists */
/* and return SECWouldBlock if so. */
/* We should probably add a new return value such as */
/* SECDublicateModule, but to minimize ripples, I'll */
/* give SECWouldBlock a new meaning */
if (SECMOD_FindModule(newModule->commonName)) {
return SECWouldBlock;
/* module already exists. */
}
rv = SECMOD_LoadModule(newModule);
if (rv != SECSuccess) {
return rv;
}
newListElement = SECMOD_NewModuleListElement();
if (newListElement == NULL) {
return SECFailure;
}
SECMOD_AddPermDB(newModule);
newListElement->module = newModule;
SECMOD_GetWriteLock(moduleLock);
/* Added it to the end (This is very inefficient, but Adding a module
* on the fly should happen maybe 2-3 times through the life this program
* on a given computer, and this list should be *SHORT*. */
for(mlp = modules; mlp != NULL; mlp = mlp->next) {
last = mlp;
}
if (last == NULL) {
modules = newListElement;
} else {
SECMOD_AddList(last,newListElement,NULL);
}
SECMOD_ReleaseWriteLock(moduleLock);
return SECSuccess;
}
PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,char *name) {
int i;
char *string;
for (i=0; i < module->slotCount; i++) {
PK11SlotInfo *slot = module->slots[i];
if (PK11_IsPresent(slot)) {
string = PK11_GetTokenName(slot);
} else {
string = PK11_GetSlotName(slot);
}
if (PORT_Strcmp(name,string) == 0) {
return PK11_ReferenceSlot(slot);
}
}
return NULL;
}
SECStatus
PK11_GetModInfo(SECMODModule *mod,CK_INFO *info) {
CK_RV crv;
if (mod->functionList == NULL) return SECFailure;
crv = PK11_GETTAB(mod)->C_GetInfo(info);
return (crv == CKR_OK) ? SECSuccess : SECFailure;
}
/* Determine if we have the FIP's module loaded as the default
* module to trigger other bogus FIPS requirements in PKCS #12 and
* SSL
*/
PRBool
PK11_IsFIPS(void)
{
SECMODModule *mod = SECMOD_GetInternalModule();
if (mod && mod->internal) {
return mod->isFIPS;
}
return PR_FALSE;
}
/* combines NewModule() & AddModule */
/* give a string for the module name & the full-path for the dll, */
/* installs the PKCS11 module & update registry */
SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath,
unsigned long defaultMechanismFlags,
unsigned long cipherEnableFlags) {
SECMODModule *module;
SECStatus result;
int s,i;
PK11SlotInfo* slot;
module = SECMOD_NewModule();
if (moduleName) {
module->commonName=PORT_ArenaStrdup(module->arena,moduleName);
} else {
module->commonName=NULL;
}
if (dllPath) {
module->dllName=PORT_ArenaStrdup(module->arena,dllPath);
} else {
module->dllName=NULL;
}
if (module->dllName != NULL) {
if (module->dllName[0] != 0) {
SECStatus rv = SECMOD_AddModule(module);
if (rv != SECSuccess) {
/* SECFailure: failed to add module, corrupt or missing module etc. */
/* SECBlock: a module with the same name already exists */
return rv;
} else { /* successfully added module */
/* turn on SSL cipher enable flags */
module->ssl[0] = cipherEnableFlags;
/* check each slot to turn on appropriate mechanisms */
for (s = 0; s < module->slotCount; s++) {
slot = (module->slots)[s];
/* for each possible mechanism */
for (i=0; i < num_pk11_default_mechanisms; i++) {
/* we are told to turn it on by default ? */
if (PK11_DefaultArray[i].flag & defaultMechanismFlags) {
/* it ignores if slot attribute update failes */
result = PK11_UpdateSlotAttribute(slot, &(PK11_DefaultArray[i]), PR_TRUE);
} else { /* turn this mechanism of the slot off by default */
result = PK11_UpdateSlotAttribute(slot, &(PK11_DefaultArray[i]), PR_FALSE);
}
} /* for each mechanism */
/* disable each slot if the defaultFlags say so */
if (defaultMechanismFlags & PK11_DISABLE_FLAG) {
PK11_UserDisableSlot(slot);
}
} /* for each slot of this module */
/* delete and re-add module in order to save changes to the module */
result = SECMOD_DeletePermDB(module);
if (result == SECSuccess) {
result = SECMOD_AddPermDB(module);
if (result == SECSuccess) {
return SECSuccess;
}
}
}
}
}
SECMOD_DestroyModule(module);
return SECFailure;
}
/* Public & Internal(Security Library) representation of
* encryption mechanism flags conversion */
/* Currently, the only difference is that internal representation
* puts RANDOM_FLAG at bit 31 (Most-significant bit), but
* public representation puts this bit at bit 28
*/
unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags) {
unsigned long internalFlags = publicFlags;
if (publicFlags & PUBLIC_MECH_RANDOM_FLAG) {
internalFlags &= ~PUBLIC_MECH_RANDOM_FLAG;
internalFlags |= SECMOD_RANDOM_FLAG;
}
return internalFlags;
}
unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags) {
unsigned long publicFlags = internalFlags;
if (internalFlags & SECMOD_RANDOM_FLAG) {
publicFlags &= ~SECMOD_RANDOM_FLAG;
publicFlags |= PUBLIC_MECH_RANDOM_FLAG;
}
return publicFlags;
}
/* Public & Internal(Security Library) representation of */
/* cipher flags conversion */
/* Note: currently they are just stubs */
unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags) {
return publicFlags;
}
unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags) {
return internalFlags;
}
/* Funtion reports true if module of modType is installed/configured */
PRBool
SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags )
{
PRBool result = PR_FALSE;
SECMODModuleList *mods = SECMOD_GetDefaultModuleList();
SECMODListLock *modsLock = SECMOD_GetDefaultModuleListLock();
SECMOD_GetReadLock(moduleLock);
for ( ; mods != NULL; mods = mods->next) {
if (mods->module->ssl[0] & SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) {
result = PR_TRUE;
}
}
SECMOD_ReleaseReadLock(moduleLock);
return result;
}

View File

@ -0,0 +1,132 @@
/*
* 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.
*
* Definition of Security Module Data Structure. There is a separate data
* structure for each loaded PKCS #11 module.
*/
#ifndef _SECMOD_H_
#define _SEDMOD_H_
#include "seccomon.h"
#include "secmodt.h"
#define PKCS11_USE_THREADS
/* These mechanisms flags are visible to all other libraries. */
/* They must be converted to internal SECMOD_*_FLAG */
/* if used inside the functions of the security library */
#define PUBLIC_MECH_RSA_FLAG 0x00000001ul
#define PUBLIC_MECH_DSA_FLAG 0x00000002ul
#define PUBLIC_MECH_RC2_FLAG 0x00000004ul
#define PUBLIC_MECH_RC4_FLAG 0x00000008ul
#define PUBLIC_MECH_DES_FLAG 0x00000010ul
#define PUBLIC_MECH_DH_FLAG 0x00000020ul
#define PUBLIC_MECH_FORTEZZA_FLAG 0x00000040ul
#define PUBLIC_MECH_RC5_FLAG 0x00000080ul
#define PUBLIC_MECH_SHA1_FLAG 0x00000100ul
#define PUBLIC_MECH_MD5_FLAG 0x00000200ul
#define PUBLIC_MECH_MD2_FLAG 0x00000400ul
#define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul
#define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul
#define PUBLIC_OWN_PW_DEFAULTS 0X20000000ul
#define PUBLIC_DISABLE_FLAG 0x40000000ul
/* warning: reserved means reserved */
#define PUBLIC_MECH_RESERVED_FLAGS 0x87FFF800ul
/* These cipher flags are visible to all other libraries, */
/* But they must be converted before used in functions */
/* withing the security module */
#define PUBLIC_CIPHER_FORTEZZA_FLAG 0x00000001ul
/* warning: reserved means reserved */
#define PUBLIC_CIPHER_RESERVED_FLAGS 0xFFFFFFFEul
SEC_BEGIN_PROTOS
/* protoypes */
extern void SECMOD_init(char *dbname);
extern SECMODModuleList *SECMOD_GetDefaultModuleList(void);
extern SECMODListLock *SECMOD_GetDefaultModuleListLock(void);
/* lock management */
extern SECMODListLock *SECMOD_NewListLock(void);
extern void SECMOD_DestroyListLock(SECMODListLock *);
extern void SECMOD_GetReadLock(SECMODListLock *);
extern void SECMOD_ReleaseReadLock(SECMODListLock *);
extern void SECMOD_GetWriteLock(SECMODListLock *);
extern void SECMOD_ReleaseWriteLock(SECMODListLock *);
/* list managment */
extern void SECMOD_RemoveList(SECMODModuleList **,SECMODModuleList *);
extern void SECMOD_AddList(SECMODModuleList *,SECMODModuleList *,SECMODListLock *);
/* Operate on modules by name */
extern SECMODModule *SECMOD_FindModule(char *name);
extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID);
extern SECStatus SECMOD_DeleteModule(char *name, int *type);
extern SECStatus SECMOD_DeleteInternalModule(char *name);
extern SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath,
unsigned long defaultMechanismFlags,
unsigned long cipherEnableFlags);
/* database/memory management */
extern SECMODModule *SECMOD_NewModule(void);
extern SECMODModuleList *SECMOD_NewModuleListElement(void);
extern SECMODModule *SECMOD_GetInternalModule(void);
extern SECMODModule *SECMOD_GetFIPSInternal(void);
extern SECMODModule *SECMOD_ReferenceModule(SECMODModule *module);
extern void SECMOD_DestroyModule(SECMODModule *module);
extern SECMODModuleList *SECMOD_DestroyModuleListElement(SECMODModuleList *);
extern void SECMOD_DestroyModuleList(SECMODModuleList *);
extern SECMODModule *SECMOD_DupModule(SECMODModule *old);
extern SECStatus SECMOD_AddModule(SECMODModule *newModule);
extern PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,char *name);
extern PK11SlotInfo *SECMOD_LookupSlot(SECMODModuleID module,
unsigned long slotID);
SECStatus SECMOD_DeletePermDB(SECMODModule *);
SECStatus SECMOD_AddPermDB(SECMODModule *);
/* Funtion reports true if at least one of the modules */
/* of modType has been installed */
PRBool SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags );
/* Functions used to convert between internal & public representation
* of Mechanism Flags and Cipher Enable Flags */
extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags);
extern unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags);
extern unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags);
extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags);
SEC_END_PROTOS
#endif

View File

@ -0,0 +1,81 @@
/*
* 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 header file included only by files in pkcs11 dir, or in
* pkcs11 specific client and server files.
*/
#ifndef _SECMODI_H_
#define _SECMODI_H_ 1
#include "pkcs11.h"
#include "prlock.h"
#include "mcom_db.h"
#include "secoidt.h"
#include "secdert.h"
#include "certt.h"
#include "secmodti.h"
#ifdef PKCS11_USE_THREADS
#define PK11_USE_THREADS(x) x
#else
#define PK11_USE_THREADS(x)
#endif
SEC_BEGIN_PROTOS
/* proto-types */
SECMODModule * SECMOD_NewModule(void); /* create a new module */
SECMODModule * SECMOD_NewInternal(void); /* create an internal module */
/* Data base functions */
void SECMOD_InitDB(char *);
SECMODModuleList * SECMOD_ReadPermDB(void);
/*void SECMOD_ReferenceModule(SECMODModule *); */
/* Library functions */
SECStatus SECMOD_LoadModule(SECMODModule *);
SECStatus SECMOD_UnloadModule(SECMODModule *);
void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot);
CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
CK_VOID_PTR pdata);
void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib);
CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot,
CK_ATTRIBUTE *inTemplate,int tsize);
SEC_END_PROTOS
#define PK11_GETTAB(x) ((CK_FUNCTION_LIST_PTR)((x)->functionList))
#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
(x)->pValue=(v); (x)->ulValueLen = (l);
#endif

View File

@ -0,0 +1,173 @@
/*
* 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.
*
* Definition of Security Module Data Structure. There is a separate data
* structure for each loaded PKCS #11 module.
*/
#ifndef _SECMODT_H_
#define _SECMODT_H_ 1
/* PKCS11 needs to be included */
typedef struct SECMODModuleStr SECMODModule;
typedef struct SECMODModuleListStr SECMODModuleList;
typedef struct SECMODListLockStr SECMODListLock; /* defined in secmodi.h */
typedef struct PK11SlotInfoStr PK11SlotInfo; /* defined in secmodti.h */
typedef struct PK11PreSlotInfoStr PK11PreSlotInfo; /* defined in secmodti.h */
typedef struct PK11SymKeyStr PK11SymKey; /* defined in secmodti.h */
typedef struct PK11ContextStr PK11Context; /* defined in secmodti.h */
typedef struct PK11SlotListStr PK11SlotList;
typedef struct PK11SlotListElementStr PK11SlotListElement;
typedef struct PK11RSAGenParamsStr PK11RSAGenParams;
typedef unsigned long SECMODModuleID;
typedef struct PK11DefaultArrayEntryStr PK11DefaultArrayEntry;
struct SECMODModuleStr {
PRArenaPool *arena;
PRBool internal; /* true of internally linked modules, false
* for the loaded modules */
PRBool loaded; /* Set to true if module has been loaded */
PRBool isFIPS; /* Set to true if module is finst internal */
char *dllName; /* name of the shared library which implements
* this module */
char *commonName; /* name of the module to display to the user */
void *library; /* pointer to the library. opaque. used only by
* pk11load.c */
void *functionList; /* The PKCS #11 function table */
void *refLock; /* only used pk11db.c */
int refCount; /* Module reference count */
PK11SlotInfo **slots; /* array of slot points attatched to this mod*/
int slotCount; /* count of slot in above array */
PK11PreSlotInfo *slotInfo; /* special info about slots default settings */
int slotInfoCount; /* count */
SECMODModuleID moduleID; /* ID so we can find this module again */
PRBool isThreadSafe;
unsigned long ssl[2]; /* SSL cipher enable flags */
};
struct SECMODModuleListStr {
SECMODModuleList *next;
SECMODModule *module;
};
struct PK11SlotListStr {
PK11SlotListElement *head;
PK11SlotListElement *tail;
void *lock;
};
struct PK11SlotListElementStr {
PK11SlotListElement *next;
PK11SlotListElement *prev;
PK11SlotInfo *slot;
int refCount;
};
struct PK11RSAGenParamsStr {
int keySizeInBits;
unsigned long pe;
};
/*
* Entry into the Array which lists all the legal bits for the default flags
* in the slot, their definition, and the PKCS #11 mechanism the represent
* Always Statically allocated.
*/
struct PK11DefaultArrayEntryStr {
char *name;
unsigned long flag;
unsigned long mechanism; /* this is a long so we don't include the
* whole pkcs 11 world to use this header */
};
#define SECMOD_RSA_FLAG 0x00000001L
#define SECMOD_DSA_FLAG 0x00000002L
#define SECMOD_RC2_FLAG 0x00000004L
#define SECMOD_RC4_FLAG 0x00000008L
#define SECMOD_DES_FLAG 0x00000010L
#define SECMOD_DH_FLAG 0x00000020L
#define SECMOD_FORTEZZA_FLAG 0x00000040L
#define SECMOD_RC5_FLAG 0x00000080L
#define SECMOD_SHA1_FLAG 0x00000100L
#define SECMOD_MD5_FLAG 0x00000200L
#define SECMOD_MD2_FLAG 0x00000400L
/* reserved bit for future, do not use */
#define SECMOD_RESERVED_FLAG 0X08000000L
#define SECMOD_FRIENDLY_FLAG 0x10000000L
#define SECMOD_RANDOM_FLAG 0x80000000L
/* need to make SECMOD and PK11 prefixes consistant. */
#define PK11_OWN_PW_DEFAULTS 0x20000000L
#define PK11_DISABLE_FLAG 0x40000000L
/* FAKE PKCS #11 defines */
#define CKM_FAKE_RANDOM 0x80000efeL
#define CKM_INVALID_MECHANISM 0xffffffffL
#define CKA_DIGEST 0x81000000L
#define CK_INVALID_KEY 0
#define CK_INVALID_SESSION 0
/* Cryptographic module types */
#define SECMOD_EXTERNAL 0 /* external module */
#define SECMOD_INTERNAL 1 /* internal default module */
#define SECMOD_FIPS 2 /* internal fips module */
/*
* What is the origin of a given Key. Normally this doesn't matter, but
* the fortezza code needs to know if it needs to invoke the SSL3 fortezza
* hack.
*/
typedef enum {
PK11_OriginNULL, /* There is not key, it's a null SymKey */
PK11_OriginDerive, /* Key was derived from some other key */
PK11_OriginGenerated, /* Key was generated (also PBE keys) */
PK11_OriginFortezzaHack,/* Key was marked for fortezza hack */
PK11_OriginUnwrap /* Key was unwrapped or decrypted */
} PK11Origin;
/* PKCS #11 disable reasons */
typedef enum {
PK11_DIS_NONE = 0,
PK11_DIS_USER_SELECTED,
PK11_DIS_COULD_NOT_INIT_TOKEN,
PK11_DIS_TOKEN_VERIFY_FAILED,
PK11_DIS_TOKEN_NOT_PRESENT
} PK11DisableReasons;
/* function pointer type for password callback function.
* This type is passed in to PK11_SetPasswordFunc()
*/
typedef char *(*PK11PasswordFunc)(PK11SlotInfo *slot, PRBool retry, void *arg);
typedef PRBool (*PK11VerifyPasswordFunc)(PK11SlotInfo *slot, void *arg);
typedef PRBool (*PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg);
#endif /*_SECMODT_H_ */

View File

@ -0,0 +1,179 @@
/*
* 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 header file included only by files in pkcs11 dir, or in
* pkcs11 specific client and server files.
*/
#include "prmon.h"
#include "prtypes.h"
/* internal data structures */
/* structure to allow us to implement the read/write locks for our
* module lists */
struct SECMODListLockStr {
PRLock *mutex; /*general mutex to protect this data structure*/
PRMonitor *monitor; /* monitor to allow us to signal */
int state; /* read/write/waiting state */
int count; /* how many waiters on this lock */
};
/* represent a pkcs#11 slot reference counted. */
struct PK11SlotInfoStr {
/* the PKCS11 function list for this slot */
void *functionList;
SECMODModule *module; /* our parent module */
/* Boolean to indicate the current state of this slot */
PRBool needTest; /* Has this slot been tested for Export complience */
PRBool isPerm; /* is this slot a permanment device */
PRBool isHW; /* is this slot a hardware device */
PRBool isInternal; /* is this slot one of our internal PKCS #11 devices */
PRBool disabled; /* is this slot disabled... */
PK11DisableReasons reason; /* Why this slot is disabled */
PRBool readOnly; /* is the token in this slot read-only */
PRBool needLogin; /* does the token of the type that needs
* authentication (still true even if token is logged
* in) */
PRBool hasRandom; /* can this token generated random numbers */
PRBool defRWSession; /* is the default session RW (we open our default
* session rw if the token can only handle one session
* at a time. */
PRBool isThreadSafe; /* copied from the module */
/* The actual flags (many of which are distilled into the above PRBools) */
CK_FLAGS flags; /* flags from PKCS #11 token Info */
/* a default session handle to do quick and dirty functions */
CK_SESSION_HANDLE session;
PRLock *sessionLock; /* lock for this session */
/* our ID */
CK_SLOT_ID slotID;
/* persistant flags saved from startup to startup */
unsigned long defaultFlags;
/* keep track of who is using us so we don't accidently get freed while
* still in use */
int refCount;
PRLock *refLock;
/* Password control functions for this slot. many of these are only
* active if the appropriate flag is on in defaultFlags */
int askpw; /* what our password options are */
int timeout; /* If we're ask_timeout, what is our timeout time is
* seconds */
int authTransact; /* allow multiple authentications off one password if
* they are all part of the same transaction */
int64 authTime; /* when were we last authenticated */
int minPassword; /* smallest legal password */
int maxPassword; /* largest legal password */
uint16 series; /* break up the slot info into various groups of
* inserted tokens so that keys and certs can be
* invalidated */
uint16 wrapKey; /* current wrapping key for SSL master secrets */
CK_MECHANISM_TYPE wrapMechanism;
/* current wrapping mechanism for current wrapKey */
CK_OBJECT_HANDLE refKeys[1]; /* array of existing wrapping keys for */
CK_MECHANISM_TYPE *mechanismList; /* list of mechanism supported by this
* token */
int mechanismCount;
/* cache the certificates stored on the token of this slot */
CERTCertificate **cert_array;
int array_size;
int cert_count;
char serial[16];
/* since these are odd sizes, keep them last. They are odd sizes to
* allow them to become null terminated strings */
char slot_name[65];
char token_name[33];
PRBool hasRSAInfo;
CK_FLAGS RSAInfoFlags;
};
/* hold slot default flags until we initialize a slot. This structure is only
* useful between the time we define a module (either by hand or from the
* database) and the time the module is loaded. Not reference counted */
struct PK11PreSlotInfoStr {
CK_SLOT_ID slotID; /* slot these flags are for */
unsigned long defaultFlags; /* bit mask of default implementation this slot
* provides */
int askpw; /* slot specific password bits */
long timeout; /* slot specific timeout value */
};
/* Symetric Key structure. Reference Counted */
struct PK11SymKeyStr {
CK_MECHANISM_TYPE type; /* type of operation this key was created for*/
CK_OBJECT_HANDLE objectID; /* object id of this key in the slot */
PK11SlotInfo *slot; /* Slot this key is loaded into */
void *cx; /* window context in case we need to loggin */
PRBool owner;
SECItem data; /* raw key data if available */
CK_SESSION_HANDLE session;
PRBool sessionOwner;
int refCount; /* number of references to this key */
PRLock *refLock;
int size; /* key size in bytes */
PK11Origin origin; /* where this key came from
(see def in secmodt.h) */
uint16 series; /* break up the slot info into various groups of
* inserted tokens so that keys and certs can be
* invalidated */
};
/*
* hold a hash, encryption or signing context for multi-part operations.
* hold enough information so that multiple contexts can be interleaved
* if necessary. ... Not RefCounted.
*/
struct PK11ContextStr {
CK_ATTRIBUTE_TYPE operation; /* type of operation this context is doing
* (CKA_ENCRYPT, CKA_SIGN, CKA_HASH, etc. */
PK11SymKey *key; /* symetric key used in this context */
PK11SlotInfo *slot; /* slot this context is operationing on */
CK_SESSION_HANDLE session; /* session this context is using */
PRLock *sessionLock; /* lock before accessing a PKCS #11
* session */
PRBool ownSession;/* do we own the session? */
void *cx; /* window context in case we need to loggin*/
void *savedData;/* save data when we are multiplexing on a
* single context */
unsigned long savedLength; /* length of the saved context */
SECItem *param; /* mechanism parameters used to build this
context */
PRBool init; /* has this contexted been initialized */
CK_MECHANISM_TYPE type; /* what is the PKCS #11 this context is
* representing (usually what algorithm is
* being used (CKM_RSA_PKCS, CKM_DES,
* CKM_SHA, etc.*/
PRBool fortezzaHack; /*Fortezza SSL has some special
* non-standard semantics*/
};

View File

@ -0,0 +1,77 @@
#! 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). #
#######################################################################

View File

@ -0,0 +1,45 @@
#
# 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 =

View File

@ -0,0 +1,58 @@
#
# 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 = ../../..
EXPORTS = \
pkcs12t.h \
pkcs12.h \
p12plcy.h \
p12.h \
p12t.h \
$(NULL)
MODULE = security
CSRCS = \
p12local.c \
p12creat.c \
p12dec.c \
p12plcy.c \
p12tmpl.c \
p12e.c \
p12d.c \
$(NULL)
REQUIRES = security dbm
LIBRARY_NAME = pkcs12

View File

@ -0,0 +1,173 @@
/*
* 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 _P12_H_
#define _P12_H_
#include "secoid.h"
#include "key.h"
#include "secpkcs7.h"
#include "p12t.h"
typedef int (* PKCS12OpenFunction)(void *arg);
typedef int (* PKCS12ReadFunction)(void *arg, unsigned char *buffer,
unsigned int *lenRead, unsigned int maxLen);
typedef int (* PKCS12WriteFunction)(void *arg, unsigned char *buffer,
unsigned int *bufLen, unsigned int *lenWritten);
typedef int (* PKCS12CloseFunction)(void *arg);
typedef SECStatus (* PKCS12UnicodeConvertFunction)(PRArenaPool *arena,
SECItem *dest, SECItem *src,
PRBool toUnicode,
PRBool swapBytes);
typedef void (* SEC_PKCS12EncoderOutputCallback)(void *arg, const char *buf,
unsigned long len);
typedef void (* SEC_PKCS12DecoderOutputCallback)(void *arg, const char *buf,
unsigned long len);
typedef SECItem * (* SEC_PKCS12NicknameCollisionCallback)(SECItem *old_nickname,
PRBool *cancel,
void *arg);
typedef SECStatus (*digestOpenFn)(void *arg, PRBool readData);
typedef SECStatus (*digestCloseFn)(void *arg, PRBool removeFile);
typedef int (*digestIOFn)(void *arg, unsigned char *buf,
unsigned long len);
typedef struct SEC_PKCS12ExportContextStr SEC_PKCS12ExportContext;
typedef struct SEC_PKCS12SafeInfoStr SEC_PKCS12SafeInfo;
typedef struct SEC_PKCS12DecoderContextStr SEC_PKCS12DecoderContext;
struct sec_PKCS12PasswordModeInfo {
SECItem *password;
SECOidTag algorithm;
};
struct sec_PKCS12PublicKeyModeInfo {
CERTCertificate *cert;
CERTCertDBHandle *certDb;
SECOidTag algorithm;
int keySize;
};
SEC_PKCS12SafeInfo *
SEC_PKCS12CreatePubKeyEncryptedSafe(SEC_PKCS12ExportContext *p12ctxt,
CERTCertDBHandle *certDb,
CERTCertificate *signer,
CERTCertificate **recipients,
SECOidTag algorithm, int keysize);
extern SEC_PKCS12SafeInfo *
SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
SECItem *pwitem, SECOidTag privAlg);
extern SEC_PKCS12SafeInfo *
SEC_PKCS12CreateUnencryptedSafe(SEC_PKCS12ExportContext *p12ctxt);
extern SECStatus
SEC_PKCS12AddPasswordIntegrity(SEC_PKCS12ExportContext *p12ctxt,
SECItem *pwitem, SECOidTag integAlg);
extern SECStatus
SEC_PKCS12AddPublicKeyIntegrity(SEC_PKCS12ExportContext *p12ctxt,
CERTCertificate *cert, CERTCertDBHandle *certDb,
SECOidTag algorithm, int keySize);
extern SEC_PKCS12ExportContext *
SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
PK11SlotInfo *slot, void *wincx);
extern SECStatus
SEC_PKCS12AddCert(SEC_PKCS12ExportContext *p12ctxt,
SEC_PKCS12SafeInfo *safe, void *nestedDest,
CERTCertificate *cert, CERTCertDBHandle *certDb,
SECItem *keyId, PRBool includeCertChain);
extern SECStatus
SEC_PKCS12AddKeyForCert(SEC_PKCS12ExportContext *p12ctxt,
SEC_PKCS12SafeInfo *safe,
void *nestedDest, CERTCertificate *cert,
PRBool shroudKey, SECOidTag algorithm, SECItem *pwitem,
SECItem *keyId, SECItem *nickName);
extern SECStatus
SEC_PKCS12AddCertAndKey(SEC_PKCS12ExportContext *p12ctxt,
void *certSafe, void *certNestedDest,
CERTCertificate *cert, CERTCertDBHandle *certDb,
void *keySafe, void *keyNestedDest,
PRBool shroudKey, SECItem *pwitem, SECOidTag algorithm);
extern SECStatus
SEC_PKCS12AddDERCertAndEncryptedKey(SEC_PKCS12ExportContext *p12ctxt,
void *certSafe, void *certNestedDest, SECItem *derCert,
void *keySafe, void *keyNestedDest,
SECKEYEncryptedPrivateKeyInfo *epki, char *nickname);
extern void *
SEC_PKCS12CreateNestedSafeContents(SEC_PKCS12ExportContext *p12ctxt,
void *baseSafe, void *nestedDest);
extern SECStatus
SEC_PKCS12Encode(SEC_PKCS12ExportContext *p12exp,
SEC_PKCS12EncoderOutputCallback output, void *outputarg);
extern void
SEC_PKCS12DestroyExportContext(SEC_PKCS12ExportContext *p12exp);
extern SEC_PKCS12DecoderContext *
SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
digestOpenFn dOpen, digestCloseFn dClose,
digestIOFn dRead, digestIOFn dWrite, void *dArg);
extern SECStatus
SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx, unsigned char *data,
unsigned long len);
extern void
SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx);
extern SECStatus
SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx);
extern SECStatus
SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx,
SEC_PKCS12NicknameCollisionCallback nicknameCb);
extern SECStatus
SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx);
CERTCertList *
SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx);
#endif

View File

@ -0,0 +1,251 @@
/*
* 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 "pkcs12.h"
#include "secitem.h"
#include "secport.h"
#include "secder.h"
#include "secoid.h"
#include "p12local.h"
#include "secerr.h"
/* allocate space for a PFX structure and set up initial
* arena pool. pfx structure is cleared and a pointer to
* the new structure is returned.
*/
SEC_PKCS12PFXItem *
sec_pkcs12_new_pfx(void)
{
SEC_PKCS12PFXItem *pfx = NULL;
PRArenaPool *poolp = NULL;
poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); /* XXX Different size? */
if(poolp == NULL)
goto loser;
pfx = (SEC_PKCS12PFXItem *)PORT_ArenaZAlloc(poolp,
sizeof(SEC_PKCS12PFXItem));
if(pfx == NULL)
goto loser;
pfx->poolp = poolp;
return pfx;
loser:
PORT_FreeArena(poolp, PR_TRUE);
return NULL;
}
/* allocate space for a PFX structure and set up initial
* arena pool. pfx structure is cleared and a pointer to
* the new structure is returned.
*/
SEC_PKCS12AuthenticatedSafe *
sec_pkcs12_new_asafe(PRArenaPool *poolp)
{
SEC_PKCS12AuthenticatedSafe *asafe = NULL;
void *mark;
mark = PORT_ArenaMark(poolp);
asafe = (SEC_PKCS12AuthenticatedSafe *)PORT_ArenaZAlloc(poolp,
sizeof(SEC_PKCS12AuthenticatedSafe));
if(asafe == NULL)
goto loser;
asafe->poolp = poolp;
PORT_Memset(&asafe->old_baggage, 0, sizeof(SEC_PKCS7ContentInfo));
PORT_ArenaUnmark(poolp, mark);
return asafe;
loser:
PORT_ArenaRelease(poolp, mark);
return NULL;
}
/* create a safe contents structure with a list of
* length 0 with the first element being NULL
*/
SEC_PKCS12SafeContents *
sec_pkcs12_create_safe_contents(PRArenaPool *poolp)
{
SEC_PKCS12SafeContents *safe;
void *mark;
if(poolp == NULL)
return NULL;
/* allocate structure */
mark = PORT_ArenaMark(poolp);
safe = (SEC_PKCS12SafeContents *)PORT_ArenaZAlloc(poolp,
sizeof(SEC_PKCS12SafeContents));
if(safe == NULL)
{
PORT_SetError(SEC_ERROR_NO_MEMORY);
PORT_ArenaRelease(poolp, mark);
return NULL;
}
/* init list */
safe->contents = (SEC_PKCS12SafeBag**)PORT_ArenaZAlloc(poolp,
sizeof(SEC_PKCS12SafeBag *));
if(safe->contents == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
PORT_ArenaRelease(poolp, mark);
return NULL;
}
safe->contents[0] = NULL;
safe->poolp = poolp;
safe->safe_size = 0;
PORT_ArenaUnmark(poolp, mark);
return safe;
}
/* create a new external bag which is appended onto the list
* of bags in baggage. the bag is created in the same arena
* as baggage
*/
SEC_PKCS12BaggageItem *
sec_pkcs12_create_external_bag(SEC_PKCS12Baggage *luggage)
{
void *dummy, *mark;
SEC_PKCS12BaggageItem *bag;
if(luggage == NULL) {
return NULL;
}
mark = PORT_ArenaMark(luggage->poolp);
/* allocate space for null terminated bag list */
if(luggage->bags == NULL) {
luggage->bags=(SEC_PKCS12BaggageItem**)PORT_ArenaZAlloc(luggage->poolp,
sizeof(SEC_PKCS12BaggageItem *));
if(luggage->bags == NULL) {
goto loser;
}
luggage->luggage_size = 0;
}
/* grow the list */
dummy = PORT_ArenaGrow(luggage->poolp, luggage->bags,
sizeof(SEC_PKCS12BaggageItem *) * (luggage->luggage_size + 1),
sizeof(SEC_PKCS12BaggageItem *) * (luggage->luggage_size + 2));
if(dummy == NULL) {
goto loser;
}
luggage->bags = (SEC_PKCS12BaggageItem**)dummy;
luggage->bags[luggage->luggage_size] =
(SEC_PKCS12BaggageItem *)PORT_ArenaZAlloc(luggage->poolp,
sizeof(SEC_PKCS12BaggageItem));
if(luggage->bags[luggage->luggage_size] == NULL) {
goto loser;
}
/* create new bag and append it to the end */
bag = luggage->bags[luggage->luggage_size];
bag->espvks = (SEC_PKCS12ESPVKItem **)PORT_ArenaZAlloc(
luggage->poolp,
sizeof(SEC_PKCS12ESPVKItem *));
bag->unencSecrets = (SEC_PKCS12SafeBag **)PORT_ArenaZAlloc(
luggage->poolp,
sizeof(SEC_PKCS12SafeBag *));
if((bag->espvks == NULL) || (bag->unencSecrets == NULL)) {
goto loser;
}
bag->poolp = luggage->poolp;
luggage->luggage_size++;
luggage->bags[luggage->luggage_size] = NULL;
bag->espvks[0] = NULL;
bag->unencSecrets[0] = NULL;
bag->nEspvks = bag->nSecrets = 0;
PORT_ArenaUnmark(luggage->poolp, mark);
return bag;
loser:
PORT_ArenaRelease(luggage->poolp, mark);
PORT_SetError(SEC_ERROR_NO_MEMORY);
return NULL;
}
/* creates a baggage witha NULL terminated 0 length list */
SEC_PKCS12Baggage *
sec_pkcs12_create_baggage(PRArenaPool *poolp)
{
SEC_PKCS12Baggage *luggage;
void *mark;
if(poolp == NULL)
return NULL;
mark = PORT_ArenaMark(poolp);
/* allocate bag */
luggage = (SEC_PKCS12Baggage *)PORT_ArenaZAlloc(poolp,
sizeof(SEC_PKCS12Baggage));
if(luggage == NULL)
{
PORT_SetError(SEC_ERROR_NO_MEMORY);
PORT_ArenaRelease(poolp, mark);
return NULL;
}
/* init list */
luggage->bags = (SEC_PKCS12BaggageItem **)PORT_ArenaZAlloc(poolp,
sizeof(SEC_PKCS12BaggageItem *));
if(luggage->bags == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
PORT_ArenaRelease(poolp, mark);
return NULL;
}
luggage->bags[0] = NULL;
luggage->luggage_size = 0;
luggage->poolp = poolp;
PORT_ArenaUnmark(poolp, mark);
return luggage;
}
/* free pfx structure and associated items in the arena */
void
SEC_PKCS12DestroyPFX(SEC_PKCS12PFXItem *pfx)
{
if (pfx != NULL && pfx->poolp != NULL)
{
PORT_FreeArena(pfx->poolp, PR_TRUE);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,692 @@
/*
* 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 "pkcs12.h"
#include "plarena.h"
#include "secpkcs7.h"
#include "p12local.h"
#include "secoid.h"
#include "secitem.h"
#include "secport.h"
#include "secasn1.h"
#include "secder.h"
#include "secerr.h"
#include "cert.h"
#include "certdb.h"
#include "p12plcy.h"
#include "p12.h"
/* PFX extraction and validation routines */
/* decode the DER encoded PFX item. if unable to decode, check to see if it
* is an older PFX item. If that fails, assume the file was not a valid
* pfx file.
* the returned pfx structure should be destroyed using SEC_PKCS12DestroyPFX
*/
static SEC_PKCS12PFXItem *
sec_pkcs12_decode_pfx(SECItem *der_pfx)
{
SEC_PKCS12PFXItem *pfx;
SECStatus rv;
if(der_pfx == NULL) {
return NULL;
}
/* allocate the space for a new PFX item */
pfx = sec_pkcs12_new_pfx();
if(pfx == NULL) {
return NULL;
}
rv = SEC_ASN1DecodeItem(pfx->poolp, pfx, SEC_PKCS12PFXItemTemplate,
der_pfx);
/* if a failure occurred, check for older version...
* we also get rid of the old pfx structure, because we don't
* know where it failed and what data in may contain
*/
if(rv != SECSuccess) {
SEC_PKCS12DestroyPFX(pfx);
pfx = sec_pkcs12_new_pfx();
if(pfx == NULL) {
return NULL;
}
rv = SEC_ASN1DecodeItem(pfx->poolp, pfx, SEC_PKCS12PFXItemTemplate_OLD,
der_pfx);
if(rv != SECSuccess) {
PORT_SetError(SEC_ERROR_PKCS12_DECODING_PFX);
PORT_FreeArena(pfx->poolp, PR_TRUE);
return NULL;
}
pfx->old = PR_TRUE;
SGN_CopyDigestInfo(pfx->poolp, &pfx->macData.safeMac, &pfx->old_safeMac);
SECITEM_CopyItem(pfx->poolp, &pfx->macData.macSalt, &pfx->old_macSalt);
} else {
pfx->old = PR_FALSE;
}
/* convert bit string from bits to bytes */
pfx->macData.macSalt.len /= 8;
return pfx;
}
/* validate the integrity MAC used in the PFX. The MAC is generated
* per the PKCS 12 document. If the MAC is incorrect, it is most likely
* due to an invalid password.
* pwitem is the integrity password
* pfx is the decoded pfx item
*/
static PRBool
sec_pkcs12_check_pfx_mac(SEC_PKCS12PFXItem *pfx,
SECItem *pwitem)
{
SECItem *key = NULL, *mac = NULL, *data = NULL;
SECItem *vpwd = NULL;
SECOidTag algorithm;
PRBool ret = PR_FALSE;
if(pfx == NULL) {
return PR_FALSE;
}
algorithm = SECOID_GetAlgorithmTag(&pfx->macData.safeMac.digestAlgorithm);
switch(algorithm) {
/* only SHA1 hashing supported as a MACing algorithm */
case SEC_OID_SHA1:
if(pfx->old == PR_FALSE) {
pfx->swapUnicode = PR_FALSE;
}
recheckUnicodePassword:
vpwd = sec_pkcs12_create_virtual_password(pwitem,
&pfx->macData.macSalt,
pfx->swapUnicode);
if(vpwd == NULL) {
return PR_FALSE;
}
key = sec_pkcs12_generate_key_from_password(algorithm,
&pfx->macData.macSalt,
(pfx->old ? pwitem : vpwd));
/* free vpwd only for newer PFX */
if(vpwd) {
SECITEM_ZfreeItem(vpwd, PR_TRUE);
}
if(key == NULL) {
return PR_FALSE;
}
data = SEC_PKCS7GetContent(&pfx->authSafe);
if(data == NULL) {
break;
}
/* check MAC */
mac = sec_pkcs12_generate_mac(key, data, pfx->old);
ret = PR_TRUE;
if(mac) {
SECItem *safeMac = &pfx->macData.safeMac.digest;
if(SECITEM_CompareItem(mac, safeMac) != SECEqual) {
/* if we encounter an invalid mac, lets invert the
* password in case of unicode changes
*/
if(((!pfx->old) && pfx->swapUnicode) || (pfx->old)){
PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);
ret = PR_FALSE;
} else {
SECITEM_ZfreeItem(mac, PR_TRUE);
pfx->swapUnicode = PR_TRUE;
goto recheckUnicodePassword;
}
}
SECITEM_ZfreeItem(mac, PR_TRUE);
} else {
ret = PR_FALSE;
}
break;
default:
PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM);
ret = PR_FALSE;
break;
}
/* let success fall through */
if(key != NULL)
SECITEM_ZfreeItem(key, PR_TRUE);
return ret;
}
/* check the validity of the pfx structure. we currently only support
* password integrity mode, so we check the MAC.
*/
static PRBool
sec_pkcs12_validate_pfx(SEC_PKCS12PFXItem *pfx,
SECItem *pwitem)
{
SECOidTag contentType;
contentType = SEC_PKCS7ContentType(&pfx->authSafe);
switch(contentType)
{
case SEC_OID_PKCS7_DATA:
return sec_pkcs12_check_pfx_mac(pfx, pwitem);
break;
case SEC_OID_PKCS7_SIGNED_DATA:
default:
PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE);
break;
}
return PR_FALSE;
}
/* decode and return the valid PFX. if the PFX item is not valid,
* NULL is returned.
*/
static SEC_PKCS12PFXItem *
sec_pkcs12_get_pfx(SECItem *pfx_data,
SECItem *pwitem)
{
SEC_PKCS12PFXItem *pfx;
PRBool valid_pfx;
if((pfx_data == NULL) || (pwitem == NULL)) {
return NULL;
}
pfx = sec_pkcs12_decode_pfx(pfx_data);
if(pfx == NULL) {
return NULL;
}
valid_pfx = sec_pkcs12_validate_pfx(pfx, pwitem);
if(valid_pfx != PR_TRUE) {
SEC_PKCS12DestroyPFX(pfx);
pfx = NULL;
}
return pfx;
}
/* authenticated safe decoding, validation, and access routines
*/
/* convert dogbert beta 3 authenticated safe structure to a post
* beta three structure, so that we don't have to change more routines.
*/
static SECStatus
sec_pkcs12_convert_old_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe)
{
SEC_PKCS12Baggage *baggage;
SEC_PKCS12BaggageItem *bag;
SECStatus rv = SECSuccess;
if(asafe->old_baggage.espvks == NULL) {
/* XXX should the ASN1 engine produce a single NULL element list
* rather than setting the pointer to NULL?
* There is no need to return an error -- assume that the list
* was empty.
*/
return SECSuccess;
}
baggage = sec_pkcs12_create_baggage(asafe->poolp);
if(!baggage) {
return SECFailure;
}
bag = sec_pkcs12_create_external_bag(baggage);
if(!bag) {
return SECFailure;
}
PORT_Memcpy(&asafe->baggage, baggage, sizeof(SEC_PKCS12Baggage));
/* if there are shrouded keys, append them to the bag */
rv = SECSuccess;
if(asafe->old_baggage.espvks[0] != NULL) {
int nEspvk = 0;
rv = SECSuccess;
while((asafe->old_baggage.espvks[nEspvk] != NULL) &&
(rv == SECSuccess)) {
rv = sec_pkcs12_append_shrouded_key(bag,
asafe->old_baggage.espvks[nEspvk]);
nEspvk++;
}
}
return rv;
}
/* decodes the authenticated safe item. a return of NULL indicates
* an error. however, the error will have occured either in memory
* allocation or in decoding the authenticated safe.
*
* if an old PFX item has been found, we want to convert the
* old authenticated safe to the new one.
*/
static SEC_PKCS12AuthenticatedSafe *
sec_pkcs12_decode_authenticated_safe(SEC_PKCS12PFXItem *pfx)
{
SECItem *der_asafe = NULL;
SEC_PKCS12AuthenticatedSafe *asafe = NULL;
SECStatus rv;
if(pfx == NULL) {
return NULL;
}
der_asafe = SEC_PKCS7GetContent(&pfx->authSafe);
if(der_asafe == NULL) {
/* XXX set error ? */
goto loser;
}
asafe = sec_pkcs12_new_asafe(pfx->poolp);
if(asafe == NULL) {
goto loser;
}
if(pfx->old == PR_FALSE) {
rv = SEC_ASN1DecodeItem(pfx->poolp, asafe,
SEC_PKCS12AuthenticatedSafeTemplate,
der_asafe);
asafe->old = PR_FALSE;
asafe->swapUnicode = pfx->swapUnicode;
} else {
/* handle beta exported files */
rv = SEC_ASN1DecodeItem(pfx->poolp, asafe,
SEC_PKCS12AuthenticatedSafeTemplate_OLD,
der_asafe);
asafe->safe = &(asafe->old_safe);
rv = sec_pkcs12_convert_old_auth_safe(asafe);
asafe->old = PR_TRUE;
}
if(rv != SECSuccess) {
goto loser;
}
asafe->poolp = pfx->poolp;
return asafe;
loser:
return NULL;
}
/* validates the safe within the authenticated safe item.
* in order to be valid:
* 1. the privacy salt must be present
* 2. the encryption algorithm must be supported (including
* export policy)
* PR_FALSE indicates an error, PR_TRUE indicates a valid safe
*/
static PRBool
sec_pkcs12_validate_encrypted_safe(SEC_PKCS12AuthenticatedSafe *asafe)
{
PRBool valid = PR_FALSE;
SECAlgorithmID *algid;
if(asafe == NULL) {
return PR_FALSE;
}
/* if mode is password privacy, then privacySalt is assumed
* to be non-zero.
*/
if(asafe->privacySalt.len != 0) {
valid = PR_TRUE;
asafe->privacySalt.len /= 8;
} else {
PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
return PR_FALSE;
}
/* until spec changes, content will have between 2 and 8 bytes depending
* upon the algorithm used if certs are unencrypted...
* also want to support case where content is empty -- which we produce
*/
if(SEC_PKCS7IsContentEmpty(asafe->safe, 8) == PR_TRUE) {
asafe->emptySafe = PR_TRUE;
return PR_TRUE;
}
asafe->emptySafe = PR_FALSE;
/* make sure that a pbe algorithm is being used */
algid = SEC_PKCS7GetEncryptionAlgorithm(asafe->safe);
if(algid != NULL) {
if(SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
valid = SEC_PKCS12DecryptionAllowed(algid);
if(valid == PR_FALSE) {
PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
}
} else {
PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM);
valid = PR_FALSE;
}
} else {
valid = PR_FALSE;
PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM);
}
return valid;
}
/* validates authenticates safe:
* 1. checks that the version is supported
* 2. checks that only password privacy mode is used (currently)
* 3. further, makes sure safe has appropriate policies per above function
* PR_FALSE indicates failure.
*/
static PRBool
sec_pkcs12_validate_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe)
{
PRBool valid = PR_TRUE;
SECOidTag safe_type;
int version;
if(asafe == NULL) {
return PR_FALSE;
}
/* check version, since it is default it may not be present.
* therefore, assume ok
*/
if((asafe->version.len > 0) && (asafe->old == PR_FALSE)) {
version = DER_GetInteger(&asafe->version);
if(version > SEC_PKCS12_PFX_VERSION) {
PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION);
return PR_FALSE;
}
}
/* validate password mode is being used */
safe_type = SEC_PKCS7ContentType(asafe->safe);
switch(safe_type)
{
case SEC_OID_PKCS7_ENCRYPTED_DATA:
valid = sec_pkcs12_validate_encrypted_safe(asafe);
break;
case SEC_OID_PKCS7_ENVELOPED_DATA:
default:
PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE);
valid = PR_FALSE;
break;
}
return valid;
}
/* retrieves the authenticated safe item from the PFX item
* before returning the authenticated safe, the validity of the
* authenticated safe is checked and if valid, returned.
* a return of NULL indicates that an error occured.
*/
static SEC_PKCS12AuthenticatedSafe *
sec_pkcs12_get_auth_safe(SEC_PKCS12PFXItem *pfx)
{
SEC_PKCS12AuthenticatedSafe *asafe;
PRBool valid_safe;
if(pfx == NULL) {
return NULL;
}
asafe = sec_pkcs12_decode_authenticated_safe(pfx);
if(asafe == NULL) {
return NULL;
}
valid_safe = sec_pkcs12_validate_auth_safe(asafe);
if(valid_safe != PR_TRUE) {
asafe = NULL;
} else if(asafe) {
asafe->baggage.poolp = asafe->poolp;
}
return asafe;
}
/* decrypts the authenticated safe.
* a return of anything but SECSuccess indicates an error. the
* password is not known to be valid until the call to the
* function sec_pkcs12_get_safe_contents. If decoding the safe
* fails, it is assumed the password was incorrect and the error
* is set then. any failure here is assumed to be due to
* internal problems in SEC_PKCS7DecryptContents or below.
*/
static SECStatus
sec_pkcs12_decrypt_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe,
SECItem *pwitem,
void *wincx)
{
SECStatus rv = SECFailure;
SECItem *vpwd = NULL;
if((asafe == NULL) || (pwitem == NULL)) {
return SECFailure;
}
if(asafe->old == PR_FALSE) {
vpwd = sec_pkcs12_create_virtual_password(pwitem, &asafe->privacySalt,
asafe->swapUnicode);
if(vpwd == NULL) {
return SECFailure;
}
}
rv = SEC_PKCS7DecryptContents(asafe->poolp, asafe->safe,
(asafe->old ? pwitem : vpwd), wincx);
if(asafe->old == PR_FALSE) {
SECITEM_ZfreeItem(vpwd, PR_TRUE);
}
return rv;
}
/* extract the safe from the authenticated safe.
* if we are unable to decode the safe, then it is likely that the
* safe has not been decrypted or the password used to decrypt
* the safe was invalid. we assume that the password was invalid and
* set an error accordingly.
* a return of NULL indicates that an error occurred.
*/
static SEC_PKCS12SafeContents *
sec_pkcs12_get_safe_contents(SEC_PKCS12AuthenticatedSafe *asafe)
{
SECItem *src = NULL;
SEC_PKCS12SafeContents *safe = NULL;
SECStatus rv = SECFailure;
if(asafe == NULL) {
return NULL;
}
safe = (SEC_PKCS12SafeContents *)PORT_ArenaZAlloc(asafe->poolp,
sizeof(SEC_PKCS12SafeContents));
if(safe == NULL) {
return NULL;
}
safe->poolp = asafe->poolp;
safe->old = asafe->old;
safe->swapUnicode = asafe->swapUnicode;
src = SEC_PKCS7GetContent(asafe->safe);
if(src != NULL) {
const SEC_ASN1Template *theTemplate;
if(asafe->old != PR_TRUE) {
theTemplate = SEC_PKCS12SafeContentsTemplate;
} else {
theTemplate = SEC_PKCS12SafeContentsTemplate_OLD;
}
rv = SEC_ASN1DecodeItem(asafe->poolp, safe, theTemplate, src);
/* if we could not decode the item, password was probably invalid */
if(rv != SECSuccess) {
safe = NULL;
PORT_SetError(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT);
}
} else {
PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
rv = SECFailure;
}
return safe;
}
/* import PFX item
* der_pfx is the der encoded pfx structure
* pbef and pbearg are the integrity/encryption password call back
* ncCall is the nickname collision calllback
* slot is the destination token
* wincx window handler
*
* on error, error code set and SECFailure returned
*/
SECStatus
SEC_PKCS12PutPFX(SECItem *der_pfx, SECItem *pwitem,
SEC_PKCS12NicknameCollisionCallback ncCall,
PK11SlotInfo *slot,
void *wincx)
{
SEC_PKCS12PFXItem *pfx;
SEC_PKCS12AuthenticatedSafe *asafe;
SEC_PKCS12SafeContents *safe_contents = NULL;
SECStatus rv;
if(!der_pfx || !pwitem || !slot) {
return SECFailure;
}
/* decode and validate each section */
rv = SECFailure;
pfx = sec_pkcs12_get_pfx(der_pfx, pwitem);
if(pfx != NULL) {
asafe = sec_pkcs12_get_auth_safe(pfx);
if(asafe != NULL) {
/* decrypt safe -- only if not empty */
if(asafe->emptySafe != PR_TRUE) {
rv = sec_pkcs12_decrypt_auth_safe(asafe, pwitem, wincx);
if(rv == SECSuccess) {
safe_contents = sec_pkcs12_get_safe_contents(asafe);
if(safe_contents == NULL) {
rv = SECFailure;
}
}
} else {
safe_contents = sec_pkcs12_create_safe_contents(asafe->poolp);
safe_contents->swapUnicode = pfx->swapUnicode;
if(safe_contents == NULL) {
rv = SECFailure;
} else {
rv = SECSuccess;
}
}
/* get safe contents and begin import */
if(rv == SECSuccess) {
SEC_PKCS12DecoderContext *p12dcx;
p12dcx = sec_PKCS12ConvertOldSafeToNew(pfx->poolp, slot,
pfx->swapUnicode,
pwitem, wincx, safe_contents,
&asafe->baggage);
if(!p12dcx) {
rv = SECFailure;
goto loser;
}
if(SEC_PKCS12DecoderValidateBags(p12dcx, ncCall)
!= SECSuccess) {
rv = SECFailure;
goto loser;
}
rv = SEC_PKCS12DecoderImportBags(p12dcx);
}
}
}
loser:
if(pfx) {
SEC_PKCS12DestroyPFX(pfx);
}
return rv;
}
PRBool
SEC_PKCS12ValidData(char *buf, int bufLen, long int totalLength)
{
int lengthLength;
PRBool valid = PR_FALSE;
if(buf == NULL) {
return PR_FALSE;
}
/* check for constructed sequence identifier tag */
if(*buf == (SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE)) {
totalLength--; /* header byte taken care of */
buf++;
lengthLength = (long int)SEC_ASN1LengthLength(totalLength - 1);
if(totalLength > 0x7f) {
lengthLength--;
*buf &= 0x7f; /* remove bit 8 indicator */
if((*buf - (char)lengthLength) == 0) {
valid = PR_TRUE;
}
} else {
lengthLength--;
if((*buf - (char)lengthLength) == 0) {
valid = PR_TRUE;
}
}
}
return valid;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
/*
* 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 _P12LOCAL_H_
#define _P12LOCAL_H_
#include "plarena.h"
#include "secoidt.h"
#include "secasn1.h"
#include "secder.h"
#include "certt.h"
#include "secpkcs7.h"
#include "pkcs12.h"
#include "p12.h"
/* helper functions */
extern const SEC_ASN1Template *
sec_pkcs12_choose_bag_type(void *src_or_dest, PRBool encoding);
extern const SEC_ASN1Template *
sec_pkcs12_choose_cert_crl_type(void *src_or_dest, PRBool encoding);
extern const SEC_ASN1Template *
sec_pkcs12_choose_shroud_type(void *src_or_dest, PRBool encoding);
extern SECItem *sec_pkcs12_generate_salt(void);
extern SECItem *sec_pkcs12_generate_key_from_password(SECOidTag algorithm,
SECItem *salt, SECItem *password);
extern SECItem *sec_pkcs12_generate_mac(SECItem *key, SECItem *msg,
PRBool old_method);
extern SGNDigestInfo *sec_pkcs12_compute_thumbprint(SECItem *der_cert);
extern SECItem *sec_pkcs12_create_virtual_password(SECItem *password,
SECItem *salt, PRBool swapUnicodeBytes);
extern SECStatus sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag,
SEC_PKCS12ESPVKItem *espvk);
extern void *sec_pkcs12_find_object(SEC_PKCS12SafeContents *safe,
SEC_PKCS12Baggage *baggage, SECOidTag objType,
SECItem *nickname, SGNDigestInfo *thumbprint);
extern PRBool sec_pkcs12_convert_item_to_unicode(PRArenaPool *arena, SECItem *dest,
SECItem *src, PRBool zeroTerm,
PRBool asciiConvert, PRBool toUnicode);
/* create functions */
extern SEC_PKCS12PFXItem *sec_pkcs12_new_pfx(void);
extern SEC_PKCS12SafeContents *sec_pkcs12_create_safe_contents(
PRArenaPool *poolp);
extern SEC_PKCS12Baggage *sec_pkcs12_create_baggage(PRArenaPool *poolp);
extern SEC_PKCS12BaggageItem *sec_pkcs12_create_external_bag(SEC_PKCS12Baggage *luggage);
extern void SEC_PKCS12DestroyPFX(SEC_PKCS12PFXItem *pfx);
extern SEC_PKCS12AuthenticatedSafe *sec_pkcs12_new_asafe(PRArenaPool *poolp);
/* conversion from old to new */
extern SEC_PKCS12DecoderContext *
sec_PKCS12ConvertOldSafeToNew(PRArenaPool *arena, PK11SlotInfo *slot,
PRBool swapUnicode, SECItem *pwitem,
void *wincx, SEC_PKCS12SafeContents *safe,
SEC_PKCS12Baggage *baggage);
#endif

View File

@ -0,0 +1,198 @@
/*
* 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 "p12plcy.h"
#include "secoid.h"
#include "secport.h"
#include "secpkcs5.h" /* LOTS of PKCS5 calls below. XXX EVIL. */
#define PKCS12_NULL 0x0000
typedef struct pkcs12SuiteMapStr {
SECOidTag algTag;
unsigned int keyLengthBits; /* in bits */
unsigned long suite;
PRBool allowed;
PRBool preferred;
} pkcs12SuiteMap;
static pkcs12SuiteMap pkcs12SuiteMaps[] = {
{ SEC_OID_RC4, 40, PKCS12_RC4_40, PR_FALSE, PR_FALSE},
{ SEC_OID_RC4, 128, PKCS12_RC4_128, PR_FALSE, PR_FALSE},
{ SEC_OID_RC2_CBC, 40, PKCS12_RC2_CBC_40, PR_FALSE, PR_TRUE},
{ SEC_OID_RC2_CBC, 128, PKCS12_RC2_CBC_128, PR_FALSE, PR_FALSE},
{ SEC_OID_DES_CBC, 64, PKCS12_DES_56, PR_FALSE, PR_FALSE},
{ SEC_OID_DES_EDE3_CBC, 192, PKCS12_DES_EDE3_168, PR_FALSE, PR_FALSE},
{ SEC_OID_UNKNOWN, 0, PKCS12_NULL, PR_FALSE, PR_FALSE},
{ SEC_OID_UNKNOWN, 0, 0L, PR_FALSE, PR_FALSE}
};
/* determine if algid is an algorithm which is allowed */
PRBool
SEC_PKCS12DecryptionAllowed(SECAlgorithmID *algid)
{
unsigned int keyLengthBits;
SECOidTag algId;
int i;
algId = SEC_PKCS5GetCryptoAlgorithm(algid);
if(algId == SEC_OID_UNKNOWN) {
return PR_FALSE;
}
keyLengthBits = (unsigned int)(SEC_PKCS5GetKeyLength(algid) * 8);
i = 0;
while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
if((pkcs12SuiteMaps[i].algTag == algId) &&
(pkcs12SuiteMaps[i].keyLengthBits == keyLengthBits)) {
return pkcs12SuiteMaps[i].allowed;
}
i++;
}
return PR_FALSE;
}
/* is any encryption allowed? */
PRBool
SEC_PKCS12IsEncryptionAllowed(void)
{
int i;
i = 0;
while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
if(pkcs12SuiteMaps[i].allowed == PR_TRUE) {
return PR_TRUE;
}
i++;
}
return PR_FALSE;
}
/* get the preferred algorithm.
*/
SECOidTag
SEC_PKCS12GetPreferredEncryptionAlgorithm(void)
{
int i;
i = 0;
while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
if((pkcs12SuiteMaps[i].preferred == PR_TRUE) &&
(pkcs12SuiteMaps[i].allowed == PR_TRUE)) {
return SEC_PKCS5GetPBEAlgorithm(pkcs12SuiteMaps[i].algTag,
pkcs12SuiteMaps[i].keyLengthBits);
}
i++;
}
return SEC_OID_UNKNOWN;
}
/* return the strongest algorithm allowed */
SECOidTag
SEC_PKCS12GetStrongestAllowedAlgorithm(void)
{
int i, keyLengthBits = 0;
SECOidTag algorithm = SEC_OID_UNKNOWN;
i = 0;
while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
if((pkcs12SuiteMaps[i].allowed == PR_TRUE) &&
(pkcs12SuiteMaps[i].keyLengthBits > (unsigned int)keyLengthBits) &&
(pkcs12SuiteMaps[i].algTag != SEC_OID_RC4)) {
algorithm = pkcs12SuiteMaps[i].algTag;
keyLengthBits = pkcs12SuiteMaps[i].keyLengthBits;
}
i++;
}
if(algorithm == SEC_OID_UNKNOWN) {
return SEC_OID_UNKNOWN;
}
return SEC_PKCS5GetPBEAlgorithm(algorithm, keyLengthBits);
}
SECStatus
SEC_PKCS12EnableCipher(long which, int on)
{
int i;
i = 0;
while(pkcs12SuiteMaps[i].suite != 0L) {
if(pkcs12SuiteMaps[i].suite == (unsigned long)which) {
if(on) {
pkcs12SuiteMaps[i].allowed = PR_TRUE;
} else {
pkcs12SuiteMaps[i].allowed = PR_FALSE;
}
return SECSuccess;
}
i++;
}
return SECFailure;
}
SECStatus
SEC_PKCS12SetPreferredCipher(long which, int on)
{
int i;
PRBool turnedOff = PR_FALSE;
PRBool turnedOn = PR_FALSE;
i = 0;
while(pkcs12SuiteMaps[i].suite != 0L) {
if(pkcs12SuiteMaps[i].preferred == PR_TRUE) {
pkcs12SuiteMaps[i].preferred = PR_FALSE;
turnedOff = PR_TRUE;
}
if(pkcs12SuiteMaps[i].suite == (unsigned long)which) {
pkcs12SuiteMaps[i].preferred = PR_TRUE;
turnedOn = PR_TRUE;
}
i++;
}
if((turnedOn) && (turnedOff)) {
return SECSuccess;
}
return SECFailure;
}

View File

@ -0,0 +1,57 @@
/*
* 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 _P12PLCY_H_
#define _P12PLCY_H_
#include "secoid.h"
#include "ciferfam.h"
/* for the algid specified, can we decrypt it ? */
extern PRBool SEC_PKCS12DecryptionAllowed(SECAlgorithmID *algid);
/* is encryption allowed? */
extern PRBool SEC_PKCS12IsEncryptionAllowed(void);
/* get the preferred encryption algorithm */
extern SECOidTag SEC_PKCS12GetPreferredEncryptionAlgorithm(void);
/* get the stronget crypto allowed (based on order in the table */
extern SECOidTag SEC_PKCS12GetStrongestAllowedAlgorithm(void);
/* enable a cipher for encryption/decryption */
extern SECStatus SEC_PKCS12EnableCipher(long which, int on);
/* return the preferred cipher for encryption */
extern SECStatus SEC_PKCS12SetPreferredCipher(long which, int on);
#endif

View File

@ -0,0 +1,182 @@
/*
* 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 _P12T_H_
#define _P12T_H_
#include "secoid.h"
#include "key.h"
#include "pkcs11.h"
#include "secpkcs7.h"
#include "secdig.h" /* for SGNDigestInfo */
#define SEC_PKCS12_VERSION 3
/* structure declarations */
typedef struct sec_PKCS12PFXItemStr sec_PKCS12PFXItem;
typedef struct sec_PKCS12MacDataStr sec_PKCS12MacData;
typedef struct sec_PKCS12AuthenticatedSafeStr sec_PKCS12AuthenticatedSafe;
typedef struct sec_PKCS12SafeContentsStr sec_PKCS12SafeContents;
typedef struct sec_PKCS12SafeBagStr sec_PKCS12SafeBag;
typedef struct sec_PKCS12PKCS8ShroudedKeyBagStr sec_PKCS12PKCS8ShroudedKeyBag;
typedef struct sec_PKCS12CertBagStr sec_PKCS12CertBag;
typedef struct sec_PKCS12CRLBagStr sec_PKCS12CRLBag;
typedef struct sec_PKCS12SecretBag sec_PKCS12SecretBag;
typedef struct sec_PKCS12AttributeStr sec_PKCS12Attribute;
struct sec_PKCS12CertBagStr {
/* what type of cert is stored? */
SECItem bagID;
/* certificate information */
union {
SECItem x509Cert;
SECItem SDSICert;
} value;
};
struct sec_PKCS12CRLBagStr {
/* what type of cert is stored? */
SECItem bagID;
/* certificate information */
union {
SECItem x509CRL;
} value;
};
struct sec_PKCS12SecretBag {
/* what type of secret? */
SECItem secretType;
/* secret information. ssshhhh be vewy vewy quiet. */
SECItem secretContent;
};
struct sec_PKCS12AttributeStr {
SECItem attrType;
SECItem **attrValue;
};
struct sec_PKCS12SafeBagStr {
/* What type of bag are we using? */
SECItem safeBagType;
/* Dependent upon the type of bag being used. */
union {
SECKEYPrivateKeyInfo *pkcs8KeyBag;
SECKEYEncryptedPrivateKeyInfo *pkcs8ShroudedKeyBag;
sec_PKCS12CertBag *certBag;
sec_PKCS12CRLBag *crlBag;
sec_PKCS12SecretBag *secretBag;
sec_PKCS12SafeContents *safeContents;
} safeBagContent;
sec_PKCS12Attribute **attribs;
/* used locally */
SECOidData *bagTypeTag;
PRArenaPool *arena;
unsigned int nAttribs;
/* used for validation/importing */
PRBool problem, noInstall, validated, hasKey, removeExisting, installed;
int error;
PRBool swapUnicodeBytes;
PK11SlotInfo *slot;
SECItem *pwitem;
PRBool oldBagType;
};
struct sec_PKCS12SafeContentsStr {
sec_PKCS12SafeBag **safeBags;
SECItem **encodedSafeBags;
/* used locally */
PRArenaPool *arena;
unsigned int bagCount;
};
struct sec_PKCS12MacDataStr {
SGNDigestInfo safeMac;
SECItem macSalt;
SECItem iter;
};
struct sec_PKCS12PFXItemStr {
SECItem version;
/* Content type will either be Data (password integrity mode)
* or signedData (public-key integrity mode)
*/
SEC_PKCS7ContentInfo *authSafe;
SECItem encodedAuthSafe;
/* Only present in password integrity mode */
sec_PKCS12MacData macData;
SECItem encodedMacData;
};
struct sec_PKCS12AuthenticatedSafeStr {
/* Content type will either be encryptedData (password privacy mode)
* or envelopedData (public-key privacy mode)
*/
SEC_PKCS7ContentInfo **safes;
SECItem **encodedSafes;
/* used locally */
unsigned int safeCount;
SECItem dummySafe;
};
extern const SEC_ASN1Template sec_PKCS12PFXItemTemplate[];
extern const SEC_ASN1Template sec_PKCS12MacDataTemplate[];
extern const SEC_ASN1Template sec_PKCS12AuthenticatedSafeTemplate[];
extern const SEC_ASN1Template sec_PKCS12SafeContentsTemplate[];
extern const SEC_ASN1Template sec_PKCS12SafeContentsDecodeTemplate[];
extern const SEC_ASN1Template sec_PKCS12NestedSafeContentsDecodeTemplate[];
extern const SEC_ASN1Template sec_PKCS12CertBagTemplate[];
extern const SEC_ASN1Template sec_PKCS12CRLBagTemplate[];
extern const SEC_ASN1Template sec_PKCS12SecretBagTemplate[];
extern const SEC_ASN1Template sec_PKCS12PointerToCertBagTemplate[];
extern const SEC_ASN1Template sec_PKCS12PointerToCRLBagTemplate[];
extern const SEC_ASN1Template sec_PKCS12PointerToSecretBagTemplate[];
extern const SEC_ASN1Template sec_PKCS12PointerToSafeContentsTemplate[];
extern const SEC_ASN1Template sec_PKCS12AttributeTemplate[];
extern const SEC_ASN1Template sec_PKCS12PointerToContentInfoTemplate[];
extern const SEC_ASN1Template sec_PKCS12SafeBagTemplate[];
#endif

View File

@ -0,0 +1,315 @@
/*
* 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 "secitem.h"
#include "secoid.h"
#include "seccomon.h"
#include "secport.h"
#include "cert.h"
#include "secpkcs7.h"
#include "secasn1.h"
#include "p12t.h"
static const SEC_ASN1Template *
sec_pkcs12_choose_safe_bag_type(void *src_or_dest, PRBool encoding)
{
const SEC_ASN1Template *theTemplate;
sec_PKCS12SafeBag *safeBag;
SECOidData *oiddata;
if (src_or_dest == NULL) {
return NULL;
}
safeBag = (sec_PKCS12SafeBag*)src_or_dest;
oiddata = SECOID_FindOID(&safeBag->safeBagType);
if(oiddata == NULL) {
return SEC_AnyTemplate;
}
switch (oiddata->offset) {
default:
theTemplate = SEC_AnyTemplate;
break;
case SEC_OID_PKCS12_V1_KEY_BAG_ID:
theTemplate = SECKEY_PointerToPrivateKeyInfoTemplate;
break;
case SEC_OID_PKCS12_V1_CERT_BAG_ID:
theTemplate = sec_PKCS12PointerToCertBagTemplate;
break;
case SEC_OID_PKCS12_V1_CRL_BAG_ID:
theTemplate = sec_PKCS12PointerToCRLBagTemplate;
break;
case SEC_OID_PKCS12_V1_SECRET_BAG_ID:
theTemplate = sec_PKCS12PointerToSecretBagTemplate;
break;
case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
theTemplate = SECKEY_PointerToEncryptedPrivateKeyInfoTemplate;
break;
case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID:
if(encoding) {
theTemplate = sec_PKCS12PointerToSafeContentsTemplate;
} else {
theTemplate = SEC_PointerToAnyTemplate;
}
break;
}
return theTemplate;
}
static const SEC_ASN1Template *
sec_pkcs12_choose_crl_bag_type(void *src_or_dest, PRBool encoding)
{
const SEC_ASN1Template *theTemplate;
sec_PKCS12CRLBag *crlbag;
SECOidData *oiddata;
if (src_or_dest == NULL) {
return NULL;
}
crlbag = (sec_PKCS12CRLBag*)src_or_dest;
oiddata = SECOID_FindOID(&crlbag->bagID);
if(oiddata == NULL) {
return SEC_AnyTemplate;
}
switch (oiddata->offset) {
default:
theTemplate = SEC_AnyTemplate;
break;
case SEC_OID_PKCS9_X509_CRL:
theTemplate = SEC_OctetStringTemplate;
break;
}
return theTemplate;
}
static const SEC_ASN1Template *
sec_pkcs12_choose_cert_bag_type(void *src_or_dest, PRBool encoding)
{
const SEC_ASN1Template *theTemplate;
sec_PKCS12CertBag *certbag;
SECOidData *oiddata;
if (src_or_dest == NULL) {
return NULL;
}
certbag = (sec_PKCS12CertBag*)src_or_dest;
oiddata = SECOID_FindOID(&certbag->bagID);
if(oiddata == NULL) {
return SEC_AnyTemplate;
}
switch (oiddata->offset) {
default:
theTemplate = SEC_AnyTemplate;
break;
case SEC_OID_PKCS9_X509_CERT:
theTemplate = SEC_OctetStringTemplate;
break;
case SEC_OID_PKCS9_SDSI_CERT:
theTemplate = SEC_IA5StringTemplate;
break;
}
return theTemplate;
}
static const SEC_ASN1Template *
sec_pkcs12_choose_attr_type(void *src_or_dest, PRBool encoding)
{
const SEC_ASN1Template *theTemplate;
sec_PKCS12Attribute *attr;
SECOidData *oiddata;
if (src_or_dest == NULL) {
return NULL;
}
attr = (sec_PKCS12Attribute*)src_or_dest;
oiddata = SECOID_FindOID(&attr->attrType);
if(oiddata == NULL) {
return SEC_AnyTemplate;
}
switch (oiddata->offset) {
default:
theTemplate = SEC_AnyTemplate;
break;
case SEC_OID_PKCS9_FRIENDLY_NAME:
theTemplate = SEC_BMPStringTemplate;
break;
case SEC_OID_PKCS9_LOCAL_KEY_ID:
theTemplate = SEC_OctetStringTemplate;
break;
case SEC_OID_PKCS12_KEY_USAGE:
theTemplate = SEC_BitStringTemplate;
break;
}
return theTemplate;
}
const SEC_ASN1Template sec_PKCS12PointerToContentInfoTemplate[] = {
{ SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM, 0, sec_PKCS7ContentInfoTemplate }
};
static SEC_ChooseASN1TemplateFunc sec_pkcs12_crl_bag_chooser =
sec_pkcs12_choose_crl_bag_type;
static SEC_ChooseASN1TemplateFunc sec_pkcs12_cert_bag_chooser =
sec_pkcs12_choose_cert_bag_type;
static SEC_ChooseASN1TemplateFunc sec_pkcs12_safe_bag_chooser =
sec_pkcs12_choose_safe_bag_type;
static SEC_ChooseASN1TemplateFunc sec_pkcs12_attr_chooser =
sec_pkcs12_choose_attr_type;
const SEC_ASN1Template sec_PKCS12PointerToCertBagTemplate[] = {
{ SEC_ASN1_POINTER, 0, sec_PKCS12CertBagTemplate }
};
const SEC_ASN1Template sec_PKCS12PointerToCRLBagTemplate[] = {
{ SEC_ASN1_POINTER, 0, sec_PKCS12CRLBagTemplate }
};
const SEC_ASN1Template sec_PKCS12PointerToSecretBagTemplate[] = {
{ SEC_ASN1_POINTER, 0, sec_PKCS12SecretBagTemplate }
};
const SEC_ASN1Template sec_PKCS12PointerToSafeContentsTemplate[] = {
{ SEC_ASN1_POINTER, 0, sec_PKCS12SafeContentsTemplate }
};
const SEC_ASN1Template sec_PKCS12PFXItemTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, 0, NULL,
sizeof(sec_PKCS12PFXItem) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
offsetof(sec_PKCS12PFXItem, version) },
{ SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM,
offsetof(sec_PKCS12PFXItem, encodedAuthSafe) },
{ SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM,
offsetof(sec_PKCS12PFXItem, encodedMacData) },
{ 0 }
};
const SEC_ASN1Template sec_PKCS12MacDataTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12MacData) },
{ SEC_ASN1_INLINE, offsetof(sec_PKCS12MacData, safeMac),
sgn_DigestInfoTemplate },
{ SEC_ASN1_OCTET_STRING, offsetof(sec_PKCS12MacData, macSalt) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, offsetof(sec_PKCS12MacData, iter) },
{ 0 }
};
const SEC_ASN1Template sec_PKCS12AuthenticatedSafeTemplate[] = {
{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM,
offsetof(sec_PKCS12AuthenticatedSafe, encodedSafes), SEC_AnyTemplate }
};
const SEC_ASN1Template sec_PKCS12SafeBagTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, 0, NULL,
sizeof(sec_PKCS12SafeBag) },
{ SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12SafeBag, safeBagType) },
{ SEC_ASN1_EXPLICIT | SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED |
SEC_ASN1_MAY_STREAM | SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(sec_PKCS12SafeBag, safeBagContent),
&sec_pkcs12_safe_bag_chooser },
{ SEC_ASN1_SET_OF | SEC_ASN1_OPTIONAL, offsetof(sec_PKCS12SafeBag, attribs),
sec_PKCS12AttributeTemplate },
{ 0 }
};
const SEC_ASN1Template sec_PKCS12SafeContentsTemplate[] = {
{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM,
offsetof(sec_PKCS12SafeContents, safeBags),
sec_PKCS12SafeBagTemplate }
};
const SEC_ASN1Template sec_PKCS12SequenceOfAnyTemplate[] = {
{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM, 0,
SEC_AnyTemplate }
};
const SEC_ASN1Template sec_PKCS12NestedSafeContentsDecodeTemplate[] = {
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
offsetof(sec_PKCS12SafeContents, encodedSafeBags),
sec_PKCS12SequenceOfAnyTemplate }
};
const SEC_ASN1Template sec_PKCS12SafeContentsDecodeTemplate[] = {
{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM,
offsetof(sec_PKCS12SafeContents, encodedSafeBags),
SEC_AnyTemplate }
};
const SEC_ASN1Template sec_PKCS12CRLBagTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12CRLBag) },
{ SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12CRLBag, bagID) },
{ SEC_ASN1_DYNAMIC | SEC_ASN1_POINTER,
offsetof(sec_PKCS12CRLBag, value), &sec_pkcs12_crl_bag_chooser },
{ 0 }
};
const SEC_ASN1Template sec_PKCS12CertBagTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12CertBag) },
{ SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12CertBag, bagID) },
{ SEC_ASN1_DYNAMIC | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(sec_PKCS12CertBag, value), &sec_pkcs12_cert_bag_chooser },
{ 0 }
};
const SEC_ASN1Template sec_PKCS12SecretBagTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12SecretBag) },
{ SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12SecretBag, secretType) },
{ SEC_ASN1_ANY, offsetof(sec_PKCS12SecretBag, secretContent) },
{ 0 }
};
const SEC_ASN1Template sec_PKCS12AttributeTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12Attribute) },
{ SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12Attribute, attrType) },
{ SEC_ASN1_SET_OF | SEC_ASN1_DYNAMIC,
offsetof(sec_PKCS12Attribute, attrValue),
&sec_pkcs12_attr_chooser },
{ 0 }
};

View File

@ -0,0 +1,67 @@
/*
* 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 _PKCS12_H_
#define _PKCS12_H_
#include "pkcs12t.h"
#include "p12.h"
typedef SECItem * (* SEC_PKCS12GetPassword)(void *arg);
/* Decode functions */
/* Import a PFX item.
* der_pfx is the der-encoded pfx item to import.
* pbef, and pbefarg are used to retrieve passwords for the HMAC,
* and any passwords needed for passing to PKCS5 encryption
* routines.
* algorithm is the algorithm by which private keys are stored in
* the key database. this could be a specific algorithm or could
* be based on a global setting.
* slot is the slot to where the certificates will be placed. if NULL,
* the internal key slot is used.
* If the process is successful, a SECSuccess is returned, otherwise
* a failure occurred.
*/
SECStatus
SEC_PKCS12PutPFX(SECItem *der_pfx, SECItem *pwitem,
SEC_PKCS12NicknameCollisionCallback ncCall,
PK11SlotInfo *slot, void *wincx);
/* check the first two bytes of a file to make sure that it matches
* the desired header for a PKCS 12 file
*/
PRBool SEC_PKCS12ValidData(char *buf, int bufLen, long int totalLength);
#endif

View File

@ -0,0 +1,386 @@
/*
* 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 _PKCS12T_H_
#define _PKCS12T_H_
#include "seccomon.h"
#include "secoid.h"
#include "cert.h"
#include "key.h"
#include "plarena.h"
#include "secpkcs7.h"
#include "secdig.h" /* for SGNDigestInfo */
/* PKCS12 Structures */
typedef struct SEC_PKCS12PFXItemStr SEC_PKCS12PFXItem;
typedef struct SEC_PKCS12MacDataStr SEC_PKCS12MacData;
typedef struct SEC_PKCS12AuthenticatedSafeStr SEC_PKCS12AuthenticatedSafe;
typedef struct SEC_PKCS12BaggageItemStr SEC_PKCS12BaggageItem;
typedef struct SEC_PKCS12BaggageStr SEC_PKCS12Baggage;
typedef struct SEC_PKCS12Baggage_OLDStr SEC_PKCS12Baggage_OLD;
typedef struct SEC_PKCS12ESPVKItemStr SEC_PKCS12ESPVKItem;
typedef struct SEC_PKCS12PVKSupportingDataStr SEC_PKCS12PVKSupportingData;
typedef struct SEC_PKCS12PVKAdditionalDataStr SEC_PKCS12PVKAdditionalData;
typedef struct SEC_PKCS12SafeContentsStr SEC_PKCS12SafeContents;
typedef struct SEC_PKCS12SafeBagStr SEC_PKCS12SafeBag;
typedef struct SEC_PKCS12PrivateKeyStr SEC_PKCS12PrivateKey;
typedef struct SEC_PKCS12PrivateKeyBagStr SEC_PKCS12PrivateKeyBag;
typedef struct SEC_PKCS12CertAndCRLBagStr SEC_PKCS12CertAndCRLBag;
typedef struct SEC_PKCS12CertAndCRLStr SEC_PKCS12CertAndCRL;
typedef struct SEC_PKCS12X509CertCRLStr SEC_PKCS12X509CertCRL;
typedef struct SEC_PKCS12SDSICertStr SEC_PKCS12SDSICert;
typedef struct SEC_PKCS12SecretStr SEC_PKCS12Secret;
typedef struct SEC_PKCS12SecretAdditionalStr SEC_PKCS12SecretAdditional;
typedef struct SEC_PKCS12SecretItemStr SEC_PKCS12SecretItem;
typedef struct SEC_PKCS12SecretBagStr SEC_PKCS12SecretBag;
typedef SECItem *(* SEC_PKCS12PasswordFunc)(SECItem *args);
/* PKCS12 types */
/* stores shrouded keys */
struct SEC_PKCS12BaggageStr
{
PRArenaPool *poolp;
SEC_PKCS12BaggageItem **bags;
int luggage_size; /* used locally */
};
/* additional data to be associated with keys. currently there
* is nothing defined to be stored here. allows future expansion.
*/
struct SEC_PKCS12PVKAdditionalDataStr
{
PRArenaPool *poolp;
SECOidData *pvkAdditionalTypeTag; /* used locally */
SECItem pvkAdditionalType;
SECItem pvkAdditionalContent;
};
/* cert and other supporting data for private keys. used
* for both shrouded and non-shrouded keys.
*/
struct SEC_PKCS12PVKSupportingDataStr
{
PRArenaPool *poolp;
SGNDigestInfo **assocCerts;
SECItem regenerable;
SECItem nickname;
SEC_PKCS12PVKAdditionalData pvkAdditional;
SECItem pvkAdditionalDER;
SECItem uniNickName;
/* used locally */
int nThumbs;
};
/* shrouded key structure. supports only pkcs8 shrouding
* currently.
*/
struct SEC_PKCS12ESPVKItemStr
{
PRArenaPool *poolp; /* used locally */
SECOidData *espvkTag; /* used locally */
SECItem espvkOID;
SEC_PKCS12PVKSupportingData espvkData;
union
{
SECKEYEncryptedPrivateKeyInfo *pkcs8KeyShroud;
} espvkCipherText;
PRBool duplicate; /* used locally */
PRBool problem_cert; /* used locally */
PRBool single_cert; /* used locally */
int nCerts; /* used locally */
SECItem derCert; /* used locally */
};
/* generic bag store for the safe. safeBagType identifies
* the type of bag stored.
*/
struct SEC_PKCS12SafeBagStr
{
PRArenaPool *poolp;
SECOidData *safeBagTypeTag; /* used locally */
SECItem safeBagType;
union
{
SEC_PKCS12PrivateKeyBag *keyBag;
SEC_PKCS12CertAndCRLBag *certAndCRLBag;
SEC_PKCS12SecretBag *secretBag;
} safeContent;
SECItem derSafeContent;
SECItem safeBagName;
SECItem uniSafeBagName;
};
/* stores private keys and certificates in a list. each safebag
* has an ID identifying the type of content stored.
*/
struct SEC_PKCS12SafeContentsStr
{
PRArenaPool *poolp;
SEC_PKCS12SafeBag **contents;
/* used for tracking purposes */
int safe_size;
PRBool old;
PRBool swapUnicode;
PRBool possibleSwapUnicode;
};
/* private key structure which holds encrypted private key and
* supporting data including nickname and certificate thumbprint.
*/
struct SEC_PKCS12PrivateKeyStr
{
PRArenaPool *poolp;
SEC_PKCS12PVKSupportingData pvkData;
SECKEYPrivateKeyInfo pkcs8data; /* borrowed from PKCS 8 */
PRBool duplicate; /* used locally */
PRBool problem_cert;/* used locally */
PRBool single_cert; /* used locally */
int nCerts; /* used locally */
SECItem derCert; /* used locally */
};
/* private key bag, holds a (null terminated) list of private key
* structures.
*/
struct SEC_PKCS12PrivateKeyBagStr
{
PRArenaPool *poolp;
SEC_PKCS12PrivateKey **privateKeys;
int bag_size; /* used locally */
};
/* container to hold certificates. currently supports x509
* and sdsi certificates
*/
struct SEC_PKCS12CertAndCRLStr
{
PRArenaPool *poolp;
SECOidData *BagTypeTag; /* used locally */
SECItem BagID;
union
{
SEC_PKCS12X509CertCRL *x509;
SEC_PKCS12SDSICert *sdsi;
} value;
SECItem derValue;
SECItem nickname; /* used locally */
PRBool duplicate; /* used locally */
};
/* x509 certificate structure. typically holds the der encoding
* of the x509 certificate. thumbprint contains a digest of the
* certificate
*/
struct SEC_PKCS12X509CertCRLStr
{
PRArenaPool *poolp;
SEC_PKCS7ContentInfo certOrCRL;
SGNDigestInfo thumbprint;
SECItem *derLeafCert; /* used locally */
};
/* sdsi certificate structure. typically holds the der encoding
* of the sdsi certificate. thumbprint contains a digest of the
* certificate
*/
struct SEC_PKCS12SDSICertStr
{
PRArenaPool *poolp;
SECItem value;
SGNDigestInfo thumbprint;
};
/* contains a null terminated list of certs and crls */
struct SEC_PKCS12CertAndCRLBagStr
{
PRArenaPool *poolp;
SEC_PKCS12CertAndCRL **certAndCRLs;
int bag_size; /* used locally */
};
/* additional secret information. currently no information
* stored in this structure.
*/
struct SEC_PKCS12SecretAdditionalStr
{
PRArenaPool *poolp;
SECOidData *secretTypeTag; /* used locally */
SECItem secretAdditionalType;
SECItem secretAdditionalContent;
};
/* secrets container. this will be used to contain currently
* unspecified secrets. (it's a secret)
*/
struct SEC_PKCS12SecretStr
{
PRArenaPool *poolp;
SECItem secretName;
SECItem value;
SEC_PKCS12SecretAdditional secretAdditional;
SECItem uniSecretName;
};
struct SEC_PKCS12SecretItemStr
{
PRArenaPool *poolp;
SEC_PKCS12Secret secret;
SEC_PKCS12SafeBag subFolder;
};
/* a bag of secrets. holds a null terminated list of secrets.
*/
struct SEC_PKCS12SecretBagStr
{
PRArenaPool *poolp;
SEC_PKCS12SecretItem **secrets;
int bag_size; /* used locally */
};
struct SEC_PKCS12MacDataStr
{
SGNDigestInfo safeMac;
SECItem macSalt;
};
/* outer transfer unit */
struct SEC_PKCS12PFXItemStr
{
PRArenaPool *poolp;
SEC_PKCS12MacData macData;
SEC_PKCS7ContentInfo authSafe;
/* for compatibility with beta */
PRBool old;
SGNDigestInfo old_safeMac;
SECItem old_macSalt;
/* compatibility between platforms for unicode swapping */
PRBool swapUnicode;
};
struct SEC_PKCS12BaggageItemStr {
PRArenaPool *poolp;
SEC_PKCS12ESPVKItem **espvks;
SEC_PKCS12SafeBag **unencSecrets;
int nEspvks;
int nSecrets;
};
/* stores shrouded keys */
struct SEC_PKCS12Baggage_OLDStr
{
PRArenaPool *poolp;
SEC_PKCS12ESPVKItem **espvks;
int luggage_size; /* used locally */
};
/* authenticated safe, stores certs, keys, and shrouded keys */
struct SEC_PKCS12AuthenticatedSafeStr
{
PRArenaPool *poolp;
SECItem version;
SECOidData *transportTypeTag; /* local not part of encoding*/
SECItem transportMode;
SECItem privacySalt;
SEC_PKCS12Baggage baggage;
SEC_PKCS7ContentInfo *safe;
/* used for beta compatibility */
PRBool old;
PRBool emptySafe;
SEC_PKCS12Baggage_OLD old_baggage;
SEC_PKCS7ContentInfo old_safe;
PRBool swapUnicode;
};
#define SEC_PKCS12_PFX_VERSION 1 /* what we create */
/* PKCS 12 Templates */
extern const SEC_ASN1Template SEC_PKCS12PFXItemTemplate_OLD[];
extern const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate_OLD[];
extern const SEC_ASN1Template SEC_PKCS12BaggageTemplate_OLD[];
extern const SEC_ASN1Template SEC_PKCS12PFXItemTemplate[];
extern const SEC_ASN1Template SEC_PKCS12MacDataTemplate[];
extern const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate[];
extern const SEC_ASN1Template SEC_PKCS12BaggageTemplate[];
extern const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate[];
extern const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate[];
extern const SEC_ASN1Template SEC_PKCS12PVKAdditionalTemplate[];
extern const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate_OLD[];
extern const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate[];
extern const SEC_ASN1Template SEC_PKCS12SafeBagTemplate[];
extern const SEC_ASN1Template SEC_PKCS12PrivateKeyTemplate[];
extern const SEC_ASN1Template SEC_PKCS12PrivateKeyBagTemplate[];
extern const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate[];
extern const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate[];
extern const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate_OLD[];
extern const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate[];
extern const SEC_ASN1Template SEC_PKCS12SDSICertTemplate[];
extern const SEC_ASN1Template SEC_PKCS12SecretBagTemplate[];
extern const SEC_ASN1Template SEC_PKCS12SecretTemplate[];
extern const SEC_ASN1Template SEC_PKCS12SecretItemTemplate[];
extern const SEC_ASN1Template SEC_PKCS12SecretAdditionalTemplate[];
extern const SEC_ASN1Template SGN_DigestInfoTemplate[];
extern const SEC_ASN1Template SEC_PointerToPKCS12KeyBagTemplate[];
extern const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate[];
extern const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD[];
extern const SEC_ASN1Template SEC_PointerToPKCS12SecretBagTemplate[];
extern const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate_OLD[];
extern const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate[];
extern const SEC_ASN1Template SEC_PointerToPKCS12SDSICertTemplate[];
extern const SEC_ASN1Template SEC_PKCS12CodedSafeBagTemplate[];
extern const SEC_ASN1Template SEC_PKCS12CodedCertBagTemplate[];
extern const SEC_ASN1Template SEC_PKCS12CodedCertAndCRLBagTemplate[];
extern const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate_OLD[];
extern const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate_OLD[];
#endif

View File

@ -0,0 +1,76 @@
#! 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). #
#######################################################################

View File

@ -0,0 +1,44 @@
#
# 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 =

View File

@ -0,0 +1,59 @@
#
# 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 = ../../..
EXPORTS = \
secmime.h \
secpkcs7.h \
pkcs7t.h \
$(NULL)
PRIVATE_EXPORTS = \
p7local.h \
$(NULL)
MODULE = security
CSRCS = \
p7common.c \
p7create.c \
p7decode.c \
p7encode.c \
p7local.c \
secmime.c \
$(NULL)
REQUIRES = security dbm
LIBRARY_NAME = pkcs7

View File

@ -0,0 +1,738 @@
/*
* 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.
*/
/*
* PKCS7 implementation -- the exported parts that are used whether
* creating or decoding.
*
* $Id: p7common.c,v 1.1 2000/03/31 19:16:04 relyea%netscape.com Exp $
*/
#include "p7local.h"
#include "cert.h"
#include "secitem.h"
#include "secoid.h"
#include "secpkcs5.h"
#include "pk11func.h"
/*
* Find out (saving pointer to lookup result for future reference)
* and return the inner content type.
*/
SECOidTag
SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo)
{
if (cinfo->contentTypeTag == NULL)
cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
if (cinfo->contentTypeTag == NULL)
return SEC_OID_UNKNOWN;
return cinfo->contentTypeTag->offset;
}
/*
* Destroy a PKCS7 contentInfo and all of its sub-pieces.
*/
void
SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *cinfo)
{
SECOidTag kind;
CERTCertificate **certs;
CERTCertificateList **certlists;
SEC_PKCS7SignerInfo **signerinfos;
SEC_PKCS7RecipientInfo **recipientinfos;
PORT_Assert (cinfo->refCount > 0);
if (cinfo->refCount <= 0)
return;
cinfo->refCount--;
if (cinfo->refCount > 0)
return;
certs = NULL;
certlists = NULL;
recipientinfos = NULL;
signerinfos = NULL;
kind = SEC_PKCS7ContentType (cinfo);
switch (kind) {
case SEC_OID_PKCS7_ENVELOPED_DATA:
{
SEC_PKCS7EnvelopedData *edp;
edp = cinfo->content.envelopedData;
if (edp != NULL) {
recipientinfos = edp->recipientInfos;
}
}
break;
case SEC_OID_PKCS7_SIGNED_DATA:
{
SEC_PKCS7SignedData *sdp;
sdp = cinfo->content.signedData;
if (sdp != NULL) {
certs = sdp->certs;
certlists = sdp->certLists;
signerinfos = sdp->signerInfos;
}
}
break;
case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
{
SEC_PKCS7SignedAndEnvelopedData *saedp;
saedp = cinfo->content.signedAndEnvelopedData;
if (saedp != NULL) {
certs = saedp->certs;
certlists = saedp->certLists;
recipientinfos = saedp->recipientInfos;
signerinfos = saedp->signerInfos;
if (saedp->sigKey != NULL)
PK11_FreeSymKey (saedp->sigKey);
}
}
break;
default:
/* XXX Anything else that needs to be "manually" freed/destroyed? */
break;
}
if (certs != NULL) {
CERTCertificate *cert;
while ((cert = *certs++) != NULL) {
CERT_DestroyCertificate (cert);
}
}
if (certlists != NULL) {
CERTCertificateList *certlist;
while ((certlist = *certlists++) != NULL) {
CERT_DestroyCertificateList (certlist);
}
}
if (recipientinfos != NULL) {
SEC_PKCS7RecipientInfo *ri;
while ((ri = *recipientinfos++) != NULL) {
if (ri->cert != NULL)
CERT_DestroyCertificate (ri->cert);
}
}
if (signerinfos != NULL) {
SEC_PKCS7SignerInfo *si;
while ((si = *signerinfos++) != NULL) {
if (si->cert != NULL)
CERT_DestroyCertificate (si->cert);
if (si->certList != NULL)
CERT_DestroyCertificateList (si->certList);
}
}
if (cinfo->poolp != NULL) {
PORT_FreeArena (cinfo->poolp, PR_FALSE); /* XXX clear it? */
}
}
/*
* Return a copy of the given contentInfo. The copy may be virtual
* or may be real -- either way, the result needs to be passed to
* SEC_PKCS7DestroyContentInfo later (as does the original).
*/
SEC_PKCS7ContentInfo *
SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *cinfo)
{
if (cinfo == NULL)
return NULL;
PORT_Assert (cinfo->refCount > 0);
if (cinfo->created) {
/*
* Want to do a real copy of these; otherwise subsequent
* changes made to either copy are likely to be a surprise.
* XXX I suspect that this will not actually be called for yet,
* which is why the assert, so to notice if it is...
*/
PORT_Assert (0);
/*
* XXX Create a new pool here, and copy everything from
* within. For cert stuff, need to call the appropriate
* copy functions, etc.
*/
}
cinfo->refCount++;
return cinfo;
}
/*
* Return a pointer to the actual content. In the case of those types
* which are encrypted, this returns the *plain* content.
* XXX Needs revisiting if/when we handle nested encrypted types.
*/
SECItem *
SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo)
{
SECOidTag kind;
kind = SEC_PKCS7ContentType (cinfo);
switch (kind) {
case SEC_OID_PKCS7_DATA:
return cinfo->content.data;
case SEC_OID_PKCS7_DIGESTED_DATA:
{
SEC_PKCS7DigestedData *digd;
digd = cinfo->content.digestedData;
if (digd == NULL)
break;
return SEC_PKCS7GetContent (&(digd->contentInfo));
}
case SEC_OID_PKCS7_ENCRYPTED_DATA:
{
SEC_PKCS7EncryptedData *encd;
encd = cinfo->content.encryptedData;
if (encd == NULL)
break;
return &(encd->encContentInfo.plainContent);
}
case SEC_OID_PKCS7_ENVELOPED_DATA:
{
SEC_PKCS7EnvelopedData *envd;
envd = cinfo->content.envelopedData;
if (envd == NULL)
break;
return &(envd->encContentInfo.plainContent);
}
case SEC_OID_PKCS7_SIGNED_DATA:
{
SEC_PKCS7SignedData *sigd;
sigd = cinfo->content.signedData;
if (sigd == NULL)
break;
return SEC_PKCS7GetContent (&(sigd->contentInfo));
}
case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
{
SEC_PKCS7SignedAndEnvelopedData *saed;
saed = cinfo->content.signedAndEnvelopedData;
if (saed == NULL)
break;
return &(saed->encContentInfo.plainContent);
}
default:
PORT_Assert(0);
break;
}
return NULL;
}
/*
* XXX Fix the placement and formatting of the
* following routines (i.e. make them consistent with the rest of
* the pkcs7 code -- I think some/many belong in other files and
* they all need a formatting/style rehaul)
*/
/* retrieve the algorithm identifier for encrypted data.
* the identifier returned is a copy of the algorithm identifier
* in the content info and needs to be freed after being used.
*
* cinfo is the content info for which to retrieve the
* encryption algorithm.
*
* if the content info is not encrypted data or an error
* occurs NULL is returned.
*/
SECAlgorithmID *
SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo)
{
SECAlgorithmID *alg = 0;
switch (SEC_PKCS7ContentType(cinfo))
{
case SEC_OID_PKCS7_ENCRYPTED_DATA:
alg = &cinfo->content.encryptedData->encContentInfo.contentEncAlg;
break;
case SEC_OID_PKCS7_ENVELOPED_DATA:
alg = &cinfo->content.envelopedData->encContentInfo.contentEncAlg;
break;
case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
alg = &cinfo->content.signedAndEnvelopedData
->encContentInfo.contentEncAlg;
break;
default:
alg = 0;
break;
}
return alg;
}
/* set the content of the content info. For data content infos,
* the data is set. For encrytped content infos, the plainContent
* is set, and is expected to be encrypted later.
*
* cinfo is the content info where the data will be set
*
* buf is a buffer of the data to set
*
* len is the length of the data being set.
*
* in the event of an error, SECFailure is returned. SECSuccess
* indicates the content was successfully set.
*/
SECStatus
SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo,
const char *buf,
unsigned long len)
{
SECOidTag cinfo_type;
SECStatus rv;
SECItem content;
SECOidData *contentTypeTag = NULL;
content.data = (unsigned char *)buf;
content.len = len;
cinfo_type = SEC_PKCS7ContentType(cinfo);
/* set inner content */
switch(cinfo_type)
{
case SEC_OID_PKCS7_SIGNED_DATA:
if(content.len > 0) {
/* we "leak" the old content here, but as it's all in the pool */
/* it does not really matter */
/* create content item if necessary */
if (cinfo->content.signedData->contentInfo.content.data == NULL)
cinfo->content.signedData->contentInfo.content.data = SECITEM_AllocItem(cinfo->poolp, NULL, 0);
rv = SECITEM_CopyItem(cinfo->poolp,
cinfo->content.signedData->contentInfo.content.data,
&content);
} else {
cinfo->content.signedData->contentInfo.content.data->data = NULL;
cinfo->content.signedData->contentInfo.content.data->len = 0;
rv = SECSuccess;
}
if(rv == SECFailure)
goto loser;
break;
case SEC_OID_PKCS7_ENCRYPTED_DATA:
/* XXX this forces the inner content type to be "data" */
/* do we really want to override without asking or reason? */
contentTypeTag = SECOID_FindOIDByTag(SEC_OID_PKCS7_DATA);
if(contentTypeTag == NULL)
goto loser;
rv = SECITEM_CopyItem(cinfo->poolp,
&(cinfo->content.encryptedData->encContentInfo.contentType),
&(contentTypeTag->oid));
if(rv == SECFailure)
goto loser;
if(content.len > 0) {
rv = SECITEM_CopyItem(cinfo->poolp,
&(cinfo->content.encryptedData->encContentInfo.plainContent),
&content);
} else {
cinfo->content.encryptedData->encContentInfo.plainContent.data = NULL;
cinfo->content.encryptedData->encContentInfo.encContent.data = NULL;
cinfo->content.encryptedData->encContentInfo.plainContent.len = 0;
cinfo->content.encryptedData->encContentInfo.encContent.len = 0;
rv = SECSuccess;
}
if(rv == SECFailure)
goto loser;
break;
case SEC_OID_PKCS7_DATA:
cinfo->content.data = (SECItem *)PORT_ArenaZAlloc(cinfo->poolp,
sizeof(SECItem));
if(cinfo->content.data == NULL)
goto loser;
if(content.len > 0) {
rv = SECITEM_CopyItem(cinfo->poolp,
cinfo->content.data, &content);
} else {
/* handle case with NULL content */
rv = SECSuccess;
}
if(rv == SECFailure)
goto loser;
break;
default:
goto loser;
}
return SECSuccess;
loser:
return SECFailure;
}
/* the content of an encrypted data content info is encrypted.
* it is assumed that for encrypted data, that the data has already
* been set and is in the "plainContent" field of the content info.
*
* cinfo is the content info to encrypt
*
* key is the key with which to perform the encryption. if the
* algorithm is a password based encryption algorithm, the
* key is actually a password which will be processed per
* PKCS #5.
*
* in the event of an error, SECFailure is returned. SECSuccess
* indicates a success.
*/
SECStatus
SEC_PKCS7EncryptContents(PRArenaPool *poolp,
SEC_PKCS7ContentInfo *cinfo,
SECItem *key,
void *wincx)
{
SECAlgorithmID *algid = NULL;
SECItem * result = NULL;
SECItem * src;
SECItem * dest;
SECItem * blocked_data = NULL;
void * mark;
void * cx;
PK11SymKey * eKey = NULL;
PK11SlotInfo * slot = NULL;
CK_MECHANISM pbeMech;
CK_MECHANISM cryptoMech;
int bs;
SECOidTag algtag;
SECStatus rv = SECFailure;
SECItem c_param;
if((cinfo == NULL) || (key == NULL))
return SECFailure;
if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
return SECFailure;
algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
if(algid == NULL)
return SECFailure;
if(poolp == NULL)
poolp = cinfo->poolp;
mark = PORT_ArenaMark(poolp);
src = &cinfo->content.encryptedData->encContentInfo.plainContent;
dest = &cinfo->content.encryptedData->encContentInfo.encContent;
algtag = SECOID_GetAlgorithmTag(algid);
c_param.data = NULL;
dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));
dest->len = (src->len + 64);
if(dest->data == NULL) {
rv = SECFailure;
goto loser;
}
slot = PK11_GetInternalKeySlot();
if(slot == NULL) {
rv = SECFailure;
goto loser;
}
eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
if(eKey == NULL) {
rv = SECFailure;
goto loser;
}
pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
result = PK11_ParamFromAlgid(algid);
pbeMech.pParameter = result->data;
pbeMech.ulParameterLen = result->len;
if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key,
PR_FALSE) != CKR_OK) {
rv = SECFailure;
goto loser;
}
c_param.data = (unsigned char *)cryptoMech.pParameter;
c_param.len = cryptoMech.ulParameterLen;
/* block according to PKCS 8 */
bs = PK11_GetBlockSize(cryptoMech.mechanism, &c_param);
rv = SECSuccess;
if(bs) {
char pad_char;
pad_char = (char)(bs - (src->len % bs));
if(src->len % bs) {
rv = SECSuccess;
blocked_data = PK11_BlockData(src, bs);
if(blocked_data) {
PORT_Memset((blocked_data->data + blocked_data->len - (int)pad_char),
pad_char, (int)pad_char);
} else {
rv = SECFailure;
goto loser;
}
} else {
blocked_data = SECITEM_DupItem(src);
if(blocked_data) {
blocked_data->data = (unsigned char*)PORT_Realloc(
blocked_data->data,
blocked_data->len + bs);
if(blocked_data->data) {
blocked_data->len += bs;
PORT_Memset((blocked_data->data + src->len), (char)bs, bs);
} else {
rv = SECFailure;
goto loser;
}
} else {
rv = SECFailure;
goto loser;
}
}
} else {
blocked_data = SECITEM_DupItem(src);
if(!blocked_data) {
rv = SECFailure;
goto loser;
}
}
cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_ENCRYPT,
eKey, &c_param);
if(cx == NULL) {
rv = SECFailure;
goto loser;
}
rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len),
(int)(src->len + 64), blocked_data->data,
(int)blocked_data->len);
PK11_DestroyContext((PK11Context*)cx, PR_TRUE);
loser:
/* let success fall through */
if(blocked_data != NULL)
SECITEM_ZfreeItem(blocked_data, PR_TRUE);
if(result != NULL)
SECITEM_ZfreeItem(result, PR_TRUE);
if(rv == SECFailure)
PORT_ArenaRelease(poolp, mark);
else
PORT_ArenaUnmark(poolp, mark);
if(eKey != NULL)
PK11_FreeSymKey(eKey);
if(slot != NULL)
PK11_FreeSlot(slot);
if(c_param.data != NULL)
SECITEM_ZfreeItem(&c_param, PR_FALSE);
return rv;
}
/* the content of an encrypted data content info is decrypted.
* it is assumed that for encrypted data, that the data has already
* been set and is in the "encContent" field of the content info.
*
* cinfo is the content info to decrypt
*
* key is the key with which to perform the decryption. if the
* algorithm is a password based encryption algorithm, the
* key is actually a password which will be processed per
* PKCS #5.
*
* in the event of an error, SECFailure is returned. SECSuccess
* indicates a success.
*/
SECStatus
SEC_PKCS7DecryptContents(PRArenaPool *poolp,
SEC_PKCS7ContentInfo *cinfo,
SECItem *key,
void *wincx)
{
SECAlgorithmID *algid = NULL;
SECOidTag algtag;
SECStatus rv = SECFailure;
SECItem *result = NULL, *dest, *src;
void *mark;
PK11SymKey *eKey = NULL;
PK11SlotInfo *slot = NULL;
CK_MECHANISM pbeMech, cryptoMech;
void *cx;
SECItem c_param;
int bs;
if((cinfo == NULL) || (key == NULL))
return SECFailure;
if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
return SECFailure;
algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
if(algid == NULL)
return SECFailure;
if(poolp == NULL)
poolp = cinfo->poolp;
mark = PORT_ArenaMark(poolp);
src = &cinfo->content.encryptedData->encContentInfo.encContent;
dest = &cinfo->content.encryptedData->encContentInfo.plainContent;
algtag = SECOID_GetAlgorithmTag(algid);
c_param.data = NULL;
dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));
dest->len = (src->len + 64);
if(dest->data == NULL) {
rv = SECFailure;
goto loser;
}
slot = PK11_GetInternalKeySlot();
if(slot == NULL) {
rv = SECFailure;
goto loser;
}
eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
if(eKey == NULL) {
rv = SECFailure;
goto loser;
}
pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
result = PK11_ParamFromAlgid(algid);
pbeMech.pParameter = result->data;
pbeMech.ulParameterLen = result->len;
if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key,
PR_FALSE) != CKR_OK) {
rv = SECFailure;
goto loser;
}
c_param.data = (unsigned char *)cryptoMech.pParameter;
c_param.len = cryptoMech.ulParameterLen;
cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_DECRYPT,
eKey, &c_param);
if(cx == NULL) {
rv = SECFailure;
goto loser;
}
rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len),
(int)(src->len + 64), src->data, (int)src->len);
PK11_DestroyContext((PK11Context *)cx, PR_TRUE);
bs = PK11_GetBlockSize(cryptoMech.mechanism, &c_param);
if(bs) {
/* check for proper badding in block algorithms. this assumes
* RC2 cbc or a DES cbc variant. and the padding is thus defined
*/
if(((int)dest->data[dest->len-1] <= bs) &&
((int)dest->data[dest->len-1] > 0)) {
dest->len -= (int)dest->data[dest->len-1];
} else {
rv = SECFailure;
/* set an error ? */
}
}
loser:
/* let success fall through */
if(result != NULL)
SECITEM_ZfreeItem(result, PR_TRUE);
if(rv == SECFailure)
PORT_ArenaRelease(poolp, mark);
else
PORT_ArenaUnmark(poolp, mark);
if(eKey != NULL)
PK11_FreeSymKey(eKey);
if(slot != NULL)
PK11_FreeSlot(slot);
if(c_param.data != NULL)
SECITEM_ZfreeItem(&c_param, PR_FALSE);
return rv;
}
SECItem **
SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo)
{
switch(SEC_PKCS7ContentType(cinfo))
{
case SEC_OID_PKCS7_SIGNED_DATA:
return cinfo->content.signedData->rawCerts;
break;
default:
return NULL;
break;
}
}
int
SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo)
{
if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA)
return cinfo->content.envelopedData->encContentInfo.keysize;
else
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
/*
* 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.
*/
/*
* Support routines for PKCS7 implementation, none of which are exported.
* This file should only contain things that are needed by both the
* encoding/creation side *and* the decoding/decryption side. Anything
* else should just be static routines in the appropriate file.
*
* Do not export this file! If something in here is really needed outside
* of pkcs7 code, first try to add a PKCS7 interface which will do it for
* you. If that has a problem, then just move out what you need, changing
* its name as appropriate!
*
* $Id: p7local.h,v 1.1 2000/03/31 19:16:07 relyea%netscape.com Exp $
*/
#ifndef _P7LOCAL_H_
#define _P7LOCAL_H_
#include "secpkcs7.h"
#include "secasn1t.h"
extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[];
/* opaque objects */
typedef struct sec_pkcs7_cipher_object sec_PKCS7CipherObject;
/************************************************************************/
SEC_BEGIN_PROTOS
/*
* Look through a set of attributes and find one that matches the
* specified object ID. If "only" is true, then make sure that
* there is not more than one attribute of the same type. Otherwise,
* just return the first one found. (XXX Does anybody really want
* that first-found behavior? It was like that when I found it...)
*/
extern SEC_PKCS7Attribute *sec_PKCS7FindAttribute (SEC_PKCS7Attribute **attrs,
SECOidTag oidtag,
PRBool only);
/*
* Return the single attribute value, doing some sanity checking first:
* - Multiple values are *not* expected.
* - Empty values are *not* expected.
*/
extern SECItem *sec_PKCS7AttributeValue (SEC_PKCS7Attribute *attr);
/*
* Encode a set of attributes (found in "src").
*/
extern SECItem *sec_PKCS7EncodeAttributes (PRArenaPool *poolp,
SECItem *dest, void *src);
/*
* Make sure that the order of the attributes guarantees valid DER
* (which must be in lexigraphically ascending order for a SET OF);
* if reordering is necessary it will be done in place (in attrs).
*/
extern SECStatus sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs);
/*
* Create a context for decrypting, based on the given key and algorithm.
*/
extern sec_PKCS7CipherObject *
sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid);
/*
* Create a context for encrypting, based on the given key and algorithm,
* and fill in the algorithm id.
*/
extern sec_PKCS7CipherObject *
sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key,
SECOidTag algtag, SECAlgorithmID *algid);
/*
* Destroy the given decryption or encryption object.
*/
extern void sec_PKCS7DestroyDecryptObject (sec_PKCS7CipherObject *obj);
extern void sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj);
/*
* What will be the output length of the next call to encrypt/decrypt?
* Result can be used to perform memory allocations. Note that the amount
* is exactly accurate only when not doing a block cipher or when final
* is false, otherwise it is an upper bound on the amount because until
* we see the data we do not know how many padding bytes there are
* (always between 1 and the cipher block size).
*
* Note that this can return zero, which does not mean that the cipher
* operation can be skipped! (It simply means that there are not enough
* bytes to make up an entire block; the bytes will be reserved until
* there are enough to encrypt/decrypt at least one block.) However,
* if zero is returned it *does* mean that no output buffer need be
* passed in to the subsequent cipher operation, as no output bytes
* will be stored.
*/
extern unsigned int sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj,
unsigned int input_len,
PRBool final);
extern unsigned int sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj,
unsigned int input_len,
PRBool final);
/*
* Decrypt a given length of input buffer (starting at "input" and
* containing "input_len" bytes), placing the decrypted bytes in
* "output" and storing the output length in "*output_len_p".
* "obj" is the return value from sec_PKCS7CreateDecryptObject.
* When "final" is true, this is the last of the data to be decrypted.
*/
extern SECStatus sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj,
unsigned char *output,
unsigned int *output_len_p,
unsigned int max_output_len,
const unsigned char *input,
unsigned int input_len,
PRBool final);
/*
* Encrypt a given length of input buffer (starting at "input" and
* containing "input_len" bytes), placing the encrypted bytes in
* "output" and storing the output length in "*output_len_p".
* "obj" is the return value from sec_PKCS7CreateEncryptObject.
* When "final" is true, this is the last of the data to be encrypted.
*/
extern SECStatus sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj,
unsigned char *output,
unsigned int *output_len_p,
unsigned int max_output_len,
const unsigned char *input,
unsigned int input_len,
PRBool final);
/* return the correct kea template based on the template selector. skipjack
* does not have the extra IV.
*/
const SEC_ASN1Template *
sec_pkcs7_get_kea_template(SECKEATemplateSelector whichTemplate);
/************************************************************************/
SEC_END_PROTOS
#endif /* _P7LOCAL_H_ */

View File

@ -0,0 +1,292 @@
/*
* 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.
*/
/*
* Header for pkcs7 types.
*
* $Id: pkcs7t.h,v 1.1 2000/03/31 19:16:07 relyea%netscape.com Exp $
*/
#ifndef _PKCS7T_H_
#define _PKCS7T_H_
#include "plarena.h"
#include "seccomon.h"
#include "secoidt.h"
#include "certt.h"
#include "secmodt.h"
/* Opaque objects */
typedef struct SEC_PKCS7DecoderContextStr SEC_PKCS7DecoderContext;
typedef struct SEC_PKCS7EncoderContextStr SEC_PKCS7EncoderContext;
/* Non-opaque objects. NOTE, though: I want them to be treated as
* opaque as much as possible. If I could hide them completely,
* I would. (I tried, but ran into trouble that was taking me too
* much time to get out of.) I still intend to try to do so.
* In fact, the only type that "outsiders" should even *name* is
* SEC_PKCS7ContentInfo, and they should not reference its fields.
*/
/* rjr: PKCS #11 cert handling (pk11cert.c) does use SEC_PKCS7RecipientInfo's.
* This is because when we search the recipient list for the cert and key we
* want, we need to invert the order of the loops we used to have. The old
* loops were:
*
* For each recipient {
* find_cert = PK11_Find_AllCert(recipient->issuerSN);
* [which unrolls to... ]
* For each slot {
* Log into slot;
* search slot for cert;
* }
* }
*
* the new loop searchs all the recipients at once on a slot. this allows
* PKCS #11 to order slots in such a way that logout slots don't get checked
* if we can find the cert on a logged in slot. This eliminates lots of
* spurious password prompts when smart cards are installed... so why this
* comment? If you make SEC_PKCS7RecipientInfo completely opaque, you need
* to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs
* and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11
* function.
*/
typedef struct SEC_PKCS7ContentInfoStr SEC_PKCS7ContentInfo;
typedef struct SEC_PKCS7SignedDataStr SEC_PKCS7SignedData;
typedef struct SEC_PKCS7EncryptedContentInfoStr SEC_PKCS7EncryptedContentInfo;
typedef struct SEC_PKCS7EnvelopedDataStr SEC_PKCS7EnvelopedData;
typedef struct SEC_PKCS7SignedAndEnvelopedDataStr
SEC_PKCS7SignedAndEnvelopedData;
typedef struct SEC_PKCS7SignerInfoStr SEC_PKCS7SignerInfo;
typedef struct SEC_PKCS7RecipientInfoStr SEC_PKCS7RecipientInfo;
typedef struct SEC_PKCS7DigestedDataStr SEC_PKCS7DigestedData;
typedef struct SEC_PKCS7EncryptedDataStr SEC_PKCS7EncryptedData;
typedef struct SEC_PKCS7SMIMEKEAParametersStr SEC_PKCS7SMIMEKEAParameters;
/*
* The following is not actually a PKCS7 type, but for now it is only
* used by PKCS7, so we have adopted it. If someone else *ever* needs
* it, its name should be changed and it should be moved out of here.
* Do not dare to use it without doing so!
*/
typedef struct SEC_PKCS7AttributeStr SEC_PKCS7Attribute;
struct SEC_PKCS7ContentInfoStr {
PRArenaPool *poolp; /* local; not part of encoding */
PRBool created; /* local; not part of encoding */
int refCount; /* local; not part of encoding */
SECOidData *contentTypeTag; /* local; not part of encoding */
SECKEYGetPasswordKey pwfn; /* local; not part of encoding */
void *pwfn_arg; /* local; not part of encoding */
SECItem contentType;
union {
SECItem *data;
SEC_PKCS7DigestedData *digestedData;
SEC_PKCS7EncryptedData *encryptedData;
SEC_PKCS7EnvelopedData *envelopedData;
SEC_PKCS7SignedData *signedData;
SEC_PKCS7SignedAndEnvelopedData *signedAndEnvelopedData;
} content;
};
struct SEC_PKCS7SignedDataStr {
SECItem version;
SECAlgorithmID **digestAlgorithms;
SEC_PKCS7ContentInfo contentInfo;
SECItem **rawCerts;
CERTSignedCrl **crls;
SEC_PKCS7SignerInfo **signerInfos;
SECItem **digests; /* local; not part of encoding */
CERTCertificate **certs; /* local; not part of encoding */
CERTCertificateList **certLists; /* local; not part of encoding */
};
#define SEC_PKCS7_SIGNED_DATA_VERSION 1 /* what we *create* */
struct SEC_PKCS7EncryptedContentInfoStr {
SECOidData *contentTypeTag; /* local; not part of encoding */
SECItem contentType;
SECAlgorithmID contentEncAlg;
SECItem encContent;
SECItem plainContent; /* local; not part of encoding */
/* bytes not encrypted, but encoded */
int keysize; /* local; not part of encoding */
/* size of bulk encryption key
* (only used by creation code) */
SECOidTag encalg; /* local; not part of encoding */
/* oid tag of encryption algorithm
* (only used by creation code) */
};
struct SEC_PKCS7EnvelopedDataStr {
SECItem version;
SEC_PKCS7RecipientInfo **recipientInfos;
SEC_PKCS7EncryptedContentInfo encContentInfo;
};
#define SEC_PKCS7_ENVELOPED_DATA_VERSION 0 /* what we *create* */
struct SEC_PKCS7SignedAndEnvelopedDataStr {
SECItem version;
SEC_PKCS7RecipientInfo **recipientInfos;
SECAlgorithmID **digestAlgorithms;
SEC_PKCS7EncryptedContentInfo encContentInfo;
SECItem **rawCerts;
CERTSignedCrl **crls;
SEC_PKCS7SignerInfo **signerInfos;
SECItem **digests; /* local; not part of encoding */
CERTCertificate **certs; /* local; not part of encoding */
CERTCertificateList **certLists; /* local; not part of encoding */
PK11SymKey *sigKey; /* local; not part of encoding */
};
#define SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION 1 /* what we *create* */
struct SEC_PKCS7SignerInfoStr {
SECItem version;
CERTIssuerAndSN *issuerAndSN;
SECAlgorithmID digestAlg;
SEC_PKCS7Attribute **authAttr;
SECAlgorithmID digestEncAlg;
SECItem encDigest;
SEC_PKCS7Attribute **unAuthAttr;
CERTCertificate *cert; /* local; not part of encoding */
CERTCertificateList *certList; /* local; not part of encoding */
};
#define SEC_PKCS7_SIGNER_INFO_VERSION 1 /* what we *create* */
struct SEC_PKCS7RecipientInfoStr {
SECItem version;
CERTIssuerAndSN *issuerAndSN;
SECAlgorithmID keyEncAlg;
SECItem encKey;
CERTCertificate *cert; /* local; not part of encoding */
};
#define SEC_PKCS7_RECIPIENT_INFO_VERSION 0 /* what we *create* */
struct SEC_PKCS7DigestedDataStr {
SECItem version;
SECAlgorithmID digestAlg;
SEC_PKCS7ContentInfo contentInfo;
SECItem digest;
};
#define SEC_PKCS7_DIGESTED_DATA_VERSION 0 /* what we *create* */
struct SEC_PKCS7EncryptedDataStr {
SECItem version;
SEC_PKCS7EncryptedContentInfo encContentInfo;
};
#define SEC_PKCS7_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
/*
* See comment above about this type not really belonging to PKCS7.
*/
struct SEC_PKCS7AttributeStr {
/* The following fields make up an encoded Attribute: */
SECItem type;
SECItem **values; /* data may or may not be encoded */
/* The following fields are not part of an encoded Attribute: */
SECOidData *typeTag;
PRBool encoded; /* when true, values are encoded */
};
/* An enumerated type used to select templates based on the encryption
scenario and data specifics. */
typedef enum
{
SECKEAUsesSkipjack,
SECKEAUsesNonSkipjack,
SECKEAUsesNonSkipjackWithPaddedEncKey
} SECKEATemplateSelector;
/* ### mwelch - S/MIME KEA parameters. These don't really fit here,
but I cannot think of a more appropriate place at this time. */
struct SEC_PKCS7SMIMEKEAParametersStr {
SECItem originatorKEAKey; /* sender KEA key (encrypted?) */
SECItem originatorRA; /* random number generated by sender */
SECItem nonSkipjackIV; /* init'n vector for SkipjackCBC64
decryption of KEA key if Skipjack
is not the bulk algorithm used on
the message */
SECItem bulkKeySize; /* if Skipjack is not the bulk
algorithm used on the message,
and the size of the bulk encryption
key is not the same as that of
originatorKEAKey (due to padding
perhaps), this field will contain
the real size of the bulk encryption
key. */
};
/*
* Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart.
* If specified, this is where the content bytes (only) will be "sent"
* as they are recovered during the decoding.
*
* XXX Should just combine this with SEC_PKCS7EncoderContentCallback type
* and use a simpler, common name.
*/
typedef void (* SEC_PKCS7DecoderContentCallback)(void *arg,
const char *buf,
unsigned long len);
/*
* Type of function passed to SEC_PKCS7Encode or SEC_PKCS7EncoderStart.
* This is where the encoded bytes will be "sent".
*
* XXX Should just combine this with SEC_PKCS7DecoderContentCallback type
* and use a simpler, common name.
*/
typedef void (* SEC_PKCS7EncoderOutputCallback)(void *arg,
const char *buf,
unsigned long len);
/*
* Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart
* to retrieve the decryption key. This function is inteded to be
* used for EncryptedData content info's which do not have a key available
* in a certificate, etc.
*/
typedef PK11SymKey * (* SEC_PKCS7GetDecryptKeyCallback)(void *arg,
SECAlgorithmID *algid);
/*
* Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart.
* This function in intended to be used to verify that decrypting a
* particular crypto algorithm is allowed. Content types which do not
* require decryption will not need the callback. If the callback
* is not specified for content types which require decryption, the
* decryption will be disallowed.
*/
typedef PRBool (* SEC_PKCS7DecryptionAllowedCallback)(SECAlgorithmID *algid,
PK11SymKey *bulkkey);
#endif /* _PKCS7T_H_ */

View File

@ -0,0 +1,901 @@
/*
* 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.
*/
/*
* Stuff specific to S/MIME policy and interoperability.
* Depends on PKCS7, but there should be no dependency the other way around.
*
* $Id: secmime.c,v 1.1 2000/03/31 19:16:08 relyea%netscape.com Exp $
*/
#include "secmime.h"
#include "secoid.h"
#include "pk11func.h"
#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
#include "secasn1.h"
#include "secitem.h"
#include "cert.h"
#include "key.h"
#include "secerr.h"
typedef struct smime_cipher_map_struct {
unsigned long cipher;
SECOidTag algtag;
SECItem *parms;
} smime_cipher_map;
/*
* These are macros because I think some subsequent parameters,
* like those for RC5, will want to use them, too, separately.
*/
#define SMIME_DER_INTVAL_16 SEC_ASN1_INTEGER, 0x01, 0x10
#define SMIME_DER_INTVAL_40 SEC_ASN1_INTEGER, 0x01, 0x28
#define SMIME_DER_INTVAL_64 SEC_ASN1_INTEGER, 0x01, 0x40
#define SMIME_DER_INTVAL_128 SEC_ASN1_INTEGER, 0x02, 0x00, 0x80
#ifdef SMIME_DOES_RC5 /* will be needed; quiet unused warning for now */
static unsigned char smime_int16[] = { SMIME_DER_INTVAL_16 };
#endif
static unsigned char smime_int40[] = { SMIME_DER_INTVAL_40 };
static unsigned char smime_int64[] = { SMIME_DER_INTVAL_64 };
static unsigned char smime_int128[] = { SMIME_DER_INTVAL_128 };
static SECItem smime_rc2p40 = { siBuffer, smime_int40, sizeof(smime_int40) };
static SECItem smime_rc2p64 = { siBuffer, smime_int64, sizeof(smime_int64) };
static SECItem smime_rc2p128 = { siBuffer, smime_int128, sizeof(smime_int128) };
static smime_cipher_map smime_cipher_maps[] = {
{ SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, &smime_rc2p40 },
{ SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &smime_rc2p64 },
{ SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &smime_rc2p128 },
#ifdef SMIME_DOES_RC5
{ SMIME_RC5PAD_64_16_40, SEC_OID_RC5_CBC_PAD, &smime_rc5p40 },
{ SMIME_RC5PAD_64_16_64, SEC_OID_RC5_CBC_PAD, &smime_rc5p64 },
{ SMIME_RC5PAD_64_16_128, SEC_OID_RC5_CBC_PAD, &smime_rc5p128 },
#endif
{ SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL },
{ SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL },
{ SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL}
};
/*
* Note, the following value really just needs to be an upper bound
* on the ciphers.
*/
static const int smime_symmetric_count = sizeof(smime_cipher_maps)
/ sizeof(smime_cipher_map);
static unsigned long *smime_prefs, *smime_newprefs;
static int smime_current_pref_index = 0;
static PRBool smime_prefs_complete = PR_FALSE;
static PRBool smime_prefs_changed = PR_TRUE;
static unsigned long smime_policy_bits = 0;
static int
smime_mapi_by_cipher (unsigned long cipher)
{
int i;
for (i = 0; i < smime_symmetric_count; i++) {
if (smime_cipher_maps[i].cipher == cipher)
break;
}
if (i == smime_symmetric_count)
return -1;
return i;
}
/*
* this function locally records the user's preference
*/
SECStatus
SECMIME_EnableCipher(long which, int on)
{
unsigned long mask;
if (smime_newprefs == NULL || smime_prefs_complete) {
/*
* This is either the very first time, or we are starting over.
*/
smime_newprefs = (unsigned long*)PORT_ZAlloc (smime_symmetric_count
* sizeof(*smime_newprefs));
if (smime_newprefs == NULL)
return SECFailure;
smime_current_pref_index = 0;
smime_prefs_complete = PR_FALSE;
}
mask = which & CIPHER_FAMILYID_MASK;
if (mask == CIPHER_FAMILYID_MASK) {
/*
* This call signifies that all preferences have been set.
* Move "newprefs" over, after checking first whether or
* not the new ones are different from the old ones.
*/
if (smime_prefs != NULL) {
if (PORT_Memcmp (smime_prefs, smime_newprefs,
smime_symmetric_count * sizeof(*smime_prefs)) == 0)
smime_prefs_changed = PR_FALSE;
else
smime_prefs_changed = PR_TRUE;
PORT_Free (smime_prefs);
}
smime_prefs = smime_newprefs;
smime_prefs_complete = PR_TRUE;
return SECSuccess;
}
PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
if (mask != CIPHER_FAMILYID_SMIME) {
/* XXX set an error! */
return SECFailure;
}
if (on) {
PORT_Assert (smime_current_pref_index < smime_symmetric_count);
if (smime_current_pref_index >= smime_symmetric_count) {
/* XXX set an error! */
return SECFailure;
}
smime_newprefs[smime_current_pref_index++] = which;
}
return SECSuccess;
}
/*
* this function locally records the export policy
*/
SECStatus
SECMIME_SetPolicy(long which, int on)
{
unsigned long mask;
PORT_Assert ((which & CIPHER_FAMILYID_MASK) == CIPHER_FAMILYID_SMIME);
if ((which & CIPHER_FAMILYID_MASK) != CIPHER_FAMILYID_SMIME) {
/* XXX set an error! */
return SECFailure;
}
which &= ~CIPHER_FAMILYID_MASK;
PORT_Assert (which < 32); /* bits in the long */
if (which >= 32) {
/* XXX set an error! */
return SECFailure;
}
mask = 1UL << which;
if (on) {
smime_policy_bits |= mask;
} else {
smime_policy_bits &= ~mask;
}
return SECSuccess;
}
/*
* Based on the given algorithm (including its parameters, in some cases!)
* and the given key (may or may not be inspected, depending on the
* algorithm), find the appropriate policy algorithm specification
* and return it. If no match can be made, -1 is returned.
*/
static long
smime_policy_algorithm (SECAlgorithmID *algid, PK11SymKey *key)
{
SECOidTag algtag;
algtag = SECOID_GetAlgorithmTag (algid);
switch (algtag) {
case SEC_OID_RC2_CBC:
{
unsigned int keylen_bits;
keylen_bits = PK11_GetKeyStrength (key, algid);
switch (keylen_bits) {
case 40:
return SMIME_RC2_CBC_40;
case 64:
return SMIME_RC2_CBC_64;
case 128:
return SMIME_RC2_CBC_128;
default:
break;
}
}
break;
case SEC_OID_DES_CBC:
return SMIME_DES_CBC_56;
case SEC_OID_DES_EDE3_CBC:
return SMIME_DES_EDE3_168;
case SEC_OID_FORTEZZA_SKIPJACK:
return SMIME_FORTEZZA;
#ifdef SMIME_DOES_RC5
case SEC_OID_RC5_CBC_PAD:
PORT_Assert (0); /* XXX need to pull out parameters and match */
break;
#endif
default:
break;
}
return -1;
}
static PRBool
smime_cipher_allowed (unsigned long which)
{
unsigned long mask;
which &= ~CIPHER_FAMILYID_MASK;
PORT_Assert (which < 32); /* bits per long (min) */
if (which >= 32)
return PR_FALSE;
mask = 1UL << which;
if ((mask & smime_policy_bits) == 0)
return PR_FALSE;
return PR_TRUE;
}
PRBool
SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
{
long which;
which = smime_policy_algorithm (algid, key);
if (which < 0)
return PR_FALSE;
return smime_cipher_allowed ((unsigned long)which);
}
/*
* Does the current policy allow *any* S/MIME encryption (or decryption)?
*
* This tells whether or not *any* S/MIME encryption can be done,
* according to policy. Callers may use this to do nicer user interface
* (say, greying out a checkbox so a user does not even try to encrypt
* a message when they are not allowed to) or for any reason they want
* to check whether S/MIME encryption (or decryption, for that matter)
* may be done.
*
* It takes no arguments. The return value is a simple boolean:
* PR_TRUE means encryption (or decryption) is *possible*
* (but may still fail due to other reasons, like because we cannot
* find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
* PR_FALSE means encryption (or decryption) is not permitted
*
* There are no errors from this routine.
*/
PRBool
SECMIME_EncryptionPossible (void)
{
if (smime_policy_bits != 0)
return PR_TRUE;
return PR_FALSE;
}
/*
* XXX Would like the "parameters" field to be a SECItem *, but the
* encoder is having trouble with optional pointers to an ANY. Maybe
* once that is fixed, can change this back...
*/
typedef struct smime_capability_struct {
unsigned long cipher; /* local; not part of encoding */
SECOidTag capIDTag; /* local; not part of encoding */
SECItem capabilityID;
SECItem parameters;
} smime_capability;
static const SEC_ASN1Template smime_capability_template[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(smime_capability) },
{ SEC_ASN1_OBJECT_ID,
offsetof(smime_capability,capabilityID), },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
offsetof(smime_capability,parameters), },
{ 0, }
};
static const SEC_ASN1Template smime_capabilities_template[] = {
{ SEC_ASN1_SEQUENCE_OF, 0, smime_capability_template }
};
static void
smime_fill_capability (smime_capability *cap)
{
unsigned long cipher;
SECOidTag algtag;
int i;
algtag = SECOID_FindOIDTag (&(cap->capabilityID));
for (i = 0; i < smime_symmetric_count; i++) {
if (smime_cipher_maps[i].algtag != algtag)
continue;
/*
* XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing
* 2 NULLs as equal and NULL and non-NULL as not equal), we could
* use that here instead of all of the following comparison code.
*/
if (cap->parameters.data != NULL) {
if (smime_cipher_maps[i].parms == NULL)
continue;
if (cap->parameters.len != smime_cipher_maps[i].parms->len)
continue;
if (PORT_Memcmp (cap->parameters.data,
smime_cipher_maps[i].parms->data,
cap->parameters.len) == 0)
break;
} else if (smime_cipher_maps[i].parms == NULL) {
break;
}
}
if (i == smime_symmetric_count)
cipher = 0;
else
cipher = smime_cipher_maps[i].cipher;
cap->cipher = cipher;
cap->capIDTag = algtag;
}
static long
smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
{
PRArenaPool *poolp;
long chosen_cipher;
int *cipher_abilities;
int *cipher_votes;
int strong_mapi;
int rcount, mapi, max, i;
PRBool isFortezza = PK11_FortezzaHasKEA(scert);
if (smime_policy_bits == 0) {
PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM);
return -1;
}
chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
poolp = PORT_NewArena (1024); /* XXX what is right value? */
if (poolp == NULL)
goto done;
cipher_abilities = (int*)PORT_ArenaZAlloc (poolp,
smime_symmetric_count * sizeof(int));
if (cipher_abilities == NULL)
goto done;
cipher_votes = (int*)PORT_ArenaZAlloc (poolp,
smime_symmetric_count * sizeof(int));
if (cipher_votes == NULL)
goto done;
/*
* XXX Should have a #define somewhere which specifies default
* strong cipher. (Or better, a way to configure, which would
* take Fortezza into account as well.)
*/
/* If the user has the Fortezza preference turned on, make
* that the strong cipher. Otherwise, use triple-DES. */
strong_mapi = -1;
if (isFortezza) {
for(i=0;i < smime_current_pref_index && strong_mapi < 0;i++)
{
if (smime_prefs[i] == SMIME_FORTEZZA)
strong_mapi = smime_mapi_by_cipher(SMIME_FORTEZZA);
}
}
if (strong_mapi == -1)
strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
PORT_Assert (strong_mapi >= 0);
for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
SECItem *profile;
smime_capability **caps;
int capi, pref;
SECStatus dstat;
pref = smime_symmetric_count;
profile = CERT_FindSMimeProfile (rcerts[rcount]);
if (profile != NULL && profile->data != NULL && profile->len > 0) {
caps = NULL;
dstat = SEC_ASN1DecodeItem (poolp, &caps,
smime_capabilities_template,
profile);
if (dstat == SECSuccess && caps != NULL) {
for (capi = 0; caps[capi] != NULL; capi++) {
smime_fill_capability (caps[capi]);
mapi = smime_mapi_by_cipher (caps[capi]->cipher);
if (mapi >= 0) {
cipher_abilities[mapi]++;
cipher_votes[mapi] += pref;
--pref;
}
}
}
} else {
SECKEYPublicKey *key;
unsigned int pklen_bits;
/*
* XXX This is probably only good for RSA keys. What I would
* really like is a function to just say; Is the public key in
* this cert an export-length key? Then I would not have to
* know things like the value 512, or the kind of key, or what
* a subjectPublicKeyInfo is, etc.
*/
key = CERT_ExtractPublicKey (rcerts[rcount]);
if (key != NULL) {
pklen_bits = SECKEY_PublicKeyStrength (key) * 8;
SECKEY_DestroyPublicKey (key);
if (pklen_bits > 512) {
cipher_abilities[strong_mapi]++;
cipher_votes[strong_mapi] += pref;
}
}
}
if (profile != NULL)
SECITEM_FreeItem (profile, PR_TRUE);
}
max = 0;
for (mapi = 0; mapi < smime_symmetric_count; mapi++) {
if (cipher_abilities[mapi] != rcount)
continue;
if (! smime_cipher_allowed (smime_cipher_maps[mapi].cipher))
continue;
if (!isFortezza && (smime_cipher_maps[mapi].cipher == SMIME_FORTEZZA))
continue;
if (cipher_votes[mapi] > max) {
chosen_cipher = smime_cipher_maps[mapi].cipher;
max = cipher_votes[mapi];
} /* XXX else if a tie, let scert break it? */
}
done:
if (poolp != NULL)
PORT_FreeArena (poolp, PR_FALSE);
return chosen_cipher;
}
/*
* XXX This is a hack for now to satisfy our current interface.
* Eventually, with more parameters needing to be specified, just
* looking up the keysize is not going to be sufficient.
*/
static int
smime_keysize_by_cipher (unsigned long which)
{
int keysize;
switch (which) {
case SMIME_RC2_CBC_40:
keysize = 40;
break;
case SMIME_RC2_CBC_64:
keysize = 64;
break;
case SMIME_RC2_CBC_128:
keysize = 128;
break;
#ifdef SMIME_DOES_RC5
case SMIME_RC5PAD_64_16_40:
case SMIME_RC5PAD_64_16_64:
case SMIME_RC5PAD_64_16_128:
/* XXX See comment above; keysize is not enough... */
PORT_Assert (0);
PORT_SetError (SEC_ERROR_INVALID_ALGORITHM);
keysize = -1;
break;
#endif
case SMIME_DES_CBC_56:
case SMIME_DES_EDE3_168:
case SMIME_FORTEZZA:
/*
* These are special; since the key size is fixed, we actually
* want to *avoid* specifying a key size.
*/
keysize = 0;
break;
default:
keysize = -1;
break;
}
return keysize;
}
/*
* Start an S/MIME encrypting context.
*
* "scert" is the cert for the sender. It will be checked for validity.
* "rcerts" are the certs for the recipients. They will also be checked.
*
* "certdb" is the cert database to use for verifying the certs.
* It can be NULL if a default database is available (like in the client).
*
* This function already does all of the stuff specific to S/MIME protocol
* and local policy; the return value just needs to be passed to
* SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
* and finally to SEC_PKCS7DestroyContentInfo().
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
SEC_PKCS7ContentInfo *
SECMIME_CreateEncrypted(CERTCertificate *scert,
CERTCertificate **rcerts,
CERTCertDBHandle *certdb,
SECKEYGetPasswordKey pwfn,
void *pwfn_arg)
{
SEC_PKCS7ContentInfo *cinfo;
long cipher;
SECOidTag encalg;
int keysize;
int mapi, rci;
cipher = smime_choose_cipher (scert, rcerts);
if (cipher < 0)
return NULL;
mapi = smime_mapi_by_cipher (cipher);
if (mapi < 0)
return NULL;
/*
* XXX This is stretching it -- CreateEnvelopedData should probably
* take a cipher itself of some sort, because we cannot know what the
* future will bring in terms of parameters for each type of algorithm.
* For example, just an algorithm and keysize is *not* sufficient to
* fully specify the usage of RC5 (which also needs to know rounds and
* block size). Work this out into a better API!
*/
encalg = smime_cipher_maps[mapi].algtag;
keysize = smime_keysize_by_cipher (cipher);
if (keysize < 0)
return NULL;
cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient,
certdb, encalg, keysize,
pwfn, pwfn_arg);
if (cinfo == NULL)
return NULL;
for (rci = 0; rcerts[rci] != NULL; rci++) {
if (rcerts[rci] == scert)
continue;
if (SEC_PKCS7AddRecipient (cinfo, rcerts[rci], certUsageEmailRecipient,
NULL) != SECSuccess) {
SEC_PKCS7DestroyContentInfo (cinfo);
return NULL;
}
}
return cinfo;
}
static smime_capability **smime_capabilities;
static SECItem *smime_encoded_caps;
static PRBool lastUsedFortezza;
static SECStatus
smime_init_caps (PRBool isFortezza)
{
smime_capability *cap;
smime_cipher_map *map;
SECOidData *oiddata;
SECStatus rv;
int i, capIndex;
if (smime_encoded_caps != NULL
&& (! smime_prefs_changed)
&& lastUsedFortezza == isFortezza)
return SECSuccess;
if (smime_encoded_caps != NULL) {
SECITEM_FreeItem (smime_encoded_caps, PR_TRUE);
smime_encoded_caps = NULL;
}
if (smime_capabilities == NULL) {
smime_capabilities = (smime_capability**)PORT_ZAlloc (
(smime_symmetric_count + 1)
* sizeof(smime_capability *));
if (smime_capabilities == NULL)
return SECFailure;
}
rv = SECFailure;
/*
The process of creating the encoded PKCS7 cipher capability list
involves two basic steps:
(a) Convert our internal representation of cipher preferences
(smime_prefs) into an array containing cipher OIDs and
parameter data (smime_capabilities). This step is
performed here.
(b) Encode, using ASN.1, the cipher information in
smime_capabilities, leaving the encoded result in
smime_encoded_caps.
(In the process of performing (a), Lisa put in some optimizations
which allow us to avoid needlessly re-populating elements in
smime_capabilities as we walk through smime_prefs.)
We want to use separate loop variables for smime_prefs and
smime_capabilities because in the case where the Skipjack cipher
is turned on in the prefs, but where we don't want to include
Skipjack in the encoded capabilities (presumably due to using a
non-fortezza cert when sending a message), we want to avoid creating
an empty element in smime_capabilities. This would otherwise cause
the encoding step to produce an empty set, since Skipjack happens
to be the first cipher in smime_prefs, if it is turned on.
*/
for (i = 0, capIndex = 0; i < smime_current_pref_index; i++, capIndex++) {
int mapi;
/* Get the next cipher preference in smime_prefs. */
mapi = smime_mapi_by_cipher (smime_prefs[i]);
if (mapi < 0)
break;
/* Find the corresponding entry in the cipher map. */
PORT_Assert (mapi < smime_symmetric_count);
map = &(smime_cipher_maps[mapi]);
/* If we're using a non-Fortezza cert, only advertise non-Fortezza
capabilities. (We advertise all capabilities if we have a
Fortezza cert.) */
if ((!isFortezza) && (map->cipher == SMIME_FORTEZZA))
{
capIndex--; /* we want to visit the same caps index entry next time */
continue;
}
/*
* Convert the next preference found in smime_prefs into an
* smime_capability.
*/
cap = smime_capabilities[capIndex];
if (cap == NULL) {
cap = (smime_capability*)PORT_ZAlloc (sizeof(smime_capability));
if (cap == NULL)
break;
smime_capabilities[capIndex] = cap;
} else if (cap->cipher == smime_prefs[i]) {
continue; /* no change to this one */
}
cap->capIDTag = map->algtag;
oiddata = SECOID_FindOIDByTag (map->algtag);
if (oiddata == NULL)
break;
if (cap->capabilityID.data != NULL) {
SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE);
cap->capabilityID.data = NULL;
cap->capabilityID.len = 0;
}
rv = SECITEM_CopyItem (NULL, &(cap->capabilityID), &(oiddata->oid));
if (rv != SECSuccess)
break;
if (map->parms == NULL) {
cap->parameters.data = NULL;
cap->parameters.len = 0;
} else {
cap->parameters.data = map->parms->data;
cap->parameters.len = map->parms->len;
}
cap->cipher = smime_prefs[i];
}
if (i != smime_current_pref_index)
return rv;
while (capIndex < smime_symmetric_count) {
cap = smime_capabilities[capIndex];
if (cap != NULL) {
SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE);
PORT_Free (cap);
}
smime_capabilities[capIndex] = NULL;
capIndex++;
}
smime_capabilities[capIndex] = NULL;
smime_encoded_caps = SEC_ASN1EncodeItem (NULL, NULL, &smime_capabilities,
smime_capabilities_template);
if (smime_encoded_caps == NULL)
return SECFailure;
lastUsedFortezza = isFortezza;
return SECSuccess;
}
static SECStatus
smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
{
PRBool isFortezza = PR_FALSE;
PORT_Assert (smime_prefs_complete);
if (! smime_prefs_complete)
return SECFailure;
/* See if the sender's cert specifies Fortezza key exchange. */
if (cert != NULL)
isFortezza = PK11_FortezzaHasKEA(cert);
/* For that matter, if capabilities haven't been initialized yet,
do so now. */
if (isFortezza != lastUsedFortezza || smime_encoded_caps == NULL || smime_prefs_changed) {
SECStatus rv;
rv = smime_init_caps(isFortezza);
if (rv != SECSuccess)
return rv;
PORT_Assert (smime_encoded_caps != NULL);
}
return SEC_PKCS7AddSignedAttribute (cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES,
smime_encoded_caps);
}
/*
* Start an S/MIME signing context.
*
* "scert" is the cert that will be used to sign the data. It will be
* checked for validity.
*
* "ecert" is the signer's encryption cert. If it is different from
* scert, then it will be included in the signed message so that the
* recipient can save it for future encryptions.
*
* "certdb" is the cert database to use for verifying the cert.
* It can be NULL if a default database is available (like in the client).
*
* "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
* XXX There should be SECMIME functions for hashing, or the hashing should
* be built into this interface, which we would like because we would
* support more smartcards that way, and then this argument should go away.)
*
* "digest" is the actual digest of the data. It must be provided in
* the case of detached data or NULL if the content will be included.
*
* This function already does all of the stuff specific to S/MIME protocol
* and local policy; the return value just needs to be passed to
* SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
* and finally to SEC_PKCS7DestroyContentInfo().
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
SEC_PKCS7ContentInfo *
SECMIME_CreateSigned (CERTCertificate *scert,
CERTCertificate *ecert,
CERTCertDBHandle *certdb,
SECOidTag digestalg,
SECItem *digest,
SECKEYGetPasswordKey pwfn,
void *pwfn_arg)
{
SEC_PKCS7ContentInfo *cinfo;
SECStatus rv;
/* See note in header comment above about digestalg. */
PORT_Assert (digestalg == SEC_OID_SHA1);
cinfo = SEC_PKCS7CreateSignedData (scert, certUsageEmailSigner,
certdb, digestalg, digest,
pwfn, pwfn_arg);
if (cinfo == NULL)
return NULL;
if (SEC_PKCS7IncludeCertChain (cinfo, NULL) != SECSuccess) {
SEC_PKCS7DestroyContentInfo (cinfo);
return NULL;
}
/* if the encryption cert and the signing cert differ, then include
* the encryption cert too.
*/
/* it is ok to compare the pointers since we ref count, and the same
* cert will always have the same pointer
*/
if ( ( ecert != NULL ) && ( ecert != scert ) ) {
rv = SEC_PKCS7AddCertificate(cinfo, ecert);
if ( rv != SECSuccess ) {
SEC_PKCS7DestroyContentInfo (cinfo);
return NULL;
}
}
/*
* Add the signing time. But if it fails for some reason,
* may as well not give up altogether -- just assert.
*/
rv = SEC_PKCS7AddSigningTime (cinfo);
PORT_Assert (rv == SECSuccess);
/*
* Add the email profile. Again, if it fails for some reason,
* may as well not give up altogether -- just assert.
*/
rv = smime_add_profile (ecert, cinfo);
PORT_Assert (rv == SECSuccess);
return cinfo;
}

View File

@ -0,0 +1,192 @@
/*
* 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.
*/
/*
* Header file for routines specific to S/MIME. Keep things that are pure
* pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc.
*
* $Id: secmime.h,v 1.1 2000/03/31 19:16:08 relyea%netscape.com Exp $
*/
#ifndef _SECMIME_H_
#define _SECMIME_H_ 1
#include "secpkcs7.h"
/************************************************************************/
SEC_BEGIN_PROTOS
/*
* Initialize the local recording of the user S/MIME cipher preferences.
* This function is called once for each cipher, the order being
* important (first call records greatest preference, and so on).
* When finished, it is called with a "which" of CIPHER_FAMILID_MASK.
* If the function is called again after that, it is assumed that
* the preferences are being reset, and the old preferences are
* discarded.
*
* XXX This is for a particular user, and right now the storage is
* XXX local, static. The preference should be stored elsewhere to allow
* XXX for multiple uses of one library? How does SSL handle this;
* XXX it has something similar?
*
* - The "which" values are defined in ciferfam.h (the SMIME_* values,
* for example SMIME_DES_CBC_56).
* - If "on" is non-zero then the named cipher is enabled, otherwise
* it is disabled. (It is not necessary to call the function for
* ciphers that are disabled, however, as that is the default.)
*
* If the cipher preference is successfully recorded, SECSuccess
* is returned. Otherwise SECFailure is returned. The only errors
* are due to failure allocating memory or bad parameters/calls:
* SEC_ERROR_XXX ("which" is not in the S/MIME cipher family)
* SEC_ERROR_XXX (function is being called more times than there
* are known/expected ciphers)
*/
extern SECStatus SECMIME_EnableCipher(long which, int on);
/*
* Initialize the local recording of the S/MIME policy.
* This function is called to enable/disable a particular cipher.
* (S/MIME encryption or decryption using a particular cipher is only
* allowed if that cipher is currently enabled.) At startup, all S/MIME
* ciphers are disabled. From that point, this function can be called
* to enable a cipher -- it is not necessary to call this to disable
* a cipher unless that cipher was previously, explicitly enabled via
* this function.
*
* XXX This is for a the current module, I think, so local, static storage
* XXX is okay. Is that correct, or could multiple uses of the same
* XXX library expect to operate under different policies?
*
* - The "which" values are defined in ciferfam.h (the SMIME_* values,
* for example SMIME_DES_CBC_56).
* - If "on" is non-zero then the named cipher is enabled, otherwise
* it is disabled.
*
* If the cipher is successfully enabled/disabled, SECSuccess is
* returned. Otherwise SECFailure is returned. The only errors
* are due to bad parameters:
* SEC_ERROR_XXX ("which" is not in the S/MIME cipher family)
* SEC_ERROR_XXX ("which" exceeds expected maximum cipher; this is
* really an internal error)
*/
extern SECStatus SECMIME_SetPolicy(long which, int on);
/*
* Does the current policy allow S/MIME decryption of this particular
* algorithm and keysize?
*/
extern PRBool SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key);
/*
* Does the current policy allow *any* S/MIME encryption (or decryption)?
*
* This tells whether or not *any* S/MIME encryption can be done,
* according to policy. Callers may use this to do nicer user interface
* (say, greying out a checkbox so a user does not even try to encrypt
* a message when they are not allowed to) or for any reason they want
* to check whether S/MIME encryption (or decryption, for that matter)
* may be done.
*
* It takes no arguments. The return value is a simple boolean:
* PR_TRUE means encryption (or decryption) is *possible*
* (but may still fail due to other reasons, like because we cannot
* find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
* PR_FALSE means encryption (or decryption) is not permitted
*
* There are no errors from this routine.
*/
extern PRBool SECMIME_EncryptionPossible(void);
/*
* Start an S/MIME encrypting context.
*
* "scert" is the cert for the sender. It will be checked for validity.
* "rcerts" are the certs for the recipients. They will also be checked.
*
* "certdb" is the cert database to use for verifying the certs.
* It can be NULL if a default database is available (like in the client).
*
* This function already does all of the stuff specific to S/MIME protocol
* and local policy; the return value just needs to be passed to
* SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
* and finally to SEC_PKCS7DestroyContentInfo().
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert,
CERTCertificate **rcerts,
CERTCertDBHandle *certdb,
SECKEYGetPasswordKey pwfn,
void *pwfn_arg);
/*
* Start an S/MIME signing context.
*
* "scert" is the cert that will be used to sign the data. It will be
* checked for validity.
*
* "certdb" is the cert database to use for verifying the cert.
* It can be NULL if a default database is available (like in the client).
*
* "digestalg" names the digest algorithm. (It should be SEC_OID_SHA1;
* XXX There should be SECMIME functions for hashing, or the hashing should
* be built into this interface, which we would like because we would
* support more smartcards that way, and then this argument should go away.)
*
* "digest" is the actual digest of the data. It must be provided in
* the case of detached data or NULL if the content will be included.
*
* This function already does all of the stuff specific to S/MIME protocol
* and local policy; the return value just needs to be passed to
* SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
* and finally to SEC_PKCS7DestroyContentInfo().
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *SECMIME_CreateSigned(CERTCertificate *scert,
CERTCertificate *ecert,
CERTCertDBHandle *certdb,
SECOidTag digestalg,
SECItem *digest,
SECKEYGetPasswordKey pwfn,
void *pwfn_arg);
/************************************************************************/
SEC_END_PROTOS
#endif /* _SECMIME_H_ */

View File

@ -0,0 +1,618 @@
/*
* 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.
*/
/*
* Interface to the PKCS7 implementation.
*
* $Id: secpkcs7.h,v 1.1 2000/03/31 19:16:09 relyea%netscape.com Exp $
*/
#ifndef _SECPKCS7_H_
#define _SECPKCS7_H_
#include "seccomon.h"
#include "mcom_db.h" /* needed by certt.h */
#include "secoidt.h"
#include "secder.h" /* needed by certt.h; XXX go away when possible */
#include "certt.h"
#include "keyt.h"
#include "hasht.h"
#include "pkcs7t.h"
extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[];
/************************************************************************/
SEC_BEGIN_PROTOS
/************************************************************************
* Miscellaneous
************************************************************************/
/*
* Returns the content type of the given contentInfo.
*/
extern SECOidTag SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo);
/*
* Destroy a PKCS7 contentInfo and all of its sub-pieces.
*/
extern void SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *contentInfo);
/*
* Copy a PKCS7 contentInfo. A Destroy is needed on *each* copy.
*/
extern SEC_PKCS7ContentInfo *
SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *contentInfo);
/*
* Return a pointer to the actual content. In the case of those types
* which are encrypted, this returns the *plain* content.
*/
extern SECItem *SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo);
/************************************************************************
* PKCS7 Decoding, Verification, etc..
************************************************************************/
extern SEC_PKCS7DecoderContext *
SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback callback,
void *callback_arg,
SECKEYGetPasswordKey pwfn, void *pwfn_arg,
SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb,
void *decrypt_key_cb_arg,
SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb);
extern SECStatus
SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx,
const char *buf, unsigned long len);
extern SEC_PKCS7ContentInfo *
SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx);
extern SEC_PKCS7ContentInfo *
SEC_PKCS7DecodeItem(SECItem *p7item,
SEC_PKCS7DecoderContentCallback cb, void *cb_arg,
SECKEYGetPasswordKey pwfn, void *pwfn_arg,
SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb,
void *decrypt_key_cb_arg,
SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb);
extern PRBool SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo);
/* checks to see if the contents of the content info is
* empty. it so, PR_TRUE is returned. PR_FALSE, otherwise.
*
* minLen is used to specify a minimum size. if content size <= minLen,
* content is assumed empty.
*/
extern PRBool
SEC_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen);
extern PRBool SEC_PKCS7ContentIsEncrypted(SEC_PKCS7ContentInfo *cinfo);
/*
* If the PKCS7 content has a signature (not just *could* have a signature)
* return true; false otherwise. This can/should be called before calling
* VerifySignature, which will always indicate failure if no signature is
* present, but that does not mean there even was a signature!
* Note that the content itself can be empty (detached content was sent
* another way); it is the presence of the signature that matters.
*/
extern PRBool SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo);
/*
* SEC_PKCS7VerifySignature
* Look at a PKCS7 contentInfo and check if the signature is good.
* The verification checks that the signing cert is valid and trusted
* for the purpose specified by "certusage".
*
* In addition, if "keepcerts" is true, add any new certificates found
* into our local database.
*/
extern PRBool SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
SECCertUsage certusage,
PRBool keepcerts);
/*
* SEC_PKCS7VerifyDetachedSignature
* Look at a PKCS7 contentInfo and check if the signature matches
* a passed-in digest (calculated, supposedly, from detached contents).
* The verification checks that the signing cert is valid and trusted
* for the purpose specified by "certusage".
*
* In addition, if "keepcerts" is true, add any new certificates found
* into our local database.
*/
extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
SECCertUsage certusage,
SECItem *detached_digest,
HASH_HashType digest_type,
PRBool keepcerts);
/*
* SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress
* The passed-in contentInfo is espected to be Signed, and these
* functions return the specified portion of the full signer name.
*
* Returns a pointer to allocated memory, which must be freed.
* A NULL return value is an error.
*/
extern char *SEC_PKCS7GetSignerCommonName(SEC_PKCS7ContentInfo *cinfo);
extern char *SEC_PKCS7GetSignerEmailAddress(SEC_PKCS7ContentInfo *cinfo);
/*
* Return the the signing time, in UTCTime format, of a PKCS7 contentInfo.
*/
extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo);
/************************************************************************
* PKCS7 Creation and Encoding.
************************************************************************/
/*
* Start a PKCS7 signing context.
*
* "cert" is the cert that will be used to sign the data. It will be
* checked for validity.
*
* "certusage" describes the signing usage (e.g. certUsageEmailSigner)
* XXX Maybe SECCertUsage should be split so that our caller just says
* "email" and *we* add the "signing" part -- otherwise our caller
* could be lying about the usage; we do not want to allow encryption
* certs for signing or vice versa.
*
* "certdb" is the cert database to use for verifying the cert.
* It can be NULL if a default database is available (like in the client).
*
* "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
*
* "digest" is the actual digest of the data. It must be provided in
* the case of detached data or NULL if the content will be included.
*
* The return value can be passed to functions which add things to
* it like attributes, then eventually to SEC_PKCS7Encode() or to
* SEC_PKCS7EncoderStart() to create the encoded data, and finally to
* SEC_PKCS7DestroyContentInfo().
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *
SEC_PKCS7CreateSignedData (CERTCertificate *cert,
SECCertUsage certusage,
CERTCertDBHandle *certdb,
SECOidTag digestalg,
SECItem *digest,
SECKEYGetPasswordKey pwfn, void *pwfn_arg);
/*
* Create a PKCS7 certs-only container.
*
* "cert" is the (first) cert that will be included.
*
* "include_chain" specifies whether the entire chain for "cert" should
* be included.
*
* "certdb" is the cert database to use for finding the chain.
* It can be NULL in when "include_chain" is false, or when meaning
* use the default database.
*
* More certs and chains can be added via AddCertficate and AddCertChain.
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *
SEC_PKCS7CreateCertsOnly (CERTCertificate *cert,
PRBool include_chain,
CERTCertDBHandle *certdb);
/*
* Start a PKCS7 enveloping context.
*
* "cert" is the cert for the recipient. It will be checked for validity.
*
* "certusage" describes the encryption usage (e.g. certUsageEmailRecipient)
* XXX Maybe SECCertUsage should be split so that our caller just says
* "email" and *we* add the "recipient" part -- otherwise our caller
* could be lying about the usage; we do not want to allow encryption
* certs for signing or vice versa.
*
* "certdb" is the cert database to use for verifying the cert.
* It can be NULL if a default database is available (like in the client).
*
* "encalg" specifies the bulk encryption algorithm to use (e.g. SEC_OID_RC2).
*
* "keysize" specifies the bulk encryption key size, in bits.
*
* The return value can be passed to functions which add things to
* it like more recipients, then eventually to SEC_PKCS7Encode() or to
* SEC_PKCS7EncoderStart() to create the encoded data, and finally to
* SEC_PKCS7DestroyContentInfo().
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *
SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert,
SECCertUsage certusage,
CERTCertDBHandle *certdb,
SECOidTag encalg,
int keysize,
SECKEYGetPasswordKey pwfn, void *pwfn_arg);
/*
* XXX There will be a similar routine for creating signedAndEnvelopedData.
* But its parameters will be different and I have no plans to implement
* it any time soon because we have no current need for it.
*/
/*
* Create an empty PKCS7 data content info.
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *SEC_PKCS7CreateData (void);
/*
* Create an empty PKCS7 encrypted content info.
*
* "algorithm" specifies the bulk encryption algorithm to use.
*
* An error results in a return value of NULL and an error set.
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *
SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize,
SECKEYGetPasswordKey pwfn, void *pwfn_arg);
/*
* All of the following things return SECStatus to signal success or failure.
* Failure should have a more specific error status available via
* PORT_GetError()/XP_GetError().
*/
/*
* Add the specified attribute to the authenticated (i.e. signed) attributes
* of "cinfo" -- "oidtag" describes the attribute and "value" is the
* value to be associated with it. NOTE! "value" must already be encoded;
* no interpretation of "oidtag" is done. Also, it is assumed that this
* signedData has only one signer -- if we ever need to add attributes
* when there is more than one signature, we need a way to specify *which*
* signature should get the attribute.
*
* XXX Technically, a signed attribute can have multiple values; if/when
* we ever need to support an attribute which takes multiple values, we
* either need to change this interface or create an AddSignedAttributeValue
* which can be called subsequently, and would then append a value.
*
* "cinfo" should be of type signedData (the only kind of pkcs7 data
* that is allowed authenticated attributes); SECFailure will be returned
* if it is not.
*/
extern SECStatus SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
SECOidTag oidtag,
SECItem *value);
/*
* Add "cert" and its entire chain to the set of certs included in "cinfo".
*
* "certdb" is the cert database to use for finding the chain.
* It can be NULL, meaning use the default database.
*
* "cinfo" should be of type signedData or signedAndEnvelopedData;
* SECFailure will be returned if it is not.
*/
extern SECStatus SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo,
CERTCertificate *cert,
CERTCertDBHandle *certdb);
/*
* Add "cert" to the set of certs included in "cinfo".
*
* "cinfo" should be of type signedData or signedAndEnvelopedData;
* SECFailure will be returned if it is not.
*/
extern SECStatus SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo,
CERTCertificate *cert);
/*
* Add another recipient to an encrypted message.
*
* "cinfo" should be of type envelopedData or signedAndEnvelopedData;
* SECFailure will be returned if it is not.
*
* "cert" is the cert for the recipient. It will be checked for validity.
*
* "certusage" describes the encryption usage (e.g. certUsageEmailRecipient)
* XXX Maybe SECCertUsage should be split so that our caller just says
* "email" and *we* add the "recipient" part -- otherwise our caller
* could be lying about the usage; we do not want to allow encryption
* certs for signing or vice versa.
*
* "certdb" is the cert database to use for verifying the cert.
* It can be NULL if a default database is available (like in the client).
*/
extern SECStatus SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo,
CERTCertificate *cert,
SECCertUsage certusage,
CERTCertDBHandle *certdb);
/*
* Add the signing time to the authenticated (i.e. signed) attributes
* of "cinfo". This is expected to be included in outgoing signed
* messages for email (S/MIME) but is likely useful in other situations.
*
* This should only be added once; a second call will either do
* nothing or replace an old signing time with a newer one.
*
* XXX This will probably just shove the current time into "cinfo"
* but it will not actually get signed until the entire item is
* processed for encoding. Is this (expected to be small) delay okay?
*
* "cinfo" should be of type signedData (the only kind of pkcs7 data
* that is allowed authenticated attributes); SECFailure will be returned
* if it is not.
*/
extern SECStatus SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo);
/*
* Add the signer's symmetric capabilities to the authenticated
* (i.e. signed) attributes of "cinfo". This is expected to be
* included in outgoing signed messages for email (S/MIME).
*
* This can only be added once; a second call will return SECFailure.
*
* "cinfo" should be of type signedData or signedAndEnvelopedData;
* SECFailure will be returned if it is not.
*/
extern SECStatus SEC_PKCS7AddSymmetricCapabilities(SEC_PKCS7ContentInfo *cinfo);
/*
* Mark that the signer's certificate and its issuing chain should
* be included in the encoded data. This is expected to be used
* in outgoing signed messages for email (S/MIME).
*
* "certdb" is the cert database to use for finding the chain.
* It can be NULL, meaning use the default database.
*
* "cinfo" should be of type signedData or signedAndEnvelopedData;
* SECFailure will be returned if it is not.
*/
extern SECStatus SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo,
CERTCertDBHandle *certdb);
/*
* Set the content; it will be included and also hashed and/or encrypted
* as appropriate. This is for in-memory content (expected to be "small")
* that will be included in the PKCS7 object. All others should stream the
* content through when encoding (see SEC_PKCS7Encoder{Start,Update,Finish}).
*
* "buf" points to data of length "len"; it will be copied.
*/
extern SECStatus SEC_PKCS7SetContent (SEC_PKCS7ContentInfo *cinfo,
const char *buf, unsigned long len);
/*
* Encode a PKCS7 object, in one shot. All necessary components
* of the object must already be specified. Either the data has
* already been included (via SetContent), or the data is detached,
* or there is no data at all (certs-only).
*
* "cinfo" specifies the object to be encoded.
*
* "outputfn" is where the encoded bytes will be passed.
*
* "outputarg" is an opaque argument to the above callback.
*
* "bulkkey" specifies the bulk encryption key to use. This argument
* can be NULL if no encryption is being done, or if the bulk key should
* be generated internally (usually the case for EnvelopedData but never
* for EncryptedData, which *must* provide a bulk encryption key).
*
* "pwfn" is a callback for getting the password which protects the
* private key of the signer. This argument can be NULL if it is known
* that no signing is going to be done.
*
* "pwfnarg" is an opaque argument to the above callback.
*/
extern SECStatus SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo,
SEC_PKCS7EncoderOutputCallback outputfn,
void *outputarg,
PK11SymKey *bulkkey,
SECKEYGetPasswordKey pwfn,
void *pwfnarg);
/*
* Encode a PKCS7 object, in one shot. All necessary components
* of the object must already be specified. Either the data has
* already been included (via SetContent), or the data is detached,
* or there is no data at all (certs-only). The output, rather than
* being passed to an output function as is done above, is all put
* into a SECItem.
*
* "pool" specifies a pool from which to allocate the result.
* It can be NULL, in which case memory is allocated generically.
*
* "dest" specifies a SECItem in which to put the result data.
* It can be NULL, in which case the entire item is allocated, too.
*
* "cinfo" specifies the object to be encoded.
*
* "bulkkey" specifies the bulk encryption key to use. This argument
* can be NULL if no encryption is being done, or if the bulk key should
* be generated internally (usually the case for EnvelopedData but never
* for EncryptedData, which *must* provide a bulk encryption key).
*
* "pwfn" is a callback for getting the password which protects the
* private key of the signer. This argument can be NULL if it is known
* that no signing is going to be done.
*
* "pwfnarg" is an opaque argument to the above callback.
*/
extern SECItem *SEC_PKCS7EncodeItem (PRArenaPool *pool,
SECItem *dest,
SEC_PKCS7ContentInfo *cinfo,
PK11SymKey *bulkkey,
SECKEYGetPasswordKey pwfn,
void *pwfnarg);
/*
* For those who want to simply point to the pkcs7 contentInfo ASN.1
* template, and *not* call the encoding functions directly, the
* following function can be used -- after it is called, the entire
* PKCS7 contentInfo is ready to be encoded.
*/
extern SECStatus SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo,
PK11SymKey *bulkkey,
SECKEYGetPasswordKey pwfn,
void *pwfnarg);
/*
* Start the process of encoding a PKCS7 object. The first part of
* the encoded object will be passed to the output function right away;
* after that it is expected that SEC_PKCS7EncoderUpdate will be called,
* streaming in the actual content that is getting included as well as
* signed or encrypted (or both).
*
* "cinfo" specifies the object to be encoded.
*
* "outputfn" is where the encoded bytes will be passed.
*
* "outputarg" is an opaque argument to the above callback.
*
* "bulkkey" specifies the bulk encryption key to use. This argument
* can be NULL if no encryption is being done, or if the bulk key should
* be generated internally (usually the case for EnvelopedData but never
* for EncryptedData, which *must* provide a bulk encryption key).
*
* Returns an object to be passed to EncoderUpdate and EncoderFinish.
*/
extern SEC_PKCS7EncoderContext *
SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo,
SEC_PKCS7EncoderOutputCallback outputfn,
void *outputarg,
PK11SymKey *bulkkey);
/*
* Encode more contents, hashing and/or encrypting along the way.
*/
extern SECStatus SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx,
const char *buf,
unsigned long len);
/*
* No more contents; finish the signature creation, if appropriate,
* and then the encoding.
*
* "pwfn" is a callback for getting the password which protects the
* signer's private key. This argument can be NULL if it is known
* that no signing is going to be done.
*
* "pwfnarg" is an opaque argument to the above callback.
*/
extern SECStatus SEC_PKCS7EncoderFinish (SEC_PKCS7EncoderContext *p7ecx,
SECKEYGetPasswordKey pwfn,
void *pwfnarg);
/* retrieve the algorithm ID used to encrypt the content info
* for encrypted and enveloped data. The SECAlgorithmID pointer
* returned needs to be freed as it is a copy of the algorithm
* id in the content info.
*/
extern SECAlgorithmID *
SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo);
/* the content of an encrypted data content info is encrypted.
* it is assumed that for encrypted data, that the data has already
* been set and is in the "plainContent" field of the content info.
*
* cinfo is the content info to encrypt
*
* key is the key with which to perform the encryption. if the
* algorithm is a password based encryption algorithm, the
* key is actually a password which will be processed per
* PKCS #5.
*
* in the event of an error, SECFailure is returned. SECSuccess
* indicates a success.
*/
extern SECStatus
SEC_PKCS7EncryptContents(PRArenaPool *poolp,
SEC_PKCS7ContentInfo *cinfo,
SECItem *key,
void *wincx);
/* the content of an encrypted data content info is decrypted.
* it is assumed that for encrypted data, that the data has already
* been set and is in the "encContent" field of the content info.
*
* cinfo is the content info to decrypt
*
* key is the key with which to perform the decryption. if the
* algorithm is a password based encryption algorithm, the
* key is actually a password which will be processed per
* PKCS #5.
*
* in the event of an error, SECFailure is returned. SECSuccess
* indicates a success.
*/
extern SECStatus
SEC_PKCS7DecryptContents(PRArenaPool *poolp,
SEC_PKCS7ContentInfo *cinfo,
SECItem *key,
void *wincx);
/* retrieve the certificate list from the content info. the list
* is a pointer to the list in the content info. this should not
* be deleted or freed in any way short of calling
* SEC_PKCS7DestroyContentInfo
*/
extern SECItem **
SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo);
/* Returns the key length (in bits) of the algorithm used to encrypt
this object. Returns 0 if it's not encrypted, or the key length is
irrelevant. */
extern int
SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo);
/************************************************************************/
SEC_END_PROTOS
#endif /* _SECPKCS7_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,261 @@
/*
* 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 NSSPKIT_H
#define NSSPKIT_H
#ifdef DEBUG
static const char NSSPKIT_CVS_ID[] = "@(#) $RCSfile: nsspkit.h,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:14 $ $Name: $";
#endif /* DEBUG */
/*
* nsspkit.h
*
* This file defines the types of the top-level PKI objects.
*/
#ifndef NSSBASET_H
#include "nssbaset.h"
#endif /* NSSBASET_H */
PR_BEGIN_EXTERN_C
/*
* NSSCertificate
*
* This is the public representation of a Certificate. The certificate
* may be one found on a smartcard or other token, one decoded from data
* received as part of a protocol, one constructed from constituent
* parts, etc. Usually it is associated with ("in") a trust domain; as
* it can be verified only within a trust domain. The underlying type
* of certificate may be of any supported standard, e.g. PKIX, PGP, etc.
*
* People speak of "verifying (with) the server's, or correspondant's,
* certificate"; for simple operations we support that simplification
* by implementing public-key crypto operations as methods on this type.
*/
struct NSSCertificateStr;
typedef struct NSSCertificateStr NSSCertificate;
/*
* NSSUserCertificate
*
* A ``User'' certificate is one for which the private key is available.
* People speak of "using my certificate to sign my email" and "using
* my certificate to authenticate to (or login to) the server"; for
* simple operations, we support that simplification by implementing
* private-key crypto operations as methods on this type.
*
* The current design only weakly distinguishes between certificates
* and user certificates: as far as the compiler goes they're
* interchangable; debug libraries only have one common pointer-tracker;
* etc. However, attempts to do private-key operations on a certificate
* for which the private key is not available will fail.
*
* Open design question: should these types be more firmly separated?
*/
typedef NSSCertificate NSSUserCertificate;
/*
* NSSPrivateKey
*
* This is the public representation of a Private Key. In general,
* the actual value of the key is not available, but operations may
* be performed with it.
*/
struct NSSPrivateKeyStr;
typedef struct NSSPrivateKeyStr NSSPrivateKey;
/*
* NSSPublicKey
*
*/
struct NSSPublicKeyStr;
typedef struct NSSPublicKeyStr NSSPublicKey;
/*
* NSSSymmetricKey
*
*/
struct NSSSymmetricKeyStr;
typedef struct NSSSymmetricKeyStr NSSSymmetricKey;
/*
* NSSTrustDomain
*
* A Trust Domain is the field in which certificates may be validated.
* A trust domain will generally have one or more cryptographic modules
* open; these modules perform the cryptographic operations, and
* provide the basic "root" trust information from which the trust in
* a specific certificate or key depends.
*
* A client program, or a simple server, would typically have one
* trust domain. A server supporting multiple "virtual servers" might
* have a separate trust domain for each virtual server. The separate
* trust domains might share some modules (e.g., a hardware crypto
* accelerator) but not others (e.g., the tokens storing the different
* servers' private keys, or the databases with each server's trusted
* root certificates).
*
* This object descends from the "permananet database" in the old code.
*/
struct NSSTrustDomainStr;
typedef struct NSSTrustDomainStr NSSTrustDomain;
/*
* NSSCryptoContext
*
* A Crypto Context is a short-term, "helper" object which is used
* for the lifetime of one ongoing "crypto operation." Such an
* operation may be the creation of a signed message, the use of an
* TLS socket connection, etc. Each crypto context is "in" a
* specific trust domain, and it may have associated with it a
* distinguished certificate, public key, private key, and/or
* symmetric key. It can also temporarily hold and use temporary
* data (e.g. intermediate certificates) which is not stored
* permanently in the trust domain.
*
* In OO terms, this interface inherits interfaces from the trust
* domain, the certificates, and the keys. It also provides
* streaming crypto operations.
*
* This object descends from the "temporary database" concept in the
* old code, but it has changed a lot as a result of what we've
* learned.
*/
struct NSSCryptoContextStr;
typedef struct NSSCryptoContextStr NSSCryptoContext;
/*
* fgmr others
*/
/*
* NSSTime
*
* Unfortunately, we need an "exceptional" value to indicate
* an error upon return, or "no value" on input. Note that zero
* is a perfectly valid value for both time_t and PRTime.
*
* If we were to create a "range" object, with two times for
* Not Before and Not After, we would have an obvious place for
* the somewhat arbitrary logic involved in comparing them.
*
* Failing that, let's have an NSSTime_CompareRanges function.
*/
struct NSSTimeStr;
typedef struct NSSTimeStr NSSTime;
/*
* NSSUsage
*
* This is trickier than originally planned; I'll write up a
* doc on it.
*
* We'd still like nsspki.h to have a list of common usages,
* e.g.:
*
* extern const NSSUsage *NSSUsage_ClientAuth;
* extern const NSSUsage *NSSUsage_ServerAuth;
* extern const NSSUsage *NSSUsage_SignEmail;
* extern const NSSUsage *NSSUsage_EncryptEmail;
* etc.
*/
struct NSSUsageStr;
typedef struct NSSUsageStr NSSUsage;
/*
* NSSPolicies
*
* Placeholder, for now.
*/
struct NSSPoliciesStr;
typedef struct NSSPoliciesStr NSSPolicies;
/*
* NSSAlgorithmAndParameters
*
* Algorithm is an OID
* Parameters depend on the algorithm
*/
struct NSSAlgorithmAndParametersStr;
typedef struct NSSAlgorithmAndParametersStr NSSAlgorithmAndParameters;
/*
* NSSCallback
*
* At minimum, a "challenge" method and a closure argument.
* Usually the challenge will just be prompting for a password.
* How OO do we want to make it?
*/
struct NSSCallbackStr;
typedef struct NSSCallbackStr NSSCallback;
/*
* NSSModule and NSSSlot -- placeholders for the PKCS#11 types
*/
struct NSSModuleStr;
typedef struct NSSModuleStr NSSModule;
struct NSSSlotStr;
typedef struct NSSSlotStr NSSSlot;
typedef PRUint32 NSSOperations;
/* 1) Do we want these to be preprocessor definitions or constants? */
/* 2) What is the correct and complete list? */
#define NSSOperations_ENCRYPT 0x0001
#define NSSOperations_DECRYPT 0x0002
#define NSSOperations_WRAP 0x0004
#define NSSOperations_UNWRAP 0x0008
#define NSSOperations_SIGN 0x0010
#define NSSOperations_SIGN_RECOVER 0x0020
#define NSSOperations_VERIFY 0x0040
#define NSSOperations_VERIFY_RECOVER 0x0080
PR_END_EXTERN_C
#endif /* NSSPKIT_H */

View File

@ -0,0 +1,3 @@
oiddata.c
oiddata.h

View File

@ -0,0 +1,38 @@
#
# 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.
#
MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:16 $ $Name: $"
include manifest.mn
include config.mk
include $(CORE_DEPTH)/coreconf/config.mk
include $(CORE_DEPTH)/coreconf/rules.mk

1803
security/nss/lib/pki1/atav.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
#
# 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.
#
CONFIG_CVS_ID = "@(#) $RCSfile: config.mk,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:16 $ $Name: $"
ifdef BUILD_IDG
DEFINES += -DNSSDEBUG
endif

View File

@ -0,0 +1,94 @@
/*
* 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.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: genname.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:18 $ $Name: $";
#endif /* DEBUG */
/*
* genname.c
*
* This file contains the implementation of the PKIX part-1 object
* GeneralName.
*/
#ifndef NSSBASE_H
#include "nssbase.h"
#endif /* NSSBASE_H */
#ifndef ASN1_H
#include "asn1.h"
#endif /* ASN1_H */
#ifndef PKI1_H
#include "pki1.h"
#endif /* PKI1_H */
/*
* GeneralName
*
* From draft-ietf-pkix-ipki-part1-10:
*
* GeneralName ::= CHOICE {
* otherName [0] INSTANCE OF OTHER-NAME,
* rfc822Name [1] IA5String,
* dNSName [2] IA5String,
* x400Address [3] ORAddress,
* directoryName [4] Name,
* ediPartyName [5] EDIPartyName,
* uniformResourceIdentifier [6] IA5String,
* iPAddress [7] OCTET STRING,
* registeredID [8] OBJECT IDENTIFIER }
*
* OTHER-NAME ::= TYPE-IDENTIFIER
*
* EDIPartyName ::= SEQUENCE {
* nameAssigner [0] DirectoryString {ub-name} OPTIONAL,
* partyName [1] DirectoryString {ub-name} }
*
*/
struct nssGeneralNameStr {
NSSGeneralNameChoice choice;
union {
/* OTHER-NAME otherName */
NSSUTF8 *rfc822Name;
NSSUTF8 *dNSName;
/* ORAddress x400Address */
NSSName *directoryName;
/* EDIPartyName ediPartyName */
NSSUTF8 *uniformResourceIdentifier;
NSSItem *iPAddress;
NSSOID *registeredID;
} u;
};

View File

@ -0,0 +1,71 @@
/*
* 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.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: gnseq.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:18 $ $Name: $";
#endif /* DEBUG */
/*
* gnseq.c
*
* This file contains the implementation of the PKIX part-1 object
* GeneralNames (note the ending 's').
*/
#ifndef NSSBASE_H
#include "nssbase.h"
#endif /* NSSBASE_H */
#ifndef ASN1_H
#include "asn1.h"
#endif /* ASN1_H */
#ifndef PKI1_H
#include "pki1.h"
#endif /* PKI1_H */
/*
* GeneralNames (or, as we call it, GeneralNameSeq)
*
* From draft-ietf-pkix-ipki-part1-10:
*
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
*
* A GeneralNames is simply an (ordered) sequence of General Names.
* The seqSize variable is "helper" kept for simplicity.
*/
struct nssGeneralNameSeqStr {
PRUint32 seqSize;
NSSGeneralName **generalNames;
};

View File

@ -0,0 +1,63 @@
#
# 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.
#
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:18 $ $Name: $"
CORE_DEPTH = ../../..
PRIVATE_EXPORTS = \
pki1.h \
pki1t.h \
$(NULL)
EXPORTS = \
oiddata.h \
nsspki1.h \
nsspki1t.h \
$(NULL)
MODULE = security
CSRCS = \
atav.c \
genname.c \
gnseq.c \
name.c \
oid.c \
oiddata.c \
rdn.c \
rdnseq.c \
$(NULL)
REQUIRES = security nspr
LIBRARY_NAME = pki1

View File

@ -0,0 +1,77 @@
/*
* 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.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: name.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:19 $ $Name: $";
#endif /* DEBUG */
/*
* name.c
*
* This file contains the implementation of the PKIX part-1 object
* Name.
*/
#ifndef NSSBASE_H
#include "nssbase.h"
#endif /* NSSBASE_H */
#ifndef ASN1_H
#include "asn1.h"
#endif /* ASN1_H */
#ifndef PKI1_H
#include "pki1.h"
#endif /* PKI1_H */
/*
* Name
*
* From draft-ietf-pkix-ipki-part1-10:
*
* -- naming data types --
*
* Name ::= CHOICE { -- only one possibility for now --
* rdnSequence RDNSequence }
*
* A name is basically a union of the possible names. At the moment,
* there is only one type of name: an RDNSequence.
*/
struct nssNameStr {
PRUint32 tagPlaceHolder;
union {
NSSRDNSeq *rdnSequence;
} n;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
/*
* 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 NSSPKI1T_H
#define NSSPKI1T_H
#ifdef DEBUG
static const char NSSPKI1T_CVS_ID[] = "@(#) $RCSfile: nsspki1t.h,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:21 $ $Name: $";
#endif /* DEBUG */
/*
* nsspki1t.h
*
* This file contains the public type definitions for the PKIX part-1
* objects.
*/
#ifndef NSSBASET_H
#include "nssbaset.h"
#endif /* NSSBASET_H */
PR_BEGIN_EXTERN_C
/*
* OBJECT IDENTIFIER
*
* This is the basic OID that crops up everywhere.
*/
struct NSSOIDStr;
typedef struct NSSOIDStr NSSOID;
/*
* AttributeTypeAndValue
*
* This structure contains an attribute type (indicated by an OID),
* and the type-specific value. RelativeDistinguishedNamess consist
* of a set of these. These are distinct from Attributes (which have
* SET of values), from AttributeDescriptions (which have qualifiers
* on the types), and from AttributeValueAssertions (which assert a
* a value comparison under some matching rule).
*/
struct NSSATAVStr;
typedef struct NSSATAVStr NSSATAV;
/*
* RelativeDistinguishedName
*
* This structure contains an unordered set of AttributeTypeAndValue
* objects. RDNs are used to distinguish a set of objects underneath
* a common object.
*
* Often, a single ATAV is sufficient to make a unique distinction.
* For example, if a company assigns its people unique uid values,
* then in the Name "uid=smith,ou=People,o=Acme,c=US" the "uid=smith"
* ATAV by itself forms an RDN. However, sometimes a set of ATAVs is
* needed. For example, if a company needed to distinguish between
* two Smiths by specifying their corporate divisions, then in the
* Name "(cn=Smith,ou=Sales),ou=People,o=Acme,c=US" the parenthesised
* set of ATAVs forms the RDN.
*/
struct NSSRDNStr;
typedef struct NSSRDNStr NSSRDN;
/*
* RDNSequence
*
* This structure contains a sequence of RelativeDistinguishedName
* objects.
*/
struct NSSRDNSeqStr;
typedef struct NSSRDNSeqStr NSSRDNSeq;
/*
* Name
*
* This structure contains a union of the possible name formats,
* which at the moment is limited to an RDNSequence.
*/
struct NSSNameStr;
typedef struct NSSNameStr NSSName;
/*
* NameChoice
*
* This enumeration is used to specify choice within a name.
*/
enum NSSNameChoiceEnum {
NSSNameChoiceInvalid = -1,
NSSNameChoiceRdnSequence
};
typedef enum NSSNameChoiceEnum NSSNameChoice;
/*
* GeneralName
*
* This structure contains a union of the possible general names,
* of which there are several.
*/
struct NSSGeneralNameStr;
typedef struct NSSGeneralNameStr NSSGeneralName;
/*
* GeneralNameChoice
*
* This enumerates the possible general name types.
*/
enum NSSGeneralNameChoiceEnum {
NSSGeneralNameChoiceInvalid = -1,
NSSGeneralNameChoiceOtherName = 0,
NSSGeneralNameChoiceRfc822Name = 1,
NSSGeneralNameChoiceDNSName = 2,
NSSGeneralNameChoiceX400Address = 3,
NSSGeneralNameChoiceDirectoryName = 4,
NSSGeneralNameChoiceEdiPartyName = 5,
NSSGeneralNameChoiceUniformResourceIdentifier = 6,
NSSGeneralNameChoiceIPAddress = 7,
NSSGeneralNameChoiceRegisteredID = 8
};
typedef enum NSSGeneralNameChoiceEnum NSSGeneralNameChoice;
/*
* The "other" types of general names.
*/
struct NSSOtherNameStr;
typedef struct NSSOtherNameStr NSSOtherName;
struct NSSRFC822NameStr;
typedef struct NSSRFC822NameStr NSSRFC822Name;
struct NSSDNSNameStr;
typedef struct NSSDNSNameStr NSSDNSName;
struct NSSX400AddressStr;
typedef struct NSSX400AddressStr NSSX400Address;
struct NSSEdiPartyNameStr;
typedef struct NSSEdiPartyNameStr NSSEdiPartyName;
struct NSSURIStr;
typedef struct NSSURIStr NSSURI;
struct NSSIPAddressStr;
typedef struct NSSIPAddressStr NSSIPAddress;
struct NSSRegisteredIDStr;
typedef struct NSSRegisteredIDStr NSSRegisteredID;
/*
* GeneralNameSeq
*
* This structure contains a sequence of GeneralName objects.
* Note that the PKIX documents refer to this as "GeneralNames,"
* which differs from "GeneralName" by only one letter. To
* try to reduce confusion, we expand the name slightly to
* "GeneralNameSeq."
*/
struct NSSGeneralNameSeqStr;
typedef struct NSSGeneralNameSeqStr NSSGeneralNameSeq;
PR_END_EXTERN_C
#endif /* NSSPKI1T_H */

1615
security/nss/lib/pki1/oid.c Normal file

File diff suppressed because it is too large Load Diff

311
security/nss/lib/pki1/oidgen.perl Executable file
View File

@ -0,0 +1,311 @@
#!perl
#
# 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.
#
$cvs_id = '@(#) $RCSfile: oidgen.perl,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:22 $ $Name: $';
$count = -1;
while(<>) {
s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
next if (/^\s*$/);
/^([\S]+)\s+([^"][\S]*|"[^"]*")/;
$name = $1;
$value = $2;
# This is certainly not the best way to dequote the data.
$value =~ s/"//g;
if( $name =~ "OID" ) {
$count++;
$x[$count]{$name} = $value;
$enc = encodeoid($value);
$x[$count]{" encoding"} = escapeoid($enc);
$x[$count]{" encoding length"} = length($enc);
} else {
if( $count < 0 ) {
$g{$name} = $value;
} else {
$x[$count]{$name} = $value;
}
}
}
# dodump();
doprint();
sub dodump {
for( $i = 0; $i <= $count; $i++ ) {
print "number $i:\n";
%y = %{$x[$i]};
while(($n,$v) = each(%y)) {
print "\t$n ==> $v\n";
}
}
}
sub doprint {
open(CFILE, ">oiddata.c") || die "Can't open oiddata.c: $!";
open(HFILE, ">oiddata.h") || die "Can't open oiddata.h: $!";
print CFILE <<EOD
/* THIS IS A GENERATED FILE */
/*
* 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.
*/
#ifdef DEBUG
static const char CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
#endif /* DEBUG */
#ifndef PKI1T_H
#include "pki1t.h"
#endif /* PKI1T_H */
const NSSOID nss_builtin_oids[] = {
EOD
;
for( $i = 0; $i <= $count; $i++ ) {
%y = %{$x[$i]};
print CFILE " {\n";
print CFILE "#ifdef DEBUG\n";
print CFILE " \"$y{TAG}\",\n";
print CFILE " \"$y{EXPL}\",\n";
print CFILE "#endif /* DEBUG */\n";
print CFILE " { \"", $y{" encoding"};
print CFILE "\", ", $y{" encoding length"}, " }\n";
if( $i == $count ) {
print CFILE " }\n";
} else {
print CFILE " },\n";
}
}
print CFILE "};\n\n";
print CFILE "const PRUint32 nss_builtin_oid_count = ", ($count+1), ";\n\n";
for( $i = 0; $i <= $count; $i++ ) {
%y = %{$x[$i]};
if( defined($y{NAME}) ) {
print CFILE "const NSSOID *$y{NAME} = (NSSOID *)&nss_builtin_oids[$i];\n";
}
}
print CFILE "\n";
$attrcount = -1;
for( $i = 0; $i <= $count; $i++ ) {
%y = %{$x[$i]};
if( defined($y{ATTR}) ) {
if( defined($y{NAME}) ) {
$attrcount++;
$attr[$attrcount]{ATTR} = $y{ATTR};
$attr[$attrcount]{NAME} = $y{NAME};
} else {
warn "Attribute $y{ATTR} has no name, and will be omitted!";
}
}
}
print CFILE "const nssAttributeTypeAliasTable nss_attribute_type_aliases[] = {\n";
for( $i = 0; $i <= $attrcount; $i++ ) {
%y = %{$attr[$i]};
print CFILE " {\n";
print CFILE " \"$y{ATTR}\",\n";
print CFILE " &$y{NAME}\n";
if( $i == $attrcount ) {
print CFILE " }\n";
} else {
print CFILE " },\n";
}
}
print CFILE "};\n\n";
print CFILE "const PRUint32 nss_attribute_type_alias_count = ", ($attrcount+1), ";\n\n";
print HFILE <<EOD
/* THIS IS A GENERATED FILE */
/*
* 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 OIDDATA_H
#define OIDDATA_H
#ifdef DEBUG
static const char OIDDATA_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
#endif /* DEBUG */
#ifndef NSSPKI1T_H
#include "nsspki1t.h"
#endif /* NSSPKI1T_H */
extern const NSSOID nss_builtin_oids[];
extern const PRUint32 nss_builtin_oid_count;
/*extern const nssAttributeTypeAliasTable nss_attribute_type_aliases[];*/
/*extern const PRUint32 nss_attribute_type_alias_count;*/
EOD
;
for( $i = 0; $i <= $count; $i++ ) {
%y = %{$x[$i]};
if( defined($y{NAME}) ) {
print HFILE "extern const NSSOID *$y{NAME};\n";
}
}
print HFILE <<EOD
#endif /* OIDDATA_H */
EOD
;
close CFILE;
close HFILE;
}
sub encodenum {
my $v = $_[0];
my @d;
my $i;
my $rv = "";
while( $v > 128 ) {
push @d, ($v % 128);
$v /= 128;
};
push @d, ($v%128);
for( $i = @d-1; $i > 0; $i-- ) {
$rv = $rv . chr(128 + $d[$i]);
}
$rv = $rv . chr($d[0]);
return $rv;
}
sub encodeoid {
my @o = split(/\./, $_[0]);
my $rv = "";
my $i;
if( @o < 2 ) {
# NSS's special "illegal" encoding
return chr(128) . encodenum($o[0]);
}
$rv = encodenum($o[0] * 40 + $o[1]);
shift @o; shift @o;
foreach $i (@o) {
$rv = $rv . encodenum($i);
}
return $rv;
}
sub escapeoid {
my @v = unpack("C*", $_[0]);
my $a;
my $rv = "";
foreach $a (@v) {
$rv = $rv . sprintf("\\x%02x", $a);
}
return $rv;
}

File diff suppressed because it is too large Load Diff

3032
security/nss/lib/pki1/pki1.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/*
* 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 PKI1T_H
#define PKI1T_H
#ifdef DEBUG
static const char PKI1T_CVS_ID[] = "@(#) $RCSfile: pki1t.h,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:25 $ $Name: $";
#endif /* DEBUG */
/*
* pki1t.h
*
* This file contains definitions for the types used in the PKIX part-1
* code, but not available publicly.
*/
#ifndef BASET_H
#include "baset.h"
#endif /* BASET_H */
#ifndef NSSPKI1T_H
#include "nsspki1t.h"
#endif /* NSSPKI1T_H */
PR_BEGIN_EXTERN_C
/*
* NSSOID
*
* This structure is used to hold our internal table of built-in OID
* data. The fields are as follows:
*
* NSSItem data -- this is the actual DER-encoded multinumber oid
* const char *expl -- this explains the derivation, and is checked
* in a unit test. While the field always exists,
* it is only populated or used in debug builds.
*
*/
struct NSSOIDStr {
#ifdef DEBUG
const NSSUTF8 *tag;
const NSSUTF8 *expl;
#endif /* DEBUG */
NSSItem data;
};
/*
* nssAttributeTypeAliasTable
*
* Attribute types are passed around as oids (at least in the X.500
* and PKI worlds, as opposed to ldap). However, when written as
* strings they usually have well-known aliases, e.g., "ou" or "c."
*
* This type defines a table, populated in the generated oiddata.c
* file, of the aliases we recognize.
*
* The fields are as follows:
*
* NSSUTF8 *alias -- a well-known string alias for an oid
* NSSOID *oid -- the oid to which the alias corresponds
*
*/
struct nssAttributeTypeAliasTableStr {
const NSSUTF8 *alias;
const NSSOID **oid;
};
typedef struct nssAttributeTypeAliasTableStr nssAttributeTypeAliasTable;
PR_END_EXTERN_C
#endif /* PKI1T_H */

View File

@ -0,0 +1,73 @@
/*
* 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.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: rdn.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:25 $ $Name: $";
#endif /* DEBUG */
/*
* rdn.c
*
* This file contains the implementation of the PKIX part-1 object
* RelativeDistinguishedName.
*/
#ifndef NSSBASE_H
#include "nssbase.h"
#endif /* NSSBASE_H */
#ifndef ASN1_H
#include "asn1.h"
#endif /* ASN1_H */
#ifndef PKI1_H
#include "pki1.h"
#endif /* PKI1_H */
/*
* RelativeDistinguishedName
*
* From draft-ietf-pkix-ipki-part1-10:
*
* RelativeDistinguishedName ::=
* SET SIZE (1 .. MAX) OF AttributeTypeAndValue
*
* An RDN is merely an (unordered) set of ATAV's. The setSize (that's
* a noun, not a verb) variable is a "helper" variable kept for
* convenience.
*/
struct nssRDNStr {
PRUint32 setSize;
NSSATAV **atavs;
};

View File

@ -0,0 +1,71 @@
/*
* 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.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: rdnseq.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:16:26 $ $Name: $";
#endif /* DEBUG */
/*
* rdnseq.c
*
* This file contains the implementation of the PKIX part-1 object
* RDNSequence.
*/
#ifndef NSSBASE_H
#include "nssbase.h"
#endif /* NSSBASE_H */
#ifndef ASN1_H
#include "asn1.h"
#endif /* ASN1_H */
#ifndef PKI1_H
#include "pki1.h"
#endif /* PKI1_H */
/*
* RDNSequence
*
* From draft-ietf-pkix-ipki-part1-10:
*
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
*
* An RDNSequence is simply an (ordered) sequence of RDN's. The
* seqSize variable is a "helper" kept for simplicity.
*/
struct nssRDNSeqStr {
PRUint32 seqSize;
NSSRDN **rdns;
};