mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-27 20:25:44 +00:00
310 lines
8.5 KiB
C
310 lines
8.5 KiB
C
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Netscape security libraries.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* Alternatively, the contents of this file may be used under the
|
|
* terms of the GNU General Public License Version 2 or later (the
|
|
* "GPL"), in which case the provisions of the GPL are applicable
|
|
* instead of those above. If you wish to allow use of your
|
|
* version of this file only under the terms of the GPL and not to
|
|
* allow others to use your version of this file under the MPL,
|
|
* indicate your decision by deleting the provisions above and
|
|
* replace them with the notice and other provisions required by
|
|
* the GPL. If you do not delete the provisions above, a recipient
|
|
* may use your version of this file under either the MPL or the
|
|
* GPL.
|
|
*/
|
|
|
|
#ifdef DEBUG
|
|
static const char CVS_ID[] = "@(#) $RCSfile: nss3hack.c,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
|
|
#endif /* DEBUG */
|
|
|
|
/*
|
|
* Hacks to integrate NSS 3.4 and NSS 4.0 certificates.
|
|
*/
|
|
|
|
#ifndef NSSPKI_H
|
|
#include "nsspki.h"
|
|
#endif /* NSSPKI_H */
|
|
|
|
#ifndef PKIM_H
|
|
#include "pkim.h"
|
|
#endif /* PKIM_H */
|
|
|
|
#ifndef DEVT_H
|
|
#include "devt.h"
|
|
#endif /* DEVT_H */
|
|
|
|
#ifndef DEVNSS3HACK_H
|
|
#include "devnss3hack.h"
|
|
#endif /* DEVNSS3HACK_H */
|
|
|
|
#ifndef PKINSS3HACK_H
|
|
#include "pkinss3hack.h"
|
|
#endif /* PKINSS3HACK_H */
|
|
|
|
#include "secitem.h"
|
|
#include "certdb.h"
|
|
#include "certt.h"
|
|
#include "cert.h"
|
|
#include "pk11func.h"
|
|
|
|
#define NSSITEM_FROM_SECITEM(nssit, secit) \
|
|
(nssit)->data = (void *)(secit)->data; \
|
|
(nssit)->size = (secit)->len;
|
|
|
|
#define SECITEM_FROM_NSSITEM(secit, nssit) \
|
|
(secit)->data = (unsigned char *)(nssit)->data; \
|
|
(secit)->len = (nssit)->size;
|
|
|
|
NSSTrustDomain *g_default_trust_domain = NULL;
|
|
|
|
NSSTrustDomain *
|
|
STAN_GetDefaultTrustDomain()
|
|
{
|
|
return g_default_trust_domain;
|
|
}
|
|
|
|
NSS_IMPLEMENT void
|
|
STAN_LoadDefaultNSS3TrustDomain
|
|
(
|
|
void
|
|
)
|
|
{
|
|
NSSTrustDomain *td;
|
|
NSSToken *token;
|
|
PK11SlotList *list;
|
|
PK11SlotListElement *le;
|
|
td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL);
|
|
if (!td) {
|
|
/* um, some kind a fatal here */
|
|
return;
|
|
}
|
|
td->tokenList = nssList_Create(td->arena, PR_TRUE);
|
|
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
|
|
if (list) {
|
|
#if 0
|
|
/* XXX this doesn't work until softoken is a true PKCS#11 mod */
|
|
for (le = list->head; le; le = le->next) {
|
|
token = nssToken_CreateFromPK11SlotInfo(td, le->slot);
|
|
PK11Slot_SetNSSToken(le->slot, token);
|
|
nssList_Add(td->tokenList, token);
|
|
}
|
|
#endif
|
|
}
|
|
td->tokens = nssList_CreateIterator(td->tokenList);
|
|
g_default_trust_domain = td;
|
|
}
|
|
|
|
NSS_IMPLEMENT PRStatus
|
|
STAN_AddNewSlotToDefaultTD
|
|
(
|
|
PK11SlotInfo *sl
|
|
)
|
|
{
|
|
NSSToken *token;
|
|
token = nssToken_CreateFromPK11SlotInfo(g_default_trust_domain, sl);
|
|
PK11Slot_SetNSSToken(sl, token);
|
|
nssList_Add(g_default_trust_domain->tokenList, token);
|
|
return PR_SUCCESS;
|
|
}
|
|
|
|
/* this function should not be a hack; it will be needed in 4.0 (rename) */
|
|
NSS_IMPLEMENT NSSItem *
|
|
STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
|
|
{
|
|
NSSItem *rvKey;
|
|
SECItem secDER;
|
|
SECItem secKey = { 0 };
|
|
SECStatus secrv;
|
|
SECITEM_FROM_NSSITEM(&secDER, der);
|
|
secrv = CERT_KeyFromDERCert(NULL, &secDER, &secKey);
|
|
rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
|
|
return rvKey;
|
|
}
|
|
|
|
static NSSItem *
|
|
nss3certificate_getIdentifier(nssDecodedCert *dc)
|
|
{
|
|
NSSItem *rvID;
|
|
CERTCertificate *c = (CERTCertificate *)dc->data;
|
|
rvID = nssItem_Create(NULL, NULL, c->certKey.len, c->certKey.data);
|
|
return rvID;
|
|
}
|
|
|
|
static NSSItem *
|
|
nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
|
|
{
|
|
CERTCertificate *c = (CERTCertificate *)dc->data;
|
|
CERTAuthKeyID *cAuthKeyID;
|
|
PRArenaPool *tmpArena = NULL;
|
|
SECItem issuerCertKey;
|
|
SECItem *identifier = NULL;
|
|
NSSItem *rvID = NULL;
|
|
SECStatus secrv;
|
|
tmpArena = PORT_NewArena(512);
|
|
cAuthKeyID = CERT_FindAuthKeyIDExten(tmpArena, c);
|
|
if (cAuthKeyID) {
|
|
if (cAuthKeyID->keyID.data) {
|
|
identifier = &cAuthKeyID->keyID;
|
|
} else if (cAuthKeyID->authCertIssuer) {
|
|
SECItem *caName;
|
|
caName = (SECItem *)CERT_GetGeneralNameByType(
|
|
cAuthKeyID->authCertIssuer,
|
|
certDirectoryName, PR_TRUE);
|
|
if (caName) {
|
|
secrv = CERT_KeyFromIssuerAndSN(tmpArena, caName,
|
|
&cAuthKeyID->authCertSerialNumber,
|
|
&issuerCertKey);
|
|
if (secrv == SECSuccess) {
|
|
identifier = &issuerCertKey;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (identifier) {
|
|
rvID = nssItem_Create(NULL, NULL, identifier->len, identifier->data);
|
|
}
|
|
if (tmpArena) PORT_FreeArena(tmpArena, PR_FALSE);
|
|
return rvID;
|
|
}
|
|
|
|
static NSSUsage *
|
|
nss3certificate_getUsage(nssDecodedCert *dc)
|
|
{
|
|
CERTCertificate *c = (CERTCertificate *)dc->data;
|
|
return NULL;
|
|
}
|
|
|
|
static PRBool
|
|
nss3certificate_isValidAtTime(nssDecodedCert *dc, NSSTime *time)
|
|
{
|
|
SECCertTimeValidity validity;
|
|
CERTCertificate *c = (CERTCertificate *)dc->data;
|
|
validity = CERT_CheckCertValidTimes(c, NSSTime_GetPRTime(time), PR_TRUE);
|
|
if (validity == secCertTimeValid) {
|
|
return PR_TRUE;
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
static PRBool
|
|
nss3certificate_isNewerThan(nssDecodedCert *dc, nssDecodedCert *cmpdc)
|
|
{
|
|
/* I know this isn't right, but this is glue code anyway */
|
|
if (cmpdc->type == dc->type) {
|
|
CERTCertificate *certa = (CERTCertificate *)dc->data;
|
|
CERTCertificate *certb = (CERTCertificate *)cmpdc->data;
|
|
return CERT_IsNewer(certa, certb);
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
NSS_IMPLEMENT nssDecodedCert *
|
|
nssDecodedPKIXCertificate_Create
|
|
(
|
|
NSSArena *arenaOpt,
|
|
NSSDER *encoding
|
|
)
|
|
{
|
|
nssDecodedCert *rvDC;
|
|
SECItem secDER;
|
|
rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
|
|
rvDC->type = NSSCertificateType_PKIX;
|
|
SECITEM_FROM_NSSITEM(&secDER, encoding);
|
|
rvDC->data = (void *)CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL);
|
|
rvDC->getIdentifier = nss3certificate_getIdentifier;
|
|
rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
|
|
rvDC->getUsage = nss3certificate_getUsage;
|
|
rvDC->isValidAtTime = nss3certificate_isValidAtTime;
|
|
rvDC->isNewerThan = nss3certificate_isNewerThan;
|
|
return rvDC;
|
|
}
|
|
|
|
NSS_IMPLEMENT PRStatus
|
|
nssDecodedPKIXCertificate_Destroy
|
|
(
|
|
nssDecodedCert *dc
|
|
)
|
|
{
|
|
/*CERT_DestroyCertificate((CERTCertificate *)dc->data);*/
|
|
nss_ZFreeIf(dc);
|
|
return PR_SUCCESS;
|
|
}
|
|
|
|
/* see pk11cert.c:pk11_HandleTrustObject */
|
|
static unsigned int
|
|
get_nss3trust_from_cktrust(CK_TRUST t)
|
|
{
|
|
unsigned int rt = 0;
|
|
if (t & CKT_NETSCAPE_TRUSTED) {
|
|
rt |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
|
|
}
|
|
if (t & CKT_NETSCAPE_TRUSTED_DELEGATOR) {
|
|
rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
|
|
}
|
|
if (t & CKT_NETSCAPE_VALID) {
|
|
rt |= CERTDB_VALID_PEER;
|
|
}
|
|
if (t & CKT_NETSCAPE_VALID_DELEGATOR) {
|
|
rt |= CERTDB_VALID_CA;
|
|
}
|
|
/* user */
|
|
return rt;
|
|
}
|
|
|
|
static CERTCertTrust *
|
|
NSSTrust_GetCERTCertTrust(NSSTrust *t)
|
|
{
|
|
CERTCertTrust *rvTrust = nss_ZNEW(NULL, CERTCertTrust);
|
|
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
|
|
rvTrust->emailFlags = get_nss3trust_from_cktrust(t->emailProtection);
|
|
rvTrust->objectSigningFlags = get_nss3trust_from_cktrust(t->codeSigning);
|
|
return rvTrust;
|
|
}
|
|
|
|
NSS_EXTERN CERTCertificate *
|
|
STAN_GetCERTCertificate(NSSCertificate *c)
|
|
{
|
|
nssDecodedCert *dc;
|
|
CERTCertificate *cc;
|
|
if (!c->decoding) {
|
|
dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
|
|
c->decoding = dc;
|
|
/* decoded, so cache */
|
|
} else {
|
|
dc = c->decoding;
|
|
}
|
|
/* fill other fields needed by NSS3 functions using CERTCertificate */
|
|
cc = (CERTCertificate *)dc->data;
|
|
/* nickname */
|
|
cc->nickname = PL_strdup(c->nickname);
|
|
/* emailAddr ??? */
|
|
/* slot */
|
|
cc->slot = c->token->pk11slot;
|
|
/* trust */
|
|
cc->trust = NSSTrust_GetCERTCertTrust(&c->trust);
|
|
/* referenceCount addref? */
|
|
/* subjectList ? */
|
|
/* pkcs11ID */
|
|
cc->pkcs11ID = c->handle;
|
|
return cc;
|
|
}
|
|
|