mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 11:57:32 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
62
security/nss/lib/pk11wrap/Makefile
Normal file
62
security/nss/lib/pk11wrap/Makefile
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#! gmake
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#######################################################################
|
||||
# (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
|
||||
|
||||
$(OBJDIR)/pk11load$(OBJ_SUFFIX): debug_module.c
|
||||
|
||||
# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile
|
||||
# pk11slot.c in 64-bit mode for unknown reasons. A workaround is
|
||||
# to compile it with optimizations turned on. (Bugzilla bug #63815)
|
||||
ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3)
|
||||
ifeq ($(USE_64),1)
|
||||
ifndef BUILD_OPT
|
||||
$(OBJDIR)/pk11slot.o: pk11slot.c
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ -c -O2 $(CFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
15
security/nss/lib/pk11wrap/config.mk
Normal file
15
security/nss/lib/pk11wrap/config.mk
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#
|
||||
# Override TARGETS variable so that only static libraries
|
||||
# are specifed as dependencies within rules.mk.
|
||||
#
|
||||
|
||||
TARGETS = $(LIBRARY)
|
||||
SHARED_LIBRARY =
|
||||
IMPORT_LIBRARY =
|
||||
PROGRAM =
|
||||
|
||||
2760
security/nss/lib/pk11wrap/debug_module.c
Normal file
2760
security/nss/lib/pk11wrap/debug_module.c
Normal file
File diff suppressed because it is too large
Load diff
279
security/nss/lib/pk11wrap/dev3hack.c
Normal file
279
security/nss/lib/pk11wrap/dev3hack.c
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef PKIT_H
|
||||
#include "pkit.h"
|
||||
#endif /* PKIT_H */
|
||||
|
||||
#ifndef DEVM_H
|
||||
#include "devm.h"
|
||||
#endif /* DEVM_H */
|
||||
|
||||
#include "pki3hack.h"
|
||||
#include "dev3hack.h"
|
||||
#include "pkim.h"
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
#include "pk11func.h"
|
||||
#include "secmodti.h"
|
||||
#include "secerr.h"
|
||||
|
||||
NSS_IMPLEMENT nssSession *
|
||||
nssSession_ImportNSS3Session(NSSArena *arenaOpt,
|
||||
CK_SESSION_HANDLE session,
|
||||
PZLock *lock, PRBool rw)
|
||||
{
|
||||
nssSession *rvSession = NULL;
|
||||
if (session != CK_INVALID_SESSION) {
|
||||
rvSession = nss_ZNEW(arenaOpt, nssSession);
|
||||
if (rvSession) {
|
||||
rvSession->handle = session;
|
||||
rvSession->lock = lock;
|
||||
rvSession->ownLock = PR_FALSE;
|
||||
rvSession->isRW = rw;
|
||||
}
|
||||
}
|
||||
return rvSession;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT nssSession *
|
||||
nssSlot_CreateSession(
|
||||
NSSSlot *slot,
|
||||
NSSArena *arenaOpt,
|
||||
PRBool readWrite)
|
||||
{
|
||||
nssSession *rvSession;
|
||||
|
||||
if (!readWrite) {
|
||||
/* nss3hack version only returns rw swssions */
|
||||
return NULL;
|
||||
}
|
||||
rvSession = nss_ZNEW(arenaOpt, nssSession);
|
||||
if (!rvSession) {
|
||||
return (nssSession *)NULL;
|
||||
}
|
||||
|
||||
rvSession->handle = PK11_GetRWSession(slot->pk11slot);
|
||||
if (rvSession->handle == CK_INVALID_HANDLE) {
|
||||
nss_ZFreeIf(rvSession);
|
||||
return NULL;
|
||||
}
|
||||
rvSession->isRW = PR_TRUE;
|
||||
rvSession->slot = slot;
|
||||
/*
|
||||
* The session doesn't need its own lock. Here's why.
|
||||
* 1. If we are reusing the default RW session of the slot,
|
||||
* the slot lock is already locked to protect the session.
|
||||
* 2. If the module is not thread safe, the slot (or rather
|
||||
* module) lock is already locked.
|
||||
* 3. If the module is thread safe and we are using a new
|
||||
* session, no higher-level lock has been locked and we
|
||||
* would need a lock for the new session. However, the
|
||||
* current usage of the session is that it is always
|
||||
* used and destroyed within the same function and never
|
||||
* shared with another thread.
|
||||
* So the session is either already protected by another
|
||||
* lock or only used by one thread.
|
||||
*/
|
||||
rvSession->lock = NULL;
|
||||
rvSession->ownLock = PR_FALSE;
|
||||
return rvSession;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssSession_Destroy(nssSession *s)
|
||||
{
|
||||
PRStatus rv = PR_SUCCESS;
|
||||
if (s) {
|
||||
if (s->isRW) {
|
||||
PK11_RestoreROSession(s->slot->pk11slot, s->handle);
|
||||
}
|
||||
rv = nss_ZFreeIf(s);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static NSSSlot *
|
||||
nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
|
||||
{
|
||||
NSSSlot *rvSlot;
|
||||
NSSArena *arena;
|
||||
arena = nssArena_Create();
|
||||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
rvSlot = nss_ZNEW(arena, NSSSlot);
|
||||
if (!rvSlot) {
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
rvSlot->base.refCount = 1;
|
||||
rvSlot->base.lock = PZ_NewLock(nssILockOther);
|
||||
rvSlot->base.arena = arena;
|
||||
rvSlot->pk11slot = nss3slot;
|
||||
rvSlot->epv = nss3slot->functionList;
|
||||
rvSlot->slotID = nss3slot->slotID;
|
||||
/* Grab the slot name from the PKCS#11 fixed-length buffer */
|
||||
rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name, td->arena);
|
||||
rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
|
||||
return rvSlot;
|
||||
}
|
||||
|
||||
NSSToken *
|
||||
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
|
||||
{
|
||||
NSSToken *rvToken;
|
||||
NSSArena *arena;
|
||||
|
||||
/* Don't create a token object for a disabled slot */
|
||||
if (nss3slot->disabled) {
|
||||
PORT_SetError(SEC_ERROR_NO_TOKEN);
|
||||
return NULL;
|
||||
}
|
||||
arena = nssArena_Create();
|
||||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
rvToken = nss_ZNEW(arena, NSSToken);
|
||||
if (!rvToken) {
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
rvToken->base.refCount = 1;
|
||||
rvToken->base.lock = PZ_NewLock(nssILockOther);
|
||||
if (!rvToken->base.lock) {
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
rvToken->base.arena = arena;
|
||||
rvToken->pk11slot = nss3slot;
|
||||
rvToken->epv = nss3slot->functionList;
|
||||
rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
|
||||
nss3slot->session,
|
||||
nss3slot->sessionLock,
|
||||
nss3slot->defRWSession);
|
||||
#if 0 /* we should do this instead of blindly continuing. */
|
||||
if (!rvToken->defaultSession) {
|
||||
PORT_SetError(SEC_ERROR_NO_TOKEN);
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
|
||||
rvToken->cache = nssTokenObjectCache_Create(rvToken,
|
||||
PR_TRUE, PR_TRUE, PR_TRUE);
|
||||
if (!rvToken->cache)
|
||||
goto loser;
|
||||
}
|
||||
rvToken->trustDomain = td;
|
||||
/* Grab the token name from the PKCS#11 fixed-length buffer */
|
||||
rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name, td->arena);
|
||||
rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
|
||||
if (!rvToken->slot) {
|
||||
goto loser;
|
||||
}
|
||||
rvToken->slot->token = rvToken;
|
||||
if (rvToken->defaultSession)
|
||||
rvToken->defaultSession->slot = rvToken->slot;
|
||||
return rvToken;
|
||||
loser:
|
||||
PZ_DestroyLock(rvToken->base.lock);
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nssToken_UpdateName(NSSToken *token)
|
||||
{
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name, token->base.arena);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRBool
|
||||
nssSlot_IsPermanent(NSSSlot *slot)
|
||||
{
|
||||
return slot->pk11slot->isPerm;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRBool
|
||||
nssSlot_IsFriendly(NSSSlot *slot)
|
||||
{
|
||||
return PK11_IsFriendly(slot->pk11slot);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_Refresh(NSSToken *token)
|
||||
{
|
||||
PK11SlotInfo *nss3slot;
|
||||
|
||||
if (!token) {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
nss3slot = token->pk11slot;
|
||||
token->defaultSession =
|
||||
nssSession_ImportNSS3Session(token->slot->base.arena,
|
||||
nss3slot->session,
|
||||
nss3slot->sessionLock,
|
||||
nss3slot->defRWSession);
|
||||
return token->defaultSession ? PR_SUCCESS : PR_FAILURE;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssSlot_Refresh(NSSSlot *slot)
|
||||
{
|
||||
PK11SlotInfo *nss3slot = slot->pk11slot;
|
||||
PRBool doit = PR_FALSE;
|
||||
if (slot->token && slot->token->base.name[0] == 0) {
|
||||
doit = PR_TRUE;
|
||||
}
|
||||
if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (doit) {
|
||||
nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
|
||||
slot->token);
|
||||
}
|
||||
return nssToken_Refresh(slot->token);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_GetTrustOrder(NSSToken *tok)
|
||||
{
|
||||
PK11SlotInfo *slot;
|
||||
SECMODModule *module;
|
||||
slot = tok->pk11slot;
|
||||
module = PK11_GetModule(slot);
|
||||
return module->trustOrder;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRBool
|
||||
nssSlot_IsLoggedIn(NSSSlot *slot)
|
||||
{
|
||||
if (!slot->pk11slot->needLogin) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PK11_IsLoggedIn(slot->pk11slot, NULL);
|
||||
}
|
||||
|
||||
NSSTrustDomain *
|
||||
nssToken_GetTrustDomain(NSSToken *token)
|
||||
{
|
||||
return token->trustDomain;
|
||||
}
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssTrustDomain_RemoveTokenCertsFromCache(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token);
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_NotifyCertsNotVisible(
|
||||
NSSToken *tok)
|
||||
{
|
||||
return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
|
||||
}
|
||||
30
security/nss/lib/pk11wrap/dev3hack.h
Normal file
30
security/nss/lib/pk11wrap/dev3hack.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef DEVNSS3HACK_H
|
||||
#define DEVNSS3HACK_H
|
||||
|
||||
#include "cert.h"
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
NSS_EXTERN NSSToken *
|
||||
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot);
|
||||
|
||||
NSS_EXTERN void
|
||||
nssToken_UpdateName(NSSToken *);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_Refresh(NSSToken *);
|
||||
|
||||
NSSTrustDomain *
|
||||
nssToken_GetTrustDomain(NSSToken *token);
|
||||
|
||||
void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst);
|
||||
|
||||
NSSToken *PK11Slot_GetNSSToken(PK11SlotInfo *sl);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* DEVNSS3HACK_H */
|
||||
39
security/nss/lib/pk11wrap/exports.gyp
Normal file
39
security/nss/lib/pk11wrap/exports.gyp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
{
|
||||
'includes': [
|
||||
'../../coreconf/config.gypi'
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'lib_pk11wrap_exports',
|
||||
'type': 'none',
|
||||
'copies': [
|
||||
{
|
||||
'files': [
|
||||
'pk11func.h',
|
||||
'pk11pqg.h',
|
||||
'pk11priv.h',
|
||||
'pk11pub.h',
|
||||
'pk11sdr.h',
|
||||
'secmod.h',
|
||||
'secmodt.h',
|
||||
'secpkcs5.h'
|
||||
],
|
||||
'destination': '<(nss_public_dist_dir)/<(module)'
|
||||
},
|
||||
{
|
||||
'files': [
|
||||
'dev3hack.h',
|
||||
'secmodi.h'
|
||||
],
|
||||
'destination': '<(nss_private_dist_dir)/<(module)'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'variables': {
|
||||
'module': 'nss'
|
||||
}
|
||||
}
|
||||
63
security/nss/lib/pk11wrap/manifest.mn
Normal file
63
security/nss/lib/pk11wrap/manifest.mn
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
CORE_DEPTH = ../..
|
||||
|
||||
EXPORTS = \
|
||||
secmod.h \
|
||||
secmodt.h \
|
||||
secpkcs5.h \
|
||||
pk11func.h \
|
||||
pk11pub.h \
|
||||
pk11priv.h \
|
||||
pk11sdr.h \
|
||||
pk11pqg.h \
|
||||
$(NULL)
|
||||
|
||||
PRIVATE_EXPORTS = \
|
||||
secmodi.h \
|
||||
dev3hack.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = nss
|
||||
|
||||
CSRCS = \
|
||||
dev3hack.c \
|
||||
pk11akey.c \
|
||||
pk11auth.c \
|
||||
pk11cert.c \
|
||||
pk11cxt.c \
|
||||
pk11err.c \
|
||||
pk11kea.c \
|
||||
pk11list.c \
|
||||
pk11load.c \
|
||||
pk11mech.c \
|
||||
pk11merge.c \
|
||||
pk11nobj.c \
|
||||
pk11obj.c \
|
||||
pk11pars.c \
|
||||
pk11pbe.c \
|
||||
pk11pk12.c \
|
||||
pk11pqg.c \
|
||||
pk11sdr.c \
|
||||
pk11skey.c \
|
||||
pk11slot.c \
|
||||
pk11util.c \
|
||||
$(NULL)
|
||||
|
||||
LIBRARY_NAME = pk11wrap
|
||||
|
||||
LIBRARY_VERSION = 3
|
||||
SOFTOKEN_LIBRARY_VERSION = 3
|
||||
DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" \
|
||||
-DSHLIB_VERSION=\"$(LIBRARY_VERSION)\" \
|
||||
-DSOFTOKEN_SHLIB_VERSION=\"$(SOFTOKEN_LIBRARY_VERSION)\"
|
||||
|
||||
# only add module debugging in opt builds if DEBUG_PKCS11 is set
|
||||
ifdef DEBUG_PKCS11
|
||||
DEFINES += -DDEBUG_MODULE -DFORCE_PR_LOG
|
||||
endif
|
||||
|
||||
# This part of the code, including all sub-dirs, can be optimized for size
|
||||
export ALLOW_OPT_CODE_SIZE = 1
|
||||
2525
security/nss/lib/pk11wrap/pk11akey.c
Normal file
2525
security/nss/lib/pk11wrap/pk11akey.c
Normal file
File diff suppressed because it is too large
Load diff
807
security/nss/lib/pk11wrap/pk11auth.c
Normal file
807
security/nss/lib/pk11wrap/pk11auth.c
Normal file
|
|
@ -0,0 +1,807 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* This file deals with PKCS #11 passwords and authentication.
|
||||
*/
|
||||
#include "seccomon.h"
|
||||
#include "secmod.h"
|
||||
#include "secmodi.h"
|
||||
#include "secmodti.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "pk11func.h"
|
||||
#include "secitem.h"
|
||||
#include "secerr.h"
|
||||
|
||||
#include "pkim.h"
|
||||
|
||||
/*************************************************************
|
||||
* local static and global data
|
||||
*************************************************************/
|
||||
/*
|
||||
* This structure keeps track of status that spans all the Slots.
|
||||
* NOTE: This is a global data structure. It semantics expect thread crosstalk
|
||||
* be very careful when you see it used.
|
||||
* It's major purpose in life is to allow the user to log in one PER
|
||||
* Tranaction, even if a transaction spans threads. The problem is the user
|
||||
* may have to enter a password one just to be able to look at the
|
||||
* personalities/certificates (s)he can use. Then if Auth every is one, they
|
||||
* may have to enter the password again to use the card. See PK11_StartTransac
|
||||
* and PK11_EndTransaction.
|
||||
*/
|
||||
static struct PK11GlobalStruct {
|
||||
int transaction;
|
||||
PRBool inTransaction;
|
||||
char *(PR_CALLBACK *getPass)(PK11SlotInfo *, PRBool, void *);
|
||||
PRBool(PR_CALLBACK *verifyPass)(PK11SlotInfo *, void *);
|
||||
PRBool(PR_CALLBACK *isLoggedIn)(PK11SlotInfo *, void *);
|
||||
} PK11_Global = { 1, PR_FALSE, NULL, NULL, NULL };
|
||||
|
||||
/***********************************************************
|
||||
* Password Utilities
|
||||
***********************************************************/
|
||||
/*
|
||||
* Check the user's password. Log into the card if it's correct.
|
||||
* succeed if the user is already logged in.
|
||||
*/
|
||||
static SECStatus
|
||||
pk11_CheckPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
|
||||
char *pw, PRBool alreadyLocked, PRBool contextSpecific)
|
||||
{
|
||||
int len = 0;
|
||||
CK_RV crv;
|
||||
SECStatus rv;
|
||||
PRTime currtime = PR_Now();
|
||||
PRBool mustRetry;
|
||||
int retry = 0;
|
||||
|
||||
if (slot->protectedAuthPath) {
|
||||
len = 0;
|
||||
pw = NULL;
|
||||
} else if (pw == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
} else {
|
||||
len = PORT_Strlen(pw);
|
||||
}
|
||||
|
||||
do {
|
||||
if (!alreadyLocked)
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
crv = PK11_GETTAB(slot)->C_Login(session,
|
||||
contextSpecific ? CKU_CONTEXT_SPECIFIC : CKU_USER,
|
||||
(unsigned char *)pw, len);
|
||||
slot->lastLoginCheck = 0;
|
||||
mustRetry = PR_FALSE;
|
||||
if (!alreadyLocked)
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
switch (crv) {
|
||||
/* if we're already logged in, we're good to go */
|
||||
case CKR_OK:
|
||||
/* TODO If it was for CKU_CONTEXT_SPECIFIC should we do this */
|
||||
slot->authTransact = PK11_Global.transaction;
|
||||
/* Fall through */
|
||||
case CKR_USER_ALREADY_LOGGED_IN:
|
||||
slot->authTime = currtime;
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
case CKR_PIN_INCORRECT:
|
||||
PORT_SetError(SEC_ERROR_BAD_PASSWORD);
|
||||
rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
|
||||
break;
|
||||
/* someone called reset while we fetched the password, try again once
|
||||
* if the token is still there. */
|
||||
case CKR_SESSION_HANDLE_INVALID:
|
||||
case CKR_SESSION_CLOSED:
|
||||
if (session != slot->session) {
|
||||
/* don't bother retrying, we were in a middle of an operation,
|
||||
* which is now lost. Just fail. */
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
if (retry++ == 0) {
|
||||
rv = PK11_InitToken(slot, PR_FALSE);
|
||||
if (rv == SECSuccess) {
|
||||
if (slot->session != CK_INVALID_SESSION) {
|
||||
session = slot->session; /* we should have
|
||||
* a new session now */
|
||||
mustRetry = PR_TRUE;
|
||||
} else {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
rv = SECFailure;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
rv = SECFailure; /* some failure we can't fix by retrying */
|
||||
}
|
||||
} while (mustRetry);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the user's password. Logout before hand to make sure that
|
||||
* we are really checking the password.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_CheckUserPassword(PK11SlotInfo *slot, const char *pw)
|
||||
{
|
||||
int len = 0;
|
||||
CK_RV crv;
|
||||
SECStatus rv;
|
||||
PRTime currtime = PR_Now();
|
||||
|
||||
if (slot->protectedAuthPath) {
|
||||
len = 0;
|
||||
pw = NULL;
|
||||
} else if (pw == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
} else {
|
||||
len = PORT_Strlen(pw);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the token doesn't need a login, don't try to relogin because the
|
||||
* effect is undefined. It's not clear what it means to check a non-empty
|
||||
* password with such a token, so treat that as an error.
|
||||
*/
|
||||
if (!slot->needLogin) {
|
||||
if (len == 0) {
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
PORT_SetError(SEC_ERROR_BAD_PASSWORD);
|
||||
rv = SECFailure;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* force a logout */
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
PK11_GETTAB(slot)->C_Logout(slot->session);
|
||||
|
||||
crv = PK11_GETTAB(slot)->C_Login(slot->session, CKU_USER,
|
||||
(unsigned char *)pw, len);
|
||||
slot->lastLoginCheck = 0;
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
switch (crv) {
|
||||
/* if we're already logged in, we're good to go */
|
||||
case CKR_OK:
|
||||
slot->authTransact = PK11_Global.transaction;
|
||||
slot->authTime = currtime;
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
case CKR_PIN_INCORRECT:
|
||||
PORT_SetError(SEC_ERROR_BAD_PASSWORD);
|
||||
rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
rv = SECFailure; /* some failure we can't fix by retrying */
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_Logout(PK11SlotInfo *slot)
|
||||
{
|
||||
CK_RV crv;
|
||||
|
||||
/* force a logout */
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
crv = PK11_GETTAB(slot)->C_Logout(slot->session);
|
||||
slot->lastLoginCheck = 0;
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* transaction stuff is for when we test for the need to do every
|
||||
* time auth to see if we already did it for this slot/transaction
|
||||
*/
|
||||
void
|
||||
PK11_StartAuthTransaction(void)
|
||||
{
|
||||
PK11_Global.transaction++;
|
||||
PK11_Global.inTransaction = PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
PK11_EndAuthTransaction(void)
|
||||
{
|
||||
PK11_Global.transaction++;
|
||||
PK11_Global.inTransaction = PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* before we do a private key op, we check to see if we
|
||||
* need to reauthenticate.
|
||||
*/
|
||||
void
|
||||
PK11_HandlePasswordCheck(PK11SlotInfo *slot, void *wincx)
|
||||
{
|
||||
int askpw = slot->askpw;
|
||||
PRBool NeedAuth = PR_FALSE;
|
||||
|
||||
if (!slot->needLogin)
|
||||
return;
|
||||
|
||||
if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
|
||||
PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
|
||||
|
||||
if (def_slot) {
|
||||
askpw = def_slot->askpw;
|
||||
PK11_FreeSlot(def_slot);
|
||||
}
|
||||
}
|
||||
|
||||
/* timeouts are handled by isLoggedIn */
|
||||
if (!PK11_IsLoggedIn(slot, wincx)) {
|
||||
NeedAuth = PR_TRUE;
|
||||
} else if (askpw == -1) {
|
||||
if (!PK11_Global.inTransaction ||
|
||||
(PK11_Global.transaction != slot->authTransact)) {
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
PK11_GETTAB(slot)->C_Logout(slot->session);
|
||||
slot->lastLoginCheck = 0;
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
NeedAuth = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (NeedAuth)
|
||||
PK11_DoPassword(slot, slot->session, PR_TRUE,
|
||||
wincx, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
PK11_SlotDBUpdate(PK11SlotInfo *slot)
|
||||
{
|
||||
SECMOD_UpdateModule(slot->module);
|
||||
}
|
||||
|
||||
/*
|
||||
* set new askpw and timeout values
|
||||
*/
|
||||
void
|
||||
PK11_SetSlotPWValues(PK11SlotInfo *slot, int askpw, int timeout)
|
||||
{
|
||||
slot->askpw = askpw;
|
||||
slot->timeout = timeout;
|
||||
slot->defaultFlags |= PK11_OWN_PW_DEFAULTS;
|
||||
PK11_SlotDBUpdate(slot);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the askpw and timeout values for this slot
|
||||
*/
|
||||
void
|
||||
PK11_GetSlotPWValues(PK11SlotInfo *slot, int *askpw, int *timeout)
|
||||
{
|
||||
*askpw = slot->askpw;
|
||||
*timeout = slot->timeout;
|
||||
|
||||
if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
|
||||
PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
|
||||
|
||||
if (def_slot) {
|
||||
*askpw = def_slot->askpw;
|
||||
*timeout = def_slot->timeout;
|
||||
PK11_FreeSlot(def_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the token is needLogin and isn't logged in.
|
||||
* This function is used to determine if authentication is needed
|
||||
* before attempting a potentially privelleged operation.
|
||||
*/
|
||||
PRBool
|
||||
pk11_LoginStillRequired(PK11SlotInfo *slot, void *wincx)
|
||||
{
|
||||
return slot->needLogin && !PK11_IsLoggedIn(slot, wincx);
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure a slot is authenticated...
|
||||
* This function only does the authentication if it is needed.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
|
||||
{
|
||||
if (!slot) {
|
||||
return SECFailure;
|
||||
}
|
||||
if (pk11_LoginStillRequired(slot, wincx)) {
|
||||
return PK11_DoPassword(slot, slot->session, loadCerts, wincx,
|
||||
PR_FALSE, PR_FALSE);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticate to "unfriendly" tokens (tokens which need to be logged
|
||||
* in to find the certs.
|
||||
*/
|
||||
SECStatus
|
||||
pk11_AuthenticateUnfriendly(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
if (!PK11_IsFriendly(slot)) {
|
||||
rv = PK11_Authenticate(slot, loadCerts, wincx);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: this assumes that we are logged out of the card before hand
|
||||
*/
|
||||
SECStatus
|
||||
PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw)
|
||||
{
|
||||
CK_SESSION_HANDLE rwsession;
|
||||
CK_RV crv;
|
||||
SECStatus rv = SECFailure;
|
||||
int len = 0;
|
||||
|
||||
/* get a rwsession */
|
||||
rwsession = PK11_GetRWSession(slot);
|
||||
if (rwsession == CK_INVALID_SESSION) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (slot->protectedAuthPath) {
|
||||
len = 0;
|
||||
ssopw = NULL;
|
||||
} else if (ssopw == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
} else {
|
||||
len = PORT_Strlen(ssopw);
|
||||
}
|
||||
|
||||
/* check the password */
|
||||
crv = PK11_GETTAB(slot)->C_Login(rwsession, CKU_SO,
|
||||
(unsigned char *)ssopw, len);
|
||||
slot->lastLoginCheck = 0;
|
||||
switch (crv) {
|
||||
/* if we're already logged in, we're good to go */
|
||||
case CKR_OK:
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
case CKR_PIN_INCORRECT:
|
||||
PORT_SetError(SEC_ERROR_BAD_PASSWORD);
|
||||
rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
rv = SECFailure; /* some failure we can't fix by retrying */
|
||||
}
|
||||
PK11_GETTAB(slot)->C_Logout(rwsession);
|
||||
slot->lastLoginCheck = 0;
|
||||
|
||||
/* release rwsession */
|
||||
PK11_RestoreROSession(slot, rwsession);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure the password conforms to your token's requirements.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_VerifyPW(PK11SlotInfo *slot, char *pw)
|
||||
{
|
||||
int len = PORT_Strlen(pw);
|
||||
|
||||
if ((slot->minPassword > len) || (slot->maxPassword < len)) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize a user PIN Value
|
||||
*/
|
||||
SECStatus
|
||||
PK11_InitPin(PK11SlotInfo *slot, const char *ssopw, const char *userpw)
|
||||
{
|
||||
CK_SESSION_HANDLE rwsession = CK_INVALID_SESSION;
|
||||
CK_RV crv;
|
||||
SECStatus rv = SECFailure;
|
||||
int len;
|
||||
int ssolen;
|
||||
|
||||
if (userpw == NULL)
|
||||
userpw = "";
|
||||
if (ssopw == NULL)
|
||||
ssopw = "";
|
||||
|
||||
len = PORT_Strlen(userpw);
|
||||
ssolen = PORT_Strlen(ssopw);
|
||||
|
||||
/* get a rwsession */
|
||||
rwsession = PK11_GetRWSession(slot);
|
||||
if (rwsession == CK_INVALID_SESSION) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
slot->lastLoginCheck = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (slot->protectedAuthPath) {
|
||||
len = 0;
|
||||
ssolen = 0;
|
||||
ssopw = NULL;
|
||||
userpw = NULL;
|
||||
}
|
||||
|
||||
/* check the password */
|
||||
crv = PK11_GETTAB(slot)->C_Login(rwsession, CKU_SO,
|
||||
(unsigned char *)ssopw, ssolen);
|
||||
slot->lastLoginCheck = 0;
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
goto done;
|
||||
}
|
||||
|
||||
crv = PK11_GETTAB(slot)->C_InitPIN(rwsession, (unsigned char *)userpw, len);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
} else {
|
||||
rv = SECSuccess;
|
||||
}
|
||||
|
||||
done:
|
||||
PK11_GETTAB(slot)->C_Logout(rwsession);
|
||||
slot->lastLoginCheck = 0;
|
||||
PK11_RestoreROSession(slot, rwsession);
|
||||
if (rv == SECSuccess) {
|
||||
/* update our view of the world */
|
||||
PK11_InitToken(slot, PR_TRUE);
|
||||
if (slot->needLogin) {
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
PK11_GETTAB(slot)->C_Login(slot->session, CKU_USER,
|
||||
(unsigned char *)userpw, len);
|
||||
slot->lastLoginCheck = 0;
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change an existing user password
|
||||
*/
|
||||
SECStatus
|
||||
PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw, const char *newpw)
|
||||
{
|
||||
CK_RV crv;
|
||||
SECStatus rv = SECFailure;
|
||||
int newLen = 0;
|
||||
int oldLen = 0;
|
||||
CK_SESSION_HANDLE rwsession;
|
||||
|
||||
/* use NULL values to trigger the protected authentication path */
|
||||
if (!slot->protectedAuthPath) {
|
||||
if (newpw == NULL)
|
||||
newpw = "";
|
||||
if (oldpw == NULL)
|
||||
oldpw = "";
|
||||
}
|
||||
if (newpw)
|
||||
newLen = PORT_Strlen(newpw);
|
||||
if (oldpw)
|
||||
oldLen = PORT_Strlen(oldpw);
|
||||
|
||||
/* get a rwsession */
|
||||
rwsession = PK11_GetRWSession(slot);
|
||||
if (rwsession == CK_INVALID_SESSION) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return rv;
|
||||
}
|
||||
|
||||
crv = PK11_GETTAB(slot)->C_SetPIN(rwsession,
|
||||
(unsigned char *)oldpw, oldLen, (unsigned char *)newpw, newLen);
|
||||
if (crv == CKR_OK) {
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
}
|
||||
|
||||
PK11_RestoreROSession(slot, rwsession);
|
||||
|
||||
/* update our view of the world */
|
||||
PK11_InitToken(slot, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static char *
|
||||
pk11_GetPassword(PK11SlotInfo *slot, PRBool retry, void *wincx)
|
||||
{
|
||||
if (PK11_Global.getPass == NULL)
|
||||
return NULL;
|
||||
return (*PK11_Global.getPass)(slot, retry, wincx);
|
||||
}
|
||||
|
||||
void
|
||||
PK11_SetPasswordFunc(PK11PasswordFunc func)
|
||||
{
|
||||
PK11_Global.getPass = func;
|
||||
}
|
||||
|
||||
void
|
||||
PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func)
|
||||
{
|
||||
PK11_Global.verifyPass = func;
|
||||
}
|
||||
|
||||
void
|
||||
PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func)
|
||||
{
|
||||
PK11_Global.isLoggedIn = func;
|
||||
}
|
||||
|
||||
/*
|
||||
* authenticate to a slot. This loops until we can't recover, the user
|
||||
* gives up, or we succeed. If we're already logged in and this function
|
||||
* is called we will still prompt for a password, but we will probably
|
||||
* succeed no matter what the password was (depending on the implementation
|
||||
* of the PKCS 11 module.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
|
||||
PRBool loadCerts, void *wincx, PRBool alreadyLocked,
|
||||
PRBool contextSpecific)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
char *password;
|
||||
PRBool attempt = PR_FALSE;
|
||||
|
||||
if (PK11_NeedUserInit(slot)) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* Central server type applications which control access to multiple
|
||||
* slave applications to single crypto devices need to virtuallize the
|
||||
* login state. This is done by a callback out of PK11_IsLoggedIn and
|
||||
* here. If we are actually logged in, then we got here because the
|
||||
* higher level code told us that the particular client application may
|
||||
* still need to be logged in. If that is the case, we simply tell the
|
||||
* server code that it should now verify the clients password and tell us
|
||||
* the results.
|
||||
*/
|
||||
if (PK11_IsLoggedIn(slot, NULL) &&
|
||||
(PK11_Global.verifyPass != NULL)) {
|
||||
if (!PK11_Global.verifyPass(slot, wincx)) {
|
||||
PORT_SetError(SEC_ERROR_BAD_PASSWORD);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* get the password. This can drop out of the while loop
|
||||
* for the following reasons:
|
||||
* (1) the user refused to enter a password.
|
||||
* (return error to caller)
|
||||
* (2) the token user password is disabled [usually due to
|
||||
* too many failed authentication attempts].
|
||||
* (return error to caller)
|
||||
* (3) the password was successful.
|
||||
*/
|
||||
while ((password = pk11_GetPassword(slot, attempt, wincx)) != NULL) {
|
||||
/* if the token has a protectedAuthPath, the application may have
|
||||
* already issued the C_Login as part of it's pk11_GetPassword call.
|
||||
* In this case the application will tell us what the results were in
|
||||
* the password value (retry or the authentication was successful) so
|
||||
* we can skip our own C_Login call (which would force the token to
|
||||
* try to login again).
|
||||
*
|
||||
* Applications that don't know about protectedAuthPath will return a
|
||||
* password, which we will ignore and trigger the token to
|
||||
* 'authenticate' itself anyway. Hopefully the blinking display on
|
||||
* the reader, or the flashing light under the thumbprint reader will
|
||||
* attract the user's attention */
|
||||
attempt = PR_TRUE;
|
||||
if (slot->protectedAuthPath) {
|
||||
/* application tried to authenticate and failed. it wants to try
|
||||
* again, continue looping */
|
||||
if (strcmp(password, PK11_PW_RETRY) == 0) {
|
||||
rv = SECWouldBlock;
|
||||
PORT_Free(password);
|
||||
continue;
|
||||
}
|
||||
/* applicaton tried to authenticate and succeeded we're done */
|
||||
if (strcmp(password, PK11_PW_AUTHENTICATED) == 0) {
|
||||
rv = SECSuccess;
|
||||
PORT_Free(password);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rv = pk11_CheckPassword(slot, session, password,
|
||||
alreadyLocked, contextSpecific);
|
||||
PORT_Memset(password, 0, PORT_Strlen(password));
|
||||
PORT_Free(password);
|
||||
if (rv != SECWouldBlock)
|
||||
break;
|
||||
}
|
||||
if (rv == SECSuccess) {
|
||||
if (!PK11_IsFriendly(slot)) {
|
||||
nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
|
||||
slot->nssToken);
|
||||
}
|
||||
} else if (!attempt)
|
||||
PORT_SetError(SEC_ERROR_BAD_PASSWORD);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
PK11_LogoutAll(void)
|
||||
{
|
||||
SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
|
||||
SECMODModuleList *modList;
|
||||
SECMODModuleList *mlp = NULL;
|
||||
int i;
|
||||
|
||||
/* NSS is not initialized, there are not tokens to log out */
|
||||
if (lock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SECMOD_GetReadLock(lock);
|
||||
modList = SECMOD_GetDefaultModuleList();
|
||||
/* find the number of entries */
|
||||
for (mlp = modList; mlp != NULL; mlp = mlp->next) {
|
||||
for (i = 0; i < mlp->module->slotCount; i++) {
|
||||
PK11_Logout(mlp->module->slots[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SECMOD_ReleaseReadLock(lock);
|
||||
}
|
||||
|
||||
int
|
||||
PK11_GetMinimumPwdLength(PK11SlotInfo *slot)
|
||||
{
|
||||
return ((int)slot->minPassword);
|
||||
}
|
||||
|
||||
/* Does this slot have a protected pin path? */
|
||||
PRBool
|
||||
PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot)
|
||||
{
|
||||
return slot->protectedAuthPath;
|
||||
}
|
||||
|
||||
/*
|
||||
* we can initialize the password if 1) The toke is not inited
|
||||
* (need login == true and see need UserInit) or 2) the token has
|
||||
* a NULL password. (slot->needLogin = false & need user Init = false).
|
||||
*/
|
||||
PRBool
|
||||
PK11_NeedPWInitForSlot(PK11SlotInfo *slot)
|
||||
{
|
||||
if (slot->needLogin && PK11_NeedUserInit(slot)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (!slot->needLogin && !PK11_NeedUserInit(slot)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
PK11_NeedPWInit()
|
||||
{
|
||||
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
|
||||
PRBool ret = PK11_NeedPWInitForSlot(slot);
|
||||
|
||||
PK11_FreeSlot(slot);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PRBool
|
||||
pk11_InDelayPeriod(PRIntervalTime lastTime, PRIntervalTime delayTime,
|
||||
PRIntervalTime *retTime)
|
||||
{
|
||||
PRIntervalTime time;
|
||||
|
||||
*retTime = time = PR_IntervalNow();
|
||||
return (PRBool)(lastTime) && ((time - lastTime) < delayTime);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if the token is logged in. We have to actually query the token,
|
||||
* because it's state can change without intervention from us.
|
||||
*/
|
||||
PRBool
|
||||
PK11_IsLoggedIn(PK11SlotInfo *slot, void *wincx)
|
||||
{
|
||||
CK_SESSION_INFO sessionInfo;
|
||||
int askpw = slot->askpw;
|
||||
int timeout = slot->timeout;
|
||||
CK_RV crv;
|
||||
PRIntervalTime curTime;
|
||||
static PRIntervalTime login_delay_time = 0;
|
||||
|
||||
if (login_delay_time == 0) {
|
||||
login_delay_time = PR_SecondsToInterval(1);
|
||||
}
|
||||
|
||||
/* If we don't have our own password default values, use the system
|
||||
* ones */
|
||||
if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
|
||||
PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
|
||||
|
||||
if (def_slot) {
|
||||
askpw = def_slot->askpw;
|
||||
timeout = def_slot->timeout;
|
||||
PK11_FreeSlot(def_slot);
|
||||
}
|
||||
}
|
||||
|
||||
if ((wincx != NULL) && (PK11_Global.isLoggedIn != NULL) &&
|
||||
(*PK11_Global.isLoggedIn)(slot, wincx) == PR_FALSE) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* forget the password if we've been inactive too long */
|
||||
if (askpw == 1) {
|
||||
PRTime currtime = PR_Now();
|
||||
PRTime result;
|
||||
PRTime mult;
|
||||
|
||||
LL_I2L(result, timeout);
|
||||
LL_I2L(mult, 60 * 1000 * 1000);
|
||||
LL_MUL(result, result, mult);
|
||||
LL_ADD(result, result, slot->authTime);
|
||||
if (LL_CMP(result, <, currtime)) {
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
PK11_GETTAB(slot)->C_Logout(slot->session);
|
||||
slot->lastLoginCheck = 0;
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
} else {
|
||||
slot->authTime = currtime;
|
||||
}
|
||||
}
|
||||
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
if (pk11_InDelayPeriod(slot->lastLoginCheck, login_delay_time, &curTime)) {
|
||||
sessionInfo.state = slot->lastState;
|
||||
crv = CKR_OK;
|
||||
} else {
|
||||
crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session, &sessionInfo);
|
||||
if (crv == CKR_OK) {
|
||||
slot->lastState = sessionInfo.state;
|
||||
slot->lastLoginCheck = curTime;
|
||||
}
|
||||
}
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
/* if we can't get session info, something is really wrong */
|
||||
if (crv != CKR_OK) {
|
||||
slot->session = CK_INVALID_SESSION;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
switch (sessionInfo.state) {
|
||||
case CKS_RW_PUBLIC_SESSION:
|
||||
case CKS_RO_PUBLIC_SESSION:
|
||||
default:
|
||||
break; /* fail */
|
||||
case CKS_RW_USER_FUNCTIONS:
|
||||
case CKS_RW_SO_FUNCTIONS:
|
||||
case CKS_RO_USER_FUNCTIONS:
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
2744
security/nss/lib/pk11wrap/pk11cert.c
Normal file
2744
security/nss/lib/pk11wrap/pk11cert.c
Normal file
File diff suppressed because it is too large
Load diff
1019
security/nss/lib/pk11wrap/pk11cxt.c
Normal file
1019
security/nss/lib/pk11wrap/pk11cxt.c
Normal file
File diff suppressed because it is too large
Load diff
141
security/nss/lib/pk11wrap/pk11err.c
Normal file
141
security/nss/lib/pk11wrap/pk11err.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Some PKCS11 errors are mapped to SEC_ERROR_LIBRARY_FAILURE intentionally
|
||||
* because they indicate that there is a bug in the library (either NSS or
|
||||
* the token).
|
||||
*/
|
||||
#include "pkcs11t.h"
|
||||
#include "pk11func.h"
|
||||
#include "secerr.h"
|
||||
#include "prerror.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 */
|
||||
/* clang-format off */
|
||||
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_ARGUMENTS_BAD, SEC_ERROR_INVALID_ARGS)
|
||||
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_BUFFER_TOO_SMALL, SEC_ERROR_OUTPUT_LEN)
|
||||
MAPERROR(CKR_DATA_INVALID, SEC_ERROR_BAD_DATA)
|
||||
MAPERROR(CKR_DATA_LEN_RANGE, SEC_ERROR_INPUT_LEN)
|
||||
MAPERROR(CKR_DEVICE_ERROR, SEC_ERROR_PKCS11_DEVICE_ERROR)
|
||||
MAPERROR(CKR_DEVICE_MEMORY, SEC_ERROR_NO_MEMORY)
|
||||
MAPERROR(CKR_DEVICE_REMOVED, SEC_ERROR_NO_TOKEN)
|
||||
MAPERROR(CKR_DOMAIN_PARAMS_INVALID, SEC_ERROR_INVALID_KEY)
|
||||
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_FAILED, SEC_ERROR_PKCS11_FUNCTION_FAILED)
|
||||
MAPERROR(CKR_FUNCTION_NOT_PARALLEL, SEC_ERROR_LIBRARY_FAILURE)
|
||||
MAPERROR(CKR_FUNCTION_NOT_SUPPORTED, PR_NOT_IMPLEMENTED_ERROR)
|
||||
MAPERROR(CKR_GENERAL_ERROR, SEC_ERROR_PKCS11_GENERAL_ERROR)
|
||||
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_INVALID_ALGORITHM)
|
||||
MAPERROR(CKR_MECHANISM_PARAM_INVALID, SEC_ERROR_BAD_DATA)
|
||||
MAPERROR(CKR_NO_EVENT, SEC_ERROR_NO_EVENT)
|
||||
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_INVALID_PASSWORD)
|
||||
MAPERROR(CKR_PIN_LEN_RANGE, SEC_ERROR_INVALID_PASSWORD)
|
||||
MAPERROR(CKR_PIN_EXPIRED, SEC_ERROR_EXPIRED_PASSWORD)
|
||||
MAPERROR(CKR_PIN_LOCKED, SEC_ERROR_LOCKED_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_READ_ONLY)
|
||||
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_TOKEN_NOT_LOGGED_IN)
|
||||
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)
|
||||
MAPERROR(CKR_NETSCAPE_CERTDB_FAILED, SEC_ERROR_BAD_DATABASE)
|
||||
MAPERROR(CKR_NETSCAPE_KEYDB_FAILED, SEC_ERROR_BAD_DATABASE)
|
||||
MAPERROR(CKR_CANT_LOCK, SEC_ERROR_INCOMPATIBLE_PKCS11)
|
||||
/* clang-format on */
|
||||
|
||||
#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_UNKNOWN_PKCS11_ERROR;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* clang-format off */
|
||||
default :
|
||||
break;
|
||||
/* clang-format on */
|
||||
}
|
||||
return SEC_ERROR_UNKNOWN_PKCS11_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
15
security/nss/lib/pk11wrap/pk11func.h
Normal file
15
security/nss/lib/pk11wrap/pk11func.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _PK11FUNC_H_
|
||||
#define _PK11FUNC_H_
|
||||
|
||||
/*
|
||||
* The original pk11func.h had a mix of public and private functions.
|
||||
* Continue to provide those for backward compatibility. New code should
|
||||
* include pk11pub.h instead of pk11func.h.
|
||||
*/
|
||||
#include "pk11pub.h"
|
||||
#include "pk11priv.h"
|
||||
|
||||
#endif
|
||||
140
security/nss/lib/pk11wrap/pk11kea.c
Normal file
140
security/nss/lib/pk11wrap/pk11kea.c
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* This file implements the Symkey wrapper and the PKCS context
|
||||
* Interfaces.
|
||||
*/
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secmod.h"
|
||||
#include "nssilock.h"
|
||||
#include "secmodi.h"
|
||||
#include "secmodti.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);
|
||||
}
|
||||
|
||||
PK11SymKey *
|
||||
pk11_KeyExchange(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags,
|
||||
PRBool isPerm, PK11SymKey *symKey)
|
||||
{
|
||||
PK11SymKey *newSymKey = NULL;
|
||||
SECStatus rv;
|
||||
/* performance improvement can go here --- use a generated key at startup
|
||||
* to generate a per token 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_HANDLE;
|
||||
CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_HANDLE;
|
||||
SECKEYPublicKey *pubKey = NULL;
|
||||
SECKEYPrivateKey *privKey = NULL;
|
||||
SECItem wrapData;
|
||||
unsigned int symKeyLength = PK11_GetKeyLength(symKey);
|
||||
|
||||
wrapData.data = NULL;
|
||||
|
||||
/* find RSA Public Key on target */
|
||||
pubKeyHandle = pk11_FindRSAPubKey(slot);
|
||||
if (pubKeyHandle != CK_INVALID_HANDLE) {
|
||||
privKeyHandle = PK11_MatchItem(slot, pubKeyHandle, CKO_PRIVATE_KEY);
|
||||
}
|
||||
|
||||
/* if no key exists, generate a key pair */
|
||||
if (privKeyHandle == CK_INVALID_HANDLE) {
|
||||
PK11RSAGenParams rsaParams;
|
||||
|
||||
if (symKeyLength > 53) /* bytes */ {
|
||||
/* we'd have to generate an RSA key pair > 512 bits long,
|
||||
** and that's too costly. Don't even try.
|
||||
*/
|
||||
PORT_SetError(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY);
|
||||
goto rsa_failed;
|
||||
}
|
||||
rsaParams.keySizeInBits =
|
||||
(symKeyLength > 21 || symKeyLength == 0) ? 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 keys 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_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
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_PubUnwrapSymKeyWithFlagsPerm(privKey,
|
||||
&wrapData, type, operation,
|
||||
symKeyLength, flags, isPerm);
|
||||
/* make sure we wound up where we wanted to be! */
|
||||
if (newSymKey && newSymKey->slot != slot) {
|
||||
PK11_FreeSymKey(newSymKey);
|
||||
newSymKey = NULL;
|
||||
}
|
||||
}
|
||||
rsa_failed:
|
||||
if (wrapData.data != NULL)
|
||||
PORT_Free(wrapData.data);
|
||||
if (privKey != NULL)
|
||||
SECKEY_DestroyPrivateKey(privKey);
|
||||
if (pubKey != NULL)
|
||||
SECKEY_DestroyPublicKey(pubKey);
|
||||
|
||||
return newSymKey;
|
||||
}
|
||||
PORT_SetError(SEC_ERROR_NO_MODULE);
|
||||
return NULL;
|
||||
}
|
||||
99
security/nss/lib/pk11wrap/pk11list.c
Normal file
99
security/nss/lib/pk11wrap/pk11list.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* Locking and queue management primatives
|
||||
*
|
||||
*/
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "nssilock.h"
|
||||
#include "secmod.h"
|
||||
#include "secmodi.h"
|
||||
#include "secmodti.h"
|
||||
#include "nssrwlk.h"
|
||||
|
||||
/*
|
||||
* create a new lock for a Module List
|
||||
*/
|
||||
SECMODListLock *
|
||||
SECMOD_NewListLock()
|
||||
{
|
||||
return NSSRWLock_New(10, "moduleListLock");
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy the lock
|
||||
*/
|
||||
void
|
||||
SECMOD_DestroyListLock(SECMODListLock *lock)
|
||||
{
|
||||
NSSRWLock_Destroy(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)
|
||||
{
|
||||
NSSRWLock_LockRead(modLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the Read lock
|
||||
*/
|
||||
void
|
||||
SECMOD_ReleaseReadLock(SECMODListLock *modLock)
|
||||
{
|
||||
NSSRWLock_UnlockRead(modLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* lock the list for Write
|
||||
*/
|
||||
void
|
||||
SECMOD_GetWriteLock(SECMODListLock *modLock)
|
||||
{
|
||||
NSSRWLock_LockWrite(modLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the Write Lock: NOTE, this code is pretty inefficient if you have
|
||||
* lots of write collisions.
|
||||
*/
|
||||
void
|
||||
SECMOD_ReleaseWriteLock(SECMODListLock *modLock)
|
||||
{
|
||||
NSSRWLock_UnlockWrite(modLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
643
security/nss/lib/pk11wrap/pk11load.c
Normal file
643
security/nss/lib/pk11wrap/pk11load.c
Normal file
|
|
@ -0,0 +1,643 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* The following handles the loading, unloading and management of
|
||||
* various PCKS #11 modules
|
||||
*/
|
||||
#define FORCE_PR_LOG 1
|
||||
#include "seccomon.h"
|
||||
#include "pkcs11.h"
|
||||
#include "secmod.h"
|
||||
#include "prlink.h"
|
||||
#include "pk11func.h"
|
||||
#include "secmodi.h"
|
||||
#include "secmodti.h"
|
||||
#include "nssilock.h"
|
||||
#include "secerr.h"
|
||||
#include "prenv.h"
|
||||
#include "utilparst.h"
|
||||
|
||||
#define DEBUG_MODULE 1
|
||||
|
||||
#ifdef DEBUG_MODULE
|
||||
static char *modToDBG = NULL;
|
||||
|
||||
#include "debug_module.c"
|
||||
#endif
|
||||
|
||||
/* build the PKCS #11 2.01 lock files */
|
||||
CK_RV PR_CALLBACK
|
||||
secmodCreateMutext(CK_VOID_PTR_PTR pmutex)
|
||||
{
|
||||
*pmutex = (CK_VOID_PTR)PZ_NewLock(nssILockOther);
|
||||
if (*pmutex)
|
||||
return CKR_OK;
|
||||
return CKR_HOST_MEMORY;
|
||||
}
|
||||
|
||||
CK_RV PR_CALLBACK
|
||||
secmodDestroyMutext(CK_VOID_PTR mutext)
|
||||
{
|
||||
PZ_DestroyLock((PZLock *)mutext);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV PR_CALLBACK
|
||||
secmodLockMutext(CK_VOID_PTR mutext)
|
||||
{
|
||||
PZ_Lock((PZLock *)mutext);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV PR_CALLBACK
|
||||
secmodUnlockMutext(CK_VOID_PTR mutext)
|
||||
{
|
||||
PZ_Unlock((PZLock *)mutext);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static SECMODModuleID nextModuleID = 1;
|
||||
static const CK_C_INITIALIZE_ARGS secmodLockFunctions = {
|
||||
secmodCreateMutext, secmodDestroyMutext, secmodLockMutext,
|
||||
secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS |
|
||||
CKF_OS_LOCKING_OK,
|
||||
NULL
|
||||
};
|
||||
static const CK_C_INITIALIZE_ARGS secmodNoLockArgs = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
CKF_LIBRARY_CANT_CREATE_OS_THREADS, NULL
|
||||
};
|
||||
|
||||
static PRBool loadSingleThreadedModules = PR_TRUE;
|
||||
static PRBool enforceAlreadyInitializedError = PR_TRUE;
|
||||
static PRBool finalizeModules = PR_TRUE;
|
||||
|
||||
/* set global options for NSS PKCS#11 module loader */
|
||||
SECStatus
|
||||
pk11_setGlobalOptions(PRBool noSingleThreadedModules,
|
||||
PRBool allowAlreadyInitializedModules,
|
||||
PRBool dontFinalizeModules)
|
||||
{
|
||||
if (noSingleThreadedModules) {
|
||||
loadSingleThreadedModules = PR_FALSE;
|
||||
} else {
|
||||
loadSingleThreadedModules = PR_TRUE;
|
||||
}
|
||||
if (allowAlreadyInitializedModules) {
|
||||
enforceAlreadyInitializedError = PR_FALSE;
|
||||
} else {
|
||||
enforceAlreadyInitializedError = PR_TRUE;
|
||||
}
|
||||
if (dontFinalizeModules) {
|
||||
finalizeModules = PR_FALSE;
|
||||
} else {
|
||||
finalizeModules = PR_TRUE;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
PRBool
|
||||
pk11_getFinalizeModulesOption(void)
|
||||
{
|
||||
return finalizeModules;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow specification loading the same module more than once at init time.
|
||||
* This enables 2 things.
|
||||
*
|
||||
* 1) we can load additional databases by manipulating secmod.db/pkcs11.txt.
|
||||
* 2) we can handle the case where some library has already initialized NSS
|
||||
* before the main application.
|
||||
*
|
||||
* oldModule is the module we have already initialized.
|
||||
* char *modulespec is the full module spec for the library we want to
|
||||
* initialize.
|
||||
*/
|
||||
static SECStatus
|
||||
secmod_handleReload(SECMODModule *oldModule, SECMODModule *newModule)
|
||||
{
|
||||
PK11SlotInfo *slot;
|
||||
char *modulespec;
|
||||
char *newModuleSpec;
|
||||
char **children;
|
||||
CK_SLOT_ID *ids;
|
||||
SECMODConfigList *conflist = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
int count = 0;
|
||||
|
||||
/* first look for tokens= key words from the module spec */
|
||||
modulespec = newModule->libraryParams;
|
||||
newModuleSpec = secmod_ParseModuleSpecForTokens(PR_TRUE,
|
||||
newModule->isFIPS, modulespec, &children, &ids);
|
||||
if (!newModuleSpec) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are now trying to open a new slot on an already loaded module.
|
||||
* If that slot represents a cert/key database, we don't want to open
|
||||
* multiple copies of that same database. Unfortunately we understand
|
||||
* the softoken flags well enough to be able to do this, so we can only get
|
||||
* the list of already loaded databases if we are trying to open another
|
||||
* internal module.
|
||||
*/
|
||||
if (oldModule->internal) {
|
||||
conflist = secmod_GetConfigList(oldModule->isFIPS,
|
||||
oldModule->libraryParams, &count);
|
||||
}
|
||||
|
||||
/* don't open multiple of the same db */
|
||||
if (conflist && secmod_MatchConfigList(newModuleSpec, conflist, count)) {
|
||||
rv = SECSuccess;
|
||||
goto loser;
|
||||
}
|
||||
slot = SECMOD_OpenNewSlot(oldModule, newModuleSpec);
|
||||
if (slot) {
|
||||
int newID;
|
||||
char **thisChild;
|
||||
CK_SLOT_ID *thisID;
|
||||
char *oldModuleSpec;
|
||||
|
||||
if (secmod_IsInternalKeySlot(newModule)) {
|
||||
pk11_SetInternalKeySlotIfFirst(slot);
|
||||
}
|
||||
newID = slot->slotID;
|
||||
PK11_FreeSlot(slot);
|
||||
for (thisChild = children, thisID = ids; thisChild && *thisChild;
|
||||
thisChild++, thisID++) {
|
||||
if (conflist &&
|
||||
secmod_MatchConfigList(*thisChild, conflist, count)) {
|
||||
*thisID = (CK_SLOT_ID)-1;
|
||||
continue;
|
||||
}
|
||||
slot = SECMOD_OpenNewSlot(oldModule, *thisChild);
|
||||
if (slot) {
|
||||
*thisID = slot->slotID;
|
||||
PK11_FreeSlot(slot);
|
||||
} else {
|
||||
*thisID = (CK_SLOT_ID)-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* update the old module initialization string in case we need to
|
||||
* shutdown and reinit the whole mess (this is rare, but can happen
|
||||
* when trying to stop smart card insertion/removal threads)... */
|
||||
oldModuleSpec = secmod_MkAppendTokensList(oldModule->arena,
|
||||
oldModule->libraryParams, newModuleSpec, newID,
|
||||
children, ids);
|
||||
if (oldModuleSpec) {
|
||||
oldModule->libraryParams = oldModuleSpec;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
secmod_FreeChildren(children, ids);
|
||||
PORT_Free(newModuleSpec);
|
||||
if (conflist) {
|
||||
secmod_FreeConfigList(conflist, count);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* collect the steps we need to initialize a module in a single function
|
||||
*/
|
||||
SECStatus
|
||||
secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
|
||||
PRBool *alreadyLoaded)
|
||||
{
|
||||
CK_C_INITIALIZE_ARGS moduleArgs;
|
||||
CK_VOID_PTR pInitArgs;
|
||||
CK_RV crv;
|
||||
|
||||
if (reload) {
|
||||
*reload = NULL;
|
||||
}
|
||||
|
||||
if (!mod || !alreadyLoaded) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (mod->libraryParams == NULL) {
|
||||
if (mod->isThreadSafe) {
|
||||
pInitArgs = (void *)&secmodLockFunctions;
|
||||
} else {
|
||||
pInitArgs = NULL;
|
||||
}
|
||||
} else {
|
||||
if (mod->isThreadSafe) {
|
||||
moduleArgs = secmodLockFunctions;
|
||||
} else {
|
||||
moduleArgs = secmodNoLockArgs;
|
||||
}
|
||||
moduleArgs.LibraryParameters = (void *)mod->libraryParams;
|
||||
pInitArgs = &moduleArgs;
|
||||
}
|
||||
crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
|
||||
if (CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) {
|
||||
SECMODModule *oldModule = NULL;
|
||||
|
||||
/* Library has already been loaded once, if caller expects it, and it
|
||||
* has additional configuration, try reloading it as well. */
|
||||
if (reload != NULL && mod->libraryParams) {
|
||||
oldModule = secmod_FindModuleByFuncPtr(mod->functionList);
|
||||
}
|
||||
/* Library has been loaded by NSS. It means it may be capable of
|
||||
* reloading */
|
||||
if (oldModule) {
|
||||
SECStatus rv;
|
||||
rv = secmod_handleReload(oldModule, mod);
|
||||
if (rv == SECSuccess) {
|
||||
/* This module should go away soon, since we've
|
||||
* simply expanded the slots on the old module.
|
||||
* When it goes away, it should not Finalize since
|
||||
* that will close our old module as well. Setting
|
||||
* the function list to NULL will prevent that close */
|
||||
mod->functionList = NULL;
|
||||
*reload = oldModule;
|
||||
return SECSuccess;
|
||||
}
|
||||
SECMOD_DestroyModule(oldModule);
|
||||
}
|
||||
/* reload not possible, fall back to old semantics */
|
||||
if (!enforceAlreadyInitializedError) {
|
||||
*alreadyLoaded = PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
if (crv != CKR_OK) {
|
||||
if (!mod->isThreadSafe ||
|
||||
crv == CKR_NETSCAPE_CERTDB_FAILED ||
|
||||
crv == CKR_NETSCAPE_KEYDB_FAILED) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return SECFailure;
|
||||
}
|
||||
/* If we had attempted to init a single threaded module "with"
|
||||
* parameters and it failed, should we retry "without" parameters?
|
||||
* (currently we don't retry in this scenario) */
|
||||
|
||||
if (!loadSingleThreadedModules) {
|
||||
PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
|
||||
return SECFailure;
|
||||
}
|
||||
/* If we arrive here, the module failed a ThreadSafe init. */
|
||||
mod->isThreadSafe = PR_FALSE;
|
||||
if (!mod->libraryParams) {
|
||||
pInitArgs = NULL;
|
||||
} else {
|
||||
moduleArgs = secmodNoLockArgs;
|
||||
moduleArgs.LibraryParameters = (void *)mod->libraryParams;
|
||||
pInitArgs = &moduleArgs;
|
||||
}
|
||||
crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
|
||||
if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
|
||||
(!enforceAlreadyInitializedError)) {
|
||||
*alreadyLoaded = PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* set the hasRootCerts flags in the module so it can be stored back
|
||||
* into the database.
|
||||
*/
|
||||
void
|
||||
SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod)
|
||||
{
|
||||
PK11PreSlotInfo *psi = NULL;
|
||||
int i;
|
||||
|
||||
if (slot->hasRootCerts) {
|
||||
for (i = 0; i < mod->slotInfoCount; i++) {
|
||||
if (slot->slotID == mod->slotInfo[i].slotID) {
|
||||
psi = &mod->slotInfo[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (psi == NULL) {
|
||||
/* allocate more slots */
|
||||
PK11PreSlotInfo *psi_list = (PK11PreSlotInfo *)
|
||||
PORT_ArenaAlloc(mod->arena,
|
||||
(mod->slotInfoCount + 1) * sizeof(PK11PreSlotInfo));
|
||||
/* copy the old ones */
|
||||
if (mod->slotInfoCount > 0) {
|
||||
PORT_Memcpy(psi_list, mod->slotInfo,
|
||||
(mod->slotInfoCount) * sizeof(PK11PreSlotInfo));
|
||||
}
|
||||
/* assign psi to the last new slot */
|
||||
psi = &psi_list[mod->slotInfoCount];
|
||||
psi->slotID = slot->slotID;
|
||||
psi->askpw = 0;
|
||||
psi->timeout = 0;
|
||||
psi->defaultFlags = 0;
|
||||
|
||||
/* increment module count & store new list */
|
||||
mod->slotInfo = psi_list;
|
||||
mod->slotInfoCount++;
|
||||
}
|
||||
psi->hasRootCerts = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *my_shlib_name =
|
||||
SHLIB_PREFIX "nss" SHLIB_VERSION "." SHLIB_SUFFIX;
|
||||
static const char *softoken_shlib_name =
|
||||
SHLIB_PREFIX "softokn" SOFTOKEN_SHLIB_VERSION "." SHLIB_SUFFIX;
|
||||
static const PRCallOnceType pristineCallOnce;
|
||||
static PRCallOnceType loadSoftokenOnce;
|
||||
static PRLibrary *softokenLib;
|
||||
static PRInt32 softokenLoadCount;
|
||||
|
||||
#include "prio.h"
|
||||
#include "prprf.h"
|
||||
#include <stdio.h>
|
||||
#include "prsystem.h"
|
||||
|
||||
/* This function must be run only once. */
|
||||
/* determine if hybrid platform, then actually load the DSO. */
|
||||
static PRStatus
|
||||
softoken_LoadDSO(void)
|
||||
{
|
||||
PRLibrary *handle;
|
||||
|
||||
handle = PORT_LoadLibraryFromOrigin(my_shlib_name,
|
||||
(PRFuncPtr)&softoken_LoadDSO,
|
||||
softoken_shlib_name);
|
||||
if (handle) {
|
||||
softokenLib = handle;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* load a new module into our address space and initialize it.
|
||||
*/
|
||||
SECStatus
|
||||
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
||||
{
|
||||
PRLibrary *library = NULL;
|
||||
CK_C_GetFunctionList entry = NULL;
|
||||
CK_INFO info;
|
||||
CK_ULONG slotCount = 0;
|
||||
SECStatus rv;
|
||||
PRBool alreadyLoaded = PR_FALSE;
|
||||
char *disableUnload = NULL;
|
||||
|
||||
if (mod->loaded)
|
||||
return SECSuccess;
|
||||
|
||||
/* intenal modules get loaded from their internal list */
|
||||
if (mod->internal && (mod->dllName == NULL)) {
|
||||
/*
|
||||
* Loads softoken as a dynamic library,
|
||||
* even though the rest of NSS assumes this as the "internal" module.
|
||||
*/
|
||||
if (!softokenLib &&
|
||||
PR_SUCCESS != PR_CallOnce(&loadSoftokenOnce, &softoken_LoadDSO))
|
||||
return SECFailure;
|
||||
|
||||
PR_ATOMIC_INCREMENT(&softokenLoadCount);
|
||||
|
||||
if (mod->isFIPS) {
|
||||
entry = (CK_C_GetFunctionList)
|
||||
PR_FindSymbol(softokenLib, "FC_GetFunctionList");
|
||||
} else {
|
||||
entry = (CK_C_GetFunctionList)
|
||||
PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
|
||||
}
|
||||
|
||||
if (!entry)
|
||||
return SECFailure;
|
||||
|
||||
if (mod->isModuleDB) {
|
||||
mod->moduleDBFunc = (CK_C_GetFunctionList)
|
||||
PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
|
||||
}
|
||||
|
||||
if (mod->moduleDBOnly) {
|
||||
mod->loaded = PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
} else {
|
||||
/* Not internal, load the DLL and look up C_GetFunctionList */
|
||||
if (mod->dllName == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* 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(mod->dllName);
|
||||
mod->library = (void *)library;
|
||||
|
||||
if (library == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* now we need to get the entry point to find the function pointers
|
||||
*/
|
||||
if (!mod->moduleDBOnly) {
|
||||
entry = (CK_C_GetFunctionList)
|
||||
PR_FindSymbol(library, "C_GetFunctionList");
|
||||
}
|
||||
if (mod->isModuleDB) {
|
||||
mod->moduleDBFunc = (void *)
|
||||
PR_FindSymbol(library, "NSS_ReturnModuleSpecData");
|
||||
}
|
||||
if (mod->moduleDBFunc == NULL)
|
||||
mod->isModuleDB = PR_FALSE;
|
||||
if (entry == NULL) {
|
||||
if (mod->isModuleDB) {
|
||||
mod->loaded = PR_TRUE;
|
||||
mod->moduleDBOnly = PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
PR_UnloadLibrary(library);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to get the function list
|
||||
*/
|
||||
if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
|
||||
goto fail;
|
||||
|
||||
#ifdef DEBUG_MODULE
|
||||
if (PR_TRUE) {
|
||||
modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
|
||||
if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
|
||||
mod->functionList = (void *)nss_InsertDeviceLog(
|
||||
(CK_FUNCTION_LIST_PTR)mod->functionList);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mod->isThreadSafe = PR_TRUE;
|
||||
|
||||
/* Now we initialize the module */
|
||||
rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
|
||||
if (rv != SECSuccess) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* module has been reloaded, this module itself is done,
|
||||
* return to the caller */
|
||||
if (mod->functionList == NULL) {
|
||||
mod->loaded = PR_TRUE; /* technically the module is loaded.. */
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
if (!loadSingleThreadedModules) {
|
||||
PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
|
||||
goto fail2;
|
||||
} else {
|
||||
mod->isThreadSafe = PR_FALSE;
|
||||
}
|
||||
}
|
||||
mod->cryptokiVersion = info.cryptokiVersion;
|
||||
|
||||
/* 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 crv;
|
||||
|
||||
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;
|
||||
}
|
||||
crv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_Free(slotIDs);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
/* Initialize each slot */
|
||||
for (i = 0; i < (int)slotCount; i++) {
|
||||
mod->slots[i] = PK11_NewSlotInfo(mod);
|
||||
PK11_InitSlot(mod, slotIDs[i], mod->slots[i]);
|
||||
/* look down the slot info table */
|
||||
PK11_LoadSlotList(mod->slots[i], mod->slotInfo, mod->slotInfoCount);
|
||||
SECMOD_SetRootCerts(mod->slots[i], mod);
|
||||
/* explicitly mark the internal slot as such if IsInternalKeySlot()
|
||||
* is set */
|
||||
if (secmod_IsInternalKeySlot(mod) && (i == (mod->isFIPS ? 0 : 1))) {
|
||||
pk11_SetInternalKeySlotIfFirst(mod->slots[i]);
|
||||
}
|
||||
}
|
||||
mod->slotCount = slotCount;
|
||||
mod->slotInfoCount = 0;
|
||||
PORT_Free(slotIDs);
|
||||
}
|
||||
|
||||
mod->loaded = PR_TRUE;
|
||||
mod->moduleID = nextModuleID++;
|
||||
return SECSuccess;
|
||||
fail2:
|
||||
if (enforceAlreadyInitializedError || (!alreadyLoaded)) {
|
||||
PK11_GETTAB(mod)->C_Finalize(NULL);
|
||||
}
|
||||
fail:
|
||||
mod->functionList = NULL;
|
||||
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
||||
if (library && !disableUnload) {
|
||||
PR_UnloadLibrary(library);
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SECMOD_UnloadModule(SECMODModule *mod)
|
||||
{
|
||||
PRLibrary *library;
|
||||
char *disableUnload = NULL;
|
||||
|
||||
if (!mod->loaded) {
|
||||
return SECFailure;
|
||||
}
|
||||
if (finalizeModules) {
|
||||
if (mod->functionList && !mod->moduleDBOnly) {
|
||||
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 && (mod->dllName == NULL)) {
|
||||
if (0 == PR_ATOMIC_DECREMENT(&softokenLoadCount)) {
|
||||
if (softokenLib) {
|
||||
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
||||
if (!disableUnload) {
|
||||
#ifdef DEBUG
|
||||
PRStatus status = PR_UnloadLibrary(softokenLib);
|
||||
PORT_Assert(PR_SUCCESS == status);
|
||||
#else
|
||||
PR_UnloadLibrary(softokenLib);
|
||||
#endif
|
||||
}
|
||||
softokenLib = NULL;
|
||||
}
|
||||
loadSoftokenOnce = pristineCallOnce;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
library = (PRLibrary *)mod->library;
|
||||
/* paranoia */
|
||||
if (library == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
||||
if (!disableUnload) {
|
||||
PR_UnloadLibrary(library);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
nss_DumpModuleLog(void)
|
||||
{
|
||||
#ifdef DEBUG_MODULE
|
||||
if (modToDBG) {
|
||||
print_final_statistics();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
1913
security/nss/lib/pk11wrap/pk11mech.c
Normal file
1913
security/nss/lib/pk11wrap/pk11mech.c
Normal file
File diff suppressed because it is too large
Load diff
1432
security/nss/lib/pk11wrap/pk11merge.c
Normal file
1432
security/nss/lib/pk11wrap/pk11merge.c
Normal file
File diff suppressed because it is too large
Load diff
791
security/nss/lib/pk11wrap/pk11nobj.c
Normal file
791
security/nss/lib/pk11wrap/pk11nobj.c
Normal file
|
|
@ -0,0 +1,791 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* This file manages Netscape specific PKCS #11 objects (CRLs, Trust objects,
|
||||
* etc).
|
||||
*/
|
||||
|
||||
#include "secport.h"
|
||||
#include "seccomon.h"
|
||||
#include "secmod.h"
|
||||
#include "secmodi.h"
|
||||
#include "secmodti.h"
|
||||
#include "pkcs11.h"
|
||||
#include "pk11func.h"
|
||||
#include "cert.h"
|
||||
#include "certi.h"
|
||||
#include "secitem.h"
|
||||
#include "sechash.h"
|
||||
#include "secoid.h"
|
||||
|
||||
#include "certdb.h"
|
||||
#include "secerr.h"
|
||||
|
||||
#include "pki3hack.h"
|
||||
#include "dev3hack.h"
|
||||
|
||||
#include "devm.h"
|
||||
#include "pki.h"
|
||||
#include "pkim.h"
|
||||
|
||||
extern const NSSError NSS_ERROR_NOT_FOUND;
|
||||
|
||||
CK_TRUST
|
||||
pk11_GetTrustField(PK11SlotInfo *slot, PLArenaPool *arena,
|
||||
CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type)
|
||||
{
|
||||
CK_TRUST rv = 0;
|
||||
SECItem item;
|
||||
|
||||
item.data = NULL;
|
||||
item.len = 0;
|
||||
|
||||
if (SECSuccess == PK11_ReadAttribute(slot, id, type, arena, &item)) {
|
||||
PORT_Assert(item.len == sizeof(CK_TRUST));
|
||||
PORT_Memcpy(&rv, item.data, sizeof(CK_TRUST));
|
||||
/* Damn, is there an endian problem here? */
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRBool
|
||||
pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust *trust)
|
||||
{
|
||||
PLArenaPool *arena;
|
||||
|
||||
CK_ATTRIBUTE tobjTemplate[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_CERT_SHA1_HASH, NULL, 0 },
|
||||
};
|
||||
|
||||
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
|
||||
CK_OBJECT_HANDLE tobjID;
|
||||
unsigned char sha1_hash[SHA1_LENGTH];
|
||||
|
||||
CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;
|
||||
|
||||
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);
|
||||
|
||||
PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc));
|
||||
PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash,
|
||||
SHA1_LENGTH);
|
||||
|
||||
tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
|
||||
sizeof(tobjTemplate) / sizeof(tobjTemplate[0]));
|
||||
if (CK_INVALID_HANDLE == tobjID) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (NULL == arena)
|
||||
return PR_FALSE;
|
||||
|
||||
/* Unfortunately, it seems that PK11_GetAttributes doesn't deal
|
||||
* well with nonexistent attributes. I guess we have to check
|
||||
* the trust info fields one at a time.
|
||||
*/
|
||||
|
||||
/* We could verify CKA_CERT_HASH here */
|
||||
|
||||
/* We could verify CKA_EXPIRES here */
|
||||
|
||||
/* "Purpose" trust information */
|
||||
serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
|
||||
clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH);
|
||||
codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
|
||||
emailProtection = pk11_GetTrustField(slot, arena, tobjID,
|
||||
CKA_TRUST_EMAIL_PROTECTION);
|
||||
/* Here's where the fun logic happens. We have to map back from the
|
||||
* key usage, extended key usage, purpose, and possibly other trust values
|
||||
* into the old trust-flags bits. */
|
||||
|
||||
/* First implementation: keep it simple for testing. We can study what other
|
||||
* mappings would be appropriate and add them later.. fgmr 20000724 */
|
||||
|
||||
if (serverAuth == CKT_NSS_TRUSTED) {
|
||||
trust->sslFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
|
||||
}
|
||||
|
||||
if (serverAuth == CKT_NSS_TRUSTED_DELEGATOR) {
|
||||
trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
|
||||
CERTDB_NS_TRUSTED_CA;
|
||||
}
|
||||
if (clientAuth == CKT_NSS_TRUSTED_DELEGATOR) {
|
||||
trust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA;
|
||||
}
|
||||
|
||||
if (emailProtection == CKT_NSS_TRUSTED) {
|
||||
trust->emailFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
|
||||
}
|
||||
|
||||
if (emailProtection == CKT_NSS_TRUSTED_DELEGATOR) {
|
||||
trust->emailFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
|
||||
}
|
||||
|
||||
if (codeSigning == CKT_NSS_TRUSTED) {
|
||||
trust->objectSigningFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
|
||||
}
|
||||
|
||||
if (codeSigning == CKT_NSS_TRUSTED_DELEGATOR) {
|
||||
trust->objectSigningFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
|
||||
}
|
||||
|
||||
/* There's certainly a lot more logic that can go here.. */
|
||||
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
|
||||
{
|
||||
SECItem derCrl;
|
||||
CERTCrlHeadNode *head = (CERTCrlHeadNode *)arg;
|
||||
CERTCrlNode *new_node = NULL;
|
||||
CK_ATTRIBUTE fetchCrl[3] = {
|
||||
{ CKA_VALUE, NULL, 0 },
|
||||
{ CKA_NETSCAPE_KRL, NULL, 0 },
|
||||
{ CKA_NETSCAPE_URL, NULL, 0 },
|
||||
};
|
||||
const int fetchCrlSize = sizeof(fetchCrl) / sizeof(fetchCrl[2]);
|
||||
CK_RV crv;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
crv = PK11_GetAttributes(head->arena, slot, crlID, fetchCrl, fetchCrlSize);
|
||||
if (CKR_OK != crv) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (!fetchCrl[1].pValue) {
|
||||
PORT_SetError(SEC_ERROR_CRL_INVALID);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
|
||||
if (new_node == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (*((CK_BBOOL *)fetchCrl[1].pValue))
|
||||
new_node->type = SEC_KRL_TYPE;
|
||||
else
|
||||
new_node->type = SEC_CRL_TYPE;
|
||||
|
||||
derCrl.type = siBuffer;
|
||||
derCrl.data = (unsigned char *)fetchCrl[0].pValue;
|
||||
derCrl.len = fetchCrl[0].ulValueLen;
|
||||
new_node->crl = CERT_DecodeDERCrl(head->arena, &derCrl, new_node->type);
|
||||
if (new_node->crl == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (fetchCrl[2].pValue) {
|
||||
int nnlen = fetchCrl[2].ulValueLen;
|
||||
new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen + 1);
|
||||
if (!new_node->crl->url) {
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
|
||||
new_node->crl->url[nnlen] = 0;
|
||||
} else {
|
||||
new_node->crl->url = NULL;
|
||||
}
|
||||
|
||||
new_node->next = NULL;
|
||||
if (head->last) {
|
||||
head->last->next = new_node;
|
||||
head->last = new_node;
|
||||
} else {
|
||||
head->first = head->last = new_node;
|
||||
}
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a list of all the CRLs .
|
||||
* CRLs are allocated in the list's arena.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx)
|
||||
{
|
||||
pk11TraverseSlot creater;
|
||||
CK_ATTRIBUTE theTemplate[2];
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
|
||||
CK_BBOOL isKrl = CK_FALSE;
|
||||
|
||||
attrs = theTemplate;
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
|
||||
attrs++;
|
||||
if (type != -1) {
|
||||
isKrl = (CK_BBOOL)(type == SEC_KRL_TYPE);
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl));
|
||||
attrs++;
|
||||
}
|
||||
|
||||
creater.callback = pk11_CollectCrls;
|
||||
creater.callbackArg = (void *)nodes;
|
||||
creater.findTemplate = theTemplate;
|
||||
creater.templateCount = (attrs - theTemplate);
|
||||
|
||||
return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
|
||||
}
|
||||
|
||||
struct crlOptionsStr {
|
||||
CERTCrlHeadNode *head;
|
||||
PRInt32 decodeOptions;
|
||||
};
|
||||
|
||||
typedef struct crlOptionsStr crlOptions;
|
||||
|
||||
static SECStatus
|
||||
pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
|
||||
void *arg)
|
||||
{
|
||||
SECItem *derCrl = NULL;
|
||||
crlOptions *options = (crlOptions *)arg;
|
||||
CERTCrlHeadNode *head = options->head;
|
||||
CERTCrlNode *new_node = NULL;
|
||||
CK_ATTRIBUTE fetchCrl[3] = {
|
||||
{ CKA_VALUE, NULL, 0 },
|
||||
{ CKA_NETSCAPE_KRL, NULL, 0 },
|
||||
{ CKA_NETSCAPE_URL, NULL, 0 },
|
||||
};
|
||||
const int fetchCrlSize = sizeof(fetchCrl) / sizeof(fetchCrl[2]);
|
||||
CK_RV crv;
|
||||
SECStatus rv = SECFailure;
|
||||
PRBool adopted = PR_FALSE; /* whether the CRL adopted the DER memory
|
||||
successfully */
|
||||
int i;
|
||||
|
||||
crv = PK11_GetAttributes(NULL, slot, crlID, fetchCrl, fetchCrlSize);
|
||||
if (CKR_OK != crv) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (!fetchCrl[1].pValue) {
|
||||
/* reject KRLs */
|
||||
PORT_SetError(SEC_ERROR_CRL_INVALID);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena,
|
||||
sizeof(CERTCrlNode));
|
||||
if (new_node == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
new_node->type = SEC_CRL_TYPE;
|
||||
|
||||
derCrl = SECITEM_AllocItem(NULL, NULL, 0);
|
||||
if (!derCrl) {
|
||||
goto loser;
|
||||
}
|
||||
derCrl->type = siBuffer;
|
||||
derCrl->data = (unsigned char *)fetchCrl[0].pValue;
|
||||
derCrl->len = fetchCrl[0].ulValueLen;
|
||||
new_node->crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, new_node->type,
|
||||
options->decodeOptions);
|
||||
if (new_node->crl == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
adopted = PR_TRUE; /* now that the CRL has adopted the DER memory,
|
||||
we won't need to free it upon exit */
|
||||
|
||||
if (fetchCrl[2].pValue && fetchCrl[2].ulValueLen) {
|
||||
/* copy the URL if there is one */
|
||||
int nnlen = fetchCrl[2].ulValueLen;
|
||||
new_node->crl->url = (char *)PORT_ArenaAlloc(new_node->crl->arena,
|
||||
nnlen + 1);
|
||||
if (!new_node->crl->url) {
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
|
||||
new_node->crl->url[nnlen] = 0;
|
||||
} else {
|
||||
new_node->crl->url = NULL;
|
||||
}
|
||||
|
||||
new_node->next = NULL;
|
||||
if (head->last) {
|
||||
head->last->next = new_node;
|
||||
head->last = new_node;
|
||||
} else {
|
||||
head->first = head->last = new_node;
|
||||
}
|
||||
rv = SECSuccess;
|
||||
new_node->crl->slot = PK11_ReferenceSlot(slot);
|
||||
new_node->crl->pkcs11ID = crlID;
|
||||
|
||||
loser:
|
||||
/* free attributes that weren't adopted by the CRL */
|
||||
for (i = 1; i < fetchCrlSize; i++) {
|
||||
if (fetchCrl[i].pValue) {
|
||||
PORT_Free(fetchCrl[i].pValue);
|
||||
}
|
||||
}
|
||||
/* free the DER if the CRL object didn't adopt it */
|
||||
if (fetchCrl[0].pValue && PR_FALSE == adopted) {
|
||||
PORT_Free(fetchCrl[0].pValue);
|
||||
}
|
||||
if (derCrl && !adopted) {
|
||||
/* clear the data fields, which we already took care of above */
|
||||
derCrl->data = NULL;
|
||||
derCrl->len = 0;
|
||||
/* free the memory for the SECItem structure itself */
|
||||
SECITEM_FreeItem(derCrl, PR_TRUE);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a list of CRLs matching specified issuer and type
|
||||
* CRLs are not allocated in the list's arena, but rather in their own,
|
||||
* arena, so that they can be used individually in the CRL cache .
|
||||
* CRLs are always partially decoded for efficiency.
|
||||
*/
|
||||
SECStatus
|
||||
pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem *issuer,
|
||||
void *wincx)
|
||||
{
|
||||
pk11TraverseSlot creater;
|
||||
CK_ATTRIBUTE theTemplate[2];
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
|
||||
crlOptions options;
|
||||
|
||||
attrs = theTemplate;
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass));
|
||||
attrs++;
|
||||
|
||||
options.head = nodes;
|
||||
|
||||
/* - do a partial decoding - we don't need to decode the entries while fetching
|
||||
- don't copy the DER for optimal performance - CRL can be very large
|
||||
- have the CRL objects adopt the DER, so SEC_DestroyCrl will free it
|
||||
- keep bad CRL objects. The CRL cache is interested in them, for
|
||||
security purposes. Bad CRL objects are a sign of something amiss.
|
||||
*/
|
||||
|
||||
options.decodeOptions = CRL_DECODE_SKIP_ENTRIES | CRL_DECODE_DONT_COPY_DER |
|
||||
CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_KEEP_BAD_CRL;
|
||||
if (issuer) {
|
||||
PK11_SETATTRS(attrs, CKA_SUBJECT, issuer->data, issuer->len);
|
||||
attrs++;
|
||||
}
|
||||
|
||||
creater.callback = pk11_RetrieveCrlsCallback;
|
||||
creater.callbackArg = (void *)&options;
|
||||
creater.findTemplate = theTemplate;
|
||||
creater.templateCount = (attrs - theTemplate);
|
||||
|
||||
return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the crl associated with a derSubjectName
|
||||
*/
|
||||
SECItem *
|
||||
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
|
||||
SECItem *name, int type, char **pUrl)
|
||||
{
|
||||
NSSCRL **crls, **crlp, *crl = NULL;
|
||||
NSSDER subject;
|
||||
SECItem *rvItem;
|
||||
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
|
||||
char *url = NULL;
|
||||
|
||||
PORT_SetError(0);
|
||||
NSSITEM_FROM_SECITEM(&subject, name);
|
||||
if (*slot) {
|
||||
nssCryptokiObject **instances;
|
||||
nssPKIObjectCollection *collection;
|
||||
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
|
||||
NSSToken *token = PK11Slot_GetNSSToken(*slot);
|
||||
collection = nssCRLCollection_Create(td, NULL);
|
||||
if (!collection) {
|
||||
goto loser;
|
||||
}
|
||||
instances = nssToken_FindCRLsBySubject(token, NULL, &subject,
|
||||
tokenOnly, 0, NULL);
|
||||
nssPKIObjectCollection_AddInstances(collection, instances, 0);
|
||||
nss_ZFreeIf(instances);
|
||||
crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
|
||||
nssPKIObjectCollection_Destroy(collection);
|
||||
} else {
|
||||
crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
|
||||
}
|
||||
if ((!crls) || (*crls == NULL)) {
|
||||
if (crls) {
|
||||
nssCRLArray_Destroy(crls);
|
||||
}
|
||||
if (NSS_GetError() == NSS_ERROR_NOT_FOUND) {
|
||||
PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
|
||||
}
|
||||
goto loser;
|
||||
}
|
||||
for (crlp = crls; *crlp; crlp++) {
|
||||
if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
|
||||
((*crlp)->isKRL && type != SEC_CRL_TYPE)) {
|
||||
crl = nssCRL_AddRef(*crlp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssCRLArray_Destroy(crls);
|
||||
if (!crl) {
|
||||
/* CRL collection was found, but no interesting CRL's were on it.
|
||||
* Not an error */
|
||||
PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
|
||||
goto loser;
|
||||
}
|
||||
if (crl->url) {
|
||||
url = PORT_Strdup(crl->url);
|
||||
if (!url) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
|
||||
if (!rvItem) {
|
||||
goto loser;
|
||||
}
|
||||
memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
|
||||
*slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
|
||||
*crlHandle = crl->object.instances[0]->handle;
|
||||
*pUrl = url;
|
||||
nssCRL_Destroy(crl);
|
||||
return rvItem;
|
||||
|
||||
loser:
|
||||
if (url)
|
||||
PORT_Free(url);
|
||||
if (crl)
|
||||
nssCRL_Destroy(crl);
|
||||
if (PORT_GetError() == 0) {
|
||||
PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CK_OBJECT_HANDLE
|
||||
PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
|
||||
char *url, int type)
|
||||
{
|
||||
NSSItem derCRL, derSubject;
|
||||
NSSToken *token = PK11Slot_GetNSSToken(slot);
|
||||
nssCryptokiObject *object;
|
||||
PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
|
||||
CK_OBJECT_HANDLE rvH;
|
||||
|
||||
NSSITEM_FROM_SECITEM(&derSubject, name);
|
||||
NSSITEM_FROM_SECITEM(&derCRL, crl);
|
||||
|
||||
object = nssToken_ImportCRL(token, NULL,
|
||||
&derSubject, &derCRL, isKRL, url, PR_TRUE);
|
||||
|
||||
if (object) {
|
||||
rvH = object->handle;
|
||||
nssCryptokiObject_Destroy(object);
|
||||
} else {
|
||||
rvH = CK_INVALID_HANDLE;
|
||||
PORT_SetError(SEC_ERROR_CRL_IMPORT_FAILED);
|
||||
}
|
||||
return rvH;
|
||||
}
|
||||
|
||||
/*
|
||||
* delete a crl.
|
||||
*/
|
||||
SECStatus
|
||||
SEC_DeletePermCRL(CERTSignedCrl *crl)
|
||||
{
|
||||
PRStatus status;
|
||||
NSSToken *token;
|
||||
nssCryptokiObject *object;
|
||||
PK11SlotInfo *slot = crl->slot;
|
||||
|
||||
if (slot == NULL) {
|
||||
PORT_Assert(slot);
|
||||
/* shouldn't happen */
|
||||
PORT_SetError(SEC_ERROR_CRL_INVALID);
|
||||
return SECFailure;
|
||||
}
|
||||
token = PK11Slot_GetNSSToken(slot);
|
||||
|
||||
object = nss_ZNEW(NULL, nssCryptokiObject);
|
||||
if (!object) {
|
||||
return SECFailure;
|
||||
}
|
||||
object->token = nssToken_AddRef(token);
|
||||
object->handle = crl->pkcs11ID;
|
||||
object->isTokenObject = PR_TRUE;
|
||||
|
||||
status = nssToken_DeleteStoredObject(object);
|
||||
|
||||
nssCryptokiObject_Destroy(object);
|
||||
return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the certificate associated with a derCert
|
||||
*/
|
||||
SECItem *
|
||||
PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
|
||||
SECItem *name, SECItem **profileTime)
|
||||
{
|
||||
CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
|
||||
CK_ATTRIBUTE theTemplate[] = {
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_NETSCAPE_EMAIL, NULL, 0 },
|
||||
};
|
||||
CK_ATTRIBUTE smimeData[] = {
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 },
|
||||
};
|
||||
/* if you change the array, change the variable below as well */
|
||||
int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
|
||||
CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
|
||||
CK_ATTRIBUTE *attrs = theTemplate;
|
||||
CK_RV crv;
|
||||
SECItem *emailProfile = NULL;
|
||||
|
||||
if (!emailAddr || !emailAddr[0]) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr));
|
||||
attrs++;
|
||||
|
||||
if (*slot) {
|
||||
smimeh = pk11_FindObjectByTemplate(*slot, theTemplate, tsize);
|
||||
} else {
|
||||
PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
|
||||
PR_FALSE, PR_TRUE, NULL);
|
||||
PK11SlotListElement *le;
|
||||
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
/* loop through all the slots */
|
||||
for (le = list->head; le; le = le->next) {
|
||||
smimeh = pk11_FindObjectByTemplate(le->slot, theTemplate, tsize);
|
||||
if (smimeh != CK_INVALID_HANDLE) {
|
||||
*slot = PK11_ReferenceSlot(le->slot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
PK11_FreeSlotList(list);
|
||||
}
|
||||
|
||||
if (smimeh == CK_INVALID_HANDLE) {
|
||||
PORT_SetError(SEC_ERROR_NO_KRL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (profileTime) {
|
||||
PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
|
||||
}
|
||||
|
||||
crv = PK11_GetAttributes(NULL, *slot, smimeh, smimeData, 2);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (!profileTime) {
|
||||
SECItem profileSubject;
|
||||
|
||||
profileSubject.data = (unsigned char *)smimeData[0].pValue;
|
||||
profileSubject.len = smimeData[0].ulValueLen;
|
||||
if (!SECITEM_ItemsAreEqual(&profileSubject, name)) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
|
||||
if (emailProfile == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
emailProfile->data = (unsigned char *)smimeData[1].pValue;
|
||||
emailProfile->len = smimeData[1].ulValueLen;
|
||||
|
||||
if (profileTime) {
|
||||
*profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
|
||||
if (*profileTime) {
|
||||
(*profileTime)->data = (unsigned char *)smimeData[0].pValue;
|
||||
(*profileTime)->len = smimeData[0].ulValueLen;
|
||||
}
|
||||
}
|
||||
|
||||
loser:
|
||||
if (emailProfile == NULL) {
|
||||
if (smimeData[1].pValue) {
|
||||
PORT_Free(smimeData[1].pValue);
|
||||
}
|
||||
}
|
||||
if (profileTime == NULL || *profileTime == NULL) {
|
||||
if (smimeData[0].pValue) {
|
||||
PORT_Free(smimeData[0].pValue);
|
||||
}
|
||||
}
|
||||
return emailProfile;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
|
||||
SECItem *emailProfile, SECItem *profileTime)
|
||||
{
|
||||
CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
|
||||
CK_BBOOL ck_true = CK_TRUE;
|
||||
CK_ATTRIBUTE theTemplate[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_TOKEN, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_NETSCAPE_EMAIL, NULL, 0 },
|
||||
{ CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 }
|
||||
};
|
||||
/* if you change the array, change the variable below as well */
|
||||
int realSize = 0;
|
||||
CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
|
||||
CK_ATTRIBUTE *attrs = theTemplate;
|
||||
CK_SESSION_HANDLE rwsession;
|
||||
PK11SlotInfo *free_slot = NULL;
|
||||
CK_RV crv;
|
||||
#ifdef DEBUG
|
||||
int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
|
||||
#endif
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true, sizeof(ck_true));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL,
|
||||
emailAddr, PORT_Strlen(emailAddr) + 1);
|
||||
attrs++;
|
||||
if (profileTime) {
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data,
|
||||
profileTime->len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_VALUE, emailProfile->data,
|
||||
emailProfile->len);
|
||||
attrs++;
|
||||
}
|
||||
realSize = attrs - theTemplate;
|
||||
PORT_Assert(realSize <= tsize);
|
||||
|
||||
if (slot == NULL) {
|
||||
free_slot = slot = PK11_GetInternalKeySlot();
|
||||
/* we need to free the key slot in the end!!! */
|
||||
}
|
||||
|
||||
rwsession = PK11_GetRWSession(slot);
|
||||
if (rwsession == CK_INVALID_SESSION) {
|
||||
PORT_SetError(SEC_ERROR_READ_ONLY);
|
||||
if (free_slot) {
|
||||
PK11_FreeSlot(free_slot);
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
crv = PK11_GETTAB(slot)->C_CreateObject(rwsession, theTemplate, realSize, &smimeh);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
}
|
||||
|
||||
PK11_RestoreROSession(slot, rwsession);
|
||||
|
||||
if (free_slot) {
|
||||
PK11_FreeSlot(free_slot);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
CERTSignedCrl *crl_storeCRL(PK11SlotInfo *slot, char *url,
|
||||
CERTSignedCrl *newCrl, SECItem *derCrl, int type);
|
||||
|
||||
/* import the CRL into the token */
|
||||
|
||||
CERTSignedCrl *
|
||||
PK11_ImportCRL(PK11SlotInfo *slot, SECItem *derCRL, char *url,
|
||||
int type, void *wincx, PRInt32 importOptions, PLArenaPool *arena,
|
||||
PRInt32 decodeoptions)
|
||||
{
|
||||
CERTSignedCrl *newCrl, *crl;
|
||||
SECStatus rv;
|
||||
CERTCertificate *caCert = NULL;
|
||||
|
||||
newCrl = crl = NULL;
|
||||
|
||||
do {
|
||||
newCrl = CERT_DecodeDERCrlWithFlags(arena, derCRL, type,
|
||||
decodeoptions);
|
||||
if (newCrl == NULL) {
|
||||
if (type == SEC_CRL_TYPE) {
|
||||
/* only promote error when the error code is too generic */
|
||||
if (PORT_GetError() == SEC_ERROR_BAD_DER)
|
||||
PORT_SetError(SEC_ERROR_CRL_INVALID);
|
||||
} else {
|
||||
PORT_SetError(SEC_ERROR_KRL_INVALID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)) {
|
||||
CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
|
||||
PR_ASSERT(handle != NULL);
|
||||
caCert = CERT_FindCertByName(handle,
|
||||
&newCrl->crl.derName);
|
||||
if (caCert == NULL) {
|
||||
PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If caCert is a v3 certificate, make sure that it can be used for
|
||||
crl signing purpose */
|
||||
rv = CERT_CheckCertUsage(caCert, KU_CRL_SIGN);
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
|
||||
rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert,
|
||||
PR_Now(), wincx);
|
||||
if (rv != SECSuccess) {
|
||||
if (type == SEC_CRL_TYPE) {
|
||||
PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
|
||||
} else {
|
||||
PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
crl = crl_storeCRL(slot, url, newCrl, derCRL, type);
|
||||
|
||||
} while (0);
|
||||
|
||||
if (crl == NULL) {
|
||||
SEC_DestroyCrl(newCrl);
|
||||
}
|
||||
if (caCert) {
|
||||
CERT_DestroyCertificate(caCert);
|
||||
}
|
||||
return (crl);
|
||||
}
|
||||
2098
security/nss/lib/pk11wrap/pk11obj.c
Normal file
2098
security/nss/lib/pk11wrap/pk11obj.c
Normal file
File diff suppressed because it is too large
Load diff
1796
security/nss/lib/pk11wrap/pk11pars.c
Normal file
1796
security/nss/lib/pk11wrap/pk11pars.c
Normal file
File diff suppressed because it is too large
Load diff
1433
security/nss/lib/pk11wrap/pk11pbe.c
Normal file
1433
security/nss/lib/pk11wrap/pk11pbe.c
Normal file
File diff suppressed because it is too large
Load diff
669
security/nss/lib/pk11wrap/pk11pk12.c
Normal file
669
security/nss/lib/pk11wrap/pk11pk12.c
Normal file
|
|
@ -0,0 +1,669 @@
|
|||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* This file PKCS #12 fuctions that should really be moved to the
|
||||
* PKCS #12 directory, however we can't do that in a point release
|
||||
* because that will break binary compatibility, so we keep them here for now.
|
||||
*/
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secmod.h"
|
||||
#include "secmodi.h"
|
||||
#include "pkcs11.h"
|
||||
#include "pk11func.h"
|
||||
#include "secitem.h"
|
||||
#include "key.h"
|
||||
#include "secoid.h"
|
||||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
#include "prerror.h"
|
||||
|
||||
/* These data structures should move to a common .h file shared between the
|
||||
* wrappers and the pkcs 12 code. */
|
||||
|
||||
/*
|
||||
** RSA Raw Private Key structures
|
||||
*/
|
||||
|
||||
/* member names from PKCS#1, section 7.2 */
|
||||
struct SECKEYRSAPrivateKeyStr {
|
||||
PLArenaPool *arena;
|
||||
SECItem version;
|
||||
SECItem modulus;
|
||||
SECItem publicExponent;
|
||||
SECItem privateExponent;
|
||||
SECItem prime1;
|
||||
SECItem prime2;
|
||||
SECItem exponent1;
|
||||
SECItem exponent2;
|
||||
SECItem coefficient;
|
||||
};
|
||||
typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey;
|
||||
|
||||
/*
|
||||
** DSA Raw Private Key structures
|
||||
*/
|
||||
|
||||
struct SECKEYDSAPrivateKeyStr {
|
||||
SECKEYPQGParams params;
|
||||
SECItem privateValue;
|
||||
};
|
||||
typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey;
|
||||
|
||||
/*
|
||||
** Diffie-Hellman Raw Private Key structures
|
||||
** Structure member names suggested by PKCS#3.
|
||||
*/
|
||||
struct SECKEYDHPrivateKeyStr {
|
||||
PLArenaPool *arena;
|
||||
SECItem prime;
|
||||
SECItem base;
|
||||
SECItem privateValue;
|
||||
};
|
||||
typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey;
|
||||
|
||||
/*
|
||||
** raw private key object
|
||||
*/
|
||||
struct SECKEYRawPrivateKeyStr {
|
||||
PLArenaPool *arena;
|
||||
KeyType keyType;
|
||||
union {
|
||||
SECKEYRSAPrivateKey rsa;
|
||||
SECKEYDSAPrivateKey dsa;
|
||||
SECKEYDHPrivateKey dh;
|
||||
} u;
|
||||
};
|
||||
typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
|
||||
|
||||
SEC_ASN1_MKSUB(SEC_AnyTemplate)
|
||||
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
|
||||
|
||||
/* ASN1 Templates for new decoder/encoder */
|
||||
/*
|
||||
* Attribute value for PKCS8 entries (static?)
|
||||
*/
|
||||
const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(SECKEYAttribute) },
|
||||
{ SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
|
||||
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue),
|
||||
SEC_ASN1_SUB(SEC_AnyTemplate) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
|
||||
{ SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo, version) },
|
||||
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
|
||||
offsetof(SECKEYPrivateKeyInfo, algorithm),
|
||||
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
|
||||
{ SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo, privateKey) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(SECKEYPrivateKeyInfo, attributes),
|
||||
SECKEY_SetOfAttributeTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
|
||||
{ SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.version) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.modulus) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.publicExponent) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.privateExponent) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime1) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime2) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent1) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent2) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.coefficient) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = {
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dsa.privateValue) },
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.privateValue) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.base) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) },
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
|
||||
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
|
||||
offsetof(SECKEYEncryptedPrivateKeyInfo, algorithm),
|
||||
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
|
||||
{ SEC_ASN1_OCTET_STRING,
|
||||
offsetof(SECKEYEncryptedPrivateKeyInfo, encryptedData) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
|
||||
{ SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
|
||||
};
|
||||
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
|
||||
|
||||
/*
|
||||
* See bugzilla bug 125359
|
||||
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||
* all of the templates above that en/decode into integers must be converted
|
||||
* from ASN.1's signed integer type. This is done by marking either the
|
||||
* source or destination (encoding or decoding, respectively) type as
|
||||
* siUnsignedInteger.
|
||||
*/
|
||||
|
||||
static void
|
||||
prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
|
||||
{
|
||||
key->u.rsa.modulus.type = siUnsignedInteger;
|
||||
key->u.rsa.publicExponent.type = siUnsignedInteger;
|
||||
key->u.rsa.privateExponent.type = siUnsignedInteger;
|
||||
key->u.rsa.prime1.type = siUnsignedInteger;
|
||||
key->u.rsa.prime2.type = siUnsignedInteger;
|
||||
key->u.rsa.exponent1.type = siUnsignedInteger;
|
||||
key->u.rsa.exponent2.type = siUnsignedInteger;
|
||||
key->u.rsa.coefficient.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
|
||||
{
|
||||
key->u.dsa.privateValue.type = siUnsignedInteger;
|
||||
key->u.dsa.params.prime.type = siUnsignedInteger;
|
||||
key->u.dsa.params.subPrime.type = siUnsignedInteger;
|
||||
key->u.dsa.params.base.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
|
||||
{
|
||||
key->u.dh.privateValue.type = siUnsignedInteger;
|
||||
key->u.dh.prime.type = siUnsignedInteger;
|
||||
key->u.dh.base.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
|
||||
SECItem *nickname, SECItem *publicValue, PRBool isPerm,
|
||||
PRBool isPrivate, unsigned int keyUsage, void *wincx)
|
||||
{
|
||||
return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI,
|
||||
nickname, publicValue,
|
||||
isPerm, isPrivate, keyUsage,
|
||||
NULL, wincx);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
|
||||
SECItem *nickname, SECItem *publicValue,
|
||||
PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
|
||||
SECKEYPrivateKey **privk, void *wincx)
|
||||
{
|
||||
SECKEYPrivateKeyInfo *pki = NULL;
|
||||
PLArenaPool *temparena = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!temparena)
|
||||
return rv;
|
||||
pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo);
|
||||
if (!pki) {
|
||||
PORT_FreeArena(temparena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
pki->arena = temparena;
|
||||
|
||||
rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
|
||||
derPKI);
|
||||
if (rv != SECSuccess) {
|
||||
/* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
|
||||
* validity of the data in pki. The best we can do is free the arena
|
||||
* and return. */
|
||||
PORT_FreeArena(temparena, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
if (pki->privateKey.data == NULL) {
|
||||
/* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
|
||||
* is a zero-length octet string, free the arena and return a failure
|
||||
* to avoid trying to zero the corresponding SECItem in
|
||||
* SECKEY_DestroyPrivateKeyInfo(). */
|
||||
PORT_FreeArena(temparena, PR_TRUE);
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
|
||||
publicValue, isPerm, isPrivate,
|
||||
keyUsage, privk, wincx);
|
||||
|
||||
/* this zeroes the key and frees the arena */
|
||||
SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
|
||||
SECItem *nickname, SECItem *publicValue, PRBool isPerm,
|
||||
PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk,
|
||||
void *wincx)
|
||||
{
|
||||
CK_BBOOL cktrue = CK_TRUE;
|
||||
CK_BBOOL ckfalse = CK_FALSE;
|
||||
CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
|
||||
CK_KEY_TYPE keyType = CKK_RSA;
|
||||
CK_OBJECT_HANDLE objectID;
|
||||
CK_ATTRIBUTE theTemplate[20];
|
||||
int templateCount = 0;
|
||||
SECStatus rv = SECFailure;
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_ATTRIBUTE *signedattr = NULL;
|
||||
int signedcount = 0;
|
||||
CK_ATTRIBUTE *ap;
|
||||
SECItem *ck_id = NULL;
|
||||
|
||||
attrs = theTemplate;
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse,
|
||||
sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse,
|
||||
sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse,
|
||||
sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
|
||||
switch (lpk->keyType) {
|
||||
case rsaKey:
|
||||
keyType = CKK_RSA;
|
||||
PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue
|
||||
: &ckfalse,
|
||||
sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue
|
||||
: &ckfalse,
|
||||
sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
|
||||
: &ckfalse,
|
||||
sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
|
||||
(keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
|
||||
: &ckfalse,
|
||||
sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus);
|
||||
if (ck_id == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
|
||||
attrs++;
|
||||
if (nickname) {
|
||||
PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
|
||||
attrs++;
|
||||
}
|
||||
signedattr = attrs;
|
||||
PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data,
|
||||
lpk->u.rsa.modulus.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
|
||||
lpk->u.rsa.publicExponent.data,
|
||||
lpk->u.rsa.publicExponent.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT,
|
||||
lpk->u.rsa.privateExponent.data,
|
||||
lpk->u.rsa.privateExponent.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_PRIME_1,
|
||||
lpk->u.rsa.prime1.data,
|
||||
lpk->u.rsa.prime1.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_PRIME_2,
|
||||
lpk->u.rsa.prime2.data,
|
||||
lpk->u.rsa.prime2.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_EXPONENT_1,
|
||||
lpk->u.rsa.exponent1.data,
|
||||
lpk->u.rsa.exponent1.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_EXPONENT_2,
|
||||
lpk->u.rsa.exponent2.data,
|
||||
lpk->u.rsa.exponent2.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_COEFFICIENT,
|
||||
lpk->u.rsa.coefficient.data,
|
||||
lpk->u.rsa.coefficient.len);
|
||||
attrs++;
|
||||
break;
|
||||
case dsaKey:
|
||||
keyType = CKK_DSA;
|
||||
/* To make our intenal PKCS #11 module work correctly with
|
||||
* our database, we need to pass in the public key value for
|
||||
* this dsa key. We have a netscape only CKA_ value to do this.
|
||||
* Only send it to internal slots */
|
||||
if (publicValue == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (PK11_IsInternal(slot)) {
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
|
||||
publicValue->data, publicValue->len);
|
||||
attrs++;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
if (nickname) {
|
||||
PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
|
||||
attrs++;
|
||||
}
|
||||
ck_id = PK11_MakeIDFromPubKey(publicValue);
|
||||
if (ck_id == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
|
||||
attrs++;
|
||||
signedattr = attrs;
|
||||
PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data,
|
||||
lpk->u.dsa.params.prime.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_SUBPRIME, lpk->u.dsa.params.subPrime.data,
|
||||
lpk->u.dsa.params.subPrime.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data,
|
||||
lpk->u.dsa.params.base.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data,
|
||||
lpk->u.dsa.privateValue.len);
|
||||
attrs++;
|
||||
break;
|
||||
case dhKey:
|
||||
keyType = CKK_DH;
|
||||
/* To make our intenal PKCS #11 module work correctly with
|
||||
* our database, we need to pass in the public key value for
|
||||
* this dh key. We have a netscape only CKA_ value to do this.
|
||||
* Only send it to internal slots */
|
||||
if (PK11_IsInternal(slot)) {
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
|
||||
publicValue->data, publicValue->len);
|
||||
attrs++;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
if (nickname) {
|
||||
PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
|
||||
attrs++;
|
||||
}
|
||||
ck_id = PK11_MakeIDFromPubKey(publicValue);
|
||||
if (ck_id == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
|
||||
attrs++;
|
||||
signedattr = attrs;
|
||||
PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data,
|
||||
lpk->u.dh.prime.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data,
|
||||
lpk->u.dh.base.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data,
|
||||
lpk->u.dh.privateValue.len);
|
||||
attrs++;
|
||||
break;
|
||||
/* what about fortezza??? */
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
goto loser;
|
||||
}
|
||||
templateCount = attrs - theTemplate;
|
||||
PORT_Assert(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE));
|
||||
PORT_Assert(signedattr != NULL);
|
||||
signedcount = attrs - signedattr;
|
||||
|
||||
for (ap = signedattr; signedcount; ap++, signedcount--) {
|
||||
pk11_SignedToUnsigned(ap);
|
||||
}
|
||||
|
||||
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION,
|
||||
theTemplate, templateCount, isPerm, &objectID);
|
||||
|
||||
/* create and return a SECKEYPrivateKey */
|
||||
if (rv == SECSuccess && privk != NULL) {
|
||||
*privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx);
|
||||
if (*privk == NULL) {
|
||||
rv = SECFailure;
|
||||
}
|
||||
}
|
||||
loser:
|
||||
if (ck_id) {
|
||||
SECITEM_ZfreeItem(ck_id, PR_TRUE);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
||||
SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
|
||||
PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
|
||||
SECKEYPrivateKey **privk, void *wincx)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
SECKEYRawPrivateKey *lpk = NULL;
|
||||
const SEC_ASN1Template *keyTemplate, *paramTemplate;
|
||||
void *paramDest = NULL;
|
||||
PLArenaPool *arena = NULL;
|
||||
|
||||
arena = PORT_NewArena(2048);
|
||||
if (!arena) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* need to change this to use RSA/DSA keys */
|
||||
lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
|
||||
sizeof(SECKEYRawPrivateKey));
|
||||
if (lpk == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lpk->arena = arena;
|
||||
|
||||
switch (SECOID_GetAlgorithmTag(&pki->algorithm)) {
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
prepare_rsa_priv_key_export_for_asn1(lpk);
|
||||
keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
|
||||
paramTemplate = NULL;
|
||||
paramDest = NULL;
|
||||
lpk->keyType = rsaKey;
|
||||
break;
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
prepare_dsa_priv_key_export_for_asn1(lpk);
|
||||
keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
|
||||
paramTemplate = SECKEY_PQGParamsTemplate;
|
||||
paramDest = &(lpk->u.dsa.params);
|
||||
lpk->keyType = dsaKey;
|
||||
break;
|
||||
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
||||
if (!publicValue) {
|
||||
goto loser;
|
||||
}
|
||||
prepare_dh_priv_key_export_for_asn1(lpk);
|
||||
keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
|
||||
paramTemplate = NULL;
|
||||
paramDest = NULL;
|
||||
lpk->keyType = dhKey;
|
||||
break;
|
||||
|
||||
default:
|
||||
keyTemplate = NULL;
|
||||
paramTemplate = NULL;
|
||||
paramDest = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!keyTemplate) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the private key and any algorithm parameters */
|
||||
rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
if (paramDest && paramTemplate) {
|
||||
rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
|
||||
&(pki->algorithm.parameters));
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm,
|
||||
isPrivate, keyUsage, privk, wincx);
|
||||
|
||||
loser:
|
||||
if (arena != NULL) {
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki,
|
||||
SECItem *nickname, SECItem *publicValue, PRBool isPerm,
|
||||
PRBool isPrivate, unsigned int keyUsage, void *wincx)
|
||||
{
|
||||
return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
|
||||
publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
|
||||
}
|
||||
|
||||
SECItem *
|
||||
PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx)
|
||||
{
|
||||
SECKEYPrivateKeyInfo *pki = PK11_ExportPrivKeyInfo(pk, wincx);
|
||||
SECItem *derPKI;
|
||||
|
||||
if (!pki) {
|
||||
return NULL;
|
||||
}
|
||||
derPKI = SEC_ASN1EncodeItem(NULL, NULL, pki,
|
||||
SECKEY_PrivateKeyInfoTemplate);
|
||||
SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
|
||||
return derPKI;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
ReadAttribute(SECKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
|
||||
PLArenaPool *arena, SECItem *output)
|
||||
{
|
||||
SECStatus rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, type,
|
||||
arena, output);
|
||||
return rv == SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller is responsible for freeing the return value by passing it to
|
||||
* SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE).
|
||||
*/
|
||||
SECKEYPrivateKeyInfo *
|
||||
PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx)
|
||||
{
|
||||
/* PrivateKeyInfo version (always zero) */
|
||||
const unsigned char pkiVersion = 0;
|
||||
/* RSAPrivateKey version (always zero) */
|
||||
const unsigned char rsaVersion = 0;
|
||||
PLArenaPool *arena = NULL;
|
||||
SECKEYRawPrivateKey rawKey;
|
||||
SECKEYPrivateKeyInfo *pki;
|
||||
SECItem *encoded;
|
||||
SECStatus rv;
|
||||
|
||||
if (pk->keyType != rsaKey) {
|
||||
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) {
|
||||
goto loser;
|
||||
}
|
||||
memset(&rawKey, 0, sizeof(rawKey));
|
||||
rawKey.keyType = pk->keyType;
|
||||
rawKey.u.rsa.version.type = siUnsignedInteger;
|
||||
rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
|
||||
if (!rawKey.u.rsa.version.data) {
|
||||
goto loser;
|
||||
}
|
||||
rawKey.u.rsa.version.data[0] = rsaVersion;
|
||||
rawKey.u.rsa.version.len = 1;
|
||||
|
||||
/* Read the component attributes of the private key */
|
||||
prepare_rsa_priv_key_export_for_asn1(&rawKey);
|
||||
if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) ||
|
||||
!ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena,
|
||||
&rawKey.u.rsa.publicExponent) ||
|
||||
!ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena,
|
||||
&rawKey.u.rsa.privateExponent) ||
|
||||
!ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) ||
|
||||
!ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) ||
|
||||
!ReadAttribute(pk, CKA_EXPONENT_1, arena,
|
||||
&rawKey.u.rsa.exponent1) ||
|
||||
!ReadAttribute(pk, CKA_EXPONENT_2, arena,
|
||||
&rawKey.u.rsa.exponent2) ||
|
||||
!ReadAttribute(pk, CKA_COEFFICIENT, arena,
|
||||
&rawKey.u.rsa.coefficient)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo);
|
||||
if (!pki) {
|
||||
goto loser;
|
||||
}
|
||||
encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey,
|
||||
SECKEY_RSAPrivateKeyExportTemplate);
|
||||
if (!encoded) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SECOID_SetAlgorithmID(arena, &pki->algorithm,
|
||||
SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
pki->version.type = siUnsignedInteger;
|
||||
pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
|
||||
if (!pki->version.data) {
|
||||
goto loser;
|
||||
}
|
||||
pki->version.data[0] = pkiVersion;
|
||||
pki->version.len = 1;
|
||||
pki->arena = arena;
|
||||
|
||||
return pki;
|
||||
|
||||
loser:
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
522
security/nss/lib/pk11wrap/pk11pqg.c
Normal file
522
security/nss/lib/pk11wrap/pk11pqg.c
Normal file
|
|
@ -0,0 +1,522 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* Thse functions are stub functions which will get replaced with calls through
|
||||
* PKCS #11.
|
||||
*/
|
||||
|
||||
#include "pk11func.h"
|
||||
#include "secmod.h"
|
||||
#include "secmodi.h"
|
||||
#include "secmodti.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "pk11pqg.h"
|
||||
#include "secerr.h"
|
||||
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of P specified by L.
|
||||
* if L is greater than 1024 then the resulting verify parameters will be
|
||||
* DSA2.
|
||||
* Length of Q specified by N. If zero, The PKCS #11 module will
|
||||
* pick an appropriately sized Q for P. If N is specified and L = 1024, then
|
||||
* the resulting verify parameters will be DSA2, Otherwise DSA1 parameters
|
||||
* will be returned.
|
||||
* Length of SEED in bytes specified in seedBytes.
|
||||
*
|
||||
* The underlying PKCS #11 module will check the values for L, N,
|
||||
* and seedBytes. The rules for softoken are:
|
||||
*
|
||||
* If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits.
|
||||
* If L <= 1024, then N must be 0 or 160.
|
||||
* If L >= 1024, then L and N must match the following table:
|
||||
* L=1024 N=0 or 160
|
||||
* L=2048 N=0 or 224
|
||||
* L=2048 N=256
|
||||
* L=3072 N=0 or 256
|
||||
* if L <= 1024
|
||||
* seedBbytes must be in the range [20..256].
|
||||
* if L >= 1024
|
||||
* seedBbytes must be in the range [20..L/16].
|
||||
*/
|
||||
extern SECStatus
|
||||
PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
|
||||
unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
|
||||
{
|
||||
PK11SlotInfo *slot = NULL;
|
||||
CK_ATTRIBUTE genTemplate[5];
|
||||
CK_ATTRIBUTE *attrs = genTemplate;
|
||||
int count = sizeof(genTemplate) / sizeof(genTemplate[0]);
|
||||
CK_MECHANISM mechanism;
|
||||
CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE;
|
||||
CK_RV crv;
|
||||
CK_ATTRIBUTE pTemplate[] = {
|
||||
{ CKA_PRIME, NULL, 0 },
|
||||
{ CKA_SUBPRIME, NULL, 0 },
|
||||
{ CKA_BASE, NULL, 0 },
|
||||
};
|
||||
CK_ATTRIBUTE vTemplate[] = {
|
||||
{ CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
|
||||
{ CKA_NETSCAPE_PQG_SEED, NULL, 0 },
|
||||
{ CKA_NETSCAPE_PQG_H, NULL, 0 },
|
||||
};
|
||||
CK_ULONG primeBits = L;
|
||||
CK_ULONG subPrimeBits = N;
|
||||
int pTemplateCount = sizeof(pTemplate) / sizeof(pTemplate[0]);
|
||||
int vTemplateCount = sizeof(vTemplate) / sizeof(vTemplate[0]);
|
||||
PLArenaPool *parena = NULL;
|
||||
PLArenaPool *varena = NULL;
|
||||
PQGParams *params = NULL;
|
||||
PQGVerify *verify = NULL;
|
||||
CK_ULONG seedBits = seedBytes * 8;
|
||||
|
||||
*pParams = NULL;
|
||||
*pVfy = NULL;
|
||||
|
||||
if (primeBits == (CK_ULONG)-1) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
goto loser;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_PRIME_BITS, &primeBits, sizeof(primeBits));
|
||||
attrs++;
|
||||
if (subPrimeBits != 0) {
|
||||
PK11_SETATTRS(attrs, CKA_SUB_PRIME_BITS,
|
||||
&subPrimeBits, sizeof(subPrimeBits));
|
||||
attrs++;
|
||||
}
|
||||
if (seedBits != 0) {
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS,
|
||||
&seedBits, sizeof(seedBits));
|
||||
attrs++;
|
||||
}
|
||||
count = attrs - genTemplate;
|
||||
PR_ASSERT(count <= sizeof(genTemplate) / sizeof(CK_ATTRIBUTE));
|
||||
|
||||
slot = PK11_GetInternalSlot();
|
||||
if (slot == NULL) {
|
||||
/* set error */
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); /* shouldn't happen */
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* make sure the internal slot can handle DSA2 type parameters. */
|
||||
if (primeBits > 1024) {
|
||||
CK_MECHANISM_INFO mechanism_info;
|
||||
|
||||
if (!slot->isThreadSafe)
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
|
||||
CKM_DSA_PARAMETER_GEN,
|
||||
&mechanism_info);
|
||||
if (!slot->isThreadSafe)
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
/* a bug in the old softoken left CKM_DSA_PARAMETER_GEN off of the
|
||||
* mechanism List. If we get a failure asking for this value, we know
|
||||
* it can't handle DSA2 */
|
||||
if ((crv != CKR_OK) || (mechanism_info.ulMaxKeySize < primeBits)) {
|
||||
PK11_FreeSlot(slot);
|
||||
slot = PK11_GetBestSlotWithAttributes(CKM_DSA_PARAMETER_GEN, 0,
|
||||
primeBits, NULL);
|
||||
if (slot == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_TOKEN); /* can happen */
|
||||
goto loser;
|
||||
}
|
||||
/* ditch seedBits in this case, they are NSS specific and at
|
||||
* this point we have a token that claims to handle DSA2 */
|
||||
if (seedBits) {
|
||||
attrs--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the Key Gen Mechanism */
|
||||
mechanism.mechanism = CKM_DSA_PARAMETER_GEN;
|
||||
mechanism.pParameter = NULL;
|
||||
mechanism.ulParameterLen = 0;
|
||||
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session,
|
||||
&mechanism, genTemplate, count, &objectID);
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
goto loser;
|
||||
}
|
||||
|
||||
parena = PORT_NewArena(60);
|
||||
if (!parena) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
goto loser;
|
||||
}
|
||||
|
||||
params = (PQGParams *)PORT_ArenaAlloc(parena, sizeof(PQGParams));
|
||||
if (params == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* fill in Params */
|
||||
params->arena = parena;
|
||||
params->prime.type = siUnsignedInteger;
|
||||
params->prime.data = pTemplate[0].pValue;
|
||||
params->prime.len = pTemplate[0].ulValueLen;
|
||||
params->subPrime.type = siUnsignedInteger;
|
||||
params->subPrime.data = pTemplate[1].pValue;
|
||||
params->subPrime.len = pTemplate[1].ulValueLen;
|
||||
params->base.type = siUnsignedInteger;
|
||||
params->base.data = pTemplate[2].pValue;
|
||||
params->base.len = pTemplate[2].ulValueLen;
|
||||
|
||||
varena = PORT_NewArena(60);
|
||||
if (!varena) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
goto loser;
|
||||
}
|
||||
|
||||
verify = (PQGVerify *)PORT_ArenaAlloc(varena, sizeof(PQGVerify));
|
||||
if (verify == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
/* fill in Params */
|
||||
verify->arena = varena;
|
||||
verify->counter = (unsigned int)(*(CK_ULONG *)vTemplate[0].pValue);
|
||||
verify->seed.type = siUnsignedInteger;
|
||||
verify->seed.data = vTemplate[1].pValue;
|
||||
verify->seed.len = vTemplate[1].ulValueLen;
|
||||
verify->h.type = siUnsignedInteger;
|
||||
verify->h.data = vTemplate[2].pValue;
|
||||
verify->h.len = vTemplate[2].ulValueLen;
|
||||
|
||||
PK11_DestroyObject(slot, objectID);
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
*pParams = params;
|
||||
*pVfy = verify;
|
||||
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
if (objectID != CK_INVALID_HANDLE) {
|
||||
PK11_DestroyObject(slot, objectID);
|
||||
}
|
||||
if (parena != NULL) {
|
||||
PORT_FreeArena(parena, PR_FALSE);
|
||||
}
|
||||
if (varena != NULL) {
|
||||
PORT_FreeArena(varena, PR_FALSE);
|
||||
}
|
||||
if (slot) {
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of P specified by j. Length of h will match length of P.
|
||||
* Length of SEED in bytes specified in seedBytes.
|
||||
* seedBbytes must be in the range [20..255] or an error will result.
|
||||
*/
|
||||
extern SECStatus
|
||||
PK11_PQG_ParamGenSeedLen(unsigned int j, unsigned int seedBytes,
|
||||
PQGParams **pParams, PQGVerify **pVfy)
|
||||
{
|
||||
unsigned int primeBits = PQG_INDEX_TO_PBITS(j);
|
||||
return PK11_PQG_ParamGenV2(primeBits, 0, seedBytes, pParams, pVfy);
|
||||
}
|
||||
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of seed and length of h both equal length of P.
|
||||
* All lengths are specified by "j", according to the table above.
|
||||
*/
|
||||
extern SECStatus
|
||||
PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
|
||||
{
|
||||
unsigned int primeBits = PQG_INDEX_TO_PBITS(j);
|
||||
return PK11_PQG_ParamGenV2(primeBits, 0, 0, pParams, pVfy);
|
||||
}
|
||||
|
||||
/* Test PQGParams for validity as DSS PQG values.
|
||||
* If vfy is non-NULL, test PQGParams to make sure they were generated
|
||||
* using the specified seed, counter, and h values.
|
||||
*
|
||||
* Return value indicates whether Verification operation ran successfully
|
||||
* to completion, but does not indicate if PQGParams are valid or not.
|
||||
* If return value is SECSuccess, then *pResult has these meanings:
|
||||
* SECSuccess: PQGParams are valid.
|
||||
* SECFailure: PQGParams are invalid.
|
||||
*/
|
||||
|
||||
extern SECStatus
|
||||
PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
|
||||
SECStatus *result)
|
||||
{
|
||||
CK_ATTRIBUTE keyTempl[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_KEY_TYPE, NULL, 0 },
|
||||
{ CKA_PRIME, NULL, 0 },
|
||||
{ CKA_SUBPRIME, NULL, 0 },
|
||||
{ CKA_BASE, NULL, 0 },
|
||||
{ CKA_TOKEN, NULL, 0 },
|
||||
{ CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
|
||||
{ CKA_NETSCAPE_PQG_SEED, NULL, 0 },
|
||||
{ CKA_NETSCAPE_PQG_H, NULL, 0 },
|
||||
};
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_BBOOL ckfalse = CK_FALSE;
|
||||
CK_OBJECT_CLASS class = CKO_KG_PARAMETERS;
|
||||
CK_KEY_TYPE keyType = CKK_DSA;
|
||||
SECStatus rv = SECSuccess;
|
||||
PK11SlotInfo *slot;
|
||||
int keyCount;
|
||||
CK_OBJECT_HANDLE objectID;
|
||||
CK_ULONG counter;
|
||||
CK_RV crv;
|
||||
|
||||
attrs = keyTempl;
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data,
|
||||
params->prime.len);
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data,
|
||||
params->subPrime.len);
|
||||
attrs++;
|
||||
if (params->base.len) {
|
||||
PK11_SETATTRS(attrs, CKA_BASE, params->base.data, params->base.len);
|
||||
attrs++;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse));
|
||||
attrs++;
|
||||
if (vfy) {
|
||||
if (vfy->counter != -1) {
|
||||
counter = vfy->counter;
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER,
|
||||
&counter, sizeof(counter));
|
||||
attrs++;
|
||||
}
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED,
|
||||
vfy->seed.data, vfy->seed.len);
|
||||
attrs++;
|
||||
if (vfy->h.len) {
|
||||
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H,
|
||||
vfy->h.data, vfy->h.len);
|
||||
attrs++;
|
||||
}
|
||||
}
|
||||
|
||||
keyCount = attrs - keyTempl;
|
||||
PORT_Assert(keyCount <= sizeof(keyTempl) / sizeof(keyTempl[0]));
|
||||
|
||||
slot = PK11_GetInternalSlot();
|
||||
if (slot == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount,
|
||||
&objectID);
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
|
||||
/* throw away the keys, we only wanted the return code */
|
||||
PK11_DestroyObject(slot, objectID);
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
*result = SECSuccess;
|
||||
if (crv == CKR_ATTRIBUTE_VALUE_INVALID) {
|
||||
*result = SECFailure;
|
||||
} else if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
rv = SECFailure;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Free the PQGParams struct and the things it points to. *
|
||||
**************************************************************************/
|
||||
extern void
|
||||
PK11_PQG_DestroyParams(PQGParams *params)
|
||||
{
|
||||
if (params == NULL)
|
||||
return;
|
||||
if (params->arena != NULL) {
|
||||
PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
|
||||
} else {
|
||||
SECITEM_FreeItem(¶ms->prime, PR_FALSE); /* don't free prime */
|
||||
SECITEM_FreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */
|
||||
SECITEM_FreeItem(¶ms->base, PR_FALSE); /* don't free base */
|
||||
PORT_Free(params);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Free the PQGVerify struct and the things it points to. *
|
||||
**************************************************************************/
|
||||
extern void
|
||||
PK11_PQG_DestroyVerify(PQGVerify *vfy)
|
||||
{
|
||||
if (vfy == NULL)
|
||||
return;
|
||||
if (vfy->arena != NULL) {
|
||||
PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
|
||||
} else {
|
||||
SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
|
||||
SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */
|
||||
PORT_Free(vfy);
|
||||
}
|
||||
}
|
||||
|
||||
#define PQG_DEFAULT_CHUNKSIZE 2048 /* bytes */
|
||||
|
||||
/**************************************************************************
|
||||
* Return a pointer to a new PQGParams struct that is constructed from *
|
||||
* copies of the arguments passed in. *
|
||||
* Return NULL on failure. *
|
||||
**************************************************************************/
|
||||
extern PQGParams *
|
||||
PK11_PQG_NewParams(const SECItem *prime, const SECItem *subPrime,
|
||||
const SECItem *base)
|
||||
{
|
||||
PLArenaPool *arena;
|
||||
PQGParams *dest;
|
||||
SECStatus status;
|
||||
|
||||
arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL)
|
||||
goto loser;
|
||||
|
||||
dest = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
|
||||
if (dest == NULL)
|
||||
goto loser;
|
||||
|
||||
dest->arena = arena;
|
||||
|
||||
status = SECITEM_CopyItem(arena, &dest->prime, prime);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
status = SECITEM_CopyItem(arena, &dest->subPrime, subPrime);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
status = SECITEM_CopyItem(arena, &dest->base, base);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
return dest;
|
||||
|
||||
loser:
|
||||
if (arena != NULL)
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "prime" SECItem with the prime value in params.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus
|
||||
PK11_PQG_GetPrimeFromParams(const PQGParams *params, SECItem *prime)
|
||||
{
|
||||
return SECITEM_CopyItem(NULL, prime, ¶ms->prime);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "subPrime" SECItem with the prime value in params.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus
|
||||
PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, SECItem *subPrime)
|
||||
{
|
||||
return SECITEM_CopyItem(NULL, subPrime, ¶ms->subPrime);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "base" SECItem with the base value in params.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus
|
||||
PK11_PQG_GetBaseFromParams(const PQGParams *params, SECItem *base)
|
||||
{
|
||||
return SECITEM_CopyItem(NULL, base, ¶ms->base);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Return a pointer to a new PQGVerify struct that is constructed from *
|
||||
* copies of the arguments passed in. *
|
||||
* Return NULL on failure. *
|
||||
**************************************************************************/
|
||||
extern PQGVerify *
|
||||
PK11_PQG_NewVerify(unsigned int counter, const SECItem *seed,
|
||||
const SECItem *h)
|
||||
{
|
||||
PLArenaPool *arena;
|
||||
PQGVerify *dest;
|
||||
SECStatus status;
|
||||
|
||||
arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL)
|
||||
goto loser;
|
||||
|
||||
dest = (PQGVerify *)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
|
||||
if (dest == NULL)
|
||||
goto loser;
|
||||
|
||||
dest->arena = arena;
|
||||
dest->counter = counter;
|
||||
|
||||
status = SECITEM_CopyItem(arena, &dest->seed, seed);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
status = SECITEM_CopyItem(arena, &dest->h, h);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
return dest;
|
||||
|
||||
loser:
|
||||
if (arena != NULL)
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Returns "counter" value from the PQGVerify.
|
||||
**************************************************************************/
|
||||
extern unsigned int
|
||||
PK11_PQG_GetCounterFromVerify(const PQGVerify *verify)
|
||||
{
|
||||
return verify->counter;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "seed" SECItem with the seed value in verify.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus
|
||||
PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, SECItem *seed)
|
||||
{
|
||||
return SECITEM_CopyItem(NULL, seed, &verify->seed);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "h" SECItem with the h value in verify.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus
|
||||
PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem *h)
|
||||
{
|
||||
return SECITEM_CopyItem(NULL, h, &verify->h);
|
||||
}
|
||||
135
security/nss/lib/pk11wrap/pk11pqg.h
Normal file
135
security/nss/lib/pk11wrap/pk11pqg.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* Thse functions are stub functions which will get replaced with calls through
|
||||
* PKCS #11.
|
||||
*/
|
||||
|
||||
#ifndef _PK11PQG_H_
|
||||
#define _PK11PQG_H_ 1
|
||||
|
||||
#include "blapit.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of seed and length of h both equal length of P.
|
||||
* All lengths are specified by "j", according to the table above.
|
||||
*/
|
||||
extern SECStatus PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams,
|
||||
PQGVerify **pVfy);
|
||||
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of P specified by j. Length of h will match length of P.
|
||||
* Length of SEED in bytes specified in seedBytes.
|
||||
* seedBbytes must be in the range [20..255] or an error will result.
|
||||
*/
|
||||
extern SECStatus PK11_PQG_ParamGenSeedLen(unsigned int j,
|
||||
unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy);
|
||||
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of P specified by L.
|
||||
* if L is greater than 1024 then the resulting verify parameters will be
|
||||
* DSA2.
|
||||
* Length of Q specified by N. If zero, The PKCS #11 module will
|
||||
* pick an appropriately sized Q for L. If N is specified and L = 1024, then
|
||||
* the resulting verify parameters will be DSA2, Otherwise DSA1 parameters
|
||||
* will be returned.
|
||||
* Length of SEED in bytes specified in seedBytes.
|
||||
*
|
||||
* The underlying PKCS #11 module will check the values for L, N,
|
||||
* and seedBytes. The rules for softoken are:
|
||||
*
|
||||
* If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits.
|
||||
* If L <= 1024, then N must be 0 or 160.
|
||||
* If L >= 1024, then L and N must match the following table:
|
||||
* L=1024 N=0 or 160
|
||||
* L=2048 N=0 or 224
|
||||
* L=2048 N=256
|
||||
* L=3072 N=0 or 256
|
||||
* if L <= 1024
|
||||
* seedBbytes must be in the range [20..256].
|
||||
* if L >= 1024
|
||||
* seedBbytes must be in the range [20..L/16].
|
||||
*/
|
||||
extern SECStatus
|
||||
PK11_PQG_ParamGenV2(unsigned int L, unsigned int N, unsigned int seedBytes,
|
||||
PQGParams **pParams, PQGVerify **pVfy);
|
||||
|
||||
/* Test PQGParams for validity as DSS PQG values.
|
||||
* If vfy is non-NULL, test PQGParams to make sure they were generated
|
||||
* using the specified seed, counter, and h values.
|
||||
*
|
||||
* Return value indicates whether Verification operation ran successfully
|
||||
* to completion, but does not indicate if PQGParams are valid or not.
|
||||
* If return value is SECSuccess, then *pResult has these meanings:
|
||||
* SECSuccess: PQGParams are valid.
|
||||
* SECFailure: PQGParams are invalid.
|
||||
*
|
||||
* Verify the following 12 facts about PQG counter SEED g and h
|
||||
* These tests are specified in FIPS 186-3 Appendix A.1.1.1, A.1.1.3, and A.2.2
|
||||
* PQG_VerifyParams in softoken/freebl will automatically choose the
|
||||
* appropriate test.
|
||||
*/
|
||||
extern SECStatus PK11_PQG_VerifyParams(const PQGParams *params,
|
||||
const PQGVerify *vfy, SECStatus *result);
|
||||
extern void PK11_PQG_DestroyParams(PQGParams *params);
|
||||
extern void PK11_PQG_DestroyVerify(PQGVerify *vfy);
|
||||
|
||||
/**************************************************************************
|
||||
* Return a pointer to a new PQGParams struct that is constructed from *
|
||||
* copies of the arguments passed in. *
|
||||
* Return NULL on failure. *
|
||||
**************************************************************************/
|
||||
extern PQGParams *PK11_PQG_NewParams(const SECItem *prime, const SECItem *subPrime, const SECItem *base);
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "prime" SECItem with the prime value in params.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus PK11_PQG_GetPrimeFromParams(const PQGParams *params,
|
||||
SECItem *prime);
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "subPrime" SECItem with the prime value in params.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus PK11_PQG_GetSubPrimeFromParams(const PQGParams *params,
|
||||
SECItem *subPrime);
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "base" SECItem with the base value in params.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus PK11_PQG_GetBaseFromParams(const PQGParams *params,
|
||||
SECItem *base);
|
||||
|
||||
/**************************************************************************
|
||||
* Return a pointer to a new PQGVerify struct that is constructed from *
|
||||
* copies of the arguments passed in. *
|
||||
* Return NULL on failure. *
|
||||
**************************************************************************/
|
||||
extern PQGVerify *PK11_PQG_NewVerify(unsigned int counter,
|
||||
const SECItem *seed, const SECItem *h);
|
||||
|
||||
/**************************************************************************
|
||||
* Returns "counter" value from the PQGVerify.
|
||||
**************************************************************************/
|
||||
extern unsigned int PK11_PQG_GetCounterFromVerify(const PQGVerify *verify);
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "seed" SECItem with the seed value in verify.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus PK11_PQG_GetSeedFromVerify(const PQGVerify *verify,
|
||||
SECItem *seed);
|
||||
|
||||
/**************************************************************************
|
||||
* Fills in caller's "h" SECItem with the h value in verify.
|
||||
* Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
|
||||
**************************************************************************/
|
||||
extern SECStatus PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem *h);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
187
security/nss/lib/pk11wrap/pk11priv.h
Normal file
187
security/nss/lib/pk11wrap/pk11priv.h
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _PK11PRIV_H_
|
||||
#define _PK11PRIV_H_
|
||||
#include "plarena.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"
|
||||
#include "cmsreclist.h"
|
||||
|
||||
/*
|
||||
* These are the private NSS functions. They are not exported by nss.def, and
|
||||
* are not callable outside nss3.dll.
|
||||
*/
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/************************************************************
|
||||
* Generic Slot Lists Management
|
||||
************************************************************/
|
||||
PK11SlotList *PK11_NewSlotList(void);
|
||||
PK11SlotList *PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type,
|
||||
PRBool needRW, void *wincx);
|
||||
SECStatus PK11_AddSlotToList(PK11SlotList *list, PK11SlotInfo *slot, PRBool sorted);
|
||||
SECStatus PK11_DeleteSlotFromList(PK11SlotList *list, PK11SlotListElement *le);
|
||||
PK11SlotListElement *PK11_FindSlotElement(PK11SlotList *list,
|
||||
PK11SlotInfo *slot);
|
||||
PK11SlotInfo *PK11_FindSlotBySerial(char *serial);
|
||||
int PK11_GetMaxKeyLength(CK_MECHANISM_TYPE type);
|
||||
|
||||
/************************************************************
|
||||
* Generic Slot Management
|
||||
************************************************************/
|
||||
CK_OBJECT_HANDLE PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject);
|
||||
SECStatus PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
|
||||
CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result);
|
||||
CK_ULONG PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
|
||||
CK_ATTRIBUTE_TYPE type);
|
||||
char *PK11_MakeString(PLArenaPool *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(SECMODModule *mod);
|
||||
void PK11_EnterSlotMonitor(PK11SlotInfo *);
|
||||
void PK11_ExitSlotMonitor(PK11SlotInfo *);
|
||||
void PK11_CleanKeyList(PK11SlotInfo *slot);
|
||||
|
||||
/************************************************************
|
||||
* Slot Password Management
|
||||
************************************************************/
|
||||
SECStatus PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
|
||||
PRBool loadCerts, void *wincx, PRBool alreadyLocked,
|
||||
PRBool contextSpecific);
|
||||
SECStatus PK11_VerifyPW(PK11SlotInfo *slot, char *pw);
|
||||
void PK11_HandlePasswordCheck(PK11SlotInfo *slot, void *wincx);
|
||||
void PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func);
|
||||
void PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func);
|
||||
|
||||
/************************************************************
|
||||
* Manage the built-In Slot Lists
|
||||
************************************************************/
|
||||
SECStatus PK11_InitSlotLists(void);
|
||||
void PK11_DestroySlotLists(void);
|
||||
PK11SlotList *PK11_GetSlotList(CK_MECHANISM_TYPE type);
|
||||
void PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count);
|
||||
void PK11_ClearSlotList(PK11SlotInfo *slot);
|
||||
|
||||
/******************************************************************
|
||||
* Slot initialization
|
||||
******************************************************************/
|
||||
SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts);
|
||||
void PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot);
|
||||
PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot);
|
||||
SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot);
|
||||
void pk11_SetInternalKeySlot(PK11SlotInfo *slot);
|
||||
PK11SlotInfo *pk11_SwapInternalKeySlot(PK11SlotInfo *slot);
|
||||
void pk11_SetInternalKeySlotIfFirst(PK11SlotInfo *slot);
|
||||
|
||||
/*********************************************************************
|
||||
* Mechanism Mapping functions
|
||||
*********************************************************************/
|
||||
void PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
|
||||
CK_MECHANISM_TYPE keygen, CK_MECHANISM_TYPE pad,
|
||||
int ivLen, int blocksize);
|
||||
CK_MECHANISM_TYPE PK11_GetKeyMechanism(CK_KEY_TYPE type);
|
||||
CK_MECHANISM_TYPE PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size);
|
||||
|
||||
/**********************************************************************
|
||||
* Symetric, Public, and Private Keys
|
||||
**********************************************************************/
|
||||
/* Key Generation specialized for SDR (fixed DES3 key) */
|
||||
PK11SymKey *PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx);
|
||||
SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType,
|
||||
CK_OBJECT_HANDLE id);
|
||||
CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert,
|
||||
void *wincx, PK11SlotInfo **pSlot);
|
||||
PK11SymKey *pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey);
|
||||
|
||||
/**********************************************************************
|
||||
* Certs
|
||||
**********************************************************************/
|
||||
SECStatus PK11_TraversePrivateKeysInSlot(PK11SlotInfo *slot,
|
||||
SECStatus (*callback)(SECKEYPrivateKey *, void *), void *arg);
|
||||
SECKEYPrivateKey *PK11_FindPrivateKeyFromNickname(char *nickname, void *wincx);
|
||||
CK_OBJECT_HANDLE *PK11_FindObjectsFromNickname(char *nickname,
|
||||
PK11SlotInfo **slotptr, CK_OBJECT_CLASS objclass, int *returnCount,
|
||||
void *wincx);
|
||||
CK_OBJECT_HANDLE PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE peer,
|
||||
CK_OBJECT_CLASS o_class);
|
||||
CK_BBOOL PK11_HasAttributeSet(PK11SlotInfo *slot,
|
||||
CK_OBJECT_HANDLE id,
|
||||
CK_ATTRIBUTE_TYPE type,
|
||||
PRBool haslock);
|
||||
CK_RV PK11_GetAttributes(PLArenaPool *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_GetKEAMatchedCerts(PK11SlotInfo *slot1,
|
||||
PK11SlotInfo *slot2, CERTCertificate **cert1, CERTCertificate **cert2);
|
||||
SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
|
||||
SECStatus (*callback)(CERTCertificate *, void *), void *arg);
|
||||
SECStatus PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx);
|
||||
|
||||
/**********************************************************************
|
||||
* Crypto Contexts
|
||||
**********************************************************************/
|
||||
PK11Context *PK11_CreateContextByRawKey(PK11SlotInfo *slot,
|
||||
CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation,
|
||||
SECItem *key, SECItem *param, void *wincx);
|
||||
PRBool PK11_HashOK(SECOidTag hashAlg);
|
||||
|
||||
/**********************************************************************
|
||||
* Functions which are deprecated....
|
||||
**********************************************************************/
|
||||
|
||||
SECItem *
|
||||
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *handle,
|
||||
SECItem *derName, int type, char **url);
|
||||
|
||||
CK_OBJECT_HANDLE
|
||||
PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl,
|
||||
SECItem *name, char *url, int type);
|
||||
|
||||
SECItem *
|
||||
PK11_FindSMimeProfile(PK11SlotInfo **slotp, char *emailAddr, SECItem *derSubj,
|
||||
SECItem **profileTime);
|
||||
SECStatus
|
||||
PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
|
||||
SECItem *emailProfile, SECItem *profileTime);
|
||||
|
||||
PRBool PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle);
|
||||
|
||||
char *PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id);
|
||||
SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
|
||||
const char *nickname);
|
||||
|
||||
/* private */
|
||||
SECStatus pk11_TraverseAllSlots(SECStatus (*callback)(PK11SlotInfo *, void *),
|
||||
void *cbArg, PRBool forceLogin, void *pwArg);
|
||||
|
||||
/* fetch multiple CRLs for a specific issuer */
|
||||
SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem *issuer,
|
||||
void *wincx);
|
||||
|
||||
/* set global options for NSS PKCS#11 module loader */
|
||||
SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
|
||||
PRBool allowAlreadyInitializedModules,
|
||||
PRBool dontFinalizeModules);
|
||||
|
||||
/* return whether NSS is allowed to call C_Finalize */
|
||||
PRBool pk11_getFinalizeModulesOption(void);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
879
security/nss/lib/pk11wrap/pk11pub.h
Normal file
879
security/nss/lib/pk11wrap/pk11pub.h
Normal file
|
|
@ -0,0 +1,879 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _PK11PUB_H_
|
||||
#define _PK11PUB_H_
|
||||
#include "plarena.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"
|
||||
#include "cmsreclist.h"
|
||||
|
||||
/*
|
||||
* Exported PK11 wrap functions.
|
||||
*/
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/************************************************************
|
||||
* Generic Slot Lists Management
|
||||
************************************************************/
|
||||
void PK11_FreeSlotList(PK11SlotList *list);
|
||||
SECStatus PK11_FreeSlotListElement(PK11SlotList *list, PK11SlotListElement *le);
|
||||
PK11SlotListElement *PK11_GetFirstSafe(PK11SlotList *list);
|
||||
PK11SlotListElement *PK11_GetNextSafe(PK11SlotList *list,
|
||||
PK11SlotListElement *le, PRBool restart);
|
||||
|
||||
/************************************************************
|
||||
* Generic Slot Management
|
||||
************************************************************/
|
||||
PK11SlotInfo *PK11_ReferenceSlot(PK11SlotInfo *slot);
|
||||
void PK11_FreeSlot(PK11SlotInfo *slot);
|
||||
SECStatus PK11_DestroyObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object);
|
||||
SECStatus PK11_DestroyTokenObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object);
|
||||
PK11SlotInfo *PK11_GetInternalKeySlot(void);
|
||||
PK11SlotInfo *PK11_GetInternalSlot(void);
|
||||
SECStatus PK11_Logout(PK11SlotInfo *slot);
|
||||
void PK11_LogoutAll(void);
|
||||
|
||||
/************************************************************
|
||||
* 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, const char *pw);
|
||||
PRBool PK11_IsLoggedIn(PK11SlotInfo *slot, void *wincx);
|
||||
SECStatus PK11_InitPin(PK11SlotInfo *slot, const char *ssopw,
|
||||
const char *pk11_userpwd);
|
||||
SECStatus PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw,
|
||||
const char *newpw);
|
||||
void PK11_SetPasswordFunc(PK11PasswordFunc func);
|
||||
int PK11_GetMinimumPwdLength(PK11SlotInfo *slot);
|
||||
SECStatus PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd);
|
||||
SECStatus PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx);
|
||||
SECStatus PK11_TokenRefresh(PK11SlotInfo *slot);
|
||||
|
||||
/******************************************************************
|
||||
* Slot info functions
|
||||
******************************************************************/
|
||||
PK11SlotInfo *PK11_FindSlotByName(const char *name);
|
||||
/******************************************************************
|
||||
* PK11_FindSlotsByNames searches for a PK11SlotInfo using one or
|
||||
* more criteria : dllName, slotName and tokenName . In addition, if
|
||||
* presentOnly is set , only slots with a token inserted will be
|
||||
* returned.
|
||||
******************************************************************/
|
||||
PK11SlotList *PK11_FindSlotsByNames(const char *dllName,
|
||||
const char *slotName, const char *tokenName, PRBool presentOnly);
|
||||
PRBool PK11_IsReadOnly(PK11SlotInfo *slot);
|
||||
PRBool PK11_IsInternal(PK11SlotInfo *slot);
|
||||
PRBool PK11_IsInternalKeySlot(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_IsRemovable(PK11SlotInfo *slot);
|
||||
PRBool PK11_NeedUserInit(PK11SlotInfo *slot);
|
||||
PRBool PK11_ProtectedAuthenticationPath(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);
|
||||
PRBool PK11_HasRootCerts(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);
|
||||
/*
|
||||
* wait for a specific slot event.
|
||||
* event is a specific event to wait for. Currently only
|
||||
* PK11TokenChangeOrRemovalEvent and PK11TokenPresentEvents are defined.
|
||||
* timeout can be an interval time to wait, PR_INTERVAL_NO_WAIT (meaning only
|
||||
* poll once), or PR_INTERVAL_NO_TIMEOUT (meaning block until a change).
|
||||
* pollInterval is a suggested pulling interval value. '0' means use the
|
||||
* default. Future implementations that don't poll may ignore this value.
|
||||
* series is the current series for the last slot. This should be the series
|
||||
* value for the slot the last time you read persistant information from the
|
||||
* slot. For instance, if you publish a cert from the slot, you should obtain
|
||||
* the slot series at that time. Then PK11_WaitForTokenEvent can detect a
|
||||
* a change in the slot between the time you publish and the time
|
||||
* PK11_WaitForTokenEvent is called, elliminating potential race conditions.
|
||||
*
|
||||
* The current status that is returned is:
|
||||
* PK11TokenNotRemovable - always returned for any non-removable token.
|
||||
* PK11TokenPresent - returned when the token is present and we are waiting
|
||||
* on a PK11TokenPresentEvent. Then next event to look for is a
|
||||
* PK11TokenChangeOrRemovalEvent.
|
||||
* PK11TokenChanged - returned when the old token has been removed and a new
|
||||
* token ad been inserted, and we are waiting for a
|
||||
* PK11TokenChangeOrRemovalEvent. The next event to look for is another
|
||||
* PK11TokenChangeOrRemovalEvent.
|
||||
* PK11TokenRemoved - returned when the token is not present and we are
|
||||
* waiting for a PK11TokenChangeOrRemovalEvent. The next event to look for
|
||||
* is a PK11TokenPresentEvent.
|
||||
*/
|
||||
PK11TokenStatus PK11_WaitForTokenEvent(PK11SlotInfo *slot, PK11TokenEvent event,
|
||||
PRIntervalTime timeout, PRIntervalTime pollInterval, int series);
|
||||
|
||||
PRBool PK11_NeedPWInit(void);
|
||||
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);
|
||||
PK11SlotInfo *PK11_GetBestSlotMultipleWithAttributes(CK_MECHANISM_TYPE *type,
|
||||
CK_FLAGS *mechFlag, unsigned int *keySize,
|
||||
unsigned int count, void *wincx);
|
||||
PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type,
|
||||
unsigned int count, void *wincx);
|
||||
PK11SlotInfo *PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx);
|
||||
PK11SlotInfo *PK11_GetBestSlotWithAttributes(CK_MECHANISM_TYPE type,
|
||||
CK_FLAGS mechFlag, unsigned int keySize, void *wincx);
|
||||
CK_MECHANISM_TYPE PK11_GetBestWrapMechanism(PK11SlotInfo *slot);
|
||||
int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
|
||||
|
||||
/*
|
||||
* Open a new database using the softoken. The caller is responsible for making
|
||||
* sure the module spec is correct and usable. The caller should ask for one
|
||||
* new database per call if the caller wants to get meaningful information
|
||||
* about the new database.
|
||||
*
|
||||
* moduleSpec is the same data that you would pass to softoken at
|
||||
* initialization time under the 'tokens' options. For example, if you were
|
||||
* to specify tokens=<0x4=[configdir='./mybackup' tokenDescription='Backup']>
|
||||
* You would specify "configdir='./mybackup' tokenDescription='Backup'" as your
|
||||
* module spec here. The slot ID will be calculated for you by
|
||||
* SECMOD_OpenUserDB().
|
||||
*
|
||||
* Typical parameters here are configdir, tokenDescription and flags.
|
||||
*
|
||||
* a Full list is below:
|
||||
*
|
||||
*
|
||||
* configDir - The location of the databases for this token. If configDir is
|
||||
* not specified, and noCertDB and noKeyDB is not specified, the load
|
||||
* will fail.
|
||||
* certPrefix - Cert prefix for this token.
|
||||
* keyPrefix - Prefix for the key database for this token. (if not specified,
|
||||
* certPrefix will be used).
|
||||
* tokenDescription - The label value for this token returned in the
|
||||
* CK_TOKEN_INFO structure with an internationalize string (UTF8).
|
||||
* This value will be truncated at 32 bytes (no NULL, partial UTF8
|
||||
* characters dropped). You should specify a user friendly name here
|
||||
* as this is the value the token will be referred to in most
|
||||
* application UI's. You should make sure tokenDescription is unique.
|
||||
* slotDescription - The slotDescription value for this token returned
|
||||
* in the CK_SLOT_INFO structure with an internationalize string
|
||||
* (UTF8). This value will be truncated at 64 bytes (no NULL, partial
|
||||
* UTF8 characters dropped). This name will not change after the
|
||||
* database is closed. It should have some number to make this unique.
|
||||
* minPWLen - minimum password length for this token.
|
||||
* flags - comma separated list of flag values, parsed case-insensitive.
|
||||
* Valid flags are:
|
||||
* readOnly - Databases should be opened read only.
|
||||
* noCertDB - Don't try to open a certificate database.
|
||||
* noKeyDB - Don't try to open a key database.
|
||||
* forceOpen - Don't fail to initialize the token if the
|
||||
* databases could not be opened.
|
||||
* passwordRequired - zero length passwords are not acceptable
|
||||
* (valid only if there is a keyDB).
|
||||
* optimizeSpace - allocate smaller hash tables and lock tables.
|
||||
* When this flag is not specified, Softoken will allocate
|
||||
* large tables to prevent lock contention.
|
||||
*/
|
||||
PK11SlotInfo *SECMOD_OpenUserDB(const char *moduleSpec);
|
||||
SECStatus SECMOD_CloseUserDB(PK11SlotInfo *slot);
|
||||
|
||||
/*
|
||||
* This is exactly the same as OpenUserDB except it can be called on any
|
||||
* module that understands softoken style new slot entries. The resulting
|
||||
* slot can be closed using SECMOD_CloseUserDB above. Value of moduleSpec
|
||||
* is token specific.
|
||||
*/
|
||||
PK11SlotInfo *SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec);
|
||||
|
||||
/*
|
||||
* merge the permanent objects from on token to another
|
||||
*/
|
||||
SECStatus PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
|
||||
PK11MergeLog *log, void *targetPwArg, void *sourcePwArg);
|
||||
|
||||
/*
|
||||
* create and destroy merge logs needed by PK11_MergeTokens
|
||||
*/
|
||||
PK11MergeLog *PK11_CreateMergeLog(void);
|
||||
void PK11_DestroyMergeLog(PK11MergeLog *log);
|
||||
|
||||
/*********************************************************************
|
||||
* Mechanism Mapping functions
|
||||
*********************************************************************/
|
||||
CK_KEY_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,
|
||||
PLArenaPool *arena, SECAlgorithmID *algid);
|
||||
SECStatus PK11_SeedRandom(PK11SlotInfo *, unsigned char *data, int len);
|
||||
SECStatus PK11_GenerateRandomOnSlot(PK11SlotInfo *, unsigned char *data, int len);
|
||||
SECStatus PK11_RandomUpdate(void *data, size_t bytes);
|
||||
SECStatus PK11_GenerateRandom(unsigned char *data, int len);
|
||||
|
||||
/* warning: cannot work with pkcs 5 v2
|
||||
* use algorithm ID s instead of pkcs #11 mechanism pointers */
|
||||
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);
|
||||
CK_MECHANISM_TYPE PK11_MapSignKeyType(KeyType keyType);
|
||||
|
||||
/**********************************************************************
|
||||
* Symmetric, Public, and Private Keys
|
||||
**********************************************************************/
|
||||
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_ImportSymKeyWithFlags(PK11SlotInfo *slot,
|
||||
CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation,
|
||||
SECItem *key, CK_FLAGS flags, PRBool isPerm, 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);
|
||||
/*
|
||||
* This function is not thread-safe. It can only be called when only
|
||||
* one thread has a reference to wrapKey.
|
||||
*/
|
||||
void PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey);
|
||||
CK_MECHANISM_TYPE PK11_GetMechanism(PK11SymKey *symKey);
|
||||
/*
|
||||
* import a public key into the desired slot
|
||||
*
|
||||
* This function takes a public key structure and creates a public key in a
|
||||
* given slot. If isToken is set, then a persistant public key is created.
|
||||
*
|
||||
* Note: it is possible for this function to return a handle for a key which
|
||||
* is persistant, even if isToken is not set.
|
||||
*/
|
||||
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);
|
||||
PK11SymKey *PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
SECItem *param, int keySize, SECItem *keyid,
|
||||
PRBool isToken, void *wincx);
|
||||
PK11SymKey *PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot,
|
||||
CK_MECHANISM_TYPE type, SECItem *param,
|
||||
int keySize, SECItem *keyid, CK_FLAGS opFlags,
|
||||
PK11AttrFlags attrFlags, void *wincx);
|
||||
/* Generates a key using the exact template supplied by the caller. The other
|
||||
* PK11_[Token]KeyGen mechanisms should be used instead of this one whenever
|
||||
* they work because they include/exclude the CKA_VALUE_LEN template value
|
||||
* based on the mechanism type as required by many tokens.
|
||||
*
|
||||
* keyGenType should be PK11_GetKeyGenWithSize(type, <key size>) or it should
|
||||
* be equal to type if PK11_GetKeyGenWithSize cannot be used (e.g. because
|
||||
* pk11wrap does not know about the mechanisms).
|
||||
*/
|
||||
PK11SymKey *PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
CK_MECHANISM_TYPE keyGenType,
|
||||
SECItem *param, CK_ATTRIBUTE *attrs,
|
||||
unsigned int attrsCount, void *wincx);
|
||||
PK11SymKey *PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname,
|
||||
void *wincx);
|
||||
PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey);
|
||||
CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *key);
|
||||
CK_OBJECT_HANDLE PK11_GetSymKeyHandle(PK11SymKey *symKey);
|
||||
|
||||
/*
|
||||
* PK11_SetSymKeyUserData
|
||||
* sets generic user data on keys (usually a pointer to a data structure)
|
||||
* that can later be retrieved by PK11_GetSymKeyUserData().
|
||||
* symKey - key where data will be set.
|
||||
* data - data to be set.
|
||||
* freefunc - function used to free the data.
|
||||
* Setting user data on symKeys with existing user data already set will cause
|
||||
* the existing user data to be freed before the new user data is set.
|
||||
* Freeing user data is done by calling the user specified freefunc.
|
||||
* If freefunc is NULL, the user data is assumed to be global or static an
|
||||
* not freed. Passing NULL for user data to PK11_SetSymKeyUserData has the
|
||||
* effect of freeing any existing user data, and clearing the user data
|
||||
* pointer. If user data exists when the symKey is finally freed, that
|
||||
* data will be freed with freefunc.
|
||||
*
|
||||
* Applications should only use this function on keys which the application
|
||||
* has created directly, as there is only one user data value per key.
|
||||
*/
|
||||
void PK11_SetSymKeyUserData(PK11SymKey *symKey, void *data,
|
||||
PK11FreeDataFunc freefunc);
|
||||
/* PK11_GetSymKeyUserData
|
||||
* retrieves generic user data which was set on a key by
|
||||
* PK11_SetSymKeyUserData.
|
||||
* symKey - key with data to be fetched
|
||||
*
|
||||
* If no data exists, or the data has been cleared, PK11_GetSymKeyUserData
|
||||
* will return NULL. Returned data is still owned and managed by the SymKey,
|
||||
* the caller should not free the data.
|
||||
*
|
||||
*/
|
||||
void *PK11_GetSymKeyUserData(PK11SymKey *symKey);
|
||||
|
||||
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);
|
||||
/* move a key to 'slot' optionally set the key attributes according to either
|
||||
* operation or the flags and making the key permanent at the same time.
|
||||
* If the key is moved to the same slot, operation and flags values are
|
||||
* currently ignored */
|
||||
PK11SymKey *PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
|
||||
CK_FLAGS flags, PRBool perm, PK11SymKey *symKey);
|
||||
/*
|
||||
* derive a new key from the base key.
|
||||
* PK11_Derive returns a key which can do exactly one operation, and is
|
||||
* ephemeral (session key).
|
||||
* PK11_DeriveWithFlags is the same as PK11_Derive, except you can use
|
||||
* CKF_ flags to enable more than one operation.
|
||||
* PK11_DeriveWithFlagsPerm is the same as PK11_DeriveWithFlags except you can
|
||||
* (optionally) make the key permanent (token key).
|
||||
*/
|
||||
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_DeriveWithFlagsPerm(PK11SymKey *baseKey,
|
||||
CK_MECHANISM_TYPE derive,
|
||||
SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
|
||||
int keySize, CK_FLAGS flags, PRBool isPerm);
|
||||
PK11SymKey *
|
||||
PK11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
|
||||
SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
|
||||
int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs,
|
||||
PRBool isPerm);
|
||||
|
||||
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_PubDeriveWithKDF(SECKEYPrivateKey *privKey,
|
||||
SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB,
|
||||
CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
|
||||
CK_ATTRIBUTE_TYPE operation, int keySize,
|
||||
CK_ULONG kdf, SECItem *sharedData, void *wincx);
|
||||
|
||||
/*
|
||||
* unwrap a new key with a symetric key.
|
||||
* PK11_Unwrap returns a key which can do exactly one operation, and is
|
||||
* ephemeral (session key).
|
||||
* PK11_UnwrapWithFlags is the same as PK11_Unwrap, except you can use
|
||||
* CKF_ flags to enable more than one operation.
|
||||
* PK11_UnwrapWithFlagsPerm is the same as PK11_UnwrapWithFlags except you can
|
||||
* (optionally) make the key permanent (token key).
|
||||
*/
|
||||
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_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey,
|
||||
CK_MECHANISM_TYPE wrapType,
|
||||
SECItem *param, SECItem *wrappedKey,
|
||||
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
|
||||
int keySize, CK_FLAGS flags, PRBool isPerm);
|
||||
|
||||
/*
|
||||
* unwrap a new key with a private key.
|
||||
* PK11_PubUnwrap returns a key which can do exactly one operation, and is
|
||||
* ephemeral (session key).
|
||||
* PK11_PubUnwrapWithFlagsPerm is the same as PK11_PubUnwrap except you can
|
||||
* use * CKF_ flags to enable more than one operation, and optionally make
|
||||
* the key permanent (token key).
|
||||
*/
|
||||
PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey,
|
||||
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize);
|
||||
PK11SymKey *PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey,
|
||||
SECItem *wrappedKey, CK_MECHANISM_TYPE target,
|
||||
CK_ATTRIBUTE_TYPE operation, int keySize,
|
||||
CK_FLAGS flags, PRBool isPerm);
|
||||
PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
SECItem *keyID, void *wincx);
|
||||
SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force);
|
||||
SECStatus PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey);
|
||||
SECStatus PK11_DeleteTokenSymKey(PK11SymKey *symKey);
|
||||
SECStatus PK11_DeleteTokenCertAndKey(CERTCertificate *cert, void *wincx);
|
||||
SECKEYPrivateKey *PK11_LoadPrivKey(PK11SlotInfo *slot,
|
||||
SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
|
||||
PRBool token, PRBool sensitive);
|
||||
char *PK11_GetSymKeyNickname(PK11SymKey *symKey);
|
||||
char *PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey);
|
||||
char *PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey);
|
||||
SECStatus PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname);
|
||||
SECStatus PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey,
|
||||
const char *nickname);
|
||||
SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey,
|
||||
const char *nickname);
|
||||
|
||||
/*
|
||||
* Using __PK11_SetCertificateNickname is *DANGEROUS*.
|
||||
*
|
||||
* The API will update the NSS database, but it *will NOT* update the in-memory data.
|
||||
* As a result, after calling this API, there will be INCONSISTENCY between
|
||||
* in-memory data and the database.
|
||||
*
|
||||
* Use of the API should be limited to short-lived tools, which will exit immediately
|
||||
* after using this API.
|
||||
*
|
||||
* If you ignore this warning, your process is TAINTED and will most likely misbehave.
|
||||
*/
|
||||
SECStatus __PK11_SetCertificateNickname(CERTCertificate *cert,
|
||||
const char *nickname);
|
||||
|
||||
/* 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);
|
||||
|
||||
/*
|
||||
* Explicitly set the key usage for the generated private key.
|
||||
*
|
||||
* This allows us to specify single use EC and RSA keys whose usage
|
||||
* can be regulated by the underlying token.
|
||||
*
|
||||
* The underlying key usage is set using opFlags. opFlagsMask specifies
|
||||
* which operations are specified by opFlags. For instance to turn encrypt
|
||||
* on and signing off, opFlags would be CKF_ENCRYPT|CKF_DECRYPT and
|
||||
* opFlagsMask would be CKF_ENCRYPT|CKF_DECRYPT|CKF_SIGN|CKF_VERIFY. You
|
||||
* need to specify both the public and private key flags,
|
||||
* PK11_GenerateKeyPairWithOpFlags will sort out the correct flag to the
|
||||
* correct key type. Flags not specified in opFlagMask will be defaulted
|
||||
* according to mechanism type and token capabilities.
|
||||
*/
|
||||
SECKEYPrivateKey *PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,
|
||||
CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
|
||||
PK11AttrFlags attrFlags, CK_FLAGS opFlags, CK_FLAGS opFlagsMask,
|
||||
void *wincx);
|
||||
/*
|
||||
* The attrFlags is the logical OR of the PK11_ATTR_XXX bitflags.
|
||||
* These flags apply to the private key. The PK11_ATTR_TOKEN,
|
||||
* PK11_ATTR_SESSION, PK11_ATTR_MODIFIABLE, and PK11_ATTR_UNMODIFIABLE
|
||||
* flags also apply to the public key.
|
||||
*/
|
||||
SECKEYPrivateKey *PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,
|
||||
CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
|
||||
PK11AttrFlags attrFlags, void *wincx);
|
||||
SECKEYPrivateKey *PK11_GenerateKeyPair(PK11SlotInfo *slot,
|
||||
CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
|
||||
PRBool isPerm, PRBool isSensitive, 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);
|
||||
int PK11_GetPrivateModulusLen(SECKEYPrivateKey *key);
|
||||
|
||||
SECStatus PK11_Decrypt(PK11SymKey *symkey,
|
||||
CK_MECHANISM_TYPE mechanism, SECItem *param,
|
||||
unsigned char *out, unsigned int *outLen,
|
||||
unsigned int maxLen,
|
||||
const unsigned char *enc, unsigned int encLen);
|
||||
SECStatus PK11_Encrypt(PK11SymKey *symKey,
|
||||
CK_MECHANISM_TYPE mechanism, SECItem *param,
|
||||
unsigned char *out, unsigned int *outLen,
|
||||
unsigned int maxLen,
|
||||
const unsigned char *data, unsigned int dataLen);
|
||||
|
||||
/* note: despite the name, this function takes a private key. */
|
||||
SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key,
|
||||
unsigned char *data, unsigned *outLen,
|
||||
unsigned int maxLen,
|
||||
const unsigned char *enc, unsigned encLen);
|
||||
#define PK11_PrivDecryptRaw PK11_PubDecryptRaw
|
||||
/* The encrypt function that complements the above decrypt function. */
|
||||
SECStatus PK11_PubEncryptRaw(SECKEYPublicKey *key,
|
||||
unsigned char *enc,
|
||||
const unsigned char *data, unsigned dataLen,
|
||||
void *wincx);
|
||||
|
||||
SECStatus PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key,
|
||||
unsigned char *data, unsigned *outLen,
|
||||
unsigned int maxLen,
|
||||
const unsigned char *enc, unsigned encLen);
|
||||
/* The encrypt function that complements the above decrypt function. */
|
||||
SECStatus PK11_PubEncryptPKCS1(SECKEYPublicKey *key,
|
||||
unsigned char *enc,
|
||||
const unsigned char *data, unsigned dataLen,
|
||||
void *wincx);
|
||||
|
||||
SECStatus PK11_PrivDecrypt(SECKEYPrivateKey *key,
|
||||
CK_MECHANISM_TYPE mechanism, SECItem *param,
|
||||
unsigned char *out, unsigned int *outLen,
|
||||
unsigned int maxLen,
|
||||
const unsigned char *enc, unsigned int encLen);
|
||||
SECStatus PK11_PubEncrypt(SECKEYPublicKey *key,
|
||||
CK_MECHANISM_TYPE mechanism, SECItem *param,
|
||||
unsigned char *out, unsigned int *outLen,
|
||||
unsigned int maxLen,
|
||||
const unsigned char *data, unsigned int 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_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
||||
SECKEYPrivateKeyInfo *pki, SECItem *nickname,
|
||||
SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
|
||||
unsigned int usage, SECKEYPrivateKey **privk, void *wincx);
|
||||
SECStatus PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot,
|
||||
SECItem *derPKI, SECItem *nickname,
|
||||
SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
|
||||
unsigned int usage, void *wincx);
|
||||
SECStatus PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
||||
SECItem *derPKI, SECItem *nickname,
|
||||
SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
|
||||
unsigned int usage, SECKEYPrivateKey **privk, 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);
|
||||
SECStatus PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
||||
SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
|
||||
SECItem *nickname, SECItem *publicValue, PRBool isPerm,
|
||||
PRBool isPrivate, KeyType type,
|
||||
unsigned int usage, SECKEYPrivateKey **privk, void *wincx);
|
||||
SECItem *PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx);
|
||||
SECKEYPrivateKeyInfo *PK11_ExportPrivKeyInfo(
|
||||
SECKEYPrivateKey *pk, void *wincx);
|
||||
SECKEYPrivateKeyInfo *PK11_ExportPrivateKeyInfo(
|
||||
CERTCertificate *cert, void *wincx);
|
||||
SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivKeyInfo(
|
||||
PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem,
|
||||
SECKEYPrivateKey *pk, int iteration, 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);
|
||||
/*
|
||||
* The caller of PK11_DEREncodePublicKey should free the returned SECItem with
|
||||
* a SECITEM_FreeItem(..., PR_TRUE) call.
|
||||
*/
|
||||
SECItem *PK11_DEREncodePublicKey(const SECKEYPublicKey *pubk);
|
||||
PK11SymKey *PK11_CopySymKeyForSigning(PK11SymKey *originalKey,
|
||||
CK_MECHANISM_TYPE mech);
|
||||
SECKEYPrivateKeyList *PK11_ListPrivKeysInSlot(PK11SlotInfo *slot,
|
||||
char *nickname, void *wincx);
|
||||
SECKEYPublicKeyList *PK11_ListPublicKeysInSlot(PK11SlotInfo *slot,
|
||||
char *nickname);
|
||||
SECKEYPQGParams *PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey);
|
||||
/* deprecated */
|
||||
SECKEYPrivateKeyList *PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot);
|
||||
|
||||
PK11SymKey *PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk,
|
||||
void *wincx);
|
||||
SECKEYPrivateKey *PK11_ConvertSessionPrivKeyToTokenPrivKey(
|
||||
SECKEYPrivateKey *privk, void *wincx);
|
||||
SECKEYPrivateKey *PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
|
||||
SECKEYPrivateKey *privKey);
|
||||
|
||||
/**********************************************************************
|
||||
* Certs
|
||||
**********************************************************************/
|
||||
SECItem *PK11_MakeIDFromPubKey(SECItem *pubKeyData);
|
||||
SECStatus PK11_TraverseSlotCerts(
|
||||
SECStatus (*callback)(CERTCertificate *, SECItem *, void *),
|
||||
void *arg, void *wincx);
|
||||
CERTCertificate *PK11_FindCertFromNickname(const char *nickname, void *wincx);
|
||||
CERTCertList *PK11_FindCertsFromEmailAddress(const char *email, void *wincx);
|
||||
CERTCertList *PK11_FindCertsFromNickname(const char *nickname, void *wincx);
|
||||
CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey);
|
||||
SECStatus PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||
CK_OBJECT_HANDLE key, const char *nickname,
|
||||
PRBool includeTrust);
|
||||
SECStatus PK11_ImportDERCert(PK11SlotInfo *slot, SECItem *derCert,
|
||||
CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust);
|
||||
PK11SlotInfo *PK11_ImportCertForKey(CERTCertificate *cert,
|
||||
const char *nickname, void *wincx);
|
||||
PK11SlotInfo *PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,
|
||||
void *wincx);
|
||||
PK11SlotInfo *PK11_KeyForCertExists(CERTCertificate *cert,
|
||||
CK_OBJECT_HANDLE *keyPtr, void *wincx);
|
||||
PK11SlotInfo *PK11_KeyForDERCertExists(SECItem *derCert,
|
||||
CK_OBJECT_HANDLE *keyPtr, void *wincx);
|
||||
CERTCertificate *PK11_FindCertByIssuerAndSN(PK11SlotInfo **slot,
|
||||
CERTIssuerAndSN *sn, void *wincx);
|
||||
CERTCertificate *PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slot,
|
||||
SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip,
|
||||
SECKEYPrivateKey **privKey, void *wincx);
|
||||
int PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist,
|
||||
void *wincx);
|
||||
SECStatus PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert,
|
||||
PK11SlotInfo *slot, SECStatus (*callback)(CERTCertificate *, void *),
|
||||
void *arg);
|
||||
CERTCertificate *PK11_FindCertFromDERCert(PK11SlotInfo *slot,
|
||||
CERTCertificate *cert, void *wincx);
|
||||
CERTCertificate *PK11_FindCertFromDERCertItem(PK11SlotInfo *slot,
|
||||
const SECItem *derCert, void *wincx);
|
||||
SECStatus PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||
char *nickname, PRBool addUsage,
|
||||
void *wincx);
|
||||
CERTCertificate *PK11_FindBestKEAMatch(CERTCertificate *serverCert, void *wincx);
|
||||
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);
|
||||
CERTCertList *PK11_ListCerts(PK11CertListType type, void *pwarg);
|
||||
CERTCertList *PK11_ListCertsInSlot(PK11SlotInfo *slot);
|
||||
CERTSignedCrl *PK11_ImportCRL(PK11SlotInfo *slot, SECItem *derCRL, char *url,
|
||||
int type, void *wincx, PRInt32 importOptions, PLArenaPool *arena, PRInt32 decodeOptions);
|
||||
|
||||
/**********************************************************************
|
||||
* Sign/Verify
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
* Return the length in bytes of a signature generated with the
|
||||
* private key.
|
||||
*
|
||||
* Return 0 or -1 on failure. (XXX Should we fix it to always return
|
||||
* -1 on failure?)
|
||||
*/
|
||||
int PK11_SignatureLen(SECKEYPrivateKey *key);
|
||||
PK11SlotInfo *PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key);
|
||||
SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig,
|
||||
const SECItem *hash);
|
||||
SECStatus PK11_SignWithMechanism(SECKEYPrivateKey *key,
|
||||
CK_MECHANISM_TYPE mechanism,
|
||||
const SECItem *param, SECItem *sig,
|
||||
const SECItem *hash);
|
||||
SECStatus PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
|
||||
SECItem *param, SECItem *sig, const SECItem *data);
|
||||
SECStatus PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
|
||||
SECItem *dsig, void *wincx);
|
||||
SECStatus PK11_Verify(SECKEYPublicKey *key, const SECItem *sig,
|
||||
const SECItem *hash, void *wincx);
|
||||
SECStatus PK11_VerifyWithMechanism(SECKEYPublicKey *key,
|
||||
CK_MECHANISM_TYPE mechanism,
|
||||
const SECItem *param, const SECItem *sig,
|
||||
const SECItem *hash, void *wincx);
|
||||
|
||||
/**********************************************************************
|
||||
* Crypto Contexts
|
||||
**********************************************************************/
|
||||
void PK11_DestroyContext(PK11Context *context, PRBool freeit);
|
||||
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);
|
||||
/*
|
||||
* The output buffer 'out' must be big enough to hold the output of
|
||||
* the hash algorithm 'hashAlg'.
|
||||
*/
|
||||
SECStatus PK11_HashBuf(SECOidTag hashAlg, unsigned char *out,
|
||||
const unsigned char *in, PRInt32 len);
|
||||
SECStatus PK11_DigestOp(PK11Context *context, const unsigned char *in,
|
||||
unsigned len);
|
||||
SECStatus PK11_CipherOp(PK11Context *context, unsigned char *out, int *outlen,
|
||||
int maxout, const unsigned char *in, int inlen);
|
||||
SECStatus PK11_Finalize(PK11Context *context);
|
||||
SECStatus PK11_DigestFinal(PK11Context *context, unsigned char *data,
|
||||
unsigned int *outLen, unsigned int length);
|
||||
#define PK11_CipherFinal PK11_DigestFinal
|
||||
SECStatus PK11_SaveContext(PK11Context *cx, unsigned char *save,
|
||||
int *len, int saveLength);
|
||||
|
||||
/* Save the context's state, with possible allocation.
|
||||
* The caller may supply an already allocated buffer in preAllocBuf,
|
||||
* with length pabLen. If the buffer is large enough for the context's
|
||||
* state, it will receive the state.
|
||||
* If the buffer is not large enough (or NULL), then a new buffer will
|
||||
* be allocated with PORT_Alloc.
|
||||
* In either case, the state will be returned as a buffer, and the length
|
||||
* of the state will be given in *stateLen.
|
||||
*/
|
||||
unsigned char *
|
||||
PK11_SaveContextAlloc(PK11Context *cx,
|
||||
unsigned char *preAllocBuf, unsigned int pabLen,
|
||||
unsigned int *stateLen);
|
||||
|
||||
SECStatus PK11_RestoreContext(PK11Context *cx, unsigned char *save, int len);
|
||||
SECStatus PK11_GenerateFortezzaIV(PK11SymKey *symKey, unsigned char *iv, int len);
|
||||
void PK11_SetFortezzaHack(PK11SymKey *symKey);
|
||||
|
||||
/**********************************************************************
|
||||
* PBE functions
|
||||
**********************************************************************/
|
||||
|
||||
/* This function creates PBE parameters from the given inputs. The result
|
||||
* can be used to create a password integrity key for PKCS#12, by sending
|
||||
* the return value to PK11_KeyGen along with the appropriate mechanism.
|
||||
*/
|
||||
SECItem *
|
||||
PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations);
|
||||
|
||||
/* free params created above (can be called after keygen is done */
|
||||
void PK11_DestroyPBEParams(SECItem *params);
|
||||
|
||||
SECAlgorithmID *
|
||||
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt);
|
||||
|
||||
/* use to create PKCS5 V2 algorithms with finder control than that provided
|
||||
* by PK11_CreatePBEAlgorithmID. */
|
||||
SECAlgorithmID *
|
||||
PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag,
|
||||
SECOidTag prfAlgTag, int keyLength, int iteration,
|
||||
SECItem *salt);
|
||||
PK11SymKey *
|
||||
PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
|
||||
PRBool faulty3DES, void *wincx);
|
||||
|
||||
/* warning: cannot work with PKCS 5 v2 use PK11_PBEKeyGen instead */
|
||||
PK11SymKey *
|
||||
PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *params,
|
||||
SECItem *pwitem, PRBool faulty3DES, void *wincx);
|
||||
SECItem *
|
||||
PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem);
|
||||
/*
|
||||
* Get the Mechanism and parameter of the base encryption or mac scheme from
|
||||
* a PBE algorithm ID.
|
||||
* Caller is responsible for freeing the return parameter (param).
|
||||
*/
|
||||
CK_MECHANISM_TYPE
|
||||
PK11_GetPBECryptoMechanism(SECAlgorithmID *algid,
|
||||
SECItem **param, SECItem *pwd);
|
||||
|
||||
/**********************************************************************
|
||||
* Functions to manage secmod flags
|
||||
**********************************************************************/
|
||||
const PK11DefaultArrayEntry *PK11_GetDefaultArray(int *size);
|
||||
SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *slot,
|
||||
const PK11DefaultArrayEntry *entry,
|
||||
PRBool add);
|
||||
|
||||
/**********************************************************************
|
||||
* Functions to look at PKCS #11 dependent data
|
||||
**********************************************************************/
|
||||
PK11GenericObject *PK11_FindGenericObjects(PK11SlotInfo *slot,
|
||||
CK_OBJECT_CLASS objClass);
|
||||
PK11GenericObject *PK11_GetNextGenericObject(PK11GenericObject *object);
|
||||
PK11GenericObject *PK11_GetPrevGenericObject(PK11GenericObject *object);
|
||||
SECStatus PK11_UnlinkGenericObject(PK11GenericObject *object);
|
||||
SECStatus PK11_LinkGenericObject(PK11GenericObject *list,
|
||||
PK11GenericObject *object);
|
||||
SECStatus PK11_DestroyGenericObjects(PK11GenericObject *object);
|
||||
SECStatus PK11_DestroyGenericObject(PK11GenericObject *object);
|
||||
PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot,
|
||||
const CK_ATTRIBUTE *pTemplate,
|
||||
int count, PRBool token);
|
||||
|
||||
/*
|
||||
* PK11_ReadRawAttribute and PK11_WriteRawAttribute are generic
|
||||
* functions to read and modify the actual PKCS #11 attributes of
|
||||
* the underlying pkcs #11 object.
|
||||
*
|
||||
* object is a pointer to an NSS object that represents the underlying
|
||||
* PKCS #11 object. It's type must match the type of PK11ObjectType
|
||||
* as follows:
|
||||
*
|
||||
* type object
|
||||
* PK11_TypeGeneric PK11GenericObject *
|
||||
* PK11_TypePrivKey SECKEYPrivateKey *
|
||||
* PK11_TypePubKey SECKEYPublicKey *
|
||||
* PK11_TypeSymKey PK11SymKey *
|
||||
*
|
||||
* All other types are considered invalid. If type does not match the object
|
||||
* passed, unpredictable results will occur.
|
||||
*
|
||||
* PK11_ReadRawAttribute allocates the buffer for returning the attribute
|
||||
* value. The caller of PK11_ReadRawAttribute should free the data buffer
|
||||
* pointed to by item using a SECITEM_FreeItem(item, PR_FALSE) or
|
||||
* PORT_Free(item->data) call.
|
||||
*/
|
||||
SECStatus PK11_ReadRawAttribute(PK11ObjectType type, void *object,
|
||||
CK_ATTRIBUTE_TYPE attr, SECItem *item);
|
||||
SECStatus PK11_WriteRawAttribute(PK11ObjectType type, void *object,
|
||||
CK_ATTRIBUTE_TYPE attr, SECItem *item);
|
||||
|
||||
/*
|
||||
* PK11_GetAllSlotsForCert returns all the slots that a given certificate
|
||||
* exists on, since it's possible for a cert to exist on more than one
|
||||
* PKCS#11 token.
|
||||
*/
|
||||
PK11SlotList *
|
||||
PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg);
|
||||
|
||||
/**********************************************************************
|
||||
* New functions which are already deprecated....
|
||||
**********************************************************************/
|
||||
SECItem *
|
||||
PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
|
||||
CERTCertificate *cert, void *pwarg);
|
||||
SECItem *
|
||||
PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key);
|
||||
|
||||
PRBool SECMOD_HasRootCerts(void);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
437
security/nss/lib/pk11wrap/pk11sdr.c
Normal file
437
security/nss/lib/pk11wrap/pk11sdr.c
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secoid.h"
|
||||
#include "secasn1.h"
|
||||
#include "pkcs11.h"
|
||||
#include "pk11func.h"
|
||||
#include "pk11sdr.h"
|
||||
|
||||
/*
|
||||
* Data structure and template for encoding the result of an SDR operation
|
||||
* This is temporary. It should include the algorithm ID of the encryption mechanism
|
||||
*/
|
||||
struct SDRResult {
|
||||
SECItem keyid;
|
||||
SECAlgorithmID alg;
|
||||
SECItem data;
|
||||
};
|
||||
typedef struct SDRResult SDRResult;
|
||||
|
||||
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
|
||||
|
||||
static SEC_ASN1Template template[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SDRResult) },
|
||||
{ SEC_ASN1_OCTET_STRING, offsetof(SDRResult, keyid) },
|
||||
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(SDRResult, alg),
|
||||
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
|
||||
{ SEC_ASN1_OCTET_STRING, offsetof(SDRResult, data) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static unsigned char keyID[] = {
|
||||
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
|
||||
static SECItem keyIDItem = {
|
||||
0,
|
||||
keyID,
|
||||
sizeof keyID
|
||||
};
|
||||
|
||||
/* local utility function for padding an incoming data block
|
||||
* to the mechanism block size.
|
||||
*/
|
||||
static SECStatus
|
||||
padBlock(SECItem *data, int blockSize, SECItem *result)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
int padLength;
|
||||
unsigned int i;
|
||||
|
||||
result->data = 0;
|
||||
result->len = 0;
|
||||
|
||||
/* This algorithm always adds to the block (to indicate the number
|
||||
* of pad bytes). So allocate a block large enough.
|
||||
*/
|
||||
padLength = blockSize - (data->len % blockSize);
|
||||
result->len = data->len + padLength;
|
||||
result->data = (unsigned char *)PORT_Alloc(result->len);
|
||||
|
||||
/* Copy the data */
|
||||
PORT_Memcpy(result->data, data->data, data->len);
|
||||
|
||||
/* Add the pad values */
|
||||
for (i = data->len; i < result->len; i++)
|
||||
result->data[i] = (unsigned char)padLength;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
unpadBlock(SECItem *data, int blockSize, SECItem *result)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
int padLength;
|
||||
unsigned int i;
|
||||
|
||||
result->data = 0;
|
||||
result->len = 0;
|
||||
|
||||
/* Remove the padding from the end if the input data */
|
||||
if (data->len == 0 || data->len % blockSize != 0) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
padLength = data->data[data->len - 1];
|
||||
if (padLength > blockSize) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* verify padding */
|
||||
for (i = data->len - padLength; i < data->len; i++) {
|
||||
if (data->data[i] != padLength) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
result->len = data->len - padLength;
|
||||
result->data = (unsigned char *)PORT_Alloc(result->len);
|
||||
if (!result->data) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PORT_Memcpy(result->data, data->data, result->len);
|
||||
|
||||
if (padLength < 2) {
|
||||
return SECWouldBlock;
|
||||
}
|
||||
|
||||
loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static PRLock *pk11sdrLock = NULL;
|
||||
|
||||
void
|
||||
pk11sdr_Init(void)
|
||||
{
|
||||
pk11sdrLock = PR_NewLock();
|
||||
}
|
||||
|
||||
void
|
||||
pk11sdr_Shutdown(void)
|
||||
{
|
||||
if (pk11sdrLock) {
|
||||
PR_DestroyLock(pk11sdrLock);
|
||||
pk11sdrLock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* PK11SDR_Encrypt
|
||||
* Encrypt a block of data using the symmetric key identified. The result
|
||||
* is an ASN.1 (DER) encoded block of keyid, params and data.
|
||||
*/
|
||||
SECStatus
|
||||
PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
PK11SlotInfo *slot = 0;
|
||||
PK11SymKey *key = 0;
|
||||
SECItem *params = 0;
|
||||
PK11Context *ctx = 0;
|
||||
CK_MECHANISM_TYPE type;
|
||||
SDRResult sdrResult;
|
||||
SECItem paddedData;
|
||||
SECItem *pKeyID;
|
||||
PLArenaPool *arena = 0;
|
||||
|
||||
/* Initialize */
|
||||
paddedData.len = 0;
|
||||
paddedData.data = 0;
|
||||
|
||||
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (!arena) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* 1. Locate the requested keyid, or the default key (which has a keyid)
|
||||
* 2. Create an encryption context
|
||||
* 3. Encrypt
|
||||
* 4. Encode the results (using ASN.1)
|
||||
*/
|
||||
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
if (!slot) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Use triple-DES */
|
||||
type = CKM_DES3_CBC;
|
||||
|
||||
/*
|
||||
* Login to the internal token before we look for the key, otherwise we
|
||||
* won't find it.
|
||||
*/
|
||||
rv = PK11_Authenticate(slot, PR_TRUE, cx);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Find the key to use */
|
||||
pKeyID = keyid;
|
||||
if (pKeyID->len == 0) {
|
||||
pKeyID = &keyIDItem; /* Use default value */
|
||||
|
||||
/* put in a course lock to prevent a race between not finding the
|
||||
* key and creating one.
|
||||
*/
|
||||
|
||||
if (pk11sdrLock)
|
||||
PR_Lock(pk11sdrLock);
|
||||
|
||||
/* Try to find the key */
|
||||
key = PK11_FindFixedKey(slot, type, pKeyID, cx);
|
||||
|
||||
/* If the default key doesn't exist yet, try to create it */
|
||||
if (!key)
|
||||
key = PK11_GenDES3TokenKey(slot, pKeyID, cx);
|
||||
if (pk11sdrLock)
|
||||
PR_Unlock(pk11sdrLock);
|
||||
} else {
|
||||
key = PK11_FindFixedKey(slot, type, pKeyID, cx);
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
params = PK11_GenerateNewParam(type, key);
|
||||
if (!params) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ctx = PK11_CreateContextBySymKey(type, CKA_ENCRYPT, key, params);
|
||||
if (!ctx) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = padBlock(data, PK11_GetBlockSize(type, 0), &paddedData);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
sdrResult.data.len = paddedData.len;
|
||||
sdrResult.data.data = (unsigned char *)PORT_ArenaAlloc(arena, sdrResult.data.len);
|
||||
|
||||
rv = PK11_CipherOp(ctx, sdrResult.data.data, (int *)&sdrResult.data.len, sdrResult.data.len,
|
||||
paddedData.data, paddedData.len);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
PK11_Finalize(ctx);
|
||||
|
||||
sdrResult.keyid = *pKeyID;
|
||||
|
||||
rv = PK11_ParamToAlgid(SEC_OID_DES_EDE3_CBC, params, arena, &sdrResult.alg);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
if (!SEC_ASN1EncodeItem(0, result, &sdrResult, template)) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
SECITEM_ZfreeItem(&paddedData, PR_FALSE);
|
||||
if (arena)
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
if (ctx)
|
||||
PK11_DestroyContext(ctx, PR_TRUE);
|
||||
if (params)
|
||||
SECITEM_ZfreeItem(params, PR_TRUE);
|
||||
if (key)
|
||||
PK11_FreeSymKey(key);
|
||||
if (slot)
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* decrypt a block */
|
||||
static SECStatus
|
||||
pk11Decrypt(PK11SlotInfo *slot, PLArenaPool *arena,
|
||||
CK_MECHANISM_TYPE type, PK11SymKey *key,
|
||||
SECItem *params, SECItem *in, SECItem *result)
|
||||
{
|
||||
PK11Context *ctx = 0;
|
||||
SECItem paddedResult;
|
||||
SECStatus rv;
|
||||
|
||||
paddedResult.len = 0;
|
||||
paddedResult.data = 0;
|
||||
|
||||
ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params);
|
||||
if (!ctx) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
paddedResult.len = in->len;
|
||||
paddedResult.data = PORT_ArenaAlloc(arena, paddedResult.len);
|
||||
|
||||
rv = PK11_CipherOp(ctx, paddedResult.data,
|
||||
(int *)&paddedResult.len, paddedResult.len,
|
||||
in->data, in->len);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
PK11_Finalize(ctx);
|
||||
|
||||
/* Remove the padding */
|
||||
rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result);
|
||||
if (rv)
|
||||
goto loser;
|
||||
|
||||
loser:
|
||||
if (ctx)
|
||||
PK11_DestroyContext(ctx, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* PK11SDR_Decrypt
|
||||
* Decrypt a block of data produced by PK11SDR_Encrypt. The key used is identified
|
||||
* by the keyid field within the input.
|
||||
*/
|
||||
SECStatus
|
||||
PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
PK11SlotInfo *slot = 0;
|
||||
PK11SymKey *key = 0;
|
||||
CK_MECHANISM_TYPE type;
|
||||
SDRResult sdrResult;
|
||||
SECItem *params = 0;
|
||||
SECItem possibleResult = { 0, NULL, 0 };
|
||||
PLArenaPool *arena = 0;
|
||||
|
||||
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (!arena) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the incoming data */
|
||||
memset(&sdrResult, 0, sizeof sdrResult);
|
||||
rv = SEC_QuickDERDecodeItem(arena, &sdrResult, template, data);
|
||||
if (rv != SECSuccess)
|
||||
goto loser; /* Invalid format */
|
||||
|
||||
/* Find the slot and key for the given keyid */
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
if (!slot) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = PK11_Authenticate(slot, PR_TRUE, cx);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Get the parameter values from the data */
|
||||
params = PK11_ParamFromAlgid(&sdrResult.alg);
|
||||
if (!params) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Use triple-DES (Should look up the algorithm) */
|
||||
type = CKM_DES3_CBC;
|
||||
key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx);
|
||||
if (!key) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
rv = pk11Decrypt(slot, arena, type, key, params,
|
||||
&sdrResult.data, result);
|
||||
}
|
||||
|
||||
/*
|
||||
* if the pad value was too small (1 or 2), then it's statistically
|
||||
* 'likely' that (1 in 256) that we may not have the correct key.
|
||||
* Check the other keys for a better match. If we find none, use
|
||||
* this result.
|
||||
*/
|
||||
if (rv == SECWouldBlock) {
|
||||
possibleResult = *result;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle the case where your key indicies may have been broken
|
||||
*/
|
||||
if (rv != SECSuccess) {
|
||||
PK11SymKey *keyList = PK11_ListFixedKeysInSlot(slot, NULL, cx);
|
||||
PK11SymKey *testKey = NULL;
|
||||
PK11SymKey *nextKey = NULL;
|
||||
|
||||
for (testKey = keyList; testKey;
|
||||
testKey = PK11_GetNextSymKey(testKey)) {
|
||||
rv = pk11Decrypt(slot, arena, type, testKey, params,
|
||||
&sdrResult.data, result);
|
||||
if (rv == SECSuccess) {
|
||||
break;
|
||||
}
|
||||
/* found a close match. If it's our first remember it */
|
||||
if (rv == SECWouldBlock) {
|
||||
if (possibleResult.data) {
|
||||
/* this is unlikely but possible. If we hit this condition,
|
||||
* we have no way of knowing which possibility to prefer.
|
||||
* in this case we just match the key the application
|
||||
* thought was the right one */
|
||||
SECITEM_ZfreeItem(result, PR_FALSE);
|
||||
} else {
|
||||
possibleResult = *result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free the list */
|
||||
for (testKey = keyList; testKey; testKey = nextKey) {
|
||||
nextKey = PK11_GetNextSymKey(testKey);
|
||||
PK11_FreeSymKey(testKey);
|
||||
}
|
||||
}
|
||||
|
||||
/* we didn't find a better key, use the one with a small pad value */
|
||||
if ((rv != SECSuccess) && (possibleResult.data)) {
|
||||
*result = possibleResult;
|
||||
possibleResult.data = NULL;
|
||||
rv = SECSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (arena)
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
if (key)
|
||||
PK11_FreeSymKey(key);
|
||||
if (params)
|
||||
SECITEM_ZfreeItem(params, PR_TRUE);
|
||||
if (slot)
|
||||
PK11_FreeSlot(slot);
|
||||
if (possibleResult.data)
|
||||
SECITEM_ZfreeItem(&possibleResult, PR_FALSE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
28
security/nss/lib/pk11wrap/pk11sdr.h
Normal file
28
security/nss/lib/pk11wrap/pk11sdr.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _PK11SDR_H_
|
||||
#define _PK11SDR_H_
|
||||
|
||||
#include "seccomon.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/*
|
||||
* PK11SDR_Encrypt - encrypt data using the specified key id or SDR default
|
||||
* result should be freed with SECItem_ZfreeItem
|
||||
*/
|
||||
SECStatus
|
||||
PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx);
|
||||
|
||||
/*
|
||||
* PK11SDR_Decrypt - decrypt data previously encrypted with PK11SDR_Encrypt
|
||||
* result should be freed with SECItem_ZfreeItem
|
||||
*/
|
||||
SECStatus
|
||||
PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
2770
security/nss/lib/pk11wrap/pk11skey.c
Normal file
2770
security/nss/lib/pk11wrap/pk11skey.c
Normal file
File diff suppressed because it is too large
Load diff
2484
security/nss/lib/pk11wrap/pk11slot.c
Normal file
2484
security/nss/lib/pk11wrap/pk11slot.c
Normal file
File diff suppressed because it is too large
Load diff
1629
security/nss/lib/pk11wrap/pk11util.c
Normal file
1629
security/nss/lib/pk11wrap/pk11util.c
Normal file
File diff suppressed because it is too large
Load diff
51
security/nss/lib/pk11wrap/pk11wrap.gyp
Normal file
51
security/nss/lib/pk11wrap/pk11wrap.gyp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
{
|
||||
'includes': [
|
||||
'../../coreconf/config.gypi'
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'pk11wrap',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'dev3hack.c',
|
||||
'pk11akey.c',
|
||||
'pk11auth.c',
|
||||
'pk11cert.c',
|
||||
'pk11cxt.c',
|
||||
'pk11err.c',
|
||||
'pk11kea.c',
|
||||
'pk11list.c',
|
||||
'pk11load.c',
|
||||
'pk11mech.c',
|
||||
'pk11merge.c',
|
||||
'pk11nobj.c',
|
||||
'pk11obj.c',
|
||||
'pk11pars.c',
|
||||
'pk11pbe.c',
|
||||
'pk11pk12.c',
|
||||
'pk11pqg.c',
|
||||
'pk11sdr.c',
|
||||
'pk11skey.c',
|
||||
'pk11slot.c',
|
||||
'pk11util.c'
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
]
|
||||
}
|
||||
],
|
||||
'target_defaults': {
|
||||
'defines': [
|
||||
'SHLIB_SUFFIX=\"<(dll_suffix)\"',
|
||||
'SHLIB_PREFIX=\"<(dll_prefix)\"',
|
||||
'SHLIB_VERSION=\"3\"',
|
||||
'SOFTOKEN_SHLIB_VERSION=\"3\"'
|
||||
]
|
||||
},
|
||||
'variables': {
|
||||
'module': 'nss'
|
||||
}
|
||||
}
|
||||
167
security/nss/lib/pk11wrap/secmod.h
Normal file
167
security/nss/lib/pk11wrap/secmod.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _SECMOD_H_
|
||||
#define _SECMOD_H_
|
||||
#include "seccomon.h"
|
||||
#include "secmodt.h"
|
||||
#include "prinrval.h"
|
||||
|
||||
/* 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_SSL_FLAG 0x00000800ul
|
||||
#define PUBLIC_MECH_TLS_FLAG 0x00001000ul
|
||||
#define PUBLIC_MECH_AES_FLAG 0x00002000ul
|
||||
#define PUBLIC_MECH_SHA256_FLAG 0x00004000ul
|
||||
#define PUBLIC_MECH_SHA512_FLAG 0x00008000ul
|
||||
#define PUBLIC_MECH_CAMELLIA_FLAG 0x00010000ul
|
||||
#define PUBLIC_MECH_SEED_FLAG 0x00020000ul
|
||||
#define PUBLIC_MECH_ECC_FLAG 0x00040000ul
|
||||
|
||||
#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 0x87FF0000ul
|
||||
|
||||
/* 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
|
||||
|
||||
/*
|
||||
* the following functions are going to be deprecated in NSS 4.0 in
|
||||
* favor of the new stan functions.
|
||||
*/
|
||||
|
||||
/* Initialization */
|
||||
extern SECMODModule *SECMOD_LoadModule(char *moduleSpec, SECMODModule *parent,
|
||||
PRBool recurse);
|
||||
|
||||
extern SECMODModule *SECMOD_LoadUserModule(char *moduleSpec, SECMODModule *parent,
|
||||
PRBool recurse);
|
||||
|
||||
SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
|
||||
|
||||
SECMODModule *SECMOD_CreateModule(const char *lib, const char *name,
|
||||
const char *param, const char *nss);
|
||||
SECMODModule *SECMOD_CreateModuleEx(const char *lib, const char *name,
|
||||
const char *param, const char *nss,
|
||||
const char *config);
|
||||
/*
|
||||
* After a fork(), PKCS #11 says we need to call C_Initialize again in
|
||||
* the child before we can use the module. This function causes this
|
||||
* reinitialization.
|
||||
* NOTE: Any outstanding handles will become invalid, which means your
|
||||
* keys and contexts will fail, but new ones can be created.
|
||||
*
|
||||
* Setting 'force' to true means to do the reinitialization even if the
|
||||
* PKCS #11 module does not seem to need it. This allows software modules
|
||||
* which ignore fork to preserve their keys across the fork().
|
||||
*/
|
||||
SECStatus SECMOD_RestartModules(PRBool force);
|
||||
|
||||
/* Module Management */
|
||||
char **SECMOD_GetModuleSpecList(SECMODModule *module);
|
||||
SECStatus SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList);
|
||||
|
||||
/* protoypes */
|
||||
/* Get a list of active PKCS #11 modules */
|
||||
extern SECMODModuleList *SECMOD_GetDefaultModuleList(void);
|
||||
/* Get a list of defined but not loaded PKCS #11 modules */
|
||||
extern SECMODModuleList *SECMOD_GetDeadModuleList(void);
|
||||
/* Get a list of Modules which define PKCS #11 modules to load */
|
||||
extern SECMODModuleList *SECMOD_GetDBModuleList(void);
|
||||
|
||||
/* lock to protect all three module lists above */
|
||||
extern SECMODListLock *SECMOD_GetDefaultModuleListLock(void);
|
||||
|
||||
extern SECStatus SECMOD_UpdateModule(SECMODModule *module);
|
||||
|
||||
/* lock management */
|
||||
extern void SECMOD_GetReadLock(SECMODListLock *);
|
||||
extern void SECMOD_ReleaseReadLock(SECMODListLock *);
|
||||
|
||||
/* Operate on modules by name */
|
||||
extern SECMODModule *SECMOD_FindModule(const char *name);
|
||||
extern SECStatus SECMOD_DeleteModule(const char *name, int *type);
|
||||
extern SECStatus SECMOD_DeleteModuleEx(const char *name,
|
||||
SECMODModule *mod,
|
||||
int *type,
|
||||
PRBool permdb);
|
||||
extern SECStatus SECMOD_DeleteInternalModule(const char *name);
|
||||
extern PRBool SECMOD_CanDeleteInternalModule(void);
|
||||
extern SECStatus SECMOD_AddNewModule(const char *moduleName,
|
||||
const char *dllPath,
|
||||
unsigned long defaultMechanismFlags,
|
||||
unsigned long cipherEnableFlags);
|
||||
extern SECStatus SECMOD_AddNewModuleEx(const char *moduleName,
|
||||
const char *dllPath,
|
||||
unsigned long defaultMechanismFlags,
|
||||
unsigned long cipherEnableFlags,
|
||||
char *modparms,
|
||||
char *nssparms);
|
||||
|
||||
/* database/memory management */
|
||||
extern SECMODModule *SECMOD_GetInternalModule(void);
|
||||
extern SECMODModule *SECMOD_ReferenceModule(SECMODModule *module);
|
||||
extern void SECMOD_DestroyModule(SECMODModule *module);
|
||||
extern PK11SlotInfo *SECMOD_LookupSlot(SECMODModuleID module,
|
||||
unsigned long slotID);
|
||||
extern PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module, const char *name);
|
||||
|
||||
/* Funtion reports true if at least one of the modules */
|
||||
/* of modType has been installed */
|
||||
PRBool SECMOD_IsModulePresent(unsigned long int pubCipherEnableFlags);
|
||||
|
||||
/* accessors */
|
||||
PRBool SECMOD_GetSkipFirstFlag(SECMODModule *mod);
|
||||
PRBool SECMOD_GetDefaultModDBFlag(SECMODModule *mod);
|
||||
|
||||
/* 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);
|
||||
|
||||
PRBool SECMOD_HasRemovableSlots(SECMODModule *mod);
|
||||
PK11SlotInfo *SECMOD_WaitForAnyTokenEvent(SECMODModule *mod,
|
||||
unsigned long flags, PRIntervalTime latency);
|
||||
/*
|
||||
* Warning: the SECMOD_CancelWait function is highly destructive, potentially
|
||||
* finalizing the module 'mod' (causing inprogress operations to fail,
|
||||
* and session key material to disappear). It should only be called when
|
||||
* shutting down the module.
|
||||
*/
|
||||
SECStatus SECMOD_CancelWait(SECMODModule *mod);
|
||||
/*
|
||||
* check to see if the module has added new slots. PKCS 11 v2.20 allows for
|
||||
* modules to add new slots, but never remove them. Slots not be added between
|
||||
* a call to C_GetSlotLlist(Flag, NULL, &count) and the corresponding
|
||||
* C_GetSlotList(flag, &data, &count) so that the array doesn't accidently
|
||||
* grow on the caller. It is permissible for the slots to increase between
|
||||
* corresponding calls with NULL to get the size.
|
||||
*/
|
||||
SECStatus SECMOD_UpdateSlotList(SECMODModule *mod);
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
170
security/nss/lib/pk11wrap/secmodi.h
Normal file
170
security/nss/lib/pk11wrap/secmodi.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* 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 "nssilock.h"
|
||||
#include "secoidt.h"
|
||||
#include "secdert.h"
|
||||
#include "certt.h"
|
||||
#include "secmodt.h"
|
||||
#include "keyt.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/* proto-types */
|
||||
extern SECStatus SECMOD_DeletePermDB(SECMODModule *module);
|
||||
extern SECStatus SECMOD_AddPermDB(SECMODModule *module);
|
||||
extern SECStatus SECMOD_Shutdown(void);
|
||||
void nss_DumpModuleLog(void);
|
||||
|
||||
extern int secmod_PrivateModuleCount;
|
||||
|
||||
extern void SECMOD_Init(void);
|
||||
SECStatus secmod_ModuleInit(SECMODModule *mod, SECMODModule **oldModule,
|
||||
PRBool *alreadyLoaded);
|
||||
|
||||
/* list managment */
|
||||
extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule);
|
||||
extern SECStatus SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule);
|
||||
extern SECStatus SECMOD_AddModuleToUnloadList(SECMODModule *newModule);
|
||||
extern void SECMOD_RemoveList(SECMODModuleList **, SECMODModuleList *);
|
||||
extern void SECMOD_AddList(SECMODModuleList *, SECMODModuleList *, SECMODListLock *);
|
||||
extern SECMODListLock *SECMOD_NewListLock(void);
|
||||
extern void SECMOD_DestroyListLock(SECMODListLock *);
|
||||
extern void SECMOD_GetWriteLock(SECMODListLock *);
|
||||
extern void SECMOD_ReleaseWriteLock(SECMODListLock *);
|
||||
|
||||
/* Operate on modules by name */
|
||||
extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID);
|
||||
extern SECMODModule *secmod_FindModuleByFuncPtr(void *funcPtr);
|
||||
|
||||
/* database/memory management */
|
||||
extern SECMODModuleList *SECMOD_NewModuleListElement(void);
|
||||
extern SECMODModuleList *SECMOD_DestroyModuleListElement(SECMODModuleList *);
|
||||
extern void SECMOD_DestroyModuleList(SECMODModuleList *);
|
||||
extern SECStatus SECMOD_AddModule(SECMODModule *newModule);
|
||||
|
||||
extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags);
|
||||
|
||||
/* Library functions */
|
||||
SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
|
||||
SECStatus SECMOD_UnloadModule(SECMODModule *);
|
||||
void SECMOD_SetInternalModule(SECMODModule *);
|
||||
PRBool secmod_IsInternalKeySlot(SECMODModule *);
|
||||
void secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val);
|
||||
|
||||
/* tools for checking if we are loading the same database twice */
|
||||
typedef struct SECMODConfigListStr SECMODConfigList;
|
||||
/* collect all the databases in a given spec */
|
||||
SECMODConfigList *secmod_GetConfigList(PRBool isFIPS, char *spec, int *count);
|
||||
/* see is a spec matches a database on the list */
|
||||
PRBool secmod_MatchConfigList(const char *spec,
|
||||
SECMODConfigList *conflist, int count);
|
||||
/* returns the slot id from a module and modulespec */
|
||||
CK_SLOT_ID secmod_GetSlotIDFromModuleSpec(const char *moduleSpec, SECMODModule *module);
|
||||
/* free our list of databases */
|
||||
void secmod_FreeConfigList(SECMODConfigList *conflist, int count);
|
||||
|
||||
/* parsing parameters */
|
||||
/* returned char * must be freed by caller with PORT_Free */
|
||||
/* children and ids are null terminated arrays which must be freed with
|
||||
* secmod_FreeChildren */
|
||||
char *secmod_ParseModuleSpecForTokens(PRBool convert,
|
||||
PRBool isFIPS,
|
||||
const char *moduleSpec,
|
||||
char ***children,
|
||||
CK_SLOT_ID **ids);
|
||||
void secmod_FreeChildren(char **children, CK_SLOT_ID *ids);
|
||||
char *secmod_MkAppendTokensList(PLArenaPool *arena, char *origModuleSpec,
|
||||
char *newModuleSpec, CK_SLOT_ID newID,
|
||||
char **children, CK_SLOT_ID *ids);
|
||||
|
||||
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);
|
||||
CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot,
|
||||
CK_ATTRIBUTE *inTemplate, int tsize, int *objCount);
|
||||
|
||||
#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);
|
||||
SECStatus PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
|
||||
const CK_ATTRIBUTE *theTemplate, int count,
|
||||
PRBool token, CK_OBJECT_HANDLE *objectID);
|
||||
|
||||
SECStatus pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech);
|
||||
SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param,
|
||||
PLArenaPool *arena, SECAlgorithmID *algId);
|
||||
|
||||
PK11SymKey *pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot,
|
||||
CK_MECHANISM_TYPE type, SECItem *param, CK_KEY_TYPE keyType,
|
||||
int keySize, SECItem *keyId, CK_FLAGS opFlags,
|
||||
PK11AttrFlags attrFlags, void *wincx);
|
||||
|
||||
CK_MECHANISM_TYPE pk11_GetPBECryptoMechanism(SECAlgorithmID *algid,
|
||||
SECItem **param, SECItem *pwd, PRBool faulty3DES);
|
||||
|
||||
extern void pk11sdr_Init(void);
|
||||
extern void pk11sdr_Shutdown(void);
|
||||
|
||||
/*
|
||||
* Private to pk11wrap.
|
||||
*/
|
||||
|
||||
PRBool pk11_LoginStillRequired(PK11SlotInfo *slot, void *wincx);
|
||||
CK_SESSION_HANDLE pk11_GetNewSession(PK11SlotInfo *slot, PRBool *owner);
|
||||
void pk11_CloseSession(PK11SlotInfo *slot, CK_SESSION_HANDLE sess, PRBool own);
|
||||
PK11SymKey *pk11_ForceSlot(PK11SymKey *symKey, CK_MECHANISM_TYPE type,
|
||||
CK_ATTRIBUTE_TYPE operation);
|
||||
/* Convert key operation flags to PKCS #11 attributes. */
|
||||
unsigned int pk11_OpFlagsToAttributes(CK_FLAGS flags,
|
||||
CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue);
|
||||
/* Check for bad (conflicting) attribute flags */
|
||||
PRBool pk11_BadAttrFlags(PK11AttrFlags attrFlags);
|
||||
/* Convert key attribute flags to PKCS #11 attributes. */
|
||||
unsigned int pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags,
|
||||
CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue, CK_BBOOL *ckFalse);
|
||||
PRBool pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs,
|
||||
CK_ATTRIBUTE_TYPE target);
|
||||
|
||||
CK_MECHANISM_TYPE pk11_mapWrapKeyType(KeyType keyType);
|
||||
PK11SymKey *pk11_KeyExchange(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, PRBool isPerm,
|
||||
PK11SymKey *symKey);
|
||||
|
||||
PRBool pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||
CERTCertTrust *trust);
|
||||
CK_OBJECT_HANDLE pk11_FindPubKeyByAnyCert(CERTCertificate *cert,
|
||||
PK11SlotInfo **slot, void *wincx);
|
||||
SECStatus pk11_AuthenticateUnfriendly(PK11SlotInfo *slot, PRBool loadCerts,
|
||||
void *wincx);
|
||||
int PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
|
||||
int templateCount);
|
||||
SECItem *pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot,
|
||||
CK_OBJECT_HANDLE handle);
|
||||
SECStatus PK11_TraverseSlot(PK11SlotInfo *slot, void *arg);
|
||||
CK_OBJECT_HANDLE pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot,
|
||||
SECItem *keyID);
|
||||
SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
|
||||
PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx);
|
||||
CERTCertificate *PK11_MakeCertFromHandle(PK11SlotInfo *slot,
|
||||
CK_OBJECT_HANDLE certID, CK_ATTRIBUTE *privateLabel);
|
||||
|
||||
SECItem *pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen);
|
||||
SECItem *pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type,
|
||||
SECItem *iv, int keyLen);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
444
security/nss/lib/pk11wrap/secmodt.h
Normal file
444
security/nss/lib/pk11wrap/secmodt.h
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _SECMODT_H_
|
||||
#define _SECMODT_H_ 1
|
||||
|
||||
#include "nssrwlkt.h"
|
||||
#include "nssilckt.h"
|
||||
#include "secoid.h"
|
||||
#include "secasn1.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "utilmodt.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/* find a better home for these... */
|
||||
extern const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[];
|
||||
SEC_ASN1_CHOOSER_DECLARE(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
|
||||
extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[];
|
||||
SEC_ASN1_CHOOSER_DECLARE(SECKEY_EncryptedPrivateKeyInfoTemplate)
|
||||
extern const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[];
|
||||
SEC_ASN1_CHOOSER_DECLARE(SECKEY_PrivateKeyInfoTemplate)
|
||||
extern const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[];
|
||||
SEC_ASN1_CHOOSER_DECLARE(SECKEY_PointerToPrivateKeyInfoTemplate)
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
/* PKCS11 needs to be included */
|
||||
typedef struct SECMODModuleStr SECMODModule;
|
||||
typedef struct SECMODModuleListStr SECMODModuleList;
|
||||
typedef NSSRWLock SECMODListLock;
|
||||
typedef struct PK11SlotInfoStr PK11SlotInfo; /* defined in secmodti.h */
|
||||
typedef struct NSSUTILPreSlotInfoStr 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;
|
||||
typedef struct PK11GenericObjectStr PK11GenericObject;
|
||||
typedef void (*PK11FreeDataFunc)(void *);
|
||||
|
||||
struct SECMODModuleStr {
|
||||
PLArenaPool *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 */
|
||||
PZLock *refLock; /* only used pk11db.c */
|
||||
int refCount; /* Module reference count */
|
||||
PK11SlotInfo **slots; /* array of slot points attached 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 */
|
||||
char *libraryParams; /* Module specific parameters */
|
||||
void *moduleDBFunc; /* function to return module configuration data*/
|
||||
SECMODModule *parent; /* module that loaded us */
|
||||
PRBool isCritical; /* This module must load successfully */
|
||||
PRBool isModuleDB; /* this module has lists of PKCS #11 modules */
|
||||
PRBool moduleDBOnly; /* this module only has lists of PKCS #11 modules */
|
||||
int trustOrder; /* order for this module's certificate trust rollup */
|
||||
int cipherOrder; /* order for cipher operations */
|
||||
unsigned long evControlMask; /* control the running and shutdown of slot
|
||||
* events (SECMOD_WaitForAnyTokenEvent) */
|
||||
CK_VERSION cryptokiVersion; /* version of this library */
|
||||
};
|
||||
|
||||
/* evControlMask flags */
|
||||
/*
|
||||
* These bits tell the current state of a SECMOD_WaitForAnyTokenEvent.
|
||||
*
|
||||
* SECMOD_WAIT_PKCS11_EVENT - we're waiting in the PKCS #11 module in
|
||||
* C_WaitForSlotEvent().
|
||||
* SECMOD_WAIT_SIMULATED_EVENT - we're waiting in the NSS simulation code
|
||||
* which polls for token insertion and removal events.
|
||||
* SECMOD_END_WAIT - SECMOD_CancelWait has been called while the module is
|
||||
* waiting in SECMOD_WaitForAnyTokenEvent. SECMOD_WaitForAnyTokenEvent
|
||||
* should return immediately to it's caller.
|
||||
*/
|
||||
#define SECMOD_END_WAIT 0x01
|
||||
#define SECMOD_WAIT_SIMULATED_EVENT 0x02
|
||||
#define SECMOD_WAIT_PKCS11_EVENT 0x04
|
||||
|
||||
struct SECMODModuleListStr {
|
||||
SECMODModuleList *next;
|
||||
SECMODModule *module;
|
||||
};
|
||||
|
||||
struct PK11SlotListStr {
|
||||
PK11SlotListElement *head;
|
||||
PK11SlotListElement *tail;
|
||||
PZLock *lock;
|
||||
};
|
||||
|
||||
struct PK11SlotListElementStr {
|
||||
PK11SlotListElement *next;
|
||||
PK11SlotListElement *prev;
|
||||
PK11SlotInfo *slot;
|
||||
int refCount;
|
||||
};
|
||||
|
||||
struct PK11RSAGenParamsStr {
|
||||
int keySizeInBits;
|
||||
unsigned long pe;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PK11CertListUnique = 0, /* get one instance of all certs */
|
||||
PK11CertListUser = 1, /* get all instances of user certs */
|
||||
PK11CertListRootUnique = 2, /* get one instance of CA certs without a private key.
|
||||
* deprecated. Use PK11CertListCAUnique
|
||||
*/
|
||||
PK11CertListCA = 3, /* get all instances of CA certs */
|
||||
PK11CertListCAUnique = 4, /* get one instance of CA certs */
|
||||
PK11CertListUserUnique = 5, /* get one instance of user certs */
|
||||
PK11CertListAll = 6 /* get all instances of all certs */
|
||||
} PK11CertListType;
|
||||
|
||||
/*
|
||||
* Entry into the array which lists all the legal bits for the default flags
|
||||
* in the slot, their definition, and the PKCS #11 mechanism they represent.
|
||||
* Always statically allocated.
|
||||
*/
|
||||
struct PK11DefaultArrayEntryStr {
|
||||
const 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 */
|
||||
};
|
||||
|
||||
/*
|
||||
* PK11AttrFlags
|
||||
*
|
||||
* A 32-bit bitmask of PK11_ATTR_XXX flags
|
||||
*/
|
||||
typedef PRUint32 PK11AttrFlags;
|
||||
|
||||
/*
|
||||
* PK11_ATTR_XXX
|
||||
*
|
||||
* The following PK11_ATTR_XXX bitflags are used to specify
|
||||
* PKCS #11 object attributes that have Boolean values. Some NSS
|
||||
* functions have a "PK11AttrFlags attrFlags" parameter whose value
|
||||
* is the logical OR of these bitflags. NSS use these bitflags on
|
||||
* private keys or secret keys. Some of these bitflags also apply
|
||||
* to the public keys associated with the private keys.
|
||||
*
|
||||
* For each PKCS #11 object attribute, we need two bitflags to
|
||||
* specify not only "true" and "false" but also "default". For
|
||||
* example, PK11_ATTR_PRIVATE and PK11_ATTR_PUBLIC control the
|
||||
* CKA_PRIVATE attribute. If PK11_ATTR_PRIVATE is set, we add
|
||||
* { CKA_PRIVATE, &cktrue, sizeof(CK_BBOOL) }
|
||||
* to the template. If PK11_ATTR_PUBLIC is set, we add
|
||||
* { CKA_PRIVATE, &ckfalse, sizeof(CK_BBOOL) }
|
||||
* to the template. If neither flag is set, we don't add any
|
||||
* CKA_PRIVATE entry to the template.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Attributes for PKCS #11 storage objects, which include not only
|
||||
* keys but also certificates and domain parameters.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PK11_ATTR_TOKEN
|
||||
* PK11_ATTR_SESSION
|
||||
*
|
||||
* These two flags determine whether the object is a token or
|
||||
* session object.
|
||||
*
|
||||
* These two flags are related and cannot both be set.
|
||||
* If the PK11_ATTR_TOKEN flag is set, the object is a token
|
||||
* object. If the PK11_ATTR_SESSION flag is set, the object is
|
||||
* a session object. If neither flag is set, the object is *by
|
||||
* default* a session object.
|
||||
*
|
||||
* These two flags specify the value of the PKCS #11 CKA_TOKEN
|
||||
* attribute.
|
||||
*/
|
||||
#define PK11_ATTR_TOKEN 0x00000001L
|
||||
#define PK11_ATTR_SESSION 0x00000002L
|
||||
|
||||
/*
|
||||
* PK11_ATTR_PRIVATE
|
||||
* PK11_ATTR_PUBLIC
|
||||
*
|
||||
* These two flags determine whether the object is a private or
|
||||
* public object. A user may not access a private object until the
|
||||
* user has authenticated to the token.
|
||||
*
|
||||
* These two flags are related and cannot both be set.
|
||||
* If the PK11_ATTR_PRIVATE flag is set, the object is a private
|
||||
* object. If the PK11_ATTR_PUBLIC flag is set, the object is a
|
||||
* public object. If neither flag is set, it is token-specific
|
||||
* whether the object is private or public.
|
||||
*
|
||||
* These two flags specify the value of the PKCS #11 CKA_PRIVATE
|
||||
* attribute. NSS only uses this attribute on private and secret
|
||||
* keys, so public keys created by NSS get the token-specific
|
||||
* default value of the CKA_PRIVATE attribute.
|
||||
*/
|
||||
#define PK11_ATTR_PRIVATE 0x00000004L
|
||||
#define PK11_ATTR_PUBLIC 0x00000008L
|
||||
|
||||
/*
|
||||
* PK11_ATTR_MODIFIABLE
|
||||
* PK11_ATTR_UNMODIFIABLE
|
||||
*
|
||||
* These two flags determine whether the object is modifiable or
|
||||
* read-only.
|
||||
*
|
||||
* These two flags are related and cannot both be set.
|
||||
* If the PK11_ATTR_MODIFIABLE flag is set, the object can be
|
||||
* modified. If the PK11_ATTR_UNMODIFIABLE flag is set, the object
|
||||
* is read-only. If neither flag is set, the object is *by default*
|
||||
* modifiable.
|
||||
*
|
||||
* These two flags specify the value of the PKCS #11 CKA_MODIFIABLE
|
||||
* attribute.
|
||||
*/
|
||||
#define PK11_ATTR_MODIFIABLE 0x00000010L
|
||||
#define PK11_ATTR_UNMODIFIABLE 0x00000020L
|
||||
|
||||
/* Attributes for PKCS #11 key objects. */
|
||||
|
||||
/*
|
||||
* PK11_ATTR_SENSITIVE
|
||||
* PK11_ATTR_INSENSITIVE
|
||||
*
|
||||
* These two flags are related and cannot both be set.
|
||||
* If the PK11_ATTR_SENSITIVE flag is set, the key is sensitive.
|
||||
* If the PK11_ATTR_INSENSITIVE flag is set, the key is not
|
||||
* sensitive. If neither flag is set, it is token-specific whether
|
||||
* the key is sensitive or not.
|
||||
*
|
||||
* If a key is sensitive, certain attributes of the key cannot be
|
||||
* revealed in plaintext outside the token.
|
||||
*
|
||||
* This flag specifies the value of the PKCS #11 CKA_SENSITIVE
|
||||
* attribute. Although the default value of the CKA_SENSITIVE
|
||||
* attribute for secret keys is CK_FALSE per PKCS #11, some FIPS
|
||||
* tokens set the default value to CK_TRUE because only CK_TRUE
|
||||
* is allowed. So in practice the default value of this attribute
|
||||
* is token-specific, hence the need for two bitflags.
|
||||
*/
|
||||
#define PK11_ATTR_SENSITIVE 0x00000040L
|
||||
#define PK11_ATTR_INSENSITIVE 0x00000080L
|
||||
|
||||
/*
|
||||
* PK11_ATTR_EXTRACTABLE
|
||||
* PK11_ATTR_UNEXTRACTABLE
|
||||
*
|
||||
* These two flags are related and cannot both be set.
|
||||
* If the PK11_ATTR_EXTRACTABLE flag is set, the key is extractable
|
||||
* and can be wrapped. If the PK11_ATTR_UNEXTRACTABLE flag is set,
|
||||
* the key is not extractable, and certain attributes of the key
|
||||
* cannot be revealed in plaintext outside the token (just like a
|
||||
* sensitive key). If neither flag is set, it is token-specific
|
||||
* whether the key is extractable or not.
|
||||
*
|
||||
* These two flags specify the value of the PKCS #11 CKA_EXTRACTABLE
|
||||
* attribute.
|
||||
*/
|
||||
#define PK11_ATTR_EXTRACTABLE 0x00000100L
|
||||
#define PK11_ATTR_UNEXTRACTABLE 0x00000200L
|
||||
|
||||
/* Cryptographic module types */
|
||||
#define SECMOD_EXTERNAL 0 /* external module */
|
||||
#define SECMOD_INTERNAL 1 /* internal default module */
|
||||
#define SECMOD_FIPS 2 /* internal fips module */
|
||||
|
||||
/* default module configuration strings */
|
||||
#define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]"
|
||||
|
||||
#define SECMOD_MAKE_NSS_FLAGS(fips, slot) \
|
||||
"Flags=internal,critical" fips " slotparams=(" #slot "={" SECMOD_SLOT_FLAGS "})"
|
||||
|
||||
#define SECMOD_INT_NAME "NSS Internal PKCS #11 Module"
|
||||
#define SECMOD_INT_FLAGS SECMOD_MAKE_NSS_FLAGS("", 1)
|
||||
#define SECMOD_FIPS_NAME "NSS Internal FIPS PKCS #11 Module"
|
||||
#define SECMOD_FIPS_FLAGS SECMOD_MAKE_NSS_FLAGS(",fips", 3)
|
||||
|
||||
/*
|
||||
* 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 = 0, /* There is not key, it's a null SymKey */
|
||||
PK11_OriginDerive = 1, /* Key was derived from some other key */
|
||||
PK11_OriginGenerated = 2, /* Key was generated (also PBE keys) */
|
||||
PK11_OriginFortezzaHack = 3, /* Key was marked for fortezza hack */
|
||||
PK11_OriginUnwrap = 4 /* Key was unwrapped or decrypted */
|
||||
} PK11Origin;
|
||||
|
||||
/* PKCS #11 disable reasons */
|
||||
typedef enum {
|
||||
PK11_DIS_NONE = 0,
|
||||
PK11_DIS_USER_SELECTED = 1,
|
||||
PK11_DIS_COULD_NOT_INIT_TOKEN = 2,
|
||||
PK11_DIS_TOKEN_VERIFY_FAILED = 3,
|
||||
PK11_DIS_TOKEN_NOT_PRESENT = 4
|
||||
} PK11DisableReasons;
|
||||
|
||||
/* types of PKCS #11 objects
|
||||
* used to identify which NSS data structure is
|
||||
* passed to the PK11_Raw* functions. Types map as follows:
|
||||
* PK11_TypeGeneric PK11GenericObject *
|
||||
* PK11_TypePrivKey SECKEYPrivateKey *
|
||||
* PK11_TypePubKey SECKEYPublicKey *
|
||||
* PK11_TypeSymKey PK11SymKey *
|
||||
* PK11_TypeCert CERTCertificate * (currently not used).
|
||||
*/
|
||||
typedef enum {
|
||||
PK11_TypeGeneric = 0,
|
||||
PK11_TypePrivKey = 1,
|
||||
PK11_TypePubKey = 2,
|
||||
PK11_TypeCert = 3,
|
||||
PK11_TypeSymKey = 4
|
||||
} PK11ObjectType;
|
||||
|
||||
/* function pointer type for password callback function.
|
||||
* This type is passed in to PK11_SetPasswordFunc()
|
||||
*/
|
||||
typedef char *(PR_CALLBACK *PK11PasswordFunc)(PK11SlotInfo *slot, PRBool retry, void *arg);
|
||||
typedef PRBool(PR_CALLBACK *PK11VerifyPasswordFunc)(PK11SlotInfo *slot, void *arg);
|
||||
typedef PRBool(PR_CALLBACK *PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg);
|
||||
|
||||
/*
|
||||
* Special strings the password callback function can return only if
|
||||
* the slot is an protected auth path slot.
|
||||
*/
|
||||
#define PK11_PW_RETRY "RETRY" /* an failed attempt to authenticate \
|
||||
* has already been made, just retry \
|
||||
* the operation */
|
||||
#define PK11_PW_AUTHENTICATED "AUTH" /* a successful attempt to authenticate \
|
||||
* has completed. Continue without \
|
||||
* another call to C_Login */
|
||||
/* All other non-null values mean that that NSS could call C_Login to force
|
||||
* the authentication. The following define is to aid applications in
|
||||
* documenting that is what it's trying to do */
|
||||
#define PK11_PW_TRY "TRY" /* Default: a prompt has been presented \
|
||||
* to the user, initiate a C_Login \
|
||||
* to authenticate the token */
|
||||
|
||||
/*
|
||||
* PKCS #11 key structures
|
||||
*/
|
||||
|
||||
/*
|
||||
** Attributes
|
||||
*/
|
||||
struct SECKEYAttributeStr {
|
||||
SECItem attrType;
|
||||
SECItem **attrValue;
|
||||
};
|
||||
typedef struct SECKEYAttributeStr SECKEYAttribute;
|
||||
|
||||
/*
|
||||
** A PKCS#8 private key info object
|
||||
*/
|
||||
struct SECKEYPrivateKeyInfoStr {
|
||||
PLArenaPool *arena;
|
||||
SECItem version;
|
||||
SECAlgorithmID algorithm;
|
||||
SECItem privateKey;
|
||||
SECKEYAttribute **attributes;
|
||||
};
|
||||
typedef struct SECKEYPrivateKeyInfoStr SECKEYPrivateKeyInfo;
|
||||
|
||||
/*
|
||||
** A PKCS#8 private key info object
|
||||
*/
|
||||
struct SECKEYEncryptedPrivateKeyInfoStr {
|
||||
PLArenaPool *arena;
|
||||
SECAlgorithmID algorithm;
|
||||
SECItem encryptedData;
|
||||
};
|
||||
typedef struct SECKEYEncryptedPrivateKeyInfoStr SECKEYEncryptedPrivateKeyInfo;
|
||||
|
||||
/*
|
||||
* token removal detection
|
||||
*/
|
||||
typedef enum {
|
||||
PK11TokenNotRemovable = 0,
|
||||
PK11TokenPresent = 1,
|
||||
PK11TokenChanged = 2,
|
||||
PK11TokenRemoved = 3
|
||||
} PK11TokenStatus;
|
||||
|
||||
typedef enum {
|
||||
PK11TokenRemovedOrChangedEvent = 0,
|
||||
PK11TokenPresentEvent = 1
|
||||
} PK11TokenEvent;
|
||||
|
||||
/*
|
||||
* CRL Import Flags
|
||||
*/
|
||||
#define CRL_IMPORT_DEFAULT_OPTIONS 0x00000000
|
||||
#define CRL_IMPORT_BYPASS_CHECKS 0x00000001
|
||||
|
||||
/*
|
||||
* Merge Error Log
|
||||
*/
|
||||
typedef struct PK11MergeLogStr PK11MergeLog;
|
||||
typedef struct PK11MergeLogNodeStr PK11MergeLogNode;
|
||||
|
||||
/* These need to be global, leave some open fields so we can 'expand'
|
||||
* these without breaking binary compatibility */
|
||||
struct PK11MergeLogNodeStr {
|
||||
PK11MergeLogNode *next; /* next entry in the list */
|
||||
PK11MergeLogNode *prev; /* last entry in the list */
|
||||
PK11GenericObject *object; /* object that failed */
|
||||
int error; /* what the error was */
|
||||
CK_RV reserved1;
|
||||
unsigned long reserved2; /* future flags */
|
||||
unsigned long reserved3; /* future scalar */
|
||||
void *reserved4; /* future pointer */
|
||||
void *reserved5; /* future expansion pointer */
|
||||
};
|
||||
|
||||
struct PK11MergeLogStr {
|
||||
PK11MergeLogNode *head;
|
||||
PK11MergeLogNode *tail;
|
||||
PLArenaPool *arena;
|
||||
int version;
|
||||
unsigned long reserved1;
|
||||
unsigned long reserved2;
|
||||
unsigned long reserved3;
|
||||
void *reserverd4;
|
||||
void *reserverd5;
|
||||
};
|
||||
|
||||
#endif /*_SECMODT_H_ */
|
||||
183
security/nss/lib/pk11wrap/secmodti.h
Normal file
183
security/nss/lib/pk11wrap/secmodti.h
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* Internal header file included only by files in pkcs11 dir, or in
|
||||
* pkcs11 specific client and server files.
|
||||
*/
|
||||
|
||||
#ifndef _SECMODTI_H_
|
||||
#define _SECMODTI_H_ 1
|
||||
#include "prmon.h"
|
||||
#include "prtypes.h"
|
||||
#include "nssilckt.h"
|
||||
#include "secmodt.h"
|
||||
#include "pkcs11t.h"
|
||||
|
||||
#include "nssdevt.h"
|
||||
|
||||
/* internal data structures */
|
||||
|
||||
/* Traverse slots callback */
|
||||
typedef struct pk11TraverseSlotStr {
|
||||
SECStatus (*callback)(PK11SlotInfo *, CK_OBJECT_HANDLE, void *);
|
||||
void *callbackArg;
|
||||
CK_ATTRIBUTE *findTemplate;
|
||||
int templateCount;
|
||||
} pk11TraverseSlot;
|
||||
|
||||
/* 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;
|
||||
PZLock *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 */
|
||||
PRInt32 refCount; /* to be in/decremented by atomic calls ONLY! */
|
||||
PZLock *freeListLock;
|
||||
PK11SymKey *freeSymKeysWithSessionHead;
|
||||
PK11SymKey *freeSymKeysHead;
|
||||
int keyCount;
|
||||
int maxKeyCount;
|
||||
/* 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 */
|
||||
PRTime authTime; /* when were we last authenticated */
|
||||
int minPassword; /* smallest legal password */
|
||||
int maxPassword; /* largest legal password */
|
||||
PRUint16 series; /* break up the slot info into various groups of
|
||||
* inserted tokens so that keys and certs can be
|
||||
* invalidated */
|
||||
PRUint16 flagSeries; /* record the last series for the last event
|
||||
* returned for this slot */
|
||||
PRBool flagState; /* record the state of the last event returned for this
|
||||
* slot. */
|
||||
PRUint16 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 hasRootCerts;
|
||||
PRBool hasRootTrust;
|
||||
PRBool hasRSAInfo;
|
||||
CK_FLAGS RSAInfoFlags;
|
||||
PRBool protectedAuthPath;
|
||||
PRBool isActiveCard;
|
||||
PRIntervalTime lastLoginCheck;
|
||||
unsigned int lastState;
|
||||
/* for Stan */
|
||||
NSSToken *nssToken;
|
||||
/* fast mechanism lookup */
|
||||
char mechanismBits[256];
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
PK11SymKey *next;
|
||||
PRBool owner;
|
||||
SECItem data; /* raw key data if available */
|
||||
CK_SESSION_HANDLE session;
|
||||
PRBool sessionOwner;
|
||||
PRInt32 refCount; /* number of references to this key */
|
||||
int size; /* key size in bytes */
|
||||
PK11Origin origin; /* where this key came from
|
||||
* (see def in secmodt.h) */
|
||||
PK11SymKey *parent; /* potential owner key of the session */
|
||||
PRUint16 series; /* break up the slot info into various groups
|
||||
* of inserted tokens so that keys and certs
|
||||
* can be invalidated */
|
||||
void *userData; /* random data the application can attach to
|
||||
* this key */
|
||||
PK11FreeDataFunc freeFunc; /* function to free the user data */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
PZLock *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*/
|
||||
};
|
||||
|
||||
/*
|
||||
* structure to hold a pointer to a unique PKCS #11 object
|
||||
* (pointer to the slot and the object id).
|
||||
*/
|
||||
struct PK11GenericObjectStr {
|
||||
PK11GenericObject *prev;
|
||||
PK11GenericObject *next;
|
||||
PK11SlotInfo *slot;
|
||||
CK_OBJECT_HANDLE objectID;
|
||||
};
|
||||
|
||||
#define MAX_TEMPL_ATTRS 16 /* maximum attributes in template */
|
||||
|
||||
/* This mask includes all CK_FLAGs with an equivalent CKA_ attribute. */
|
||||
#define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL
|
||||
|
||||
#endif /* _SECMODTI_H_ */
|
||||
61
security/nss/lib/pk11wrap/secpkcs5.h
Normal file
61
security/nss/lib/pk11wrap/secpkcs5.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _SECPKCS5_H_
|
||||
#define _SECPKCS5_H_
|
||||
#include "seccomon.h"
|
||||
#include "secmodt.h"
|
||||
|
||||
/* used for V2 PKCS 12 Draft Spec */
|
||||
typedef enum {
|
||||
pbeBitGenIDNull = 0,
|
||||
pbeBitGenCipherKey = 0x01,
|
||||
pbeBitGenCipherIV = 0x02,
|
||||
pbeBitGenIntegrityKey = 0x03
|
||||
} PBEBitGenID;
|
||||
|
||||
typedef struct PBEBitGenContextStr PBEBitGenContext;
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/* private */
|
||||
SECAlgorithmID *
|
||||
sec_pkcs5CreateAlgorithmID(SECOidTag algorithm, SECOidTag cipherAlgorithm,
|
||||
SECOidTag prfAlg, SECOidTag *pPbeAlgorithm,
|
||||
int keyLengh, SECItem *salt, int iteration);
|
||||
|
||||
/* Get the initialization vector. The password is passed in, hashing
|
||||
* is performed, and the initialization vector is returned.
|
||||
* algid is a pointer to a PBE algorithm ID
|
||||
* pwitem is the password
|
||||
* If an error occurs or the algorithm id is not a PBE algrithm,
|
||||
* NULL is returned. Otherwise, the iv is returned in a secitem.
|
||||
*/
|
||||
SECItem *
|
||||
SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
|
||||
|
||||
SECOidTag SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid);
|
||||
PRBool SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid);
|
||||
PRBool SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algTag);
|
||||
SECOidTag SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen);
|
||||
int SEC_PKCS5GetKeyLength(SECAlgorithmID *algid);
|
||||
|
||||
/**********************************************************************
|
||||
* Deprecated PBE functions. Use the PBE functions in pk11func.h
|
||||
* instead.
|
||||
**********************************************************************/
|
||||
|
||||
PBEBitGenContext *
|
||||
PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
|
||||
SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
|
||||
unsigned int iterations);
|
||||
|
||||
void
|
||||
PBE_DestroyContext(PBEBitGenContext *context);
|
||||
|
||||
SECItem *
|
||||
PBE_GenerateBits(PBEBitGenContext *context);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _SECPKS5_H_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue