зеркало из https://github.com/mozilla/pjs.git
Bug 673382, Upgrade to NSS 3.12.11, landing beta 3, r=wtc
This commit is contained in:
Родитель
2666a41d1e
Коммит
a2ae009116
|
@ -43,3 +43,4 @@
|
|||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
NSS_3_12_11_BETA2
|
||||
NSS_3_12_11_BETA3
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
/*
|
||||
* Certificate handling code
|
||||
*
|
||||
* $Id: certdb.c,v 1.104.2.4 2011/07/28 22:19:57 wtc%google.com Exp $
|
||||
* $Id: certdb.c,v 1.104.2.5 2011/08/05 01:16:27 wtc%google.com Exp $
|
||||
*/
|
||||
|
||||
#include "nssilock.h"
|
||||
|
@ -1266,8 +1266,9 @@ CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage,
|
|||
switch ( usage ) {
|
||||
case certUsageSSLClient:
|
||||
/*
|
||||
* Only accept KU_DIGITAL_SIGNATURE.
|
||||
* KU_NON_REPUDIATION cannot be used for SSL client auth.
|
||||
* RFC 5280 lists digitalSignature and keyAgreement for
|
||||
* id-kp-clientAuth. NSS does not support the *_fixed_dh and
|
||||
* *_fixed_ecdh client certificate types.
|
||||
*/
|
||||
requiredKeyUsage = KU_DIGITAL_SIGNATURE;
|
||||
requiredCertType = NS_CERT_TYPE_SSL_CLIENT;
|
||||
|
@ -1294,7 +1295,8 @@ CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage,
|
|||
requiredCertType = NS_CERT_TYPE_EMAIL;
|
||||
break;
|
||||
case certUsageObjectSigner:
|
||||
requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION;
|
||||
/* RFC 5280 lists only digitalSignature for id-kp-codeSigning. */
|
||||
requiredKeyUsage = KU_DIGITAL_SIGNATURE;
|
||||
requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING;
|
||||
break;
|
||||
case certUsageStatusResponder:
|
||||
|
|
|
@ -150,79 +150,6 @@ CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert,
|
|||
}
|
||||
|
||||
|
||||
/* Software FORTEZZA installation hack. The software fortezza installer does
|
||||
* not have access to the krl and cert.db file. Accept FORTEZZA Certs without
|
||||
* KRL's in this case.
|
||||
*/
|
||||
static int dont_use_krl = 0;
|
||||
/* not a public exposed function... */
|
||||
void sec_SetCheckKRLState(int value) { dont_use_krl = value; }
|
||||
|
||||
SECStatus
|
||||
SEC_CheckKRL(CERTCertDBHandle *handle,SECKEYPublicKey *key,
|
||||
CERTCertificate *rootCert, int64 t, void * wincx)
|
||||
{
|
||||
CERTSignedCrl *crl = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
SECStatus rv2;
|
||||
CERTCrlEntry **crlEntry;
|
||||
SECCertTimeValidity validity;
|
||||
CERTCertificate *issuerCert = NULL;
|
||||
|
||||
if (dont_use_krl) return SECSuccess;
|
||||
|
||||
/* first look up the KRL */
|
||||
crl = SEC_FindCrlByName(handle,&rootCert->derSubject, SEC_KRL_TYPE);
|
||||
if (crl == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_KRL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* get the issuing certificate */
|
||||
issuerCert = CERT_FindCertByName(handle, &crl->crl.derName);
|
||||
if (issuerCert == NULL) {
|
||||
PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/* now verify the KRL signature */
|
||||
rv2 = CERT_VerifySignedData(&crl->signatureWrap, issuerCert, t, wincx);
|
||||
if (rv2 != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Verify the date validity of the KRL */
|
||||
validity = SEC_CheckCrlTimes(&crl->crl, t);
|
||||
if (validity == secCertTimeExpired) {
|
||||
PORT_SetError(SEC_ERROR_KRL_EXPIRED);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now make sure the key in this cert is still valid */
|
||||
if (key->keyType != fortezzaKey) {
|
||||
PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
goto done; /* This should be an assert? */
|
||||
}
|
||||
|
||||
/* now make sure the key is not on the revocation list */
|
||||
for (crlEntry = crl->crl.entries; crlEntry && *crlEntry; crlEntry++) {
|
||||
if (PORT_Memcmp((*crlEntry)->serialNumber.data,
|
||||
key->u.fortezza.KMID,
|
||||
(*crlEntry)->serialNumber.len) == 0) {
|
||||
PORT_SetError(SEC_ERROR_REVOKED_KEY);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
rv = SECSuccess;
|
||||
|
||||
done:
|
||||
if (issuerCert) CERT_DestroyCertificate(issuerCert);
|
||||
if (crl) SEC_DestroyCrl(crl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert,
|
||||
CERTCertificate *caCert, int64 t, void * wincx)
|
||||
|
@ -405,85 +332,6 @@ cert_AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, unsigned long err
|
|||
cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, (void *)arg); \
|
||||
}
|
||||
|
||||
|
||||
typedef enum { cbd_None, cbd_User, cbd_CA } cbd_FortezzaType;
|
||||
|
||||
static SECStatus
|
||||
cert_VerifyFortezzaV1Cert(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||
cbd_FortezzaType *next_type, cbd_FortezzaType last_type,
|
||||
int64 t, void *wincx)
|
||||
{
|
||||
unsigned char priv = 0;
|
||||
SECKEYPublicKey *key;
|
||||
SECStatus rv;
|
||||
|
||||
*next_type = cbd_CA;
|
||||
|
||||
/* read the key */
|
||||
key = CERT_ExtractPublicKey(cert);
|
||||
|
||||
/* Cant' get Key? fail. */
|
||||
if (key == NULL) {
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
/* if the issuer is not an old fortezza cert, we bail */
|
||||
if (key->keyType != fortezzaKey) {
|
||||
SECKEY_DestroyPublicKey(key);
|
||||
/* CA Cert not fortezza */
|
||||
PORT_SetError(SEC_ERROR_NOT_FORTEZZA_ISSUER);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* get the privilege mask */
|
||||
if (key->u.fortezza.DSSprivilege.len > 0) {
|
||||
priv = key->u.fortezza.DSSprivilege.data[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure the CA's keys are OK
|
||||
*/
|
||||
|
||||
rv = SEC_CheckKRL(handle, key, NULL, t, wincx);
|
||||
SECKEY_DestroyPublicKey(key);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
switch (last_type) {
|
||||
case cbd_User:
|
||||
/* first check for subordination */
|
||||
/*rv = FortezzaSubordinateCheck(cert,issuerCert);*/
|
||||
rv = SECSuccess;
|
||||
|
||||
/* now check for issuer privilege */
|
||||
if ((rv != SECSuccess) || ((priv & 0x10) == 0)) {
|
||||
/* bail */
|
||||
PORT_SetError (SEC_ERROR_CA_CERT_INVALID);
|
||||
return SECFailure;
|
||||
}
|
||||
break;
|
||||
case cbd_CA:
|
||||
if ((priv & 0x20) == 0) {
|
||||
/* bail */
|
||||
PORT_SetError (SEC_ERROR_CA_CERT_INVALID);
|
||||
return SECFailure;
|
||||
}
|
||||
break;
|
||||
case cbd_None:
|
||||
*next_type = (priv & 0x30) ? cbd_CA : cbd_User;
|
||||
break;
|
||||
default:
|
||||
/* bail */ /* shouldn't ever happen */
|
||||
PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
||||
static SECStatus
|
||||
cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||
PRBool checkSig, PRBool* sigerror,
|
||||
|
@ -496,7 +344,6 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
CERTCertificate *subjectCert = NULL;
|
||||
CERTCertificate *badCert = NULL;
|
||||
PRBool isca;
|
||||
PRBool isFortezzaV1 = PR_FALSE;
|
||||
SECStatus rv;
|
||||
SECStatus rvFinal = SECSuccess;
|
||||
int count;
|
||||
|
@ -512,8 +359,6 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
int namesCount = 0;
|
||||
PRBool subjectCertIsSelfIssued;
|
||||
|
||||
cbd_FortezzaType last_type = cbd_None;
|
||||
|
||||
if (revoked) {
|
||||
*revoked = PR_FALSE;
|
||||
}
|
||||
|
@ -562,21 +407,6 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
goto loser;
|
||||
}
|
||||
|
||||
/* determine if the cert is fortezza.
|
||||
*/
|
||||
isFortezzaV1 = (PRBool)
|
||||
(CERT_GetCertKeyType(&subjectCert->subjectPublicKeyInfo)
|
||||
== fortezzaKey);
|
||||
|
||||
if (isFortezzaV1) {
|
||||
rv = cert_VerifyFortezzaV1Cert(handle, subjectCert, &last_type,
|
||||
cbd_None, t, wincx);
|
||||
if (rv == SECFailure) {
|
||||
/**** PORT_SetError is already set by cert_VerifyFortezzaV1Cert **/
|
||||
LOG_ERROR_OR_EXIT(log,subjectCert,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL) {
|
||||
goto loser;
|
||||
|
@ -663,19 +493,6 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - fortezza may need error logging stuff added
|
||||
*/
|
||||
if (isFortezzaV1) {
|
||||
rv = cert_VerifyFortezzaV1Cert(handle, issuerCert, &last_type,
|
||||
last_type, t, wincx);
|
||||
if (rv == SECFailure) {
|
||||
/**** PORT_SetError is already set by *
|
||||
* cert_VerifyFortezzaV1Cert **/
|
||||
LOG_ERROR_OR_EXIT(log,subjectCert,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the basicConstraint extension is included in an immediate CA
|
||||
* certificate, make sure that the isCA flag is on. If the
|
||||
* pathLenConstraint component exists, it must be greater than the
|
||||
|
@ -683,12 +500,6 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
* is omitted, we will assume that this is a CA certificate with
|
||||
* an unlimited pathLenConstraint (since it already passes the
|
||||
* netscape-cert-type extension checking).
|
||||
*
|
||||
* In the fortezza (V1) case, we've already checked the CA bits
|
||||
* in the key, so we're presumed to be a CA; however we really don't
|
||||
* want to bypass Basic constraint or netscape extension parsing.
|
||||
*
|
||||
* In Fortezza V2, basicConstraint will be set for every CA,PCA,PAA
|
||||
*/
|
||||
|
||||
rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint);
|
||||
|
@ -697,10 +508,8 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0);
|
||||
}
|
||||
pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT;
|
||||
/* no basic constraints found, if we're fortezza, CA bit is already
|
||||
* verified (isca = PR_TRUE). otherwise, we aren't (yet) a ca
|
||||
* isca = PR_FALSE */
|
||||
isca = isFortezzaV1;
|
||||
/* no basic constraints found, we aren't (yet) a CA. */
|
||||
isca = PR_FALSE;
|
||||
} else {
|
||||
if ( basicConstraint.isCA == PR_FALSE ) {
|
||||
PORT_SetError (SEC_ERROR_CA_CERT_INVALID);
|
||||
|
@ -960,12 +769,6 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
* is omitted, we will assume that this is a CA certificate with
|
||||
* an unlimited pathLenConstraint (since it already passes the
|
||||
* netscape-cert-type extension checking).
|
||||
*
|
||||
* In the fortezza (V1) case, we've already checked the CA bits
|
||||
* in the key, so we're presumed to be a CA; however we really don't
|
||||
* want to bypass Basic constraint or netscape extension parsing.
|
||||
*
|
||||
* In Fortezza V2, basicConstraint will be set for every CA,PCA,PAA
|
||||
*/
|
||||
|
||||
rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
|
||||
|
@ -973,9 +776,7 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {
|
||||
LOG_ERROR_OR_EXIT(log,cert,0,0);
|
||||
}
|
||||
/* no basic constraints found, if we're fortezza, CA bit is already
|
||||
* verified (isca = PR_TRUE). otherwise, we aren't (yet) a ca
|
||||
* isca = PR_FALSE */
|
||||
/* no basic constraints found, we aren't (yet) a CA. */
|
||||
isca = PR_FALSE;
|
||||
} else {
|
||||
if ( basicConstraint.isCA == PR_FALSE ) {
|
||||
|
|
|
@ -105,47 +105,6 @@ const SEC_ASN1Template SECKEY_DHParamKeyTemplate[] = {
|
|||
{ 0, }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_FortezzaParameterTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
|
||||
{ SEC_ASN1_OCTET_STRING, offsetof(SECKEYPQGParams,prime), },
|
||||
{ SEC_ASN1_OCTET_STRING, offsetof(SECKEYPQGParams,subPrime), },
|
||||
{ SEC_ASN1_OCTET_STRING, offsetof(SECKEYPQGParams,base), },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_FortezzaDiffParameterTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYDiffPQGParams) },
|
||||
{ SEC_ASN1_INLINE, offsetof(SECKEYDiffPQGParams,DiffKEAParams),
|
||||
SECKEY_FortezzaParameterTemplate},
|
||||
{ SEC_ASN1_INLINE, offsetof(SECKEYDiffPQGParams,DiffDSAParams),
|
||||
SECKEY_FortezzaParameterTemplate},
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_FortezzaPreParamTemplate[] = {
|
||||
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
|
||||
SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(SECKEYPQGDualParams,CommParams),
|
||||
SECKEY_FortezzaParameterTemplate},
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_FortezzaAltPreParamTemplate[] = {
|
||||
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
|
||||
SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(SECKEYPQGDualParams,DiffParams),
|
||||
SECKEY_FortezzaDiffParameterTemplate},
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_KEAPublicKeyTemplate[] = {
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.kea.publicValue), },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template SECKEY_KEAParamsTemplate[] = {
|
||||
{ SEC_ASN1_OCTET_STRING, offsetof(SECKEYPublicKey,u.kea.params.hash), },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate)
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate)
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate)
|
||||
|
@ -187,12 +146,6 @@ prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk)
|
|||
pubk->u.dh.publicValue.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_kea_pub_key_for_asn1(SECKEYPublicKey *pubk)
|
||||
{
|
||||
pubk->u.kea.publicValue.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
/* Create an RSA key pair is any slot able to do so.
|
||||
** The created keys are "session" (temporary), not "token" (permanent),
|
||||
** and they are "sensitive", which makes them costly to move to another token.
|
||||
|
@ -603,149 +556,6 @@ SECKEY_UpdateCertPQG(CERTCertificate * subjectCert)
|
|||
}
|
||||
|
||||
|
||||
/* Decode the PQG parameters. The params could be stored in two
|
||||
* possible formats, the old fortezza-only wrapped format or
|
||||
* the standard DER encoded format. Store the decoded parameters in an
|
||||
* old fortezza cert data structure */
|
||||
|
||||
SECStatus
|
||||
SECKEY_FortezzaDecodePQGtoOld(PRArenaPool *arena, SECKEYPublicKey *pubk,
|
||||
SECItem *params) {
|
||||
SECStatus rv;
|
||||
SECKEYPQGDualParams dual_params;
|
||||
SECItem newparams;
|
||||
|
||||
PORT_Assert(arena);
|
||||
|
||||
if (params == NULL) return SECFailure;
|
||||
|
||||
if (params->data == NULL) return SECFailure;
|
||||
|
||||
/* make a copy of the data into the arena so QuickDER output is valid */
|
||||
rv = SECITEM_CopyItem(arena, &newparams, params);
|
||||
|
||||
/* Check if params use the standard format.
|
||||
* The value 0xa1 will appear in the first byte of the parameter data
|
||||
* if the PQG parameters are not using the standard format. This
|
||||
* code should be changed to use a better method to detect non-standard
|
||||
* parameters. */
|
||||
|
||||
if ((newparams.data[0] != 0xa1) &&
|
||||
(newparams.data[0] != 0xa0)) {
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
/* PQG params are in the standard format */
|
||||
|
||||
/* Store DSA PQG parameters */
|
||||
prepare_pqg_params_for_asn1(&pubk->u.fortezza.params);
|
||||
rv = SEC_QuickDERDecodeItem(arena, &pubk->u.fortezza.params,
|
||||
SECKEY_PQGParamsTemplate,
|
||||
&newparams);
|
||||
}
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
|
||||
/* Copy the DSA PQG parameters to the KEA PQG parameters. */
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime,
|
||||
&pubk->u.fortezza.params.prime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime,
|
||||
&pubk->u.fortezza.params.subPrime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base,
|
||||
&pubk->u.fortezza.params.base);
|
||||
}
|
||||
} else {
|
||||
|
||||
dual_params.CommParams.prime.len = 0;
|
||||
dual_params.CommParams.subPrime.len = 0;
|
||||
dual_params.CommParams.base.len = 0;
|
||||
dual_params.DiffParams.DiffDSAParams.prime.len = 0;
|
||||
dual_params.DiffParams.DiffDSAParams.subPrime.len = 0;
|
||||
dual_params.DiffParams.DiffDSAParams.base.len = 0;
|
||||
|
||||
/* else the old fortezza-only wrapped format is used. */
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
if (newparams.data[0] == 0xa1) {
|
||||
rv = SEC_QuickDERDecodeItem(arena, &dual_params,
|
||||
SECKEY_FortezzaPreParamTemplate, &newparams);
|
||||
} else {
|
||||
rv = SEC_QuickDERDecodeItem(arena, &dual_params,
|
||||
SECKEY_FortezzaAltPreParamTemplate, &newparams);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (dual_params.CommParams.prime.len > 0) &&
|
||||
(dual_params.CommParams.subPrime.len > 0) &&
|
||||
(dual_params.CommParams.base.len > 0) ) {
|
||||
/* copy in common params */
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.prime,
|
||||
&dual_params.CommParams.prime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.subPrime,
|
||||
&dual_params.CommParams.subPrime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.base,
|
||||
&dual_params.CommParams.base);
|
||||
}
|
||||
|
||||
/* Copy the DSA PQG parameters to the KEA PQG parameters. */
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime,
|
||||
&pubk->u.fortezza.params.prime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime,
|
||||
&pubk->u.fortezza.params.subPrime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base,
|
||||
&pubk->u.fortezza.params.base);
|
||||
}
|
||||
} else {
|
||||
|
||||
/* else copy in different params */
|
||||
|
||||
/* copy DSA PQG parameters */
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.prime,
|
||||
&dual_params.DiffParams.DiffDSAParams.prime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.subPrime,
|
||||
&dual_params.DiffParams.DiffDSAParams.subPrime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.base,
|
||||
&dual_params.DiffParams.DiffDSAParams.base);
|
||||
}
|
||||
|
||||
/* copy KEA PQG parameters */
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime,
|
||||
&dual_params.DiffParams.DiffKEAParams.prime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime,
|
||||
&dual_params.DiffParams.DiffKEAParams.subPrime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base,
|
||||
&dual_params.DiffParams.DiffKEAParams.base);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* Decode the DSA PQG parameters. The params could be stored in two
|
||||
* possible formats, the old fortezza-only wrapped format or
|
||||
* the normal standard format. Store the decoded parameters in
|
||||
|
@ -754,7 +564,6 @@ SECKEY_FortezzaDecodePQGtoOld(PRArenaPool *arena, SECKEYPublicKey *pubk,
|
|||
SECStatus
|
||||
SECKEY_DSADecodePQG(PRArenaPool *arena, SECKEYPublicKey *pubk, SECItem *params) {
|
||||
SECStatus rv;
|
||||
SECKEYPQGDualParams dual_params;
|
||||
SECItem newparams;
|
||||
|
||||
if (params == NULL) return SECFailure;
|
||||
|
@ -784,187 +593,16 @@ SECKEY_DSADecodePQG(PRArenaPool *arena, SECKEYPublicKey *pubk, SECItem *params)
|
|||
}
|
||||
} else {
|
||||
|
||||
dual_params.CommParams.prime.len = 0;
|
||||
dual_params.CommParams.subPrime.len = 0;
|
||||
dual_params.CommParams.base.len = 0;
|
||||
dual_params.DiffParams.DiffDSAParams.prime.len = 0;
|
||||
dual_params.DiffParams.DiffDSAParams.subPrime.len = 0;
|
||||
dual_params.DiffParams.DiffDSAParams.base.len = 0;
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
/* else the old fortezza-only wrapped format is used. */
|
||||
if (newparams.data[0] == 0xa1) {
|
||||
rv = SEC_QuickDERDecodeItem(arena, &dual_params,
|
||||
SECKEY_FortezzaPreParamTemplate, &newparams);
|
||||
} else {
|
||||
rv = SEC_QuickDERDecodeItem(arena, &dual_params,
|
||||
SECKEY_FortezzaAltPreParamTemplate, &newparams);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (dual_params.CommParams.prime.len > 0) &&
|
||||
(dual_params.CommParams.subPrime.len > 0) &&
|
||||
(dual_params.CommParams.base.len > 0) ) {
|
||||
/* copy in common params */
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
|
||||
&dual_params.CommParams.prime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
|
||||
&dual_params.CommParams.subPrime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
|
||||
&dual_params.CommParams.base);
|
||||
}
|
||||
} else {
|
||||
|
||||
/* else copy in different params */
|
||||
|
||||
/* copy DSA PQG parameters */
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
|
||||
&dual_params.DiffParams.DiffDSAParams.prime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
|
||||
&dual_params.DiffParams.DiffDSAParams.subPrime);
|
||||
}
|
||||
if (SECSuccess == rv) {
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
|
||||
&dual_params.DiffParams.DiffDSAParams.base);
|
||||
}
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
rv = SECFailure;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* Decodes the DER encoded fortezza public key and stores the results in a
|
||||
* structure of type SECKEYPublicKey. */
|
||||
|
||||
SECStatus
|
||||
SECKEY_FortezzaDecodeCertKey(PRArenaPool *arena, SECKEYPublicKey *pubk,
|
||||
SECItem *rawkey, SECItem *params) {
|
||||
|
||||
unsigned char *rawptr = rawkey->data;
|
||||
unsigned char *end = rawkey->data + rawkey->len;
|
||||
unsigned char *clearptr;
|
||||
|
||||
/* first march down and decode the raw key data */
|
||||
|
||||
/* version */
|
||||
pubk->u.fortezza.KEAversion = *rawptr++;
|
||||
if (*rawptr++ != 0x01) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* KMID */
|
||||
PORT_Memcpy(pubk->u.fortezza.KMID,rawptr,
|
||||
sizeof(pubk->u.fortezza.KMID));
|
||||
rawptr += sizeof(pubk->u.fortezza.KMID);
|
||||
|
||||
/* clearance (the string up to the first byte with the hi-bit on */
|
||||
clearptr = rawptr;
|
||||
while ((rawptr < end) && (*rawptr++ & 0x80));
|
||||
|
||||
if (rawptr >= end) { return SECFailure; }
|
||||
pubk->u.fortezza.clearance.len = rawptr - clearptr;
|
||||
pubk->u.fortezza.clearance.data =
|
||||
(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.clearance.len);
|
||||
if (pubk->u.fortezza.clearance.data == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(pubk->u.fortezza.clearance.data,clearptr,
|
||||
pubk->u.fortezza.clearance.len);
|
||||
|
||||
/* KEAPrivilege (the string up to the first byte with the hi-bit on */
|
||||
clearptr = rawptr;
|
||||
while ((rawptr < end) && (*rawptr++ & 0x80));
|
||||
if (rawptr >= end) { return SECFailure; }
|
||||
pubk->u.fortezza.KEAprivilege.len = rawptr - clearptr;
|
||||
pubk->u.fortezza.KEAprivilege.data =
|
||||
(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.KEAprivilege.len);
|
||||
if (pubk->u.fortezza.KEAprivilege.data == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(pubk->u.fortezza.KEAprivilege.data,clearptr,
|
||||
pubk->u.fortezza.KEAprivilege.len);
|
||||
|
||||
|
||||
/* now copy the key. The next to bytes are the key length, and the
|
||||
* key follows */
|
||||
pubk->u.fortezza.KEAKey.len = (*rawptr << 8) | rawptr[1];
|
||||
|
||||
rawptr += 2;
|
||||
if (rawptr+pubk->u.fortezza.KEAKey.len > end) { return SECFailure; }
|
||||
pubk->u.fortezza.KEAKey.data =
|
||||
(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.KEAKey.len);
|
||||
if (pubk->u.fortezza.KEAKey.data == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(pubk->u.fortezza.KEAKey.data,rawptr,
|
||||
pubk->u.fortezza.KEAKey.len);
|
||||
rawptr += pubk->u.fortezza.KEAKey.len;
|
||||
|
||||
/* shared key */
|
||||
if (rawptr >= end) {
|
||||
pubk->u.fortezza.DSSKey.len = pubk->u.fortezza.KEAKey.len;
|
||||
/* this depends on the fact that we are going to get freed with an
|
||||
* ArenaFree call. We cannot free DSSKey and KEAKey separately */
|
||||
pubk->u.fortezza.DSSKey.data=
|
||||
pubk->u.fortezza.KEAKey.data;
|
||||
pubk->u.fortezza.DSSprivilege.len =
|
||||
pubk->u.fortezza.KEAprivilege.len;
|
||||
pubk->u.fortezza.DSSprivilege.data =
|
||||
pubk->u.fortezza.DSSprivilege.data;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/* DSS Version is next */
|
||||
pubk->u.fortezza.DSSversion = *rawptr++;
|
||||
|
||||
if (*rawptr++ != 2) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* DSSPrivilege (the string up to the first byte with the hi-bit on */
|
||||
clearptr = rawptr;
|
||||
while ((rawptr < end) && (*rawptr++ & 0x80));
|
||||
if (rawptr >= end) { return SECFailure; }
|
||||
pubk->u.fortezza.DSSprivilege.len = rawptr - clearptr;
|
||||
pubk->u.fortezza.DSSprivilege.data =
|
||||
(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.DSSprivilege.len);
|
||||
if (pubk->u.fortezza.DSSprivilege.data == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(pubk->u.fortezza.DSSprivilege.data,clearptr,
|
||||
pubk->u.fortezza.DSSprivilege.len);
|
||||
|
||||
/* finally copy the DSS key. The next to bytes are the key length,
|
||||
* and the key follows */
|
||||
pubk->u.fortezza.DSSKey.len = (*rawptr << 8) | rawptr[1];
|
||||
|
||||
rawptr += 2;
|
||||
if (rawptr+pubk->u.fortezza.DSSKey.len > end){ return SECFailure; }
|
||||
pubk->u.fortezza.DSSKey.data =
|
||||
(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.DSSKey.len);
|
||||
if (pubk->u.fortezza.DSSKey.data == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(pubk->u.fortezza.DSSKey.data,rawptr,
|
||||
pubk->u.fortezza.DSSKey.len);
|
||||
|
||||
/* ok, now we decode the parameters */
|
||||
done:
|
||||
|
||||
return SECKEY_FortezzaDecodePQGtoOld(arena, pubk, params);
|
||||
}
|
||||
|
||||
|
||||
/* Function used to make an oid tag to a key type */
|
||||
KeyType
|
||||
seckey_GetKeyType (SECOidTag tag) {
|
||||
|
@ -1094,59 +732,6 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
|
|||
|
||||
if (rv == SECSuccess) return pubk;
|
||||
break;
|
||||
case SEC_OID_MISSI_KEA_DSS_OLD:
|
||||
case SEC_OID_MISSI_KEA_DSS:
|
||||
case SEC_OID_MISSI_DSS_OLD:
|
||||
case SEC_OID_MISSI_DSS:
|
||||
pubk->keyType = fortezzaKey;
|
||||
rv = SECKEY_FortezzaDecodeCertKey(arena, pubk, &newOs,
|
||||
&spki->algorithm.parameters);
|
||||
if (rv == SECSuccess)
|
||||
return pubk;
|
||||
break;
|
||||
|
||||
case SEC_OID_MISSI_KEA:
|
||||
pubk->keyType = keaKey;
|
||||
|
||||
prepare_kea_pub_key_for_asn1(pubk);
|
||||
rv = SEC_QuickDERDecodeItem(arena, pubk,
|
||||
SECKEY_KEAPublicKeyTemplate, &newOs);
|
||||
if (rv != SECSuccess) break;
|
||||
|
||||
/* copy the DER into the arena, since Quick DER returns data that points
|
||||
into the DER input, which may get freed by the caller */
|
||||
rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters);
|
||||
if ( rv != SECSuccess )
|
||||
break;
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,
|
||||
&newParms);
|
||||
|
||||
if (rv == SECSuccess)
|
||||
return pubk;
|
||||
|
||||
break;
|
||||
|
||||
case SEC_OID_MISSI_ALT_KEA:
|
||||
pubk->keyType = keaKey;
|
||||
|
||||
rv = SECITEM_CopyItem(arena,&pubk->u.kea.publicValue,&newOs);
|
||||
if (rv != SECSuccess) break;
|
||||
|
||||
/* copy the DER into the arena, since Quick DER returns data that points
|
||||
into the DER input, which may get freed by the caller */
|
||||
rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters);
|
||||
if ( rv != SECSuccess )
|
||||
break;
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,
|
||||
&newParms);
|
||||
|
||||
if (rv == SECSuccess)
|
||||
return pubk;
|
||||
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
pubk->keyType = ecKey;
|
||||
pubk->u.ec.size = 0;
|
||||
|
@ -1163,6 +748,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
|
|||
break;
|
||||
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
@ -1733,6 +1319,7 @@ SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
|
|||
case nullKey:
|
||||
return copyk;
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -381,13 +381,10 @@ PKIX_RevocationChecker_Check(
|
|||
PKIX_UInt32 methodFlags = 0;
|
||||
|
||||
PKIX_DECREF(method);
|
||||
pkixErrorResult = PKIX_List_GetItem(revList, methodNum,
|
||||
(PKIX_PL_Object**)&method,
|
||||
plContext);
|
||||
if (pkixErrorResult) {
|
||||
/* Return error. Should not shappen in normal conditions. */
|
||||
goto cleanup;
|
||||
}
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetItem(revList, methodNum,
|
||||
(PKIX_PL_Object**)&method, plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
methodFlags = method->flags;
|
||||
if (!(methodFlags & PKIX_REV_M_TEST_USING_THIS_METHOD)) {
|
||||
/* Will not check with this method. Skipping... */
|
||||
|
@ -396,14 +393,14 @@ PKIX_RevocationChecker_Check(
|
|||
if (!onlyUseRemoteMethods &&
|
||||
methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
|
||||
pkixErrorResult =
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
(*method->localRevChecker)(cert, issuer, date,
|
||||
method, procParams,
|
||||
methodFlags,
|
||||
chainVerificationState,
|
||||
&revStatus,
|
||||
pReasonCode, plContext);
|
||||
pReasonCode, plContext),
|
||||
PKIX_REVCHECKERCHECKFAILED);
|
||||
methodStatus[methodNum] = revStatus;
|
||||
if (revStatus == PKIX_RevStatus_Revoked) {
|
||||
/* if error was generated use it as final error. */
|
||||
|
@ -423,12 +420,13 @@ PKIX_RevocationChecker_Check(
|
|||
methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
|
||||
if (!(methodFlags & PKIX_REV_M_FORBID_NETWORK_FETCHING)) {
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
pkixErrorResult =
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
(*method->externalRevChecker)(cert, issuer, date,
|
||||
method,
|
||||
procParams, methodFlags,
|
||||
&revStatus, pReasonCode,
|
||||
&nbioContext, plContext);
|
||||
&nbioContext, plContext),
|
||||
PKIX_REVCHECKERCHECKFAILED);
|
||||
methodStatus[methodNum] = revStatus;
|
||||
if (revStatus == PKIX_RevStatus_Revoked) {
|
||||
/* if error was generated use it as final error. */
|
||||
|
|
|
@ -349,6 +349,17 @@ extern PLHashNumber PR_CALLBACK pkix_ErrorGen_Hash (const void *key);
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/* like PKIX_CHECK but without goto cleanup */
|
||||
#define PKIX_CHECK_NO_GOTO(func, descNum) \
|
||||
do { \
|
||||
pkixErrorResult = (func); \
|
||||
if (pkixErrorResult) { \
|
||||
TRACE_CHECK_FAILURE((func), PKIX_ErrorText[descNum]) \
|
||||
pkixErrorClass = pkixErrorResult->errClass; \
|
||||
pkixErrorCode = descNum; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PKIX_CHECK_ONLY_FATAL(func, descNum) \
|
||||
do { \
|
||||
pkixTempErrorReceived = PKIX_FALSE; \
|
||||
|
|
Загрузка…
Ссылка в новой задаче