diff options
Diffstat (limited to 'security/nss/lib')
198 files changed, 14434 insertions, 6669 deletions
diff --git a/security/nss/lib/base/arena.c b/security/nss/lib/base/arena.c index 61fb07147..18238ee91 100644 --- a/security/nss/lib/base/arena.c +++ b/security/nss/lib/base/arena.c @@ -520,12 +520,12 @@ nssArena_Destroy } #endif /* NSSDEBUG */ - PR_Lock(arena->lock); if( (PRLock *)NULL == arena->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return PR_FAILURE; } + PR_Lock(arena->lock); #ifdef DEBUG if( PR_SUCCESS != arena_remove_pointer(arena) ) { @@ -585,12 +585,12 @@ nssArena_Mark } #endif /* NSSDEBUG */ - PR_Lock(arena->lock); if( (PRLock *)NULL == arena->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return (nssArenaMark *)NULL; } + PR_Lock(arena->lock); #ifdef ARENA_THREADMARK if( (PRThread *)NULL == arena->marking_thread ) { @@ -668,12 +668,12 @@ nss_arena_unmark_release return PR_FAILURE; } - PR_Lock(arena->lock); if( (PRLock *)NULL == arena->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return PR_FAILURE; } + PR_Lock(arena->lock); #ifdef ARENA_THREADMARK if( (PRThread *)NULL != arena->marking_thread ) { @@ -908,12 +908,12 @@ nss_ZAlloc } #endif /* NSSDEBUG */ - PR_Lock(arenaOpt->lock); if( (PRLock *)NULL == arenaOpt->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return (void *)NULL; } + PR_Lock(arenaOpt->lock); #ifdef ARENA_THREADMARK if( (PRThread *)NULL != arenaOpt->marking_thread ) { diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index 9c5c22f31..f710db899 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -864,8 +864,7 @@ CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, } if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) { - PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); - goto loser; + cert->options.bits.hasUnsupportedCriticalExt = PR_TRUE; } /* generate and save the database key for the cert */ diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h index 8567ebbe4..b50ad6e5c 100644 --- a/security/nss/lib/certdb/certt.h +++ b/security/nss/lib/certdb/certt.h @@ -301,7 +301,13 @@ struct CERTCertificateStr { * XXX - these should be moved into some sort of application specific * data structure. They are only used by the browser right now. */ - struct SECSocketNode *authsocketlist; + union { + void* apointer; /* was struct SECSocketNode* authsocketlist */ + struct { + unsigned int hasUnsupportedCriticalExt :1; + /* add any new option bits needed here */ + } bits; + } options; int series; /* was int authsocketcount; record the series of the pkcs11ID */ /* This is PKCS #11 stuff. */ diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index 7cd308c0a..0c8bcc505 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -463,13 +463,21 @@ CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl, SECStatus rv; OpaqueCRLFields* extended = NULL; const SEC_ASN1Template* crlTemplate = CERT_SignedCrlTemplate; + PRInt32 testOptions = options; - if (!derSignedCrl || - ( (options & CRL_DECODE_ADOPT_HEAP_DER) && /* adopting DER requires - not copying it */ - (!(options & CRL_DECODE_DONT_COPY_DER)) - ) - ) { + PORT_Assert(derSignedCrl); + if (!derSignedCrl) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + /* Adopting DER requires not copying it. Code that sets ADOPT flag + * but doesn't set DONT_COPY probably doesn't know What it is doing. + * That condition is a programming error in the caller. + */ + testOptions &= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER); + PORT_Assert(testOptions != CRL_DECODE_ADOPT_HEAP_DER); + if (testOptions == CRL_DECODE_ADOPT_HEAP_DER) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } @@ -570,9 +578,13 @@ CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl, loser: if (options & CRL_DECODE_KEEP_BAD_CRL) { - extended->decodingError = PR_TRUE; - crl->referenceCount = 1; - return(crl); + if (extended) { + extended->decodingError = PR_TRUE; + } + if (crl) { + crl->referenceCount = 1; + return(crl); + } } if ((narena == NULL) && arena ) { @@ -597,8 +609,9 @@ CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) * caching stuff used by certificates....? * return values : * - * SECSuccess means we got a valid DER CRL (passed in "decoded"), or no CRL at - * all + * SECSuccess means we got a valid decodable DER CRL, or no CRL at all. + * Caller may distinguish those cases by the value returned in "decoded". + * When DER CRL is not found, error code will be SEC_ERROR_CRL_NOT_FOUND. * * SECFailure means we got a fatal error - most likely, we found a CRL, * and it failed decoding, or there was an out of memory error. Do NOT ignore @@ -616,7 +629,6 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, SECItem *derCrl = NULL; CK_OBJECT_HANDLE crlHandle = 0; char *url = NULL; - int nsserror; PORT_Assert(decoded); if (!decoded) { @@ -624,15 +636,12 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, return SECFailure; } - /* XXX it would be really useful to be able to fetch the CRL directly into - an arena. This would avoid a copy later on in the decode step */ - PORT_SetError(0); derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey, type, &url); if (derCrl == NULL) { /* if we had a problem other than the CRL just didn't exist, return * a failure to the upper level */ - nsserror = PORT_GetError(); - if ((nsserror != 0) && (nsserror != SEC_ERROR_CRL_NOT_FOUND)) { + int nsserror = PORT_GetError(); + if (nsserror != SEC_ERROR_CRL_NOT_FOUND) { rv = SECFailure; } goto loser; @@ -640,15 +649,16 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, PORT_Assert(crlHandle != CK_INVALID_HANDLE); /* PK11_FindCrlByName obtained a slot reference. */ - if (!(decodeoptions & CRL_DECODE_DONT_COPY_DER) ) { - /* force adoption of the DER from the heap - this will cause it to be - automatically freed when SEC_DestroyCrl is invoked */ - decodeoptions |= CRL_DECODE_ADOPT_HEAP_DER; - } + /* derCRL is a fresh HEAP copy made for us by PK11_FindCrlByName. + Force adoption of the DER CRL from the heap - this will cause it + to be automatically freed when SEC_DestroyCrl is invoked */ + decodeoptions |= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER); + crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, type, decodeoptions); if (crl) { crl->slot = slot; slot = NULL; /* adopt it */ + derCrl = NULL; /* adopted by the crl struct */ crl->pkcs11ID = crlHandle; if (url) { crl->url = PORT_ArenaStrdup(crl->arena,url); @@ -667,10 +677,7 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, loser: if (derCrl) { - /* destroy the DER if it was copied to the CRL */ - if (crl && (!(decodeoptions & CRL_DECODE_DONT_COPY_DER)) ) { - SECITEM_FreeItem(derCrl, PR_TRUE); - } + SECITEM_FreeItem(derCrl, PR_TRUE); } *decoded = crl; @@ -678,7 +685,6 @@ loser: return rv; } -SECStatus SEC_DestroyCrl(CERTSignedCrl *crl); CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url, @@ -687,15 +693,15 @@ crl_storeCRL (PK11SlotInfo *slot,char *url, CERTSignedCrl *oldCrl = NULL, *crl = NULL; PRBool deleteOldCrl = PR_FALSE; CK_OBJECT_HANDLE crlHandle = CK_INVALID_HANDLE; + SECStatus rv; PORT_Assert(newCrl); PORT_Assert(derCrl); /* we can't use the cache here because we must look in the same token */ - SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type, + rv = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type, &oldCrl, CRL_DECODE_SKIP_ENTRIES); - /* if there is an old crl on the token, make sure the one we are installing is newer. If not, exit out, otherwise delete the old crl. @@ -2127,7 +2133,6 @@ static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer, } *returned = NULL; cache = PORT_ZAlloc(sizeof(CRLDPCache)); - PORT_Assert(cache); if (!cache) { return SECFailure; @@ -2139,6 +2144,7 @@ static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer, #endif if (!cache->lock) { + PORT_Free(cache); return SECFailure; } if (issuer) @@ -2776,25 +2782,29 @@ SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl) } if (PR_TRUE == dupe) { - DPCache_RemoveCRL(cache, i); /* got a match */ - cache->mustchoose = PR_TRUE; - removed = PR_TRUE; + rv = DPCache_RemoveCRL(cache, i); /* got a match */ + if (SECSuccess == rv) { + cache->mustchoose = PR_TRUE; + removed = PR_TRUE; + } break; } } DPCache_UnlockWrite(); + + if (SECSuccess != CachedCrl_Destroy(returned) ) { + rv = SECFailure; + } } ReleaseDPCache(cache, writeLocked); - - if (PR_TRUE != removed) - { - rv = SECFailure; - } } - SEC_DestroyCrl(oldcrl); /* need to do this because object is refcounted */ - if (PR_TRUE != removed) + if (SECSuccess != SEC_DestroyCrl(oldcrl) ) { + /* need to do this because object is refcounted */ + rv = SECFailure; + } + if (SECSuccess == rv && PR_TRUE != removed) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index 18e35b299..4f820463f 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -155,6 +155,9 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, NSSCryptoContext *context; nssCryptokiObject *permInstance; NSSCertificate *c = STAN_GetNSSCertificate(cert); + nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + context = c->object.cryptoContext; if (!context) { PORT_SetError(SEC_ERROR_ADDING_CERT); @@ -170,9 +173,10 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena); } /* Delete the temp instance */ - nssCertificateStore_Lock(context->certStore); + nssCertificateStore_Lock(context->certStore, &lockTrace); nssCertificateStore_RemoveCertLOCKED(context->certStore, c); - nssCertificateStore_Unlock(context->certStore); + nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); c->object.cryptoContext = NULL; /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); @@ -225,7 +229,7 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, PRStatus nssrv; NSSCertificate *c; CERTCertificate *cc; - NSSCertificate *tempCert; + NSSCertificate *tempCert = NULL; nssPKIObject *pkio; NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); @@ -256,7 +260,7 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, return cc; } } - pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC); + pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor); if (!pkio) { return NULL; } @@ -307,33 +311,26 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); } - /* this function cannot detect if the cert exists as a temp cert now, but - * didn't when CERT_NewTemp was first called. - */ - nssrv = NSSCryptoContext_ImportCertificate(gCC, c); - if (nssrv != PR_SUCCESS) { + + tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c); + if (!tempCert) { goto loser; } - /* so find the entry in the temp store */ - tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(gCC, - &c->issuer, - &c->serial); - /* destroy the copy */ + /* destroy our copy */ NSSCertificate_Destroy(c); - if (tempCert) { - /* and use the "official" entry */ - c = tempCert; - cc = STAN_GetCERTCertificateOrRelease(c); - if (!cc) { - return NULL; - } - } else { + /* and use the stored entry */ + c = tempCert; + cc = STAN_GetCERTCertificateOrRelease(c); + if (!cc) { + /* STAN_GetCERTCertificateOrRelease destroys c on failure. */ return NULL; } + cc->istemp = PR_TRUE; cc->isperm = PR_FALSE; return cc; loser: + /* Perhaps this should be nssCertificate_Destroy(c) */ nssPKIObject_Destroy(&c->object); return NULL; } @@ -811,23 +808,10 @@ certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr, emailProfile->data); } else if (profileTime && emailProfile) { PRStatus nssrv; - NSSDER subject; NSSItem profTime, profData; - NSSItem *pprofTime, *pprofData; - NSSITEM_FROM_SECITEM(&subject, &cert->derSubject); - if (profileTime) { - NSSITEM_FROM_SECITEM(&profTime, profileTime); - pprofTime = &profTime; - } else { - pprofTime = NULL; - } - if (emailProfile) { - NSSITEM_FROM_SECITEM(&profData, emailProfile); - pprofData = &profData; - } else { - pprofData = NULL; - } - stanProfile = nssSMIMEProfile_Create(c, pprofTime, pprofData); + NSSITEM_FROM_SECITEM(&profTime, profileTime); + NSSITEM_FROM_SECITEM(&profData, emailProfile); + stanProfile = nssSMIMEProfile_Create(c, &profTime, &profData); if (!stanProfile) goto loser; nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile); rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; diff --git a/security/nss/lib/certdb/xauthkid.c b/security/nss/lib/certdb/xauthkid.c index 8d9df2123..8fb5a0122 100644 --- a/security/nss/lib/certdb/xauthkid.c +++ b/security/nss/lib/certdb/xauthkid.c @@ -119,10 +119,10 @@ CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue) do { mark = PORT_ArenaMark (arena); - value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); - value->DERAuthCertIssuer = NULL; + value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); if (value == NULL) break; + value->DERAuthCertIssuer = NULL; /* 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, &newEncodedValue, encodedValue); diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c index 2c0ffe7cb..ea7f50a0e 100644 --- a/security/nss/lib/certhigh/certhigh.c +++ b/security/nss/lib/certhigh/certhigh.c @@ -443,15 +443,16 @@ CollectNicknames( NSSCertificate *c, void *data) /* allocate the node */ node = (stringNode*)PORT_ArenaAlloc(names->arena, sizeof(stringNode)); if ( node == NULL ) { - return(PR_FAILURE); + PORT_Free(nickname); + return PR_FAILURE; } /* copy the string */ len = PORT_Strlen(nickname) + 1; node->string = (char*)PORT_ArenaAlloc(names->arena, len); if ( node->string == NULL ) { - if (nickname) PORT_Free(nickname); - return(PR_FAILURE); + PORT_Free(nickname); + return PR_FAILURE; } PORT_Memcpy(node->string, nickname, len); @@ -494,7 +495,7 @@ CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx) names->totallen = 0; /* make sure we are logged in */ - (void) pk11_TraverseAllSlots(NULL, NULL, wincx); + (void) pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx); NSSTrustDomain_TraverseCertificates(handle, CollectNicknames, (void *)names); @@ -672,12 +673,12 @@ CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames, arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) goto loser; - dnames = (CERTDistNames*)PORT_Alloc(sizeof(CERTDistNames)); + dnames = PORT_ArenaZNew(arena, CERTDistNames); if (dnames == NULL) goto loser; dnames->arena = arena; dnames->nnames = nnames; - dnames->names = names = (SECItem*)PORT_Alloc(nnames * sizeof(SECItem)); + dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, nnames); if (names == NULL) goto loser; for (i = 0; i < nnames; i++) { @@ -720,11 +721,9 @@ CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr) if ( name ) { nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name, CERT_NameTemplate); - if ( nameItem == NULL ) { - goto loser; + if ( nameItem != NULL ) { + cert = CERT_FindCertByName(handle, nameItem); } - - cert = CERT_FindCertByName(handle, nameItem); CERT_DestroyName(name); } diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index 25d0eaf42..b57720d68 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -101,7 +101,6 @@ CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd, void *wincx) { SECStatus rv; - SECOidTag algid; SECItem sig; if ( !pubKey || !sd ) { @@ -114,9 +113,8 @@ CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd, /* convert sig->len from bit counts to byte count. */ DER_ConvertBitString(&sig); - algid = SECOID_GetAlgorithmTag(&sd->signatureAlgorithm); - rv = VFY_VerifyData(sd->data.data, sd->data.len, pubKey, &sig, - algid, wincx); + rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey, + &sig, &sd->signatureAlgorithm, NULL, wincx); return rv ? SECFailure : SECSuccess; } @@ -362,20 +360,20 @@ loser: chain, 2, NULL, &status, td, cc); nss_ZFreeIf(nssTime); if (status == PR_SUCCESS) { + PORT_Assert(me == chain[0]); /* if it's a root, the chain will only have one cert */ if (!chain[1]) { /* already has a reference from the call to BuildChain */ return cert; - } else { - CERT_DestroyCertificate(cert); /* the first cert in the chain */ - return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ - } - } else { - if (chain[0]) { - CERT_DestroyCertificate(cert); - } - PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); - } + } + NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ + return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ + } + if (chain[0]) { + PORT_Assert(me == chain[0]); + NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ + } + PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); return NULL; #endif } @@ -729,6 +727,13 @@ cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, namesCount += subjectNameListLen; namesList = cert_CombineNamesLists(namesList, subjectNameList); } + + /* check if the cert has an unsupported critical extension */ + if ( subjectCert->options.bits.hasUnsupportedCriticalExt ) { + PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); + LOG_ERROR_OR_EXIT(log,subjectCert,count,0); + } + /* find the certificate of the issuer */ issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage); if ( ! issuerCert ) { @@ -1207,30 +1212,21 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, } valid = SECSuccess ; /* start off assuming cert is valid */ -#ifdef notdef - /* check if this cert is in the Evil list */ - rv = CERT_CheckForEvilCert(cert); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - LOG_ERROR(log,cert,0,0); - return SECFailure; - } -#endif - /* make sure that the cert is valid at time t */ allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) || (requiredUsages & certificateUsageSSLServerWithStepUp)); validity = CERT_CheckCertValidTimes(cert, t, allowOverride); if ( validity != secCertTimeValid ) { - LOG_ERROR(log,cert,0,validity); - return SECFailure; + valid = SECFailure; + LOG_ERROR_OR_EXIT(log,cert,0,validity); } /* check key usage and netscape cert type */ cert_GetCertType(cert); certType = cert->nsCertType; - for (i=1;i<=certificateUsageHighest && !(SECFailure == valid && !returnedUsages) ;) { + for (i=1; i<=certificateUsageHighest && + (SECSuccess == valid || returnedUsages || log) ; ) { PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { NEXT_USAGE(); @@ -1394,7 +1390,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, if (PR_FALSE == checkedOCSP) { checkedOCSP = PR_TRUE; /* only check OCSP once */ statusConfig = CERT_GetStatusConfig(handle); - if ( (! (requiredUsages & certificateUsageStatusResponder)) && + if ( (! (requiredUsages == certificateUsageStatusResponder)) && statusConfig != NULL) { if (statusConfig->statusChecker != NULL) { rv = (* statusConfig->statusChecker)(handle, cert, @@ -1411,6 +1407,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, NEXT_USAGE(); } +loser: return(valid); } diff --git a/security/nss/lib/certhigh/manifest.mn b/security/nss/lib/certhigh/manifest.mn index bd8de3771..98eb9876d 100644 --- a/security/nss/lib/certhigh/manifest.mn +++ b/security/nss/lib/certhigh/manifest.mn @@ -43,6 +43,7 @@ EXPORTS = \ PRIVATE_EXPORTS = \ ocspti.h \ + ocspi.h \ $(NULL) MODULE = nss diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c index 9eda390b4..183f9b902 100644 --- a/security/nss/lib/certhigh/ocsp.c +++ b/security/nss/lib/certhigh/ocsp.c @@ -68,6 +68,59 @@ #include <stdarg.h> +static struct OCSPGlobalStruct { + PRLock *lock; + const SEC_HttpClientFcn *defaultHttpClientFcn; +} OCSP_Global = { NULL, NULL }; + +SECStatus +SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable) +{ + if (!OCSP_Global.lock) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + PR_Lock(OCSP_Global.lock); + OCSP_Global.defaultHttpClientFcn = fcnTable; + PR_Unlock(OCSP_Global.lock); + + return SECSuccess; +} + +/* this function is called at NSS initialization time */ +SECStatus InitOCSPGlobal(void) +{ + if (OCSP_Global.lock != NULL) { + /* already initialized */ + return SECSuccess; + } + + OCSP_Global.lock = PR_NewLock(); + + return (OCSP_Global.lock) ? SECSuccess : SECFailure; +} + +/* + * A return value of NULL means: + * The application did not register it's own HTTP client. + */ +static const SEC_HttpClientFcn *GetRegisteredHttpClient() +{ + const SEC_HttpClientFcn *retval; + + if (!OCSP_Global.lock) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return NULL; + } + + PR_Lock(OCSP_Global.lock); + retval = OCSP_Global.defaultHttpClientFcn; + PR_Unlock(OCSP_Global.lock); + + return retval; +} + /* * The following structure is only used internally. It is allocated when * someone turns on OCSP checking, and hangs off of the status-configuration @@ -801,6 +854,7 @@ ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest, /* prepare for following loser gotos */ rv = SECFailure; + PORT_SetError(0); extensionHandle = cert_StartExtensions(singleRequest, singleRequest->arena, SetSingleReqExts); @@ -1702,6 +1756,8 @@ ocsp_ParseURL(char *url, char **pHostname, PRUint16 *pPort, char **pPath) path[len] = '\0'; } else { path = PORT_Strdup("/"); + if (path == NULL) + goto loser; } *pHostname = hostname; @@ -1712,8 +1768,6 @@ ocsp_ParseURL(char *url, char **pHostname, PRUint16 *pPort, char **pPath) loser: if (hostname != NULL) PORT_Free(hostname); - if (path != NULL) - PORT_Free(path); PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); return SECFailure; } @@ -2133,6 +2187,110 @@ ocsp_GetEncodedResponse(PRArenaPool *arena, PRFileDesc *sock) return result; } +/* + * Limit the size of http responses we are willing to accept. + */ +#define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024 + +static SECItem * +fetchOcspHttpClientV1(PRArenaPool *arena, + const SEC_HttpClientFcnV1 *hcv1, + char *location, + SECItem *encodedRequest) +{ + char *hostname = NULL; + char *path = NULL; + PRUint16 port; + SECItem *encodedResponse = NULL; + SEC_HTTP_SERVER_SESSION pServerSession = NULL; + SEC_HTTP_REQUEST_SESSION pRequestSession = NULL; + PRUint16 myHttpResponseCode; + const char *myHttpResponseData; + PRUint32 myHttpResponseDataLen; + + if (ocsp_ParseURL(location, &hostname, &port, &path) == SECFailure) { + PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); + goto loser; + } + + PORT_Assert(hostname != NULL); + PORT_Assert(path != NULL); + + if ((*hcv1->createSessionFcn)( + hostname, + port, + &pServerSession) != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + /* We use a non-zero timeout, which means: + - the client will use blocking I/O + - TryFcn will not return WOULD_BLOCK nor a poll descriptor + - it's sufficient to call TryFcn once + */ + + if ((*hcv1->createFcn)( + pServerSession, + "http", + path, + "POST", + PR_TicksPerSecond() * 60, + &pRequestSession) != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + if ((*hcv1->setPostDataFcn)( + pRequestSession, + (char*)encodedRequest->data, + encodedRequest->len, + "application/ocsp-request") != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + /* we don't want result objects larger than this: */ + myHttpResponseDataLen = MAX_WANTED_OCSP_RESPONSE_LEN; + + if ((*hcv1->trySendAndReceiveFcn)( + pRequestSession, + NULL, + &myHttpResponseCode, + NULL, + NULL, + &myHttpResponseData, + &myHttpResponseDataLen) != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + if (myHttpResponseCode != 200) { + PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); + goto loser; + } + + encodedResponse = SECITEM_AllocItem(arena, NULL, myHttpResponseDataLen); + + if (!encodedResponse) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + goto loser; + } + + PORT_Memcpy(encodedResponse->data, myHttpResponseData, myHttpResponseDataLen); + +loser: + if (pRequestSession != NULL) + (*hcv1->freeFcn)(pRequestSession); + if (pServerSession != NULL) + (*hcv1->freeSessionFcn)(pServerSession); + if (path != NULL) + PORT_Free(path); + if (hostname != NULL) + PORT_Free(hostname); + + return encodedResponse; +} /* * FUNCTION: CERT_GetEncodedOCSPResponse @@ -2192,6 +2350,7 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, SECItem *encodedResponse = NULL; PRFileDesc *sock = NULL; SECStatus rv; + const SEC_HttpClientFcn *registeredHttpClient = NULL; request = CERT_CreateOCSPRequest(certList, time, addServiceLocator, signerCert); @@ -2207,11 +2366,27 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, if (encodedRequest == NULL) goto loser; - sock = ocsp_SendEncodedRequest(location, encodedRequest); - if (sock == NULL) - goto loser; + registeredHttpClient = GetRegisteredHttpClient(); + + if (registeredHttpClient + && + registeredHttpClient->version == 1) { + encodedResponse = fetchOcspHttpClientV1( + arena, + ®isteredHttpClient->fcnTable.ftable1, + location, + encodedRequest); + } + else { + /* use internal http client */ + + sock = ocsp_SendEncodedRequest(location, encodedRequest); + if (sock == NULL) + goto loser; + + encodedResponse = ocsp_GetEncodedResponse(arena, sock); + } - encodedResponse = ocsp_GetEncodedResponse(arena, sock); if (encodedResponse != NULL && pRequest != NULL) { *pRequest = request; request = NULL; /* avoid destroying below */ @@ -2268,6 +2443,7 @@ ocsp_CertIsOCSPSigner(CERTCertificate *cert) loser: retval = PR_FALSE; + PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT); goto done; success: retval = PR_TRUE; @@ -2453,7 +2629,7 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs, rv = SECFailure; if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) { /* Make the error a little more specific. */ - PORT_SetError(SEC_ERROR_UNKNOWN_SIGNER); + PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT); } goto finish; } @@ -2504,10 +2680,9 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs, */ DER_ConvertBitString(&rawSignature); - rv = VFY_VerifyData(encodedTBS->data, encodedTBS->len, signerKey, - &rawSignature, - SECOID_GetAlgorithmTag(&signature->signatureAlgorithm), - pwArg); + rv = VFY_VerifyDataWithAlgorithmID(encodedTBS->data, encodedTBS->len, + signerKey, &rawSignature, + &signature->signatureAlgorithm, NULL, pwArg); finish: if (signature->wasChecked) @@ -2622,15 +2797,16 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response, } /* - * See if two certIDs match. This can be easy or difficult, depending - * on whether the same hash algorithm was used. + * See if the request's certID and the single response's certID match. + * This can be easy or difficult, depending on whether the same hash + * algorithm was used. */ static PRBool ocsp_CertIDsMatch(CERTCertDBHandle *handle, - CERTOCSPCertID *certID1, CERTOCSPCertID *certID2) + CERTOCSPCertID *requestCertID, + CERTOCSPCertID *responseCertID) { PRBool match = PR_FALSE; - SECItem *foundHash = NULL; SECOidTag hashAlg; SECItem *keyHash = NULL; SECItem *nameHash = NULL; @@ -2641,52 +2817,54 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle, * * We just compare the easier things first. */ - if (SECITEM_CompareItem(&certID1->serialNumber, - &certID2->serialNumber) != SECEqual) { + if (SECITEM_CompareItem(&requestCertID->serialNumber, + &responseCertID->serialNumber) != SECEqual) { goto done; } - if (SECOID_CompareAlgorithmID(&certID1->hashAlgorithm, - &certID2->hashAlgorithm) == SECEqual) { + /* + * Make sure the "parameters" are not too bogus. Since we encoded + * requestCertID->hashAlgorithm, we don't need to check it. + */ + if (responseCertID->hashAlgorithm.parameters.len > 2) { + goto done; + } + if (SECITEM_CompareItem(&requestCertID->hashAlgorithm.algorithm, + &responseCertID->hashAlgorithm.algorithm) == SECEqual) { /* * If the hash algorithms match then we can do a simple compare * of the hash values themselves. */ - if ((SECITEM_CompareItem(&certID1->issuerNameHash, - &certID2->issuerNameHash) == SECEqual) - && (SECITEM_CompareItem(&certID1->issuerKeyHash, - &certID2->issuerKeyHash) == SECEqual)) { + if ((SECITEM_CompareItem(&requestCertID->issuerNameHash, + &responseCertID->issuerNameHash) == SECEqual) + && (SECITEM_CompareItem(&requestCertID->issuerKeyHash, + &responseCertID->issuerKeyHash) == SECEqual)) { match = PR_TRUE; } goto done; } - hashAlg = SECOID_FindOIDTag(&certID2->hashAlgorithm.algorithm); + hashAlg = SECOID_FindOIDTag(&responseCertID->hashAlgorithm.algorithm); switch (hashAlg) { case SEC_OID_SHA1: - keyHash = &certID1->issuerSHA1KeyHash; - nameHash = &certID1->issuerSHA1NameHash; + keyHash = &requestCertID->issuerSHA1KeyHash; + nameHash = &requestCertID->issuerSHA1NameHash; break; case SEC_OID_MD5: - keyHash = &certID1->issuerMD5KeyHash; - nameHash = &certID1->issuerMD5NameHash; + keyHash = &requestCertID->issuerMD5KeyHash; + nameHash = &requestCertID->issuerMD5NameHash; break; case SEC_OID_MD2: - keyHash = &certID1->issuerMD2KeyHash; - nameHash = &certID1->issuerMD2NameHash; - break; - default: - foundHash = NULL; + keyHash = &requestCertID->issuerMD2KeyHash; + nameHash = &requestCertID->issuerMD2NameHash; break; } - if (foundHash == NULL) { - goto done; - } - PORT_Assert(keyHash && nameHash); - - if ((SECITEM_CompareItem(nameHash, &certID2->issuerNameHash) == SECEqual) - && (SECITEM_CompareItem(keyHash, &certID2->issuerKeyHash) == SECEqual)) { + if ((keyHash != NULL) + && (SECITEM_CompareItem(nameHash, + &responseCertID->issuerNameHash) == SECEqual) + && (SECITEM_CompareItem(keyHash, + &responseCertID->issuerKeyHash) == SECEqual)) { match = PR_TRUE; } @@ -3025,7 +3203,7 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single, * char * * A copy of the URI for the OCSP method, if found. If either the * extension is not present or it does not contain an entry for OCSP, - * SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned. + * SEC_ERROR_CERT_BAD_ACCESS_LOCATION will be set and a NULL returned. * Any other error will also result in a NULL being returned. * * This result should be freed (via PORT_Free) when no longer in use. @@ -3053,8 +3231,10 @@ CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert) rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS, encodedAuthInfoAccess); - if (rv == SECFailure) + if (rv == SECFailure) { + PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); goto loser; + } /* * The rest of the things allocated in the routine will come out of @@ -3084,7 +3264,7 @@ CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert) * not there at all. */ if (locname == NULL) { - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); + PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); goto loser; } @@ -3101,7 +3281,7 @@ CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert) * this should probably be something more like the extension was * badly formed. */ - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); + PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); goto loser; } @@ -3307,10 +3487,13 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, */ location = ocsp_GetResponderLocation(handle, cert, &locationIsDefault); if (location == NULL) { - if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) + int err = PORT_GetError(); + if (err == SEC_ERROR_EXTENSION_NOT_FOUND || + err == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) { + PORT_SetError(0); return SECSuccess; - else - return SECFailure; + } + return SECFailure; } /* @@ -3590,8 +3773,6 @@ ocsp_InitStatusChecking(CERTCertDBHandle *handle) return SECSuccess; loser: - if (statusContext != NULL) - PORT_Free(statusContext); if (statusConfig != NULL) PORT_Free(statusConfig); return SECFailure; diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h index c188f6780..810bc010c 100644 --- a/security/nss/lib/certhigh/ocsp.h +++ b/security/nss/lib/certhigh/ocsp.h @@ -56,6 +56,18 @@ SEC_BEGIN_PROTOS /* + * This function registers the HttpClient with whose functions the + * HttpClientFcn structure have been populated as the default Http + * client. + * + * The function table must be a global object. + * The caller must ensure that NSS will be able to call + * the registered functions for the lifetime of the process. + */ +extern SECStatus +SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable); + +/* * FUNCTION: CERT_EnableOCSPChecking * Turns on OCSP checking for the given certificate database. * INPUTS: diff --git a/security/nss/lib/certhigh/ocspi.h b/security/nss/lib/certhigh/ocspi.h new file mode 100644 index 000000000..a1c1ccb78 --- /dev/null +++ b/security/nss/lib/certhigh/ocspi.h @@ -0,0 +1,47 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +/* + * ocspi.h - NSS internal interfaces to OCSP code + * + * $Id$ + */ + +#ifndef _OCSPI_H_ +#define _OCSPI_H_ + +SECStatus InitOCSPGlobal(void); + +#endif /* _OCSPI_H_ */ diff --git a/security/nss/lib/certhigh/ocspt.h b/security/nss/lib/certhigh/ocspt.h index 5171d9cdb..18ca8ecb6 100644 --- a/security/nss/lib/certhigh/ocspt.h +++ b/security/nss/lib/certhigh/ocspt.h @@ -59,4 +59,235 @@ typedef struct CERTOCSPCertIDStr CERTOCSPCertID; typedef struct CERTOCSPCertStatusStr CERTOCSPCertStatus; typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse; +/* + * This interface is described in terms of an HttpClient which + * supports at least a specified set of functions. (An implementer may + * provide HttpClients with additional functionality accessible only to + * users with a particular implementation in mind.) The basic behavior + * is provided by defining a set of functions, listed in an + * SEC_HttpServerFcnStruct. If the implementor of a SpecificHttpClient + * registers his SpecificHttpClient as the default HttpClient, then his + * functions will be called by the user of an HttpClient, such as an + * OCSPChecker. + * + * The implementer of a specific HttpClient (e.g., the NSS-provided + * DefaultHttpClient), populates an SEC_HttpClientFcnStruct, uses it to + * register his client, and waits for his functions to be called. + * + * For future expandability, the SEC_HttpClientFcnStruct is defined as a + * union, with the version field acting as a selector. The proposed + * initial version of the structure is given following the definition + * of the union. The HttpClientState structure is implementation- + * dependent, and should be opaque to the user. + */ + +typedef void * SEC_HTTP_SERVER_SESSION; +typedef void * SEC_HTTP_REQUEST_SESSION; + +/* + * This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a + * specific HttpClient will allocate the necessary space, when this + * function is called, and will free it when the corresponding FreeFcn + * is called. The SEC_HTTP_SERVER_SESSION object is passed, as an opaque object, + * to subsequent calls. + * + * If the function returns SECSuccess, the returned SEC_HTTP_SERVER_SESSION + * must be cleaned up with a call to SEC_HttpServer_FreeSession, + * after processing is finished. + */ +typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)( + const char *host, + PRUint16 portnum, + SEC_HTTP_SERVER_SESSION *pSession); + +/* + * This function is called to allow the implementation to attempt to keep + * the connection alive. Depending on the underlying platform, it might + * immediately return SECSuccess without having performed any operations. + * (If a connection has not been kept alive, a subsequent call to + * SEC_HttpRequest_TrySendAndReceiveFcn should reopen the connection + * automatically.) + * + * If the connection uses nonblocking I/O, this function may return + * SECWouldBlock and store a nonzero value at "pPollDesc". In that case + * the caller may wait on the poll descriptor, and should call this function + * again until SECSuccess (and a zero value at "pPollDesc") is obtained. + */ +typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)( + SEC_HTTP_SERVER_SESSION session, + PRPollDesc **pPollDesc); + +/* + * This function frees the client SEC_HTTP_SERVER_SESSION object, closes all + * SEC_HTTP_REQUEST_SESSIONs created for that server, discards all partial results, + * frees any memory that was allocated by the client, and invalidates any + * response pointers that might have been returned by prior server or request + * functions. + */ +typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)( + SEC_HTTP_SERVER_SESSION session); + +/* + * This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a + * specific HttpClient will allocate the necessary space, when this + * function is called, and will free it when the corresponding FreeFcn + * is called. The SEC_HTTP_REQUEST_SESSION object is passed, as an opaque object, + * to subsequent calls. + * + * An implementation that does not support the requested protocol variant + * (usually "http", but could eventually allow "https") or request method + * should return SECFailure. + * + * Timeout values may include the constants PR_INTERVAL_NO_TIMEOUT (wait + * forever) or PR_INTERVAL_NO_WAIT (nonblocking I/O). + * + * If the function returns SECSuccess, the returned SEC_HTTP_REQUEST_SESSION + * must be cleaned up with a call to SEC_HttpRequest_FreeSession, + * after processing is finished. + */ +typedef SECStatus (*SEC_HttpRequest_CreateFcn)( + SEC_HTTP_SERVER_SESSION session, + const char *http_protocol_variant, /* usually "http" */ + const char *path_and_query_string, + const char *http_request_method, + const PRIntervalTime timeout, + SEC_HTTP_REQUEST_SESSION *pRequest); + +/* + * This function sets data to be sent to the server for an HTTP request + * of http_request_method == POST. If a particular implementation + * supports it, the details for the POST request can be set by calling + * this function, prior to activating the request with TrySendAndReceiveFcn. + * + * An implementation that does not support the POST method should + * implement a SetPostDataFcn function that returns immediately. + * + * Setting http_content_type is optional, the parameter may + * by NULL or the empty string. + */ +typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)( + SEC_HTTP_REQUEST_SESSION request, + const char *http_data, + const PRUint32 http_data_len, + const char *http_content_type); + +/* + * This function sets an additional HTTP protocol request header. + * If a particular implementation supports it, one or multiple headers + * can be added to the request by calling this function once or multiple + * times, prior to activating the request with TryFcn. + * + * An implementation that does not support setting additional headers + * should implement an AddRequestHeaderFcn function that returns immediately. + */ +typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)( + SEC_HTTP_REQUEST_SESSION request, + const char *http_header_name, + const char *http_header_value); + +/* + * This function initiates or continues an HTTP request. After + * parameters have been set with the Create function and, optionally, + * modified or enhanced with the AddParams function, this call creates + * the socket connection and initiates the communication. + * + * If a timeout value of zero is specified, indicating non-blocking + * I/O, the client creates a non-blocking socket, and returns a status + * of SECWouldBlock and a non-NULL PRPollDesc if the operation is not + * complete. In that case all other return parameters are undefined. + * The caller is expected to repeat the call, possibly after using + * PRPoll to determine that a completion has occurred, until a return + * value of SECSuccess (and a NULL value for pPollDesc) or a return + * value of SECFailure (indicating failure on the network level) + * is obtained. + * + * http_response_data_len is both input and output parameter. + * If a pointer to a PRUint32 is supplied, the http client is + * expected to check the given integer value and always set an out + * value, even on failure. + * An input value of zero means, the caller will accept any response len. + * A different input value indicates the maximum response value acceptable + * to the caller. + * If data is successfully read and the size is acceptable to the caller, + * the function will return SECSuccess and set http_response_data_len to + * the size of the block returned in http_response_data. + * If the data read from the http server is larger than the acceptable + * size, the function will return SECFailure. + * http_response_data_len will be set to a value different from zero to + * indicate the reason of the failure. + * An out value of "0" means, the failure was unrelated to the + * acceptable size. + * An out value of "1" means, the result data is larger than the + * accpeptable size, but the real size is not yet known to the http client + * implementation and it stopped retrieving it, + * Any other out value combined with a return value of SECFailure + * will indicate the actual size of the server data. + * + * The caller is permitted to provide NULL values for any of the + * http_response arguments, indicating the caller is not interested in + * those values. If the caller does provide an address, the HttpClient + * stores at that address a pointer to the corresponding argument, at + * the completion of the operation. + * + * All returned pointers will be owned by the the HttpClient + * implementation and will remain valid until the call to + * SEC_HttpRequest_FreeFcn. + */ +typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)( + SEC_HTTP_REQUEST_SESSION request, + PRPollDesc **pPollDesc, + PRUint16 *http_response_code, + const char **http_response_content_type, + const char **http_response_headers, + const char **http_response_data, + PRUint32 *http_response_data_len); + +/* + * Calling CancelFcn asks for premature termination of the request. + * + * Future calls to SEC_HttpRequest_TrySendAndReceive should + * by avoided, but in this case the HttpClient implementation + * is expected to return immediately with SECFailure. + * + * After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn + * is still necessary to free resources. + */ +typedef SECStatus (*SEC_HttpRequest_CancelFcn)( + SEC_HTTP_REQUEST_SESSION request); + +/* + * Before calling this function, it must be assured the request + * has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has + * returned SECSuccess, or the request has been canceled with + * a call to SEC_HttpRequest_CancelFcn. + * + * This function frees the client state object, closes all sockets, + * discards all partial results, frees any memory that was allocated + * by the client, and invalidates all response pointers that might + * have been returned by SEC_HttpRequest_TrySendAndReceiveFcn + */ +typedef SECStatus (*SEC_HttpRequest_FreeFcn)( + SEC_HTTP_REQUEST_SESSION request); + +typedef struct SEC_HttpClientFcnV1Struct { + SEC_HttpServer_CreateSessionFcn createSessionFcn; + SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn; + SEC_HttpServer_FreeSessionFcn freeSessionFcn; + SEC_HttpRequest_CreateFcn createFcn; + SEC_HttpRequest_SetPostDataFcn setPostDataFcn; + SEC_HttpRequest_AddHeaderFcn addHeaderFcn; + SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn; + SEC_HttpRequest_CancelFcn cancelFcn; + SEC_HttpRequest_FreeFcn freeFcn; +} SEC_HttpClientFcnV1; + +typedef struct SEC_HttpClientFcnStruct { + PRInt16 version; + union { + SEC_HttpClientFcnV1 ftable1; + /* SEC_HttpClientFcnV2 ftable2; */ + /* ... */ + } fcnTable; +} SEC_HttpClientFcn; + #endif /* _OCSPT_H_ */ diff --git a/security/nss/lib/ckfw/builtins/binst.c b/security/nss/lib/ckfw/builtins/binst.c index 2df0777a0..2d912f4a4 100644 --- a/security/nss/lib/ckfw/builtins/binst.c +++ b/security/nss/lib/ckfw/builtins/binst.c @@ -101,6 +101,11 @@ builtins_mdInstance_GetLibraryVersion NSSCKFWInstance *fwInstance ) { + extern const char __nss_builtins_rcsid[]; + extern const char __nss_builtins_sccsid[]; + volatile char c; /* force a reference that won't get optimized away */ + + c = __nss_builtins_rcsid[0] + __nss_builtins_sccsid[0]; return nss_builtins_LibraryVersion; } diff --git a/security/nss/lib/ckfw/builtins/certdata.c b/security/nss/lib/ckfw/builtins/certdata.c index ca3d68970..c8f3dde8e 100644 --- a/security/nss/lib/ckfw/builtins/certdata.c +++ b/security/nss/lib/ckfw/builtins/certdata.c @@ -623,6 +623,60 @@ static const CK_ATTRIBUTE_TYPE nss_builtins_types_188 [] = { static const CK_ATTRIBUTE_TYPE nss_builtins_types_189 [] = { CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED }; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_190 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_191 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_192 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_193 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_194 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_195 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_196 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_197 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_198 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_199 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_200 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_201 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_202 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_203 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_204 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_205 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_206 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_207 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; #ifdef DEBUG static const NSSItem nss_builtins_items_0 [] = { { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) }, @@ -631,7 +685,7 @@ static const NSSItem nss_builtins_items_0 [] = { { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, { (void *)"CVS ID", (PRUint32)7 }, { (void *)"NSS", (PRUint32)4 }, - { (void *)"@(#) $RCSfile$ $Revision$ $Date$""; @(#) $RCSfile$ $Revision$ $Date$", (PRUint32)160 } + { (void *)"@(#) $RCSfile$ $Revision$ $Date$""; @(#) $RCSfile$ $Revision$ $Date$", (PRUint32)165 } }; #endif /* DEBUG */ static const NSSItem nss_builtins_items_1 [] = { @@ -7566,6 +7620,379 @@ static const NSSItem nss_builtins_items_118 [] = { { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Global CA 2", (PRUint32)21 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003" +"\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141" +"\154\040\103\101\040\062" +, (PRUint32)70 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003" +"\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141" +"\154\040\103\101\040\062" +, (PRUint32)70 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\003\146\060\202\002\116\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026" +"\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163" +"\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003\023" +"\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141\154" +"\040\103\101\040\062\060\036\027\015\060\064\060\063\060\064\060" +"\065\060\060\060\060\132\027\015\061\071\060\063\060\064\060\065" +"\060\060\060\060\132\060\104\061\013\060\011\006\003\125\004\006" +"\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015\107" +"\145\157\124\162\165\163\164\040\111\156\143\056\061\035\060\033" +"\006\003\125\004\003\023\024\107\145\157\124\162\165\163\164\040" +"\107\154\157\142\141\154\040\103\101\040\062\060\202\001\042\060" +"\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202" +"\001\017\000\060\202\001\012\002\202\001\001\000\357\074\115\100" +"\075\020\337\073\123\000\341\147\376\224\140\025\076\205\210\361" +"\211\015\220\310\050\043\231\005\350\053\040\235\306\363\140\106" +"\330\301\262\325\214\061\331\334\040\171\044\201\277\065\062\374" +"\143\151\333\261\052\153\356\041\130\362\010\351\170\313\157\313" +"\374\026\122\310\221\304\377\075\163\336\261\076\247\302\175\146" +"\301\365\176\122\044\032\342\325\147\221\320\202\020\327\170\113" +"\117\053\102\071\275\144\055\100\240\260\020\323\070\110\106\210" +"\241\014\273\072\063\052\142\230\373\000\235\023\131\177\157\073" +"\162\252\356\246\017\206\371\005\141\352\147\177\014\067\226\213" +"\346\151\026\107\021\302\047\131\003\263\246\140\302\041\100\126" +"\372\240\307\175\072\023\343\354\127\307\263\326\256\235\211\200" +"\367\001\347\054\366\226\053\023\015\171\054\331\300\344\206\173" +"\113\214\014\162\202\212\373\027\315\000\154\072\023\074\260\204" +"\207\113\026\172\051\262\117\333\035\324\013\363\146\067\275\330" +"\366\127\273\136\044\172\270\074\213\271\372\222\032\032\204\236" +"\330\164\217\252\033\177\136\364\376\105\042\041\002\003\001\000" +"\001\243\143\060\141\060\017\006\003\125\035\023\001\001\377\004" +"\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004" +"\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251\020" +"\025\130\040\005\011\060\037\006\003\125\035\043\004\030\060\026" +"\200\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251" +"\020\025\130\040\005\011\060\016\006\003\125\035\017\001\001\377" +"\004\004\003\002\001\206\060\015\006\011\052\206\110\206\367\015" +"\001\001\005\005\000\003\202\001\001\000\003\367\265\053\253\135" +"\020\374\173\262\262\136\254\233\016\176\123\170\131\076\102\004" +"\376\165\243\255\254\201\116\327\002\213\136\304\055\310\122\166" +"\307\054\037\374\201\062\230\321\113\306\222\223\063\065\061\057" +"\374\330\035\104\335\340\201\177\235\351\213\341\144\221\142\013" +"\071\010\214\254\164\235\131\331\172\131\122\227\021\271\026\173" +"\157\105\323\226\331\061\175\002\066\017\234\073\156\317\054\015" +"\003\106\105\353\240\364\177\110\104\306\010\100\314\336\033\160" +"\265\051\255\272\213\073\064\145\165\033\161\041\035\054\024\012" +"\260\226\225\270\326\352\362\145\373\051\272\117\352\221\223\164" +"\151\266\362\377\341\032\320\014\321\166\205\313\212\045\275\227" +"\136\054\157\025\231\046\347\266\051\377\042\354\311\002\307\126" +"\000\315\111\271\263\154\173\123\004\032\342\250\311\252\022\005" +"\043\302\316\347\273\004\002\314\300\107\242\344\304\051\057\133" +"\105\127\211\121\356\074\353\122\010\377\007\065\036\237\065\152" +"\107\112\126\230\321\132\205\037\214\365\042\277\253\316\203\363" +"\342\042\051\256\175\203\100\250\272\154" +, (PRUint32)874 } +}; +static const NSSItem nss_builtins_items_119 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Global CA 2", (PRUint32)21 }, + { (void *)"\251\351\170\010\024\067\130\210\362\005\031\260\155\053\015\053" +"\140\026\220\175" +, (PRUint32)20 }, + { (void *)"\016\100\247\154\336\003\135\217\321\017\344\321\215\371\154\251" +, (PRUint32)16 }, + { (void *)"\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003" +"\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141" +"\154\040\103\101\040\062" +, (PRUint32)70 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_120 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA", (PRUint32)22 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003" +"\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101" +, (PRUint32)71 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003" +"\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101" +, (PRUint32)71 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\005\150\060\202\003\120\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026" +"\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163" +"\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003\023" +"\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162" +"\163\141\154\040\103\101\060\036\027\015\060\064\060\063\060\064" +"\060\065\060\060\060\060\132\027\015\062\071\060\063\060\064\060" +"\065\060\060\060\060\132\060\105\061\013\060\011\006\003\125\004" +"\006\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015" +"\107\145\157\124\162\165\163\164\040\111\156\143\056\061\036\060" +"\034\006\003\125\004\003\023\025\107\145\157\124\162\165\163\164" +"\040\125\156\151\166\145\162\163\141\154\040\103\101\060\202\002" +"\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000" +"\003\202\002\017\000\060\202\002\012\002\202\002\001\000\246\025" +"\125\240\243\306\340\037\214\235\041\120\327\301\276\053\133\265" +"\244\236\241\331\162\130\275\000\033\114\277\141\311\024\035\105" +"\202\253\306\035\200\326\075\353\020\234\072\257\155\044\370\274" +"\161\001\236\006\365\174\137\036\301\016\125\312\203\232\131\060" +"\256\031\313\060\110\225\355\042\067\215\364\112\232\162\146\076" +"\255\225\300\340\026\000\340\020\037\053\061\016\327\224\124\323" +"\102\063\240\064\035\036\105\166\335\117\312\030\067\354\205\025" +"\172\031\010\374\325\307\234\360\362\251\056\020\251\222\346\075" +"\130\075\251\026\150\074\057\165\041\030\177\050\167\245\341\141" +"\027\267\246\351\370\036\231\333\163\156\364\012\242\041\154\356" +"\332\252\205\222\146\257\366\172\153\202\332\272\042\010\065\017" +"\317\102\361\065\372\152\356\176\053\045\314\072\021\344\155\257" +"\163\262\166\035\255\320\262\170\147\032\244\071\034\121\013\147" +"\126\203\375\070\135\015\316\335\360\273\053\226\037\336\173\062" +"\122\375\035\273\265\006\241\262\041\136\245\326\225\150\177\360" +"\231\236\334\105\010\076\347\322\011\015\065\224\335\200\116\123" +"\227\327\265\011\104\040\144\026\027\003\002\114\123\015\150\336" +"\325\252\162\115\223\155\202\016\333\234\275\317\264\363\134\135" +"\124\172\151\011\226\326\333\021\301\215\165\250\264\317\071\310" +"\316\074\274\044\174\346\142\312\341\275\175\247\275\127\145\013" +"\344\376\045\355\266\151\020\334\050\032\106\275\001\035\320\227" +"\265\341\230\073\300\067\144\326\075\224\356\013\341\365\050\256" +"\013\126\277\161\213\043\051\101\216\206\305\113\122\173\330\161" +"\253\037\212\025\246\073\203\132\327\130\001\121\306\114\101\331" +"\177\330\101\147\162\242\050\337\140\203\251\236\310\173\374\123" +"\163\162\131\365\223\172\027\166\016\316\367\345\134\331\013\125" +"\064\242\252\133\265\152\124\347\023\312\127\354\227\155\364\136" +"\006\057\105\213\130\324\043\026\222\344\026\156\050\143\131\060" +"\337\120\001\234\143\211\032\237\333\027\224\202\160\067\303\044" +"\236\232\107\326\132\312\116\250\151\211\162\037\221\154\333\176" +"\236\033\255\307\037\163\335\054\117\031\145\375\177\223\100\020" +"\056\322\360\355\074\236\056\050\076\151\046\063\305\173\002\003" +"\001\000\001\243\143\060\141\060\017\006\003\125\035\023\001\001" +"\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004" +"\026\004\024\332\273\056\252\260\014\270\210\046\121\164\134\155" +"\003\323\300\330\217\172\326\060\037\006\003\125\035\043\004\030" +"\060\026\200\024\332\273\056\252\260\014\270\210\046\121\164\134" +"\155\003\323\300\330\217\172\326\060\016\006\003\125\035\017\001" +"\001\377\004\004\003\002\001\206\060\015\006\011\052\206\110\206" +"\367\015\001\001\005\005\000\003\202\002\001\000\061\170\346\307" +"\265\337\270\224\100\311\161\304\250\065\354\106\035\302\205\363" +"\050\130\206\260\013\374\216\262\071\217\104\125\253\144\204\134" +"\151\251\320\232\070\074\372\345\037\065\345\104\343\200\171\224" +"\150\244\273\304\237\075\341\064\315\060\106\213\124\053\225\245" +"\357\367\077\231\204\375\065\346\317\061\306\334\152\277\247\327" +"\043\010\341\230\136\303\132\010\166\251\246\257\167\057\267\140" +"\275\104\106\152\357\227\377\163\225\301\216\350\223\373\375\061" +"\267\354\127\021\021\105\233\060\361\032\210\071\301\117\074\247" +"\000\325\307\374\253\155\200\042\160\245\014\340\135\004\051\002" +"\373\313\240\221\321\174\326\303\176\120\325\235\130\276\101\070" +"\353\271\165\074\025\331\233\311\112\203\131\300\332\123\375\063" +"\273\066\030\233\205\017\025\335\356\055\254\166\223\271\331\001" +"\215\110\020\250\373\365\070\206\361\333\012\306\275\204\243\043" +"\101\336\326\167\157\205\324\205\034\120\340\256\121\212\272\215" +"\076\166\342\271\312\047\362\137\237\357\156\131\015\006\330\053" +"\027\244\322\174\153\273\137\024\032\110\217\032\114\347\263\107" +"\034\216\114\105\053\040\356\110\337\347\335\011\216\030\250\332" +"\100\215\222\046\021\123\141\163\135\353\275\347\304\115\051\067" +"\141\353\254\071\055\147\056\026\326\365\000\203\205\241\314\177" +"\166\304\175\344\267\113\146\357\003\105\140\151\266\014\122\226" +"\222\204\136\246\243\265\244\076\053\331\314\330\033\107\252\362" +"\104\332\117\371\003\350\360\024\313\077\363\203\336\320\301\124" +"\343\267\350\012\067\115\213\040\131\003\060\031\241\054\310\275" +"\021\037\337\256\311\112\305\363\047\146\146\206\254\150\221\377" +"\331\346\123\034\017\213\134\151\145\012\046\310\036\064\303\135" +"\121\173\327\251\234\006\241\066\335\325\211\224\274\331\344\055" +"\014\136\011\154\010\227\174\243\075\174\223\377\077\241\024\247" +"\317\265\135\353\333\333\034\304\166\337\210\271\275\105\005\225" +"\033\256\374\106\152\114\257\110\343\316\256\017\322\176\353\346" +"\154\234\117\201\152\172\144\254\273\076\325\347\313\166\056\305" +"\247\110\301\134\220\017\313\310\077\372\346\062\341\215\033\157" +"\244\346\216\330\371\051\110\212\316\163\376\054" +, (PRUint32)1388 } +}; +static const NSSItem nss_builtins_items_121 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA", (PRUint32)22 }, + { (void *)"\346\041\363\065\103\171\005\232\113\150\060\235\212\057\164\042" +"\025\207\354\171" +, (PRUint32)20 }, + { (void *)"\222\145\130\213\242\032\061\162\163\150\134\264\245\172\007\110" +, (PRUint32)16 }, + { (void *)"\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003" +"\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101" +, (PRUint32)71 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_122 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA 2", (PRUint32)24 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003" +"\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101\040\062" +, (PRUint32)73 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003" +"\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101\040\062" +, (PRUint32)73 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\005\154\060\202\003\124\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026" +"\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163" +"\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003\023" +"\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162" +"\163\141\154\040\103\101\040\062\060\036\027\015\060\064\060\063" +"\060\064\060\065\060\060\060\060\132\027\015\062\071\060\063\060" +"\064\060\065\060\060\060\060\132\060\107\061\013\060\011\006\003" +"\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004\012" +"\023\015\107\145\157\124\162\165\163\164\040\111\156\143\056\061" +"\040\060\036\006\003\125\004\003\023\027\107\145\157\124\162\165" +"\163\164\040\125\156\151\166\145\162\163\141\154\040\103\101\040" +"\062\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001" +"\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002" +"\001\000\263\124\122\301\311\076\362\331\334\261\123\032\131\051" +"\347\261\303\105\050\345\327\321\355\305\305\113\241\252\164\173" +"\127\257\112\046\374\330\365\136\247\156\031\333\164\014\117\065" +"\133\062\013\001\343\333\353\172\167\065\352\252\132\340\326\350" +"\241\127\224\360\220\243\164\126\224\104\060\003\036\134\116\053" +"\205\046\164\202\172\014\166\240\157\115\316\101\055\240\025\006" +"\024\137\267\102\315\173\217\130\141\064\334\052\010\371\056\303" +"\001\246\042\104\034\114\007\202\346\133\316\320\112\174\004\323" +"\031\163\047\360\252\230\177\056\257\116\353\207\036\044\167\152" +"\135\266\350\133\105\272\334\303\241\005\157\126\216\217\020\046" +"\245\111\303\056\327\101\207\042\340\117\206\312\140\265\352\241" +"\143\300\001\227\020\171\275\000\074\022\155\053\025\261\254\113" +"\261\356\030\271\116\226\334\334\166\377\073\276\317\137\003\300" +"\374\073\350\276\106\033\377\332\100\302\122\367\376\343\072\367" +"\152\167\065\320\332\215\353\136\030\152\061\307\036\272\074\033" +"\050\326\153\124\306\252\133\327\242\054\033\031\314\242\002\366" +"\233\131\275\067\153\206\265\155\202\272\330\352\311\126\274\251" +"\066\130\375\076\031\363\355\014\046\251\223\070\370\117\301\135" +"\042\006\320\227\352\341\255\306\125\340\201\053\050\203\072\372" +"\364\173\041\121\000\276\122\070\316\315\146\171\250\364\201\126" +"\342\320\203\011\107\121\133\120\152\317\333\110\032\135\076\367" +"\313\366\145\367\154\361\225\370\002\073\062\126\202\071\172\133" +"\275\057\211\033\277\241\264\350\377\177\215\214\337\003\361\140" +"\116\130\021\114\353\243\077\020\053\203\232\001\163\331\224\155" +"\204\000\047\146\254\360\160\100\011\102\222\255\117\223\015\141" +"\011\121\044\330\222\325\013\224\141\262\207\262\355\377\232\065" +"\377\205\124\312\355\104\103\254\033\074\026\153\110\112\012\034" +"\100\210\037\222\302\013\000\005\377\362\310\002\112\244\252\251" +"\314\231\226\234\057\130\340\175\341\276\273\007\334\137\004\162" +"\134\061\064\303\354\137\055\340\075\144\220\042\346\321\354\270" +"\056\335\131\256\331\241\067\277\124\065\334\163\062\117\214\004" +"\036\063\262\311\106\361\330\134\310\125\120\311\150\275\250\272" +"\066\011\002\003\001\000\001\243\143\060\141\060\017\006\003\125" +"\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003" +"\125\035\016\004\026\004\024\166\363\125\341\372\244\066\373\360" +"\237\134\142\161\355\074\364\107\070\020\053\060\037\006\003\125" +"\035\043\004\030\060\026\200\024\166\363\125\341\372\244\066\373" +"\360\237\134\142\161\355\074\364\107\070\020\053\060\016\006\003" +"\125\035\017\001\001\377\004\004\003\002\001\206\060\015\006\011" +"\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001\000" +"\146\301\306\043\363\331\340\056\156\137\350\317\256\260\260\045" +"\115\053\370\073\130\233\100\044\067\132\313\253\026\111\377\263" +"\165\171\063\241\057\155\160\027\064\221\376\147\176\217\354\233" +"\345\136\202\251\125\037\057\334\324\121\007\022\376\254\026\076" +"\054\065\306\143\374\334\020\353\015\243\252\320\174\314\321\320" +"\057\121\056\304\024\132\336\350\031\341\076\306\314\244\051\347" +"\056\204\252\006\060\170\166\124\163\050\230\131\070\340\000\015" +"\142\323\102\175\041\237\256\075\072\214\325\372\167\015\030\053" +"\026\016\137\066\341\374\052\265\060\044\317\340\143\014\173\130" +"\032\376\231\272\102\022\261\221\364\174\150\342\310\350\257\054" +"\352\311\176\256\273\052\075\015\025\334\064\225\266\030\164\250" +"\152\017\307\264\364\023\304\344\133\355\012\322\244\227\114\052" +"\355\057\154\022\211\075\361\047\160\252\152\003\122\041\237\100" +"\250\147\120\362\363\132\037\337\337\043\366\334\170\116\346\230" +"\117\125\072\123\343\357\362\364\237\307\174\330\130\257\051\042" +"\227\270\340\275\221\056\260\166\354\127\021\317\357\051\104\363" +"\351\205\172\140\143\344\135\063\211\027\331\061\252\332\326\363" +"\030\065\162\317\207\053\057\143\043\204\135\204\214\077\127\240" +"\210\374\231\221\050\046\151\231\324\217\227\104\276\216\325\110" +"\261\244\050\051\361\025\264\341\345\236\335\370\217\246\157\046" +"\327\011\074\072\034\021\016\246\154\067\367\255\104\207\054\050" +"\307\330\164\202\263\320\157\112\127\273\065\051\047\240\213\350" +"\041\247\207\144\066\135\314\330\026\254\307\262\047\100\222\125" +"\070\050\215\121\156\335\024\147\123\154\161\134\046\204\115\165" +"\132\266\176\140\126\251\115\255\373\233\036\227\363\015\331\322" +"\227\124\167\332\075\022\267\340\036\357\010\006\254\371\205\207" +"\351\242\334\257\176\030\022\203\375\126\027\101\056\325\051\202" +"\175\231\364\061\366\161\251\317\054\001\047\245\005\271\252\262" +"\110\116\052\357\237\223\122\121\225\074\122\163\216\126\114\027" +"\100\300\011\050\344\213\152\110\123\333\354\315\125\125\361\306" +"\370\351\242\054\114\246\321\046\137\176\257\132\114\332\037\246" +"\362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222" +, (PRUint32)1392 } +}; +static const NSSItem nss_builtins_items_123 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA 2", (PRUint32)24 }, + { (void *)"\067\232\031\173\101\205\105\065\014\246\003\151\363\074\056\257" +"\107\117\040\171" +, (PRUint32)20 }, + { (void *)"\064\374\270\320\066\333\236\024\263\302\362\333\217\344\224\307" +, (PRUint32)16 }, + { (void *)"\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003" +"\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101\040\062" +, (PRUint32)73 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_124 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, { (void *)"UTN-USER First-Network Applications", (PRUint32)36 }, { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, { (void *)"\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123" @@ -7669,7 +8096,7 @@ static const NSSItem nss_builtins_items_118 [] = { "\152\372\246\070\254\037\304\204" , (PRUint32)1128 } }; -static const NSSItem nss_builtins_items_119 [] = { +static const NSSItem nss_builtins_items_125 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7700,7 +8127,7 @@ static const NSSItem nss_builtins_items_119 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_120 [] = { +static const NSSItem nss_builtins_items_126 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7787,7 +8214,7 @@ static const NSSItem nss_builtins_items_120 [] = { "\200\072\231\355\165\314\106\173" , (PRUint32)936 } }; -static const NSSItem nss_builtins_items_121 [] = { +static const NSSItem nss_builtins_items_127 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7813,7 +8240,7 @@ static const NSSItem nss_builtins_items_121 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_122 [] = { +static const NSSItem nss_builtins_items_128 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7932,7 +8359,7 @@ static const NSSItem nss_builtins_items_122 [] = { "\105\217\046\221\242\216\376\251" , (PRUint32)1448 } }; -static const NSSItem nss_builtins_items_123 [] = { +static const NSSItem nss_builtins_items_129 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7958,7 +8385,7 @@ static const NSSItem nss_builtins_items_123 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_124 [] = { +static const NSSItem nss_builtins_items_130 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8046,7 +8473,7 @@ static const NSSItem nss_builtins_items_124 [] = { "\222\340\134\366\007\017" , (PRUint32)934 } }; -static const NSSItem nss_builtins_items_125 [] = { +static const NSSItem nss_builtins_items_131 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8073,7 +8500,7 @@ static const NSSItem nss_builtins_items_125 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_126 [] = { +static const NSSItem nss_builtins_items_132 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8165,7 +8592,7 @@ static const NSSItem nss_builtins_items_126 [] = { "\367\115\146\177\247\360\034\001\046\170\262\146\107\160\121\144" , (PRUint32)864 } }; -static const NSSItem nss_builtins_items_127 [] = { +static const NSSItem nss_builtins_items_133 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8196,7 +8623,7 @@ static const NSSItem nss_builtins_items_127 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_128 [] = { +static const NSSItem nss_builtins_items_134 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8288,7 +8715,7 @@ static const NSSItem nss_builtins_items_128 [] = { "\030\122\051\213\107\064\022\011\324\273\222\065\357\017\333\064" , (PRUint32)864 } }; -static const NSSItem nss_builtins_items_129 [] = { +static const NSSItem nss_builtins_items_135 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8319,7 +8746,7 @@ static const NSSItem nss_builtins_items_129 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_130 [] = { +static const NSSItem nss_builtins_items_136 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8390,7 +8817,7 @@ static const NSSItem nss_builtins_items_130 [] = { "\350\140\052\233\205\112\100\363\153\212\044\354\006\026\054\163" , (PRUint32)784 } }; -static const NSSItem nss_builtins_items_131 [] = { +static const NSSItem nss_builtins_items_137 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8413,7 +8840,7 @@ static const NSSItem nss_builtins_items_131 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_132 [] = { +static const NSSItem nss_builtins_items_138 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8511,7 +8938,7 @@ static const NSSItem nss_builtins_items_132 [] = { "\225\351\066\226\230\156" , (PRUint32)1078 } }; -static const NSSItem nss_builtins_items_133 [] = { +static const NSSItem nss_builtins_items_139 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8538,7 +8965,7 @@ static const NSSItem nss_builtins_items_133 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_134 [] = { +static const NSSItem nss_builtins_items_140 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8637,7 +9064,7 @@ static const NSSItem nss_builtins_items_134 [] = { "\354\375\051" , (PRUint32)1091 } }; -static const NSSItem nss_builtins_items_135 [] = { +static const NSSItem nss_builtins_items_141 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8664,7 +9091,7 @@ static const NSSItem nss_builtins_items_135 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_136 [] = { +static const NSSItem nss_builtins_items_142 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8765,7 +9192,7 @@ static const NSSItem nss_builtins_items_136 [] = { "\160\136\310\304\170\260\142" , (PRUint32)1095 } }; -static const NSSItem nss_builtins_items_137 [] = { +static const NSSItem nss_builtins_items_143 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8793,7 +9220,7 @@ static const NSSItem nss_builtins_items_137 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_138 [] = { +static const NSSItem nss_builtins_items_144 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8971,7 +9398,7 @@ static const NSSItem nss_builtins_items_138 [] = { "\001\177\046\304\143\365\045\102\136\142\275" , (PRUint32)2043 } }; -static const NSSItem nss_builtins_items_139 [] = { +static const NSSItem nss_builtins_items_145 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9008,7 +9435,7 @@ static const NSSItem nss_builtins_items_139 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_140 [] = { +static const NSSItem nss_builtins_items_146 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9185,7 +9612,7 @@ static const NSSItem nss_builtins_items_140 [] = { "\206\063\076\346\057\110\156\257\124\220\116\255\261\045" , (PRUint32)2030 } }; -static const NSSItem nss_builtins_items_141 [] = { +static const NSSItem nss_builtins_items_147 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9222,7 +9649,7 @@ static const NSSItem nss_builtins_items_141 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_142 [] = { +static const NSSItem nss_builtins_items_148 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9399,7 +9826,7 @@ static const NSSItem nss_builtins_items_142 [] = { "\257\175\310\352\351\324\126\331\016\023\262\305\105\120" , (PRUint32)2030 } }; -static const NSSItem nss_builtins_items_143 [] = { +static const NSSItem nss_builtins_items_149 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9436,7 +9863,7 @@ static const NSSItem nss_builtins_items_143 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_144 [] = { +static const NSSItem nss_builtins_items_150 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9614,7 +10041,7 @@ static const NSSItem nss_builtins_items_144 [] = { "\336\007\043\162\346\275\040\024\113\264\206" , (PRUint32)2043 } }; -static const NSSItem nss_builtins_items_145 [] = { +static const NSSItem nss_builtins_items_151 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9651,7 +10078,7 @@ static const NSSItem nss_builtins_items_145 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_146 [] = { +static const NSSItem nss_builtins_items_152 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9829,7 +10256,7 @@ static const NSSItem nss_builtins_items_146 [] = { "\311\024\025\014\343\007\203\233\046\165\357" , (PRUint32)2043 } }; -static const NSSItem nss_builtins_items_147 [] = { +static const NSSItem nss_builtins_items_153 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9866,7 +10293,7 @@ static const NSSItem nss_builtins_items_147 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_148 [] = { +static const NSSItem nss_builtins_items_154 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9946,7 +10373,7 @@ static const NSSItem nss_builtins_items_148 [] = { "\134\152\371\162\224\325\001\117\240\333\102" , (PRUint32)699 } }; -static const NSSItem nss_builtins_items_149 [] = { +static const NSSItem nss_builtins_items_155 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9976,7 +10403,7 @@ static const NSSItem nss_builtins_items_149 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_150 [] = { +static const NSSItem nss_builtins_items_156 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10160,7 +10587,7 @@ static const NSSItem nss_builtins_items_150 [] = { "\207\112\137\334\357\351\126\360\012\014\350\165" , (PRUint32)2108 } }; -static const NSSItem nss_builtins_items_151 [] = { +static const NSSItem nss_builtins_items_157 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10198,7 +10625,7 @@ static const NSSItem nss_builtins_items_151 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_152 [] = { +static const NSSItem nss_builtins_items_158 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10324,7 +10751,7 @@ static const NSSItem nss_builtins_items_152 [] = { "\112\164\066\371" , (PRUint32)1492 } }; -static const NSSItem nss_builtins_items_153 [] = { +static const NSSItem nss_builtins_items_159 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10352,7 +10779,7 @@ static const NSSItem nss_builtins_items_153 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_154 [] = { +static const NSSItem nss_builtins_items_160 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10432,7 +10859,7 @@ static const NSSItem nss_builtins_items_154 [] = { "\057\317\246\356\311\160\042\024\275\375\276\154\013\003" , (PRUint32)862 } }; -static const NSSItem nss_builtins_items_155 [] = { +static const NSSItem nss_builtins_items_161 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10457,7 +10884,7 @@ static const NSSItem nss_builtins_items_155 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_156 [] = { +static const NSSItem nss_builtins_items_162 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10530,7 +10957,7 @@ static const NSSItem nss_builtins_items_156 [] = { "\127\275\125\232" , (PRUint32)804 } }; -static const NSSItem nss_builtins_items_157 [] = { +static const NSSItem nss_builtins_items_163 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10553,7 +10980,7 @@ static const NSSItem nss_builtins_items_157 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_158 [] = { +static const NSSItem nss_builtins_items_164 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10626,7 +11053,7 @@ static const NSSItem nss_builtins_items_158 [] = { "\160\254\337\114" , (PRUint32)804 } }; -static const NSSItem nss_builtins_items_159 [] = { +static const NSSItem nss_builtins_items_165 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10649,7 +11076,7 @@ static const NSSItem nss_builtins_items_159 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_160 [] = { +static const NSSItem nss_builtins_items_166 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10735,7 +11162,7 @@ static const NSSItem nss_builtins_items_160 [] = { "\025\301\044\174\062\174\003\035\073\241\130\105\062\223" , (PRUint32)958 } }; -static const NSSItem nss_builtins_items_161 [] = { +static const NSSItem nss_builtins_items_167 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10760,7 +11187,7 @@ static const NSSItem nss_builtins_items_161 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_162 [] = { +static const NSSItem nss_builtins_items_168 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10851,7 +11278,7 @@ static const NSSItem nss_builtins_items_162 [] = { "\151\003\142\270\231\005\005\075\153\170\022\275\260\157\145" , (PRUint32)1071 } }; -static const NSSItem nss_builtins_items_163 [] = { +static const NSSItem nss_builtins_items_169 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10875,7 +11302,7 @@ static const NSSItem nss_builtins_items_163 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_164 [] = { +static const NSSItem nss_builtins_items_170 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10979,7 +11406,7 @@ static const NSSItem nss_builtins_items_164 [] = { "\004\243\103\055\332\374\013\142\352\057\137\142\123" , (PRUint32)1309 } }; -static const NSSItem nss_builtins_items_165 [] = { +static const NSSItem nss_builtins_items_171 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11002,7 +11429,7 @@ static const NSSItem nss_builtins_items_165 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_166 [] = { +static const NSSItem nss_builtins_items_172 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11108,7 +11535,7 @@ static const NSSItem nss_builtins_items_166 [] = { "\364\010" , (PRUint32)1122 } }; -static const NSSItem nss_builtins_items_167 [] = { +static const NSSItem nss_builtins_items_173 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11138,7 +11565,7 @@ static const NSSItem nss_builtins_items_167 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_168 [] = { +static const NSSItem nss_builtins_items_174 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11252,7 +11679,7 @@ static const NSSItem nss_builtins_items_168 [] = { "\005\323\312\003\112\124" , (PRUint32)1190 } }; -static const NSSItem nss_builtins_items_169 [] = { +static const NSSItem nss_builtins_items_175 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11284,7 +11711,7 @@ static const NSSItem nss_builtins_items_169 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_170 [] = { +static const NSSItem nss_builtins_items_176 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11391,7 +11818,7 @@ static const NSSItem nss_builtins_items_170 [] = { "\062\234\036\273\235\370\146\250" , (PRUint32)1144 } }; -static const NSSItem nss_builtins_items_171 [] = { +static const NSSItem nss_builtins_items_177 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11421,7 +11848,7 @@ static const NSSItem nss_builtins_items_171 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_172 [] = { +static const NSSItem nss_builtins_items_178 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11527,7 +11954,7 @@ static const NSSItem nss_builtins_items_172 [] = { "\275\023\122\035\250\076\315\000\037\310" , (PRUint32)1130 } }; -static const NSSItem nss_builtins_items_173 [] = { +static const NSSItem nss_builtins_items_179 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11557,7 +11984,7 @@ static const NSSItem nss_builtins_items_173 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_174 [] = { +static const NSSItem nss_builtins_items_180 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11666,7 +12093,7 @@ static const NSSItem nss_builtins_items_174 [] = { "\334" , (PRUint32)1217 } }; -static const NSSItem nss_builtins_items_175 [] = { +static const NSSItem nss_builtins_items_181 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11694,7 +12121,7 @@ static const NSSItem nss_builtins_items_175 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_176 [] = { +static const NSSItem nss_builtins_items_182 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11801,7 +12228,7 @@ static const NSSItem nss_builtins_items_176 [] = { "\166\135\165\220\032\365\046\217\360" , (PRUint32)1225 } }; -static const NSSItem nss_builtins_items_177 [] = { +static const NSSItem nss_builtins_items_183 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11828,7 +12255,189 @@ static const NSSItem nss_builtins_items_177 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_178 [] = { +static const NSSItem nss_builtins_items_184 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"NetLock Qualified (Class QA) Root", (PRUint32)34 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125" +"\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160" +"\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145" +"\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172" +"\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030" +"\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004" +"\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163" +"\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151" +"\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165" +"\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034" +"\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146" +"\157\100\156\145\164\154\157\143\153\056\150\165" +, (PRUint32)204 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125" +"\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160" +"\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145" +"\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172" +"\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030" +"\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004" +"\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163" +"\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151" +"\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165" +"\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034" +"\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146" +"\157\100\156\145\164\154\157\143\153\056\150\165" +, (PRUint32)204 }, + { (void *)"\002\001\173" +, (PRUint32)3 }, + { (void *)"\060\202\006\321\060\202\005\271\240\003\002\001\002\002\001\173" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125\061" +"\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145" +"\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145\164" +"\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172\164" +"\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030\006" +"\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141\156" +"\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004\003" +"\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163\151" +"\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151\040" +"\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165\163" +"\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034\006" +"\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146\157" +"\100\156\145\164\154\157\143\153\056\150\165\060\036\027\015\060" +"\063\060\063\063\060\060\061\064\067\061\061\132\027\015\062\062" +"\061\062\061\065\060\061\064\067\061\061\132\060\201\311\061\013" +"\060\011\006\003\125\004\006\023\002\110\125\061\021\060\017\006" +"\003\125\004\007\023\010\102\165\144\141\160\145\163\164\061\047" +"\060\045\006\003\125\004\012\023\036\116\145\164\114\157\143\153" +"\040\110\141\154\157\172\141\164\142\151\172\164\157\156\163\141" +"\147\151\040\113\146\164\056\061\032\060\030\006\003\125\004\013" +"\023\021\124\141\156\165\163\151\164\166\141\156\171\153\151\141" +"\144\157\153\061\102\060\100\006\003\125\004\003\023\071\116\145" +"\164\114\157\143\153\040\115\151\156\157\163\151\164\145\164\164" +"\040\113\157\172\152\145\147\171\172\157\151\040\050\103\154\141" +"\163\163\040\121\101\051\040\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\061\036\060\034\006\011\052\206\110" +"\206\367\015\001\011\001\026\017\151\156\146\157\100\156\145\164" +"\154\157\143\153\056\150\165\060\202\001\042\060\015\006\011\052" +"\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060" +"\202\001\012\002\202\001\001\000\307\122\045\262\330\075\324\204" +"\125\011\247\033\275\154\271\024\364\212\002\333\166\374\152\052" +"\170\253\345\167\360\156\340\214\043\147\333\245\144\231\271\335" +"\001\076\157\357\055\232\074\042\360\135\311\127\240\125\101\177" +"\362\103\136\130\202\123\061\145\316\036\362\046\272\000\124\036" +"\257\260\274\034\344\122\214\240\062\257\267\067\261\123\147\150" +"\164\147\120\366\055\056\144\336\256\046\171\337\337\231\206\253" +"\253\177\205\354\240\373\200\314\364\270\014\036\223\105\143\271" +"\334\270\133\233\355\133\071\324\137\142\260\247\216\174\146\070" +"\054\252\261\010\143\027\147\175\314\275\263\361\303\077\317\120" +"\071\355\321\031\203\025\333\207\022\047\226\267\332\352\345\235" +"\274\272\352\071\117\213\357\164\232\347\305\320\322\352\206\121" +"\034\344\376\144\010\050\004\171\005\353\312\305\161\016\013\357" +"\253\352\354\022\021\241\030\005\062\151\321\014\054\032\075\045" +"\231\077\265\174\312\155\260\256\231\231\372\010\140\347\031\302" +"\362\275\121\323\314\323\002\254\301\021\014\200\316\253\334\224" +"\235\153\243\071\123\072\326\205\002\003\000\305\175\243\202\002" +"\300\060\202\002\274\060\022\006\003\125\035\023\001\001\377\004" +"\010\060\006\001\001\377\002\001\004\060\016\006\003\125\035\017" +"\001\001\377\004\004\003\002\001\006\060\202\002\165\006\011\140" +"\206\110\001\206\370\102\001\015\004\202\002\146\026\202\002\142" +"\106\111\107\131\105\114\105\115\041\040\105\172\145\156\040\164" +"\141\156\165\163\151\164\166\141\156\171\040\141\040\116\145\164" +"\114\157\143\153\040\113\146\164\056\040\115\151\156\157\163\151" +"\164\145\164\164\040\123\172\157\154\147\141\154\164\141\164\141" +"\163\151\040\123\172\141\142\141\154\171\172\141\164\141\142\141" +"\156\040\154\145\151\162\164\040\145\154\152\141\162\141\163\157" +"\153\040\141\154\141\160\152\141\156\040\153\145\163\172\165\154" +"\164\056\040\101\040\155\151\156\157\163\151\164\145\164\164\040" +"\145\154\145\153\164\162\157\156\151\153\165\163\040\141\154\141" +"\151\162\141\163\040\152\157\147\150\141\164\141\163\040\145\162" +"\166\145\156\171\145\163\165\154\145\163\145\156\145\153\054\040" +"\166\141\154\141\155\151\156\164\040\145\154\146\157\147\141\144" +"\141\163\141\156\141\153\040\146\145\154\164\145\164\145\154\145" +"\040\141\040\115\151\156\157\163\151\164\145\164\164\040\123\172" +"\157\154\147\141\154\164\141\164\141\163\151\040\123\172\141\142" +"\141\154\171\172\141\164\142\141\156\054\040\141\172\040\101\154" +"\164\141\154\141\156\157\163\040\123\172\145\162\172\157\144\145" +"\163\151\040\106\145\154\164\145\164\145\154\145\153\142\145\156" +"\040\145\154\157\151\162\164\040\145\154\154\145\156\157\162\172" +"\145\163\151\040\145\154\152\141\162\141\163\040\155\145\147\164" +"\145\164\145\154\145\056\040\101\040\144\157\153\165\155\145\156" +"\164\165\155\157\153\040\155\145\147\164\141\154\141\154\150\141" +"\164\157\153\040\141\040\150\164\164\160\163\072\057\057\167\167" +"\167\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143" +"\163\057\040\143\151\155\145\156\040\166\141\147\171\040\153\145" +"\162\150\145\164\157\153\040\141\172\040\151\156\146\157\100\156" +"\145\164\154\157\143\153\056\156\145\164\040\145\055\155\141\151" +"\154\040\143\151\155\145\156\056\040\127\101\122\116\111\116\107" +"\041\040\124\150\145\040\151\163\163\165\141\156\143\145\040\141" +"\156\144\040\164\150\145\040\165\163\145\040\157\146\040\164\150" +"\151\163\040\143\145\162\164\151\146\151\143\141\164\145\040\141" +"\162\145\040\163\165\142\152\145\143\164\040\164\157\040\164\150" +"\145\040\116\145\164\114\157\143\153\040\121\165\141\154\151\146" +"\151\145\144\040\103\120\123\040\141\166\141\151\154\141\142\154" +"\145\040\141\164\040\150\164\164\160\163\072\057\057\167\167\167" +"\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143\163" +"\057\040\157\162\040\142\171\040\145\055\155\141\151\154\040\141" +"\164\040\151\156\146\157\100\156\145\164\154\157\143\153\056\156" +"\145\164\060\035\006\003\125\035\016\004\026\004\024\011\152\142" +"\026\222\260\132\273\125\016\313\165\062\072\062\345\262\041\311" +"\050\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000" +"\003\202\001\001\000\221\152\120\234\333\170\201\233\077\213\102" +"\343\073\374\246\303\356\103\340\317\363\342\200\065\111\105\166" +"\002\342\343\057\005\305\361\052\347\300\101\063\306\266\233\320" +"\063\071\315\300\333\241\255\154\067\002\114\130\101\073\362\227" +"\222\306\110\250\315\345\212\071\211\141\371\122\227\351\275\366" +"\371\224\164\350\161\016\274\167\206\303\006\314\132\174\112\176" +"\064\120\060\056\373\177\062\232\215\075\363\040\133\370\152\312" +"\206\363\061\114\054\131\200\002\175\376\070\311\060\165\034\267" +"\125\343\274\237\272\250\155\204\050\005\165\263\213\015\300\221" +"\124\041\347\246\013\264\231\365\121\101\334\315\243\107\042\331" +"\307\001\201\304\334\107\117\046\352\037\355\333\315\015\230\364" +"\243\234\264\163\062\112\226\231\376\274\177\310\045\130\370\130" +"\363\166\146\211\124\244\246\076\304\120\134\272\211\030\202\165" +"\110\041\322\117\023\350\140\176\007\166\333\020\265\121\346\252" +"\271\150\252\315\366\235\220\165\022\352\070\032\312\104\350\267" +"\231\247\052\150\225\146\225\253\255\357\211\313\140\251\006\022" +"\306\224\107\351\050" +, (PRUint32)1749 } +}; +static const NSSItem nss_builtins_items_185 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"NetLock Qualified (Class QA) Root", (PRUint32)34 }, + { (void *)"\001\150\227\341\240\270\362\303\261\064\146\134\040\247\047\267" +"\241\130\342\217" +, (PRUint32)20 }, + { (void *)"\324\200\145\150\044\371\211\042\050\333\365\244\232\027\217\024" +, (PRUint32)16 }, + { (void *)"\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125" +"\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160" +"\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145" +"\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172" +"\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030" +"\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004" +"\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163" +"\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151" +"\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165" +"\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034" +"\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146" +"\157\100\156\145\164\154\157\143\153\056\150\165" +, (PRUint32)204 }, + { (void *)"\002\001\173" +, (PRUint32)3 }, + { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_186 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11971,7 +12580,7 @@ static const NSSItem nss_builtins_items_178 [] = { "\210" , (PRUint32)1665 } }; -static const NSSItem nss_builtins_items_179 [] = { +static const NSSItem nss_builtins_items_187 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12002,7 +12611,7 @@ static const NSSItem nss_builtins_items_179 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_180 [] = { +static const NSSItem nss_builtins_items_188 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12121,7 +12730,7 @@ static const NSSItem nss_builtins_items_180 [] = { "\066\053\143\254\130\001\153\063\051\120\206\203\361\001\110" , (PRUint32)1359 } }; -static const NSSItem nss_builtins_items_181 [] = { +static const NSSItem nss_builtins_items_189 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12150,7 +12759,7 @@ static const NSSItem nss_builtins_items_181 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_182 [] = { +static const NSSItem nss_builtins_items_190 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12270,7 +12879,7 @@ static const NSSItem nss_builtins_items_182 [] = { "\063\004\324" , (PRUint32)1363 } }; -static const NSSItem nss_builtins_items_183 [] = { +static const NSSItem nss_builtins_items_191 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12299,7 +12908,7 @@ static const NSSItem nss_builtins_items_183 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_184 [] = { +static const NSSItem nss_builtins_items_192 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12400,7 +13009,7 @@ static const NSSItem nss_builtins_items_184 [] = { "\264\003\045\274" , (PRUint32)1076 } }; -static const NSSItem nss_builtins_items_185 [] = { +static const NSSItem nss_builtins_items_193 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12429,7 +13038,7 @@ static const NSSItem nss_builtins_items_185 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_186 [] = { +static const NSSItem nss_builtins_items_194 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12522,7 +13131,7 @@ static const NSSItem nss_builtins_items_186 [] = { "\177\333\275\237" , (PRUint32)1028 } }; -static const NSSItem nss_builtins_items_187 [] = { +static const NSSItem nss_builtins_items_195 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12548,7 +13157,7 @@ static const NSSItem nss_builtins_items_187 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_188 [] = { +static const NSSItem nss_builtins_items_196 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12642,7 +13251,7 @@ static const NSSItem nss_builtins_items_188 [] = { "\037\027\224" , (PRUint32)1043 } }; -static const NSSItem nss_builtins_items_189 [] = { +static const NSSItem nss_builtins_items_197 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12668,6 +13277,701 @@ static const NSSItem nss_builtins_items_189 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; +static const NSSItem nss_builtins_items_198 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"StartCom Ltd.", (PRUint32)14 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114" +"\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145" +"\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141" +"\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162" +"\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125" +"\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171" +"\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040" +"\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026" +"\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056" +"\157\162\147" +, (PRUint32)179 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114" +"\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145" +"\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141" +"\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162" +"\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125" +"\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171" +"\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040" +"\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026" +"\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056" +"\157\162\147" +, (PRUint32)179 }, + { (void *)"\002\001\000" +, (PRUint32)3 }, + { (void *)"\060\202\005\026\060\202\004\177\240\003\002\001\002\002\001\000" +"\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060" +"\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114\061" +"\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145\154" +"\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141\164" +"\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164" +"\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125\004" +"\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171\040" +"\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040\106" +"\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143" +"\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\061" +"\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026\022" +"\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056\157" +"\162\147\060\036\027\015\060\065\060\063\061\067\061\067\063\067" +"\064\070\132\027\015\063\065\060\063\061\060\061\067\063\067\064" +"\070\132\060\201\260\061\013\060\011\006\003\125\004\006\023\002" +"\111\114\061\017\060\015\006\003\125\004\010\023\006\111\163\162" +"\141\145\154\061\016\060\014\006\003\125\004\007\023\005\105\151" +"\154\141\164\061\026\060\024\006\003\125\004\012\023\015\123\164" +"\141\162\164\103\157\155\040\114\164\144\056\061\032\060\030\006" +"\003\125\004\013\023\021\103\101\040\101\165\164\150\157\162\151" +"\164\171\040\104\145\160\056\061\051\060\047\006\003\125\004\003" +"\023\040\106\162\145\145\040\123\123\114\040\103\145\162\164\151" +"\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151" +"\164\171\061\041\060\037\006\011\052\206\110\206\367\015\001\011" +"\001\026\022\141\144\155\151\156\100\163\164\141\162\164\143\157" +"\155\056\157\162\147\060\201\237\060\015\006\011\052\206\110\206" +"\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002\201" +"\201\000\355\204\140\000\043\236\310\112\121\051\047\336\072\241" +"\071\265\151\253\011\262\057\064\375\141\334\075\323\260\317\261" +"\327\302\304\302\261\344\226\126\304\276\252\024\016\347\314\072" +"\120\310\072\142\235\303\243\254\131\173\216\356\125\032\034\107" +"\276\243\227\071\263\265\357\043\054\010\350\330\257\163\057\271" +"\311\203\350\355\000\017\310\165\245\057\064\114\030\350\166\210" +"\043\111\212\333\266\355\150\332\303\265\142\051\114\245\113\267" +"\230\264\011\024\020\240\370\376\142\166\042\025\013\244\326\010" +"\057\065\002\003\001\000\001\243\202\002\074\060\202\002\070\060" +"\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377" +"\060\013\006\003\125\035\017\004\004\003\002\001\346\060\035\006" +"\003\125\035\016\004\026\004\024\034\211\303\226\314\275\376\062" +"\325\015\214\201\061\266\230\235\215\050\144\215\060\201\335\006" +"\003\125\035\043\004\201\325\060\201\322\200\024\034\211\303\226" +"\314\275\376\062\325\015\214\201\061\266\230\235\215\050\144\215" +"\241\201\266\244\201\263\060\201\260\061\013\060\011\006\003\125" +"\004\006\023\002\111\114\061\017\060\015\006\003\125\004\010\023" +"\006\111\163\162\141\145\154\061\016\060\014\006\003\125\004\007" +"\023\005\105\151\154\141\164\061\026\060\024\006\003\125\004\012" +"\023\015\123\164\141\162\164\103\157\155\040\114\164\144\056\061" +"\032\060\030\006\003\125\004\013\023\021\103\101\040\101\165\164" +"\150\157\162\151\164\171\040\104\145\160\056\061\051\060\047\006" +"\003\125\004\003\023\040\106\162\145\145\040\123\123\114\040\103" +"\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164" +"\150\157\162\151\164\171\061\041\060\037\006\011\052\206\110\206" +"\367\015\001\011\001\026\022\141\144\155\151\156\100\163\164\141" +"\162\164\143\157\155\056\157\162\147\202\001\000\060\035\006\003" +"\125\035\021\004\026\060\024\201\022\141\144\155\151\156\100\163" +"\164\141\162\164\143\157\155\056\157\162\147\060\035\006\003\125" +"\035\022\004\026\060\024\201\022\141\144\155\151\156\100\163\164" +"\141\162\164\143\157\155\056\157\162\147\060\021\006\011\140\206" +"\110\001\206\370\102\001\001\004\004\003\002\000\007\060\057\006" +"\011\140\206\110\001\206\370\102\001\015\004\042\026\040\106\162" +"\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143\141" +"\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\062" +"\006\011\140\206\110\001\206\370\102\001\004\004\045\026\043\150" +"\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162\164" +"\143\157\155\056\157\162\147\057\143\141\055\143\162\154\056\143" +"\162\154\060\050\006\011\140\206\110\001\206\370\102\001\002\004" +"\033\026\031\150\164\164\160\072\057\057\143\145\162\164\056\163" +"\164\141\162\164\143\157\155\056\157\162\147\057\060\071\006\011" +"\140\206\110\001\206\370\102\001\010\004\054\026\052\150\164\164" +"\160\072\057\057\143\145\162\164\056\163\164\141\162\164\143\157" +"\155\056\157\162\147\057\151\156\144\145\170\056\160\150\160\077" +"\141\160\160\075\061\061\061\060\015\006\011\052\206\110\206\367" +"\015\001\001\004\005\000\003\201\201\000\154\161\045\341\236\064" +"\221\041\357\333\154\275\001\010\126\217\210\330\101\072\123\365" +"\162\337\047\127\113\166\204\367\150\244\376\353\077\011\176\050" +"\270\127\352\037\301\252\342\377\226\237\111\231\346\262\225\163" +"\226\306\110\307\136\215\007\162\126\370\203\217\237\167\257\051" +"\323\105\016\244\356\260\066\164\055\360\315\230\043\173\067\113" +"\332\376\121\230\304\036\064\074\210\375\231\073\120\247\301\213" +"\063\307\302\122\026\022\225\123\145\042\357\272\213\316\142\333" +"\160\043\261\200\337\032\040\070\347\176" +, (PRUint32)1306 } +}; +static const NSSItem nss_builtins_items_199 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"StartCom Ltd.", (PRUint32)14 }, + { (void *)"\225\346\255\370\327\161\106\002\115\325\152\041\262\347\077\315" +"\362\073\065\377" +, (PRUint32)20 }, + { (void *)"\010\174\130\037\122\053\104\264\073\171\315\001\370\305\303\311" +, (PRUint32)16 }, + { (void *)"\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114" +"\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145" +"\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141" +"\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162" +"\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125" +"\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171" +"\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040" +"\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026" +"\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056" +"\157\162\147" +, (PRUint32)179 }, + { (void *)"\002\001\000" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_200 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Taiwan GRCA", (PRUint32)12 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061" +"\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156" +"\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146" +"\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164" +"\171" +, (PRUint32)65 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061" +"\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156" +"\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146" +"\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164" +"\171" +, (PRUint32)65 }, + { (void *)"\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343" +"\136\366" +, (PRUint32)18 }, + { (void *)"\060\202\005\162\060\202\003\132\240\003\002\001\002\002\020\037" +"\235\131\132\327\057\302\006\104\245\200\010\151\343\136\366\060" +"\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\077" +"\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060\060" +"\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155\145" +"\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143" +"\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060" +"\036\027\015\060\062\061\062\060\065\061\063\062\063\063\063\132" +"\027\015\063\062\061\062\060\065\061\063\062\063\063\063\132\060" +"\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060" +"\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155" +"\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001" +"\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001" +"\000\232\045\270\354\314\242\165\250\173\367\316\133\131\212\311" +"\321\206\022\010\124\354\234\362\347\106\366\210\363\174\351\245" +"\337\114\107\066\244\033\001\034\177\036\127\212\215\303\305\321" +"\041\343\332\044\077\110\053\373\237\056\241\224\347\054\034\223" +"\321\277\033\001\207\123\231\316\247\365\012\041\166\167\377\251" +"\267\306\163\224\117\106\367\020\111\067\372\250\131\111\135\152" +"\201\007\126\362\212\371\006\320\367\160\042\115\264\267\101\271" +"\062\270\261\360\261\303\234\077\160\375\123\335\201\252\330\143" +"\170\366\330\123\156\241\254\152\204\044\162\124\206\306\322\262" +"\312\034\016\171\201\326\265\160\142\010\001\056\116\117\016\325" +"\021\257\251\257\345\232\277\334\314\207\155\046\344\311\127\242" +"\373\226\371\314\341\077\123\214\154\114\176\233\123\010\013\154" +"\027\373\147\310\302\255\261\315\200\264\227\334\166\001\026\025" +"\351\152\327\244\341\170\107\316\206\325\373\061\363\372\061\276" +"\064\252\050\373\160\114\035\111\307\257\054\235\155\146\246\266" +"\215\144\176\265\040\152\235\073\201\266\217\100\000\147\113\211" +"\206\270\314\145\376\025\123\351\004\301\326\137\035\104\327\012" +"\057\047\232\106\175\241\015\165\255\124\206\025\334\111\073\361" +"\226\316\017\233\240\354\243\172\135\276\325\052\165\102\345\173" +"\336\245\266\252\257\050\254\254\220\254\070\267\325\150\065\046" +"\172\334\367\073\363\375\105\233\321\273\103\170\156\157\361\102" +"\124\152\230\360\015\255\227\351\122\136\351\325\152\162\336\152" +"\367\033\140\024\364\245\344\266\161\147\252\037\352\342\115\301" +"\102\100\376\147\106\027\070\057\107\077\161\234\256\345\041\312" +"\141\055\155\007\250\204\174\055\356\121\045\361\143\220\236\375" +"\341\127\210\153\357\212\043\155\261\346\275\077\255\321\075\226" +"\013\205\215\315\153\047\273\267\005\233\354\273\221\251\012\007" +"\022\002\227\116\040\220\360\377\015\036\342\101\073\323\100\072" +"\347\215\135\332\146\344\002\260\007\122\230\134\016\216\063\234" +"\302\246\225\373\125\031\156\114\216\256\113\017\275\301\070\115" +"\136\217\204\035\146\315\305\140\226\264\122\132\005\211\216\225" +"\172\230\301\221\074\225\043\262\016\364\171\264\311\174\301\112" +"\041\002\003\001\000\001\243\152\060\150\060\035\006\003\125\035" +"\016\004\026\004\024\314\314\357\314\051\140\244\073\261\222\266" +"\074\372\062\142\217\254\045\025\073\060\014\006\003\125\035\023" +"\004\005\060\003\001\001\377\060\071\006\004\147\052\007\000\004" +"\061\060\057\060\055\002\001\000\060\011\006\005\053\016\003\002" +"\032\005\000\060\007\006\005\147\052\003\000\000\004\024\003\233" +"\360\042\023\377\225\050\066\323\334\236\300\062\373\061\072\212" +"\121\145\060\015\006\011\052\206\110\206\367\015\001\001\005\005" +"\000\003\202\002\001\000\100\200\112\372\046\311\316\136\060\335" +"\117\206\164\166\130\365\256\263\203\063\170\244\172\164\027\031" +"\116\351\122\265\271\340\012\164\142\252\150\312\170\240\114\232" +"\216\054\043\056\325\152\022\044\277\324\150\323\212\320\330\234" +"\237\264\037\014\336\070\176\127\070\374\215\342\117\136\014\237" +"\253\073\322\377\165\227\313\244\343\147\010\377\345\300\026\265" +"\110\001\175\351\371\012\377\033\345\152\151\277\170\041\250\302" +"\247\043\251\206\253\166\126\350\016\014\366\023\335\052\146\212" +"\144\111\075\032\030\207\220\004\237\102\122\267\117\313\376\107" +"\101\166\065\357\377\000\166\066\105\062\233\306\106\205\135\342" +"\044\260\036\343\110\226\230\127\107\224\125\172\017\101\261\104" +"\044\363\301\376\032\153\277\210\375\301\246\332\223\140\136\201" +"\112\231\040\234\110\146\031\265\000\171\124\017\270\054\057\113" +"\274\251\135\133\140\177\214\207\245\340\122\143\052\276\330\073" +"\205\100\025\376\036\266\145\077\305\113\332\176\265\172\065\051" +"\243\056\172\230\140\042\243\364\175\047\116\055\352\264\164\074" +"\351\017\244\063\017\020\021\274\023\001\326\345\016\323\277\265" +"\022\242\341\105\043\300\314\010\156\141\267\211\253\203\343\044" +"\036\346\135\007\347\037\040\076\317\147\310\347\254\060\155\047" +"\113\150\156\113\052\134\002\010\064\333\370\166\344\147\243\046" +"\234\077\242\062\302\112\305\201\030\061\020\126\252\204\357\055" +"\012\377\270\037\167\322\277\245\130\240\142\344\327\113\221\165" +"\215\211\200\230\176\155\313\123\116\136\257\366\262\227\205\227" +"\271\332\125\006\271\044\356\327\306\070\036\143\033\022\073\225" +"\341\130\254\362\337\204\325\137\231\057\015\125\133\346\070\333" +"\056\077\162\351\110\205\313\273\051\023\217\036\070\125\271\363" +"\262\304\060\231\043\116\135\362\110\241\022\014\334\022\220\011" +"\220\124\221\003\074\107\345\325\311\145\340\267\113\175\354\107" +"\323\263\013\076\255\236\320\164\000\016\353\275\121\255\300\336" +"\054\300\303\152\376\357\334\013\247\372\106\337\140\333\234\246" +"\131\120\165\043\151\163\223\262\371\374\002\323\107\346\161\316" +"\020\002\356\047\214\204\377\254\105\015\023\134\203\062\340\045" +"\245\206\054\174\364\022" +, (PRUint32)1398 } +}; +static const NSSItem nss_builtins_items_201 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Taiwan GRCA", (PRUint32)12 }, + { (void *)"\364\213\021\277\336\253\276\224\124\040\161\346\101\336\153\276" +"\210\053\100\271" +, (PRUint32)20 }, + { (void *)"\067\205\104\123\062\105\037\040\360\363\225\341\045\304\103\116" +, (PRUint32)16 }, + { (void *)"\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061" +"\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156" +"\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146" +"\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164" +"\171" +, (PRUint32)65 }, + { (void *)"\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343" +"\136\366" +, (PRUint32)18 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_202 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Firmaprofesional Root CA", (PRUint32)25 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123" +"\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165" +"\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145" +"\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101" +"\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164" +"\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160" +"\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101" +"\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206" +"\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155" +"\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155" +, (PRUint32)160 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123" +"\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165" +"\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145" +"\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101" +"\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164" +"\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160" +"\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101" +"\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206" +"\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155" +"\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155" +, (PRUint32)160 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\004\127\060\202\003\077\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061" +"\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156" +"\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154" +"\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165" +"\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151" +"\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162" +"\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066" +"\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110" +"\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141" +"\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060" +"\036\027\015\060\061\061\060\062\064\062\062\060\060\060\060\132" +"\027\015\061\063\061\060\062\064\062\062\060\060\060\060\132\060" +"\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061" +"\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156" +"\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154" +"\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165" +"\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151" +"\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162" +"\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066" +"\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110" +"\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141" +"\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060" +"\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001" +"\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000" +"\347\043\003\157\157\043\245\136\170\316\225\054\355\224\036\156" +"\012\236\001\307\352\060\321\054\235\335\067\350\233\230\171\126" +"\323\374\163\337\320\212\336\125\217\121\371\132\352\336\265\160" +"\304\355\244\355\377\243\015\156\017\144\120\061\257\001\047\130" +"\256\376\154\247\112\057\027\055\323\163\325\023\034\217\131\245" +"\064\054\035\124\004\105\315\150\270\240\300\003\245\317\205\102" +"\107\225\050\133\317\357\200\154\340\220\227\212\001\074\035\363" +"\207\020\060\046\110\175\327\374\351\235\221\161\377\101\232\251" +"\100\265\067\234\051\040\117\037\122\343\240\175\023\155\124\267" +"\012\336\351\152\116\007\254\254\031\137\334\176\142\164\366\262" +"\005\000\272\205\240\375\035\070\156\313\132\273\206\274\224\147" +"\063\065\203\054\037\043\315\370\310\221\161\314\227\213\357\256" +"\017\334\051\003\033\300\071\353\160\355\301\156\016\330\147\013" +"\211\251\274\065\344\357\266\064\264\245\266\304\055\245\276\320" +"\303\224\044\110\333\337\226\323\000\265\146\032\213\146\005\017" +"\335\077\077\313\077\252\136\232\112\370\264\112\357\225\067\033" +"\002\003\001\000\001\243\201\237\060\201\234\060\052\006\003\125" +"\035\021\004\043\060\041\206\037\150\164\164\160\072\057\057\167" +"\167\167\056\146\151\162\155\141\160\162\157\146\145\163\151\157" +"\156\141\154\056\143\157\155\060\022\006\003\125\035\023\001\001" +"\377\004\010\060\006\001\001\377\002\001\001\060\053\006\003\125" +"\035\020\004\044\060\042\200\017\062\060\060\061\061\060\062\064" +"\062\062\060\060\060\060\132\201\017\062\060\061\063\061\060\062" +"\064\062\062\060\060\060\060\132\060\016\006\003\125\035\017\001" +"\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016\004" +"\026\004\024\063\013\240\146\321\352\332\316\336\142\223\004\050" +"\122\265\024\177\070\150\267\060\015\006\011\052\206\110\206\367" +"\015\001\001\005\005\000\003\202\001\001\000\107\163\376\215\047" +"\124\360\365\324\167\234\047\171\127\127\267\025\126\354\307\330" +"\130\267\001\002\364\063\355\223\120\210\236\174\106\261\275\077" +"\024\157\361\263\107\110\213\214\227\006\327\352\176\243\134\052" +"\273\115\057\107\342\370\071\006\311\234\056\061\032\003\170\364" +"\274\070\306\042\213\063\061\360\026\004\004\175\371\166\344\113" +"\327\300\346\203\354\131\314\077\336\377\117\153\267\147\176\246" +"\206\201\062\043\003\235\310\367\137\301\112\140\245\222\251\261" +"\244\240\140\303\170\207\263\042\363\052\353\133\251\355\005\253" +"\067\017\261\342\323\225\166\143\126\164\214\130\162\033\067\345" +"\144\241\276\115\014\223\230\014\227\366\207\155\263\077\347\313" +"\200\246\355\210\307\137\120\142\002\350\231\164\026\320\346\264" +"\071\361\047\313\310\100\326\343\206\020\251\043\022\222\340\151" +"\101\143\247\257\045\013\300\305\222\313\036\230\243\132\272\305" +"\063\017\240\227\001\335\177\340\173\326\006\124\317\241\342\115" +"\070\353\113\120\265\313\046\364\312\332\160\112\152\241\342\171" +"\252\341\247\063\366\375\112\037\366\331\140" +, (PRUint32)1115 } +}; +static const NSSItem nss_builtins_items_203 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Firmaprofesional Root CA", (PRUint32)25 }, + { (void *)"\251\142\217\113\230\251\033\110\065\272\322\301\106\062\206\273" +"\146\144\152\214" +, (PRUint32)20 }, + { (void *)"\021\222\171\100\074\261\203\100\345\253\146\112\147\222\200\337" +, (PRUint32)16 }, + { (void *)"\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123" +"\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165" +"\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145" +"\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101" +"\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164" +"\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160" +"\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101" +"\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206" +"\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155" +"\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155" +, (PRUint32)160 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_204 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Wells Fargo Root CA", (PRUint32)20 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123" +"\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163" +"\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023" +"\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162" +"\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157" +"\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127" +"\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040" +"\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150" +"\157\162\151\164\171" +, (PRUint32)133 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123" +"\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163" +"\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023" +"\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162" +"\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157" +"\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127" +"\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040" +"\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150" +"\157\162\151\164\171" +, (PRUint32)133 }, + { (void *)"\002\004\071\344\227\236" +, (PRUint32)6 }, + { (void *)"\060\202\003\345\060\202\002\315\240\003\002\001\002\002\004\071" +"\344\227\236\060\015\006\011\052\206\110\206\367\015\001\001\005" +"\005\000\060\201\202\061\013\060\011\006\003\125\004\006\023\002" +"\125\123\061\024\060\022\006\003\125\004\012\023\013\127\145\154" +"\154\163\040\106\141\162\147\157\061\054\060\052\006\003\125\004" +"\013\023\043\127\145\154\154\163\040\106\141\162\147\157\040\103" +"\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164" +"\150\157\162\151\164\171\061\057\060\055\006\003\125\004\003\023" +"\046\127\145\154\154\163\040\106\141\162\147\157\040\122\157\157" +"\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165" +"\164\150\157\162\151\164\171\060\036\027\015\060\060\061\060\061" +"\061\061\066\064\061\062\070\132\027\015\062\061\060\061\061\064" +"\061\066\064\061\062\070\132\060\201\202\061\013\060\011\006\003" +"\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004\012" +"\023\013\127\145\154\154\163\040\106\141\162\147\157\061\054\060" +"\052\006\003\125\004\013\023\043\127\145\154\154\163\040\106\141" +"\162\147\157\040\103\145\162\164\151\146\151\143\141\164\151\157" +"\156\040\101\165\164\150\157\162\151\164\171\061\057\060\055\006" +"\003\125\004\003\023\046\127\145\154\154\163\040\106\141\162\147" +"\157\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141" +"\164\145\040\101\165\164\150\157\162\151\164\171\060\202\001\042" +"\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003" +"\202\001\017\000\060\202\001\012\002\202\001\001\000\325\250\063" +"\073\046\371\064\377\315\233\176\345\004\107\316\000\342\175\167" +"\347\061\302\056\047\245\115\150\271\061\272\215\103\131\227\307" +"\163\252\177\075\134\100\236\005\345\241\342\211\331\114\270\077" +"\233\371\014\264\310\142\031\054\105\256\221\036\163\161\101\304" +"\113\023\375\160\302\045\254\042\365\165\013\267\123\344\245\053" +"\335\316\275\034\072\172\303\367\023\217\046\124\234\026\153\153" +"\257\373\330\226\261\140\232\110\340\045\042\044\171\064\316\016" +"\046\000\013\116\253\375\213\316\202\327\057\010\160\150\301\250" +"\012\371\164\117\007\253\244\371\342\203\176\047\163\164\076\270" +"\371\070\102\374\245\250\133\110\043\263\353\343\045\262\200\256" +"\226\324\012\234\302\170\232\306\150\030\256\067\142\067\136\121" +"\165\250\130\143\300\121\356\100\170\176\250\257\032\240\341\260" +"\170\235\120\214\173\347\263\374\216\043\260\333\145\000\160\204" +"\001\010\000\024\156\124\206\232\272\314\371\067\020\366\340\336" +"\204\055\235\244\205\067\323\207\343\025\320\301\027\220\176\031" +"\041\152\022\251\166\375\022\002\351\117\041\136\027\002\003\001" +"\000\001\243\141\060\137\060\017\006\003\125\035\023\001\001\377" +"\004\005\060\003\001\001\377\060\114\006\003\125\035\040\004\105" +"\060\103\060\101\006\013\140\206\110\001\206\373\173\207\007\001" +"\013\060\062\060\060\006\010\053\006\001\005\005\007\002\001\026" +"\044\150\164\164\160\072\057\057\167\167\167\056\167\145\154\154" +"\163\146\141\162\147\157\056\143\157\155\057\143\145\162\164\160" +"\157\154\151\143\171\060\015\006\011\052\206\110\206\367\015\001" +"\001\005\005\000\003\202\001\001\000\322\047\335\234\012\167\053" +"\273\042\362\002\265\112\112\221\371\321\055\276\344\273\032\150" +"\357\016\244\000\351\356\347\357\356\366\371\345\164\244\302\330" +"\122\130\304\164\373\316\153\265\073\051\171\030\132\357\233\355" +"\037\153\066\356\110\045\045\024\266\126\242\020\350\356\247\177" +"\320\077\243\320\303\135\046\356\007\314\303\301\044\041\207\036" +"\337\052\022\123\157\101\026\347\355\256\224\372\214\162\372\023" +"\107\360\074\176\256\175\021\072\023\354\355\372\157\162\144\173" +"\235\175\177\046\375\172\373\045\255\352\076\051\177\114\343\000" +"\127\062\260\263\351\355\123\027\331\213\262\024\016\060\350\345" +"\325\023\306\144\257\304\000\325\330\130\044\374\365\217\354\361" +"\307\175\245\333\017\047\321\306\362\100\210\346\037\366\141\250" +"\364\102\310\271\067\323\251\276\054\126\170\302\162\233\131\135" +"\065\100\212\350\116\143\032\266\351\040\152\121\342\316\244\220" +"\337\166\160\231\134\160\103\115\267\266\247\031\144\116\222\267" +"\305\221\074\177\110\026\145\173\026\375\313\374\373\331\325\326" +"\117\041\145\073\112\177\107\243\373" +, (PRUint32)1001 } +}; +static const NSSItem nss_builtins_items_205 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Wells Fargo Root CA", (PRUint32)20 }, + { (void *)"\223\346\253\042\003\003\265\043\050\334\332\126\236\272\344\321" +"\321\314\373\145" +, (PRUint32)20 }, + { (void *)"\040\013\112\172\210\247\251\102\206\212\137\164\126\173\210\005" +, (PRUint32)16 }, + { (void *)"\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123" +"\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163" +"\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023" +"\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162" +"\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157" +"\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127" +"\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040" +"\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150" +"\157\162\151\164\171" +, (PRUint32)133 }, + { (void *)"\002\004\071\344\227\236" +, (PRUint32)6 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_206 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Swisscom Root CA 1", (PRUint32)19 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061" +"\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143" +"\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147" +"\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145" +"\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125" +"\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157" +"\164\040\103\101\040\061" +, (PRUint32)102 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061" +"\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143" +"\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147" +"\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145" +"\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125" +"\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157" +"\164\040\103\101\040\061" +, (PRUint32)102 }, + { (void *)"\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235" +"\250\066" +, (PRUint32)18 }, + { (void *)"\060\202\005\331\060\202\003\301\240\003\002\001\002\002\020\134" +"\013\205\134\013\347\131\101\337\127\314\077\177\235\250\066\060" +"\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\144" +"\061\013\060\011\006\003\125\004\006\023\002\143\150\061\021\060" +"\017\006\003\125\004\012\023\010\123\167\151\163\163\143\157\155" +"\061\045\060\043\006\003\125\004\013\023\034\104\151\147\151\164" +"\141\154\040\103\145\162\164\151\146\151\143\141\164\145\040\123" +"\145\162\166\151\143\145\163\061\033\060\031\006\003\125\004\003" +"\023\022\123\167\151\163\163\143\157\155\040\122\157\157\164\040" +"\103\101\040\061\060\036\027\015\060\065\060\070\061\070\061\062" +"\060\066\062\060\132\027\015\062\065\060\070\061\070\062\062\060" +"\066\062\060\132\060\144\061\013\060\011\006\003\125\004\006\023" +"\002\143\150\061\021\060\017\006\003\125\004\012\023\010\123\167" +"\151\163\163\143\157\155\061\045\060\043\006\003\125\004\013\023" +"\034\104\151\147\151\164\141\154\040\103\145\162\164\151\146\151" +"\143\141\164\145\040\123\145\162\166\151\143\145\163\061\033\060" +"\031\006\003\125\004\003\023\022\123\167\151\163\163\143\157\155" +"\040\122\157\157\164\040\103\101\040\061\060\202\002\042\060\015" +"\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002" +"\017\000\060\202\002\012\002\202\002\001\000\320\271\260\250\014" +"\331\273\077\041\370\033\325\063\223\200\026\145\040\165\262\075" +"\233\140\155\106\310\214\061\157\027\303\372\232\154\126\355\074" +"\305\221\127\303\315\253\226\111\220\052\031\113\036\243\155\127" +"\335\361\053\142\050\165\105\136\252\326\133\372\013\045\330\241" +"\026\371\034\304\056\346\225\052\147\314\320\051\156\074\205\064" +"\070\141\111\261\000\237\326\072\161\137\115\155\316\137\271\251" +"\344\211\177\152\122\372\312\233\362\334\251\371\235\231\107\077" +"\116\051\137\264\246\215\135\173\013\231\021\003\003\376\347\333" +"\333\243\377\035\245\315\220\036\001\037\065\260\177\000\333\220" +"\157\306\176\173\321\356\172\172\247\252\014\127\157\244\155\305" +"\023\073\260\245\331\355\062\034\264\136\147\213\124\334\163\207" +"\345\323\027\174\146\120\162\135\324\032\130\301\331\317\330\211" +"\002\157\247\111\264\066\135\320\244\336\007\054\266\165\267\050" +"\221\326\227\276\050\365\230\036\352\133\046\311\275\260\227\163" +"\332\256\221\046\353\150\301\371\071\025\326\147\113\012\155\117" +"\313\317\260\344\102\161\214\123\171\347\356\341\333\035\240\156" +"\035\214\032\167\065\134\026\036\053\123\037\064\213\321\154\374" +"\362\147\007\172\365\255\355\326\232\253\241\261\113\341\314\067" +"\137\375\177\315\115\256\270\037\234\103\371\052\130\125\103\105" +"\274\226\315\160\016\374\311\343\146\272\116\215\073\201\313\025" +"\144\173\271\224\350\135\063\122\205\161\056\117\216\242\006\021" +"\121\311\343\313\241\156\061\010\144\014\302\322\074\365\066\350" +"\327\320\016\170\043\040\221\311\044\052\145\051\133\042\367\041" +"\316\203\136\244\363\336\113\323\150\217\106\165\134\203\011\156" +"\051\153\304\160\214\365\235\327\040\057\377\106\322\053\070\302" +"\057\165\034\075\176\332\245\357\036\140\205\151\102\323\314\370" +"\143\376\036\103\071\205\246\266\143\101\020\263\163\036\274\323" +"\372\312\175\026\107\342\247\325\320\243\212\012\010\226\142\126" +"\156\064\333\331\002\271\060\165\343\004\322\347\217\302\260\021" +"\100\012\254\325\161\002\142\213\061\276\335\306\043\130\061\102" +"\103\055\164\371\306\236\246\212\017\351\376\277\203\346\103\127" +"\044\272\357\106\064\252\327\022\001\070\355\002\003\001\000\001" +"\243\201\206\060\201\203\060\016\006\003\125\035\017\001\001\377" +"\004\004\003\002\001\206\060\035\006\003\125\035\041\004\026\060" +"\024\060\022\006\007\140\205\164\001\123\000\001\006\007\140\205" +"\164\001\123\000\001\060\022\006\003\125\035\023\001\001\377\004" +"\010\060\006\001\001\377\002\001\007\060\037\006\003\125\035\043" +"\004\030\060\026\200\024\003\045\057\336\157\202\001\072\134\054" +"\334\053\241\151\265\147\324\214\323\375\060\035\006\003\125\035" +"\016\004\026\004\024\003\045\057\336\157\202\001\072\134\054\334" +"\053\241\151\265\147\324\214\323\375\060\015\006\011\052\206\110" +"\206\367\015\001\001\005\005\000\003\202\002\001\000\065\020\313" +"\354\246\004\015\015\017\315\300\333\253\250\362\210\227\014\337" +"\223\057\115\174\100\126\061\172\353\244\017\140\315\172\363\276" +"\303\047\216\003\076\244\335\022\357\176\036\164\006\074\077\061" +"\362\034\173\221\061\041\264\360\320\154\227\324\351\227\262\044" +"\126\036\126\303\065\275\210\005\017\133\020\032\144\341\307\202" +"\060\371\062\255\236\120\054\347\170\005\320\061\261\132\230\212" +"\165\116\220\134\152\024\052\340\122\107\202\140\346\036\332\201" +"\261\373\024\013\132\361\237\322\225\272\076\320\033\326\025\035" +"\243\276\206\325\333\017\300\111\144\273\056\120\031\113\322\044" +"\370\335\036\007\126\320\070\240\225\160\040\166\214\327\335\036" +"\336\237\161\304\043\357\203\023\134\243\044\025\115\051\100\074" +"\152\304\251\330\267\246\104\245\015\364\340\235\167\036\100\160" +"\046\374\332\331\066\344\171\344\265\077\274\233\145\276\273\021" +"\226\317\333\306\050\071\072\010\316\107\133\123\132\305\231\376" +"\135\251\335\357\114\324\306\245\255\002\346\214\007\022\036\157" +"\003\321\157\240\243\363\051\275\022\307\120\242\260\177\210\251" +"\231\167\232\261\300\245\071\056\134\174\151\342\054\260\352\067" +"\152\244\341\132\341\365\120\345\203\357\245\273\052\210\347\214" +"\333\375\155\136\227\031\250\176\146\165\153\161\352\277\261\307" +"\157\240\364\216\244\354\064\121\133\214\046\003\160\241\167\325" +"\001\022\127\000\065\333\043\336\016\212\050\231\375\261\020\157" +"\113\377\070\055\140\116\054\234\353\147\265\255\111\356\113\037" +"\254\257\373\015\220\132\146\140\160\135\252\315\170\324\044\356" +"\310\101\240\223\001\222\234\152\236\374\271\044\305\263\025\202" +"\176\276\256\225\053\353\261\300\332\343\001\140\013\136\151\254" +"\204\126\141\276\161\027\376\035\023\017\376\306\207\105\351\376" +"\062\240\032\015\023\244\224\125\161\245\026\213\272\312\211\260" +"\262\307\374\217\330\124\265\223\142\235\316\317\131\373\075\030" +"\316\052\313\065\025\202\135\377\124\042\133\161\122\373\267\311" +"\376\140\233\000\101\144\360\252\052\354\266\102\103\316\211\146" +"\201\310\213\237\071\124\003\045\323\026\065\216\204\320\137\372" +"\060\032\365\232\154\364\016\123\371\072\133\321\034" +, (PRUint32)1501 } +}; +static const NSSItem nss_builtins_items_207 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Swisscom Root CA 1", (PRUint32)19 }, + { (void *)"\137\072\374\012\213\144\366\206\147\064\164\337\176\251\242\376" +"\371\372\172\121" +, (PRUint32)20 }, + { (void *)"\370\070\174\167\210\337\054\026\150\056\302\342\122\113\270\371" +, (PRUint32)16 }, + { (void *)"\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061" +"\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143" +"\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147" +"\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145" +"\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125" +"\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157" +"\164\040\103\101\040\061" +, (PRUint32)102 }, + { (void *)"\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235" +"\250\066" +, (PRUint32)18 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; PR_IMPLEMENT_DATA(builtinsInternalObject) nss_builtins_data[] = { @@ -12862,11 +14166,29 @@ nss_builtins_data[] = { { 11, nss_builtins_types_186, nss_builtins_items_186, {NULL} }, { 13, nss_builtins_types_187, nss_builtins_items_187, {NULL} }, { 11, nss_builtins_types_188, nss_builtins_items_188, {NULL} }, - { 13, nss_builtins_types_189, nss_builtins_items_189, {NULL} } + { 13, nss_builtins_types_189, nss_builtins_items_189, {NULL} }, + { 11, nss_builtins_types_190, nss_builtins_items_190, {NULL} }, + { 13, nss_builtins_types_191, nss_builtins_items_191, {NULL} }, + { 11, nss_builtins_types_192, nss_builtins_items_192, {NULL} }, + { 13, nss_builtins_types_193, nss_builtins_items_193, {NULL} }, + { 11, nss_builtins_types_194, nss_builtins_items_194, {NULL} }, + { 13, nss_builtins_types_195, nss_builtins_items_195, {NULL} }, + { 11, nss_builtins_types_196, nss_builtins_items_196, {NULL} }, + { 13, nss_builtins_types_197, nss_builtins_items_197, {NULL} }, + { 11, nss_builtins_types_198, nss_builtins_items_198, {NULL} }, + { 13, nss_builtins_types_199, nss_builtins_items_199, {NULL} }, + { 11, nss_builtins_types_200, nss_builtins_items_200, {NULL} }, + { 13, nss_builtins_types_201, nss_builtins_items_201, {NULL} }, + { 11, nss_builtins_types_202, nss_builtins_items_202, {NULL} }, + { 13, nss_builtins_types_203, nss_builtins_items_203, {NULL} }, + { 11, nss_builtins_types_204, nss_builtins_items_204, {NULL} }, + { 13, nss_builtins_types_205, nss_builtins_items_205, {NULL} }, + { 11, nss_builtins_types_206, nss_builtins_items_206, {NULL} }, + { 13, nss_builtins_types_207, nss_builtins_items_207, {NULL} } }; PR_IMPLEMENT_DATA(const PRUint32) #ifdef DEBUG - nss_builtins_nObjects = 189+1; + nss_builtins_nObjects = 207+1; #else - nss_builtins_nObjects = 189; + nss_builtins_nObjects = 207; #endif /* DEBUG */ diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt index 8a8b1c5b6..aa6f1c0f7 100644 --- a/security/nss/lib/ckfw/builtins/certdata.txt +++ b/security/nss/lib/ckfw/builtins/certdata.txt @@ -7603,6 +7603,409 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # +# Certificate "GeoTrust Global CA 2" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Global CA 2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003 +\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141 +\154\040\103\101\040\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003 +\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141 +\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\003\146\060\202\002\116\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026 +\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163 +\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003\023 +\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141\154 +\040\103\101\040\062\060\036\027\015\060\064\060\063\060\064\060 +\065\060\060\060\060\132\027\015\061\071\060\063\060\064\060\065 +\060\060\060\060\132\060\104\061\013\060\011\006\003\125\004\006 +\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015\107 +\145\157\124\162\165\163\164\040\111\156\143\056\061\035\060\033 +\006\003\125\004\003\023\024\107\145\157\124\162\165\163\164\040 +\107\154\157\142\141\154\040\103\101\040\062\060\202\001\042\060 +\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202 +\001\017\000\060\202\001\012\002\202\001\001\000\357\074\115\100 +\075\020\337\073\123\000\341\147\376\224\140\025\076\205\210\361 +\211\015\220\310\050\043\231\005\350\053\040\235\306\363\140\106 +\330\301\262\325\214\061\331\334\040\171\044\201\277\065\062\374 +\143\151\333\261\052\153\356\041\130\362\010\351\170\313\157\313 +\374\026\122\310\221\304\377\075\163\336\261\076\247\302\175\146 +\301\365\176\122\044\032\342\325\147\221\320\202\020\327\170\113 +\117\053\102\071\275\144\055\100\240\260\020\323\070\110\106\210 +\241\014\273\072\063\052\142\230\373\000\235\023\131\177\157\073 +\162\252\356\246\017\206\371\005\141\352\147\177\014\067\226\213 +\346\151\026\107\021\302\047\131\003\263\246\140\302\041\100\126 +\372\240\307\175\072\023\343\354\127\307\263\326\256\235\211\200 +\367\001\347\054\366\226\053\023\015\171\054\331\300\344\206\173 +\113\214\014\162\202\212\373\027\315\000\154\072\023\074\260\204 +\207\113\026\172\051\262\117\333\035\324\013\363\146\067\275\330 +\366\127\273\136\044\172\270\074\213\271\372\222\032\032\204\236 +\330\164\217\252\033\177\136\364\376\105\042\041\002\003\001\000 +\001\243\143\060\141\060\017\006\003\125\035\023\001\001\377\004 +\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004 +\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251\020 +\025\130\040\005\011\060\037\006\003\125\035\043\004\030\060\026 +\200\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251 +\020\025\130\040\005\011\060\016\006\003\125\035\017\001\001\377 +\004\004\003\002\001\206\060\015\006\011\052\206\110\206\367\015 +\001\001\005\005\000\003\202\001\001\000\003\367\265\053\253\135 +\020\374\173\262\262\136\254\233\016\176\123\170\131\076\102\004 +\376\165\243\255\254\201\116\327\002\213\136\304\055\310\122\166 +\307\054\037\374\201\062\230\321\113\306\222\223\063\065\061\057 +\374\330\035\104\335\340\201\177\235\351\213\341\144\221\142\013 +\071\010\214\254\164\235\131\331\172\131\122\227\021\271\026\173 +\157\105\323\226\331\061\175\002\066\017\234\073\156\317\054\015 +\003\106\105\353\240\364\177\110\104\306\010\100\314\336\033\160 +\265\051\255\272\213\073\064\145\165\033\161\041\035\054\024\012 +\260\226\225\270\326\352\362\145\373\051\272\117\352\221\223\164 +\151\266\362\377\341\032\320\014\321\166\205\313\212\045\275\227 +\136\054\157\025\231\046\347\266\051\377\042\354\311\002\307\126 +\000\315\111\271\263\154\173\123\004\032\342\250\311\252\022\005 +\043\302\316\347\273\004\002\314\300\107\242\344\304\051\057\133 +\105\127\211\121\356\074\353\122\010\377\007\065\036\237\065\152 +\107\112\126\230\321\132\205\037\214\365\042\277\253\316\203\363 +\342\042\051\256\175\203\100\250\272\154 +END + +# Trust for Certificate "GeoTrust Global CA 2" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Global CA 2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\251\351\170\010\024\067\130\210\362\005\031\260\155\053\015\053 +\140\026\220\175 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\016\100\247\154\336\003\135\217\321\017\344\321\215\371\154\251 +END +CKA_ISSUER MULTILINE_OCTAL +\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003 +\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141 +\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "GeoTrust Universal CA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003 +\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003 +\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\150\060\202\003\120\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026 +\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163 +\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003\023 +\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162 +\163\141\154\040\103\101\060\036\027\015\060\064\060\063\060\064 +\060\065\060\060\060\060\132\027\015\062\071\060\063\060\064\060 +\065\060\060\060\060\132\060\105\061\013\060\011\006\003\125\004 +\006\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015 +\107\145\157\124\162\165\163\164\040\111\156\143\056\061\036\060 +\034\006\003\125\004\003\023\025\107\145\157\124\162\165\163\164 +\040\125\156\151\166\145\162\163\141\154\040\103\101\060\202\002 +\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000 +\003\202\002\017\000\060\202\002\012\002\202\002\001\000\246\025 +\125\240\243\306\340\037\214\235\041\120\327\301\276\053\133\265 +\244\236\241\331\162\130\275\000\033\114\277\141\311\024\035\105 +\202\253\306\035\200\326\075\353\020\234\072\257\155\044\370\274 +\161\001\236\006\365\174\137\036\301\016\125\312\203\232\131\060 +\256\031\313\060\110\225\355\042\067\215\364\112\232\162\146\076 +\255\225\300\340\026\000\340\020\037\053\061\016\327\224\124\323 +\102\063\240\064\035\036\105\166\335\117\312\030\067\354\205\025 +\172\031\010\374\325\307\234\360\362\251\056\020\251\222\346\075 +\130\075\251\026\150\074\057\165\041\030\177\050\167\245\341\141 +\027\267\246\351\370\036\231\333\163\156\364\012\242\041\154\356 +\332\252\205\222\146\257\366\172\153\202\332\272\042\010\065\017 +\317\102\361\065\372\152\356\176\053\045\314\072\021\344\155\257 +\163\262\166\035\255\320\262\170\147\032\244\071\034\121\013\147 +\126\203\375\070\135\015\316\335\360\273\053\226\037\336\173\062 +\122\375\035\273\265\006\241\262\041\136\245\326\225\150\177\360 +\231\236\334\105\010\076\347\322\011\015\065\224\335\200\116\123 +\227\327\265\011\104\040\144\026\027\003\002\114\123\015\150\336 +\325\252\162\115\223\155\202\016\333\234\275\317\264\363\134\135 +\124\172\151\011\226\326\333\021\301\215\165\250\264\317\071\310 +\316\074\274\044\174\346\142\312\341\275\175\247\275\127\145\013 +\344\376\045\355\266\151\020\334\050\032\106\275\001\035\320\227 +\265\341\230\073\300\067\144\326\075\224\356\013\341\365\050\256 +\013\126\277\161\213\043\051\101\216\206\305\113\122\173\330\161 +\253\037\212\025\246\073\203\132\327\130\001\121\306\114\101\331 +\177\330\101\147\162\242\050\337\140\203\251\236\310\173\374\123 +\163\162\131\365\223\172\027\166\016\316\367\345\134\331\013\125 +\064\242\252\133\265\152\124\347\023\312\127\354\227\155\364\136 +\006\057\105\213\130\324\043\026\222\344\026\156\050\143\131\060 +\337\120\001\234\143\211\032\237\333\027\224\202\160\067\303\044 +\236\232\107\326\132\312\116\250\151\211\162\037\221\154\333\176 +\236\033\255\307\037\163\335\054\117\031\145\375\177\223\100\020 +\056\322\360\355\074\236\056\050\076\151\046\063\305\173\002\003 +\001\000\001\243\143\060\141\060\017\006\003\125\035\023\001\001 +\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004 +\026\004\024\332\273\056\252\260\014\270\210\046\121\164\134\155 +\003\323\300\330\217\172\326\060\037\006\003\125\035\043\004\030 +\060\026\200\024\332\273\056\252\260\014\270\210\046\121\164\134 +\155\003\323\300\330\217\172\326\060\016\006\003\125\035\017\001 +\001\377\004\004\003\002\001\206\060\015\006\011\052\206\110\206 +\367\015\001\001\005\005\000\003\202\002\001\000\061\170\346\307 +\265\337\270\224\100\311\161\304\250\065\354\106\035\302\205\363 +\050\130\206\260\013\374\216\262\071\217\104\125\253\144\204\134 +\151\251\320\232\070\074\372\345\037\065\345\104\343\200\171\224 +\150\244\273\304\237\075\341\064\315\060\106\213\124\053\225\245 +\357\367\077\231\204\375\065\346\317\061\306\334\152\277\247\327 +\043\010\341\230\136\303\132\010\166\251\246\257\167\057\267\140 +\275\104\106\152\357\227\377\163\225\301\216\350\223\373\375\061 +\267\354\127\021\021\105\233\060\361\032\210\071\301\117\074\247 +\000\325\307\374\253\155\200\042\160\245\014\340\135\004\051\002 +\373\313\240\221\321\174\326\303\176\120\325\235\130\276\101\070 +\353\271\165\074\025\331\233\311\112\203\131\300\332\123\375\063 +\273\066\030\233\205\017\025\335\356\055\254\166\223\271\331\001 +\215\110\020\250\373\365\070\206\361\333\012\306\275\204\243\043 +\101\336\326\167\157\205\324\205\034\120\340\256\121\212\272\215 +\076\166\342\271\312\047\362\137\237\357\156\131\015\006\330\053 +\027\244\322\174\153\273\137\024\032\110\217\032\114\347\263\107 +\034\216\114\105\053\040\356\110\337\347\335\011\216\030\250\332 +\100\215\222\046\021\123\141\163\135\353\275\347\304\115\051\067 +\141\353\254\071\055\147\056\026\326\365\000\203\205\241\314\177 +\166\304\175\344\267\113\146\357\003\105\140\151\266\014\122\226 +\222\204\136\246\243\265\244\076\053\331\314\330\033\107\252\362 +\104\332\117\371\003\350\360\024\313\077\363\203\336\320\301\124 +\343\267\350\012\067\115\213\040\131\003\060\031\241\054\310\275 +\021\037\337\256\311\112\305\363\047\146\146\206\254\150\221\377 +\331\346\123\034\017\213\134\151\145\012\046\310\036\064\303\135 +\121\173\327\251\234\006\241\066\335\325\211\224\274\331\344\055 +\014\136\011\154\010\227\174\243\075\174\223\377\077\241\024\247 +\317\265\135\353\333\333\034\304\166\337\210\271\275\105\005\225 +\033\256\374\106\152\114\257\110\343\316\256\017\322\176\353\346 +\154\234\117\201\152\172\144\254\273\076\325\347\313\166\056\305 +\247\110\301\134\220\017\313\310\077\372\346\062\341\215\033\157 +\244\346\216\330\371\051\110\212\316\163\376\054 +END + +# Trust for Certificate "GeoTrust Universal CA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\346\041\363\065\103\171\005\232\113\150\060\235\212\057\164\042 +\025\207\354\171 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\222\145\130\213\242\032\061\162\163\150\134\264\245\172\007\110 +END +CKA_ISSUER MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003 +\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "GeoTrust Universal CA 2" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA 2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003 +\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101\040\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003 +\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\154\060\202\003\124\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026 +\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163 +\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003\023 +\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162 +\163\141\154\040\103\101\040\062\060\036\027\015\060\064\060\063 +\060\064\060\065\060\060\060\060\132\027\015\062\071\060\063\060 +\064\060\065\060\060\060\060\132\060\107\061\013\060\011\006\003 +\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004\012 +\023\015\107\145\157\124\162\165\163\164\040\111\156\143\056\061 +\040\060\036\006\003\125\004\003\023\027\107\145\157\124\162\165 +\163\164\040\125\156\151\166\145\162\163\141\154\040\103\101\040 +\062\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001 +\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002 +\001\000\263\124\122\301\311\076\362\331\334\261\123\032\131\051 +\347\261\303\105\050\345\327\321\355\305\305\113\241\252\164\173 +\127\257\112\046\374\330\365\136\247\156\031\333\164\014\117\065 +\133\062\013\001\343\333\353\172\167\065\352\252\132\340\326\350 +\241\127\224\360\220\243\164\126\224\104\060\003\036\134\116\053 +\205\046\164\202\172\014\166\240\157\115\316\101\055\240\025\006 +\024\137\267\102\315\173\217\130\141\064\334\052\010\371\056\303 +\001\246\042\104\034\114\007\202\346\133\316\320\112\174\004\323 +\031\163\047\360\252\230\177\056\257\116\353\207\036\044\167\152 +\135\266\350\133\105\272\334\303\241\005\157\126\216\217\020\046 +\245\111\303\056\327\101\207\042\340\117\206\312\140\265\352\241 +\143\300\001\227\020\171\275\000\074\022\155\053\025\261\254\113 +\261\356\030\271\116\226\334\334\166\377\073\276\317\137\003\300 +\374\073\350\276\106\033\377\332\100\302\122\367\376\343\072\367 +\152\167\065\320\332\215\353\136\030\152\061\307\036\272\074\033 +\050\326\153\124\306\252\133\327\242\054\033\031\314\242\002\366 +\233\131\275\067\153\206\265\155\202\272\330\352\311\126\274\251 +\066\130\375\076\031\363\355\014\046\251\223\070\370\117\301\135 +\042\006\320\227\352\341\255\306\125\340\201\053\050\203\072\372 +\364\173\041\121\000\276\122\070\316\315\146\171\250\364\201\126 +\342\320\203\011\107\121\133\120\152\317\333\110\032\135\076\367 +\313\366\145\367\154\361\225\370\002\073\062\126\202\071\172\133 +\275\057\211\033\277\241\264\350\377\177\215\214\337\003\361\140 +\116\130\021\114\353\243\077\020\053\203\232\001\163\331\224\155 +\204\000\047\146\254\360\160\100\011\102\222\255\117\223\015\141 +\011\121\044\330\222\325\013\224\141\262\207\262\355\377\232\065 +\377\205\124\312\355\104\103\254\033\074\026\153\110\112\012\034 +\100\210\037\222\302\013\000\005\377\362\310\002\112\244\252\251 +\314\231\226\234\057\130\340\175\341\276\273\007\334\137\004\162 +\134\061\064\303\354\137\055\340\075\144\220\042\346\321\354\270 +\056\335\131\256\331\241\067\277\124\065\334\163\062\117\214\004 +\036\063\262\311\106\361\330\134\310\125\120\311\150\275\250\272 +\066\011\002\003\001\000\001\243\143\060\141\060\017\006\003\125 +\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003 +\125\035\016\004\026\004\024\166\363\125\341\372\244\066\373\360 +\237\134\142\161\355\074\364\107\070\020\053\060\037\006\003\125 +\035\043\004\030\060\026\200\024\166\363\125\341\372\244\066\373 +\360\237\134\142\161\355\074\364\107\070\020\053\060\016\006\003 +\125\035\017\001\001\377\004\004\003\002\001\206\060\015\006\011 +\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001\000 +\146\301\306\043\363\331\340\056\156\137\350\317\256\260\260\045 +\115\053\370\073\130\233\100\044\067\132\313\253\026\111\377\263 +\165\171\063\241\057\155\160\027\064\221\376\147\176\217\354\233 +\345\136\202\251\125\037\057\334\324\121\007\022\376\254\026\076 +\054\065\306\143\374\334\020\353\015\243\252\320\174\314\321\320 +\057\121\056\304\024\132\336\350\031\341\076\306\314\244\051\347 +\056\204\252\006\060\170\166\124\163\050\230\131\070\340\000\015 +\142\323\102\175\041\237\256\075\072\214\325\372\167\015\030\053 +\026\016\137\066\341\374\052\265\060\044\317\340\143\014\173\130 +\032\376\231\272\102\022\261\221\364\174\150\342\310\350\257\054 +\352\311\176\256\273\052\075\015\025\334\064\225\266\030\164\250 +\152\017\307\264\364\023\304\344\133\355\012\322\244\227\114\052 +\355\057\154\022\211\075\361\047\160\252\152\003\122\041\237\100 +\250\147\120\362\363\132\037\337\337\043\366\334\170\116\346\230 +\117\125\072\123\343\357\362\364\237\307\174\330\130\257\051\042 +\227\270\340\275\221\056\260\166\354\127\021\317\357\051\104\363 +\351\205\172\140\143\344\135\063\211\027\331\061\252\332\326\363 +\030\065\162\317\207\053\057\143\043\204\135\204\214\077\127\240 +\210\374\231\221\050\046\151\231\324\217\227\104\276\216\325\110 +\261\244\050\051\361\025\264\341\345\236\335\370\217\246\157\046 +\327\011\074\072\034\021\016\246\154\067\367\255\104\207\054\050 +\307\330\164\202\263\320\157\112\127\273\065\051\047\240\213\350 +\041\247\207\144\066\135\314\330\026\254\307\262\047\100\222\125 +\070\050\215\121\156\335\024\147\123\154\161\134\046\204\115\165 +\132\266\176\140\126\251\115\255\373\233\036\227\363\015\331\322 +\227\124\167\332\075\022\267\340\036\357\010\006\254\371\205\207 +\351\242\334\257\176\030\022\203\375\126\027\101\056\325\051\202 +\175\231\364\061\366\161\251\317\054\001\047\245\005\271\252\262 +\110\116\052\357\237\223\122\121\225\074\122\163\216\126\114\027 +\100\300\011\050\344\213\152\110\123\333\354\315\125\125\361\306 +\370\351\242\054\114\246\321\046\137\176\257\132\114\332\037\246 +\362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222 +END + +# Trust for Certificate "GeoTrust Universal CA 2" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA 2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\067\232\031\173\101\205\105\065\014\246\003\151\363\074\056\257 +\107\117\040\171 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\064\374\270\320\066\333\236\024\263\302\362\333\217\344\224\307 +END +CKA_ISSUER MULTILINE_OCTAL +\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003 +\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# # Certificate "UTN-USER First-Network Applications" # CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE @@ -12170,6 +12573,198 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # +# Certificate "NetLock Qualified (Class QA) Root" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "NetLock Qualified (Class QA) Root" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125 +\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160 +\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145 +\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172 +\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030 +\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004 +\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163 +\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151 +\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165 +\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034 +\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146 +\157\100\156\145\164\154\157\143\153\056\150\165 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125 +\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160 +\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145 +\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172 +\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030 +\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004 +\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163 +\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151 +\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165 +\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034 +\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146 +\157\100\156\145\164\154\157\143\153\056\150\165 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\173 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\006\321\060\202\005\271\240\003\002\001\002\002\001\173 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125\061 +\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145 +\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145\164 +\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172\164 +\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030\006 +\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141\156 +\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004\003 +\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163\151 +\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151\040 +\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165\163 +\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034\006 +\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146\157 +\100\156\145\164\154\157\143\153\056\150\165\060\036\027\015\060 +\063\060\063\063\060\060\061\064\067\061\061\132\027\015\062\062 +\061\062\061\065\060\061\064\067\061\061\132\060\201\311\061\013 +\060\011\006\003\125\004\006\023\002\110\125\061\021\060\017\006 +\003\125\004\007\023\010\102\165\144\141\160\145\163\164\061\047 +\060\045\006\003\125\004\012\023\036\116\145\164\114\157\143\153 +\040\110\141\154\157\172\141\164\142\151\172\164\157\156\163\141 +\147\151\040\113\146\164\056\061\032\060\030\006\003\125\004\013 +\023\021\124\141\156\165\163\151\164\166\141\156\171\153\151\141 +\144\157\153\061\102\060\100\006\003\125\004\003\023\071\116\145 +\164\114\157\143\153\040\115\151\156\157\163\151\164\145\164\164 +\040\113\157\172\152\145\147\171\172\157\151\040\050\103\154\141 +\163\163\040\121\101\051\040\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\061\036\060\034\006\011\052\206\110 +\206\367\015\001\011\001\026\017\151\156\146\157\100\156\145\164 +\154\157\143\153\056\150\165\060\202\001\042\060\015\006\011\052 +\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060 +\202\001\012\002\202\001\001\000\307\122\045\262\330\075\324\204 +\125\011\247\033\275\154\271\024\364\212\002\333\166\374\152\052 +\170\253\345\167\360\156\340\214\043\147\333\245\144\231\271\335 +\001\076\157\357\055\232\074\042\360\135\311\127\240\125\101\177 +\362\103\136\130\202\123\061\145\316\036\362\046\272\000\124\036 +\257\260\274\034\344\122\214\240\062\257\267\067\261\123\147\150 +\164\147\120\366\055\056\144\336\256\046\171\337\337\231\206\253 +\253\177\205\354\240\373\200\314\364\270\014\036\223\105\143\271 +\334\270\133\233\355\133\071\324\137\142\260\247\216\174\146\070 +\054\252\261\010\143\027\147\175\314\275\263\361\303\077\317\120 +\071\355\321\031\203\025\333\207\022\047\226\267\332\352\345\235 +\274\272\352\071\117\213\357\164\232\347\305\320\322\352\206\121 +\034\344\376\144\010\050\004\171\005\353\312\305\161\016\013\357 +\253\352\354\022\021\241\030\005\062\151\321\014\054\032\075\045 +\231\077\265\174\312\155\260\256\231\231\372\010\140\347\031\302 +\362\275\121\323\314\323\002\254\301\021\014\200\316\253\334\224 +\235\153\243\071\123\072\326\205\002\003\000\305\175\243\202\002 +\300\060\202\002\274\060\022\006\003\125\035\023\001\001\377\004 +\010\060\006\001\001\377\002\001\004\060\016\006\003\125\035\017 +\001\001\377\004\004\003\002\001\006\060\202\002\165\006\011\140 +\206\110\001\206\370\102\001\015\004\202\002\146\026\202\002\142 +\106\111\107\131\105\114\105\115\041\040\105\172\145\156\040\164 +\141\156\165\163\151\164\166\141\156\171\040\141\040\116\145\164 +\114\157\143\153\040\113\146\164\056\040\115\151\156\157\163\151 +\164\145\164\164\040\123\172\157\154\147\141\154\164\141\164\141 +\163\151\040\123\172\141\142\141\154\171\172\141\164\141\142\141 +\156\040\154\145\151\162\164\040\145\154\152\141\162\141\163\157 +\153\040\141\154\141\160\152\141\156\040\153\145\163\172\165\154 +\164\056\040\101\040\155\151\156\157\163\151\164\145\164\164\040 +\145\154\145\153\164\162\157\156\151\153\165\163\040\141\154\141 +\151\162\141\163\040\152\157\147\150\141\164\141\163\040\145\162 +\166\145\156\171\145\163\165\154\145\163\145\156\145\153\054\040 +\166\141\154\141\155\151\156\164\040\145\154\146\157\147\141\144 +\141\163\141\156\141\153\040\146\145\154\164\145\164\145\154\145 +\040\141\040\115\151\156\157\163\151\164\145\164\164\040\123\172 +\157\154\147\141\154\164\141\164\141\163\151\040\123\172\141\142 +\141\154\171\172\141\164\142\141\156\054\040\141\172\040\101\154 +\164\141\154\141\156\157\163\040\123\172\145\162\172\157\144\145 +\163\151\040\106\145\154\164\145\164\145\154\145\153\142\145\156 +\040\145\154\157\151\162\164\040\145\154\154\145\156\157\162\172 +\145\163\151\040\145\154\152\141\162\141\163\040\155\145\147\164 +\145\164\145\154\145\056\040\101\040\144\157\153\165\155\145\156 +\164\165\155\157\153\040\155\145\147\164\141\154\141\154\150\141 +\164\157\153\040\141\040\150\164\164\160\163\072\057\057\167\167 +\167\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143 +\163\057\040\143\151\155\145\156\040\166\141\147\171\040\153\145 +\162\150\145\164\157\153\040\141\172\040\151\156\146\157\100\156 +\145\164\154\157\143\153\056\156\145\164\040\145\055\155\141\151 +\154\040\143\151\155\145\156\056\040\127\101\122\116\111\116\107 +\041\040\124\150\145\040\151\163\163\165\141\156\143\145\040\141 +\156\144\040\164\150\145\040\165\163\145\040\157\146\040\164\150 +\151\163\040\143\145\162\164\151\146\151\143\141\164\145\040\141 +\162\145\040\163\165\142\152\145\143\164\040\164\157\040\164\150 +\145\040\116\145\164\114\157\143\153\040\121\165\141\154\151\146 +\151\145\144\040\103\120\123\040\141\166\141\151\154\141\142\154 +\145\040\141\164\040\150\164\164\160\163\072\057\057\167\167\167 +\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143\163 +\057\040\157\162\040\142\171\040\145\055\155\141\151\154\040\141 +\164\040\151\156\146\157\100\156\145\164\154\157\143\153\056\156 +\145\164\060\035\006\003\125\035\016\004\026\004\024\011\152\142 +\026\222\260\132\273\125\016\313\165\062\072\062\345\262\041\311 +\050\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000 +\003\202\001\001\000\221\152\120\234\333\170\201\233\077\213\102 +\343\073\374\246\303\356\103\340\317\363\342\200\065\111\105\166 +\002\342\343\057\005\305\361\052\347\300\101\063\306\266\233\320 +\063\071\315\300\333\241\255\154\067\002\114\130\101\073\362\227 +\222\306\110\250\315\345\212\071\211\141\371\122\227\351\275\366 +\371\224\164\350\161\016\274\167\206\303\006\314\132\174\112\176 +\064\120\060\056\373\177\062\232\215\075\363\040\133\370\152\312 +\206\363\061\114\054\131\200\002\175\376\070\311\060\165\034\267 +\125\343\274\237\272\250\155\204\050\005\165\263\213\015\300\221 +\124\041\347\246\013\264\231\365\121\101\334\315\243\107\042\331 +\307\001\201\304\334\107\117\046\352\037\355\333\315\015\230\364 +\243\234\264\163\062\112\226\231\376\274\177\310\045\130\370\130 +\363\166\146\211\124\244\246\076\304\120\134\272\211\030\202\165 +\110\041\322\117\023\350\140\176\007\166\333\020\265\121\346\252 +\271\150\252\315\366\235\220\165\022\352\070\032\312\104\350\267 +\231\247\052\150\225\146\225\253\255\357\211\313\140\251\006\022 +\306\224\107\351\050 +END + +# Trust for Certificate "NetLock Qualified (Class QA) Root" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "NetLock Qualified (Class QA) Root" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\001\150\227\341\240\270\362\303\261\064\146\134\040\247\047\267 +\241\130\342\217 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\324\200\145\150\044\371\211\042\050\333\365\244\232\027\217\024 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125 +\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160 +\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145 +\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172 +\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030 +\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004 +\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163 +\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151 +\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165 +\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034 +\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146 +\157\100\156\145\164\154\157\143\153\056\150\165 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\173 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_VALID +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# # Certificate "NetLock Notary (Class A) Root" # CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE @@ -13068,3 +13663,748 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "StartCom Ltd." +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "StartCom Ltd." +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114 +\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145 +\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141 +\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162 +\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125 +\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171 +\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040 +\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026 +\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056 +\157\162\147 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114 +\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145 +\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141 +\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162 +\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125 +\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171 +\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040 +\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026 +\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056 +\157\162\147 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\000 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\026\060\202\004\177\240\003\002\001\002\002\001\000 +\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060 +\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114\061 +\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145\154 +\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141\164 +\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164 +\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125\004 +\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171\040 +\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040\106 +\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143 +\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\061 +\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026\022 +\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056\157 +\162\147\060\036\027\015\060\065\060\063\061\067\061\067\063\067 +\064\070\132\027\015\063\065\060\063\061\060\061\067\063\067\064 +\070\132\060\201\260\061\013\060\011\006\003\125\004\006\023\002 +\111\114\061\017\060\015\006\003\125\004\010\023\006\111\163\162 +\141\145\154\061\016\060\014\006\003\125\004\007\023\005\105\151 +\154\141\164\061\026\060\024\006\003\125\004\012\023\015\123\164 +\141\162\164\103\157\155\040\114\164\144\056\061\032\060\030\006 +\003\125\004\013\023\021\103\101\040\101\165\164\150\157\162\151 +\164\171\040\104\145\160\056\061\051\060\047\006\003\125\004\003 +\023\040\106\162\145\145\040\123\123\114\040\103\145\162\164\151 +\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151 +\164\171\061\041\060\037\006\011\052\206\110\206\367\015\001\011 +\001\026\022\141\144\155\151\156\100\163\164\141\162\164\143\157 +\155\056\157\162\147\060\201\237\060\015\006\011\052\206\110\206 +\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002\201 +\201\000\355\204\140\000\043\236\310\112\121\051\047\336\072\241 +\071\265\151\253\011\262\057\064\375\141\334\075\323\260\317\261 +\327\302\304\302\261\344\226\126\304\276\252\024\016\347\314\072 +\120\310\072\142\235\303\243\254\131\173\216\356\125\032\034\107 +\276\243\227\071\263\265\357\043\054\010\350\330\257\163\057\271 +\311\203\350\355\000\017\310\165\245\057\064\114\030\350\166\210 +\043\111\212\333\266\355\150\332\303\265\142\051\114\245\113\267 +\230\264\011\024\020\240\370\376\142\166\042\025\013\244\326\010 +\057\065\002\003\001\000\001\243\202\002\074\060\202\002\070\060 +\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377 +\060\013\006\003\125\035\017\004\004\003\002\001\346\060\035\006 +\003\125\035\016\004\026\004\024\034\211\303\226\314\275\376\062 +\325\015\214\201\061\266\230\235\215\050\144\215\060\201\335\006 +\003\125\035\043\004\201\325\060\201\322\200\024\034\211\303\226 +\314\275\376\062\325\015\214\201\061\266\230\235\215\050\144\215 +\241\201\266\244\201\263\060\201\260\061\013\060\011\006\003\125 +\004\006\023\002\111\114\061\017\060\015\006\003\125\004\010\023 +\006\111\163\162\141\145\154\061\016\060\014\006\003\125\004\007 +\023\005\105\151\154\141\164\061\026\060\024\006\003\125\004\012 +\023\015\123\164\141\162\164\103\157\155\040\114\164\144\056\061 +\032\060\030\006\003\125\004\013\023\021\103\101\040\101\165\164 +\150\157\162\151\164\171\040\104\145\160\056\061\051\060\047\006 +\003\125\004\003\023\040\106\162\145\145\040\123\123\114\040\103 +\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 +\150\157\162\151\164\171\061\041\060\037\006\011\052\206\110\206 +\367\015\001\011\001\026\022\141\144\155\151\156\100\163\164\141 +\162\164\143\157\155\056\157\162\147\202\001\000\060\035\006\003 +\125\035\021\004\026\060\024\201\022\141\144\155\151\156\100\163 +\164\141\162\164\143\157\155\056\157\162\147\060\035\006\003\125 +\035\022\004\026\060\024\201\022\141\144\155\151\156\100\163\164 +\141\162\164\143\157\155\056\157\162\147\060\021\006\011\140\206 +\110\001\206\370\102\001\001\004\004\003\002\000\007\060\057\006 +\011\140\206\110\001\206\370\102\001\015\004\042\026\040\106\162 +\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143\141 +\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\062 +\006\011\140\206\110\001\206\370\102\001\004\004\045\026\043\150 +\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162\164 +\143\157\155\056\157\162\147\057\143\141\055\143\162\154\056\143 +\162\154\060\050\006\011\140\206\110\001\206\370\102\001\002\004 +\033\026\031\150\164\164\160\072\057\057\143\145\162\164\056\163 +\164\141\162\164\143\157\155\056\157\162\147\057\060\071\006\011 +\140\206\110\001\206\370\102\001\010\004\054\026\052\150\164\164 +\160\072\057\057\143\145\162\164\056\163\164\141\162\164\143\157 +\155\056\157\162\147\057\151\156\144\145\170\056\160\150\160\077 +\141\160\160\075\061\061\061\060\015\006\011\052\206\110\206\367 +\015\001\001\004\005\000\003\201\201\000\154\161\045\341\236\064 +\221\041\357\333\154\275\001\010\126\217\210\330\101\072\123\365 +\162\337\047\127\113\166\204\367\150\244\376\353\077\011\176\050 +\270\127\352\037\301\252\342\377\226\237\111\231\346\262\225\163 +\226\306\110\307\136\215\007\162\126\370\203\217\237\167\257\051 +\323\105\016\244\356\260\066\164\055\360\315\230\043\173\067\113 +\332\376\121\230\304\036\064\074\210\375\231\073\120\247\301\213 +\063\307\302\122\026\022\225\123\145\042\357\272\213\316\142\333 +\160\043\261\200\337\032\040\070\347\176 +END + +# Trust for Certificate "StartCom Ltd." +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "StartCom Ltd." +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\225\346\255\370\327\161\106\002\115\325\152\041\262\347\077\315 +\362\073\065\377 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\010\174\130\037\122\053\104\264\073\171\315\001\370\305\303\311 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114 +\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145 +\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141 +\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162 +\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125 +\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171 +\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040 +\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026 +\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056 +\157\162\147 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\000 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_VALID +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Taiwan GRCA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Taiwan GRCA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156 +\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156 +\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343 +\136\366 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\162\060\202\003\132\240\003\002\001\002\002\020\037 +\235\131\132\327\057\302\006\104\245\200\010\151\343\136\366\060 +\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\077 +\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060\060 +\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155\145 +\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143 +\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060 +\036\027\015\060\062\061\062\060\065\061\063\062\063\063\063\132 +\027\015\063\062\061\062\060\065\061\063\062\063\063\063\132\060 +\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060 +\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155 +\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001 +\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001 +\000\232\045\270\354\314\242\165\250\173\367\316\133\131\212\311 +\321\206\022\010\124\354\234\362\347\106\366\210\363\174\351\245 +\337\114\107\066\244\033\001\034\177\036\127\212\215\303\305\321 +\041\343\332\044\077\110\053\373\237\056\241\224\347\054\034\223 +\321\277\033\001\207\123\231\316\247\365\012\041\166\167\377\251 +\267\306\163\224\117\106\367\020\111\067\372\250\131\111\135\152 +\201\007\126\362\212\371\006\320\367\160\042\115\264\267\101\271 +\062\270\261\360\261\303\234\077\160\375\123\335\201\252\330\143 +\170\366\330\123\156\241\254\152\204\044\162\124\206\306\322\262 +\312\034\016\171\201\326\265\160\142\010\001\056\116\117\016\325 +\021\257\251\257\345\232\277\334\314\207\155\046\344\311\127\242 +\373\226\371\314\341\077\123\214\154\114\176\233\123\010\013\154 +\027\373\147\310\302\255\261\315\200\264\227\334\166\001\026\025 +\351\152\327\244\341\170\107\316\206\325\373\061\363\372\061\276 +\064\252\050\373\160\114\035\111\307\257\054\235\155\146\246\266 +\215\144\176\265\040\152\235\073\201\266\217\100\000\147\113\211 +\206\270\314\145\376\025\123\351\004\301\326\137\035\104\327\012 +\057\047\232\106\175\241\015\165\255\124\206\025\334\111\073\361 +\226\316\017\233\240\354\243\172\135\276\325\052\165\102\345\173 +\336\245\266\252\257\050\254\254\220\254\070\267\325\150\065\046 +\172\334\367\073\363\375\105\233\321\273\103\170\156\157\361\102 +\124\152\230\360\015\255\227\351\122\136\351\325\152\162\336\152 +\367\033\140\024\364\245\344\266\161\147\252\037\352\342\115\301 +\102\100\376\147\106\027\070\057\107\077\161\234\256\345\041\312 +\141\055\155\007\250\204\174\055\356\121\045\361\143\220\236\375 +\341\127\210\153\357\212\043\155\261\346\275\077\255\321\075\226 +\013\205\215\315\153\047\273\267\005\233\354\273\221\251\012\007 +\022\002\227\116\040\220\360\377\015\036\342\101\073\323\100\072 +\347\215\135\332\146\344\002\260\007\122\230\134\016\216\063\234 +\302\246\225\373\125\031\156\114\216\256\113\017\275\301\070\115 +\136\217\204\035\146\315\305\140\226\264\122\132\005\211\216\225 +\172\230\301\221\074\225\043\262\016\364\171\264\311\174\301\112 +\041\002\003\001\000\001\243\152\060\150\060\035\006\003\125\035 +\016\004\026\004\024\314\314\357\314\051\140\244\073\261\222\266 +\074\372\062\142\217\254\045\025\073\060\014\006\003\125\035\023 +\004\005\060\003\001\001\377\060\071\006\004\147\052\007\000\004 +\061\060\057\060\055\002\001\000\060\011\006\005\053\016\003\002 +\032\005\000\060\007\006\005\147\052\003\000\000\004\024\003\233 +\360\042\023\377\225\050\066\323\334\236\300\062\373\061\072\212 +\121\145\060\015\006\011\052\206\110\206\367\015\001\001\005\005 +\000\003\202\002\001\000\100\200\112\372\046\311\316\136\060\335 +\117\206\164\166\130\365\256\263\203\063\170\244\172\164\027\031 +\116\351\122\265\271\340\012\164\142\252\150\312\170\240\114\232 +\216\054\043\056\325\152\022\044\277\324\150\323\212\320\330\234 +\237\264\037\014\336\070\176\127\070\374\215\342\117\136\014\237 +\253\073\322\377\165\227\313\244\343\147\010\377\345\300\026\265 +\110\001\175\351\371\012\377\033\345\152\151\277\170\041\250\302 +\247\043\251\206\253\166\126\350\016\014\366\023\335\052\146\212 +\144\111\075\032\030\207\220\004\237\102\122\267\117\313\376\107 +\101\166\065\357\377\000\166\066\105\062\233\306\106\205\135\342 +\044\260\036\343\110\226\230\127\107\224\125\172\017\101\261\104 +\044\363\301\376\032\153\277\210\375\301\246\332\223\140\136\201 +\112\231\040\234\110\146\031\265\000\171\124\017\270\054\057\113 +\274\251\135\133\140\177\214\207\245\340\122\143\052\276\330\073 +\205\100\025\376\036\266\145\077\305\113\332\176\265\172\065\051 +\243\056\172\230\140\042\243\364\175\047\116\055\352\264\164\074 +\351\017\244\063\017\020\021\274\023\001\326\345\016\323\277\265 +\022\242\341\105\043\300\314\010\156\141\267\211\253\203\343\044 +\036\346\135\007\347\037\040\076\317\147\310\347\254\060\155\047 +\113\150\156\113\052\134\002\010\064\333\370\166\344\147\243\046 +\234\077\242\062\302\112\305\201\030\061\020\126\252\204\357\055 +\012\377\270\037\167\322\277\245\130\240\142\344\327\113\221\165 +\215\211\200\230\176\155\313\123\116\136\257\366\262\227\205\227 +\271\332\125\006\271\044\356\327\306\070\036\143\033\022\073\225 +\341\130\254\362\337\204\325\137\231\057\015\125\133\346\070\333 +\056\077\162\351\110\205\313\273\051\023\217\036\070\125\271\363 +\262\304\060\231\043\116\135\362\110\241\022\014\334\022\220\011 +\220\124\221\003\074\107\345\325\311\145\340\267\113\175\354\107 +\323\263\013\076\255\236\320\164\000\016\353\275\121\255\300\336 +\054\300\303\152\376\357\334\013\247\372\106\337\140\333\234\246 +\131\120\165\043\151\163\223\262\371\374\002\323\107\346\161\316 +\020\002\356\047\214\204\377\254\105\015\023\134\203\062\340\045 +\245\206\054\174\364\022 +END + +# Trust for Certificate "Taiwan GRCA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Taiwan GRCA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\364\213\021\277\336\253\276\224\124\040\161\346\101\336\153\276 +\210\053\100\271 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\067\205\104\123\062\105\037\040\360\363\225\341\045\304\103\116 +END +CKA_ISSUER MULTILINE_OCTAL +\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156 +\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343 +\136\366 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Firmaprofesional Root CA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Firmaprofesional Root CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123 +\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165 +\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145 +\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101 +\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 +\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101 +\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206 +\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155 +\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123 +\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165 +\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145 +\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101 +\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 +\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101 +\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206 +\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155 +\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\004\127\060\202\003\077\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061 +\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156 +\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154 +\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165 +\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151 +\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162 +\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066 +\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110 +\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141 +\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060 +\036\027\015\060\061\061\060\062\064\062\062\060\060\060\060\132 +\027\015\061\063\061\060\062\064\062\062\060\060\060\060\132\060 +\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061 +\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156 +\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154 +\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165 +\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151 +\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162 +\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066 +\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110 +\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141 +\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060 +\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001 +\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000 +\347\043\003\157\157\043\245\136\170\316\225\054\355\224\036\156 +\012\236\001\307\352\060\321\054\235\335\067\350\233\230\171\126 +\323\374\163\337\320\212\336\125\217\121\371\132\352\336\265\160 +\304\355\244\355\377\243\015\156\017\144\120\061\257\001\047\130 +\256\376\154\247\112\057\027\055\323\163\325\023\034\217\131\245 +\064\054\035\124\004\105\315\150\270\240\300\003\245\317\205\102 +\107\225\050\133\317\357\200\154\340\220\227\212\001\074\035\363 +\207\020\060\046\110\175\327\374\351\235\221\161\377\101\232\251 +\100\265\067\234\051\040\117\037\122\343\240\175\023\155\124\267 +\012\336\351\152\116\007\254\254\031\137\334\176\142\164\366\262 +\005\000\272\205\240\375\035\070\156\313\132\273\206\274\224\147 +\063\065\203\054\037\043\315\370\310\221\161\314\227\213\357\256 +\017\334\051\003\033\300\071\353\160\355\301\156\016\330\147\013 +\211\251\274\065\344\357\266\064\264\245\266\304\055\245\276\320 +\303\224\044\110\333\337\226\323\000\265\146\032\213\146\005\017 +\335\077\077\313\077\252\136\232\112\370\264\112\357\225\067\033 +\002\003\001\000\001\243\201\237\060\201\234\060\052\006\003\125 +\035\021\004\043\060\041\206\037\150\164\164\160\072\057\057\167 +\167\167\056\146\151\162\155\141\160\162\157\146\145\163\151\157 +\156\141\154\056\143\157\155\060\022\006\003\125\035\023\001\001 +\377\004\010\060\006\001\001\377\002\001\001\060\053\006\003\125 +\035\020\004\044\060\042\200\017\062\060\060\061\061\060\062\064 +\062\062\060\060\060\060\132\201\017\062\060\061\063\061\060\062 +\064\062\062\060\060\060\060\132\060\016\006\003\125\035\017\001 +\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016\004 +\026\004\024\063\013\240\146\321\352\332\316\336\142\223\004\050 +\122\265\024\177\070\150\267\060\015\006\011\052\206\110\206\367 +\015\001\001\005\005\000\003\202\001\001\000\107\163\376\215\047 +\124\360\365\324\167\234\047\171\127\127\267\025\126\354\307\330 +\130\267\001\002\364\063\355\223\120\210\236\174\106\261\275\077 +\024\157\361\263\107\110\213\214\227\006\327\352\176\243\134\052 +\273\115\057\107\342\370\071\006\311\234\056\061\032\003\170\364 +\274\070\306\042\213\063\061\360\026\004\004\175\371\166\344\113 +\327\300\346\203\354\131\314\077\336\377\117\153\267\147\176\246 +\206\201\062\043\003\235\310\367\137\301\112\140\245\222\251\261 +\244\240\140\303\170\207\263\042\363\052\353\133\251\355\005\253 +\067\017\261\342\323\225\166\143\126\164\214\130\162\033\067\345 +\144\241\276\115\014\223\230\014\227\366\207\155\263\077\347\313 +\200\246\355\210\307\137\120\142\002\350\231\164\026\320\346\264 +\071\361\047\313\310\100\326\343\206\020\251\043\022\222\340\151 +\101\143\247\257\045\013\300\305\222\313\036\230\243\132\272\305 +\063\017\240\227\001\335\177\340\173\326\006\124\317\241\342\115 +\070\353\113\120\265\313\046\364\312\332\160\112\152\241\342\171 +\252\341\247\063\366\375\112\037\366\331\140 +END + +# Trust for Certificate "Firmaprofesional Root CA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Firmaprofesional Root CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\251\142\217\113\230\251\033\110\065\272\322\301\106\062\206\273 +\146\144\152\214 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\021\222\171\100\074\261\203\100\345\253\146\112\147\222\200\337 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123 +\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165 +\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145 +\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101 +\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 +\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101 +\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206 +\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155 +\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_VALID +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Wells Fargo Root CA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Wells Fargo Root CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163 +\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023 +\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127 +\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040 +\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150 +\157\162\151\164\171 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163 +\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023 +\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127 +\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040 +\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150 +\157\162\151\164\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\071\344\227\236 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\003\345\060\202\002\315\240\003\002\001\002\002\004\071 +\344\227\236\060\015\006\011\052\206\110\206\367\015\001\001\005 +\005\000\060\201\202\061\013\060\011\006\003\125\004\006\023\002 +\125\123\061\024\060\022\006\003\125\004\012\023\013\127\145\154 +\154\163\040\106\141\162\147\157\061\054\060\052\006\003\125\004 +\013\023\043\127\145\154\154\163\040\106\141\162\147\157\040\103 +\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 +\150\157\162\151\164\171\061\057\060\055\006\003\125\004\003\023 +\046\127\145\154\154\163\040\106\141\162\147\157\040\122\157\157 +\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165 +\164\150\157\162\151\164\171\060\036\027\015\060\060\061\060\061 +\061\061\066\064\061\062\070\132\027\015\062\061\060\061\061\064 +\061\066\064\061\062\070\132\060\201\202\061\013\060\011\006\003 +\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004\012 +\023\013\127\145\154\154\163\040\106\141\162\147\157\061\054\060 +\052\006\003\125\004\013\023\043\127\145\154\154\163\040\106\141 +\162\147\157\040\103\145\162\164\151\146\151\143\141\164\151\157 +\156\040\101\165\164\150\157\162\151\164\171\061\057\060\055\006 +\003\125\004\003\023\046\127\145\154\154\163\040\106\141\162\147 +\157\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 +\164\145\040\101\165\164\150\157\162\151\164\171\060\202\001\042 +\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 +\202\001\017\000\060\202\001\012\002\202\001\001\000\325\250\063 +\073\046\371\064\377\315\233\176\345\004\107\316\000\342\175\167 +\347\061\302\056\047\245\115\150\271\061\272\215\103\131\227\307 +\163\252\177\075\134\100\236\005\345\241\342\211\331\114\270\077 +\233\371\014\264\310\142\031\054\105\256\221\036\163\161\101\304 +\113\023\375\160\302\045\254\042\365\165\013\267\123\344\245\053 +\335\316\275\034\072\172\303\367\023\217\046\124\234\026\153\153 +\257\373\330\226\261\140\232\110\340\045\042\044\171\064\316\016 +\046\000\013\116\253\375\213\316\202\327\057\010\160\150\301\250 +\012\371\164\117\007\253\244\371\342\203\176\047\163\164\076\270 +\371\070\102\374\245\250\133\110\043\263\353\343\045\262\200\256 +\226\324\012\234\302\170\232\306\150\030\256\067\142\067\136\121 +\165\250\130\143\300\121\356\100\170\176\250\257\032\240\341\260 +\170\235\120\214\173\347\263\374\216\043\260\333\145\000\160\204 +\001\010\000\024\156\124\206\232\272\314\371\067\020\366\340\336 +\204\055\235\244\205\067\323\207\343\025\320\301\027\220\176\031 +\041\152\022\251\166\375\022\002\351\117\041\136\027\002\003\001 +\000\001\243\141\060\137\060\017\006\003\125\035\023\001\001\377 +\004\005\060\003\001\001\377\060\114\006\003\125\035\040\004\105 +\060\103\060\101\006\013\140\206\110\001\206\373\173\207\007\001 +\013\060\062\060\060\006\010\053\006\001\005\005\007\002\001\026 +\044\150\164\164\160\072\057\057\167\167\167\056\167\145\154\154 +\163\146\141\162\147\157\056\143\157\155\057\143\145\162\164\160 +\157\154\151\143\171\060\015\006\011\052\206\110\206\367\015\001 +\001\005\005\000\003\202\001\001\000\322\047\335\234\012\167\053 +\273\042\362\002\265\112\112\221\371\321\055\276\344\273\032\150 +\357\016\244\000\351\356\347\357\356\366\371\345\164\244\302\330 +\122\130\304\164\373\316\153\265\073\051\171\030\132\357\233\355 +\037\153\066\356\110\045\045\024\266\126\242\020\350\356\247\177 +\320\077\243\320\303\135\046\356\007\314\303\301\044\041\207\036 +\337\052\022\123\157\101\026\347\355\256\224\372\214\162\372\023 +\107\360\074\176\256\175\021\072\023\354\355\372\157\162\144\173 +\235\175\177\046\375\172\373\045\255\352\076\051\177\114\343\000 +\127\062\260\263\351\355\123\027\331\213\262\024\016\060\350\345 +\325\023\306\144\257\304\000\325\330\130\044\374\365\217\354\361 +\307\175\245\333\017\047\321\306\362\100\210\346\037\366\141\250 +\364\102\310\271\067\323\251\276\054\126\170\302\162\233\131\135 +\065\100\212\350\116\143\032\266\351\040\152\121\342\316\244\220 +\337\166\160\231\134\160\103\115\267\266\247\031\144\116\222\267 +\305\221\074\177\110\026\145\173\026\375\313\374\373\331\325\326 +\117\041\145\073\112\177\107\243\373 +END + +# Trust for Certificate "Wells Fargo Root CA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Wells Fargo Root CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\223\346\253\042\003\003\265\043\050\334\332\126\236\272\344\321 +\321\314\373\145 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\040\013\112\172\210\247\251\102\206\212\137\164\126\173\210\005 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163 +\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023 +\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127 +\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040 +\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150 +\157\162\151\164\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\071\344\227\236 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Swisscom Root CA 1" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Swisscom Root CA 1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 +\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 +\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 +\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 +\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 +\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 +\164\040\103\101\040\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 +\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 +\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 +\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 +\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 +\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 +\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235 +\250\066 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\331\060\202\003\301\240\003\002\001\002\002\020\134 +\013\205\134\013\347\131\101\337\127\314\077\177\235\250\066\060 +\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\144 +\061\013\060\011\006\003\125\004\006\023\002\143\150\061\021\060 +\017\006\003\125\004\012\023\010\123\167\151\163\163\143\157\155 +\061\045\060\043\006\003\125\004\013\023\034\104\151\147\151\164 +\141\154\040\103\145\162\164\151\146\151\143\141\164\145\040\123 +\145\162\166\151\143\145\163\061\033\060\031\006\003\125\004\003 +\023\022\123\167\151\163\163\143\157\155\040\122\157\157\164\040 +\103\101\040\061\060\036\027\015\060\065\060\070\061\070\061\062 +\060\066\062\060\132\027\015\062\065\060\070\061\070\062\062\060 +\066\062\060\132\060\144\061\013\060\011\006\003\125\004\006\023 +\002\143\150\061\021\060\017\006\003\125\004\012\023\010\123\167 +\151\163\163\143\157\155\061\045\060\043\006\003\125\004\013\023 +\034\104\151\147\151\164\141\154\040\103\145\162\164\151\146\151 +\143\141\164\145\040\123\145\162\166\151\143\145\163\061\033\060 +\031\006\003\125\004\003\023\022\123\167\151\163\163\143\157\155 +\040\122\157\157\164\040\103\101\040\061\060\202\002\042\060\015 +\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 +\017\000\060\202\002\012\002\202\002\001\000\320\271\260\250\014 +\331\273\077\041\370\033\325\063\223\200\026\145\040\165\262\075 +\233\140\155\106\310\214\061\157\027\303\372\232\154\126\355\074 +\305\221\127\303\315\253\226\111\220\052\031\113\036\243\155\127 +\335\361\053\142\050\165\105\136\252\326\133\372\013\045\330\241 +\026\371\034\304\056\346\225\052\147\314\320\051\156\074\205\064 +\070\141\111\261\000\237\326\072\161\137\115\155\316\137\271\251 +\344\211\177\152\122\372\312\233\362\334\251\371\235\231\107\077 +\116\051\137\264\246\215\135\173\013\231\021\003\003\376\347\333 +\333\243\377\035\245\315\220\036\001\037\065\260\177\000\333\220 +\157\306\176\173\321\356\172\172\247\252\014\127\157\244\155\305 +\023\073\260\245\331\355\062\034\264\136\147\213\124\334\163\207 +\345\323\027\174\146\120\162\135\324\032\130\301\331\317\330\211 +\002\157\247\111\264\066\135\320\244\336\007\054\266\165\267\050 +\221\326\227\276\050\365\230\036\352\133\046\311\275\260\227\163 +\332\256\221\046\353\150\301\371\071\025\326\147\113\012\155\117 +\313\317\260\344\102\161\214\123\171\347\356\341\333\035\240\156 +\035\214\032\167\065\134\026\036\053\123\037\064\213\321\154\374 +\362\147\007\172\365\255\355\326\232\253\241\261\113\341\314\067 +\137\375\177\315\115\256\270\037\234\103\371\052\130\125\103\105 +\274\226\315\160\016\374\311\343\146\272\116\215\073\201\313\025 +\144\173\271\224\350\135\063\122\205\161\056\117\216\242\006\021 +\121\311\343\313\241\156\061\010\144\014\302\322\074\365\066\350 +\327\320\016\170\043\040\221\311\044\052\145\051\133\042\367\041 +\316\203\136\244\363\336\113\323\150\217\106\165\134\203\011\156 +\051\153\304\160\214\365\235\327\040\057\377\106\322\053\070\302 +\057\165\034\075\176\332\245\357\036\140\205\151\102\323\314\370 +\143\376\036\103\071\205\246\266\143\101\020\263\163\036\274\323 +\372\312\175\026\107\342\247\325\320\243\212\012\010\226\142\126 +\156\064\333\331\002\271\060\165\343\004\322\347\217\302\260\021 +\100\012\254\325\161\002\142\213\061\276\335\306\043\130\061\102 +\103\055\164\371\306\236\246\212\017\351\376\277\203\346\103\127 +\044\272\357\106\064\252\327\022\001\070\355\002\003\001\000\001 +\243\201\206\060\201\203\060\016\006\003\125\035\017\001\001\377 +\004\004\003\002\001\206\060\035\006\003\125\035\041\004\026\060 +\024\060\022\006\007\140\205\164\001\123\000\001\006\007\140\205 +\164\001\123\000\001\060\022\006\003\125\035\023\001\001\377\004 +\010\060\006\001\001\377\002\001\007\060\037\006\003\125\035\043 +\004\030\060\026\200\024\003\045\057\336\157\202\001\072\134\054 +\334\053\241\151\265\147\324\214\323\375\060\035\006\003\125\035 +\016\004\026\004\024\003\045\057\336\157\202\001\072\134\054\334 +\053\241\151\265\147\324\214\323\375\060\015\006\011\052\206\110 +\206\367\015\001\001\005\005\000\003\202\002\001\000\065\020\313 +\354\246\004\015\015\017\315\300\333\253\250\362\210\227\014\337 +\223\057\115\174\100\126\061\172\353\244\017\140\315\172\363\276 +\303\047\216\003\076\244\335\022\357\176\036\164\006\074\077\061 +\362\034\173\221\061\041\264\360\320\154\227\324\351\227\262\044 +\126\036\126\303\065\275\210\005\017\133\020\032\144\341\307\202 +\060\371\062\255\236\120\054\347\170\005\320\061\261\132\230\212 +\165\116\220\134\152\024\052\340\122\107\202\140\346\036\332\201 +\261\373\024\013\132\361\237\322\225\272\076\320\033\326\025\035 +\243\276\206\325\333\017\300\111\144\273\056\120\031\113\322\044 +\370\335\036\007\126\320\070\240\225\160\040\166\214\327\335\036 +\336\237\161\304\043\357\203\023\134\243\044\025\115\051\100\074 +\152\304\251\330\267\246\104\245\015\364\340\235\167\036\100\160 +\046\374\332\331\066\344\171\344\265\077\274\233\145\276\273\021 +\226\317\333\306\050\071\072\010\316\107\133\123\132\305\231\376 +\135\251\335\357\114\324\306\245\255\002\346\214\007\022\036\157 +\003\321\157\240\243\363\051\275\022\307\120\242\260\177\210\251 +\231\167\232\261\300\245\071\056\134\174\151\342\054\260\352\067 +\152\244\341\132\341\365\120\345\203\357\245\273\052\210\347\214 +\333\375\155\136\227\031\250\176\146\165\153\161\352\277\261\307 +\157\240\364\216\244\354\064\121\133\214\046\003\160\241\167\325 +\001\022\127\000\065\333\043\336\016\212\050\231\375\261\020\157 +\113\377\070\055\140\116\054\234\353\147\265\255\111\356\113\037 +\254\257\373\015\220\132\146\140\160\135\252\315\170\324\044\356 +\310\101\240\223\001\222\234\152\236\374\271\044\305\263\025\202 +\176\276\256\225\053\353\261\300\332\343\001\140\013\136\151\254 +\204\126\141\276\161\027\376\035\023\017\376\306\207\105\351\376 +\062\240\032\015\023\244\224\125\161\245\026\213\272\312\211\260 +\262\307\374\217\330\124\265\223\142\235\316\317\131\373\075\030 +\316\052\313\065\025\202\135\377\124\042\133\161\122\373\267\311 +\376\140\233\000\101\144\360\252\052\354\266\102\103\316\211\146 +\201\310\213\237\071\124\003\045\323\026\065\216\204\320\137\372 +\060\032\365\232\154\364\016\123\371\072\133\321\034 +END + +# Trust for Certificate "Swisscom Root CA 1" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Swisscom Root CA 1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\137\072\374\012\213\144\366\206\147\064\164\337\176\251\242\376 +\371\372\172\121 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\370\070\174\167\210\337\054\026\150\056\302\342\122\113\270\371 +END +CKA_ISSUER MULTILINE_OCTAL +\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 +\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 +\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 +\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 +\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 +\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 +\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235 +\250\066 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE diff --git a/security/nss/lib/ckfw/builtins/constants.c b/security/nss/lib/ckfw/builtins/constants.c index a4a8bc7c7..6cc62c0e8 100644 --- a/security/nss/lib/ckfw/builtins/constants.c +++ b/security/nss/lib/ckfw/builtins/constants.c @@ -62,7 +62,7 @@ nss_builtins_CryptokiVersion = { NSS_BUILTINS_CRYPTOKI_VERSION_MINOR }; NSS_IMPLEMENT_DATA const NSSUTF8 * -nss_builtins_ManufacturerID = (NSSUTF8 *) "Netscape Communications Corp."; +nss_builtins_ManufacturerID = (NSSUTF8 *) "Mozilla Foundation"; NSS_IMPLEMENT_DATA const NSSUTF8 * nss_builtins_LibraryDescription = (NSSUTF8 *) "NSS Builtin Object Cryptoki Module"; diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h index b0378eea9..9397c2710 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.h +++ b/security/nss/lib/ckfw/builtins/nssckbi.h @@ -75,8 +75,8 @@ * of the comment in the CK_VERSION type definition. */ #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1 -#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 60 -#define NSS_BUILTINS_LIBRARY_VERSION "1.60" +#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 62 +#define NSS_BUILTINS_LIBRARY_VERSION "1.62" /* These version numbers detail the semantic changes to the ckfw engine. */ #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 diff --git a/security/nss/lib/ckfw/builtins/nssckbi.rc b/security/nss/lib/ckfw/builtins/nssckbi.rc index 1ff4fa9c1..2d30b880c 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.rc +++ b/security/nss/lib/ckfw/builtins/nssckbi.rc @@ -80,11 +80,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_BUILTINS_LIBRARY_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_BUILTINS_LIBRARY_VERSION "\0" diff --git a/security/nss/lib/ckfw/capi/nsscapi.rc b/security/nss/lib/ckfw/capi/nsscapi.rc index d5024f7a6..254599f75 100644 --- a/security/nss/lib/ckfw/capi/nsscapi.rc +++ b/security/nss/lib/ckfw/capi/nsscapi.rc @@ -84,7 +84,6 @@ BEGIN VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_CKCAPI_LIBRARY_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2005 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_CKCAPI_LIBRARY_VERSION "\0" diff --git a/security/nss/lib/ckfw/dbm/Makefile b/security/nss/lib/ckfw/dbm/Makefile index bc6c17f1a..0df6bf84e 100644 --- a/security/nss/lib/ckfw/dbm/Makefile +++ b/security/nss/lib/ckfw/dbm/Makefile @@ -1,35 +1,39 @@ # -# 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. -# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# 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. -# +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1994-2000 +# the Initial Developer. 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. # +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$" include manifest.mn diff --git a/security/nss/lib/ckfw/dbm/anchor.c b/security/nss/lib/ckfw/dbm/anchor.c index 6f6137a3c..26f5a3fc6 100644 --- a/security/nss/lib/ckfw/dbm/anchor.c +++ b/security/nss/lib/ckfw/dbm/anchor.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/ckdbm.h b/security/nss/lib/ckfw/dbm/ckdbm.h index a38850a0f..d0b723c14 100644 --- a/security/nss/lib/ckfw/dbm/ckdbm.h +++ b/security/nss/lib/ckfw/dbm/ckdbm.h @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CKDBM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/config.mk b/security/nss/lib/ckfw/dbm/config.mk index 63eb61689..a885d8663 100644 --- a/security/nss/lib/ckfw/dbm/config.mk +++ b/security/nss/lib/ckfw/dbm/config.mk @@ -1,35 +1,39 @@ # -# 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. -# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# 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. -# +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1994-2000 +# the Initial Developer. 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. # +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$" ifdef BUILD_IDG diff --git a/security/nss/lib/ckfw/dbm/db.c b/security/nss/lib/ckfw/dbm/db.c index 83d933a67..6abdce6af 100644 --- a/security/nss/lib/ckfw/dbm/db.c +++ b/security/nss/lib/ckfw/dbm/db.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/find.c b/security/nss/lib/ckfw/dbm/find.c index 929142af8..6979e029b 100644 --- a/security/nss/lib/ckfw/dbm/find.c +++ b/security/nss/lib/ckfw/dbm/find.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/instance.c b/security/nss/lib/ckfw/dbm/instance.c index b87625f55..f1fced615 100644 --- a/security/nss/lib/ckfw/dbm/instance.c +++ b/security/nss/lib/ckfw/dbm/instance.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; @@ -119,7 +122,7 @@ nss_dbm_mdInstance_GetManufacturerID CK_RV *pError ) { - return "Netscape Communications Corp."; + return "Mozilla Foundation"; } static NSSUTF8 * diff --git a/security/nss/lib/ckfw/dbm/manifest.mn b/security/nss/lib/ckfw/dbm/manifest.mn index ff4b408ca..0bee9e620 100644 --- a/security/nss/lib/ckfw/dbm/manifest.mn +++ b/security/nss/lib/ckfw/dbm/manifest.mn @@ -1,35 +1,39 @@ # -# 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. -# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# 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. -# +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1994-2000 +# the Initial Developer. 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. # +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$" CORE_DEPTH = ../../../.. diff --git a/security/nss/lib/ckfw/dbm/object.c b/security/nss/lib/ckfw/dbm/object.c index bf85447ad..1a8f76ed3 100644 --- a/security/nss/lib/ckfw/dbm/object.c +++ b/security/nss/lib/ckfw/dbm/object.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/session.c b/security/nss/lib/ckfw/dbm/session.c index 8ce140641..371a94adc 100644 --- a/security/nss/lib/ckfw/dbm/session.c +++ b/security/nss/lib/ckfw/dbm/session.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/slot.c b/security/nss/lib/ckfw/dbm/slot.c index 800815cf7..e43700c75 100644 --- a/security/nss/lib/ckfw/dbm/slot.c +++ b/security/nss/lib/ckfw/dbm/slot.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/token.c b/security/nss/lib/ckfw/dbm/token.c index ed958ec31..16bd2b3fc 100644 --- a/security/nss/lib/ckfw/dbm/token.c +++ b/security/nss/lib/ckfw/dbm/token.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. - * + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. 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. - */ + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/find.c b/security/nss/lib/ckfw/find.c index fe9345b42..747c79ef9 100644 --- a/security/nss/lib/ckfw/find.c +++ b/security/nss/lib/ckfw/find.c @@ -176,22 +176,24 @@ nssCKFWFindObjects_Create return fwFindObjects; loser: - nss_ZFreeIf(fwFindObjects); - - if( (NSSCKMDFindObjects *)NULL != mdFindObjects1 ) { - if( (void *)NULL != (void *)mdFindObjects1->Final ) { - fwFindObjects->mdFindObjects = mdFindObjects1; - mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession, - fwSession, mdToken, fwToken, mdInstance, fwInstance); + if( fwFindObjects ) { + if( NULL != mdFindObjects1 ) { + if( NULL != mdFindObjects1->Final ) { + fwFindObjects->mdFindObjects = mdFindObjects1; + mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession, + fwSession, mdToken, fwToken, mdInstance, fwInstance); + } } - } - if( (NSSCKMDFindObjects *)NULL != mdFindObjects2 ) { - if( (void *)NULL != (void *)mdFindObjects2->Final ) { - fwFindObjects->mdFindObjects = mdFindObjects2; - mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession, - fwSession, mdToken, fwToken, mdInstance, fwInstance); + if( NULL != mdFindObjects2 ) { + if( NULL != mdFindObjects2->Final ) { + fwFindObjects->mdFindObjects = mdFindObjects2; + mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession, + fwSession, mdToken, fwToken, mdInstance, fwInstance); + } } + + nss_ZFreeIf(fwFindObjects); } if( CKR_OK == *pError ) { diff --git a/security/nss/lib/ckfw/session.c b/security/nss/lib/ckfw/session.c index b2a85d75c..2b020d77e 100644 --- a/security/nss/lib/ckfw/session.c +++ b/security/nss/lib/ckfw/session.c @@ -234,7 +234,7 @@ nssCKFWSession_Create loser: if( (NSSArena *)NULL != arena ) { - if( (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) { + if( fwSession && (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) { (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash); } NSSArena_Destroy(arena); diff --git a/security/nss/lib/ckfw/wrap.c b/security/nss/lib/ckfw/wrap.c index b9af321a3..3ffded1f0 100644 --- a/security/nss/lib/ckfw/wrap.c +++ b/security/nss/lib/ckfw/wrap.c @@ -647,7 +647,8 @@ NSSCKFWC_GetTokenInfo switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_CRYPTOKI_NOT_INITIALIZED: case CKR_DEVICE_ERROR: @@ -841,7 +842,8 @@ NSSCKFWC_GetMechanismList switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_BUFFER_TOO_SMALL: case CKR_CRYPTOKI_NOT_INITIALIZED: @@ -944,7 +946,8 @@ NSSCKFWC_GetMechanismInfo switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_CRYPTOKI_NOT_INITIALIZED: case CKR_DEVICE_ERROR: @@ -1034,7 +1037,8 @@ NSSCKFWC_InitToken switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_CRYPTOKI_NOT_INITIALIZED: case CKR_DEVICE_ERROR: diff --git a/security/nss/lib/crmf/challcli.c b/security/nss/lib/crmf/challcli.c index 47b390917..a567452d5 100644 --- a/security/nss/lib/crmf/challcli.c +++ b/security/nss/lib/crmf/challcli.c @@ -122,54 +122,39 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, { CMMFChallenge *challenge; SECItem *decryptedRand=NULL; + PRArenaPool *poolp = NULL; SECAlgorithmID *owf; - PK11SlotInfo *slot; - PK11SymKey *symKey = NULL; SECStatus rv = SECFailure; + SECOidTag tag; CMMFRand randStr; SECItem hashItem; - SECOidTag tag; unsigned char hash[HASH_LENGTH_MAX]; - PRArenaPool *poolp = NULL; PORT_Assert(inChalCont != NULL && inPrivKey != NULL); if (inChalCont == NULL || inIndex <0 || inIndex > inChalCont->numChallenges || inPrivKey == NULL){ return SECFailure; } - challenge = inChalCont->challenges[inIndex]; - decryptedRand = PORT_ZNew(SECItem); - if (decryptedRand == NULL) { + + poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); + if (poolp == NULL) { goto loser; } - decryptedRand->data = - PORT_NewArray(unsigned char, challenge->challenge.len); - if (decryptedRand->data == NULL) { + + challenge = inChalCont->challenges[inIndex]; + decryptedRand = SECITEM_AllocItem(poolp, NULL, challenge->challenge.len); + if (decryptedRand == NULL) { goto loser; } - slot = inPrivKey->pkcs11Slot; - symKey = PK11_PubUnwrapSymKey(inPrivKey, &challenge->challenge, - CKM_RSA_PKCS, CKA_VALUE, 0); - if (symKey == NULL) { - rv = SECFailure; - goto loser; - } - rv = PK11_ExtractKeyValue(symKey); + rv = PK11_PrivDecryptPKCS1(inPrivKey, decryptedRand->data, + &decryptedRand->len, decryptedRand->len, + challenge->challenge.data, challenge->challenge.len); if (rv != SECSuccess) { - goto loser; - } - decryptedRand = PK11_GetKeyData(symKey); - - poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); - if (poolp == NULL) { goto loser; } + rv = SEC_ASN1DecodeItem(poolp, &randStr, CMMFRandTemplate, decryptedRand); - /* The decryptedRand returned points to a member within the symKey - * structure, so we don't want to free it. Let the symKey destruction - * function deal with freeing that memory. - */ if (rv != SECSuccess) { goto loser; } @@ -196,6 +181,7 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, /* The hash for the data we decrypted doesn't match the hash provided * in the challenge. Bail out. */ + PORT_SetError(SEC_ERROR_BAD_DATA); rv = SECFailure; goto loser; } @@ -208,6 +194,7 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, /* The hash for the data we decrypted doesn't match the hash provided * in the challenge. Bail out. */ + PORT_SetError(SEC_ERROR_BAD_DATA); rv = SECFailure; goto loser; } @@ -215,9 +202,6 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, rv = SECITEM_CopyItem(inChalCont->poolp, &challenge->randomNumber, &randStr.integer); loser: - if (symKey != NULL) { - PK11_FreeSymKey(symKey); - } if (poolp) { PORT_FreeArena(poolp, PR_FALSE); } @@ -275,7 +259,10 @@ CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand, if (currItem == NULL) { goto loser; } - SEC_ASN1EncodeInteger(poolp, currItem,inDecodedRand[i]); + currItem = SEC_ASN1EncodeInteger(poolp, currItem, inDecodedRand[i]); + if (currItem == NULL) { + goto loser; + } } rv = cmmf_user_encode(response, inCallback, inArg, CMMFPOPODecKeyRespContentTemplate); diff --git a/security/nss/lib/crmf/crmf.h b/security/nss/lib/crmf/crmf.h index d09163ae1..315100702 100644 --- a/security/nss/lib/crmf/crmf.h +++ b/security/nss/lib/crmf/crmf.h @@ -208,7 +208,7 @@ extern SECStatus CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg, * A pointer to the new Certificate Request. A NULL return value * indicates an error in creating the Certificate Request. */ -extern CRMFCertRequest *CRMF_CreateCertRequest (long inRequestID); +extern CRMFCertRequest *CRMF_CreateCertRequest (PRUint32 inRequestID); /* * FUNCTION: CRMF_DestroyCertRequest diff --git a/security/nss/lib/crmf/crmfcont.c b/security/nss/lib/crmf/crmfcont.c index b609e84ea..f2cab57b3 100644 --- a/security/nss/lib/crmf/crmfcont.c +++ b/security/nss/lib/crmf/crmfcont.c @@ -148,21 +148,27 @@ crmf_destroy_encrypted_value(CRMFEncryptedValue *inEncrValue, PRBool freeit) if (inEncrValue != NULL) { if (inEncrValue->intendedAlg) { SECOID_DestroyAlgorithmID(inEncrValue->intendedAlg, PR_TRUE); + inEncrValue->intendedAlg = NULL; } if (inEncrValue->symmAlg) { SECOID_DestroyAlgorithmID(inEncrValue->symmAlg, PR_TRUE); + inEncrValue->symmAlg = NULL; } if (inEncrValue->encSymmKey.data) { PORT_Free(inEncrValue->encSymmKey.data); + inEncrValue->encSymmKey.data = NULL; } if (inEncrValue->keyAlg) { SECOID_DestroyAlgorithmID(inEncrValue->keyAlg, PR_TRUE); + inEncrValue->keyAlg = NULL; } if (inEncrValue->valueHint.data) { PORT_Free(inEncrValue->valueHint.data); + inEncrValue->valueHint.data = NULL; } if (inEncrValue->encValue.data) { PORT_Free(inEncrValue->encValue.data); + inEncrValue->encValue.data = NULL; } if (freeit) { PORT_Free(inEncrValue); @@ -183,15 +189,24 @@ crmf_copy_encryptedvalue_secalg(PRArenaPool *poolp, SECAlgorithmID **destAlgId) { SECAlgorithmID *newAlgId; + SECStatus rv; - *destAlgId = newAlgId = (poolp != NULL) ? - PORT_ArenaZNew(poolp, SECAlgorithmID) : - PORT_ZNew(SECAlgorithmID); + newAlgId = (poolp != NULL) ? PORT_ArenaZNew(poolp, SECAlgorithmID) : + PORT_ZNew(SECAlgorithmID); if (newAlgId == NULL) { return SECFailure; } - return SECOID_CopyAlgorithmID(poolp, newAlgId, srcAlgId); + rv = SECOID_CopyAlgorithmID(poolp, newAlgId, srcAlgId); + if (rv != SECSuccess) { + if (!poolp) { + SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE); + } + return rv; + } + *destAlgId = newAlgId; + + return rv; } SECStatus @@ -252,7 +267,7 @@ crmf_copy_encryptedvalue(PRArenaPool *poolp, return SECSuccess; loser: if (poolp == NULL && destValue != NULL) { - crmf_destroy_encrypted_value(destValue, PR_TRUE); + crmf_destroy_encrypted_value(destValue, PR_FALSE); } return SECFailure; } diff --git a/security/nss/lib/crmf/crmfit.h b/security/nss/lib/crmf/crmfit.h index 1edde840b..2f9be4946 100644 --- a/security/nss/lib/crmf/crmfit.h +++ b/security/nss/lib/crmf/crmfit.h @@ -140,7 +140,7 @@ struct CRMFCertRequestStr { * are not part of the encoding. */ PRArenaPool *poolp; - long requestID; /* This is the value that will be encoded into + PRUint32 requestID; /* This is the value that will be encoded into * the certReqId field. */ }; diff --git a/security/nss/lib/crmf/crmfpop.c b/security/nss/lib/crmf/crmfpop.c index e105a90a8..06d5f467f 100644 --- a/security/nss/lib/crmf/crmfpop.c +++ b/security/nss/lib/crmf/crmfpop.c @@ -94,35 +94,14 @@ CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg) } SECOidTag -crmf_map_keytag_to_signtag(SECOidTag inTag) -{ - switch (inTag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_DSS: - return SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; - default: - /* Put this in here to kill warnings. */ - break; - } - return inTag; -} - -SECOidTag crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey) { - CERTSubjectPublicKeyInfo *spki; - SECOidTag tag; - - spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey); - if (spki == NULL) { - return SEC_OID_UNKNOWN; + /* maintain backward compatibility with older + * implementations */ + if (inPubKey->keyType == rsaKey) { + return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; } - tag = SECOID_GetAlgorithmTag(&spki->algorithm); - SECKEY_DestroySubjectPublicKeyInfo(spki); - return crmf_map_keytag_to_signtag(tag); + return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN); } SECAlgorithmID* @@ -206,8 +185,8 @@ crmf_sign_certreq(PRArenaPool *poolp, SECKEYPrivateKey *inKey, SECAlgorithmID *inAlgId) { - SECItem derCertReq; - SECItem certReqSig; + SECItem derCertReq = { siBuffer, NULL, 0 }; + SECItem certReqSig = { siBuffer, NULL, 0 }; SECStatus rv = SECSuccess; rv = crmf_encode_certreq(certReq, &derCertReq); @@ -282,7 +261,7 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, { SECAlgorithmID *algID; PRArenaPool *poolp; - SECItem derDest = {siBuffer, NULL, 0}; + SECItem derTemp = {siBuffer, NULL, 0}; void *mark; SECStatus rv; CRMFPOPOSigningKeyInput *signKeyInput = NULL; @@ -325,7 +304,7 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, pop->popChoice.signature.algorithmIdentifier = algID; inCertReqMsg->pop = pop; - rv = crmf_init_encoder_callback_arg (&encoderArg, &derDest); + rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp); if (rv != SECSuccess) { goto loser; } @@ -335,18 +314,18 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, if (rv != SECSuccess) { goto loser; } - rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derDest); - PORT_Free (derDest.data); + rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derTemp); if (rv != SECSuccess) { goto loser; } + PORT_Free (derTemp.data); PORT_ArenaUnmark(poolp,mark); return SECSuccess; loser: PORT_ArenaRelease(poolp,mark); - if (derDest.data != NULL) { - PORT_Free(derDest.data); + if (derTemp.data != NULL) { + PORT_Free(derTemp.data); } return SECFailure; } @@ -379,13 +358,13 @@ crmf_encode_popoprivkey(PRArenaPool *poolp, const SEC_ASN1Template *privKeyTemplate) { struct crmfEncoderArg encoderArg; - SECItem derDest; + SECItem derTemp; SECStatus rv; void *mark; const SEC_ASN1Template *subDerTemplate; mark = PORT_ArenaMark(poolp); - rv = crmf_init_encoder_callback_arg(&encoderArg, &derDest); + rv = crmf_init_encoder_callback_arg(&encoderArg, &derTemp); if (rv != SECSuccess) { goto loser; } @@ -399,32 +378,32 @@ crmf_encode_popoprivkey(PRArenaPool *poolp, if (rv != SECSuccess) { goto loser; } - if (encoderArg.allocatedLen > derDest.len+2) { - void *dummy = PORT_Realloc(derDest.data, derDest.len+2); + if (encoderArg.allocatedLen > derTemp.len+2) { + void *dummy = PORT_Realloc(derTemp.data, derTemp.len+2); if (dummy == NULL) { goto loser; } - derDest.data = dummy; + derTemp.data = dummy; } - PORT_Memmove(&derDest.data[2], &derDest.data[0], derDest.len); + PORT_Memmove(&derTemp.data[2], &derTemp.data[0], derTemp.len); /* I couldn't figure out how to get the ASN1 encoder to implicitly * tag an implicitly tagged der blob. So I'm putting in the outter- * most tag myself. -javi */ - derDest.data[0] = (unsigned char)privKeyTemplate->kind; - derDest.data[1] = (unsigned char)derDest.len; - derDest.len += 2; - rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derDest); + derTemp.data[0] = (unsigned char)privKeyTemplate->kind; + derTemp.data[1] = (unsigned char)derTemp.len; + derTemp.len += 2; + rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derTemp); if (rv != SECSuccess) { goto loser; } - PORT_Free(derDest.data); + PORT_Free(derTemp.data); PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); - if (derDest.data) { - PORT_Free(derDest.data); + if (derTemp.data) { + PORT_Free(derTemp.data); } return SECFailure; } @@ -491,6 +470,47 @@ crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey, } static SECStatus +crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac, + CRMFPOPChoice inChoice) +{ + PRArenaPool *poolp; + void *mark; + CRMFPOPOPrivKey *popoPrivKey; + CRMFProofOfPossession *pop; + SECStatus rv; + + PORT_Assert(inCertReqMsg != NULL && dhmac != NULL); + poolp = inCertReqMsg->poolp; + mark = PORT_ArenaMark(poolp); + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); + if (pop == NULL) { + goto loser; + } + pop->popUsed = inChoice; + popoPrivKey = &pop->popChoice.keyAgreement; + + rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC), + dhmac); + if (rv != SECSuccess) { + goto loser; + } + popoPrivKey->message.dhMAC.len <<= 3; + popoPrivKey->messageChoice = crmfDHMAC; + inCertReqMsg->pop = pop; + rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, + crmf_get_template_for_privkey(inChoice)); + if (rv != SECSuccess) { + goto loser; + } + PORT_ArenaUnmark(poolp, mark); + return SECSuccess; + + loser: + PORT_ArenaRelease(poolp, mark); + return SECFailure; +} + +static SECStatus crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg, CRMFSubseqMessOptions subsequentMessage, CRMFPOPChoice inChoice) @@ -599,7 +619,11 @@ CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg, crmfKeyAgreement); break; case crmfDHMAC: - /* This case should be added in the future. */ + /* In this case encPrivKey should be the calculated dhMac + * as specified in RFC 2511 */ + rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey, + crmfKeyAgreement); + break; default: rv = SECFailure; } diff --git a/security/nss/lib/crmf/crmfreq.c b/security/nss/lib/crmf/crmfreq.c index b4e06bc32..73a0548b9 100644 --- a/security/nss/lib/crmf/crmfreq.c +++ b/security/nss/lib/crmf/crmfreq.c @@ -63,6 +63,20 @@ crmf_encode_integer(PRArenaPool *poolp, SECItem *dest, long value) return SECSuccess; } +SECStatus +crmf_encode_unsigned_integer(PRArenaPool *poolp, SECItem *dest, + unsigned long value) +{ + SECItem *dummy; + + dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value); + PORT_Assert (dummy == dest); + if (dummy != dest) { + return SECFailure; + } + return SECSuccess; +} + static SECStatus crmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src) { @@ -104,7 +118,8 @@ CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq, } CRMFCertRequest * -CRMF_CreateCertRequest (long inRequestID) { +CRMF_CreateCertRequest (PRUint32 inRequestID) +{ PRArenaPool *poolp; CRMFCertRequest *certReq; SECStatus rv; @@ -122,7 +137,8 @@ CRMF_CreateCertRequest (long inRequestID) { certReq->poolp = poolp; certReq->requestID = inRequestID; - rv = crmf_encode_integer(poolp, &(certReq->certReqId), inRequestID); + rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), + inRequestID); if (rv != SECSuccess) { goto loser; } @@ -177,9 +193,12 @@ crmf_template_copy_secalg (PRArenaPool *poolp, SECAlgorithmID **dest, void *mark = NULL; SECAlgorithmID *mySecAlg; - if (poolp != NULL) { - mark = PORT_ArenaMark(poolp); + if (!poolp) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } + + mark = PORT_ArenaMark(poolp); *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID); if (mySecAlg == NULL) { goto loser; diff --git a/security/nss/lib/crmf/crmftmpl.c b/security/nss/lib/crmf/crmftmpl.c index 594feea3e..296975c96 100644 --- a/security/nss/lib/crmf/crmftmpl.c +++ b/security/nss/lib/crmf/crmftmpl.c @@ -229,7 +229,7 @@ const SEC_ASN1Template CRMFSubsequentMessageTemplate[] = { }; const SEC_ASN1Template CRMFDHMACTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, + { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, 0, SEC_ASN1_SUB(SEC_BitStringTemplate) }, { 0 } diff --git a/security/nss/lib/crmf/respcmn.c b/security/nss/lib/crmf/respcmn.c index 153ecee51..14de15db8 100644 --- a/security/nss/lib/crmf/respcmn.c +++ b/security/nss/lib/crmf/respcmn.c @@ -46,12 +46,15 @@ cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit) { if (info->status.data != NULL) { PORT_Free(info->status.data); + info->status.data = NULL; } if (info->statusString.data != NULL) { PORT_Free(info->statusString.data); + info->statusString.data = NULL; } if (info->failInfo.data != NULL) { PORT_Free(info->failInfo.data); + info->failInfo.data = NULL; } if (freeit) { PORT_Free(info); @@ -232,6 +235,7 @@ cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit) case cmmfEncryptedCert: crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert, PR_TRUE); + certOrEncCert->cert.encryptedCert = NULL; break; default: break; @@ -263,14 +267,14 @@ CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair) PORT_Assert(inCertKeyPair != NULL); if (inCertKeyPair != NULL) { cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE); + if (inCertKeyPair->privateKey) { + crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); + } + if (inCertKeyPair->derPublicationInfo.data) { + PORT_Free(inCertKeyPair->derPublicationInfo.data); + } + PORT_Free(inCertKeyPair); } - if (inCertKeyPair->privateKey) { - crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); - } - if (inCertKeyPair->derPublicationInfo.data) { - PORT_Free(inCertKeyPair->derPublicationInfo.data); - } - PORT_Free(inCertKeyPair); return SECSuccess; } @@ -292,17 +296,22 @@ cmmf_CopyCertResponse(PRArenaPool *poolp, return rv; } if (src->certifiedKeyPair != NULL) { - dest->certifiedKeyPair = (poolp == NULL) ? - PORT_ZNew(CMMFCertifiedKeyPair) : - PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair); - if (dest->certifiedKeyPair == NULL) { + CMMFCertifiedKeyPair *destKeyPair; + + destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) : + PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair); + if (!destKeyPair) { return SECFailure; } - rv = cmmf_CopyCertifiedKeyPair(poolp, dest->certifiedKeyPair, + rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair, src->certifiedKeyPair); if (rv != SECSuccess) { + if (!poolp) { + CMMF_DestroyCertifiedKeyPair(destKeyPair); + } return rv; } + dest->certifiedKeyPair = destKeyPair; } return SECSuccess; } @@ -321,16 +330,19 @@ cmmf_CopyCertOrEncCert(PRArenaPool *poolp, CMMFCertOrEncCert *dest, dest->cert.certificate = CERT_DupCertificate(src->cert.certificate); break; case cmmfEncryptedCert: - dest->cert.encryptedCert = encVal = (poolp == NULL) ? - PORT_ZNew(CRMFEncryptedValue) : - PORT_ArenaZNew(poolp, CRMFEncryptedValue); + encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : + PORT_ArenaZNew(poolp, CRMFEncryptedValue); if (encVal == NULL) { return SECFailure; } rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal); if (rv != SECSuccess) { + if (!poolp) { + crmf_destroy_encrypted_value(encVal, PR_TRUE); + } return rv; } + dest->cert.encryptedCert = encVal; break; default: rv = SECFailure; @@ -351,19 +363,22 @@ cmmf_CopyCertifiedKeyPair(PRArenaPool *poolp, CMMFCertifiedKeyPair *dest, } if (src->privateKey != NULL) { - CRMFEncryptedValue *encVal; + CRMFEncryptedValue *encVal; - encVal = dest->privateKey = (poolp == NULL) ? - PORT_ZNew(CRMFEncryptedValue) : - PORT_ArenaZNew(poolp, CRMFEncryptedValue); + encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : + PORT_ArenaZNew(poolp, CRMFEncryptedValue); if (encVal == NULL) { return SECFailure; } - rv = crmf_copy_encryptedvalue(poolp, src->privateKey, - dest->privateKey); + rv = crmf_copy_encryptedvalue(poolp, src->privateKey, + encVal); if (rv != SECSuccess) { + if (!poolp) { + crmf_destroy_encrypted_value(encVal, PR_TRUE); + } return rv; } + dest->privateKey = encVal; } rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo, &src->derPublicationInfo); diff --git a/security/nss/lib/crmf/servget.c b/security/nss/lib/crmf/servget.c index 165ce5924..85be9e556 100644 --- a/security/nss/lib/crmf/servget.c +++ b/security/nss/lib/crmf/servget.c @@ -409,7 +409,7 @@ crmf_copy_poposigningkey(PRArenaPool *poolp, } return SECSuccess; loser: - if (destPopoSignKey && poolp == NULL) { + if (poolp == NULL) { CRMF_DestroyPOPOSigningKey(destPopoSignKey); } return SECFailure; @@ -440,13 +440,10 @@ crmf_copy_popoprivkey(PRArenaPool *poolp, rv = SECFailure; } - if (rv != SECSuccess) { - if (destPrivKey && poolp == NULL) { - CRMF_DestroyPOPOPrivKey(destPrivKey); - } - return SECFailure; + if (rv != SECSuccess && poolp == NULL) { + CRMF_DestroyPOPOPrivKey(destPrivKey); } - return SECSuccess; + return rv; } static CRMFProofOfPossession* @@ -510,10 +507,11 @@ crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg) return NULL; } newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); - newReqMsg->poolp = poolp; if (newReqMsg == NULL) { goto loser; } + + newReqMsg->poolp = poolp; newReqMsg->certReq = crmf_copy_cert_request(poolp, srcReqMsg->certReq); if (newReqMsg->certReq == NULL) { goto loser; diff --git a/security/nss/lib/cryptohi/cryptohi.h b/security/nss/lib/cryptohi/cryptohi.h index 0cc700703..5897a3a6b 100644 --- a/security/nss/lib/cryptohi/cryptohi.h +++ b/security/nss/lib/cryptohi/cryptohi.h @@ -269,6 +269,25 @@ extern SECStatus VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, void *wincx); +/* + * NOTE: This function is private in NSS 3.11.x +** Verify the signature on a block of data. +** "buf" the input data +** "len" the length of the input data +** "key" the public key to check the signature with +** "sig" the encrypted signature data +** "algid" specifies the signing algorithm and parameters to use. +** This must match the key type. +** "reserved" must be NULL in this version. +** "wincx" void pointer to the window context +*/ +extern SECStatus VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, + int len, const SECKEYPublicKey *key, + const SECItem *sig, + const SECAlgorithmID *algid, + SECOidTag *reserved, + void *wincx); + SEC_END_PROTOS diff --git a/security/nss/lib/cryptohi/keyhi.h b/security/nss/lib/cryptohi/keyhi.h index 8707c3d1d..350b88d0f 100644 --- a/security/nss/lib/cryptohi/keyhi.h +++ b/security/nss/lib/cryptohi/keyhi.h @@ -90,6 +90,11 @@ extern unsigned SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk); extern unsigned SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk); /* +** Return the length of the signature in bytes +*/ +extern unsigned SECKEY_SignatureLen(const SECKEYPublicKey *pubk); + +/* ** Make a copy of the private key "privKey" */ extern SECKEYPrivateKey *SECKEY_CopyPrivateKey(SECKEYPrivateKey *privKey); @@ -283,8 +288,24 @@ SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list, #define PUBKEY_LIST_NEXT(n) ((SECKEYPublicKeyListNode *)n->links.next) #define PUBKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list)) +/* + * Length in bits of the EC's field size. This is also the length of + * the x and y coordinates of EC points, such as EC public keys and + * base points. + * + * Return 0 on failure (unknown EC domain parameters). + */ extern int SECKEY_ECParamsToKeySize(const SECItem *params); +/* + * Length in bits of the EC base point order, usually denoted n. This + * is also the length of EC private keys and ECDSA signature components + * r and s. + * + * Return 0 on failure (unknown EC domain parameters). + */ +extern int SECKEY_ECParamsToBasePointOrderLen(const SECItem *params); + SEC_END_PROTOS #endif /* _KEYHI_H_ */ diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c index 97f79d99e..8a128af5f 100644 --- a/security/nss/lib/cryptohi/seckey.c +++ b/security/nss/lib/cryptohi/seckey.c @@ -198,8 +198,11 @@ SECKEYPrivateKey * SECKEY_CreateRSAPrivateKey(int keySizeInBits,SECKEYPublicKey **pubk, void *cx) { SECKEYPrivateKey *privk; - PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN,cx); PK11RSAGenParams param; + PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN,cx); + if (!slot) { + return NULL; + } param.keySizeInBits = keySizeInBits; param.pe = 65537L; @@ -222,6 +225,9 @@ SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c { SECKEYPrivateKey *privk; PK11SlotInfo *slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,cx); + if (!slot) { + return NULL; + } privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param, pubk, PR_FALSE, PR_FALSE, cx); @@ -245,6 +251,9 @@ SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *c { SECKEYPrivateKey *privk; PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN,cx); + if (!slot) { + return NULL; + } privk = PK11_GenerateKeyPair(slot, CKM_EC_KEY_PAIR_GEN, param, pubk, PR_FALSE, PR_FALSE, cx); @@ -1284,7 +1293,155 @@ SECKEY_ECParamsToKeySize(const SECItem *encodedParams) return 571; default: - return 0; + PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); + return 0; + } +} + +int +SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams) +{ + SECOidTag tag; + SECItem oid = { siBuffer, NULL, 0}; + + /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID), + * followed by the length of the curve oid and the curve oid. + */ + oid.len = encodedParams->data[1]; + oid.data = encodedParams->data + 2; + if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN) + return 0; + + switch (tag) { + case SEC_OID_SECG_EC_SECP112R1: + return 112; + case SEC_OID_SECG_EC_SECP112R2: + return 110; + + case SEC_OID_SECG_EC_SECT113R1: + case SEC_OID_SECG_EC_SECT113R2: + return 113; + + case SEC_OID_SECG_EC_SECP128R1: + return 128; + case SEC_OID_SECG_EC_SECP128R2: + return 126; + + case SEC_OID_SECG_EC_SECT131R1: + case SEC_OID_SECG_EC_SECT131R2: + return 131; + + case SEC_OID_SECG_EC_SECP160K1: + case SEC_OID_SECG_EC_SECP160R1: + case SEC_OID_SECG_EC_SECP160R2: + return 161; + + case SEC_OID_SECG_EC_SECT163K1: + return 163; + case SEC_OID_SECG_EC_SECT163R1: + return 162; + case SEC_OID_SECG_EC_SECT163R2: + case SEC_OID_ANSIX962_EC_C2PNB163V1: + return 163; + case SEC_OID_ANSIX962_EC_C2PNB163V2: + case SEC_OID_ANSIX962_EC_C2PNB163V3: + return 162; + + case SEC_OID_ANSIX962_EC_C2PNB176V1: + return 161; + + case SEC_OID_ANSIX962_EC_C2TNB191V1: + return 191; + case SEC_OID_ANSIX962_EC_C2TNB191V2: + return 190; + case SEC_OID_ANSIX962_EC_C2TNB191V3: + return 189; + case SEC_OID_ANSIX962_EC_C2ONB191V4: + return 191; + case SEC_OID_ANSIX962_EC_C2ONB191V5: + return 188; + + case SEC_OID_SECG_EC_SECP192K1: + case SEC_OID_ANSIX962_EC_PRIME192V1: + case SEC_OID_ANSIX962_EC_PRIME192V2: + case SEC_OID_ANSIX962_EC_PRIME192V3: + return 192; + + case SEC_OID_SECG_EC_SECT193R1: + case SEC_OID_SECG_EC_SECT193R2: + return 193; + + case SEC_OID_ANSIX962_EC_C2PNB208W1: + return 193; + + case SEC_OID_SECG_EC_SECP224K1: + return 225; + case SEC_OID_SECG_EC_SECP224R1: + return 224; + + case SEC_OID_SECG_EC_SECT233K1: + return 232; + case SEC_OID_SECG_EC_SECT233R1: + return 233; + + case SEC_OID_SECG_EC_SECT239K1: + case SEC_OID_ANSIX962_EC_C2TNB239V1: + return 238; + case SEC_OID_ANSIX962_EC_C2TNB239V2: + return 237; + case SEC_OID_ANSIX962_EC_C2TNB239V3: + return 236; + case SEC_OID_ANSIX962_EC_C2ONB239V4: + return 238; + case SEC_OID_ANSIX962_EC_C2ONB239V5: + return 237; + case SEC_OID_ANSIX962_EC_PRIME239V1: + case SEC_OID_ANSIX962_EC_PRIME239V2: + case SEC_OID_ANSIX962_EC_PRIME239V3: + return 239; + + case SEC_OID_SECG_EC_SECP256K1: + case SEC_OID_ANSIX962_EC_PRIME256V1: + return 256; + + case SEC_OID_ANSIX962_EC_C2PNB272W1: + return 257; + + case SEC_OID_SECG_EC_SECT283K1: + return 281; + case SEC_OID_SECG_EC_SECT283R1: + return 282; + + case SEC_OID_ANSIX962_EC_C2PNB304W1: + return 289; + + case SEC_OID_ANSIX962_EC_C2TNB359V1: + return 353; + + case SEC_OID_ANSIX962_EC_C2PNB368W1: + return 353; + + case SEC_OID_SECG_EC_SECP384R1: + return 384; + + case SEC_OID_SECG_EC_SECT409K1: + return 407; + case SEC_OID_SECG_EC_SECT409R1: + return 409; + + case SEC_OID_ANSIX962_EC_C2TNB431R1: + return 418; + + case SEC_OID_SECG_EC_SECP521R1: + return 521; + + case SEC_OID_SECG_EC_SECT571K1: + case SEC_OID_SECG_EC_SECT571R1: + return 570; + + default: + PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); + return 0; } } @@ -1321,6 +1478,7 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk) default: break; } + PORT_SetError(SEC_ERROR_INVALID_KEY); return 0; } @@ -1343,6 +1501,33 @@ SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk) default: break; } + PORT_SetError(SEC_ERROR_INVALID_KEY); + return 0; +} + +/* returns signature length in bytes (not bits) */ +unsigned +SECKEY_SignatureLen(const SECKEYPublicKey *pubk) +{ + unsigned char b0; + unsigned size; + + switch (pubk->keyType) { + case rsaKey: + b0 = pubk->u.rsa.modulus.data[0]; + return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; + case fortezzaKey: + case dsaKey: + return DSA_SIGNATURE_LEN; + case ecKey: + /* Get the base point order length in bits and adjust */ + size = SECKEY_ECParamsToBasePointOrderLen( + &pubk->u.ec.DEREncodedParams); + return ((size + 7)/8) * 2; + default: + break; + } + PORT_SetError(SEC_ERROR_INVALID_KEY); return 0; } @@ -1352,13 +1537,13 @@ SECKEY_CopyPrivateKey(SECKEYPrivateKey *privk) SECKEYPrivateKey *copyk; PRArenaPool *arena; - if (privk == NULL) { + if (!privk || !privk->pkcs11Slot) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); return NULL; } @@ -1397,7 +1582,8 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk) { SECKEYPublicKey *copyk; PRArenaPool *arena; - + SECStatus rv = SECSuccess; + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { PORT_SetError (SEC_ERROR_NO_MEMORY); @@ -1405,119 +1591,117 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk) } copyk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey)); - if (copyk != NULL) { - SECStatus rv = SECSuccess; - - copyk->arena = arena; - copyk->keyType = pubk->keyType; - if (pubk->pkcs11Slot && - PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { - copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot); - copyk->pkcs11ID = pubk->pkcs11ID; - } else { - copyk->pkcs11Slot = NULL; /* go get own reference */ - copyk->pkcs11ID = CK_INVALID_HANDLE; - } - switch (pubk->keyType) { - case rsaKey: - rv = SECITEM_CopyItem(arena, ©k->u.rsa.modulus, - &pubk->u.rsa.modulus); - if (rv == SECSuccess) { - rv = SECITEM_CopyItem (arena, ©k->u.rsa.publicExponent, - &pubk->u.rsa.publicExponent); - if (rv == SECSuccess) - return copyk; - } - break; - case dsaKey: - rv = SECITEM_CopyItem(arena, ©k->u.dsa.publicValue, - &pubk->u.dsa.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.prime, - &pubk->u.dsa.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.subPrime, - &pubk->u.dsa.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.base, - &pubk->u.dsa.params.base); - break; - case keaKey: - rv = SECITEM_CopyItem(arena, ©k->u.kea.publicValue, - &pubk->u.kea.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.kea.params.hash, - &pubk->u.kea.params.hash); - break; - case fortezzaKey: - copyk->u.fortezza.KEAversion = pubk->u.fortezza.KEAversion; - copyk->u.fortezza.DSSversion = pubk->u.fortezza.DSSversion; - PORT_Memcpy(copyk->u.fortezza.KMID, pubk->u.fortezza.KMID, - sizeof(pubk->u.fortezza.KMID)); - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.clearance, - &pubk->u.fortezza.clearance); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEApriviledge, - &pubk->u.fortezza.KEApriviledge); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSpriviledge, - &pubk->u.fortezza.DSSpriviledge); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEAKey, - &pubk->u.fortezza.KEAKey); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSKey, - &pubk->u.fortezza.DSSKey); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.prime, - &pubk->u.fortezza.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.subPrime, - &pubk->u.fortezza.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.base, - &pubk->u.fortezza.params.base); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.prime, - &pubk->u.fortezza.keaParams.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.subPrime, - &pubk->u.fortezza.keaParams.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.base, - &pubk->u.fortezza.keaParams.base); - break; - case dhKey: - rv = SECITEM_CopyItem(arena,©k->u.dh.prime,&pubk->u.dh.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena,©k->u.dh.base,&pubk->u.dh.base); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dh.publicValue, - &pubk->u.dh.publicValue); - break; - case ecKey: - copyk->u.ec.size = pubk->u.ec.size; - rv = SECITEM_CopyItem(arena,©k->u.ec.DEREncodedParams, - &pubk->u.ec.DEREncodedParams); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena,©k->u.ec.publicValue, - &pubk->u.ec.publicValue); - break; - case nullKey: - return copyk; - default: - rv = SECFailure; - break; - } - if (rv == SECSuccess) - return copyk; + if (!copyk) { + PORT_SetError (SEC_ERROR_NO_MEMORY); + PORT_FreeArena (arena, PR_FALSE); + return NULL; + } - SECKEY_DestroyPublicKey (copyk); + copyk->arena = arena; + copyk->keyType = pubk->keyType; + if (pubk->pkcs11Slot && + PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { + copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot); + copyk->pkcs11ID = pubk->pkcs11ID; } else { - PORT_SetError (SEC_ERROR_NO_MEMORY); + copyk->pkcs11Slot = NULL; /* go get own reference */ + copyk->pkcs11ID = CK_INVALID_HANDLE; + } + switch (pubk->keyType) { + case rsaKey: + rv = SECITEM_CopyItem(arena, ©k->u.rsa.modulus, + &pubk->u.rsa.modulus); + if (rv == SECSuccess) { + rv = SECITEM_CopyItem (arena, ©k->u.rsa.publicExponent, + &pubk->u.rsa.publicExponent); + if (rv == SECSuccess) + return copyk; + } + break; + case dsaKey: + rv = SECITEM_CopyItem(arena, ©k->u.dsa.publicValue, + &pubk->u.dsa.publicValue); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.prime, + &pubk->u.dsa.params.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.subPrime, + &pubk->u.dsa.params.subPrime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.base, + &pubk->u.dsa.params.base); + break; + case keaKey: + rv = SECITEM_CopyItem(arena, ©k->u.kea.publicValue, + &pubk->u.kea.publicValue); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.kea.params.hash, + &pubk->u.kea.params.hash); + break; + case fortezzaKey: + copyk->u.fortezza.KEAversion = pubk->u.fortezza.KEAversion; + copyk->u.fortezza.DSSversion = pubk->u.fortezza.DSSversion; + PORT_Memcpy(copyk->u.fortezza.KMID, pubk->u.fortezza.KMID, + sizeof(pubk->u.fortezza.KMID)); + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.clearance, + &pubk->u.fortezza.clearance); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEApriviledge, + &pubk->u.fortezza.KEApriviledge); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSpriviledge, + &pubk->u.fortezza.DSSpriviledge); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEAKey, + &pubk->u.fortezza.KEAKey); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSKey, + &pubk->u.fortezza.DSSKey); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.prime, + &pubk->u.fortezza.params.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.subPrime, + &pubk->u.fortezza.params.subPrime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.base, + &pubk->u.fortezza.params.base); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.prime, + &pubk->u.fortezza.keaParams.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.subPrime, + &pubk->u.fortezza.keaParams.subPrime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.base, + &pubk->u.fortezza.keaParams.base); + break; + case dhKey: + rv = SECITEM_CopyItem(arena,©k->u.dh.prime,&pubk->u.dh.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena,©k->u.dh.base,&pubk->u.dh.base); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dh.publicValue, + &pubk->u.dh.publicValue); + break; + case ecKey: + copyk->u.ec.size = pubk->u.ec.size; + rv = SECITEM_CopyItem(arena,©k->u.ec.DEREncodedParams, + &pubk->u.ec.DEREncodedParams); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena,©k->u.ec.publicValue, + &pubk->u.ec.publicValue); + break; + case nullKey: + return copyk; + default: + rv = SECFailure; + break; } + if (rv == SECSuccess) + return copyk; - PORT_FreeArena (arena, PR_FALSE); + SECKEY_DestroyPublicKey (copyk); return NULL; } @@ -1853,7 +2037,6 @@ SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider) } if (rv == SECSuccess) return spki; - SECKEY_DestroySubjectPublicKeyInfo(spki); } else { PORT_SetError(SEC_ERROR_NO_MEMORY); } @@ -1944,8 +2127,8 @@ SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge, /* check the signature */ sig = sd.signature; DER_ConvertBitString(&sig); - rv = VFY_VerifyData(sd.data.data, sd.data.len, pubKey, &sig, - SECOID_GetAlgorithmTag(&(sd.signatureAlgorithm)), wincx); + rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig, + &sd.signatureAlgorithm, NULL, wincx); if ( rv != SECSuccess ) { goto loser; } diff --git a/security/nss/lib/cryptohi/secsign.c b/security/nss/lib/cryptohi/secsign.c index 12e6ed3ad..270889e6c 100644 --- a/security/nss/lib/cryptohi/secsign.c +++ b/security/nss/lib/cryptohi/secsign.c @@ -121,11 +121,26 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) signalg = SEC_OID_MISSI_DSS; /* XXX Is there a better algid? */ keyType = fortezzaKey; break; - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: hashalg = SEC_OID_SHA1; signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; keyType = ecKey; break; + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + hashalg = SEC_OID_SHA256; + signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; + keyType = ecKey; + break; + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + hashalg = SEC_OID_SHA384; + signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; + keyType = ecKey; + break; + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + hashalg = SEC_OID_SHA512; + signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; + keyType = ecKey; + break; /* we don't implement MD4 hashes. * we *CERTAINLY* don't want to sign one! */ case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: @@ -142,6 +157,13 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) return 0; } +#ifndef NSS_ECC_MORE_THAN_SUITE_B + if (key->keyType == ecKey) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return 0; + } +#endif + cx = (SGNContext*) PORT_ZAlloc(sizeof(SGNContext)); if (cx) { cx->hashalg = hashalg; @@ -200,7 +222,8 @@ SECStatus SGN_End(SGNContext *cx, SECItem *result) { unsigned char digest[HASH_LENGTH_MAX]; - unsigned part1, signatureLen; + unsigned part1; + int signatureLen; SECStatus rv; SECItem digder, sigitem; PRArenaPool *arena = 0; @@ -248,6 +271,11 @@ SGN_End(SGNContext *cx, SECItem *result) ** block */ signatureLen = PK11_SignatureLen(privKey); + if (signatureLen <= 0) { + PORT_SetError(SEC_ERROR_INVALID_KEY); + rv = SECFailure; + goto loser; + } sigitem.len = signatureLen; sigitem.data = (unsigned char*) PORT_Alloc(signatureLen); @@ -266,7 +294,7 @@ SGN_End(SGNContext *cx, SECItem *result) if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) || (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { /* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */ - rv = DSAU_EncodeDerSigWithLen(result, &sigitem, signatureLen); + rv = DSAU_EncodeDerSigWithLen(result, &sigitem, sigitem.len); PORT_Free(sigitem.data); if (rv != SECSuccess) goto loser; @@ -373,7 +401,7 @@ SEC_DerSignData(PRArenaPool *arena, SECItem *result, algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break; case ecKey: - algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; + algID = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break; default: PORT_SetError(SEC_ERROR_INVALID_KEY); @@ -407,7 +435,7 @@ SECStatus SGN_Digest(SECKEYPrivateKey *privKey, SECOidTag algtag, SECItem *result, SECItem *digest) { - unsigned modulusLen; + int modulusLen; SECStatus rv; SECItem digder; PRArenaPool *arena = 0; @@ -446,6 +474,11 @@ SGN_Digest(SECKEYPrivateKey *privKey, ** block */ modulusLen = PK11_SignatureLen(privKey); + if (modulusLen <= 0) { + PORT_SetError(SEC_ERROR_INVALID_KEY); + rv = SECFailure; + goto loser; + } result->len = modulusLen; result->data = (unsigned char*) PORT_Alloc(modulusLen); @@ -503,8 +536,19 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) } break; case ecKey: - /* XXX For now only ECDSA with SHA1 is supported */ - sigTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; + switch (hashAlgTag) { + case SEC_OID_UNKNOWN: /* default for ECDSA if hash not specified */ + case SEC_OID_SHA1: /* is ECDSA_SHA1_SIGNTARURE */ + sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break; + case SEC_OID_SHA256: + sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break; + case SEC_OID_SHA384: + sigTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; break; + case SEC_OID_SHA512: + sigTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; break; + default: + break; + } break; default: break; diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c index 311bec35e..94a0b3563 100644 --- a/security/nss/lib/cryptohi/secvfy.c +++ b/security/nss/lib/cryptohi/secvfy.c @@ -48,16 +48,19 @@ #include "pk11func.h" #include "secdig.h" #include "secerr.h" +#include "secport.h" /* ** Decrypt signature block using public key ** Store the hash algorithm oid tag in *tagp ** Store the digest in the digest buffer +** Store the digest length in *digestlen ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION */ static SECStatus -DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, - SECKEYPublicKey *key, SECItem *sig, char *wincx) +DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, + unsigned int *digestlen, unsigned int maxdigestlen, + SECKEYPublicKey *key, const SECItem *sig, char *wincx) { SGNDigestInfo *di = NULL; unsigned char *buf = NULL; @@ -73,7 +76,7 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, if (!buf) goto loser; /* decrypt the block */ - rv = PK11_VerifyRecover(key, sig, &it, wincx); + rv = PK11_VerifyRecover(key, (SECItem *)sig, &it, wincx); if (rv != SECSuccess) goto loser; di = SGN_DecodeDigestInfo(&it); @@ -84,13 +87,21 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, ** ID and the signature block */ tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm); - /* XXX Check that tag is an appropriate algorithm? */ - if (di->digest.len > len) { + /* Check that tag is an appropriate algorithm */ + if (tag == SEC_OID_UNKNOWN) { + goto sigloser; + } + /* make sure the "parameters" are not too bogus. */ + if (di->digestAlgorithm.parameters.len > 2) { + goto sigloser; + } + if (di->digest.len > maxdigestlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); goto loser; } PORT_Memcpy(digest, di->digest.data, di->digest.len); *tagp = tag; + *digestlen = di->digest.len; goto done; sigloser: @@ -131,6 +142,7 @@ struct VFYContextStr { /* the full ECDSA signature */ unsigned char ecdsasig[2 * MAX_ECKEY_LEN]; } u; + unsigned int rsadigestlen; void * wincx; void *hashcx; const SECHashObject *hashobj; @@ -153,19 +165,21 @@ decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *dsig, SECStatus rv=SECSuccess; switch (algid) { + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + if (len > MAX_ECKEY_LEN * 2) { + PORT_SetError(SEC_ERROR_BAD_DER); + return SECFailure; + } + /* fall through */ case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_ANSIX9_DSA_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST: - if (algid == SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST) { - if (len > MAX_ECKEY_LEN * 2) { - PORT_SetError(SEC_ERROR_BAD_DER); - return SECFailure; - } - dsasig = DSAU_DecodeDerSigToLen(sig, len); - } else { - dsasig = DSAU_DecodeDerSig(sig); - } + dsasig = DSAU_DecodeDerSigToLen(sig, len); if ((dsasig == NULL) || (dsasig->len != len)) { rv = SECFailure; @@ -187,22 +201,32 @@ decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *dsig, return rv; } +const static SEC_ASN1Template hashParameterTemplate[] = +{ + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) }, + { SEC_ASN1_OBJECT_ID, 0 }, + { SEC_ASN1_SKIP_REST }, + { 0, } +}; /* * Pulls the hash algorithm, signing algorithm, and key type out of a * composite algorithm. * * alg: the composite algorithm to dissect. * hashalg: address of a SECOidTag which will be set with the hash algorithm. - * signalg: address of a SECOidTag which will be set with the signing alg. - * (not implemented) - * keyType: address of a KeyType which will be set with the key type. - * (not implemented) - * Returns: SECSuccess if the algorithm was acceptable, SECFailure if the + * params: specific signature parameter (from the signature AlgorithmID). + * key: public key to verify against. + * Returns: SECSuccess if the alg algorithm was acceptable, SECFailure if the * algorithm was not found or was not a signing algorithm. */ static SECStatus -decodeSigAlg(SECOidTag alg, SECOidTag *hashalg) +decodeSigAlg(SECOidTag alg, const SECItem *params, const SECKEYPublicKey *key, + SECOidTag *hashalg) { + PRArenaPool *arena; + SECStatus rv; + SECItem oid; + unsigned int len; PR_ASSERT(hashalg!=NULL); switch (alg) { @@ -218,20 +242,67 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg) *hashalg = SEC_OID_SHA1; break; + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: *hashalg = SEC_OID_SHA256; break; + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: *hashalg = SEC_OID_SHA384; break; + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: *hashalg = SEC_OID_SHA512; break; + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + /* This is an EC algorithm. Recommended means the largest + * hash algorithm that is not truncated by the keysize of + * the EC algorithm. Note that key strength is in bytes and + * algorithms are specified in bits. Never use an algorithm + * weaker than sha1. */ + len = SECKEY_PublicKeyStrength((SECKEYPublicKey *)key); + if (len < 28) { /* 28 bytes == 244 bits */ + *hashalg = SEC_OID_SHA1; + } else if (len < 32) { /* 32 bytes == 256 bits */ + /* we don't support 244 bit hash algorithms */ + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } else if (len < 48) { /* 48 bytes == 384 bits */ + *hashalg = SEC_OID_SHA256; + } else if (len < 64) { /* 48 bytes == 512 bits */ + *hashalg = SEC_OID_SHA384; + } else { + /* use the largest in this case */ + *hashalg = SEC_OID_SHA512; + } + break; + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + if (params == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) { + return SECFailure; + } + rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, params); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + return rv; + } + + *hashalg = SECOID_FindOIDTag(&oid); + PORT_FreeArena(arena, PR_FALSE); + if (*hashalg == SEC_OID_UNKNOWN) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } + break; /* what about normal DSA? */ case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: *hashalg = SEC_OID_SHA1; break; case SEC_OID_MISSI_DSS: @@ -248,9 +319,9 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg) return SECSuccess; } -VFYContext * -VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, - void *wincx) +static VFYContext * +vfy_CreateContextPrivate(const SECKEYPublicKey *key, const SECItem *sig, + SECOidTag algid, const SECItem *params, void *wincx) { VFYContext *cx; SECStatus rv; @@ -265,14 +336,17 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, switch (key->keyType) { case rsaKey: cx->type = VFY_RSA; - cx->key = SECKEY_CopyPublicKey(key); /* extra safety precautions */ + /* keep our own copy */ + cx->key = SECKEY_CopyPublicKey((SECKEYPublicKey *)key); if (sig) { SECOidTag hashid = SEC_OID_UNKNOWN; - rv = DecryptSigBlock(&hashid, cx->u.buffer, + unsigned int digestlen = 0; + rv = DecryptSigBlock(&hashid, cx->u.buffer, &digestlen, HASH_LENGTH_MAX, cx->key, sig, (char*)wincx); cx->alg = hashid; + cx->rsadigestlen = digestlen; } else { - rv = decodeSigAlg(algid,&cx->alg); + rv = decodeSigAlg(algid, params, key, &cx->alg); } break; case fortezzaKey: @@ -280,16 +354,23 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, case ecKey: if (key->keyType == ecKey) { cx->type = VFY_ECDSA; - /* Unlike DSA, EDSA does not have a fixed signature length + /* Unlike DSA, ECDSA does not have a fixed signature length * (it depends on the key size) */ - sigLen = SECKEY_PublicKeyStrength(key) * 2; + sigLen = SECKEY_SignatureLen(key); } else { cx->type = VFY_DSA; sigLen = DSA_SIGNATURE_LEN; } - cx->alg = SEC_OID_SHA1; - cx->key = SECKEY_CopyPublicKey(key); + if (sigLen == 0) { + rv = SECFailure; + break; + } + rv = decodeSigAlg(algid, params, key, &cx->alg); + if (rv != SECSuccess) { + break; + } + cx->key = SECKEY_CopyPublicKey((SECKEYPublicKey *)key); if (sig) { rv = decodeECorDSASignature(algid,sig,cx->u.buffer,sigLen); } @@ -319,6 +400,13 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, return 0; } +VFYContext * +VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, + void *wincx) +{ + return vfy_CreateContextPrivate(key, sig, algid, NULL, wincx); +} + void VFY_DestroyContext(VFYContext *cx, PRBool freeit) { @@ -392,7 +480,10 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) if (cx->type == VFY_DSA) { dsasig.len = DSA_SIGNATURE_LEN; } else { - dsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2; + dsasig.len = SECKEY_SignatureLen(cx->key); + } + if (dsasig.len == 0) { + return SECFailure; } if (sig) { rv = decodeECorDSASignature(cx->sigAlg,sig,dsasig.data, @@ -412,14 +503,15 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) case VFY_RSA: if (sig) { SECOidTag hashid = SEC_OID_UNKNOWN; - rv = DecryptSigBlock(&hashid, cx->u.buffer, + rv = DecryptSigBlock(&hashid, cx->u.buffer, &cx->rsadigestlen, HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx); if ((rv != SECSuccess) || (hashid != cx->alg)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } } - if (PORT_Memcmp(final, cx->u.buffer, part)) { + if ((part != cx->rsadigestlen) || + PORT_Memcmp(final, cx->u.buffer, part)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } @@ -458,7 +550,8 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, if (cx != NULL) { switch (key->keyType) { case rsaKey: - if (PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { + if ((digest->len != cx->rsadigestlen) || + PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); } else { rv = SECSuccess; @@ -469,11 +562,14 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, case ecKey: dsasig.data = cx->u.buffer; if (key->keyType == ecKey) { - dsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2; + dsasig.len = SECKEY_SignatureLen(cx->key); } else { /* magic size of dsa signature */ dsasig.len = DSA_SIGNATURE_LEN; } + if (dsasig.len == 0) { + break; + } if (PK11_Verify(cx->key, &dsasig, digest, cx->wincx) != SECSuccess) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); @@ -489,20 +585,21 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, return rv; } -SECStatus -VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, - SECItem *sig, SECOidTag algid, void *wincx) +static SECStatus +vfy_VerifyDataPrivate(const unsigned char *buf, int len, + const SECKEYPublicKey *key, const SECItem *sig, + SECOidTag algid, const SECItem *params, void *wincx) { SECStatus rv; VFYContext *cx; - cx = VFY_CreateContext(key, sig, algid, wincx); + cx = vfy_CreateContextPrivate(key, sig, algid, params, wincx); if (cx == NULL) return SECFailure; rv = VFY_Begin(cx); if (rv == SECSuccess) { - rv = VFY_Update(cx, buf, len); + rv = VFY_Update(cx, (unsigned char *)buf, len); if (rv == SECSuccess) rv = VFY_End(cx); } @@ -510,3 +607,34 @@ VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, VFY_DestroyContext(cx, PR_TRUE); return rv; } + +SECStatus +VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, + SECItem *sig, SECOidTag algid, void *wincx) +{ + return vfy_VerifyDataPrivate(buf, len, key, sig, algid, NULL, wincx); +} + +/* + * this function is private to nss3.dll in NSS 3.11 + */ +SECStatus +VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len, + const SECKEYPublicKey *key, + const SECItem *sig, + const SECAlgorithmID *sigAlgorithm, + SECOidTag *reserved, void *wincx) +{ + /* the hash parameter is only provided to match the NSS 3.12 signature */ + PORT_Assert(reserved == NULL); + if (reserved) { + /* shouldn't happen, This function is not exported, and the only + * NSS callers pass 'NULL' */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + return vfy_VerifyDataPrivate(buf, len, key, sig, + SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm), + &sigAlgorithm->parameters, wincx); +} + diff --git a/security/nss/lib/freebl/GF2m_ecl.c b/security/nss/lib/freebl/GF2m_ecl.c deleted file mode 100644 index 4c0ab88f7..000000000 --- a/security/nss/lib/freebl/GF2m_ecl.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 elliptic curve math library for binary polynomial field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Douglas Stebila <douglas@stebila.ca> - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifdef NSS_ENABLE_ECC -/* - * GF2m_ecl.c: Contains an implementation of elliptic curve math library - * for curves over GF2m. - * - * XXX Can be moved to a separate subdirectory later. - * - */ - -#include "GF2m_ecl.h" -#include "mpi/mplogic.h" -#include "mpi/mp_gf2m.h" -#include <stdlib.h> - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -mp_err -GF2m_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py) -{ - - if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) { - return MP_YES; - } else { - return MP_NO; - } - -} - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -mp_err -GF2m_ec_pt_set_inf_aff(mp_int *px, mp_int *py) -{ - mp_zero(px); - mp_zero(py); - return MP_OKAY; -} - -/* Computes R = P + Q based on IEEE P1363 A.10.2. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_add_aff(const mp_int *pp, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int lambda, xtemp, ytemp; - unsigned int *p; - int p_size; - - p_size = mp_bpoly2arr(pp, p, 0) + 1; - p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size)); - if (p == NULL) goto cleanup; - mp_bpoly2arr(pp, p, p_size); - - CHECK_MPI_OK( mp_init(&lambda) ); - CHECK_MPI_OK( mp_init(&xtemp) ); - CHECK_MPI_OK( mp_init(&ytemp) ); - /* if P = inf, then R = Q */ - if (GF2m_ec_pt_is_inf_aff(px, py) == 0) { - CHECK_MPI_OK( mp_copy(qx, rx) ); - CHECK_MPI_OK( mp_copy(qy, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if Q = inf, then R = P */ - if (GF2m_ec_pt_is_inf_aff(qx, qy) == 0) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if px != qx, then lambda = (py+qy) / (px+qx), - * xtemp = a + lambda^2 + lambda + px + qx - */ - if (mp_cmp(px, qx) != 0) { - CHECK_MPI_OK( mp_badd(py, qy, &ytemp) ); - CHECK_MPI_OK( mp_badd(px, qx, &xtemp) ); - CHECK_MPI_OK( mp_bdivmod(&ytemp, &xtemp, pp, p, &lambda) ); - CHECK_MPI_OK( mp_bsqrmod(&lambda, p, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, &lambda, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, a, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, px, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, qx, &xtemp) ); - } else { - /* if py != qy or qx = 0, then R = inf */ - if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* lambda = qx + qy / qx */ - CHECK_MPI_OK( mp_bdivmod(qy, qx, pp, p, &lambda) ); - CHECK_MPI_OK( mp_badd(&lambda, qx, &lambda) ); - /* xtemp = a + lambda^2 + lambda */ - CHECK_MPI_OK( mp_bsqrmod(&lambda, p, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, &lambda, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, a, &xtemp) ); - } - /* ry = (qx + xtemp) * lambda + xtemp + qy */ - CHECK_MPI_OK( mp_badd(qx, &xtemp, &ytemp) ); - CHECK_MPI_OK( mp_bmulmod(&ytemp, &lambda, p, &ytemp) ); - CHECK_MPI_OK( mp_badd(&ytemp, &xtemp, &ytemp) ); - CHECK_MPI_OK( mp_badd(&ytemp, qy, ry) ); - /* rx = xtemp */ - CHECK_MPI_OK( mp_copy(&xtemp, rx) ); - -cleanup: - mp_clear(&lambda); - mp_clear(&xtemp); - mp_clear(&ytemp); - free(p); - return err; -} - -/* Computes R = P - Q. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_sub_aff(const mp_int *pp, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int nqy; - MP_DIGITS(&nqy) = 0; - CHECK_MPI_OK( mp_init(&nqy) ); - /* nqy = qx+qy */ - CHECK_MPI_OK( mp_badd(qx, qy, &nqy) ); - err = GF2m_ec_pt_add_aff(pp, a, px, py, qx, &nqy, rx, ry); -cleanup: - mp_clear(&nqy); - return err; -} - -/* Computes R = 2P. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_dbl_aff(const mp_int *pp, const mp_int *a, const mp_int *px, - const mp_int *py, mp_int *rx, mp_int *ry) -{ - return GF2m_ec_pt_add_aff(pp, a, px, py, px, py, rx, ry); -} - -/* Gets the i'th bit in the binary representation of a. - * If i >= length(a), then return 0. - * (The above behaviour differs from mpl_get_bit, which - * causes an error if i >= length(a).) - */ -#define MP_GET_BIT(a, i) \ - ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i)) - -/* Computes R = nP based on IEEE P1363 A.10.3. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_mul_aff(const mp_int *pp, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int k, k3, qx, qy, sx, sy; - int b1, b3, i, l; - unsigned int *p; - int p_size; - - MP_DIGITS(&k) = 0; - MP_DIGITS(&k3) = 0; - MP_DIGITS(&qx) = 0; - MP_DIGITS(&qy) = 0; - MP_DIGITS(&sx) = 0; - MP_DIGITS(&sy) = 0; - CHECK_MPI_OK( mp_init(&k) ); - CHECK_MPI_OK( mp_init(&k3) ); - CHECK_MPI_OK( mp_init(&qx) ); - CHECK_MPI_OK( mp_init(&qy) ); - CHECK_MPI_OK( mp_init(&sx) ); - CHECK_MPI_OK( mp_init(&sy) ); - - p_size = mp_bpoly2arr(pp, p, 0) + 1; - p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size)); - if (p == NULL) goto cleanup; - mp_bpoly2arr(pp, p, p_size); - - /* if n = 0 then r = inf */ - if (mp_cmp_z(n) == 0) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* Q = P, k = n */ - CHECK_MPI_OK( mp_copy(px, &qx) ); - CHECK_MPI_OK( mp_copy(py, &qy) ); - CHECK_MPI_OK( mp_copy(n, &k) ); - /* if n < 0 then Q = -Q, k = -k */ - if (mp_cmp_z(n) < 0) { - CHECK_MPI_OK( mp_badd(&qx, &qy, &qy) ); - CHECK_MPI_OK( mp_neg(&k, &k) ); - } -#ifdef EC_DEBUG /* basic double and add method */ - l = mpl_significant_bits(&k) - 1; - mp_zero(&sx); - mp_zero(&sy); - for (i = l; i >= 0; i--) { - /* if k_i = 1, then S = S + Q */ - if (mpl_get_bit(&k, i) != 0) { - CHECK_MPI_OK( GF2m_ec_pt_add_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) ); - } - if (i > 0) { - /* S = 2S */ - CHECK_MPI_OK( GF2m_ec_pt_dbl_aff(pp, a, &sx, &sy, &sx, &sy) ); - } - } -#else /* double and add/subtract method from standard */ - /* k3 = 3 * k */ - mp_set(&k3, 0x3); - CHECK_MPI_OK( mp_mul(&k, &k3, &k3) ); - /* S = Q */ - CHECK_MPI_OK( mp_copy(&qx, &sx) ); - CHECK_MPI_OK( mp_copy(&qy, &sy) ); - /* l = index of high order bit in binary representation of 3*k */ - l = mpl_significant_bits(&k3) - 1; - /* for i = l-1 downto 1 */ - for (i = l - 1; i >= 1; i--) { - /* S = 2S */ - CHECK_MPI_OK( GF2m_ec_pt_dbl_aff(pp, a, &sx, &sy, &sx, &sy) ); - b3 = MP_GET_BIT(&k3, i); - b1 = MP_GET_BIT(&k, i); - /* if k3_i = 1 and k_i = 0, then S = S + Q */ - if ((b3 == 1) && (b1 == 0)) { - CHECK_MPI_OK( GF2m_ec_pt_add_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) ); - /* if k3_i = 0 and k_i = 1, then S = S - Q */ - } else if ((b3 == 0) && (b1 == 1)) { - CHECK_MPI_OK( GF2m_ec_pt_sub_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) ); - } - } -#endif - /* output S */ - CHECK_MPI_OK( mp_copy(&sx, rx) ); - CHECK_MPI_OK( mp_copy(&sy, ry) ); - -cleanup: - mp_clear(&k); - mp_clear(&k3); - mp_clear(&qx); - mp_clear(&qy); - mp_clear(&sx); - mp_clear(&sy); - free(p); - return err; -} - -/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective - * coordinates. - * Uses algorithm Mdouble in appendix of - * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - * modified to not require precomputation of c=b^{2^{m-1}}. - */ -static mp_err -gf2m_Mdouble(const mp_int *pp, const unsigned int p[], const mp_int *a, - const mp_int *b, mp_int *x, mp_int *z) -{ - mp_err err = MP_OKAY; - mp_int t1; - - MP_DIGITS(&t1) = 0; - CHECK_MPI_OK( mp_init(&t1) ); - - CHECK_MPI_OK( mp_bsqrmod(x, p, x) ); - CHECK_MPI_OK( mp_bsqrmod(z, p, &t1) ); - CHECK_MPI_OK( mp_bmulmod(x, &t1, p, z) ); - CHECK_MPI_OK( mp_bsqrmod(x, p, x) ); - CHECK_MPI_OK( mp_bsqrmod(&t1, p, &t1) ); - CHECK_MPI_OK( mp_bmulmod(b, &t1, p, &t1) ); - CHECK_MPI_OK( mp_badd(x, &t1, x) ); - -cleanup: - mp_clear(&t1); - return err; -} - -/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery - * projective coordinates. - * Uses algorithm Madd in appendix of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - */ -static mp_err -gf2m_Madd(const mp_int *pp, const unsigned int p[], const mp_int *a, - const mp_int *b, const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, - mp_int *z2) -{ - mp_err err = MP_OKAY; - mp_int t1, t2; - - MP_DIGITS(&t1) = 0; - MP_DIGITS(&t2) = 0; - CHECK_MPI_OK( mp_init(&t1) ); - CHECK_MPI_OK( mp_init(&t2) ); - - CHECK_MPI_OK( mp_copy(x, &t1) ); - CHECK_MPI_OK( mp_bmulmod(x1, z2, p, x1) ); - CHECK_MPI_OK( mp_bmulmod(z1, x2, p, z1) ); - CHECK_MPI_OK( mp_bmulmod(x1, z1, p, &t2) ); - CHECK_MPI_OK( mp_badd(z1, x1, z1) ); - CHECK_MPI_OK( mp_bsqrmod(z1, p, z1) ); - CHECK_MPI_OK( mp_bmulmod(z1, &t1, p, x1) ); - CHECK_MPI_OK( mp_badd(x1, &t2, x1) ); - -cleanup: - mp_clear(&t1); - mp_clear(&t2); - return err; -} - -/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) - * using Montgomery point multiplication algorithm Mxy() in appendix of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - * Returns: - * 0 on error - * 1 if return value should be the point at infinity - * 2 otherwise - */ -static int -gf2m_Mxy(const mp_int *pp, const unsigned int p[], const mp_int *a, - const mp_int *b, const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1, - mp_int *x2, mp_int *z2) -{ - mp_err err = MP_OKAY; - int ret; - mp_int t3, t4, t5; - - MP_DIGITS(&t3) = 0; - MP_DIGITS(&t4) = 0; - MP_DIGITS(&t5) = 0; - CHECK_MPI_OK( mp_init(&t3) ); - CHECK_MPI_OK( mp_init(&t4) ); - CHECK_MPI_OK( mp_init(&t5) ); - - if (mp_cmp_z(z1) == 0) { - mp_zero(x2); - mp_zero(z2); - ret = 1; - goto cleanup; - } - - if (mp_cmp_z(z2) == 0) { - CHECK_MPI_OK( mp_copy(x, x2) ); - CHECK_MPI_OK( mp_badd(x, y, z2) ); - ret = 2; - goto cleanup; - } - - mp_set(&t5, 0x1); - - CHECK_MPI_OK( mp_bmulmod(z1, z2, p, &t3) ); - - CHECK_MPI_OK( mp_bmulmod(z1, x, p, z1) ); - CHECK_MPI_OK( mp_badd(z1, x1, z1) ); - CHECK_MPI_OK( mp_bmulmod(z2, x, p, z2) ); - CHECK_MPI_OK( mp_bmulmod(z2, x1, p, x1) ); - CHECK_MPI_OK( mp_badd(z2, x2, z2) ); - - CHECK_MPI_OK( mp_bmulmod(z2, z1, p, z2) ); - CHECK_MPI_OK( mp_bsqrmod(x, p, &t4) ); - CHECK_MPI_OK( mp_badd(&t4, y, &t4) ); - CHECK_MPI_OK( mp_bmulmod(&t4, &t3, p, &t4) ); - CHECK_MPI_OK( mp_badd(&t4, z2, &t4) ); - - CHECK_MPI_OK( mp_bmulmod(&t3, x, p, &t3) ); - CHECK_MPI_OK( mp_bdivmod(&t5, &t3, pp, p, &t3) ); - CHECK_MPI_OK( mp_bmulmod(&t3, &t4, p, &t4) ); - CHECK_MPI_OK( mp_bmulmod(x1, &t3, p, x2) ); - CHECK_MPI_OK( mp_badd(x2, x, z2) ); - - CHECK_MPI_OK( mp_bmulmod(z2, &t4, p, z2) ); - CHECK_MPI_OK( mp_badd(z2, y, z2) ); - - ret = 2; - -cleanup: - mp_clear(&t3); - mp_clear(&t4); - mp_clear(&t5); - if (err == MP_OKAY) { - return ret; - } else { - return 0; - } -} - -/* Computes R = nP based on algorithm 2P of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - * Elliptic curve points P and R can be identical. - * Uses Montgomery projective coordinates. - */ -mp_err -GF2m_ec_pt_mul_mont(const mp_int *pp, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int x1, x2, z1, z2; - int i, j; - mp_digit top_bit, mask; - unsigned int *p; - int p_size; - - MP_DIGITS(&x1) = 0; - MP_DIGITS(&x2) = 0; - MP_DIGITS(&z1) = 0; - MP_DIGITS(&z2) = 0; - CHECK_MPI_OK( mp_init(&x1) ); - CHECK_MPI_OK( mp_init(&x2) ); - CHECK_MPI_OK( mp_init(&z1) ); - CHECK_MPI_OK( mp_init(&z2) ); - - p_size = mp_bpoly2arr(pp, p, 0) + 1; - p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size)); - if (p == NULL) goto cleanup; - mp_bpoly2arr(pp, p, p_size); - - /* if result should be point at infinity */ - if ((mp_cmp_z(n) == 0) || (GF2m_ec_pt_is_inf_aff(px, py) == MP_YES)) { - CHECK_MPI_OK( GF2m_ec_pt_set_inf_aff(rx, ry) ); - goto cleanup; - } - - CHECK_MPI_OK( mp_copy(rx, &x2) ); /* x2 = rx */ - CHECK_MPI_OK( mp_copy(ry, &z2) ); /* z2 = ry */ - - CHECK_MPI_OK( mp_copy(px, &x1) ); /* x1 = px */ - mp_set(&z1, 0x1); /* z1 = 1 */ - CHECK_MPI_OK( mp_bsqrmod(&x1, p, &z2) ); /* z2 = x1^2 = x2^2 */ - CHECK_MPI_OK( mp_bsqrmod(&z2, p, &x2) ); - CHECK_MPI_OK( mp_badd(&x2, b, &x2) ); /* x2 = px^4 + b */ - - /* find top-most bit and go one past it */ - i = MP_USED(n) - 1; - j = MP_DIGIT_BIT - 1; - top_bit = 1; - top_bit <<= MP_DIGIT_BIT - 1; - mask = top_bit; - while (!(MP_DIGITS(n)[i] & mask)) { - mask >>= 1; - j--; - } - mask >>= 1; j--; - - /* if top most bit was at word break, go to next word */ - if (!mask) { - i--; - j = MP_DIGIT_BIT - 1; - mask = top_bit; - } - - for (; i >= 0; i--) { - for (; j >= 0; j--) { - if (MP_DIGITS(n)[i] & mask) { - CHECK_MPI_OK( gf2m_Madd(pp, p, a, b, px, &x1, &z1, &x2, &z2) ); - CHECK_MPI_OK( gf2m_Mdouble(pp, p, a, b, &x2, &z2) ); - } else { - CHECK_MPI_OK( gf2m_Madd(pp, p, a, b, px, &x2, &z2, &x1, &z1) ); - CHECK_MPI_OK( gf2m_Mdouble(pp, p, a, b, &x1, &z1) ); - } - mask >>= 1; - } - j = MP_DIGIT_BIT - 1; - mask = top_bit; - } - - /* convert out of "projective" coordinates */ - i = gf2m_Mxy(pp, p, a, b, px, py, &x1, &z1, &x2, &z2); - if (i == 0) { - err = MP_BADARG; - goto cleanup; - } else if (i == 1) { - CHECK_MPI_OK( GF2m_ec_pt_set_inf_aff(rx, ry) ); - } else { - CHECK_MPI_OK( mp_copy(&x2, rx) ); - CHECK_MPI_OK( mp_copy(&z2, ry) ); - } - -cleanup: - mp_clear(&x1); - mp_clear(&x2); - mp_clear(&z1); - mp_clear(&z2); - free(p); - return err; -} - -#endif /* NSS_ENABLE_ECC */ diff --git a/security/nss/lib/freebl/GF2m_ecl.h b/security/nss/lib/freebl/GF2m_ecl.h deleted file mode 100644 index 3641d63da..000000000 --- a/security/nss/lib/freebl/GF2m_ecl.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 elliptic curve math library for binary polynomial field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Douglas Stebila <douglas@stebila.ca> - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __gf2m_ecl_h_ -#define __gf2m_ecl_h_ -#ifdef NSS_ENABLE_ECC - -#include "secmpi.h" - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -mp_err GF2m_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py); - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -mp_err GF2m_ec_pt_set_inf_aff(mp_int *px, mp_int *py); - -/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx, qy). - * Uses affine coordinates. - */ -mp_err GF2m_ec_pt_add_aff(const mp_int *pp, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = P - Q. Uses affine coordinates. */ -mp_err GF2m_ec_pt_sub_aff(const mp_int *pp, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = 2P. Uses affine coordinates. */ -mp_err GF2m_ec_pt_dbl_aff(const mp_int *pp, const mp_int *a, - const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the irreducible that - * determines the field GF2m. Uses affine coordinates. - */ -mp_err GF2m_ec_pt_mul_aff(const mp_int *pp, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the irreducible that - * determines the field GF2m. Uses Montgomery projective coordinates. - */ -mp_err GF2m_ec_pt_mul_mont(const mp_int *pp, const mp_int *a, - const mp_int *b, const mp_int *px, const mp_int *py, - const mp_int *n, mp_int *rx, mp_int *ry); - -#define GF2m_ec_pt_is_inf(px, py) GF2m_ec_pt_is_inf_aff((px), (py)) -#define GF2m_ec_pt_add(p, a, px, py, qx, qy, rx, ry) \ - GF2m_ec_pt_add_aff((p), (a), (px), (py), (qx), (qy), (rx), (ry)) - -#define GF2m_ECL_MONTGOMERY -#ifdef GF2m_ECL_AFFINE -#define GF2m_ec_pt_mul(pp, a, b, px, py, n, rx, ry) \ - GF2m_ec_pt_mul_aff((pp), (a), (b), (px), (py), (n), (rx), (ry)) -#elif defined(GF2m_ECL_MONTGOMERY) -#define GF2m_ec_pt_mul(pp, a, b, px, py, n, rx, ry) \ - GF2m_ec_pt_mul_mont((pp), (a), (b), (px), (py), (n), (rx), (ry)) -#endif /* GF2m_ECL_AFFINE or GF2m_ECL_MONTGOMERY */ - -#endif /* NSS_ENABLE_ECC */ -#endif /* __gf2m_ecl_h_ */ diff --git a/security/nss/lib/freebl/GFp_ecl.c b/security/nss/lib/freebl/GFp_ecl.c deleted file mode 100644 index 7b460cc58..000000000 --- a/security/nss/lib/freebl/GFp_ecl.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 elliptic curve math library for prime field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Sheueling Chang Shantz <sheueling.chang@sun.com> and - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories - * Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>, - * Nils Larsch <nla@trustcenter.de>, and - * Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifdef NSS_ENABLE_ECC -/* - * GFp_ecl.c: Contains an implementation of elliptic curve math library - * for curves over GFp. - * - * XXX Can be moved to a separate subdirectory later. - * - */ - -#include "GFp_ecl.h" -#include "mpi/mplogic.h" - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -mp_err -GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py) -{ - - if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) { - return MP_YES; - } else { - return MP_NO; - } - -} - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -mp_err -GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py) -{ - mp_zero(px); - mp_zero(py); - return MP_OKAY; -} - -/* Computes R = P + Q based on IEEE P1363 A.10.1. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int lambda, temp, xtemp, ytemp; - - CHECK_MPI_OK( mp_init(&lambda) ); - CHECK_MPI_OK( mp_init(&temp) ); - CHECK_MPI_OK( mp_init(&xtemp) ); - CHECK_MPI_OK( mp_init(&ytemp) ); - /* if P = inf, then R = Q */ - if (GFp_ec_pt_is_inf_aff(px, py) == 0) { - CHECK_MPI_OK( mp_copy(qx, rx) ); - CHECK_MPI_OK( mp_copy(qy, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if Q = inf, then R = P */ - if (GFp_ec_pt_is_inf_aff(qx, qy) == 0) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if px != qx, then lambda = (py-qy) / (px-qx) */ - if (mp_cmp(px, qx) != 0) { - CHECK_MPI_OK( mp_submod(py, qy, p, &ytemp) ); - CHECK_MPI_OK( mp_submod(px, qx, p, &xtemp) ); - CHECK_MPI_OK( mp_invmod(&xtemp, p, &xtemp) ); - CHECK_MPI_OK( mp_mulmod(&ytemp, &xtemp, p, &lambda) ); - } else { - /* if py != qy or qy = 0, then R = inf */ - if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* lambda = (3qx^2+a) / (2qy) */ - CHECK_MPI_OK( mp_sqrmod(qx, p, &xtemp) ); - mp_set(&temp, 0x3); - CHECK_MPI_OK( mp_mulmod(&xtemp, &temp, p, &xtemp) ); - CHECK_MPI_OK( mp_addmod(&xtemp, a, p, &xtemp) ); - mp_set(&temp, 0x2); - CHECK_MPI_OK( mp_mulmod(qy, &temp, p, &ytemp) ); - CHECK_MPI_OK( mp_invmod(&ytemp, p, &ytemp) ); - CHECK_MPI_OK( mp_mulmod(&xtemp, &ytemp, p, &lambda) ); - } - /* rx = lambda^2 - px - qx */ - CHECK_MPI_OK( mp_sqrmod(&lambda, p, &xtemp) ); - CHECK_MPI_OK( mp_submod(&xtemp, px, p, &xtemp) ); - CHECK_MPI_OK( mp_submod(&xtemp, qx, p, &xtemp) ); - /* ry = (x1-x2) * lambda - y1 */ - CHECK_MPI_OK( mp_submod(qx, &xtemp, p, &ytemp) ); - CHECK_MPI_OK( mp_mulmod(&ytemp, &lambda, p, &ytemp) ); - CHECK_MPI_OK( mp_submod(&ytemp, qy, p, &ytemp) ); - CHECK_MPI_OK( mp_copy(&xtemp, rx) ); - CHECK_MPI_OK( mp_copy(&ytemp, ry) ); - -cleanup: - mp_clear(&lambda); - mp_clear(&temp); - mp_clear(&xtemp); - mp_clear(&ytemp); - return err; -} - -/* Computes R = P - Q. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int nqy; - MP_DIGITS(&nqy) = 0; - CHECK_MPI_OK( mp_init(&nqy) ); - /* nqy = -qy */ - CHECK_MPI_OK( mp_neg(qy, &nqy) ); - err = GFp_ec_pt_add_aff(p, a, px, py, qx, &nqy, rx, ry); -cleanup: - mp_clear(&nqy); - return err; -} - -/* Computes R = 2P. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, mp_int *rx, mp_int *ry) -{ - return GFp_ec_pt_add_aff(p, a, px, py, px, py, rx, ry); -} - -/* Gets the i'th bit in the binary representation of a. - * If i >= length(a), then return 0. - * (The above behaviour differs from mpl_get_bit, which - * causes an error if i >= length(a).) - */ -#define MP_GET_BIT(a, i) \ - ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i)) - -/* Computes R = nP based on IEEE P1363 A.10.3. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, mp_int *rx, - mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int k, k3, qx, qy, sx, sy; - int b1, b3, i, l; - - MP_DIGITS(&k) = 0; - MP_DIGITS(&k3) = 0; - MP_DIGITS(&qx) = 0; - MP_DIGITS(&qy) = 0; - MP_DIGITS(&sx) = 0; - MP_DIGITS(&sy) = 0; - CHECK_MPI_OK( mp_init(&k) ); - CHECK_MPI_OK( mp_init(&k3) ); - CHECK_MPI_OK( mp_init(&qx) ); - CHECK_MPI_OK( mp_init(&qy) ); - CHECK_MPI_OK( mp_init(&sx) ); - CHECK_MPI_OK( mp_init(&sy) ); - - /* if n = 0 then r = inf */ - if (mp_cmp_z(n) == 0) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* Q = P, k = n */ - CHECK_MPI_OK( mp_copy(px, &qx) ); - CHECK_MPI_OK( mp_copy(py, &qy) ); - CHECK_MPI_OK( mp_copy(n, &k) ); - /* if n < 0 Q = -Q, k = -k */ - if (mp_cmp_z(n) < 0) { - CHECK_MPI_OK( mp_neg(&qy, &qy) ); - CHECK_MPI_OK( mp_mod(&qy, p, &qy) ); - CHECK_MPI_OK( mp_neg(&k, &k) ); - CHECK_MPI_OK( mp_mod(&k, p, &k) ); - } -#ifdef EC_DEBUG /* basic double and add method */ - l = mpl_significant_bits(&k) - 1; - mp_zero(&sx); - mp_zero(&sy); - for (i = l; i >= 0; i--) { - /* if k_i = 1, then S = S + Q */ - if (mpl_get_bit(&k, i) != 0) { - CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy, - &qx, &qy, &sx, &sy) ); - } - if (i > 0) { - /* S = 2S */ - CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) ); - } - } -#else /* double and add/subtract method from standard */ - /* k3 = 3 * k */ - mp_set(&k3, 0x3); - CHECK_MPI_OK( mp_mul(&k, &k3, &k3) ); - /* S = Q */ - CHECK_MPI_OK( mp_copy(&qx, &sx) ); - CHECK_MPI_OK( mp_copy(&qy, &sy) ); - /* l = index of high order bit in binary representation of 3*k */ - l = mpl_significant_bits(&k3) - 1; - /* for i = l-1 downto 1 */ - for (i = l - 1; i >= 1; i--) { - /* S = 2S */ - CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) ); - b3 = MP_GET_BIT(&k3, i); - b1 = MP_GET_BIT(&k, i); - /* if k3_i = 1 and k_i = 0, then S = S + Q */ - if ((b3 == 1) && (b1 == 0)) { - CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy, - &qx, &qy, &sx, &sy) ); - /* if k3_i = 0 and k_i = 1, then S = S - Q */ - } else if ((b3 == 0) && (b1 == 1)) { - CHECK_MPI_OK( GFp_ec_pt_sub_aff(p, a, &sx, &sy, - &qx, &qy, &sx, &sy) ); - } - } -#endif - /* output S */ - CHECK_MPI_OK( mp_copy(&sx, rx) ); - CHECK_MPI_OK( mp_copy(&sy, ry) ); - -cleanup: - mp_clear(&k); - mp_clear(&k3); - mp_clear(&qx); - mp_clear(&qy); - mp_clear(&sx); - mp_clear(&sy); - return err; -} - -/* Converts a point P(px, py, pz) from Jacobian projective coordinates to - * affine coordinates R(rx, ry). P and R can share x and y coordinates. - */ -mp_err -GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz, - const mp_int *p, mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int z1, z2, z3; - MP_DIGITS(&z1) = 0; - MP_DIGITS(&z2) = 0; - MP_DIGITS(&z3) = 0; - CHECK_MPI_OK( mp_init(&z1) ); - CHECK_MPI_OK( mp_init(&z2) ); - CHECK_MPI_OK( mp_init(&z3) ); - - /* if point at infinity, then set point at infinity and exit */ - if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) { - CHECK_MPI_OK( GFp_ec_pt_set_inf_aff(rx, ry) ); - goto cleanup; - } - - /* transform (px, py, pz) into (px / pz^2, py / pz^3) */ - if (mp_cmp_d(pz, 1) == 0) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - } else { - CHECK_MPI_OK( mp_invmod(pz, p, &z1) ); - CHECK_MPI_OK( mp_sqrmod(&z1, p, &z2) ); - CHECK_MPI_OK( mp_mulmod(&z1, &z2, p, &z3) ); - CHECK_MPI_OK( mp_mulmod(px, &z2, p, rx) ); - CHECK_MPI_OK( mp_mulmod(py, &z3, p, ry) ); - } - -cleanup: - mp_clear(&z1); - mp_clear(&z2); - mp_clear(&z3); - return err; -} - -/* Checks if point P(px, py, pz) is at infinity. - * Uses Jacobian coordinates. - */ -mp_err -GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz) -{ - return mp_cmp_z(pz); -} - -/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian - * coordinates. - */ -mp_err -GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz) -{ - mp_zero(pz); - return MP_OKAY; -} - -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and - * Q is (qx, qy, qz). Elliptic curve points P, Q, and R can all be - * identical. Uses Jacobian coordinates. - * - * This routine implements Point Addition in the Jacobian Projective - * space as described in the paper "Efficient elliptic curve exponentiation - * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono. - */ -mp_err -GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *pz, const mp_int *qx, - const mp_int *qy, const mp_int *qz, mp_int *rx, mp_int *ry, mp_int *rz) -{ - mp_err err = MP_OKAY; - mp_int n0, u1, u2, s1, s2, H, G; - MP_DIGITS(&n0) = 0; - MP_DIGITS(&u1) = 0; - MP_DIGITS(&u2) = 0; - MP_DIGITS(&s1) = 0; - MP_DIGITS(&s2) = 0; - MP_DIGITS(&H) = 0; - MP_DIGITS(&G) = 0; - CHECK_MPI_OK( mp_init(&n0) ); - CHECK_MPI_OK( mp_init(&u1) ); - CHECK_MPI_OK( mp_init(&u2) ); - CHECK_MPI_OK( mp_init(&s1) ); - CHECK_MPI_OK( mp_init(&s2) ); - CHECK_MPI_OK( mp_init(&H) ); - CHECK_MPI_OK( mp_init(&G) ); - - /* Use point double if pointers are equal. */ - if ((px == qx) && (py == qy) && (pz == qz)) { - err = GFp_ec_pt_dbl_jac(p, a, px, py, pz, rx, ry, rz); - goto cleanup; - } - - /* If either P or Q is the point at infinity, then return - * the other point - */ - if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) { - CHECK_MPI_OK( mp_copy(qx, rx) ); - CHECK_MPI_OK( mp_copy(qy, ry) ); - CHECK_MPI_OK( mp_copy(qz, rz) ); - goto cleanup; - } - if (GFp_ec_pt_is_inf_jac(qx, qy, qz) == MP_YES) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - CHECK_MPI_OK( mp_copy(pz, rz) ); - goto cleanup; - } - - /* Compute u1 = px * qz^2, s1 = py * qz^3 */ - if (mp_cmp_d(qz, 1) == 0) { - CHECK_MPI_OK( mp_copy(px, &u1) ); - CHECK_MPI_OK( mp_copy(py, &s1) ); - } else { - CHECK_MPI_OK( mp_sqrmod(qz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(px, &n0, p, &u1) ); - CHECK_MPI_OK( mp_mulmod(&n0, qz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(py, &n0, p, &s1) ); - } - - /* Compute u2 = qx * pz^2, s2 = qy * pz^3 */ - if (mp_cmp_d(pz, 1) == 0) { - CHECK_MPI_OK( mp_copy(qx, &u2) ); - CHECK_MPI_OK( mp_copy(qy, &s2) ); - } else { - CHECK_MPI_OK( mp_sqrmod(pz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(qx, &n0, p, &u2) ); - CHECK_MPI_OK( mp_mulmod(&n0, pz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(qy, &n0, p, &s2) ); - } - - /* Compute H = u2 - u1 ; G = s2 - s1 */ - CHECK_MPI_OK( mp_submod(&u2, &u1, p, &H) ); - CHECK_MPI_OK( mp_submod(&s2, &s1, p, &G) ); - - if (mp_cmp_z(&H) == 0) { - if (mp_cmp_z(&G) == 0) { - /* P = Q; double */ - err = GFp_ec_pt_dbl_jac(p, a, px, py, pz, - rx, ry, rz); - goto cleanup; - } else { - /* P = -Q; return point at infinity */ - CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) ); - goto cleanup; - } - } - - /* rz = pz * qz * H */ - if (mp_cmp_d(pz, 1) == 0) { - if (mp_cmp_d(qz, 1) == 0) { - /* if pz == qz == 1, then rz = H */ - CHECK_MPI_OK( mp_copy(&H, rz) ); - } else { - CHECK_MPI_OK( mp_mulmod(qz, &H, p, rz) ); - } - } else { - if (mp_cmp_d(qz, 1) == 0) { - CHECK_MPI_OK( mp_mulmod(pz, &H, p, rz) ); - } else { - CHECK_MPI_OK( mp_mulmod(pz, qz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(&n0, &H, p, rz) ); - } - } - - /* rx = G^2 - H^3 - 2 * u1 * H^2 */ - CHECK_MPI_OK( mp_sqrmod(&G, p, rx) ); - CHECK_MPI_OK( mp_sqrmod(&H, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(&n0, &u1, p, &u1) ); - CHECK_MPI_OK( mp_addmod(&u1, &u1, p, &u2) ); - CHECK_MPI_OK( mp_mulmod(&H, &n0, p, &H) ); - CHECK_MPI_OK( mp_submod(rx, &H, p, rx) ); - CHECK_MPI_OK( mp_submod(rx, &u2, p, rx) ); - - /* ry = - s1 * H^3 + G * (u1 * H^2 - rx) */ - /* (formula based on values of variables before block above) */ - CHECK_MPI_OK( mp_submod(&u1, rx, p, &u1) ); - CHECK_MPI_OK( mp_mulmod(&G, &u1, p, ry) ); - CHECK_MPI_OK( mp_mulmod(&s1, &H, p, &s1) ); - CHECK_MPI_OK( mp_submod(ry, &s1, p, ry) ); - -cleanup: - mp_clear(&n0); - mp_clear(&u1); - mp_clear(&u2); - mp_clear(&s1); - mp_clear(&s2); - mp_clear(&H); - mp_clear(&G); - return err; -} - -/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses - * Jacobian coordinates. - * - * This routine implements Point Doubling in the Jacobian Projective - * space as described in the paper "Efficient elliptic curve exponentiation - * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono. - */ -mp_err -GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *pz, mp_int *rx, mp_int *ry, mp_int *rz) -{ - mp_err err = MP_OKAY; - mp_int t0, t1, M, S; - MP_DIGITS(&t0) = 0; - MP_DIGITS(&t1) = 0; - MP_DIGITS(&M) = 0; - MP_DIGITS(&S) = 0; - CHECK_MPI_OK( mp_init(&t0) ); - CHECK_MPI_OK( mp_init(&t1) ); - CHECK_MPI_OK( mp_init(&M) ); - CHECK_MPI_OK( mp_init(&S) ); - - if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) { - CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) ); - goto cleanup; - } - - if (mp_cmp_d(pz, 1) == 0) { - /* M = 3 * px^2 + a */ - CHECK_MPI_OK( mp_sqrmod(px, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) ); - CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, a, p, &M) ); - } else if (mp_cmp_int(a, -3) == 0) { - /* M = 3 * (px + pz^2) * (px - pz) */ - CHECK_MPI_OK( mp_sqrmod(pz, p, &M) ); - CHECK_MPI_OK( mp_addmod(px, &M, p, &t0) ); - CHECK_MPI_OK( mp_submod(px, &M, p, &t1) ); - CHECK_MPI_OK( mp_mulmod(&t0, &t1, p, &M) ); - CHECK_MPI_OK( mp_addmod(&M, &M, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, &M, p, &M) ); - } else { - CHECK_MPI_OK( mp_sqrmod(px, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) ); - CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) ); - CHECK_MPI_OK( mp_sqrmod(pz, p, &M) ); - CHECK_MPI_OK( mp_sqrmod(&M, p, &M) ); - CHECK_MPI_OK( mp_mulmod(&M, a, p, &M) ); - CHECK_MPI_OK( mp_addmod(&M, &t0, p, &M) ); - } - - /* rz = 2 * py * pz */ - if (mp_cmp_d(pz, 1) == 0) { - CHECK_MPI_OK( mp_addmod(py, py, p, rz) ); - CHECK_MPI_OK( mp_sqrmod(rz, p, &t0) ); - } else { - CHECK_MPI_OK( mp_addmod(py, py, p, &t0) ); - CHECK_MPI_OK( mp_mulmod(&t0, pz, p, rz) ); - CHECK_MPI_OK( mp_sqrmod(&t0, p, &t0) ); - } - - /* S = 4 * px * py^2 = pz * (2 * py)^2 */ - CHECK_MPI_OK( mp_mulmod(px, &t0, p, &S) ); - - /* rx = M^2 - 2 * S */ - CHECK_MPI_OK( mp_addmod(&S, &S, p, &t1) ); - CHECK_MPI_OK( mp_sqrmod(&M, p, rx) ); - CHECK_MPI_OK( mp_submod(rx, &t1, p, rx) ); - - /* ry = M * (S - rx) - 8 * py^4 */ - CHECK_MPI_OK( mp_sqrmod(&t0, p, &t1) ); - if (mp_isodd(&t1)) { - CHECK_MPI_OK( mp_add(&t1, p, &t1) ); - } - CHECK_MPI_OK( mp_div_2(&t1, &t1) ); - CHECK_MPI_OK( mp_submod(&S, rx, p, &S) ); - CHECK_MPI_OK( mp_mulmod(&M, &S, p, &M) ); - CHECK_MPI_OK( mp_submod(&M, &t1, p, ry) ); - -cleanup: - mp_clear(&t0); - mp_clear(&t1); - mp_clear(&M); - mp_clear(&S); - return err; -} - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the prime that - * determines the field GFp. Elliptic curve points P and R can be - * identical. Uses Jacobian coordinates. - */ -mp_err -GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int k, qx, qy, qz, sx, sy, sz; - int i, l; - - MP_DIGITS(&k) = 0; - MP_DIGITS(&qx) = 0; - MP_DIGITS(&qy) = 0; - MP_DIGITS(&qz) = 0; - MP_DIGITS(&sx) = 0; - MP_DIGITS(&sy) = 0; - MP_DIGITS(&sz) = 0; - CHECK_MPI_OK( mp_init(&k) ); - CHECK_MPI_OK( mp_init(&qx) ); - CHECK_MPI_OK( mp_init(&qy) ); - CHECK_MPI_OK( mp_init(&qz) ); - CHECK_MPI_OK( mp_init(&sx) ); - CHECK_MPI_OK( mp_init(&sy) ); - CHECK_MPI_OK( mp_init(&sz) ); - - /* if n = 0 then r = inf */ - if (mp_cmp_z(n) == 0) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - /* if n < 0 then out of range error */ - } else if (mp_cmp_z(n) < 0) { - err = MP_RANGE; - goto cleanup; - } - /* Q = P, k = n */ - CHECK_MPI_OK( mp_copy(px, &qx) ); - CHECK_MPI_OK( mp_copy(py, &qy) ); - CHECK_MPI_OK( mp_set_int(&qz, 1) ); - CHECK_MPI_OK( mp_copy(n, &k) ); - - /* double and add method */ - l = mpl_significant_bits(&k) - 1; - mp_zero(&sx); - mp_zero(&sy); - mp_zero(&sz); - for (i = l; i >= 0; i--) { - /* if k_i = 1, then S = S + Q */ - if (MP_GET_BIT(&k, i) != 0) { - CHECK_MPI_OK( GFp_ec_pt_add_jac(p, a, &sx, &sy, &sz, - &qx, &qy, &qz, &sx, &sy, &sz) ); - } - if (i > 0) { - /* S = 2S */ - CHECK_MPI_OK( GFp_ec_pt_dbl_jac(p, a, &sx, &sy, &sz, - &sx, &sy, &sz) ); - } - } - - /* convert result S to affine coordinates */ - CHECK_MPI_OK( GFp_ec_pt_jac2aff(&sx, &sy, &sz, p, rx, ry) ); - -cleanup: - mp_clear(&k); - mp_clear(&qx); - mp_clear(&qy); - mp_clear(&qz); - mp_clear(&sx); - mp_clear(&sy); - mp_clear(&sz); - return err; -} -#endif /* NSS_ENABLE_ECC */ diff --git a/security/nss/lib/freebl/GFp_ecl.h b/security/nss/lib/freebl/GFp_ecl.h deleted file mode 100644 index d920b2e7c..000000000 --- a/security/nss/lib/freebl/GFp_ecl.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 elliptic curve math library for prime field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __gfp_ecl_h_ -#define __gfp_ecl_h_ -#ifdef NSS_ENABLE_ECC - -#include "secmpi.h" - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py); - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py); - -/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx, qy). - * Uses affine coordinates. - */ -extern mp_err GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = P - Q. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = 2P. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the prime that - * determines the field GFp. Uses affine coordinates. - */ -extern mp_err GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a, - const mp_int *b, const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry); - -/* Converts a point P(px, py, pz) from Jacobian projective coordinates to - * affine coordinates R(rx, ry). - */ -extern mp_err GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py, - const mp_int *pz, const mp_int *p, mp_int *rx, mp_int *ry); - -/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian - * coordinates. - */ -extern mp_err GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py, - const mp_int *pz); - -/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian - * coordinates. - */ -extern mp_err GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz); - -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and - * Q is (qx, qy, qz). Uses Jacobian coordinates. - */ -extern mp_err GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *pz, - const mp_int *qx, const mp_int *qy, const mp_int *qz, - mp_int *rx, mp_int *ry, mp_int *rz); - -/* Computes R = 2P. Uses Jacobian coordinates. */ -extern mp_err GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *pz, - mp_int *rx, mp_int *ry, mp_int *rz); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the prime that - * determines the field GFp. Uses Jacobian coordinates. - */ -mp_err GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry); - -#define GFp_ec_pt_is_inf(px, py) GFp_ec_pt_is_inf_aff((px), (py)) -#define GFp_ec_pt_add(p, a, px, py, qx, qy, rx, ry) \ - GFp_ec_pt_add_aff((p), (a), (px), (py), (qx), (qy), (rx), (ry)) - -#define GFp_ECL_JACOBIAN -#ifdef GFp_ECL_AFFINE -#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \ - GFp_ec_pt_mul_aff((p), (a), (b), (px), (py), (n), (rx), (ry)) -#elif defined(GFp_ECL_JACOBIAN) -#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \ - GFp_ec_pt_mul_jac((p), (a), (b), (px), (py), (n), (rx), (ry)) -#endif /* GFp_ECL_AFFINE or GFp_ECL_JACOBIAN*/ - -#endif /* NSS_ENABLE_ECC */ -#endif /* __gfp_ecl_h_ */ diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index 11c0843a8..a3100a5b9 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -98,7 +98,7 @@ ifdef NS_USE_GCC ASFILES = DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT else - ASFILES = mpi_x86.asm + MPI_SRCS += mpi_x86_asm.c DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD ifdef BUILD_OPT @@ -112,12 +112,6 @@ ifeq ($(OS_TARGET),WINCE) DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512 endif -ifdef XP_OS2_VACPP - ASFILES = mpi_x86.asm - DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE - DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD -endif - ifeq ($(OS_TARGET),IRIX) ifeq ($(USE_N32),1) ASFILES = mpi_mips.s @@ -137,12 +131,15 @@ ifeq ($(CPU_ARCH),x86_64) ASFLAGS += -march=opteron -m64 -fPIC DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY DEFINES += -DNSS_USE_COMBA + DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN +# DEFINES += -DMPI_AMD64_ADD MPI_SRCS += mpi_amd64.c mp_comba.c endif ifeq ($(CPU_ARCH),x86) ASFILES = mpi_x86.s DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE DEFINES += -DMP_ASSEMBLY_DIV_2DX1D + DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN # The floating point ECC code doesn't work on Linux x86 (bug 311432). #ECL_USE_FP = 1 endif @@ -171,13 +168,13 @@ ifdef USE_ABI32_INT32 DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512 else ifdef USE_64 -# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 32-bit digits +# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 64-bit digits MPI_SRCS += mpi_hp.c ASFILES += hpma512.s hppa20.s DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE else # this builds for DA2.0 (HP PA 2.0 Narrow) ABI32_FPU model -# (the 32-bit ABI with 64-bit registers) using 32-bit digits +# (the 32-bit ABI with 64-bit registers) using 64-bit digits MPI_SRCS += mpi_hp.c ASFILES += hpma512.s hppa20.s DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE @@ -188,6 +185,17 @@ endif endif endif +# The blapi functions are defined not only in the freebl shared +# libraries but also in the shared libraries linked with loader.c +# (libsoftokn3.so and libssl3.so). We need to use GNU ld's +# -Bsymbolic option or the equivalent option for other linkers +# to bind the blapi function references in FREEBLVector vector +# (ldvector.c) to the blapi functions defined in the freebl +# shared libraries. +ifeq (,$(filter-out BSD_OS FreeBSD Linux NetBSD, $(OS_TARGET))) + MKSHLIB += -Wl,-Bsymbolic +endif + ifeq ($(OS_TARGET),SunOS) # The -R '$ORIGIN' linker option instructs this library to search for its @@ -227,18 +235,36 @@ ifeq ($(CPU_ARCH),sparc) endif ifdef USE_ABI32_INT64 ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus + SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC endif ifdef USE_ABI32_FPU - ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus + ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plusa + SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC endif # USE_ABI32_FPU ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture + ARCHFLAG += -mcpu=v9 -Wa,-xarch=v9 + SOLARIS_AS_FLAGS = -xarch=v9 -K PIC endif ifdef USE_ABI64_FPU # this builds for Sparc v9a pure 64-bit architecture # It uses floating point, and 32-bit word size + ARCHFLAG += -mcpu=v9 -Wa,-xarch=v9a + SOLARIS_AS_FLAGS = -xarch=v9a -K PIC endif else # NS_USE_GCC + # FPU_TARGET_OPTIMIZER specifies the target processor and cache + # properties of the ABI32_FPU and ABI64_FPU architectures for use + # by the optimizer. + ifeq (,$(findstring Sun WorkShop 6,$(shell $(CC) -V 2>&1))) + # if the compiler is not Forte 6 + FPU_TARGET_OPTIMIZER = -xcache=64/32/4:1024/64/4 -xchip=ultra3 + else + # Forte 6 C compiler generates incorrect code for rijndael.c + # if -xchip=ultra3 is used (Bugzilla bug 333925). So we revert + # to what we used in NSS 3.10. + FPU_TARGET_OPTIMIZER = -xchip=ultra2 + endif ifdef USE_ABI32_INT32 #ARCHFLAG=-xarch=v8 set in coreconf/sunOS5.mk endif @@ -248,7 +274,10 @@ ifeq ($(CPU_ARCH),sparc) # no FPU (non-VIS cpus). # These flags were suggested by the compiler group for building # with SunStudio 10. - SOL_CFLAGS += -xO4 -xtarget=generic + ifdef BUILD_OPT + SOL_CFLAGS += -xO4 + endif + SOL_CFLAGS += -xtarget=generic ARCHFLAG = -xarch=v8plus SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC endif @@ -257,17 +286,23 @@ ifeq ($(CPU_ARCH),sparc) # 32-bit ABI, it uses FPU code, and 32-bit word size. # these flags were determined by running cc -### -fast and copying # the generated flag settings - SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle - SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all - SOL_CFLAGS += -xcache=64/32/4:1024/64/4 -xchip=ultra3 -xdepend - SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5 + SOL_CFLAGS += -fsingle -xmemalign=8s + ifdef BUILD_OPT + SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fsimple=1 + SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all + SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend + SOL_CFLAGS += -xlibmil -xO5 + endif ARCHFLAG = -xarch=v8plusa SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC endif ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture, # no FPU (non-VIS cpus). For building with SunStudio 10. - SOL_CFLAGS += -xO4 -xtarget=generic + ifdef BUILD_OPT + SOL_CFLAGS += -xO4 + endif + SOL_CFLAGS += -xtarget=generic ARCHFLAG = -xarch=v9 SOLARIS_AS_FLAGS = -xarch=v9 -K PIC endif @@ -275,16 +310,19 @@ ifeq ($(CPU_ARCH),sparc) # this builds for Sparc v9a pure 64-bit architecture # It uses floating point, and 32-bit word size. # See comment for USE_ABI32_FPU. - SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle - SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all - SOL_CFLAGS += -xcache=64/32/4:1024/64/4 -xchip=ultra3 -xdepend - SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5 + SOL_CFLAGS += -fsingle -xmemalign=8s + ifdef BUILD_OPT + SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fsimple=1 + SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all + SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend + SOL_CFLAGS += -xlibmil -xO5 + endif ARCHFLAG = -xarch=v9a SOLARIS_AS_FLAGS = -xarch=v9a -K PIC endif endif # NS_USE_GCC - ### set MP_ flags for both GCC and Sun cc + ### set flags for both GCC and Sun cc ifdef USE_ABI32_INT32 # this builds for Sparc v8 pure 32-bit architecture DEFINES += -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY @@ -303,6 +341,7 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv8.s montmulfv8.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL + ECL_USE_FP = 1 endif ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture @@ -315,9 +354,9 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv9.s montmulfv9.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL + ECL_USE_FP = 1 endif - ECL_USE_FP = 1 else # Solaris for non-sparc family CPUs ifdef NS_USE_GCC @@ -392,7 +431,6 @@ vpath %.h mpi ecl vpath %.c mpi ecl vpath %.S mpi ecl vpath %.s mpi ecl -vpath %.asm mpi ecl INCLUDES += -Impi -Iecl @@ -533,5 +571,19 @@ endif # FREEBL_CHILD_BUILD ifdef XP_OS2_VACPP $(OBJDIR)/alg2268.obj: alg2268.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) +endif + +# Bugzilla Bug 333917: the non-x86 code in desblapi.c seems to violate +# ANSI C's strict aliasing rules. +ifeq ($(OS_TARGET),Linux) +ifneq ($(CPU_ARCH),x86) +$(OBJDIR)/$(PROG_PREFIX)desblapi$(OBJ_SUFFIX): desblapi.c + @$(MAKE_OBJDIR) +ifdef NEED_ABSOLUTE_PATH + $(CC) -o $@ -c $(CFLAGS) -fno-strict-aliasing $(call core_abspath,$<) +else + $(CC) -o $@ -c $(CFLAGS) -fno-strict-aliasing $< +endif +endif endif diff --git a/security/nss/lib/freebl/arcfour-amd64-gas.s b/security/nss/lib/freebl/arcfour-amd64-gas.s index 66daf07ba..e131fd16a 100644 --- a/security/nss/lib/freebl/arcfour-amd64-gas.s +++ b/security/nss/lib/freebl/arcfour-amd64-gas.s @@ -114,3 +114,7 @@ ARCFOUR: ret .L_ARCFOUR_end: .size ARCFOUR,.L_ARCFOUR_end-ARCFOUR + +# Magic indicating no need for an executable stack +.section .note.GNU-stack,"",@progbits +.previous diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h index 899eadd45..06e3ef2ab 100644 --- a/security/nss/lib/freebl/blapi.h +++ b/security/nss/lib/freebl/blapi.h @@ -984,6 +984,50 @@ extern void RNG_RNGShutdown(void); extern void RNG_SystemInfoForRNG(void); +/* + * FIPS 186-2 Change Notice 1 RNG Algorithm 1, used both to + * generate the DSA X parameter and as a generic purpose RNG. + * + * The following two FIPS186Change functions are needed for + * NIST RNG Validation System. + */ + +/* + * Given the seed-key and the seed, generate the random output. + * + * Parameters: + * XKEY [input/output]: the state of the RNG (seed-key) + * XSEEDj [input]: optional user input (seed) + * x_j [output]: output of the RNG + * + * Return value: + * This function usually returns SECSuccess. The only reason + * this function returns SECFailure is that XSEEDj equals + * XKEY, including the intermediate XKEY value between the two + * iterations. (This test is actually a FIPS 140-2 requirement + * and not required for FIPS algorithm testing, but it is too + * hard to separate from this function.) If this function fails, + * XKEY is not updated, but some data may have been written to + * x_j, which should be ignored. + */ +extern SECStatus +FIPS186Change_GenerateX(unsigned char *XKEY, + const unsigned char *XSEEDj, + unsigned char *x_j); + +/* + * When generating the DSA X parameter, we generate 2*GSIZE bytes + * of random output and reduce it mod q. + * + * Input: w, 2*GSIZE bytes + * q, DSA_SUBPRIME_LEN bytes + * Output: xj, DSA_SUBPRIME_LEN bytes + */ +extern SECStatus +FIPS186Change_ReduceModQForDSA(const unsigned char *w, + const unsigned char *q, + unsigned char *xj); + /* 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. @@ -1043,6 +1087,8 @@ extern SECStatus PQG_VerifyParams(const PQGParams *params, */ extern void BL_Cleanup(void); +/* unload freebl shared library from memory */ +extern void BL_Unload(void); /************************************************************************** * Verify a given Shared library signature * diff --git a/security/nss/lib/freebl/config.mk b/security/nss/lib/freebl/config.mk index ecbc9373f..cef7dad9c 100644 --- a/security/nss/lib/freebl/config.mk +++ b/security/nss/lib/freebl/config.mk @@ -75,6 +75,10 @@ PROGRAM = EXTRA_LIBS += $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) +ifeq ($(OS_TARGET), SunOS) +OS_LIBS += -lkstat +endif + ifeq (,$(filter-out WIN%,$(OS_TARGET))) # don't want the 32 in the shared library name diff --git a/security/nss/lib/freebl/des.c b/security/nss/lib/freebl/des.c index 684a466f8..92c84692b 100644 --- a/security/nss/lib/freebl/des.c +++ b/security/nss/lib/freebl/des.c @@ -658,7 +658,7 @@ DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf) HALFPTR(outbuf)[0] = left; HALFPTR(outbuf)[1] = right; #else - if (((ptrdiff_t)inbuf & 0x03) == 0) { + if (((ptrdiff_t)outbuf & 0x03) == 0) { #if defined(IS_LITTLE_ENDIAN) BYTESWAP(left, temp); BYTESWAP(right, temp); diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c index 563e10438..196ad7442 100644 --- a/security/nss/lib/freebl/ec.c +++ b/security/nss/lib/freebl/ec.c @@ -42,6 +42,7 @@ #include "secerr.h" #include "secmpi.h" #include "secitem.h" +#include "mplogic.h" #include "ec.h" #include "ecl.h" @@ -53,7 +54,7 @@ PRBool ec_point_at_infinity(SECItem *pointP) { - int i; + unsigned int i; for (i = 1; i < pointP->len; i++) { if (pointP->data[i] != 0x00) return PR_FALSE; @@ -353,28 +354,26 @@ EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey, return rv; } -/* Generates a new EC key pair. The private key is a random value and - * the public key is the result of performing a scalar point multiplication - * of that value with the curve's base point. The random value for the - * private key is generated using the algorithm A.4.1 of ANSI X9.62, +/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62, * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the * random number generator. + * + * Parameters + * - order: a buffer that holds the curve's group order + * - len: the length in octets of the order buffer + * + * Return Value + * Returns a buffer of len octets that holds the private key. The caller + * is responsible for freeing the buffer with PORT_ZFree. */ -SECStatus -EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) +static unsigned char * +ec_GenerateRandomPrivateKey(const unsigned char *order, int len) { - SECStatus rv = SECFailure; -#ifdef NSS_ENABLE_ECC + SECStatus rv = SECSuccess; mp_err err; - int len; unsigned char *privKeyBytes = NULL; mp_int privKeyVal, order_1, one; - if (!ecParams || !privKey) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - MP_DIGITS(&privKeyVal) = 0; MP_DIGITS(&order_1) = 0; MP_DIGITS(&one) = 0; @@ -382,36 +381,62 @@ EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) CHECK_MPI_OK( mp_init(&order_1) ); CHECK_MPI_OK( mp_init(&one) ); - /* Generate random private key. - * Generates 2*len random bytes using the global random bit generator + /* Generates 2*len random bytes using the global random bit generator * (which implements Algorithm 1 of FIPS 186-2 Change Notice 1) then * reduces modulo the group order. */ - len = ecParams->order.len; if ((privKeyBytes = PORT_Alloc(2*len)) == NULL) goto cleanup; CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) ); CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) ); - CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, - ecParams->order.data, len) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) ); CHECK_MPI_OK( mp_set_int(&one, 1) ); CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) ); CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) ); CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) ); - CHECK_MPI_OK( mp_to_unsigned_octets(&privKeyVal, privKeyBytes, len) ); - /* generate public key */ - CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) ); - + CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) ); + memset(privKeyBytes+len, 0, len); cleanup: mp_clear(&privKeyVal); mp_clear(&order_1); mp_clear(&one); - if (privKeyBytes) { - PORT_ZFree(privKeyBytes, 2*len); - } if (err < MP_OKAY) { MP_TO_SEC_ERROR(err); rv = SECFailure; } + if (rv != SECSuccess && privKeyBytes) { + PORT_Free(privKeyBytes); + privKeyBytes = NULL; + } + return privKeyBytes; +} + +/* Generates a new EC key pair. The private key is a random value and + * the public key is the result of performing a scalar point multiplication + * of that value with the curve's base point. + */ +SECStatus +EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) +{ + SECStatus rv = SECFailure; +#ifdef NSS_ENABLE_ECC + int len; + unsigned char *privKeyBytes = NULL; + + if (!ecParams) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + len = ecParams->order.len; + privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len); + if (privKeyBytes == NULL) goto cleanup; + /* generate public key */ + CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) ); + +cleanup: + if (privKeyBytes) { + PORT_ZFree(privKeyBytes, len); + } #if EC_DEBUG printf("EC_NewKey returning %s\n", (rv == SECSuccess) ? "success" : "failure"); @@ -613,33 +638,41 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, mp_err err = MP_OKAY; ECParams *ecParams = NULL; SECItem kGpoint = { siBuffer, NULL, 0}; - int len = 0; + int flen = 0; /* length in bytes of the field size */ + unsigned olen; /* length in bytes of the base point order */ #if EC_DEBUG char mpstr[256]; #endif + /* Initialize MPI integers. */ + /* must happen before the first potential call to cleanup */ + MP_DIGITS(&x1) = 0; + MP_DIGITS(&d) = 0; + MP_DIGITS(&k) = 0; + MP_DIGITS(&r) = 0; + MP_DIGITS(&s) = 0; + MP_DIGITS(&n) = 0; + /* Check args */ - if (!key || !signature || !digest || !kb || (kblen < 0) || - (digest->len != SHA1_LENGTH)) { + if (!key || !signature || !digest || !kb || (kblen < 0)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); goto cleanup; } ecParams = &(key->ecParams); - len = (ecParams->fieldID.size + 7) >> 3; - if (signature->len < 2*len) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); + flen = (ecParams->fieldID.size + 7) >> 3; + olen = ecParams->order.len; + if (signature->data == NULL) { + /* a call to get the signature length only */ + goto finish; + } + if (signature->len < 2*olen) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); goto cleanup; } - /* Initialize MPI integers. */ - MP_DIGITS(&x1) = 0; - MP_DIGITS(&d) = 0; - MP_DIGITS(&k) = 0; - MP_DIGITS(&r) = 0; - MP_DIGITS(&s) = 0; - MP_DIGITS(&n) = 0; + CHECK_MPI_OK( mp_init(&x1) ); CHECK_MPI_OK( mp_init(&d) ); CHECK_MPI_OK( mp_init(&k) ); @@ -668,8 +701,8 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, ** ** Compute kG */ - kGpoint.len = 2*len + 1; - kGpoint.data = PORT_Alloc(2*len + 1); + kGpoint.len = 2*flen + 1; + kGpoint.data = PORT_Alloc(2*flen + 1); if ((kGpoint.data == NULL) || (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint) != SECSuccess)) @@ -681,7 +714,7 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, ** Extract the x co-ordinate of kG into x1 */ CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1, - (mp_size) len) ); + (mp_size) flen) ); /* ** ANSI X9.62, Section 5.3.3, Step 2 @@ -703,9 +736,16 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, /* ** ANSI X9.62, Section 5.3.3, Step 4 ** - ** s = (k**-1 * (SHA1(M) + d*r)) mod n + ** s = (k**-1 * (HASH(M) + d*r)) mod n */ - SECITEM_TO_MPINT(*digest, &s); /* s = SHA1(M) */ + SECITEM_TO_MPINT(*digest, &s); /* s = HASH(M) */ + + /* In the definition of EC signing, digests are truncated + * to the length of n in bits. + * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/ + if (digest->len*8 > ecParams->fieldID.size) { + mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size); + } #if EC_DEBUG mp_todecimal(&n, mpstr); @@ -748,9 +788,10 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, ** ** Signature is tuple (r, s) */ - CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, len) ); - CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + len, len) ); - signature->len = 2*len; + CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) ); + CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) ); +finish: + signature->len = 2*olen; rv = SECSuccess; err = MP_OKAY; @@ -763,7 +804,7 @@ cleanup: mp_clear(&n); if (kGpoint.data) { - PORT_ZFree(kGpoint.data, 2*len + 1); + PORT_ZFree(kGpoint.data, 2*flen + 1); } if (err) { @@ -791,47 +832,26 @@ ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest) { SECStatus rv = SECFailure; #ifdef NSS_ENABLE_ECC - int prerr = 0; - int n = key->ecParams.order.len; - unsigned char *kseed = NULL; - unsigned char *mask; - int i; + int len; + unsigned char *kBytes= NULL; - /* Generate random seed of appropriate size as dictated - * by field size. - */ - if ((kseed = PORT_Alloc(n)) == NULL) return SECFailure; - - do { - if (RNG_GenerateGlobalRandomBytes(kseed, n) != SECSuccess) - goto cleanup; - /* make sure that kseed is smaller than the curve order */ - mask = key->ecParams.order.data; - for (i = 0; (i < n) && (*mask == 0x00); i++, mask++) { -#if EC_DEBUG - printf("replacing byte %02x in position %d [n=%d] with zero\n", - *(kseed + i), i, n); -#endif - *(kseed + i) = 0x00; - } + if (!key) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } - if (i == n) { - rv = SECFailure; - prerr = SEC_ERROR_NEED_RANDOM; - } else { -#if EC_DEBUG - printf("replacing byte %02x in position %d [n=%d] with %d\n", - *(kseed + i), i, n, (*mask - 1)); -#endif - if (*(kseed + i) >= *mask) - *(kseed + i) = *mask - 1; - rv = ECDSA_SignDigestWithSeed(key, signature, digest, kseed, n); - if (rv) prerr = PORT_GetError(); - } - } while ((rv != SECSuccess) && (prerr == SEC_ERROR_NEED_RANDOM)); + /* Generate random value k */ + len = key->ecParams.order.len; + kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len); + if (kBytes == NULL) goto cleanup; + + /* Generate ECDSA signature with the specified k value */ + rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len); cleanup: - if (kseed) PORT_ZFree(kseed, n); + if (kBytes) { + PORT_ZFree(kBytes, len); + } #if EC_DEBUG printf("ECDSA signing %s\n", @@ -855,75 +875,65 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, #ifdef NSS_ENABLE_ECC mp_int r_, s_; /* tuple (r', s') is received signature) */ mp_int c, u1, u2, v; /* intermediate values used in verification */ - mp_int x1, y1; - mp_int x2, y2; + mp_int x1; mp_int n; mp_err err = MP_OKAY; - PRArenaPool *arena = NULL; ECParams *ecParams = NULL; - SECItem pointA = { siBuffer, NULL, 0 }; - SECItem pointB = { siBuffer, NULL, 0 }; SECItem pointC = { siBuffer, NULL, 0 }; - int len; + int slen; /* length in bytes of a half signature (r or s) */ + int flen; /* length in bytes of the field size */ + unsigned olen; /* length in bytes of the base point order */ #if EC_DEBUG char mpstr[256]; printf("ECDSA verification called\n"); #endif + /* Initialize MPI integers. */ + /* must happen before the first potential call to cleanup */ + MP_DIGITS(&r_) = 0; + MP_DIGITS(&s_) = 0; + MP_DIGITS(&c) = 0; + MP_DIGITS(&u1) = 0; + MP_DIGITS(&u2) = 0; + MP_DIGITS(&x1) = 0; + MP_DIGITS(&v) = 0; + MP_DIGITS(&n) = 0; + /* Check args */ - if (!key || !signature || !digest || - (digest->len != SHA1_LENGTH)) { + if (!key || !signature || !digest) { PORT_SetError(SEC_ERROR_INVALID_ARGS); goto cleanup; } ecParams = &(key->ecParams); - len = (ecParams->fieldID.size + 7) >> 3; - if (signature->len < 2*len) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); + flen = (ecParams->fieldID.size + 7) >> 3; + olen = ecParams->order.len; + if (signature->len == 0 || signature->len%2 != 0 || + signature->len > 2*olen) { + PORT_SetError(SEC_ERROR_INPUT_LEN); goto cleanup; } + slen = signature->len/2; - /* Initialize an arena for pointA, pointB and pointC */ - if ((arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)) == NULL) + SECITEM_AllocItem(NULL, &pointC, 2*flen + 1); + if (pointC.data == NULL) goto cleanup; - SECITEM_AllocItem(arena, &pointA, 2*len + 1); - SECITEM_AllocItem(arena, &pointB, 2*len + 1); - SECITEM_AllocItem(arena, &pointC, 2*len + 1); - if (pointA.data == NULL || pointB.data == NULL || pointC.data == NULL) - goto cleanup; - - /* Initialize MPI integers. */ - MP_DIGITS(&r_) = 0; - MP_DIGITS(&s_) = 0; - MP_DIGITS(&c) = 0; - MP_DIGITS(&u1) = 0; - MP_DIGITS(&u2) = 0; - MP_DIGITS(&x1) = 0; - MP_DIGITS(&y1) = 0; - MP_DIGITS(&x2) = 0; - MP_DIGITS(&y2) = 0; - MP_DIGITS(&v) = 0; - MP_DIGITS(&n) = 0; CHECK_MPI_OK( mp_init(&r_) ); CHECK_MPI_OK( mp_init(&s_) ); CHECK_MPI_OK( mp_init(&c) ); CHECK_MPI_OK( mp_init(&u1) ); CHECK_MPI_OK( mp_init(&u2) ); CHECK_MPI_OK( mp_init(&x1) ); - CHECK_MPI_OK( mp_init(&y1) ); - CHECK_MPI_OK( mp_init(&x2) ); - CHECK_MPI_OK( mp_init(&y2) ); CHECK_MPI_OK( mp_init(&v) ); CHECK_MPI_OK( mp_init(&n) ); /* ** Convert received signature (r', s') into MPI integers. */ - CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, len) ); - CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + len, len) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) ); /* ** ANSI X9.62, Section 5.4.2, Steps 1 and 2 @@ -932,8 +942,10 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, */ SECITEM_TO_MPINT(ecParams->order, &n); if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 || - mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) + mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); goto cleanup; /* will return rv == SECFailure */ + } /* ** ANSI X9.62, Section 5.4.2, Step 3 @@ -945,9 +957,16 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, /* ** ANSI X9.62, Section 5.4.2, Step 4 ** - ** u1 = ((SHA1(M')) * c) mod n + ** u1 = ((HASH(M')) * c) mod n */ - SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */ + SECITEM_TO_MPINT(*digest, &u1); /* u1 = HASH(M) */ + + /* In the definition of EC signing, digests are truncated + * to the length of n in bits. + * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/ + if (digest->len*8 > ecParams->fieldID.size) { /* u1 = HASH(M') */ + mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size); + } #if EC_DEBUG mp_todecimal(&r_, mpstr); @@ -976,13 +995,18 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, ** Here, A = u1.G B = u2.Q and C = A + B ** If the result, C, is the point at infinity, reject the signature */ - if ((ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC) == SECFailure) || - ec_point_at_infinity(&pointC)) { - rv = SECFailure; - goto cleanup; + if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC) + != SECSuccess) { + rv = SECFailure; + goto cleanup; + } + if (ec_point_at_infinity(&pointC)) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + rv = SECFailure; + goto cleanup; } - CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, len) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) ); /* ** ANSI X9.62, Section 5.4.4, Step 2 @@ -1028,13 +1052,10 @@ cleanup: mp_clear(&u1); mp_clear(&u2); mp_clear(&x1); - mp_clear(&y1); - mp_clear(&x2); - mp_clear(&y2); mp_clear(&v); mp_clear(&n); - if (arena) PORT_FreeArena(arena, PR_TRUE); + if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE); if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; diff --git a/security/nss/lib/freebl/ecl/Makefile b/security/nss/lib/freebl/ecl/Makefile index c791531eb..7af8d48e3 100644 --- a/security/nss/lib/freebl/ecl/Makefile +++ b/security/nss/lib/freebl/ecl/Makefile @@ -113,7 +113,7 @@ LIBOBJS = ecl.o ecl_curve.o ecl_mult.o ecl_gf.o \ ec2_163.o ec2_193.o ec2_233.o \ ecp_aff.o ecp_jac.o ecp_mont.o \ ec_naf.o ecp_jm.o \ - ecp_192.o ecp_224.o + ecp_192.o ecp_224.o ecp_256.o ecp_384.o ecp_521.o ifeq ($(ECL_USE_FP),1) LIBOBJS+= ecp_fp160.o ecp_fp192.o ecp_fp224.o ecp_fp.o endif @@ -162,6 +162,9 @@ ecp_jm.o: ecp_jm.c $(LIBHDRS) ecp_mont.o: ecp_mont.c $(LIBHDRS) ecp_192.o: ecp_192.c $(LIBHDRS) ecp_224.o: ecp_224.c $(LIBHDRS) +ecp_256.o: ecp_256.c $(LIBHDRS) +ecp_384.o: ecp_384.c $(LIBHDRS) +ecp_521.o: ecp_521.c $(LIBHDRS) ecp_fp.o: ecp_fp.c $(LIBHDRS) ifeq ($(ECL_USE_FP),1) ecp_fp160.o: ecp_fp160.c ecp_fpinc.c $(LIBHDRS) diff --git a/security/nss/lib/freebl/ecl/ec2_aff.c b/security/nss/lib/freebl/ecl/ec2_aff.c index 45b277001..64bb6fecc 100644 --- a/security/nss/lib/freebl/ecl/ec2_aff.c +++ b/security/nss/lib/freebl/ecl/ec2_aff.c @@ -312,7 +312,6 @@ ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group) /* left-hand side: y^2 + x*y */ MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) ); MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) ); - MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) ); MP_CHECKOK( group->meth->field_add(&accl, &tmp, &accl, group->meth) ); /* right-hand side: x^3 + a*x^2 + b */ MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) ); diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h index cba22b2a7..3a01dc835 100644 --- a/security/nss/lib/freebl/ecl/ecl-curve.h +++ b/security/nss/lib/freebl/ecl/ecl-curve.h @@ -42,25 +42,10 @@ #ifndef __ecl_curve_h_ #define __ecl_curve_h_ -/* NIST prime curves */ -static const ECCurveParams ecCurve_NIST_P192 = { - "NIST-P192", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 1 -}; -static const ECCurveParams ecCurve_NIST_P224 = { - "NIST-P224", ECField_GFp, 224, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", - "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1 -}; +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#error This source file is for Basic ECC only . +#endif + static const ECCurveParams ecCurve_NIST_P256 = { "NIST-P256", ECField_GFp, 256, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", @@ -70,6 +55,7 @@ static const ECCurveParams ecCurve_NIST_P256 = { "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1 }; + static const ECCurveParams ecCurve_NIST_P384 = { "NIST-P384", ECField_GFp, 384, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", @@ -80,6 +66,7 @@ static const ECCurveParams ecCurve_NIST_P384 = { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", 1 }; + static const ECCurveParams ecCurve_NIST_P521 = { "NIST-P521", ECField_GFp, 521, "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", @@ -91,558 +78,67 @@ static const ECCurveParams ecCurve_NIST_P521 = { 1 }; -/* NIST binary curves */ -static const ECCurveParams ecCurve_NIST_K163 = { - "NIST-K163", ECField_GF2m, 163, - "0800000000000000000000000000000000000000C9", - "000000000000000000000000000000000000000001", - "000000000000000000000000000000000000000001", - "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", - "0289070FB05D38FF58321F2E800536D538CCDAA3D9", - "04000000000000000000020108A2E0CC0D99F8A5EF", 2 -}; -static const ECCurveParams ecCurve_NIST_B163 = { - "NIST-B163", ECField_GF2m, 163, - "0800000000000000000000000000000000000000C9", - "000000000000000000000000000000000000000001", - "020A601907B8C953CA1481EB10512F78744A3205FD", - "03F0EBA16286A2D57EA0991168D4994637E8343E36", - "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", - "040000000000000000000292FE77E70C12A4234C33", 2 -}; -static const ECCurveParams ecCurve_NIST_K233 = { - "NIST-K233", ECField_GF2m, 233, - "020000000000000000000000000000000000000004000000000000000001", - "000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000001", - "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", - "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", - "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4 -}; -static const ECCurveParams ecCurve_NIST_B233 = { - "NIST-B233", ECField_GF2m, 233, - "020000000000000000000000000000000000000004000000000000000001", - "000000000000000000000000000000000000000000000000000000000001", - "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", - "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", - "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", - "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2 -}; -static const ECCurveParams ecCurve_NIST_K283 = { - "NIST-K283", ECField_GF2m, 283, - "0800000000000000000000000000000000000000000000000000000000000000000010A1", - "000000000000000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000000000001", - "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", - "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", - 4 -}; -static const ECCurveParams ecCurve_NIST_B283 = { - "NIST-B283", ECField_GF2m, 283, - "0800000000000000000000000000000000000000000000000000000000000000000010A1", - "000000000000000000000000000000000000000000000000000000000000000000000001", - "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", - "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", - "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", - 2 -}; -static const ECCurveParams ecCurve_NIST_K409 = { - "NIST-K409", ECField_GF2m, 409, - "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", - "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", - "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", - 4 -}; -static const ECCurveParams ecCurve_NIST_B409 = { - "NIST-B409", ECField_GF2m, 409, - "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", - "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", - "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", - "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", - 2 -}; -static const ECCurveParams ecCurve_NIST_K571 = { - "NIST-K571", ECField_GF2m, 571, - "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", - "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", - "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", - 4 -}; -static const ECCurveParams ecCurve_NIST_B571 = { - "NIST-B571", ECField_GF2m, 571, - "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", - "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", - "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", - 2 -}; - -/* ANSI X9.62 prime curves */ -static const ECCurveParams ecCurve_X9_62_PRIME_192V2 = { - "X9.62 P-192V2", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", - "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", - "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", - "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_192V3 = { - "X9.62 P-192V3", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", - "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", - "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", - "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_239V1 = { - "X9.62 P-239V1", ECField_GFp, 239, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", - "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", - "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_239V2 = { - "X9.62 P-239V2", ECField_GFp, 239, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", - "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", - "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", - "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_239V3 = { - "X9.62 P-239V3", ECField_GFp, 239, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", - "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", - "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", 1 -}; - -/* ANSI X9.62 binary curves */ -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V1 = { - "X9.62 C2-PNB163V1", ECField_GF2m, 163, - "080000000000000000000000000000000000000107", - "072546B5435234A422E0789675F432C89435DE5242", - "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", - "07AF69989546103D79329FCC3D74880F33BBE803CB", - "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", - "0400000000000000000001E60FC8821CC74DAEAFC1", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V2 = { - "X9.62 C2-PNB163V2", ECField_GF2m, 163, - "080000000000000000000000000000000000000107", - "0108B39E77C4B108BED981ED0E890E117C511CF072", - "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", - "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", - "079F684DDF6684C5CD258B3890021B2386DFD19FC5", - "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V3 = { - "X9.62 C2-PNB163V3", ECField_GF2m, 163, - "080000000000000000000000000000000000000107", - "07A526C63D3E25A256A007699F5447E32AE456B50E", - "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", - "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", - "05B935590C155E17EA48EB3FF3718B893DF59A05D0", - "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB176V1 = { - "X9.62 C2-PNB176V1", ECField_GF2m, 176, - "0100000000000000000000000000000000080000000007", - "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", - "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", - "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", - "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", - "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V1 = { - "X9.62 C2-TNB191V1", ECField_GF2m, 191, - "800000000000000000000000000000000000000000000201", - "2866537B676752636A68F56554E12640276B649EF7526267", - "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", - "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", - "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", - "40000000000000000000000004A20E90C39067C893BBB9A5", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V2 = { - "X9.62 C2-TNB191V2", ECField_GF2m, 191, - "800000000000000000000000000000000000000000000201", - "401028774D7777C7B7666D1366EA432071274F89FF01E718", - "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", - "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", - "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", - "20000000000000000000000050508CB89F652824E06B8173", 4 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V3 = { - "X9.62 C2-TNB191V3", ECField_GF2m, 191, - "800000000000000000000000000000000000000000000201", - "6C01074756099122221056911C77D77E77A777E7E7E77FCB", - "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", - "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", - "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", - "155555555555555555555555610C0B196812BFB6288A3EA3", 6 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB208W1 = { - "X9.62 C2-PNB208W1", ECField_GF2m, 208, - "010000000000000000000000000000000800000000000000000007", - "0000000000000000000000000000000000000000000000000000", - "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", - "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", - "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", - "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V1 = { - "X9.62 C2-TNB239V1", ECField_GF2m, 239, - "800000000000000000000000000000000000000000000000001000000001", - "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", - "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", - "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", - "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", - "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V2 = { - "X9.62 C2-TNB239V2", ECField_GF2m, 239, - "800000000000000000000000000000000000000000000000001000000001", - "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", - "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", - "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", - "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", - "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V3 = { - "X9.62 C2-TNB239V3", ECField_GF2m, 239, - "800000000000000000000000000000000000000000000000001000000001", - "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", - "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", - "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", - "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", - "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB272W1 = { - "X9.62 C2-PNB272W1", ECField_GF2m, 272, - "010000000000000000000000000000000000000000000000000000010000000000000B", - "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", - "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", - "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", - "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", - "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", - 0xFF06 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB304W1 = { - "X9.62 C2-PNB304W1", ECField_GF2m, 304, - "010000000000000000000000000000000000000000000000000000000000000000000000000807", - "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", - "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", - "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614", - "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B", - "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", - 0xFE2E -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB359V1 = { - "X9.62 C2-TNB359V1", ECField_GF2m, 359, - "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001", - "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", - "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", - "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097", - "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD", - "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", - 0x4C -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB368W1 = { - "X9.62 C2-PNB368W1", ECField_GF2m, 368, - "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007", - "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", - "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", - "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F", - "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310", - "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", - 0xFF70 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB431R1 = { - "X9.62 C2-TNB431R1", ECField_GF2m, 431, - "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001", - "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", - "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", - "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", - "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", - "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", - 0x2760 -}; - -/* SEC2 prime curves */ -static const ECCurveParams ecCurve_SECG_PRIME_112R1 = { - "SECP-112R1", ECField_GFp, 112, - "DB7C2ABF62E35E668076BEAD208B", - "DB7C2ABF62E35E668076BEAD2088", - "659EF8BA043916EEDE8911702B22", - "09487239995A5EE76B55F9C2F098", - "A89CE5AF8724C0A23E0E0FF77500", - "DB7C2ABF62E35E7628DFAC6561C5", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_112R2 = { - "SECP-112R2", ECField_GFp, 112, - "DB7C2ABF62E35E668076BEAD208B", - "6127C24C05F38A0AAAF65C0EF02C", - "51DEF1815DB5ED74FCC34C85D709", - "4BA30AB5E892B4E1649DD0928643", - "adcd46f5882e3747def36e956e97", - "36DF0AAFD8B8D7597CA10520D04B", 4 -}; -static const ECCurveParams ecCurve_SECG_PRIME_128R1 = { - "SECP-128R1", ECField_GFp, 128, - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", - "E87579C11079F43DD824993C2CEE5ED3", - "161FF7528B899B2D0C28607CA52C5B86", - "CF5AC8395BAFEB13C02DA292DDED7A83", - "FFFFFFFE0000000075A30D1B9038A115", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_128R2 = { - "SECP-128R2", ECField_GFp, 128, - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "D6031998D1B3BBFEBF59CC9BBFF9AEE1", - "5EEEFCA380D02919DC2C6558BB6D8A5D", - "7B6AA5D85E572983E6FB32A7CDEBC140", - "27B6916A894D3AEE7106FE805FC34B44", - "3FFFFFFF7FFFFFFFBE0024720613B5A3", 4 -}; -static const ECCurveParams ecCurve_SECG_PRIME_160K1 = { - "SECP-160K1", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000007", - "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", - "938CF935318FDCED6BC28286531733C3F03C4FEE", - "0100000000000000000001B8FA16DFAB9ACA16B6B3", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_160R1 = { - "SECP-160R1", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", - "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", - "4A96B5688EF573284664698968C38BB913CBFC82", - "23A628553168947D59DCC912042351377AC5FB32", - "0100000000000000000001F4C8F927AED3CA752257", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_160R2 = { - "SECP-160R2", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", - "B4E134D3FB59EB8BAB57274904664D5AF50388BA", - "52DCB034293A117E1F4FF11B30F7199D3144CE6D", - "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", - "0100000000000000000000351EE786A818F3A1A16B", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_192K1 = { - "SECP-192K1", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", - "000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000003", - "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", - "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", - "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_224K1 = { - "SECP-224K1", ECField_GFp, 224, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", - "00000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000000000000000000000000005", - "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", - "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", - "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_256K1 = { - "SECP-256K1", ECField_GFp, 256, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000007", - "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 1 -}; - -/* SEC2 binary curves */ -static const ECCurveParams ecCurve_SECG_CHAR2_113R1 = { - "SECT-113R1", ECField_GF2m, 113, - "020000000000000000000000000201", - "003088250CA6E7C7FE649CE85820F7", - "00E8BEE4D3E2260744188BE0E9C723", - "009D73616F35F4AB1407D73562C10F", - "00A52830277958EE84D1315ED31886", - "0100000000000000D9CCEC8A39E56F", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_113R2 = { - "SECT-113R2", ECField_GF2m, 113, - "020000000000000000000000000201", - "00689918DBEC7E5A0DD6DFC0AA55C7", - "0095E9A9EC9B297BD4BF36E059184F", - "01A57A6A7B26CA5EF52FCDB8164797", - "00B3ADC94ED1FE674C06E695BABA1D", - "010000000000000108789B2496AF93", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_131R1 = { - "SECT-131R1", ECField_GF2m, 131, - "080000000000000000000000000000010D", - "07A11B09A76B562144418FF3FF8C2570B8", - "0217C05610884B63B9C6C7291678F9D341", - "0081BAF91FDF9833C40F9C181343638399", - "078C6E7EA38C001F73C8134B1B4EF9E150", - "0400000000000000023123953A9464B54D", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_131R2 = { - "SECT-131R2", ECField_GF2m, 131, - "080000000000000000000000000000010D", - "03E5A88919D7CAFCBF415F07C2176573B2", - "04B8266A46C55657AC734CE38F018F2192", - "0356DCD8F2F95031AD652D23951BB366A8", - "0648F06D867940A5366D9E265DE9EB240F", - "0400000000000000016954A233049BA98F", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_163R1 = { - "SECT-163R1", ECField_GF2m, 163, - "0800000000000000000000000000000000000000C9", - "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", - "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", - "0369979697AB43897789566789567F787A7876A654", - "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", - "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_193R1 = { - "SECT-193R1", ECField_GF2m, 193, - "02000000000000000000000000000000000000000000008001", - "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", - "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", - "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", - "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", - "01000000000000000000000000C7F34A778F443ACC920EBA49", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_193R2 = { - "SECT-193R2", ECField_GF2m, 193, - "02000000000000000000000000000000000000000000008001", - "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", - "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", - "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", - "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", - "010000000000000000000000015AAB561B005413CCD4EE99D5", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_239K1 = { - "SECT-239K1", ECField_GF2m, 239, - "800000000000000000004000000000000000000000000000000000000001", - "000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000001", - "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", - "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", - "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4 -}; - -/* WTLS curves */ -static const ECCurveParams ecCurve_WTLS_1 = { - "WTLS-1", ECField_GF2m, 113, - "020000000000000000000000000201", - "000000000000000000000000000001", - "000000000000000000000000000001", - "01667979A40BA497E5D5C270780617", - "00F44B4AF1ECC2630E08785CEBCC15", - "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2 -}; -static const ECCurveParams ecCurve_WTLS_8 = { - "WTLS-8", ECField_GFp, 112, - "FFFFFFFFFFFFFFFFFFFFFFFFFDE7", - "0000000000000000000000000000", - "0000000000000000000000000003", - "0000000000000000000000000001", - "0000000000000000000000000002", - "0100000000000001ECEA551AD837E9", 1 -}; -static const ECCurveParams ecCurve_WTLS_9 = { - "WTLS-9", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000003", - "0000000000000000000000000000000000000001", - "0000000000000000000000000000000000000002", - "0100000000000000000001CDC98AE0E2DE574ABF33", 1 -}; - /* mapping between ECCurveName enum and pointers to ECCurveParams */ static const ECCurveParams *ecCurve_map[] = { - NULL, /* ECCurve_noName */ - &ecCurve_NIST_P192, /* ECCurve_NIST_P192 */ - &ecCurve_NIST_P224, /* ECCurve_NIST_P224 */ - &ecCurve_NIST_P256, /* ECCurve_NIST_P256 */ - &ecCurve_NIST_P384, /* ECCurve_NIST_P384 */ - &ecCurve_NIST_P521, /* ECCurve_NIST_P521 */ - &ecCurve_NIST_K163, /* ECCurve_NIST_K163 */ - &ecCurve_NIST_B163, /* ECCurve_NIST_B163 */ - &ecCurve_NIST_K233, /* ECCurve_NIST_K233 */ - &ecCurve_NIST_B233, /* ECCurve_NIST_B233 */ - &ecCurve_NIST_K283, /* ECCurve_NIST_K283 */ - &ecCurve_NIST_B283, /* ECCurve_NIST_B283 */ - &ecCurve_NIST_K409, /* ECCurve_NIST_K409 */ - &ecCurve_NIST_B409, /* ECCurve_NIST_B409 */ - &ecCurve_NIST_K571, /* ECCurve_NIST_K571 */ - &ecCurve_NIST_B571, /* ECCurve_NIST_B571 */ - &ecCurve_X9_62_PRIME_192V2, /* ECCurve_X9_62_PRIME_192V2 */ - &ecCurve_X9_62_PRIME_192V3, /* ECCurve_X9_62_PRIME_192V3 */ - &ecCurve_X9_62_PRIME_239V1, /* ECCurve_X9_62_PRIME_239V1 */ - &ecCurve_X9_62_PRIME_239V2, /* ECCurve_X9_62_PRIME_239V2 */ - &ecCurve_X9_62_PRIME_239V3, /* ECCurve_X9_62_PRIME_239V3 */ - &ecCurve_X9_62_CHAR2_PNB163V1, /* ECCurve_X9_62_CHAR2_PNB163V1 */ - &ecCurve_X9_62_CHAR2_PNB163V2, /* ECCurve_X9_62_CHAR2_PNB163V2 */ - &ecCurve_X9_62_CHAR2_PNB163V3, /* ECCurve_X9_62_CHAR2_PNB163V3 */ - &ecCurve_X9_62_CHAR2_PNB176V1, /* ECCurve_X9_62_CHAR2_PNB176V1 */ - &ecCurve_X9_62_CHAR2_TNB191V1, /* ECCurve_X9_62_CHAR2_TNB191V1 */ - &ecCurve_X9_62_CHAR2_TNB191V2, /* ECCurve_X9_62_CHAR2_TNB191V2 */ - &ecCurve_X9_62_CHAR2_TNB191V3, /* ECCurve_X9_62_CHAR2_TNB191V3 */ - &ecCurve_X9_62_CHAR2_PNB208W1, /* ECCurve_X9_62_CHAR2_PNB208W1 */ - &ecCurve_X9_62_CHAR2_TNB239V1, /* ECCurve_X9_62_CHAR2_TNB239V1 */ - &ecCurve_X9_62_CHAR2_TNB239V2, /* ECCurve_X9_62_CHAR2_TNB239V2 */ - &ecCurve_X9_62_CHAR2_TNB239V3, /* ECCurve_X9_62_CHAR2_TNB239V3 */ - &ecCurve_X9_62_CHAR2_PNB272W1, /* ECCurve_X9_62_CHAR2_PNB272W1 */ - &ecCurve_X9_62_CHAR2_PNB304W1, /* ECCurve_X9_62_CHAR2_PNB304W1 */ - &ecCurve_X9_62_CHAR2_TNB359V1, /* ECCurve_X9_62_CHAR2_TNB359V1 */ - &ecCurve_X9_62_CHAR2_PNB368W1, /* ECCurve_X9_62_CHAR2_PNB368W1 */ - &ecCurve_X9_62_CHAR2_TNB431R1, /* ECCurve_X9_62_CHAR2_TNB431R1 */ - &ecCurve_SECG_PRIME_112R1, /* ECCurve_SECG_PRIME_112R1 */ - &ecCurve_SECG_PRIME_112R2, /* ECCurve_SECG_PRIME_112R2 */ - &ecCurve_SECG_PRIME_128R1, /* ECCurve_SECG_PRIME_128R1 */ - &ecCurve_SECG_PRIME_128R2, /* ECCurve_SECG_PRIME_128R2 */ - &ecCurve_SECG_PRIME_160K1, /* ECCurve_SECG_PRIME_160K1 */ - &ecCurve_SECG_PRIME_160R1, /* ECCurve_SECG_PRIME_160R1 */ - &ecCurve_SECG_PRIME_160R2, /* ECCurve_SECG_PRIME_160R2 */ - &ecCurve_SECG_PRIME_192K1, /* ECCurve_SECG_PRIME_192K1 */ - &ecCurve_SECG_PRIME_224K1, /* ECCurve_SECG_PRIME_224K1 */ - &ecCurve_SECG_PRIME_256K1, /* ECCurve_SECG_PRIME_256K1 */ - &ecCurve_SECG_CHAR2_113R1, /* ECCurve_SECG_CHAR2_113R1 */ - &ecCurve_SECG_CHAR2_113R2, /* ECCurve_SECG_CHAR2_113R2 */ - &ecCurve_SECG_CHAR2_131R1, /* ECCurve_SECG_CHAR2_131R1 */ - &ecCurve_SECG_CHAR2_131R2, /* ECCurve_SECG_CHAR2_131R2 */ - &ecCurve_SECG_CHAR2_163R1, /* ECCurve_SECG_CHAR2_163R1 */ - &ecCurve_SECG_CHAR2_193R1, /* ECCurve_SECG_CHAR2_193R1 */ - &ecCurve_SECG_CHAR2_193R2, /* ECCurve_SECG_CHAR2_193R2 */ - &ecCurve_SECG_CHAR2_239K1, /* ECCurve_SECG_CHAR2_239K1 */ - &ecCurve_WTLS_1, /* ECCurve_WTLS_1 */ - &ecCurve_WTLS_8, /* ECCurve_WTLS_8 */ - &ecCurve_WTLS_9, /* ECCurve_WTLS_9 */ - NULL /* ECCurve_pastLastCurve */ + NULL, /* ECCurve_noName */ + NULL, /* ECCurve_NIST_P192 */ + NULL, /* ECCurve_NIST_P224 */ + &ecCurve_NIST_P256, /* ECCurve_NIST_P256 */ + &ecCurve_NIST_P384, /* ECCurve_NIST_P384 */ + &ecCurve_NIST_P521, /* ECCurve_NIST_P521 */ + NULL, /* ECCurve_NIST_K163 */ + NULL, /* ECCurve_NIST_B163 */ + NULL, /* ECCurve_NIST_K233 */ + NULL, /* ECCurve_NIST_B233 */ + NULL, /* ECCurve_NIST_K283 */ + NULL, /* ECCurve_NIST_B283 */ + NULL, /* ECCurve_NIST_K409 */ + NULL, /* ECCurve_NIST_B409 */ + NULL, /* ECCurve_NIST_K571 */ + NULL, /* ECCurve_NIST_B571 */ + NULL, /* ECCurve_X9_62_PRIME_192V2 */ + NULL, /* ECCurve_X9_62_PRIME_192V3 */ + NULL, /* ECCurve_X9_62_PRIME_239V1 */ + NULL, /* ECCurve_X9_62_PRIME_239V2 */ + NULL, /* ECCurve_X9_62_PRIME_239V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB163V1 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB163V2 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB163V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB176V1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB191V1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB191V2 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB191V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB208W1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB239V1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB239V2 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB239V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB272W1 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB304W1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB359V1 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB368W1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB431R1 */ + NULL, /* ECCurve_SECG_PRIME_112R1 */ + NULL, /* ECCurve_SECG_PRIME_112R2 */ + NULL, /* ECCurve_SECG_PRIME_128R1 */ + NULL, /* ECCurve_SECG_PRIME_128R2 */ + NULL, /* ECCurve_SECG_PRIME_160K1 */ + NULL, /* ECCurve_SECG_PRIME_160R1 */ + NULL, /* ECCurve_SECG_PRIME_160R2 */ + NULL, /* ECCurve_SECG_PRIME_192K1 */ + NULL, /* ECCurve_SECG_PRIME_224K1 */ + NULL, /* ECCurve_SECG_PRIME_256K1 */ + NULL, /* ECCurve_SECG_CHAR2_113R1 */ + NULL, /* ECCurve_SECG_CHAR2_113R2 */ + NULL, /* ECCurve_SECG_CHAR2_131R1 */ + NULL, /* ECCurve_SECG_CHAR2_131R2 */ + NULL, /* ECCurve_SECG_CHAR2_163R1 */ + NULL, /* ECCurve_SECG_CHAR2_193R1 */ + NULL, /* ECCurve_SECG_CHAR2_193R2 */ + NULL, /* ECCurve_SECG_CHAR2_239K1 */ + NULL, /* ECCurve_WTLS_1 */ + NULL, /* ECCurve_WTLS_8 */ + NULL, /* ECCurve_WTLS_9 */ + NULL /* ECCurve_pastLastCurve */ }; #endif diff --git a/security/nss/lib/freebl/ecl/ecl-priv.h b/security/nss/lib/freebl/ecl/ecl-priv.h index bce7ccf09..05abb4dff 100644 --- a/security/nss/lib/freebl/ecl/ecl-priv.h +++ b/security/nss/lib/freebl/ecl/ecl-priv.h @@ -45,22 +45,62 @@ #include "mplogic.h" /* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */ +/* the following needs to go away... */ #if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT) #define ECL_SIXTY_FOUR_BIT -#define ECL_BITS 64 -#define ECL_MAX_FIELD_SIZE_DIGITS 10 #else #define ECL_THIRTY_TWO_BIT -#define ECL_BITS 32 -#define ECL_MAX_FIELD_SIZE_DIGITS 20 #endif +#define ECL_CURVE_DIGITS(curve_size_in_bits) \ + (((curve_size_in_bits)+(sizeof(mp_digit)*8-1))/(sizeof(mp_digit)*8)) +#define ECL_BITS (sizeof(mp_digit)*8) +#define ECL_MAX_FIELD_SIZE_DIGITS (80/sizeof(mp_digit)) + /* Gets the i'th bit in the binary representation of a. If i >= length(a), * then return 0. (The above behaviour differs from mpl_get_bit, which * causes an error if i >= length(a).) */ #define MP_GET_BIT(a, i) \ ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i)) +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) +#define MP_ADD_CARRY(a1, a2, s, cin, cout) \ + { mp_word w; \ + w = ((mp_word)(cin)) + (a1) + (a2); \ + s = ACCUM(w); \ + cout = CARRYOUT(w); } + +#define MP_SUB_BORROW(a1, a2, s, bin, bout) \ + { mp_word w; \ + w = ((mp_word)(a1)) - (a2) - (bin); \ + s = ACCUM(w); \ + bout = (w >> MP_DIGIT_BIT) & 1; } + +#else +/* NOTE, + * cin and cout could be the same variable. + * bin and bout could be the same variable. + * a1 or a2 and s could be the same variable. + * don't trash those outputs until their respective inputs have + * been read. */ +#define MP_ADD_CARRY(a1, a2, s, cin, cout) \ + { mp_digit tmp,sum; \ + tmp = (a1); \ + sum = tmp + (a2); \ + tmp = (sum < tmp); /* detect overflow */ \ + s = sum += (cin); \ + cout = tmp + (sum < (cin)); } + +#define MP_SUB_BORROW(a1, a2, s, bin, bout) \ + { mp_digit tmp; \ + tmp = (a1); \ + s = tmp - (a2); \ + tmp = (s > tmp); /* detect borrow */ \ + if ((bin) && !s--) tmp++; \ + bout = tmp; } +#endif + + struct GFMethodStr; typedef struct GFMethodStr GFMethod; struct GFMethodStr { @@ -158,6 +198,25 @@ mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r, mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth); mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r, const GFMethod *meth); + +/* fixed length in-line adds. Count is in words */ +mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); + mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth); mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r, const GFMethod *meth); @@ -205,6 +264,9 @@ mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, /* Optimized field arithmetic */ mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName); mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName); +mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName); +mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName); +mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName); mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name); mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name); mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name); diff --git a/security/nss/lib/freebl/ecl/ecl.c b/security/nss/lib/freebl/ecl/ecl.c index 520755f6a..4521e5b57 100644 --- a/security/nss/lib/freebl/ecl/ecl.c +++ b/security/nss/lib/freebl/ecl/ecl.c @@ -55,23 +55,24 @@ ECGroup_new() if (group == NULL) return NULL; group->constructed = MP_YES; + group->meth = NULL; group->text = NULL; MP_DIGITS(&group->curvea) = 0; MP_DIGITS(&group->curveb) = 0; MP_DIGITS(&group->genx) = 0; MP_DIGITS(&group->geny) = 0; MP_DIGITS(&group->order) = 0; - MP_CHECKOK(mp_init(&group->curvea)); - MP_CHECKOK(mp_init(&group->curveb)); - MP_CHECKOK(mp_init(&group->genx)); - MP_CHECKOK(mp_init(&group->geny)); - MP_CHECKOK(mp_init(&group->order)); group->base_point_mul = NULL; group->points_mul = NULL; group->validate_point = NULL; group->extra1 = NULL; group->extra2 = NULL; group->extra_free = NULL; + MP_CHECKOK(mp_init(&group->curvea)); + MP_CHECKOK(mp_init(&group->curveb)); + MP_CHECKOK(mp_init(&group->genx)); + MP_CHECKOK(mp_init(&group->geny)); + MP_CHECKOK(mp_init(&group->order)); CLEANUP: if (res != MP_OKAY) { @@ -164,6 +165,7 @@ ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea, return group; } +#ifdef NSS_ECC_MORE_THAN_SUITE_B /* Construct a generic ECGroup for elliptic curves over binary polynomial * fields. */ ECGroup * @@ -205,13 +207,7 @@ ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5], } return group; } - -/* Helper macros for ecgroup_fromNameAndHex. */ -#define CHECK_GROUP \ - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } -#define CONS_GF2M \ - group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor); \ - CHECK_GROUP +#endif /* Construct ECGroup from hex parameters and name, if any. Called by * ECGroup_fromHex and ECGroup_fromName. */ @@ -253,82 +249,85 @@ ecgroup_fromNameAndHex(const ECCurveName name, /* determine which optimizations (if any) to use */ if (params->field == ECField_GFp) { - if ((name == ECCurve_SECG_PRIME_160K1) - || (name == ECCurve_SECG_PRIME_160R2)) { +#ifdef NSS_ECC_MORE_THAN_SUITE_B + switch (name) { +#ifdef ECL_USE_FP + case ECCurve_SECG_PRIME_160R1: group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); - } else if ((name == ECCurve_SECG_PRIME_160R1)) { + ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, + &order, params->cofactor); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_secp160r1_fp(group)); + break; +#endif + case ECCurve_SECG_PRIME_192R1: #ifdef ECL_USE_FP group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_secp160r1_fp(group)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_nistp192_fp(group)); #else group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, + &order, params->cofactor); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp192(group, name)); #endif - } else if ((name == ECCurve_SECG_PRIME_192K1)) { - group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp192(group, name)); - } else if ((name == ECCurve_SECG_PRIME_192R1)) { + break; + case ECCurve_SECG_PRIME_224R1: #ifdef ECL_USE_FP group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_nistp192_fp(group)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_nistp224_fp(group)); #else group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp192(group, name)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp224(group, name)); #endif - } else if ((name == ECCurve_SECG_PRIME_224K1)) { - group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp224(group, name)); - } else if ((name == ECCurve_SECG_PRIME_224R1)) { -#ifdef ECL_USE_FP + break; + case ECCurve_SECG_PRIME_256R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_nistp224_fp(group)); -#else + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp256(group, name)); + break; + case ECCurve_SECG_PRIME_521R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp224(group, name)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp521(group, name)); + break; + default: + /* use generic arithmetic */ #endif - } else { group = ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP} - /* XXX secp521r1 fails ecp_test with &ec_GFp_pts_mul_jac */ - if (name == ECCurve_SECG_PRIME_521R1) { - group->points_mul = &ec_pts_mul_simul_w2; + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } +#ifdef NSS_ECC_MORE_THAN_SUITE_B } } else if (params->field == ECField_GF2m) { - switch (bits) { - case 163: - CONS_GF2M MP_CHECKOK(ec_group_set_gf2m163(group, name)); - break; - case 193: - CONS_GF2M MP_CHECKOK(ec_group_set_gf2m193(group, name)); - break; - case 233: - CONS_GF2M MP_CHECKOK(ec_group_set_gf2m233(group, name)); - break; - default: - group = - ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, - &geny, &order, params->cofactor); - CHECK_GROUP break; + group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + if ((name == ECCurve_NIST_K163) || + (name == ECCurve_NIST_B163) || + (name == ECCurve_SECG_CHAR2_163R1)) { + MP_CHECKOK(ec_group_set_gf2m163(group, name)); + } else if ((name == ECCurve_SECG_CHAR2_193R1) || + (name == ECCurve_SECG_CHAR2_193R2)) { + MP_CHECKOK(ec_group_set_gf2m193(group, name)); + } else if ((name == ECCurve_NIST_K233) || + (name == ECCurve_NIST_B233)) { + MP_CHECKOK(ec_group_set_gf2m233(group, name)); } +#endif } /* set name, if any */ @@ -353,10 +352,6 @@ ecgroup_fromNameAndHex(const ECCurveName name, return group; } -#undef CHECK_GROUP -#undef CONS_GFP -#undef CONS_GF2M - /* Construct ECGroup from hexadecimal representations of parameters. */ ECGroup * ECGroup_fromHex(const ECCurveParams * params) @@ -418,6 +413,11 @@ ECGroup_free(ECGroup *group) GFMethod_free(group->meth); if (group->constructed == MP_NO) return; + mp_clear(&group->curvea); + mp_clear(&group->curveb); + mp_clear(&group->genx); + mp_clear(&group->geny); + mp_clear(&group->order); if (group->text != NULL) free(group->text); if (group->extra_free != NULL) diff --git a/security/nss/lib/freebl/ecl/ecl_curve.c b/security/nss/lib/freebl/ecl/ecl_curve.c index b0a7d5074..a0a7bd316 100644 --- a/security/nss/lib/freebl/ecl/ecl_curve.c +++ b/security/nss/lib/freebl/ecl/ecl_curve.c @@ -51,7 +51,7 @@ ECCurveParams_dup(const ECCurveParams * params) int res = 1; ECCurveParams *ret = NULL; - CHECK(ret = (ECCurveParams *) malloc(sizeof(ECCurveParams))); + CHECK(ret = (ECCurveParams *) calloc(1, sizeof(ECCurveParams))); if (params->text != NULL) { CHECK(ret->text = strdup(params->text)); } @@ -91,7 +91,8 @@ ECCurveParams_dup(const ECCurveParams * params) ECCurveParams * EC_GetNamedCurveParams(const ECCurveName name) { - if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name)) { + if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) || + (ecCurve_map[name] == NULL)) { return NULL; } else { return ECCurveParams_dup(ecCurve_map[name]); diff --git a/security/nss/lib/freebl/ecl/ecl_gf.c b/security/nss/lib/freebl/ecl/ecl_gf.c index 9ee3bb6ac..08fa0c3e0 100644 --- a/security/nss/lib/freebl/ecl/ecl_gf.c +++ b/security/nss/lib/freebl/ecl/ecl_gf.c @@ -40,6 +40,7 @@ #include "mpi.h" #include "mp_gf2m.h" #include "ecl-priv.h" +#include "mpi-priv.h" #include <stdlib.h> /* Allocate memory for a new GFMethod object. */ @@ -52,8 +53,9 @@ GFMethod_new() if (meth == NULL) return NULL; meth->constructed = MP_YES; - MP_CHECKOK(mp_init(&meth->irr)); + MP_DIGITS(&meth->irr) = 0; meth->extra_free = NULL; + MP_CHECKOK(mp_init(&meth->irr)); CLEANUP: if (res != MP_OKAY) { @@ -79,9 +81,29 @@ GFMethod_consGFp(const mp_int *irr) meth->irr_arr[0] = mpl_significant_bits(irr); meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] = meth->irr_arr[4] = 0; - meth->field_add = &ec_GFp_add; + switch(MP_USED(&meth->irr)) { + /* maybe we need 1 and 2 words here as well?*/ + case 3: + meth->field_add = &ec_GFp_add_3; + meth->field_sub = &ec_GFp_sub_3; + break; + case 4: + meth->field_add = &ec_GFp_add_4; + meth->field_sub = &ec_GFp_sub_4; + break; + case 5: + meth->field_add = &ec_GFp_add_5; + meth->field_sub = &ec_GFp_sub_5; + break; + case 6: + meth->field_add = &ec_GFp_add_6; + meth->field_sub = &ec_GFp_sub_6; + break; + default: + meth->field_add = &ec_GFp_add; + meth->field_sub = &ec_GFp_sub; + } meth->field_neg = &ec_GFp_neg; - meth->field_sub = &ec_GFp_sub; meth->field_mod = &ec_GFp_mod; meth->field_mul = &ec_GFp_mul; meth->field_sqr = &ec_GFp_sqr; @@ -164,6 +186,7 @@ GFMethod_free(GFMethod *meth) return; if (meth->constructed == MP_NO) return; + mp_clear(&meth->irr); if (meth->extra_free != NULL) meth->extra_free(meth); free(meth); @@ -223,6 +246,676 @@ ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r, CLEANUP: return res; } +/* + * Inline adds for small curve lengths. + */ +/* 3 words */ +mp_err +ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %5,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry) + : "r" (a0), "r" (a1), "r" (a2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a2 = MP_DIGIT(&meth->irr,2); + if (carry || r2 > a2 || + ((r2 == a2) && mp_cmp(r,&meth->irr) != MP_LT)) { + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); +#else + __asm__ ( + "subq %3,%0 \n\t" + "sbbq %4,%1 \n\t" + "sbbq %5,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "r" (a0), "r" (a1), "r" (a2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 4 words */ +mp_err +ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 4: + a3 = MP_DIGIT(a,3); + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 4: + r3 = MP_DIGIT(b,3); + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); + MP_ADD_CARRY(a3, r3, r3, carry, carry); +#else + __asm__ ( + "xorq %4,%4 \n\t" + "addq %5,%0 \n\t" + "adcq %6,%1 \n\t" + "adcq %7,%2 \n\t" + "adcq %8,%3 \n\t" + "adcq $0,%4 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(carry) + : "r" (a0), "r" (a1), "r" (a2), "r" (a3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + + MP_CHECKOK(s_mp_pad(r, 4)); + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a3 = MP_DIGIT(&meth->irr,3); + if (carry || r3 > a3 || + ((r3 == a3) && mp_cmp(r,&meth->irr) != MP_LT)) { + a2 = MP_DIGIT(&meth->irr,2); + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); + MP_SUB_BORROW(r3, a3, r3, carry, carry); +#else + __asm__ ( + "subq %4,%0 \n\t" + "sbbq %5,%1 \n\t" + "sbbq %6,%2 \n\t" + "sbbq %7,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3) + : "r" (a0), "r" (a1), "r" (a2), "r" (a3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 5 words */ +mp_err +ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 5: + a4 = MP_DIGIT(a,4); + case 4: + a3 = MP_DIGIT(a,3); + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 5: + r4 = MP_DIGIT(b,4); + case 4: + r3 = MP_DIGIT(b,3); + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); + MP_ADD_CARRY(a3, r3, r3, carry, carry); + MP_ADD_CARRY(a4, r4, r4, carry, carry); + + MP_CHECKOK(s_mp_pad(r, 5)); + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 5; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a4 = MP_DIGIT(&meth->irr,4); + if (carry || r4 > a4 || + ((r4 == a4) && mp_cmp(r,&meth->irr) != MP_LT)) { + a3 = MP_DIGIT(&meth->irr,3); + a2 = MP_DIGIT(&meth->irr,2); + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); + MP_SUB_BORROW(r3, a3, r3, carry, carry); + MP_SUB_BORROW(r4, a4, r4, carry, carry); + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 6 words */ +mp_err +ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 6: + a5 = MP_DIGIT(a,5); + case 5: + a4 = MP_DIGIT(a,4); + case 4: + a3 = MP_DIGIT(a,3); + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 6: + r5 = MP_DIGIT(b,5); + case 5: + r4 = MP_DIGIT(b,4); + case 4: + r3 = MP_DIGIT(b,3); + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); + MP_ADD_CARRY(a3, r3, r3, carry, carry); + MP_ADD_CARRY(a4, r4, r4, carry, carry); + MP_ADD_CARRY(a5, r5, r5, carry, carry); + + MP_CHECKOK(s_mp_pad(r, 6)); + MP_DIGIT(r, 5) = r5; + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 6; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a5 = MP_DIGIT(&meth->irr,5); + if (carry || r5 > a5 || + ((r5 == a5) && mp_cmp(r,&meth->irr) != MP_LT)) { + a4 = MP_DIGIT(&meth->irr,4); + a3 = MP_DIGIT(&meth->irr,3); + a2 = MP_DIGIT(&meth->irr,2); + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); + MP_SUB_BORROW(r3, a3, r3, carry, carry); + MP_SUB_BORROW(r4, a4, r4, carry, carry); + MP_SUB_BORROW(r5, a5, r5, carry, carry); + MP_DIGIT(r, 5) = r5; + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* + * The following subraction functions do in-line subractions based + * on our curve size. + * + * ... 3 words + */ +mp_err +ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "subq %4,%0 \n\t" + "sbbq %5,%1 \n\t" + "sbbq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r" (borrow) + : "r" (b0), "r" (b1), "r" (b2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); +#else + __asm__ ( + "addq %3,%0 \n\t" + "adcq %4,%1 \n\t" + "adcq %5,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "r" (b0), "r" (b1), "r" (b2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + } + +#ifdef MPI_AMD64_ADD + /* compiler fakeout? */ + if ((r2 == b0) && (r1 == b0) && (r0 == b0)) { + MP_CHECKOK(s_mp_pad(r, 4)); + } +#endif + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 4 words */ +mp_err +ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 4: + r3 = MP_DIGIT(a,3); + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 4: + b3 = MP_DIGIT(b,3); + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); + MP_SUB_BORROW(r3, b3, r3, borrow, borrow); +#else + __asm__ ( + "xorq %4,%4 \n\t" + "subq %5,%0 \n\t" + "sbbq %6,%1 \n\t" + "sbbq %7,%2 \n\t" + "sbbq %8,%3 \n\t" + "adcq $0,%4 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r" (borrow) + : "r" (b0), "r" (b1), "r" (b2), "r" (b3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b3 = MP_DIGIT(&meth->irr,3); + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); + MP_ADD_CARRY(b3, r3, r3, borrow, borrow); +#else + __asm__ ( + "addq %4,%0 \n\t" + "adcq %5,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq %7,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3) + : "r" (b0), "r" (b1), "r" (b2), "r" (b3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + } +#ifdef MPI_AMD64_ADD + /* compiler fakeout? */ + if ((r3 == b0) && (r1 == b0) && (r0 == b0)) { + MP_CHECKOK(s_mp_pad(r, 4)); + } +#endif + MP_CHECKOK(s_mp_pad(r, 4)); + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 5 words */ +mp_err +ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 5: + r4 = MP_DIGIT(a,4); + case 4: + r3 = MP_DIGIT(a,3); + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 5: + b4 = MP_DIGIT(b,4); + case 4: + b3 = MP_DIGIT(b,3); + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); + MP_SUB_BORROW(r3, b3, r3, borrow, borrow); + MP_SUB_BORROW(r4, b4, r4, borrow, borrow); + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b4 = MP_DIGIT(&meth->irr,4); + b3 = MP_DIGIT(&meth->irr,3); + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); + MP_ADD_CARRY(b3, r3, r3, borrow, borrow); + } + MP_CHECKOK(s_mp_pad(r, 5)); + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 5; + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 6 words */ +mp_err +ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 6: + r5 = MP_DIGIT(a,5); + case 5: + r4 = MP_DIGIT(a,4); + case 4: + r3 = MP_DIGIT(a,3); + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 6: + b5 = MP_DIGIT(b,5); + case 5: + b4 = MP_DIGIT(b,4); + case 4: + b3 = MP_DIGIT(b,3); + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); + MP_SUB_BORROW(r3, b3, r3, borrow, borrow); + MP_SUB_BORROW(r4, b4, r4, borrow, borrow); + MP_SUB_BORROW(r5, b5, r5, borrow, borrow); + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b5 = MP_DIGIT(&meth->irr,5); + b4 = MP_DIGIT(&meth->irr,4); + b3 = MP_DIGIT(&meth->irr,3); + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); + MP_ADD_CARRY(b3, r3, r3, borrow, borrow); + MP_ADD_CARRY(b4, r4, r4, borrow, borrow); + } + + MP_CHECKOK(s_mp_pad(r, 6)); + MP_DIGIT(r, 5) = r5; + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 6; + s_mp_clamp(r); + + CLEANUP: + return res; +} + /* Reduces an integer to a field element. */ mp_err diff --git a/security/nss/lib/freebl/ecl/ecl_mult.c b/security/nss/lib/freebl/ecl/ecl_mult.c index 69eae6965..050d0a747 100644 --- a/security/nss/lib/freebl/ecl/ecl_mult.c +++ b/security/nss/lib/freebl/ecl/ecl_mult.c @@ -57,7 +57,7 @@ ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px, MP_DIGITS(&kt) = 0; /* want scalar to be less than or equal to group order */ - if (mp_cmp(k, &group->order) >= 0) { + if (mp_cmp(k, &group->order) > 0) { MP_CHECKOK(mp_init(&kt)); MP_CHECKOK(mp_mod(k, &group->order, &kt)); } else { @@ -162,7 +162,6 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, { mp_err res = MP_OKAY; mp_int precomp[4][4][2]; - mp_digit precomp_arr[ECL_MAX_FIELD_SIZE_DIGITS * 4 * 4 * 2], *t; const mp_int *a, *b; int i, j; int ai, bi, d; @@ -180,23 +179,18 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, } /* initialize precomputation table */ - t = precomp_arr; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - /* x co-ord */ - MP_SIGN(&precomp[i][j][0]) = MP_ZPOS; - MP_ALLOC(&precomp[i][j][0]) = ECL_MAX_FIELD_SIZE_DIGITS; - MP_USED(&precomp[i][j][0]) = 1; - *t = 0; - MP_DIGITS(&precomp[i][j][0]) = t; - t += ECL_MAX_FIELD_SIZE_DIGITS; - /* y co-ord */ - MP_SIGN(&precomp[i][j][1]) = MP_ZPOS; - MP_ALLOC(&precomp[i][j][1]) = ECL_MAX_FIELD_SIZE_DIGITS; - MP_USED(&precomp[i][j][1]) = 1; - *t = 0; - MP_DIGITS(&precomp[i][j][1]) = t; - t += ECL_MAX_FIELD_SIZE_DIGITS; + MP_DIGITS(&precomp[i][j][0]) = 0; + MP_DIGITS(&precomp[i][j][1]) = 0; + } + } + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + MP_CHECKOK( mp_init_size(&precomp[i][j][0], + ECL_MAX_FIELD_SIZE_DIGITS) ); + MP_CHECKOK( mp_init_size(&precomp[i][j][1], + ECL_MAX_FIELD_SIZE_DIGITS) ); } } @@ -298,6 +292,12 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, } CLEANUP: + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + mp_clear(&precomp[i][j][0]); + mp_clear(&precomp[i][j][1]); + } + } return res; } diff --git a/security/nss/lib/freebl/ecl/ecp_192.c b/security/nss/lib/freebl/ecl/ecp_192.c index 26867ae3e..f4cd42bc3 100644 --- a/security/nss/lib/freebl/ecl/ecp_192.c +++ b/security/nss/lib/freebl/ecl/ecp_192.c @@ -42,6 +42,8 @@ #include "mpi-priv.h" #include <stdlib.h> +#define ECP192_DIGITS ECL_CURVE_DIGITS(192) + /* Fast modular reduction for p192 = 2^192 - 2^64 - 1. a can be r. Uses * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software * Implementation of the NIST Elliptic Curves over Prime Fields. */ @@ -50,101 +52,127 @@ ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth) { mp_err res = MP_OKAY; mp_size a_used = MP_USED(a); - - /* s is a statically-allocated mp_int of exactly the size we need */ - mp_int s; - + mp_digit r3; +#ifndef MPI_AMD64_ADD + mp_digit carry; +#endif #ifdef ECL_THIRTY_TWO_BIT - mp_digit sa[6]; - mp_digit a11 = 0, a10, a9 = 0, a8, a7 = 0, a6; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 6; - MP_USED(&s) = 6; - MP_DIGITS(&s) = sa; + mp_digit a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0; + mp_digit r0a, r0b, r1a, r1b, r2a, r2b; #else - mp_digit sa[3]; mp_digit a5 = 0, a4 = 0, a3 = 0; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 3; - MP_USED(&s) = 3; - MP_DIGITS(&s) = sa; + mp_digit r0, r1, r2; #endif /* reduction not needed if a is not larger than field size */ -#ifdef ECL_THIRTY_TWO_BIT - if (a_used < 6) { -#else - if (a_used < 3) { -#endif + if (a_used < ECP192_DIGITS) { + if (a == r) { + return MP_OKAY; + } return mp_copy(a, r); } -#ifdef ECL_THIRTY_TWO_BIT + /* for polynomials larger than twice the field size, use regular * reduction */ - if (a_used > 12) { + if (a_used > ECP192_DIGITS*2) { MP_CHECKOK(mp_mod(a, &meth->irr, r)); } else { /* copy out upper words of a */ + +#ifdef ECL_THIRTY_TWO_BIT + + /* in all the math below, + * nXb is most signifiant, nXa is least significant */ switch (a_used) { case 12: - a11 = MP_DIGIT(a, 11); + a5b = MP_DIGIT(a, 11); case 11: - a10 = MP_DIGIT(a, 10); + a5a = MP_DIGIT(a, 10); case 10: - a9 = MP_DIGIT(a, 9); + a4b = MP_DIGIT(a, 9); case 9: - a8 = MP_DIGIT(a, 8); + a4a = MP_DIGIT(a, 8); case 8: - a7 = MP_DIGIT(a, 7); + a3b = MP_DIGIT(a, 7); case 7: - a6 = MP_DIGIT(a, 6); + a3a = MP_DIGIT(a, 6); } + + + r2b= MP_DIGIT(a, 5); + r2a= MP_DIGIT(a, 4); + r1b = MP_DIGIT(a, 3); + r1a = MP_DIGIT(a, 2); + r0b = MP_DIGIT(a, 1); + r0a = MP_DIGIT(a, 0); + + /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */ + MP_ADD_CARRY(r0a, a3a, r0a, 0, carry); + MP_ADD_CARRY(r0b, a3b, r0b, carry, carry); + MP_ADD_CARRY(r1a, a3a, r1a, carry, carry); + MP_ADD_CARRY(r1b, a3b, r1b, carry, carry); + MP_ADD_CARRY(r2a, a4a, r2a, carry, carry); + MP_ADD_CARRY(r2b, a4b, r2b, carry, carry); + r3 = carry; carry = 0; + MP_ADD_CARRY(r0a, a5a, r0a, 0, carry); + MP_ADD_CARRY(r0b, a5b, r0b, carry, carry); + MP_ADD_CARRY(r1a, a5a, r1a, carry, carry); + MP_ADD_CARRY(r1b, a5b, r1b, carry, carry); + MP_ADD_CARRY(r2a, a5a, r2a, carry, carry); + MP_ADD_CARRY(r2b, a5b, r2b, carry, carry); + r3 += carry; + MP_ADD_CARRY(r1a, a4a, r1a, 0, carry); + MP_ADD_CARRY(r1b, a4b, r1b, carry, carry); + MP_ADD_CARRY(r2a, 0, r2a, carry, carry); + MP_ADD_CARRY(r2b, 0, r2b, carry, carry); + r3 += carry; + + /* reduce out the carry */ + while (r3) { + MP_ADD_CARRY(r0a, r3, r0a, 0, carry); + MP_ADD_CARRY(r0b, 0, r0b, carry, carry); + MP_ADD_CARRY(r1a, r3, r1a, carry, carry); + MP_ADD_CARRY(r1b, 0, r1b, carry, carry); + MP_ADD_CARRY(r2a, 0, r2a, carry, carry); + MP_ADD_CARRY(r2b, 0, r2b, carry, carry); + r3 = carry; + } + + /* check for final reduction */ + /* + * our field is 0xffffffffffffffff, 0xfffffffffffffffe, + * 0xffffffffffffffff. That means we can only be over and need + * one more reduction + * if r2 == 0xffffffffffffffffff (same as r2+1 == 0) + * and + * r1 == 0xffffffffffffffffff or + * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff + * In all cases, we subtract the field (or add the 2's + * complement value (1,1,0)). (r0, r1, r2) + */ + if (((r2b == 0xffffffff) && (r2a == 0xffffffff) + && (r1b == 0xffffffff) ) && + ((r1a == 0xffffffff) || + (r1a == 0xfffffffe) && (r0a == 0xffffffff) && + (r0b == 0xffffffff)) ) { + /* do a quick subtract */ + MP_ADD_CARRY(r0a, 1, r0a, 0, carry); + r0b += carry; + r1a = r1b = r2a = r2b = 0; + } + /* set the lower words of r */ if (a != r) { - MP_CHECKOK(s_mp_pad(r, 7)); - MP_DIGIT(r, 5) = MP_DIGIT(a, 5); - MP_DIGIT(r, 4) = MP_DIGIT(a, 4); - MP_DIGIT(r, 3) = MP_DIGIT(a, 3); - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); + MP_CHECKOK(s_mp_pad(r, 6)); } + MP_DIGIT(r, 5) = r2b; + MP_DIGIT(r, 4) = r2a; + MP_DIGIT(r, 3) = r1b; + MP_DIGIT(r, 2) = r1a; + MP_DIGIT(r, 1) = r0b; + MP_DIGIT(r, 0) = r0a; MP_USED(r) = 6; - /* compute r = s1 + s2 + s3 + s4, where s1 = (a2,a1,a0), s2 = - * (0,a3,a3), s3 = (a4,a4,0), and s4 = (a5,a5,a5), for - * sixty-four-bit words */ - switch (a_used) { - case 12: - case 11: - sa[5] = sa[3] = sa[1] = a11; - sa[4] = sa[2] = sa[0] = a10; - MP_CHECKOK(mp_add(r, &s, r)); - case 10: - case 9: - sa[5] = sa[3] = a9; - sa[4] = sa[2] = a8; - sa[1] = sa[0] = 0; - MP_CHECKOK(mp_add(r, &s, r)); - case 8: - case 7: - sa[5] = sa[4] = 0; - sa[3] = sa[1] = a7; - sa[2] = sa[0] = a6; - MP_CHECKOK(mp_add(r, &s, r)); - } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); - } #else - /* for polynomials larger than twice the field size, use regular - * reduction */ - if (a_used > 6) { - MP_CHECKOK(mp_mod(a, &meth->irr, r)); - } else { - /* copy out upper words of a */ switch (a_used) { case 6: a5 = MP_DIGIT(a, 5); @@ -153,39 +181,268 @@ ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth) case 4: a3 = MP_DIGIT(a, 3); } + + r2 = MP_DIGIT(a, 2); + r1 = MP_DIGIT(a, 1); + r0 = MP_DIGIT(a, 0); + + /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */ +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(r0, a3, r0, 0, carry); + MP_ADD_CARRY(r1, a3, r1, carry, carry); + MP_ADD_CARRY(r2, a4, r2, carry, carry); + r3 = carry; + MP_ADD_CARRY(r0, a5, r0, 0, carry); + MP_ADD_CARRY(r1, a5, r1, carry, carry); + MP_ADD_CARRY(r2, a5, r2, carry, carry); + r3 += carry; + MP_ADD_CARRY(r1, a4, r1, 0, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + r3 += carry; + +#else + r2 = MP_DIGIT(a, 2); + r1 = MP_DIGIT(a, 1); + r0 = MP_DIGIT(a, 0); + + /* set the lower words of r */ + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %4,%1 \n\t" + "adcq %5,%2 \n\t" + "adcq $0,%3 \n\t" + "addq %6,%0 \n\t" + "adcq %6,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq $0,%3 \n\t" + "addq %5,%1 \n\t" + "adcq $0,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3), + "=r"(a4), "=r"(a5) + : "0" (r0), "1" (r1), "2" (r2), "3" (r3), + "4" (a3), "5" (a4), "6"(a5) + : "%cc" ); +#endif + + /* reduce out the carry */ + while (r3) { +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(r0, r3, r0, 0, carry); + MP_ADD_CARRY(r1, r3, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + r3 = carry; +#else + a3=r3; + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %4,%1 \n\t" + "adcq $0,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3) + : "0" (r0), "1" (r1), "2" (r2), "3" (r3), "4"(a3) + : "%cc" ); +#endif + } + + /* check for final reduction */ + /* + * our field is 0xffffffffffffffff, 0xfffffffffffffffe, + * 0xffffffffffffffff. That means we can only be over and need + * one more reduction + * if r2 == 0xffffffffffffffffff (same as r2+1 == 0) + * and + * r1 == 0xffffffffffffffffff or + * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff + * In all cases, we subtract the field (or add the 2's + * complement value (1,1,0)). (r0, r1, r2) + */ + if (r3 || ((r2 == MP_DIGIT_MAX) && + ((r1 == MP_DIGIT_MAX) || + ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) { + /* do a quick subtract */ + r0++; + r1 = r2 = 0; + } /* set the lower words of r */ if (a != r) { - MP_CHECKOK(s_mp_pad(r, 4)); - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); + MP_CHECKOK(s_mp_pad(r, 3)); } + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; MP_USED(r) = 3; - /* compute r = s1 + s2 + s3 + s4, where s1 = (a2,a1,a0), s2 = - * (0,a3,a3), s3 = (a4,a4,0), and s4 = (a5,a5,a5) */ - switch (a_used) { - case 6: - sa[2] = sa[1] = sa[0] = a5; - MP_CHECKOK(mp_add(r, &s, r)); - case 5: - sa[2] = sa[1] = a4; - sa[0] = 0; - MP_CHECKOK(mp_add(r, &s, r)); - case 4: - sa[2] = 0; - sa[1] = sa[0] = a3; - MP_CHECKOK(mp_add(r, &s, r)); - } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); +#endif } + + CLEANUP: + return res; +} + +#ifndef ECL_THIRTY_TWO_BIT +/* Compute the sum of 192 bit curves. Do the work in-line since the + * number of words are so small, we don't want to overhead of mp function + * calls. Uses optimized modular reduction for p192. + */ +mp_err +ec_GFp_nistp192_add(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %5,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry) + : "r" (a0), "r" (a1), "r" (a2), "0" (r0), + "1" (r1), "2" (r2) + : "%cc" ); +#endif + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + if (carry || ((r2 == MP_DIGIT_MAX) && + ((r1 == MP_DIGIT_MAX) || + ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) { +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(r0, 1, r0, 0, carry); + MP_ADD_CARRY(r1, 1, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); +#else + __asm__ ( + "addq $1,%0 \n\t" + "adcq $1,%1 \n\t" + "adcq $0,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + } + + + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + s_mp_clamp(r); + + + CLEANUP: + return res; +} + +/* Compute the diff of 192 bit curves. Do the work in-line since the + * number of words are so small, we don't want to overhead of mp function + * calls. Uses optimized modular reduction for p192. + */ +mp_err +ec_GFp_nistp192_sub(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + + switch(MP_USED(b)) { + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "subq %4,%0 \n\t" + "sbbq %5,%1 \n\t" + "sbbq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(borrow) + : "r" (b0), "r" (b1), "r" (b2), "0" (r0), + "1" (r1), "2" (r2) + : "%cc" ); +#endif + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, 1, r0, 0, borrow); + MP_SUB_BORROW(r1, 1, r1, borrow, borrow); + MP_SUB_BORROW(r2, 0, r2, borrow, borrow); +#else + __asm__ ( + "subq $1,%0 \n\t" + "sbbq $1,%1 \n\t" + "sbbq $0,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); #endif + } + + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + s_mp_clamp(r); CLEANUP: return res; } +#endif + /* Compute the square of polynomial a, reduce modulo p192. Store the * result in r. r could be a. Uses optimized modular reduction for p192. */ @@ -215,6 +472,31 @@ ec_GFp_nistp192_mul(const mp_int *a, const mp_int *b, mp_int *r, return res; } +/* Divides two field elements. If a is NULL, then returns the inverse of + * b. */ +mp_err +ec_GFp_nistp192_div(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_int t; + + /* If a is NULL, then return the inverse of b, otherwise return a/b. */ + if (a == NULL) { + return mp_invmod(b, &meth->irr, r); + } else { + /* MPI doesn't support divmod, so we implement it using invmod and + * mulmod. */ + MP_CHECKOK(mp_init(&t)); + MP_CHECKOK(mp_invmod(b, &meth->irr, &t)); + MP_CHECKOK(mp_mul(a, &t, r)); + MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth)); + CLEANUP: + mp_clear(&t); + return res; + } +} + /* Wire in fast field arithmetic and precomputation of base point for * named curves. */ mp_err @@ -224,6 +506,11 @@ ec_group_set_gfp192(ECGroup *group, ECCurveName name) group->meth->field_mod = &ec_GFp_nistp192_mod; group->meth->field_mul = &ec_GFp_nistp192_mul; group->meth->field_sqr = &ec_GFp_nistp192_sqr; + group->meth->field_div = &ec_GFp_nistp192_div; +#ifndef ECL_THIRTY_TWO_BIT + group->meth->field_add = &ec_GFp_nistp192_add; + group->meth->field_sub = &ec_GFp_nistp192_sub; +#endif } return MP_OKAY; } diff --git a/security/nss/lib/freebl/ecl/ecp_224.c b/security/nss/lib/freebl/ecl/ecp_224.c index c3d8fa362..56683e9ef 100644 --- a/security/nss/lib/freebl/ecl/ecp_224.c +++ b/security/nss/lib/freebl/ecl/ecp_224.c @@ -42,6 +42,8 @@ #include "mpi-priv.h" #include <stdlib.h> +#define ECP224_DIGITS ECL_CURVE_DIGITS(224) + /* Fast modular reduction for p224 = 2^224 - 2^96 + 1. a can be r. Uses * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software * Implementation of the NIST Elliptic Curves over Prime Fields. */ @@ -51,213 +53,251 @@ ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth) mp_err res = MP_OKAY; mp_size a_used = MP_USED(a); - /* s is a statically-allocated mp_int of exactly the size we need */ - mp_int s; - + int r3b; + mp_digit carry; #ifdef ECL_THIRTY_TWO_BIT - mp_digit sa[8]; - mp_digit a13 = 0, a12 = 0, a11 = 0, a10, a9 = 0, a8, a7; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 8; - MP_USED(&s) = 7; - MP_DIGITS(&s) = sa; + mp_digit a6a = 0, a6b = 0, + a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0; + mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a; #else - mp_digit sa[4]; - mp_digit a6 = 0, a5 = 0, a4 = 0, a3 = 0; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 4; - MP_USED(&s) = 4; - MP_DIGITS(&s) = sa; + mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0; + mp_digit a6b = 0, a6a_a5b = 0, a5b = 0, a5a_a4b = 0, a4a_a3b = 0; + mp_digit r0, r1, r2, r3; #endif /* reduction not needed if a is not larger than field size */ -#ifdef ECL_THIRTY_TWO_BIT - if (a_used < 8) { -#else - if (a_used < 4) { -#endif + if (a_used < ECP224_DIGITS) { + if (a == r) return MP_OKAY; return mp_copy(a, r); } -#ifdef ECL_THIRTY_TWO_BIT /* for polynomials larger than twice the field size, use regular * reduction */ - if (a_used > 14) { + if (a_used > ECL_CURVE_DIGITS(224*2)) { MP_CHECKOK(mp_mod(a, &meth->irr, r)); } else { +#ifdef ECL_THIRTY_TWO_BIT /* copy out upper words of a */ switch (a_used) { case 14: - a13 = MP_DIGIT(a, 13); + a6b = MP_DIGIT(a, 13); case 13: - a12 = MP_DIGIT(a, 12); + a6a = MP_DIGIT(a, 12); case 12: - a11 = MP_DIGIT(a, 11); + a5b = MP_DIGIT(a, 11); case 11: - a10 = MP_DIGIT(a, 10); + a5a = MP_DIGIT(a, 10); case 10: - a9 = MP_DIGIT(a, 9); + a4b = MP_DIGIT(a, 9); case 9: - a8 = MP_DIGIT(a, 8); + a4a = MP_DIGIT(a, 8); case 8: - a7 = MP_DIGIT(a, 7); + a3b = MP_DIGIT(a, 7); } - /* set the lower words of r */ - if (a != r) { - MP_CHECKOK(s_mp_pad(r, 8)); - MP_DIGIT(r, 6) = MP_DIGIT(a, 6); - MP_DIGIT(r, 5) = MP_DIGIT(a, 5); - MP_DIGIT(r, 4) = MP_DIGIT(a, 4); - MP_DIGIT(r, 3) = MP_DIGIT(a, 3); - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); + r3a = MP_DIGIT(a, 6); + r2b= MP_DIGIT(a, 5); + r2a= MP_DIGIT(a, 4); + r1b = MP_DIGIT(a, 3); + r1a = MP_DIGIT(a, 2); + r0b = MP_DIGIT(a, 1); + r0a = MP_DIGIT(a, 0); + + + /* implement r = (a3a,a2,a1,a0) + +(a5a, a4,a3b, 0) + +( 0, a6,a5b, 0) + -( 0 0, 0|a6b, a6a|a5b ) + -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */ + MP_ADD_CARRY (r1b, a3b, r1b, 0, carry); + MP_ADD_CARRY (r2a, a4a, r2a, carry, carry); + MP_ADD_CARRY (r2b, a4b, r2b, carry, carry); + MP_ADD_CARRY (r3a, a5a, r3a, carry, carry); + r3b = carry; + MP_ADD_CARRY (r1b, a5b, r1b, 0, carry); + MP_ADD_CARRY (r2a, a6a, r2a, carry, carry); + MP_ADD_CARRY (r2b, a6b, r2b, carry, carry); + MP_ADD_CARRY (r3a, 0, r3a, carry, carry); + r3b += carry; + MP_SUB_BORROW(r0a, a3b, r0a, 0, carry); + MP_SUB_BORROW(r0b, a4a, r0b, carry, carry); + MP_SUB_BORROW(r1a, a4b, r1a, carry, carry); + MP_SUB_BORROW(r1b, a5a, r1b, carry, carry); + MP_SUB_BORROW(r2a, a5b, r2a, carry, carry); + MP_SUB_BORROW(r2b, a6a, r2b, carry, carry); + MP_SUB_BORROW(r3a, a6b, r3a, carry, carry); + r3b -= carry; + MP_SUB_BORROW(r0a, a5b, r0a, 0, carry); + MP_SUB_BORROW(r0b, a6a, r0b, carry, carry); + MP_SUB_BORROW(r1a, a6b, r1a, carry, carry); + if (carry) { + MP_SUB_BORROW(r1b, 0, r1b, carry, carry); + MP_SUB_BORROW(r2a, 0, r2a, carry, carry); + MP_SUB_BORROW(r2b, 0, r2b, carry, carry); + MP_SUB_BORROW(r3a, 0, r3a, carry, carry); + r3b -= carry; } - MP_USED(r) = 7; - switch (a_used) { - case 14: - case 13: - case 12: - case 11: - sa[6] = a10; - case 10: - sa[5] = a9; - case 9: - sa[4] = a8; - case 8: - sa[3] = a7; - sa[2] = sa[1] = sa[0] = 0; - MP_USED(&s) = a_used - 4; - if (MP_USED(&s) > 7) - MP_USED(&s) = 7; - MP_CHECKOK(mp_add(r, &s, r)); + + while (r3b > 0) { + int tmp; + MP_ADD_CARRY(r1b, r3b, r1b, 0, carry); + if (carry) { + MP_ADD_CARRY(r2a, 0, r2a, carry, carry); + MP_ADD_CARRY(r2b, 0, r2b, carry, carry); + MP_ADD_CARRY(r3a, 0, r3a, carry, carry); + } + tmp = carry; + MP_SUB_BORROW(r0a, r3b, r0a, 0, carry); + if (carry) { + MP_SUB_BORROW(r0b, 0, r0b, carry, carry); + MP_SUB_BORROW(r1a, 0, r1a, carry, carry); + MP_SUB_BORROW(r1b, 0, r1b, carry, carry); + MP_SUB_BORROW(r2a, 0, r2a, carry, carry); + MP_SUB_BORROW(r2b, 0, r2b, carry, carry); + MP_SUB_BORROW(r3a, 0, r3a, carry, carry); + tmp -= carry; + } + r3b = tmp; } - switch (a_used) { - case 14: - sa[5] = a13; - case 13: - sa[4] = a12; - case 12: - sa[3] = a11; - sa[2] = sa[1] = sa[0] = 0; - MP_USED(&s) = a_used - 8; - MP_CHECKOK(mp_add(r, &s, r)); + + while (r3b < 0) { + mp_digit maxInt = MP_DIGIT_MAX; + MP_ADD_CARRY (r0a, 1, r0a, 0, carry); + MP_ADD_CARRY (r0b, 0, r0b, carry, carry); + MP_ADD_CARRY (r1a, 0, r1a, carry, carry); + MP_ADD_CARRY (r1b, maxInt, r1b, carry, carry); + MP_ADD_CARRY (r2a, maxInt, r2a, carry, carry); + MP_ADD_CARRY (r2b, maxInt, r2b, carry, carry); + MP_ADD_CARRY (r3a, maxInt, r3a, carry, carry); + r3b += carry; } - switch (a_used) { - case 14: - sa[6] = a13; - case 13: - sa[5] = a12; - case 12: - sa[4] = a11; - case 11: - sa[3] = a10; - case 10: - sa[2] = a9; - case 9: - sa[1] = a8; - case 8: - sa[0] = a7; - MP_USED(&s) = a_used - 7; - MP_CHECKOK(mp_sub(r, &s, r)); + /* check for final reduction */ + /* now the only way we are over is if the top 4 words are all ones */ + if ((r3a == MP_DIGIT_MAX) && (r2b == MP_DIGIT_MAX) + && (r2a == MP_DIGIT_MAX) && (r1b == MP_DIGIT_MAX) && + ((r1a != 0) || (r0b != 0) || (r0a != 0)) ) { + /* one last subraction */ + MP_SUB_BORROW(r0a, 1, r0a, 0, carry); + MP_SUB_BORROW(r0b, 0, r0b, carry, carry); + MP_SUB_BORROW(r1a, 0, r1a, carry, carry); + r1b = r2a = r2b = r3a = 0; } - switch (a_used) { - case 14: - sa[2] = a13; - case 13: - sa[1] = a12; - case 12: - sa[0] = a11; - MP_USED(&s) = a_used - 11; - MP_CHECKOK(mp_sub(r, &s, r)); + + + if (a != r) { + MP_CHECKOK(s_mp_pad(r, 7)); } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); - } + /* set the lower words of r */ + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 7; + MP_DIGIT(r, 6) = r3a; + MP_DIGIT(r, 5) = r2b; + MP_DIGIT(r, 4) = r2a; + MP_DIGIT(r, 3) = r1b; + MP_DIGIT(r, 2) = r1a; + MP_DIGIT(r, 1) = r0b; + MP_DIGIT(r, 0) = r0a; #else - /* for polynomials larger than twice the field size, use regular - * reduction */ - if (a_used > 7) { - MP_CHECKOK(mp_mod(a, &meth->irr, r)); - } else { /* copy out upper words of a */ switch (a_used) { case 7: a6 = MP_DIGIT(a, 6); + a6b = a6 >> 32; + a6a_a5b = a6 << 32; case 6: a5 = MP_DIGIT(a, 5); + a5b = a5 >> 32; + a6a_a5b |= a5b; + a5b = a5b << 32; + a5a_a4b = a5 << 32; + a5a = a5 & 0xffffffff; case 5: a4 = MP_DIGIT(a, 4); + a5a_a4b |= a4 >> 32; + a4a_a3b = a4 << 32; case 4: - a3 = MP_DIGIT(a, 3) >> 32; + a3b = MP_DIGIT(a, 3) >> 32; + a4a_a3b |= a3b; + a3b = a3b << 32; } - /* set the lower words of r */ - if (a != r) { - MP_CHECKOK(s_mp_pad(r, 5)); - MP_DIGIT(r, 3) = MP_DIGIT(a, 3) & 0xFFFFFFFF; - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); - } else { - MP_DIGIT(r, 3) &= 0xFFFFFFFF; + + r3 = MP_DIGIT(a, 3) & 0xffffffff; + r2 = MP_DIGIT(a, 2); + r1 = MP_DIGIT(a, 1); + r0 = MP_DIGIT(a, 0); + + /* implement r = (a3a,a2,a1,a0) + +(a5a, a4,a3b, 0) + +( 0, a6,a5b, 0) + -( 0 0, 0|a6b, a6a|a5b ) + -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */ + MP_ADD_CARRY (r1, a3b, r1, 0, carry); + MP_ADD_CARRY (r2, a4 , r2, carry, carry); + MP_ADD_CARRY (r3, a5a, r3, carry, carry); + MP_ADD_CARRY (r1, a5b, r1, 0, carry); + MP_ADD_CARRY (r2, a6 , r2, carry, carry); + MP_ADD_CARRY (r3, 0, r3, carry, carry); + + MP_SUB_BORROW(r0, a4a_a3b, r0, 0, carry); + MP_SUB_BORROW(r1, a5a_a4b, r1, carry, carry); + MP_SUB_BORROW(r2, a6a_a5b, r2, carry, carry); + MP_SUB_BORROW(r3, a6b , r3, carry, carry); + MP_SUB_BORROW(r0, a6a_a5b, r0, 0, carry); + MP_SUB_BORROW(r1, a6b , r1, carry, carry); + if (carry) { + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, 0, r3, carry, carry); } - MP_USED(r) = 4; - switch (a_used) { - case 7: - case 6: - sa[3] = a5 & 0xFFFFFFFF; - case 5: - sa[2] = a4; - case 4: - sa[1] = a3 << 32; - sa[0] = 0; - MP_USED(&s) = a_used - 2; - if (MP_USED(&s) == 5) - MP_USED(&s) = 4; - MP_CHECKOK(mp_add(r, &s, r)); + + + /* if the value is negative, r3 has a 2's complement + * high value */ + r3b = (int)(r3 >>32); + while (r3b > 0) { + r3 &= 0xffffffff; + MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry); + if (carry) { + MP_ADD_CARRY(r2, 0, r2, carry, carry); + MP_ADD_CARRY(r3, 0, r3, carry, carry); + } + MP_SUB_BORROW(r0, r3b, r0, 0, carry); + if (carry) { + MP_SUB_BORROW(r1, 0, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, 0, r3, carry, carry); + } + r3b = (int)(r3 >>32); } - switch (a_used) { - case 7: - sa[2] = a6; - case 6: - sa[1] = (a5 >> 32) << 32; - sa[0] = 0; - MP_USED(&s) = a_used - 4; - MP_CHECKOK(mp_add(r, &s, r)); + + while (r3b < 0) { + MP_ADD_CARRY (r0, 1, r0, 0, carry); + MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry); + MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry); + MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry); + r3b = (int)(r3 >>32); } - sa[2] = sa[1] = sa[0] = 0; - switch (a_used) { - case 7: - sa[3] = a6 >> 32; - sa[2] = a6 << 32; - case 6: - sa[2] |= a5 >> 32; - sa[1] = a5 << 32; - case 5: - sa[1] |= a4 >> 32; - sa[0] = a4 << 32; - case 4: - sa[0] |= a3; - MP_USED(&s) = a_used - 3; - MP_CHECKOK(mp_sub(r, &s, r)); + /* check for final reduction */ + /* now the only way we are over is if the top 4 words are all ones */ + if ((r3 == (MP_DIGIT_MAX >> 32)) && (r2 == MP_DIGIT_MAX) + && ((r1 & MP_DIGIT_MAX << 32)== MP_DIGIT_MAX << 32) && + ((r1 != MP_DIGIT_MAX << 32 ) || (r0 != 0)) ) { + /* one last subraction */ + MP_SUB_BORROW(r0, 1, r0, 0, carry); + MP_SUB_BORROW(r1, 0, r1, carry, carry); + r2 = r3 = 0; } - sa[0] = 0; - switch (a_used) { - case 7: - sa[1] = a6 >> 32; - sa[0] = a6 << 32; - case 6: - sa[0] |= a5 >> 32; - MP_USED(&s) = a_used - 5; - MP_CHECKOK(mp_sub(r, &s, r)); + + + if (a != r) { + MP_CHECKOK(s_mp_pad(r, 4)); } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); - } + /* set the lower words of r */ + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; #endif + } CLEANUP: return res; @@ -292,6 +332,31 @@ ec_GFp_nistp224_mul(const mp_int *a, const mp_int *b, mp_int *r, return res; } +/* Divides two field elements. If a is NULL, then returns the inverse of + * b. */ +mp_err +ec_GFp_nistp224_div(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_int t; + + /* If a is NULL, then return the inverse of b, otherwise return a/b. */ + if (a == NULL) { + return mp_invmod(b, &meth->irr, r); + } else { + /* MPI doesn't support divmod, so we implement it using invmod and + * mulmod. */ + MP_CHECKOK(mp_init(&t)); + MP_CHECKOK(mp_invmod(b, &meth->irr, &t)); + MP_CHECKOK(mp_mul(a, &t, r)); + MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth)); + CLEANUP: + mp_clear(&t); + return res; + } +} + /* Wire in fast field arithmetic and precomputation of base point for * named curves. */ mp_err @@ -301,6 +366,7 @@ ec_group_set_gfp224(ECGroup *group, ECCurveName name) group->meth->field_mod = &ec_GFp_nistp224_mod; group->meth->field_mul = &ec_GFp_nistp224_mul; group->meth->field_sqr = &ec_GFp_nistp224_sqr; + group->meth->field_div = &ec_GFp_nistp224_div; } return MP_OKAY; } diff --git a/security/nss/lib/freebl/ecl/ecp_256.c b/security/nss/lib/freebl/ecl/ecp_256.c new file mode 100644 index 000000000..15d29ab6e --- /dev/null +++ b/security/nss/lib/freebl/ecl/ecp_256.c @@ -0,0 +1,429 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 elliptic curve math library for prime field curves. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Douglas Stebila <douglas@stebila.ca> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ecp.h" +#include "mpi.h" +#include "mplogic.h" +#include "mpi-priv.h" +#include <stdlib.h> + +/* Fast modular reduction for p256 = 2^256 - 2^224 + 2^192+ 2^96 - 1. a can be r. + * Uses algorithm 2.29 from Hankerson, Menezes, Vanstone. Guide to + * Elliptic Curve Cryptography. */ +mp_err +ec_GFp_nistp256_mod(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_size a_used = MP_USED(a); + int a_bits = mpl_significant_bits(a); + mp_digit carry; + +#ifdef ECL_THIRTY_TWO_BIT + mp_digit a8=0, a9=0, a10=0, a11=0, a12=0, a13=0, a14=0, a15=0; + mp_digit r0, r1, r2, r3, r4, r5, r6, r7; + int r8; /* must be a signed value ! */ +#else + mp_digit a4=0, a5=0, a6=0, a7=0; + mp_digit a4h, a4l, a5h, a5l, a6h, a6l, a7h, a7l; + mp_digit r0, r1, r2, r3; + int r4; /* must be a signed value ! */ +#endif + /* for polynomials larger than twice the field size + * use regular reduction */ + if (a_bits < 256) { + if (a == r) return MP_OKAY; + return mp_copy(a,r); + } + if (a_bits > 512) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { + +#ifdef ECL_THIRTY_TWO_BIT + switch (a_used) { + case 16: + a15 = MP_DIGIT(a,15); + case 15: + a14 = MP_DIGIT(a,14); + case 14: + a13 = MP_DIGIT(a,13); + case 13: + a12 = MP_DIGIT(a,12); + case 12: + a11 = MP_DIGIT(a,11); + case 11: + a10 = MP_DIGIT(a,10); + case 10: + a9 = MP_DIGIT(a,9); + case 9: + a8 = MP_DIGIT(a,8); + } + + r0 = MP_DIGIT(a,0); + r1 = MP_DIGIT(a,1); + r2 = MP_DIGIT(a,2); + r3 = MP_DIGIT(a,3); + r4 = MP_DIGIT(a,4); + r5 = MP_DIGIT(a,5); + r6 = MP_DIGIT(a,6); + r7 = MP_DIGIT(a,7); + + /* sum 1 */ + MP_ADD_CARRY(r3, a11, r3, 0, carry); + MP_ADD_CARRY(r4, a12, r4, carry, carry); + MP_ADD_CARRY(r5, a13, r5, carry, carry); + MP_ADD_CARRY(r6, a14, r6, carry, carry); + MP_ADD_CARRY(r7, a15, r7, carry, carry); + r8 = carry; + MP_ADD_CARRY(r3, a11, r3, 0, carry); + MP_ADD_CARRY(r4, a12, r4, carry, carry); + MP_ADD_CARRY(r5, a13, r5, carry, carry); + MP_ADD_CARRY(r6, a14, r6, carry, carry); + MP_ADD_CARRY(r7, a15, r7, carry, carry); + r8 += carry; + /* sum 2 */ + MP_ADD_CARRY(r3, a12, r3, 0, carry); + MP_ADD_CARRY(r4, a13, r4, carry, carry); + MP_ADD_CARRY(r5, a14, r5, carry, carry); + MP_ADD_CARRY(r6, a15, r6, carry, carry); + MP_ADD_CARRY(r7, 0, r7, carry, carry); + r8 += carry; + /* combine last bottom of sum 3 with second sum 2 */ + MP_ADD_CARRY(r0, a8, r0, 0, carry); + MP_ADD_CARRY(r1, a9, r1, carry, carry); + MP_ADD_CARRY(r2, a10, r2, carry, carry); + MP_ADD_CARRY(r3, a12, r3, carry, carry); + MP_ADD_CARRY(r4, a13, r4, carry, carry); + MP_ADD_CARRY(r5, a14, r5, carry, carry); + MP_ADD_CARRY(r6, a15, r6, carry, carry); + MP_ADD_CARRY(r7, a15, r7, carry, carry); /* from sum 3 */ + r8 += carry; + /* sum 3 (rest of it)*/ + MP_ADD_CARRY(r6, a14, r6, 0, carry); + MP_ADD_CARRY(r7, 0, r7, carry, carry); + r8 += carry; + /* sum 4 (rest of it)*/ + MP_ADD_CARRY(r0, a9, r0, 0, carry); + MP_ADD_CARRY(r1, a10, r1, carry, carry); + MP_ADD_CARRY(r2, a11, r2, carry, carry); + MP_ADD_CARRY(r3, a13, r3, carry, carry); + MP_ADD_CARRY(r4, a14, r4, carry, carry); + MP_ADD_CARRY(r5, a15, r5, carry, carry); + MP_ADD_CARRY(r6, a13, r6, carry, carry); + MP_ADD_CARRY(r7, a8, r7, carry, carry); + r8 += carry; + /* diff 5 */ + MP_SUB_BORROW(r0, a11, r0, 0, carry); + MP_SUB_BORROW(r1, a12, r1, carry, carry); + MP_SUB_BORROW(r2, a13, r2, carry, carry); + MP_SUB_BORROW(r3, 0, r3, carry, carry); + MP_SUB_BORROW(r4, 0, r4, carry, carry); + MP_SUB_BORROW(r5, 0, r5, carry, carry); + MP_SUB_BORROW(r6, a8, r6, carry, carry); + MP_SUB_BORROW(r7, a10, r7, carry, carry); + r8 -= carry; + /* diff 6 */ + MP_SUB_BORROW(r0, a12, r0, 0, carry); + MP_SUB_BORROW(r1, a13, r1, carry, carry); + MP_SUB_BORROW(r2, a14, r2, carry, carry); + MP_SUB_BORROW(r3, a15, r3, carry, carry); + MP_SUB_BORROW(r4, 0, r4, carry, carry); + MP_SUB_BORROW(r5, 0, r5, carry, carry); + MP_SUB_BORROW(r6, a9, r6, carry, carry); + MP_SUB_BORROW(r7, a11, r7, carry, carry); + r8 -= carry; + /* diff 7 */ + MP_SUB_BORROW(r0, a13, r0, 0, carry); + MP_SUB_BORROW(r1, a14, r1, carry, carry); + MP_SUB_BORROW(r2, a15, r2, carry, carry); + MP_SUB_BORROW(r3, a8, r3, carry, carry); + MP_SUB_BORROW(r4, a9, r4, carry, carry); + MP_SUB_BORROW(r5, a10, r5, carry, carry); + MP_SUB_BORROW(r6, 0, r6, carry, carry); + MP_SUB_BORROW(r7, a12, r7, carry, carry); + r8 -= carry; + /* diff 8 */ + MP_SUB_BORROW(r0, a14, r0, 0, carry); + MP_SUB_BORROW(r1, a15, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, a9, r3, carry, carry); + MP_SUB_BORROW(r4, a10, r4, carry, carry); + MP_SUB_BORROW(r5, a11, r5, carry, carry); + MP_SUB_BORROW(r6, 0, r6, carry, carry); + MP_SUB_BORROW(r7, a13, r7, carry, carry); + r8 -= carry; + + /* reduce the overflows */ + while (r8 > 0) { + mp_digit r8_d = r8; + MP_ADD_CARRY(r0, r8_d, r0, 0, carry); + MP_ADD_CARRY(r1, 0, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + MP_ADD_CARRY(r3, -r8_d, r3, carry, carry); + MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry, carry); + MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry, carry); + MP_ADD_CARRY(r6, -(r8_d+1), r6, carry, carry); + MP_ADD_CARRY(r7, (r8_d-1), r7, carry, carry); + r8 = carry; + } + + /* reduce the underflows */ + while (r8 < 0) { + mp_digit r8_d = -r8; + MP_SUB_BORROW(r0, r8_d, r0, 0, carry); + MP_SUB_BORROW(r1, 0, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, -r8_d, r3, carry, carry); + MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry, carry); + MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry, carry); + MP_SUB_BORROW(r6, -(r8_d+1), r6, carry, carry); + MP_SUB_BORROW(r7, (r8_d-1), r7, carry, carry); + r8 = -carry; + } + if (a != r) { + MP_CHECKOK(s_mp_pad(r,8)); + } + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 8; + + MP_DIGIT(r,7) = r7; + MP_DIGIT(r,6) = r6; + MP_DIGIT(r,5) = r5; + MP_DIGIT(r,4) = r4; + MP_DIGIT(r,3) = r3; + MP_DIGIT(r,2) = r2; + MP_DIGIT(r,1) = r1; + MP_DIGIT(r,0) = r0; + + /* final reduction if necessary */ + if ((r7 == MP_DIGIT_MAX) && + ((r6 > 1) || ((r6 == 1) && + (r5 || r4 || r3 || + ((r2 == MP_DIGIT_MAX) && (r1 == MP_DIGIT_MAX) + && (r0 == MP_DIGIT_MAX)))))) { + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } +#ifdef notdef + + + /* smooth the negatives */ + while (MP_SIGN(r) != MP_ZPOS) { + MP_CHECKOK(mp_add(r, &meth->irr, r)); + } + while (MP_USED(r) > 8) { + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } + + /* final reduction if necessary */ + if (MP_DIGIT(r,7) >= MP_DIGIT(&meth->irr,7)) { + if (mp_cmp(r,&meth->irr) != MP_LT) { + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } + } +#endif + s_mp_clamp(r); +#else + switch (a_used) { + case 8: + a7 = MP_DIGIT(a,7); + case 7: + a6 = MP_DIGIT(a,6); + case 6: + a5 = MP_DIGIT(a,5); + case 5: + a4 = MP_DIGIT(a,4); + } + a7l = a7 << 32; + a7h = a7 >> 32; + a6l = a6 << 32; + a6h = a6 >> 32; + a5l = a5 << 32; + a5h = a5 >> 32; + a4l = a4 << 32; + a4h = a4 >> 32; + r3 = MP_DIGIT(a,3); + r2 = MP_DIGIT(a,2); + r1 = MP_DIGIT(a,1); + r0 = MP_DIGIT(a,0); + + /* sum 1 */ + MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry); + MP_ADD_CARRY(r2, a6, r2, carry, carry); + MP_ADD_CARRY(r3, a7, r3, carry, carry); + r4 = carry; + MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry); + MP_ADD_CARRY(r2, a6, r2, carry, carry); + MP_ADD_CARRY(r3, a7, r3, carry, carry); + r4 += carry; + /* sum 2 */ + MP_ADD_CARRY(r1, a6l, r1, 0, carry); + MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry); + MP_ADD_CARRY(r3, a7h, r3, carry, carry); + r4 += carry; + MP_ADD_CARRY(r1, a6l, r1, 0, carry); + MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry); + MP_ADD_CARRY(r3, a7h, r3, carry, carry); + r4 += carry; + + /* sum 3 */ + MP_ADD_CARRY(r0, a4, r0, 0, carry); + MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + MP_ADD_CARRY(r3, a7, r3, carry, carry); + r4 += carry; + /* sum 4 */ + MP_ADD_CARRY(r0, a4h | a5l, r0, 0, carry); + MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry); + MP_ADD_CARRY(r2, a7, r2, carry, carry); + MP_ADD_CARRY(r3, a6h | a4l, r3, carry, carry); + r4 += carry; + /* diff 5 */ + MP_SUB_BORROW(r0, a5h | a6l, r0, 0, carry); + MP_SUB_BORROW(r1, a6h, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry, carry); + r4 -= carry; + /* diff 6 */ + MP_SUB_BORROW(r0, a6, r0, 0, carry); + MP_SUB_BORROW(r1, a7, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry, carry); + r4 -= carry; + /* diff 7 */ + MP_SUB_BORROW(r0, a6h|a7l, r0, 0, carry); + MP_SUB_BORROW(r1, a7h|a4l, r1, carry, carry); + MP_SUB_BORROW(r2, a4h|a5l, r2, carry, carry); + MP_SUB_BORROW(r3, a6l, r3, carry, carry); + r4 -= carry; + /* diff 8 */ + MP_SUB_BORROW(r0, a7, r0, 0, carry); + MP_SUB_BORROW(r1, a4h<<32, r1, carry, carry); + MP_SUB_BORROW(r2, a5, r2, carry, carry); + MP_SUB_BORROW(r3, a6h<<32, r3, carry, carry); + r4 -= carry; + + /* reduce the overflows */ + while (r4 > 0) { + mp_digit r4_long = r4; + mp_digit r4l = (r4_long << 32); + MP_ADD_CARRY(r0, r4_long, r0, 0, carry); + MP_ADD_CARRY(r1, -r4l, r1, carry, carry); + MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry); + MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry); + r4 = carry; + } + + /* reduce the underflows */ + while (r4 < 0) { + mp_digit r4_long = -r4; + mp_digit r4l = (r4_long << 32); + MP_SUB_BORROW(r0, r4_long, r0, 0, carry); + MP_SUB_BORROW(r1, -r4l, r1, carry, carry); + MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry, carry); + MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry, carry); + r4 = -carry; + } + + if (a != r) { + MP_CHECKOK(s_mp_pad(r,4)); + } + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + + MP_DIGIT(r,3) = r3; + MP_DIGIT(r,2) = r2; + MP_DIGIT(r,1) = r1; + MP_DIGIT(r,0) = r0; + + /* final reduction if necessary */ + if ((r3 > 0xFFFFFFFF00000001ULL) || + ((r3 == 0xFFFFFFFF00000001ULL) && + (r2 || (r1 >> 32)|| + (r1 == 0xFFFFFFFFULL && r0 == MP_DIGIT_MAX)))) { + /* very rare, just use mp_sub */ + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } + + s_mp_clamp(r); +#endif + } + + CLEANUP: + return res; +} + +/* Compute the square of polynomial a, reduce modulo p256. Store the + * result in r. r could be a. Uses optimized modular reduction for p256. + */ +mp_err +ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_sqr(a, r)); + MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Compute the product of two polynomials a and b, reduce modulo p256. + * Store the result in r. r could be a or b; a could be b. Uses + * optimized modular reduction for p256. */ +mp_err +ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_mul(a, b, r)); + MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Wire in fast field arithmetic and precomputation of base point for + * named curves. */ +mp_err +ec_group_set_gfp256(ECGroup *group, ECCurveName name) +{ + if (name == ECCurve_NIST_P256) { + group->meth->field_mod = &ec_GFp_nistp256_mod; + group->meth->field_mul = &ec_GFp_nistp256_mul; + group->meth->field_sqr = &ec_GFp_nistp256_sqr; + } + return MP_OKAY; +} diff --git a/security/nss/lib/freebl/ecl/ecp_384.c b/security/nss/lib/freebl/ecl/ecp_384.c new file mode 100644 index 000000000..4ad4137d2 --- /dev/null +++ b/security/nss/lib/freebl/ecl/ecp_384.c @@ -0,0 +1,293 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 elliptic curve math library for prime field curves. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Douglas Stebila <douglas@stebila.ca> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ecp.h" +#include "mpi.h" +#include "mplogic.h" +#include "mpi-priv.h" +#include <stdlib.h> + +/* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1. a can be r. + * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to + * Elliptic Curve Cryptography. */ +mp_err +ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + int a_bits = mpl_significant_bits(a); + int i; + + /* m1, m2 are statically-allocated mp_int of exactly the size we need */ + mp_int m[10]; + +#ifdef ECL_THIRTY_TWO_BIT + mp_digit s[10][12]; + for (i = 0; i < 10; i++) { + MP_SIGN(&m[i]) = MP_ZPOS; + MP_ALLOC(&m[i]) = 12; + MP_USED(&m[i]) = 12; + MP_DIGITS(&m[i]) = s[i]; + } +#else + mp_digit s[10][6]; + for (i = 0; i < 10; i++) { + MP_SIGN(&m[i]) = MP_ZPOS; + MP_ALLOC(&m[i]) = 6; + MP_USED(&m[i]) = 6; + MP_DIGITS(&m[i]) = s[i]; + } +#endif + +#ifdef ECL_THIRTY_TWO_BIT + /* for polynomials larger than twice the field size or polynomials + * not using all words, use regular reduction */ + if ((a_bits > 768) || (a_bits <= 736)) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { + for (i = 0; i < 12; i++) { + s[0][i] = MP_DIGIT(a, i); + } + s[1][0] = 0; + s[1][1] = 0; + s[1][2] = 0; + s[1][3] = 0; + s[1][4] = MP_DIGIT(a, 21); + s[1][5] = MP_DIGIT(a, 22); + s[1][6] = MP_DIGIT(a, 23); + s[1][7] = 0; + s[1][8] = 0; + s[1][9] = 0; + s[1][10] = 0; + s[1][11] = 0; + for (i = 0; i < 12; i++) { + s[2][i] = MP_DIGIT(a, i+12); + } + s[3][0] = MP_DIGIT(a, 21); + s[3][1] = MP_DIGIT(a, 22); + s[3][2] = MP_DIGIT(a, 23); + for (i = 3; i < 12; i++) { + s[3][i] = MP_DIGIT(a, i+9); + } + s[4][0] = 0; + s[4][1] = MP_DIGIT(a, 23); + s[4][2] = 0; + s[4][3] = MP_DIGIT(a, 20); + for (i = 4; i < 12; i++) { + s[4][i] = MP_DIGIT(a, i+8); + } + s[5][0] = 0; + s[5][1] = 0; + s[5][2] = 0; + s[5][3] = 0; + s[5][4] = MP_DIGIT(a, 20); + s[5][5] = MP_DIGIT(a, 21); + s[5][6] = MP_DIGIT(a, 22); + s[5][7] = MP_DIGIT(a, 23); + s[5][8] = 0; + s[5][9] = 0; + s[5][10] = 0; + s[5][11] = 0; + s[6][0] = MP_DIGIT(a, 20); + s[6][1] = 0; + s[6][2] = 0; + s[6][3] = MP_DIGIT(a, 21); + s[6][4] = MP_DIGIT(a, 22); + s[6][5] = MP_DIGIT(a, 23); + s[6][6] = 0; + s[6][7] = 0; + s[6][8] = 0; + s[6][9] = 0; + s[6][10] = 0; + s[6][11] = 0; + s[7][0] = MP_DIGIT(a, 23); + for (i = 1; i < 12; i++) { + s[7][i] = MP_DIGIT(a, i+11); + } + s[8][0] = 0; + s[8][1] = MP_DIGIT(a, 20); + s[8][2] = MP_DIGIT(a, 21); + s[8][3] = MP_DIGIT(a, 22); + s[8][4] = MP_DIGIT(a, 23); + s[8][5] = 0; + s[8][6] = 0; + s[8][7] = 0; + s[8][8] = 0; + s[8][9] = 0; + s[8][10] = 0; + s[8][11] = 0; + s[9][0] = 0; + s[9][1] = 0; + s[9][2] = 0; + s[9][3] = MP_DIGIT(a, 23); + s[9][4] = MP_DIGIT(a, 23); + s[9][5] = 0; + s[9][6] = 0; + s[9][7] = 0; + s[9][8] = 0; + s[9][9] = 0; + s[9][10] = 0; + s[9][11] = 0; + + MP_CHECKOK(mp_add(&m[0], &m[1], r)); + MP_CHECKOK(mp_add(r, &m[1], r)); + MP_CHECKOK(mp_add(r, &m[2], r)); + MP_CHECKOK(mp_add(r, &m[3], r)); + MP_CHECKOK(mp_add(r, &m[4], r)); + MP_CHECKOK(mp_add(r, &m[5], r)); + MP_CHECKOK(mp_add(r, &m[6], r)); + MP_CHECKOK(mp_sub(r, &m[7], r)); + MP_CHECKOK(mp_sub(r, &m[8], r)); + MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r)); + s_mp_clamp(r); + } +#else + /* for polynomials larger than twice the field size or polynomials + * not using all words, use regular reduction */ + if ((a_bits > 768) || (a_bits <= 736)) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { + for (i = 0; i < 6; i++) { + s[0][i] = MP_DIGIT(a, i); + } + s[1][0] = 0; + s[1][1] = 0; + s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32); + s[1][3] = MP_DIGIT(a, 11) >> 32; + s[1][4] = 0; + s[1][5] = 0; + for (i = 0; i < 6; i++) { + s[2][i] = MP_DIGIT(a, i+6); + } + s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32); + s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32); + for (i = 2; i < 6; i++) { + s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32); + } + s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32; + s[4][1] = MP_DIGIT(a, 10) << 32; + for (i = 2; i < 6; i++) { + s[4][i] = MP_DIGIT(a, i+4); + } + s[5][0] = 0; + s[5][1] = 0; + s[5][2] = MP_DIGIT(a, 10); + s[5][3] = MP_DIGIT(a, 11); + s[5][4] = 0; + s[5][5] = 0; + s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32; + s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32; + s[6][2] = MP_DIGIT(a, 11); + s[6][3] = 0; + s[6][4] = 0; + s[6][5] = 0; + s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32); + for (i = 1; i < 6; i++) { + s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32); + } + s[8][0] = MP_DIGIT(a, 10) << 32; + s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32); + s[8][2] = MP_DIGIT(a, 11) >> 32; + s[8][3] = 0; + s[8][4] = 0; + s[8][5] = 0; + s[9][0] = 0; + s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32; + s[9][2] = MP_DIGIT(a, 11) >> 32; + s[9][3] = 0; + s[9][4] = 0; + s[9][5] = 0; + + MP_CHECKOK(mp_add(&m[0], &m[1], r)); + MP_CHECKOK(mp_add(r, &m[1], r)); + MP_CHECKOK(mp_add(r, &m[2], r)); + MP_CHECKOK(mp_add(r, &m[3], r)); + MP_CHECKOK(mp_add(r, &m[4], r)); + MP_CHECKOK(mp_add(r, &m[5], r)); + MP_CHECKOK(mp_add(r, &m[6], r)); + MP_CHECKOK(mp_sub(r, &m[7], r)); + MP_CHECKOK(mp_sub(r, &m[8], r)); + MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r)); + s_mp_clamp(r); + } +#endif + + CLEANUP: + return res; +} + +/* Compute the square of polynomial a, reduce modulo p384. Store the + * result in r. r could be a. Uses optimized modular reduction for p384. + */ +mp_err +ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_sqr(a, r)); + MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Compute the product of two polynomials a and b, reduce modulo p384. + * Store the result in r. r could be a or b; a could be b. Uses + * optimized modular reduction for p384. */ +mp_err +ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_mul(a, b, r)); + MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Wire in fast field arithmetic and precomputation of base point for + * named curves. */ +mp_err +ec_group_set_gfp384(ECGroup *group, ECCurveName name) +{ + if (name == ECCurve_NIST_P384) { + group->meth->field_mod = &ec_GFp_nistp384_mod; + group->meth->field_mul = &ec_GFp_nistp384_mul; + group->meth->field_sqr = &ec_GFp_nistp384_sqr; + } + return MP_OKAY; +} diff --git a/security/nss/lib/freebl/ecl/ecp_521.c b/security/nss/lib/freebl/ecl/ecp_521.c new file mode 100644 index 000000000..685d19b9f --- /dev/null +++ b/security/nss/lib/freebl/ecl/ecp_521.c @@ -0,0 +1,170 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 elliptic curve math library for prime field curves. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Douglas Stebila <douglas@stebila.ca> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ecp.h" +#include "mpi.h" +#include "mplogic.h" +#include "mpi-priv.h" +#include <stdlib.h> + +#define ECP521_DIGITS ECL_CURVE_DIGITS(521) + +/* Fast modular reduction for p521 = 2^521 - 1. a can be r. Uses + * algorithm 2.31 from Hankerson, Menezes, Vanstone. Guide to + * Elliptic Curve Cryptography. */ +mp_err +ec_GFp_nistp521_mod(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + int a_bits = mpl_significant_bits(a); + int i; + + /* m1, m2 are statically-allocated mp_int of exactly the size we need */ + mp_int m1; + + mp_digit s1[ECP521_DIGITS] = { 0 }; + + MP_SIGN(&m1) = MP_ZPOS; + MP_ALLOC(&m1) = ECP521_DIGITS; + MP_USED(&m1) = ECP521_DIGITS; + MP_DIGITS(&m1) = s1; + + if (a_bits < 521) { + if (a==r) return MP_OKAY; + return mp_copy(a, r); + } + /* for polynomials larger than twice the field size or polynomials + * not using all words, use regular reduction */ + if (a_bits > (521*2)) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { +#define FIRST_DIGIT (ECP521_DIGITS-1) + for (i = FIRST_DIGIT; i < MP_USED(a)-1; i++) { + s1[i-FIRST_DIGIT] = (MP_DIGIT(a, i) >> 9) + | (MP_DIGIT(a, 1+i) << (MP_DIGIT_BIT-9)); + } + s1[i-FIRST_DIGIT] = MP_DIGIT(a, i) >> 9; + + if ( a != r ) { + MP_CHECKOK(s_mp_pad(r,ECP521_DIGITS)); + for (i = 0; i < ECP521_DIGITS; i++) { + MP_DIGIT(r,i) = MP_DIGIT(a, i); + } + } + MP_USED(r) = ECP521_DIGITS; + MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF; + + MP_CHECKOK(s_mp_add(r, &m1)); + if (MP_DIGIT(r, FIRST_DIGIT) & 0x200) { + MP_CHECKOK(s_mp_add_d(r,1)); + MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF; + } + s_mp_clamp(r); + } + + CLEANUP: + return res; +} + +/* Compute the square of polynomial a, reduce modulo p521. Store the + * result in r. r could be a. Uses optimized modular reduction for p521. + */ +mp_err +ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_sqr(a, r)); + MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Compute the product of two polynomials a and b, reduce modulo p521. + * Store the result in r. r could be a or b; a could be b. Uses + * optimized modular reduction for p521. */ +mp_err +ec_GFp_nistp521_mul(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_mul(a, b, r)); + MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Divides two field elements. If a is NULL, then returns the inverse of + * b. */ +mp_err +ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_int t; + + /* If a is NULL, then return the inverse of b, otherwise return a/b. */ + if (a == NULL) { + return mp_invmod(b, &meth->irr, r); + } else { + /* MPI doesn't support divmod, so we implement it using invmod and + * mulmod. */ + MP_CHECKOK(mp_init(&t)); + MP_CHECKOK(mp_invmod(b, &meth->irr, &t)); + MP_CHECKOK(mp_mul(a, &t, r)); + MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth)); + CLEANUP: + mp_clear(&t); + return res; + } +} + +/* Wire in fast field arithmetic and precomputation of base point for + * named curves. */ +mp_err +ec_group_set_gfp521(ECGroup *group, ECCurveName name) +{ + if (name == ECCurve_NIST_P521) { + group->meth->field_mod = &ec_GFp_nistp521_mod; + group->meth->field_mul = &ec_GFp_nistp521_mul; + group->meth->field_sqr = &ec_GFp_nistp521_sqr; + group->meth->field_div = &ec_GFp_nistp521_div; + } + return MP_OKAY; +} diff --git a/security/nss/lib/freebl/ecl/tests/ec2_test.c b/security/nss/lib/freebl/ecl/tests/ec2_test.c index e82b47da0..cf6540221 100644 --- a/security/nss/lib/freebl/ecl/tests/ec2_test.c +++ b/security/nss/lib/freebl/ecl/tests/ec2_test.c @@ -455,6 +455,36 @@ main(int argv, char **argc) ECTEST_GENERIC_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1); /* specific arithmetic tests */ + ECTEST_NAMED_GF2M("NIST-K163", ECCurve_NIST_K163); + ECTEST_NAMED_GF2M("NIST-B163", ECCurve_NIST_B163); + ECTEST_NAMED_GF2M("NIST-K233", ECCurve_NIST_K233); + ECTEST_NAMED_GF2M("NIST-B233", ECCurve_NIST_B233); + ECTEST_NAMED_GF2M("NIST-K283", ECCurve_NIST_K283); + ECTEST_NAMED_GF2M("NIST-B283", ECCurve_NIST_B283); + ECTEST_NAMED_GF2M("NIST-K409", ECCurve_NIST_K409); + ECTEST_NAMED_GF2M("NIST-B409", ECCurve_NIST_B409); + ECTEST_NAMED_GF2M("NIST-K571", ECCurve_NIST_K571); + ECTEST_NAMED_GF2M("NIST-B571", ECCurve_NIST_B571); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V1", ECCurve_X9_62_CHAR2_PNB163V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V2", ECCurve_X9_62_CHAR2_PNB163V2); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V3", ECCurve_X9_62_CHAR2_PNB163V3); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB176V1", ECCurve_X9_62_CHAR2_PNB176V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V1", ECCurve_X9_62_CHAR2_TNB191V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V2", ECCurve_X9_62_CHAR2_TNB191V2); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V3", ECCurve_X9_62_CHAR2_TNB191V3); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB208W1", ECCurve_X9_62_CHAR2_PNB208W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V1", ECCurve_X9_62_CHAR2_TNB239V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V2", ECCurve_X9_62_CHAR2_TNB239V2); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V3", ECCurve_X9_62_CHAR2_TNB239V3); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB272W1", ECCurve_X9_62_CHAR2_PNB272W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB304W1", ECCurve_X9_62_CHAR2_PNB304W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB359V1", ECCurve_X9_62_CHAR2_TNB359V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB368W1", ECCurve_X9_62_CHAR2_PNB368W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB431R1", ECCurve_X9_62_CHAR2_TNB431R1); + ECTEST_NAMED_GF2M("SECT-113R1", ECCurve_SECG_CHAR2_113R1); + ECTEST_NAMED_GF2M("SECT-113R2", ECCurve_SECG_CHAR2_113R2); + ECTEST_NAMED_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1); + ECTEST_NAMED_GF2M("SECT-131R2", ECCurve_SECG_CHAR2_131R2); ECTEST_NAMED_GF2M("SECT-163K1", ECCurve_SECG_CHAR2_163K1); ECTEST_NAMED_GF2M("SECT-163R1", ECCurve_SECG_CHAR2_163R1); ECTEST_NAMED_GF2M("SECT-163R2", ECCurve_SECG_CHAR2_163R2); @@ -462,6 +492,19 @@ main(int argv, char **argc) ECTEST_NAMED_GF2M("SECT-193R2", ECCurve_SECG_CHAR2_193R2); ECTEST_NAMED_GF2M("SECT-233K1", ECCurve_SECG_CHAR2_233K1); ECTEST_NAMED_GF2M("SECT-233R1", ECCurve_SECG_CHAR2_233R1); + ECTEST_NAMED_GF2M("SECT-239K1", ECCurve_SECG_CHAR2_239K1); + ECTEST_NAMED_GF2M("SECT-283K1", ECCurve_SECG_CHAR2_283K1); + ECTEST_NAMED_GF2M("SECT-283R1", ECCurve_SECG_CHAR2_283R1); + ECTEST_NAMED_GF2M("SECT-409K1", ECCurve_SECG_CHAR2_409K1); + ECTEST_NAMED_GF2M("SECT-409R1", ECCurve_SECG_CHAR2_409R1); + ECTEST_NAMED_GF2M("SECT-571K1", ECCurve_SECG_CHAR2_571K1); + ECTEST_NAMED_GF2M("SECT-571R1", ECCurve_SECG_CHAR2_571R1); + ECTEST_NAMED_GF2M("WTLS-1 (113)", ECCurve_WTLS_1); + ECTEST_NAMED_GF2M("WTLS-3 (163)", ECCurve_WTLS_3); + ECTEST_NAMED_GF2M("WTLS-4 (113)", ECCurve_WTLS_4); + ECTEST_NAMED_GF2M("WTLS-5 (163)", ECCurve_WTLS_5); + ECTEST_NAMED_GF2M("WTLS-10 (233)", ECCurve_WTLS_10); + ECTEST_NAMED_GF2M("WTLS-11 (233)", ECCurve_WTLS_11); CLEANUP: EC_FreeCurveParams(params); diff --git a/security/nss/lib/freebl/ecl/tests/ecp_test.c b/security/nss/lib/freebl/ecl/tests/ecp_test.c index d7ce299ec..eb2844fe5 100644 --- a/security/nss/lib/freebl/ecl/tests/ecp_test.c +++ b/security/nss/lib/freebl/ecl/tests/ecp_test.c @@ -417,6 +417,22 @@ main(int argv, char **argc) ECTEST_GENERIC_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); /* specific arithmetic tests */ + ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192); + ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224); + ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256); + ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384); + ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1); + ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1); + ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2); + ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1); + ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2); ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2); @@ -424,6 +440,15 @@ main(int argv, char **argc) ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1); ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1); ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1); + ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1); + ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1); + ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1); + ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1); + ECTEST_NAMED_GFP("WTLS-6 (112)", ECCurve_WTLS_6); + ECTEST_NAMED_GFP("WTLS-7 (160)", ECCurve_WTLS_7); + ECTEST_NAMED_GFP("WTLS-8 (112)", ECCurve_WTLS_8); + ECTEST_NAMED_GFP("WTLS-9 (160)", ECCurve_WTLS_9); + ECTEST_NAMED_GFP("WTLS-12 (224)", ECCurve_WTLS_12); CLEANUP: EC_FreeCurveParams(params); diff --git a/security/nss/lib/freebl/freebl.rc b/security/nss/lib/freebl/freebl.rc index 4f60cba9f..39b0e70bc 100644 --- a/security/nss/lib/freebl/freebl.rc +++ b/security/nss/lib/freebl/freebl.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 2005 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/freebl/ldvector.c b/security/nss/lib/freebl/ldvector.c index 595d7dd8b..70a4eed50 100644 --- a/security/nss/lib/freebl/ldvector.c +++ b/security/nss/lib/freebl/ldvector.c @@ -222,6 +222,11 @@ static const struct FREEBLVectorStr vector = RNG_SystemInfoForRNG, /* End of Version 3.008. */ + + FIPS186Change_GenerateX, + FIPS186Change_ReduceModQForDSA, + + /* End of Version 3.009. */ }; const FREEBLVector * diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c index b98ea9c68..2bce3bea2 100644 --- a/security/nss/lib/freebl/loader.c +++ b/security/nss/lib/freebl/loader.c @@ -125,20 +125,18 @@ static const char * getLibName(void) { return default_name; } #ifdef XP_UNIX #include <unistd.h> -#endif #define BL_MAXSYMLINKS 20 /* * If 'link' is a symbolic link, this function follows the symbolic links * and returns the pathname of the ultimate source of the symbolic links. - * If 'link' is not a symbolic link, this function returns a copy of 'link'. + * If 'link' is not a symbolic link, this function returns NULL. * The caller should call PR_Free to free the string returned by this * function. */ static char* bl_GetOriginalPathname(const char* link) { -#ifdef XP_UNIX char* resolved = NULL; char* input = NULL; PRUint32 iterations = 0; @@ -168,16 +166,13 @@ static char* bl_GetOriginalPathname(const char* link) resolved = tmp; } PR_Free(resolved); - return input; -#else - if (link) { - return PL_strdup(link); - } else { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; + if (iterations == 1 && retlen < 0) { + PR_Free(input); + input = NULL; } -#endif + return input; } +#endif /* XP_UNIX */ /* * We use PR_GetLibraryFilePathname to get the pathname of the loaded @@ -192,26 +187,49 @@ static char* bl_GetOriginalPathname(const char* link) const char* softoken=SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX; -typedef struct { - PRLibrary *dlh; -} BLLibrary; +static PRLibrary* blLib; + +/* + * Load the freebl library with the file name 'name' residing in the same + * directory as libsoftoken, whose pathname is 'softokenPath'. + */ +static PRLibrary * +bl_LoadFreeblLibInSoftokenDir(const char *softokenPath, const char *name) +{ + PRLibrary *dlh = NULL; + char *fullName = NULL; + char* c; + PRLibSpec libSpec; + + /* Remove "libsoftokn" from the pathname and add the freebl libname */ + c = strrchr(softokenPath, PR_GetDirectorySeparator()); + if (c) { + size_t softoknPathSize = 1 + c - softokenPath; + fullName = (char*) PORT_Alloc(strlen(name) + softoknPathSize + 1); + if (fullName) { + memcpy(fullName, softokenPath, softoknPathSize); + strcpy(fullName + softoknPathSize, name); +#ifdef DEBUG_LOADER + PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n", + fullName); +#endif + libSpec.type = PR_LibSpec_Pathname; + libSpec.value.pathname = fullName; + dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); + PORT_Free(fullName); + } + } + return dlh; +} -static BLLibrary * +static PRLibrary * bl_LoadLibrary(const char *name) { - BLLibrary *lib = NULL; + PRLibrary *lib = NULL; PRFuncPtr fn_addr; char* softokenPath = NULL; - char* fullName = NULL; PRLibSpec libSpec; - libSpec.type = PR_LibSpec_Pathname; - lib = PR_NEWZAP(BLLibrary); - if (NULL == lib) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - /* Get the pathname for the loaded libsoftokn, i.e. /usr/lib/libsoftokn3.so * PR_GetLibraryFilePathname works with either the base library name or a * function pointer, depending on the platform. We can't query an exported @@ -222,70 +240,40 @@ bl_LoadLibrary(const char *name) fn_addr = (PRFuncPtr) &bl_LoadLibrary; softokenPath = PR_GetLibraryFilePathname(softoken, fn_addr); - /* Remove "libsoftokn" from the pathname and add the freebl libname */ if (softokenPath) { - char* c; - char* originalSoftokenPath = bl_GetOriginalPathname(softokenPath); - if (originalSoftokenPath) { - PR_Free(softokenPath); - softokenPath = originalSoftokenPath; - } - c = strrchr(softokenPath, PR_GetDirectorySeparator()); - if (c) { - size_t softoknPathSize = 1 + c - softokenPath; - fullName = (char*) PORT_Alloc(strlen(name) + softoknPathSize + 1); - if (fullName) { - memcpy(fullName, softokenPath, softoknPathSize); - strcpy(fullName + softoknPathSize, name); - } - } - PR_Free(softokenPath); - } - if (fullName) { -#ifdef DEBUG_LOADER - PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n", - fullName); + lib = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); +#ifdef XP_UNIX + if (!lib) { + /* + * If softokenPath is a symbolic link, resolve the symbolic + * link and try again. + */ + char* originalSoftokenPath = bl_GetOriginalPathname(softokenPath); + if (originalSoftokenPath) { + PR_Free(softokenPath); + softokenPath = originalSoftokenPath; + lib = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); + } + } #endif - libSpec.value.pathname = fullName; - lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); - PORT_Free(fullName); + PR_Free(softokenPath); } - if (!lib->dlh) { + if (!lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", name); #endif + libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = name; - lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); + lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); } - if (NULL == lib->dlh) { + if (NULL == lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", name); #endif - PR_Free(lib); - lib = NULL; } return lib; } -static void * -bl_FindSymbol(BLLibrary *lib, const char *name) -{ - void *f; - - f = PR_FindSymbol(lib->dlh, name); - return f; -} - -static PRStatus -bl_UnloadLibrary(BLLibrary *lib) -{ - if (PR_SUCCESS != PR_UnloadLibrary(lib->dlh)) { - return PR_FAILURE; - } - PR_Free(lib); - return PR_SUCCESS; -} - #define LSB(x) ((x)&0xff) #define MSB(x) ((x)>>8) @@ -297,7 +285,7 @@ static const char *libraryName = NULL; static PRStatus freebl_LoadDSO( void ) { - BLLibrary * handle; + PRLibrary * handle; const char * name = getLibName(); if (!name) { @@ -307,7 +295,8 @@ freebl_LoadDSO( void ) handle = bl_LoadLibrary(name); if (handle) { - void * address = bl_FindSymbol(handle, "FREEBL_GetVector"); + PRFuncPtr address = PR_FindFunctionSymbol(handle, "FREEBL_GetVector"); + PRStatus status; if (address) { FREEBLGetVectorFn * getVector = (FREEBLGetVectorFn *)address; const FREEBLVector * dsoVector = getVector(); @@ -319,22 +308,26 @@ freebl_LoadDSO( void ) dsoVector->length >= sizeof(FREEBLVector)) { vector = dsoVector; libraryName = name; + blLib = handle; return PR_SUCCESS; } } } - bl_UnloadLibrary(handle); + status = PR_UnloadLibrary(handle); + PORT_Assert(PR_SUCCESS == status); } return PR_FAILURE; } +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType loadFreeBLOnce; + static PRStatus freebl_RunLoaderOnce( void ) { PRStatus status; - static PRCallOnceType once; - status = PR_CallOnce(&once, &freebl_LoadDSO); + status = PR_CallOnce(&loadFreeBLOnce, &freebl_LoadDSO); return status; } @@ -987,6 +980,25 @@ BL_Cleanup(void) (vector->p_BL_Cleanup)(); } +void +BL_Unload(void) +{ + /* This function is not thread-safe, but doesn't need to be, because it is + * only called from functions that are also defined as not thread-safe, + * namely C_Finalize in softoken, and the SSL bypass shutdown callback called + * from NSS_Shutdown. */ + vector = NULL; + /* If an SSL socket is configured with SSL_BYPASS_PKCS11, but the application + * never does a handshake on it, BL_Unload will be called even though freebl + * was never loaded. So, don't assert blLib. */ + if (blLib) { + PRStatus status = PR_UnloadLibrary(blLib); + PORT_Assert(PR_SUCCESS == status); + blLib = NULL; + } + loadFreeBLOnce = pristineCallOnce; +} + /* ============== New for 3.003 =============================== */ SECStatus @@ -1614,3 +1626,22 @@ RNG_SystemInfoForRNG(void) (vector->p_RNG_SystemInfoForRNG)(); } + +SECStatus +FIPS186Change_GenerateX(unsigned char *XKEY, const unsigned char *XSEEDj, + unsigned char *x_j) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) + return SECFailure; + return (vector->p_FIPS186Change_GenerateX)(XKEY, XSEEDj, x_j); +} + +SECStatus +FIPS186Change_ReduceModQForDSA(const unsigned char *w, + const unsigned char *q, + unsigned char *xj) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) + return SECFailure; + return (vector->p_FIPS186Change_ReduceModQForDSA)(w, q, xj); +} diff --git a/security/nss/lib/freebl/loader.h b/security/nss/lib/freebl/loader.h index 89bab5401..df7c5c99b 100644 --- a/security/nss/lib/freebl/loader.h +++ b/security/nss/lib/freebl/loader.h @@ -44,7 +44,7 @@ #include "blapi.h" -#define FREEBL_VERSION 0x0308 +#define FREEBL_VERSION 0x0309 struct FREEBLVectorStr { @@ -449,6 +449,15 @@ struct FREEBLVectorStr { void (* p_RNG_SystemInfoForRNG)(void); /* Version 3.008 came to here */ + + SECStatus (* p_FIPS186Change_GenerateX)(unsigned char *XKEY, + const unsigned char *XSEEDj, + unsigned char *x_j); + SECStatus (* p_FIPS186Change_ReduceModQForDSA)(const unsigned char *w, + const unsigned char *q, + unsigned char *xj); + + /* Version 3.009 came to here */ }; typedef struct FREEBLVectorStr FREEBLVector; diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn index 787c7fbec..8e172c426 100644 --- a/security/nss/lib/freebl/manifest.mn +++ b/security/nss/lib/freebl/manifest.mn @@ -104,11 +104,13 @@ MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c ECL_HDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h ifdef NSS_ENABLE_ECC ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \ - ec2_aff.c ec2_mont.c ec2_proj.c \ - ec2_163.c ec2_193.c ec2_233.c \ ecp_aff.c ecp_jac.c ecp_mont.c \ - ecp_192.c ecp_224.c \ ec_naf.c ecp_jm.c +ifdef NSS_ECC_MORE_THAN_SUITE_B +ECL_SRCS += ec2_aff.c ec2_mont.c ec2_proj.c \ + ec2_163.c ec2_193.c ec2_233.c \ + ecp_192.c ecp_224.c ecp_256.c ecp_384.c ecp_521.c +endif else ECL_SRCS = $(NULL) endif @@ -158,6 +160,7 @@ ALL_HDRS = \ secmpi.h \ sha.h \ sha_fast.h \ + sha256.h \ shsign.h \ vis_proto.h \ $(NULL) diff --git a/security/nss/lib/freebl/mpi/Makefile b/security/nss/lib/freebl/mpi/Makefile index 3c780f5ac..4716f6ac5 100644 --- a/security/nss/lib/freebl/mpi/Makefile +++ b/security/nss/lib/freebl/mpi/Makefile @@ -112,7 +112,7 @@ DOCS=README doc utils/README utils/PRIMES TOOLS=gcd invmod isprime lap dec2hex hex2dec primegen prng \ basecvt fact exptmod pi makeprime identest -LIBOBJS = mpprime.o mpmontg.o mplogic.o mp_gf2m.o mpi.o $(AS_OBJS) +LIBOBJS = mpprime.o mpmontg.o mplogic.o mp_gf2m.o mpi.o mpcpucache.o $(AS_OBJS) LIBHDRS = mpi-config.h mpi-priv.h mpi.h APPHDRS = mpi-config.h mpi.h mplogic.h mp_gf2m.h mpprime.h @@ -154,6 +154,8 @@ mpmontg.o: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS) mpprime.o: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS) +mpcpucache.o: mpcpucache.c $(LIBHDRS) + mpi_mips.o: mpi_mips.s $(CC) -o $@ $(ASFLAGS) -c mpi_mips.s diff --git a/security/nss/lib/freebl/mpi/mp_gf2m.c b/security/nss/lib/freebl/mpi/mp_gf2m.c index 962fdb1fb..5ce9fed9e 100644 --- a/security/nss/lib/freebl/mpi/mp_gf2m.c +++ b/security/nss/lib/freebl/mpi/mp_gf2m.c @@ -92,7 +92,7 @@ s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b) mp_digit tab[16], top3b = a >> 61; register mp_digit a1, a2, a4, a8; - a1 = a & (0x1FFFFFFFFFFFFFFF); a2 = a1 << 1; + a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1; tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2; tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4; diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c index f9602c6aa..2ea3ad15e 100644 --- a/security/nss/lib/freebl/mpi/mpi.c +++ b/security/nss/lib/freebl/mpi/mpi.c @@ -4759,6 +4759,8 @@ mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return pos; } /* end mp_to_unsigned_octets() */ /* }}} */ @@ -4797,6 +4799,8 @@ mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return pos; } /* end mp_to_signed_octets() */ /* }}} */ @@ -4832,6 +4836,8 @@ mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return MP_OKAY; } /* end mp_to_fixlen_octets() */ /* }}} */ diff --git a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s index 7515ac20a..86e16e362 100644 --- a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s +++ b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s @@ -416,3 +416,7 @@ ret .size s_mpv_mul_add_vec64, [.-s_mpv_mul_add_vec64] + +# Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits +.previous diff --git a/security/nss/lib/freebl/mpi/mpi_sparc.c b/security/nss/lib/freebl/mpi/mpi_sparc.c index eb2317dd0..f7eb19c19 100644 --- a/security/nss/lib/freebl/mpi/mpi_sparc.c +++ b/security/nss/lib/freebl/mpi/mpi_sparc.c @@ -177,11 +177,11 @@ v8_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) #endif } -/* vis versions of these functions run only on v8+vis or v9+vis CPUs. */ +/* These functions run only on v8plus+vis or v9+vis CPUs. */ /* c = a * b */ -static void -vis_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; @@ -204,8 +204,8 @@ vis_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) } /* c += a * b, where a is a_len words long. */ -static void -vis_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; @@ -227,9 +227,8 @@ vis_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) } /* c += a * b, where a is y words long. */ -static void -vis_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, - mp_digit *c) +void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; @@ -256,106 +255,3 @@ vis_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, v8_mpv_mul_d_add_prop(a, a_len, b, c); } } - -#if defined(SOLARIS2_5) -static int -isSparcV8PlusVis(void) -{ - long buflen; - int rv = 0; /* false */ - char buf[256]; - buflen = sysinfo(SI_MACHINE, buf, sizeof buf); - if (buflen > 0) { - rv = (!strcmp(buf, "sun4u") || !strcmp(buf, "sun4u1")); - } - return rv; -} -#else /* SunOS2.6or higher has SI_ISALIST */ - -static int -isSparcV8PlusVis(void) -{ - long buflen; - int rv = 0; /* false */ - char buf[256]; - buflen = sysinfo(SI_ISALIST, buf, sizeof buf); - if (buflen > 0) { -#if defined(MP_USE_LONG_DIGIT) - char * found = strstr(buf, "sparcv9+vis"); -#else - char * found = strstr(buf, "sparcv8plus+vis"); -#endif - rv = (found != 0); - } - return rv; -} -#endif - -typedef void MPVmpy(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c); - -/* forward static function declarations */ -static MPVmpy sp_mpv_mul_d; -static MPVmpy sp_mpv_mul_d_add; -static MPVmpy sp_mpv_mul_d_add_prop; - -static MPVmpy *p_mpv_mul_d = &sp_mpv_mul_d; -static MPVmpy *p_mpv_mul_d_add = &sp_mpv_mul_d_add; -static MPVmpy *p_mpv_mul_d_add_prop = &sp_mpv_mul_d_add_prop; - -static void -initPtrs(void) -{ - if (isSparcV8PlusVis()) { - p_mpv_mul_d = &vis_mpv_mul_d; - p_mpv_mul_d_add = &vis_mpv_mul_d_add; - p_mpv_mul_d_add_prop = &vis_mpv_mul_d_add_prop; - } else { - p_mpv_mul_d = &v8_mpv_mul_d; - p_mpv_mul_d_add = &v8_mpv_mul_d_add; - p_mpv_mul_d_add_prop = &v8_mpv_mul_d_add_prop; - } -} - -static void -sp_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - initPtrs(); - (* p_mpv_mul_d)(a, a_len, b, c); -} - -static void -sp_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - initPtrs(); - (* p_mpv_mul_d_add)(a, a_len, b, c); -} - -static void -sp_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - initPtrs(); - (* p_mpv_mul_d_add_prop)(a, a_len, b, c); -} - - -/* This is the external interface */ - -void -s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - (* p_mpv_mul_d)(a, a_len, b, c); -} - -void -s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - (* p_mpv_mul_d_add)(a, a_len, b, c); -} - -void -s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - (* p_mpv_mul_d_add_prop)(a, a_len, b, c); -} - - diff --git a/security/nss/lib/freebl/mpi/mpi_x86.asm b/security/nss/lib/freebl/mpi/mpi_x86.asm deleted file mode 100644 index 826747c39..000000000 --- a/security/nss/lib/freebl/mpi/mpi_x86.asm +++ /dev/null @@ -1,356 +0,0 @@ -; -; mpi_x86.asm - assembly language implementation of s_mpv_ functions. -; -; ***** BEGIN LICENSE BLOCK ***** -; Version: MPL 1.1/GPL 2.0/LGPL 2.1 -; -; 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 the Initial Developer are Copyright (C) 2000 -; the Initial Developer. All Rights Reserved. -; -; Contributor(s): -; -; Alternatively, the contents of this file may be used under the terms of -; either the GNU General Public License Version 2 or later (the "GPL"), or -; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -; in which case the provisions of the GPL or the LGPL are applicable instead -; of those above. If you wish to allow use of your version of this file only -; under the terms of either the GPL or the LGPL, and not to allow others to -; use your version of this file under the terms of the MPL, indicate your -; decision by deleting the provisions above and replace them with the notice -; and other provisions required by the GPL or the LGPL. If you do not delete -; the provisions above, a recipient may use your version of this file under -; the terms of any one of the MPL, the GPL or the LGPL. -; -; ***** END LICENSE BLOCK ***** - -; $Id$ - - .386p - .MODEL FLAT - ASSUME CS: FLAT, DS: FLAT, SS: FLAT -_TEXT SEGMENT - -; ebp - 36: caller's esi -; ebp - 32: caller's edi -; ebp - 28: -; ebp - 24: -; ebp - 20: -; ebp - 16: -; ebp - 12: -; ebp - 8: -; ebp - 4: -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: a argument -; ebp + 12: a_len argument -; ebp + 16: b argument -; ebp + 20: c argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr - -public _s_mpv_mul_d -_s_mpv_mul_d PROC NEAR - push ebp - mov ebp,esp - sub esp,28 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len - mov edi,[ebp+20] - cmp ecx,0 - je L_2 ; jmp if a_len == 0 - mov esi,[ebp+8] ; esi = a - cld -L_1: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b - - add eax,ebx ; add carry (ebx) to edx:eax - adc edx,0 - mov ebx,edx ; high half of product becomes next carry - - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_1 ; jmp if a_len != 0 -L_2: - mov [edi],ebx ; *c = carry - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_mul_d ENDP - -; ebp - 36: caller's esi -; ebp - 32: caller's edi -; ebp - 28: -; ebp - 24: -; ebp - 20: -; ebp - 16: -; ebp - 12: -; ebp - 8: -; ebp - 4: -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: a argument -; ebp + 12: a_len argument -; ebp + 16: b argument -; ebp + 20: c argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr -public _s_mpv_mul_d_add -_s_mpv_mul_d_add PROC NEAR - push ebp - mov ebp,esp - sub esp,28 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len - mov edi,[ebp+20] - cmp ecx,0 - je L_4 ; jmp if a_len == 0 - mov esi,[ebp+8] ; esi = a - cld -L_3: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b - - add eax,ebx ; add carry (ebx) to edx:eax - adc edx,0 - mov ebx,[edi] ; add in current word from *c - add eax,ebx - adc edx,0 - mov ebx,edx ; high half of product becomes next carry - - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_3 ; jmp if a_len != 0 -L_4: - mov [edi],ebx ; *c = carry - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_mul_d_add ENDP - -; ebp - 36: caller's esi -; ebp - 32: caller's edi -; ebp - 28: -; ebp - 24: -; ebp - 20: -; ebp - 16: -; ebp - 12: -; ebp - 8: -; ebp - 4: -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: a argument -; ebp + 12: a_len argument -; ebp + 16: b argument -; ebp + 20: c argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr -public _s_mpv_mul_d_add_prop -_s_mpv_mul_d_add_prop PROC NEAR - push ebp - mov ebp,esp - sub esp,28 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len - mov edi,[ebp+20] - cmp ecx,0 - je L_6 ; jmp if a_len == 0 - cld - mov esi,[ebp+8] ; esi = a -L_5: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b - - add eax,ebx ; add carry (ebx) to edx:eax - adc edx,0 - mov ebx,[edi] ; add in current word from *c - add eax,ebx - adc edx,0 - mov ebx,edx ; high half of product becomes next carry - - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_5 ; jmp if a_len != 0 -L_6: - cmp ebx,0 ; is carry zero? - jz L_8 - mov eax,[edi] ; add in current word from *c - add eax,ebx - stosd ; [es:edi] = ax; edi += 4; - jnc L_8 -L_7: - mov eax,[edi] ; add in current word from *c - adc eax,0 - stosd ; [es:edi] = ax; edi += 4; - jc L_7 -L_8: - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_mul_d_add_prop ENDP - -; ebp - 20: caller's esi -; ebp - 16: caller's edi -; ebp - 12: -; ebp - 8: carry -; ebp - 4: a_len local -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: pa argument -; ebp + 12: a_len argument -; ebp + 16: ps argument -; ebp + 20: -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr - -public _s_mpv_sqr_add_prop -_s_mpv_sqr_add_prop PROC NEAR - push ebp - mov ebp,esp - sub esp,12 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; a_len - mov edi,[ebp+16] ; edi = ps - cmp ecx,0 - je L_11 ; jump if a_len == 0 - cld - mov esi,[ebp+8] ; esi = pa -L_10: - lodsd ; eax = [ds:si]; si += 4; - mul eax - - add eax,ebx ; add "carry" - adc edx,0 - mov ebx,[edi] - add eax,ebx ; add low word from result - mov ebx,[edi+4] - stosd ; [es:di] = eax; di += 4; - adc edx,ebx ; add high word from result - mov ebx,0 - mov eax,edx - adc ebx,0 - stosd ; [es:di] = eax; di += 4; - dec ecx ; --a_len - jnz L_10 ; jmp if a_len != 0 -L_11: - cmp ebx,0 ; is carry zero? - jz L_14 - mov eax,[edi] ; add in current word from *c - add eax,ebx - stosd ; [es:edi] = ax; edi += 4; - jnc L_14 -L_12: - mov eax,[edi] ; add in current word from *c - adc eax,0 - stosd ; [es:edi] = ax; edi += 4; - jc L_12 -L_14: - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_sqr_add_prop ENDP - -; -; Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized -; so its high bit is 1. This code is from NSPR. -; -; mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, -; mp_digit *qp, mp_digit *rp) - -; Dump of assembler code for function s_mpv_div_2dx1d: -; -; esp + 0: Caller's ebx -; esp + 4: return address -; esp + 8: Nhi argument -; esp + 12: Nlo argument -; esp + 16: divisor argument -; esp + 20: qp argument -; esp + 24: rp argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr -; -public _s_mpv_div_2dx1d -_s_mpv_div_2dx1d PROC NEAR - push ebx - mov edx,[esp+8] - mov eax,[esp+12] - mov ebx,[esp+16] - div ebx - mov ebx,[esp+20] - mov [ebx],eax - mov ebx,[esp+24] - mov [ebx],edx - xor eax,eax ; return zero - pop ebx - ret - nop -_s_mpv_div_2dx1d ENDP - -_TEXT ENDS -END diff --git a/security/nss/lib/freebl/mpi/mpi_x86_asm.c b/security/nss/lib/freebl/mpi/mpi_x86_asm.c new file mode 100644 index 000000000..b8a224f14 --- /dev/null +++ b/security/nss/lib/freebl/mpi/mpi_x86_asm.c @@ -0,0 +1,368 @@ +/* + * mpi_x86.c - MSVC inline assembly implementation of s_mpv_ functions. + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Benjamin Smedberg <benjamin@smedbergs.us> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "mpi-priv.h" + +/* + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +{ + __asm { + push ebp + mov ebp,esp + sub esp,28 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len + mov edi,[ebp+20] + cmp ecx,0 + je L_2 ; jmp if a_len == 0 + mov esi,[ebp+8] ; esi = a + cld +L_1: + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b + + add eax,ebx ; add carry (ebx) to edx:eax + adc edx,0 + mov ebx,edx ; high half of product becomes next carry + + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_1 ; jmp if a_len != 0 +L_2: + mov [edi],ebx ; *c = carry + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +{ + __asm { + push ebp + mov ebp,esp + sub esp,28 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len + mov edi,[ebp+20] + cmp ecx,0 + je L_4 ; jmp if a_len == 0 + mov esi,[ebp+8] ; esi = a + cld +L_3: + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b + + add eax,ebx ; add carry (ebx) to edx:eax + adc edx,0 + mov ebx,[edi] ; add in current word from *c + add eax,ebx + adc edx,0 + mov ebx,edx ; high half of product becomes next carry + + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_3 ; jmp if a_len != 0 +L_4: + mov [edi],ebx ; *c = carry + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +{ + __asm { + push ebp + mov ebp,esp + sub esp,28 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len + mov edi,[ebp+20] + cmp ecx,0 + je L_6 ; jmp if a_len == 0 + cld + mov esi,[ebp+8] ; esi = a +L_5: + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b + + add eax,ebx ; add carry (ebx) to edx:eax + adc edx,0 + mov ebx,[edi] ; add in current word from *c + add eax,ebx + adc edx,0 + mov ebx,edx ; high half of product becomes next carry + + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_5 ; jmp if a_len != 0 +L_6: + cmp ebx,0 ; is carry zero? + jz L_8 + mov eax,[edi] ; add in current word from *c + add eax,ebx + stosd ; [es:edi] = ax; edi += 4; + jnc L_8 +L_7: + mov eax,[edi] ; add in current word from *c + adc eax,0 + stosd ; [es:edi] = ax; edi += 4; + jc L_7 +L_8: + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * ebp - 20: caller's esi + * ebp - 16: caller's edi + * ebp - 12: + * ebp - 8: carry + * ebp - 4: a_len local + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: pa argument + * ebp + 12: a_len argument + * ebp + 16: ps argument + * ebp + 20: + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs) +{ + __asm { + push ebp + mov ebp,esp + sub esp,12 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; a_len + mov edi,[ebp+16] ; edi = ps + cmp ecx,0 + je L_11 ; jump if a_len == 0 + cld + mov esi,[ebp+8] ; esi = pa +L_10: + lodsd ; eax = [ds:si]; si += 4; + mul eax + + add eax,ebx ; add "carry" + adc edx,0 + mov ebx,[edi] + add eax,ebx ; add low word from result + mov ebx,[edi+4] + stosd ; [es:di] = eax; di += 4; + adc edx,ebx ; add high word from result + mov ebx,0 + mov eax,edx + adc ebx,0 + stosd ; [es:di] = eax; di += 4; + dec ecx ; --a_len + jnz L_10 ; jmp if a_len != 0 +L_11: + cmp ebx,0 ; is carry zero? + jz L_14 + mov eax,[edi] ; add in current word from *c + add eax,ebx + stosd ; [es:edi] = ax; edi += 4; + jnc L_14 +L_12: + mov eax,[edi] ; add in current word from *c + adc eax,0 + stosd ; [es:edi] = ax; edi += 4; + jc L_12 +L_14: + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized + * so its high bit is 1. This code is from NSPR. + * + * Dump of assembler code for function s_mpv_div_2dx1d: + * + * esp + 0: Caller's ebx + * esp + 4: return address + * esp + 8: Nhi argument + * esp + 12: Nlo argument + * esp + 16: divisor argument + * esp + 20: qp argument + * esp + 24: rp argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) mp_err +s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, + mp_digit *qp, mp_digit *rp) +{ + __asm { + push ebx + mov edx,[esp+8] + mov eax,[esp+12] + mov ebx,[esp+16] + div ebx + mov ebx,[esp+20] + mov [ebx],eax + mov ebx,[esp+24] + mov [ebx],edx + xor eax,eax ; return zero + pop ebx + ret + nop + } +} diff --git a/security/nss/lib/freebl/mpi/mpmontg.c b/security/nss/lib/freebl/mpi/mpmontg.c index 1e0f0fd6d..bea8009c2 100644 --- a/security/nss/lib/freebl/mpi/mpmontg.c +++ b/security/nss/lib/freebl/mpi/mpmontg.c @@ -60,8 +60,8 @@ /* if MP_CHAR_STORE_SLOW is defined, we */ /* need to know endianness of this platform. */ #ifdef MP_CHAR_STORE_SLOW -#if !defined(MPI_IS_BIG_ENDIAN) && !defined(MPI_IS_LITTLE_ENDIAN) -#error "You must define MPI_IS_BIG_ENDIAN or MPI_IS_LITTLE_ENDIAN\n" \ +#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN) +#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \ " if you define MP_CHAR_STORE_SLOW." #endif #endif @@ -541,108 +541,106 @@ mp_err mp_set_safe_modexp(int value) #ifndef MP_CHAR_STORE_SLOW /* - * mpi_to_weave takes MPI data and stores in into a byte array interleaved. + * mpi_to_weave takes an array of bignums, a matrix in which each bignum + * occupies all the columns of a row, and transposes it into a matrix in + * which each bignum occupies a column of every row. The first row of the + * input matrix becomes the first column of the output matrix. The n'th + * row of input becomes the n'th column of output. The input data is said + * to be "interleaved" or "woven" into the output matrix. * - * The purpose of this interleaving is to hide our access to the array of - * modulus powers from and attacker snooping on cache hits and misses. Because - * the array is interleaved, each reference will cause exactly the same cache - * lines to reload. + * The array of bignums is left in this woven form. Each time a single + * bignum value is needed, it is recreated by fetching the n'th column, + * forming a single row which is the new bignum. * - * There are 2 different implementations in this file, one which works with just - * byte loads and stores, the second which works with mp_weave_word loads and - * stores. These 2 implementations have DIFFERENT results in exactly which byte - * of an mp_digit winds up in which location in the byte array. That is why - * there are 2 sets of explanations for how the array is set up. + * The purpose of this interleaving is make it impossible to determine which + * of the bignums is being used in any one operation by examining the pattern + * of cache misses. * + * The weaving function does not transpose the entire input matrix in one call. + * It transposes 4 rows of mp_ints into their respective columns of output. * - * a is an array of WEAVE_WORD_SIZE mp_ints (that is 4). - * It is a partial window into a logical array mp_int p[count] containing - * the base to the 0 through count-1 powers. Ideally this code would be - * simpler if we stored one element of that array at a time, but on some - * platforms the cost of storing a byte incurs a full read modify write cycle - * and increases the memory bandwidth cost by a factor of 4 or 8. By collecting - * for mp_ints together, we can arrange to store all 4 values in a single - * word write. - * - * b is the targeted weaved location. b[0] points to the first byte where - * first byte of the a array needs to be stored. Each b is an offset into the - * weave array. - * - * count is 2^window size. - * - * b_size is the size in mp_digits of each mp_int in the array. mp_ints - * with less than b_size elements are logically padded with zeros before - * storing. + * There are two different implementations of the weaving and unweaving code + * in this file. One uses byte loads and stores. The second uses loads and + * stores of mp_weave_word size values. The weaved forms of these two + * implementations differ. Consequently, each one has its own explanation. * + * Here is the explanation for the byte-at-a-time implementation. * - * Data is stored as follows : - * The mp_int array is treated as a byte array. + * This implementation treats each mp_int bignum as an array of bytes, + * rather than as an array of mp_digits. It stores those bytes as a + * column of bytes in the output matrix. It doesn't care if the machine + * uses big-endian or little-endian byte ordering within mp_digits. + * The first byte of the mp_digit array becomes the first byte in the output + * column, regardless of whether that byte is the MSB or LSB of the mp_digit. * + * "bignums" is an array of mp_ints. + * It points to four rows, four mp_ints, a subset of a larger array of mp_ints. * - * we want to eventually store the logical array mp_int p[count] into the - * weave array as follows: - - * p[count].digit is treated as a byte array (rather than * an mp_digit array), - * N is count, and n is b_size * *sizeof(mp_digit): - * - * p[0].digit[0] p[1].digit[0] ...... p[N-2].digit[0] p[N-1].digit[0] - * p[0].digit[1] p[1].digit[1] ...... p[N-2].digit[1] p[N-1].digit[1] - * . . - * . . - * p[0].digit[n-2] p[1].digit[n-2] ...... p[N-2].digit[n-2] p[N-1].digit[n-2] - * p[0].digit[n-1] p[1].digit[n-1] ...... p[N-2].digit[n-1] p[N-1].digit[n-1] + * "weaved" is the weaved output matrix. + * The first byte of bignums[0] is stored in weaved[0]. + * + * "nBignums" is the total number of bignums in the array of which "bignums" + * is a part. * - * This function stores that a window of p in each call. + * "nDigits" is the size in mp_digits of each mp_int in the "bignums" array. + * mp_ints that use less than nDigits digits are logically padded with zeros + * while being stored in the weaved array. */ -mp_err mpi_to_weave(const mp_int *a, unsigned char *b, - mp_size b_size, mp_size count) +mp_err mpi_to_weave(const mp_int *bignums, + unsigned char *weaved, + mp_size nDigits, /* in each mp_int of input */ + mp_size nBignums) /* in the entire source array */ { - mp_size i, j; - unsigned char *bsave = b; + mp_size i; + unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit)); for (i=0; i < WEAVE_WORD_SIZE; i++) { - unsigned char *pb = (unsigned char *)MP_DIGITS(&a[i]); - mp_size useda = MP_USED(&a[i]); - mp_size zero = b_size - useda; - unsigned char *end = pb+ (useda*sizeof(mp_digit)); - b = bsave+i; - + mp_size used = MP_USED(&bignums[i]); + unsigned char *pSrc = (unsigned char *)MP_DIGITS(&bignums[i]); + unsigned char *endSrc = pSrc + (used * sizeof(mp_digit)); + unsigned char *pDest = weaved + i; - ARGCHK(MP_SIGN(&a[i]) == MP_ZPOS, MP_BADARG); - ARGCHK(useda <= b_size, MP_BADARG); + ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG); + ARGCHK(used <= nDigits, MP_BADARG); - for (; pb < end; pb++) { - *b = *pb; - b += count; + for (; pSrc < endSrc; pSrc++) { + *pDest = *pSrc; + pDest += nBignums; } - for (j=0; j < zero; j++) { - *b = 0; - b += count; + while (pDest < endDest) { + *pDest = 0; + pDest += nBignums; } } return MP_OKAY; } -/* reverse the operation above for one entry. - * b points to the offset into the weave array of the power we are - * calculating */ -mp_err weave_to_mpi(mp_int *a, const unsigned char *b, - mp_size b_size, mp_size count) +/* Reverse the operation above for one mp_int. + * Reconstruct one mp_int from its column in the weaved array. + * "pSrc" points to the offset into the weave array of the bignum we + * are going to reconstruct. + */ +mp_err weave_to_mpi(mp_int *a, /* output, result */ + const unsigned char *pSrc, /* input, byte matrix */ + mp_size nDigits, /* per mp_int output */ + mp_size nBignums) /* bignums in weaved matrix */ { - unsigned char *pb = (unsigned char *)MP_DIGITS(a); - unsigned char *end = pb+ (b_size*sizeof(mp_digit)); + unsigned char *pDest = (unsigned char *)MP_DIGITS(a); + unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit)); MP_SIGN(a) = MP_ZPOS; - MP_USED(a) = b_size; + MP_USED(a) = nDigits; - for (; pb < end; b+=count, pb++) { - *pb = *b; + for (; pDest < endDest; pSrc += nBignums, pDest++) { + *pDest = *pSrc; } s_mp_clamp(a); return MP_OKAY; } + #else + /* Need a primitive that we know is 32 bits long... */ /* this is true on all modern processors we know of today*/ typedef unsigned int mp_weave_word; @@ -703,8 +701,8 @@ mp_err mpi_to_weave(const mp_int *a, unsigned char *b, count = count/sizeof(mp_weave_word); /* this code pretty much depends on this ! */ -#if MP_ARGCHK < 2 - assert(WEAVE_WORD_SIZE == 4); +#if MP_ARGCHK == 2 + assert(WEAVE_WORD_SIZE == 4); assert(sizeof(mp_weave_word) == 4); #endif @@ -754,19 +752,19 @@ mp_err mpi_to_weave(const mp_int *a, unsigned char *b, * NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE * is 4. */ -#ifdef IS_LITTLE_ENDIAN +#ifdef MP_IS_LITTLE_ENDIAN #define MPI_WEAVE_ONE_STEP \ - acc = (d0 >> (MP_DIGIT_BITS-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \ - acc |= (d1 >> (MP_DIGIT_BITS-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \ - acc |= (d2 >> (MP_DIGIT_BITS-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \ - acc |= (d3 >> (MP_DIGIT_BITS-32)) & 0xff000000; d3 <<= 8; /*b3*/ \ + acc = (d0 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \ + acc |= (d1 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \ + acc |= (d2 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \ + acc |= (d3 >> (MP_DIGIT_BIT-32)) & 0xff000000; d3 <<= 8; /*b3*/ \ *weaved = acc; weaved += count; #else #define MPI_WEAVE_ONE_STEP \ - acc = (d0 >> (MP_DIGIT_BITS-32)) & 0xff000000; d0 <<= 8; /*b0*/ \ - acc |= (d1 >> (MP_DIGIT_BITS-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \ - acc |= (d2 >> (MP_DIGIT_BITS-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \ - acc |= (d3 >> (MP_DIGIT_BITS-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \ + acc = (d0 >> (MP_DIGIT_BIT-32)) & 0xff000000; d0 <<= 8; /*b0*/ \ + acc |= (d1 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \ + acc |= (d2 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \ + acc |= (d3 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \ *weaved = acc; weaved += count; #endif switch (sizeof(mp_digit)) { @@ -898,7 +896,7 @@ mp_err weave_to_mpi(mp_int *a, const unsigned char *b, MUL_NOWEAVE(&tmp,a,b) #define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp -#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(~((y)-1))) +#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(((ptrdiff_t)0)-(y))) /* Do modular exponentiation using integer multiply code. */ mp_err mp_exptmod_safe_i(const mp_int * montBase, @@ -921,6 +919,14 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, unsigned char *powersArray; unsigned char *powers; + MP_DIGITS(&accum1) = 0; + MP_DIGITS(&accum2) = 0; + MP_DIGITS(&accum[0]) = 0; + MP_DIGITS(&accum[1]) = 0; + MP_DIGITS(&accum[2]) = 0; + MP_DIGITS(&accum[3]) = 0; + MP_DIGITS(&tmp) = 0; + powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1)); if (powersArray == NULL) { res = MP_MEM; @@ -930,13 +936,6 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, /* powers[i] = base ** (i); */ powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); - MP_DIGITS(&accum1) = 0; - MP_DIGITS(&accum2) = 0; - MP_DIGITS(&accum[0]) = 0; - MP_DIGITS(&accum[1]) = 0; - MP_DIGITS(&accum[2]) = 0; - MP_DIGITS(&accum[3]) = 0; - /* grab the first window value. This allows us to preload accumulator1 * and save a conversion, some squares and a multiple*/ MP_CHECKOK( mpl_get_bits(exponent, @@ -945,7 +944,6 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) ); MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) ); - MP_DIGITS(&tmp) = 0; MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) ); /* build the first WEAVE_WORD powers inline */ @@ -1070,6 +1068,7 @@ CLEANUP: mp_clear(&accum[1]); mp_clear(&accum[2]); mp_clear(&accum[3]); + mp_clear(&tmp); /* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */ free(powersArray); return res; diff --git a/security/nss/lib/freebl/mpi/mpprime.c b/security/nss/lib/freebl/mpi/mpprime.c index dfe7988f7..32d6f6f70 100644 --- a/security/nss/lib/freebl/mpi/mpprime.c +++ b/security/nss/lib/freebl/mpi/mpprime.c @@ -427,20 +427,10 @@ mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, mp_int trial; mp_int q; mp_size num_tests; - /* - * Always make sieve the last variabale allocated so that - * Mac builds don't break by adding an extra variable - * on the stack. -javi - */ -#if defined(macintosh) || defined (XP_OS2) \ - || (defined(HPUX) && defined(__ia64)) unsigned char *sieve; sieve = malloc(SIEVE_SIZE); ARGCHK(sieve != NULL, MP_MEM); -#else - unsigned char sieve[SIEVE_SIZE]; -#endif ARGCHK(start != 0, MP_BADARG); ARGCHK(nBits > 16, MP_RANGE); @@ -575,13 +565,10 @@ CLEANUP: mp_clear(&q); if (nTries) *nTries += i; -#if defined(macintosh) || defined(XP_OS2) \ - || (defined(HPUX) && defined(__ia64)) if (sieve != NULL) { memset(sieve, 0, SIEVE_SIZE); free (sieve); } -#endif return res; } diff --git a/security/nss/lib/freebl/mpi/target.mk b/security/nss/lib/freebl/mpi/target.mk index c17854819..6f71e8053 100644 --- a/security/nss/lib/freebl/mpi/target.mk +++ b/security/nss/lib/freebl/mpi/target.mk @@ -229,3 +229,21 @@ MPICMN += $(MP_CONFIG) mpi_amd64_asm.o: mpi_amd64_sun.s $(AS) -xarch=generic64 -P -D_ASM mpi_amd64_sun.s endif + +ifeq ($(TARGET),WIN32) +AS_OBJS = mpi_x86.obj +MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D +MPICMN += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD -DMP_API_COMPATIBLE +MPICMN += -DMP_MONT_USE_MP_MUL +MPICMN += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN +CFLAGS = -Od -Z7 -MDd -W3 -nologo -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USER) +CFLAGS += -DWIN32 -D_WINDOWS -D_X86_ -DWIN95 -DXP_PC -DNSS_ENABLE_ECC +CFLAGS += $(MPICMN) + +$(AS_OBJS): %.obj : %.asm + ml -Cp -Sn -Zi -coff -nologo -c $< + +$(LIBOBJS): %.obj : %.c + cl $(CFLAGS) -Fo$@ -c $< + +endif diff --git a/security/nss/lib/freebl/mpi/tests/mptest-7.c b/security/nss/lib/freebl/mpi/tests/mptest-7.c index a32be1978..3153133cb 100644 --- a/security/nss/lib/freebl/mpi/tests/mptest-7.c +++ b/security/nss/lib/freebl/mpi/tests/mptest-7.c @@ -47,7 +47,7 @@ #include <limits.h> #include <time.h> -#define MP_IOFUNC +#define MP_IOFUNC 1 #include "mpi.h" #include "mpprime.h" diff --git a/security/nss/lib/freebl/mpi/tests/mptest-8.c b/security/nss/lib/freebl/mpi/tests/mptest-8.c index 7cf95a9b1..8bff49b20 100644 --- a/security/nss/lib/freebl/mpi/tests/mptest-8.c +++ b/security/nss/lib/freebl/mpi/tests/mptest-8.c @@ -47,7 +47,7 @@ #include <limits.h> #include <time.h> -#define MP_IOFUNC +#define MP_IOFUNC 1 #include "mpi.h" #include "mpprime.h" diff --git a/security/nss/lib/freebl/nss.h b/security/nss/lib/freebl/nss.h new file mode 100644 index 000000000..d0f72fb07 --- /dev/null +++ b/security/nss/lib/freebl/nss.h @@ -0,0 +1,253 @@ +/*********************************************************************** + * + * A copy of nss.h from NSS 3.11.4 for the directories that make up the + * NSS cryptographic module (lib/freebl and lib/softoken). + * + * When compiling in these directories, the compiler uses the local copy + * of nss.h, allowing the NSS cryptographic module to stay at version + * 3.11.4 (the version submitted to NIST for FIPS 140-2 validation). + * + * DO NOT CHANGE THIS FILE. + * + ***********************************************************************/ +/* + * NSS utility functions + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +/* $Id$ */ + +#ifndef __nss_h_ +#define __nss_h_ + +#include "seccomon.h" + +SEC_BEGIN_PROTOS + +/* + * NSS's major version, minor version, patch level, and whether + * this is a beta release. + * + * The format of the version string should be + * "<major version>.<minor version>[.<patch level>] [<Beta>]" + */ +/* ***** DO NOT CHANGE THIS FILE. ***** */ +#ifdef NSS_ENABLE_ECC +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#define NSS_VERSION "3.11.4 Extended ECC" +#else +#define NSS_VERSION "3.11.4 Basic ECC" +#endif +#else +#define NSS_VERSION "3.11.4" +#endif +#define NSS_VMAJOR 3 +#define NSS_VMINOR 11 +#define NSS_VPATCH 4 +#define NSS_BETA PR_FALSE + +/* + * Return a boolean that indicates whether the underlying library + * will perform as the caller expects. + * + * The only argument is a string, which should be the verson + * identifier of the NSS library. That string will be compared + * against a string that represents the actual build version of + * the NSS library. It also invokes the version checking functions + * of the dependent libraries such as NSPR. + */ +extern PRBool NSS_VersionCheck(const char *importedVersion); + +/* + * Open the Cert, Key, and Security Module databases, read only. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_Init(const char *configdir); + +/* + * Returns whether NSS has already been initialized or not. + */ +extern PRBool NSS_IsInitialized(void); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_InitReadWrite(const char *configdir); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + * + * This allows using application defined prefixes for the cert and key db's + * and an alternate name for the secmod database. NOTE: In future releases, + * the database prefixes my not necessarily map to database names. + * + * configdir - base directory where all the cert, key, and module datbases live. + * certPrefix - prefix added to the beginning of the cert database example: " + * "https-server1-" + * keyPrefix - prefix added to the beginning of the key database example: " + * "https-server1-" + * secmodName - name of the security module database (usually "secmod.db"). + * flags - change the open options of NSS_Initialize as follows: + * NSS_INIT_READONLY - Open the databases read only. + * NSS_INIT_NOCERTDB - Don't open the cert DB and key DB's, just + * initialize the volatile certdb. + * NSS_INIT_NOMODDB - Don't open the security module DB, just + * initialize the PKCS #11 module. + * NSS_INIT_FORCEOPEN - Continue to force initializations even if the + * databases cannot be opened. + * NSS_INIT_NOROOTINIT - Don't try to look for the root certs module + * automatically. + * NSS_INIT_OPTIMIZESPACE - Use smaller tables and caches. + * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are + * thread-safe, ie. that support locking - either OS + * locking or NSS-provided locks . If a PKCS#11 + * module isn't thread-safe, don't serialize its + * calls; just don't load it instead. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example the Java SunPKCS11 provider. + * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED + * error when loading PKCS#11 modules. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example Java SunPKCS11 provider. + * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any + * PKCS#11 module. This may be necessary in order to + * ensure continuous operation and proper shutdown + * sequence if another piece of code is using the same + * PKCS#11 modules that NSS is accessing without going + * through NSS, for example Java SunPKCS11 provider. + * The following limitation applies when this is set : + * SECMOD_WaitForAnyTokenEvent will not use + * C_WaitForSlotEvent, in order to prevent the need for + * C_Finalize. This call will be emulated instead. + * NSS_INIT_RESERVED - Currently has no effect, but may be used in the + * future to trigger better cooperation between PKCS#11 + * modules used by both NSS and the Java SunPKCS11 + * provider. This should occur after a new flag is defined + * for C_Initialize by the PKCS#11 working group. + * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that + * use both NSS and the Java SunPKCS11 provider. + * + * Also NOTE: This is not the recommended method for initializing NSS. + * The prefered method is NSS_init(). + */ +#define NSS_INIT_READONLY 0x1 +#define NSS_INIT_NOCERTDB 0x2 +#define NSS_INIT_NOMODDB 0x4 +#define NSS_INIT_FORCEOPEN 0x8 +#define NSS_INIT_NOROOTINIT 0x10 +#define NSS_INIT_OPTIMIZESPACE 0x20 +#define NSS_INIT_PK11THREADSAFE 0x40 +#define NSS_INIT_PK11RELOAD 0x80 +#define NSS_INIT_NOPK11FINALIZE 0x100 +#define NSS_INIT_RESERVED 0x200 + +#define NSS_INIT_COOPERATE NSS_INIT_PK11THREADSAFE | \ + NSS_INIT_PK11RELOAD | \ + NSS_INIT_NOPK11FINALIZE | \ + NSS_INIT_RESERVED + +#ifdef macintosh +#define SECMOD_DB "Security Modules" +#else +#define SECMOD_DB "secmod.db" +#endif + +extern SECStatus NSS_Initialize(const char *configdir, + const char *certPrefix, const char *keyPrefix, + const char *secmodName, PRUint32 flags); + +/* + * initialize NSS without a creating cert db's, key db's, or secmod db's. + */ +SECStatus NSS_NoDB_Init(const char *configdir); + +/* + * Allow applications and libraries to register with NSS so that they are called + * when NSS shuts down. + * + * void *appData application specific data passed in by the application at + * NSS_RegisterShutdown() time. + * void *nssData is NULL in this release, but is reserved for future versions of + * NSS to pass some future status information * back to the shutdown function. + * + * If the shutdown function returns SECFailure, + * Shutdown will still complete, but NSS_Shutdown() will return SECFailure. + */ +typedef SECStatus (*NSS_ShutdownFunc)(void *appData, void *nssData); + +/* + * Register a shutdown function. + */ +SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Remove an existing shutdown function (you may do this if your library is + * complete and going away, but NSS is still running). + */ +SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Close the Cert, Key databases. + */ +extern SECStatus NSS_Shutdown(void); + +/* + * set the PKCS #11 strings for the internal token. + */ +void PK11_ConfigurePKCS11(const char *man, const char *libdes, + const char *tokdes, const char *ptokdes, const char *slotdes, + const char *pslotdes, const char *fslotdes, const char *fpslotdes, + int minPwd, int pwRequired); + +/* + * Dump the contents of the certificate cache and the temporary cert store. + * Use to detect leaked references of certs at shutdown time. + */ +void nss_DumpCertificateCacheInfo(void); + +SEC_END_PROTOS + +#endif /* __nss_h_ */ diff --git a/security/nss/lib/freebl/os2_rand.c b/security/nss/lib/freebl/os2_rand.c index 8138d30ae..467774b8b 100644 --- a/security/nss/lib/freebl/os2_rand.c +++ b/security/nss/lib/freebl/os2_rand.c @@ -37,7 +37,8 @@ #define INCL_DOS #define INCL_DOSERRORS #include <os2.h> -#include <secrng.h> +#include "secrng.h" +#include "prerror.h" #include <stdlib.h> #include <time.h> #include <stdio.h> @@ -331,3 +332,9 @@ void RNG_FileForRNG(const char *filename) nBytes = RNG_GetNoise(buffer, 20); RNG_RandomUpdate(buffer, nBytes); } + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return 0; +} diff --git a/security/nss/lib/freebl/pqg.c b/security/nss/lib/freebl/pqg.c index c3e92c62d..66c535fe9 100644 --- a/security/nss/lib/freebl/pqg.c +++ b/security/nss/lib/freebl/pqg.c @@ -78,6 +78,8 @@ static const unsigned char fips_186_1_a5_pqseed[] = { static SECStatus getPQseed(SECItem *seed, PRArenaPool* arena) { + SECStatus rv; + if (!seed->data) { seed->data = (unsigned char*)PORT_ArenaZAlloc(arena, seed->len); } @@ -89,7 +91,15 @@ getPQseed(SECItem *seed, PRArenaPool* arena) memcpy(seed->data, fips_186_1_a5_pqseed, seed->len); return SECSuccess; #else - return RNG_GenerateGlobalRandomBytes(seed->data, seed->len); + rv = RNG_GenerateGlobalRandomBytes(seed->data, seed->len); + /* + * NIST CMVP disallows a sequence of 20 bytes with the most + * significant byte equal to 0. Perhaps they interpret + * "a sequence of at least 160 bits" as "a number >= 2^159". + * So we always set the most significant bit to 1. (bug 334533) + */ + seed->data[0] |= 0x80; + return rv; #endif } @@ -322,8 +332,8 @@ makeGfromH(const mp_int *P, /* input. */ CHECK_MPI_OK( mp_init(&exp) ); CHECK_MPI_OK( mp_init(&pm1) ); CHECK_MPI_OK( mp_sub_d(P, 1, &pm1) ); /* P - 1 */ - if ( mp_cmp(H, &pm1) > 0) /* H = H mod (P-1) */ - CHECK_MPI_OK( mp_sub(H, &pm1, H) ); + if ( mp_cmp(H, &pm1) >= 0) /* H >= P-1 */ + CHECK_MPI_OK( mp_sub(H, &pm1, H) ); /* H = H mod (P-1) */ /* Let b = 2**n (smallest power of 2 greater than P). ** Since P-1 >= b/2, and H < b, quotient(H/(P-1)) = 0 or 1 ** so the above operation safely computes H mod (P-1) @@ -392,7 +402,7 @@ PQG_ParamGenSeedLen(unsigned int j, unsigned int seedBytes, mp_err err = MP_OKAY; SECStatus rv = SECFailure; int iterations = 0; - if (j > 8 || !pParams || !pVfy) { + if (j > 8 || seedBytes < 20 || !pParams || !pVfy) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } @@ -538,7 +548,7 @@ step_15: ** in certifying the proper generation of p and q." */ /* Generate h. */ - SECITEM_AllocItem(NULL, &hit, seedBytes); /* h is no longer than p */ + SECITEM_AllocItem(NULL, &hit, L/8); /* h is no longer than p */ if (!hit.data) goto cleanup; do { /* loop generate h until 1<h<p-1 and (h**[(p-1)/q])mod p > 1 */ @@ -628,7 +638,6 @@ PQG_VerifyParams(const PQGParams *params, /* 6. P is prime */ CHECKPARAM( mpp_pprime(&P, PQG_P_PRIMALITY_TESTS) == MP_YES ); /* Steps 7-12 are done only if the optional PQGVerify is supplied. */ - if (!vfy) goto cleanup; /* 7. counter < 4096 */ CHECKPARAM( vfy->counter < 4096 ); /* 8. g >= 160 and g < 2048 (g is length of seed in bits) */ diff --git a/security/nss/lib/freebl/prng_fips1861.c b/security/nss/lib/freebl/prng_fips1861.c index 900b98ab8..50c29692e 100644 --- a/security/nss/lib/freebl/prng_fips1861.c +++ b/security/nss/lib/freebl/prng_fips1861.c @@ -46,6 +46,7 @@ #include "nssilock.h" #include "secitem.h" #include "sha_fast.h" +#include "sha256.h" #include "secrng.h" /* for RNG_GetNoise() */ #include "secmpi.h" @@ -74,8 +75,10 @@ * SHA-256, or SHA-512). */ #define FIPS_B 256 -#define B_HASH_BUF SHA256_HashBuf #define BSIZE (FIPS_B / PR_BITS_PER_BYTE) +#if BSIZE != SHA256_LENGTH +#error "this file requires that BSIZE and SHA256_LENGTH be equal" +#endif /* Output size of the G function */ #define FIPS_G 160 @@ -106,9 +109,10 @@ * q, DSA_SUBPRIME_LEN bytes * Output: xj, DSA_SUBPRIME_LEN bytes */ -static SECStatus -dsa_reduce_mod_q(const unsigned char *w, const unsigned char *q, - unsigned char *xj) +SECStatus +FIPS186Change_ReduceModQForDSA(const unsigned char *w, + const unsigned char *q, + unsigned char *xj) { mp_int W, Q, Xj; mp_err err; @@ -168,28 +172,52 @@ struct RNGContextStr { }; typedef struct RNGContextStr RNGContext; static RNGContext *globalrng = NULL; +static RNGContext theGlobalRng; /* - * Free the global RNG context + * Clean up the global RNG context */ static void freeRNGContext() { + unsigned char inputhash[BSIZE]; + SECStatus rv; + + /* destroy context lock */ PZ_DestroyLock(globalrng->lock); - PORT_ZFree(globalrng, sizeof *globalrng); + + /* zero global RNG context except for XKEY to preserve entropy */ + rv = SHA256_HashBuf(inputhash, globalrng->XKEY, BSIZE); + PORT_Assert(SECSuccess == rv); + memset(globalrng, 0, sizeof(*globalrng)); + memcpy(globalrng->XKEY, inputhash, BSIZE); + globalrng = NULL; } /* - * Implementation of Algorithm 1 of FIPS 186-2 Change Notice 1, - * hereinafter called alg_cn_1(). It is assumed a lock for the global - * rng context has already been acquired. - * Calling this function with XSEEDj == NULL is equivalent to saying there - * is no optional user input, which is further equivalent to saying that - * the optional user input is 0. + * The core of Algorithm 1 of FIPS 186-2 Change Notice 1, + * separated from alg_fips186_2_cn_1 as a standalone function + * for FIPS algorithm testing. + * + * Parameters: + * XKEY [input/output]: the state of the RNG (seed-key) + * XSEEDj [input]: optional user input (seed) + * x_j [output]: output of the RNG + * + * Return value: + * This function usually returns SECSuccess. The only reason + * this function returns SECFailure is that XSEEDj equals + * XKEY, including the intermediate XKEY value between the two + * iterations. (This test is actually a FIPS 140-2 requirement + * and not required for FIPS algorithm testing, but it is too + * hard to separate from this function.) If this function fails, + * XKEY is not updated, but some data may have been written to + * x_j, which should be ignored. */ -static SECStatus -alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) +SECStatus +FIPS186Change_GenerateX(unsigned char *XKEY, const unsigned char *XSEEDj, + unsigned char *x_j) { /* SHA1 context for G(t, XVAL) function */ SHA1Context sha1cx; @@ -199,8 +227,6 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) PRUint8 *XKEY_new; /* input to hash function */ PRUint8 XVAL[BSIZE]; - /* store a copy of the output to compare with the previous output */ - PRUint8 x_j[2*GSIZE]; /* used by ADD_B_BIT macros */ int k, carry; /* store the output of G(t, XVAL) in the rightmost GSIZE bytes */ @@ -209,11 +235,6 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) unsigned int len; SECStatus rv = SECSuccess; - if (!rng->isValid) { - /* RNG has alread entered an invalid state. */ - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } #if GSIZE < BSIZE /* zero the leftmost bytes so we can pass it to ADD_B_BIT_PLUS_CARRY */ memset(w_i, 0, BSIZE - GSIZE); @@ -224,15 +245,15 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) * <Step 3.1> XSEEDj is optional user input */ for (i = 0; i < 2; i++) { - /* only update rng->XKEY when both iterations have been completed */ + /* only update XKEY when both iterations have been completed */ if (i == 0) { /* for iteration 0 */ - XKEY_old = rng->XKEY; + XKEY_old = XKEY; XKEY_new = XKEY_1; } else { /* for iteration 1 */ XKEY_old = XKEY_1; - XKEY_new = rng->XKEY; + XKEY_new = XKEY; } /* * <Step 3.2a> XVAL = (XKEY + XSEEDj) mod 2^b @@ -270,6 +291,39 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) */ memcpy(&x_j[i*GSIZE], &w_i[BSIZE - GSIZE], GSIZE); } + +done: + /* housekeeping */ + memset(&w_i[BSIZE - GSIZE], 0, GSIZE); + memset(XVAL, 0, BSIZE); + memset(XKEY_1, 0, BSIZE); + return rv; +} + +/* + * Implementation of Algorithm 1 of FIPS 186-2 Change Notice 1, + * hereinafter called alg_cn_1(). It is assumed a lock for the global + * rng context has already been acquired. + * Calling this function with XSEEDj == NULL is equivalent to saying there + * is no optional user input, which is further equivalent to saying that + * the optional user input is 0. + */ +static SECStatus +alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) +{ + /* store a copy of the output to compare with the previous output */ + PRUint8 x_j[2*GSIZE]; + SECStatus rv; + + if (!rng->isValid) { + /* RNG has alread entered an invalid state. */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + rv = FIPS186Change_GenerateX(rng->XKEY, XSEEDj, x_j); + if (rv != SECSuccess) { + goto done; + } /* [FIPS 140-2] verify output does not match previous output */ if (memcmp(x_j, rng->Xj, 2*GSIZE) == 0) { /* failed FIPS 140-2 continuous RNG test. RNG now invalid. */ @@ -285,32 +339,26 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) done: /* housekeeping */ - memset(&w_i[BSIZE - GSIZE], 0, GSIZE); memset(x_j, 0, 2*GSIZE); - memset(XVAL, 0, BSIZE); - memset(XKEY_1, 0, BSIZE); return rv; } /* Use NSPR to prevent RNG_RNGInit from being called from separate * threads, creating a race condition. */ -static PRCallOnceType coRNGInit = { 0, 0, 0 }; +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType coRNGInit; static PRStatus rng_init(void) { - unsigned char bytes[120]; + unsigned char bytes[SYSTEM_RNG_SEED_COUNT]; unsigned int numBytes; if (globalrng == NULL) { /* create a new global RNG context */ - globalrng = (RNGContext *)PORT_ZAlloc(sizeof(RNGContext)); - if (globalrng == NULL) { - PORT_SetError(PR_OUT_OF_MEMORY_ERROR); - return PR_FAILURE; - } + globalrng = &theGlobalRng; + PORT_Assert(NULL == globalrng->lock); /* create a lock for it */ globalrng->lock = PZ_NewLock(nssILockOther); if (globalrng->lock == NULL) { - PORT_Free(globalrng); globalrng = NULL; PORT_SetError(PR_OUT_OF_MEMORY_ERROR); return PR_FAILURE; @@ -318,6 +366,18 @@ static PRStatus rng_init(void) /* the RNG is in a valid state */ globalrng->isValid = PR_TRUE; /* Try to get some seed data for the RNG */ + numBytes = RNG_SystemRNG(bytes, sizeof bytes); + PORT_Assert(numBytes == 0 || numBytes == sizeof bytes); + if (numBytes != 0) { + RNG_RandomUpdate(bytes, numBytes); + memset(bytes, 0, numBytes); + } else if (PORT_GetError() != PR_NOT_IMPLEMENTED_ERROR) { + PZ_DestroyLock(globalrng->lock); + globalrng->lock = NULL; + globalrng->isValid = PR_FALSE; + globalrng = NULL; + return PR_FAILURE; + } numBytes = RNG_GetNoise(bytes, sizeof bytes); RNG_RandomUpdate(bytes, numBytes); } @@ -350,7 +410,6 @@ static SECStatus prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) { SECStatus rv = SECSuccess; - unsigned char inputhash[BSIZE]; /* check for a valid global RNG context */ PORT_Assert(rng != NULL); if (rng == NULL) { @@ -360,17 +419,6 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) /* RNG_SystemInfoForRNG() sometimes does this, not really an error */ if (bytes == 0) return SECSuccess; - /* If received 20 bytes of input, use it, else hash the input before - * locking. - */ - if (bytes == BSIZE) - memcpy(inputhash, data, BSIZE); - else - rv = B_HASH_BUF(inputhash, data, bytes); - if (rv != SECSuccess) { - /* B_HASH_BUF set error */ - return SECFailure; - } /* --- LOCKED --- */ PZ_Lock(rng->lock); /* @@ -380,20 +428,17 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) * Algorithm 1 of FIPS 186-2 Change Notice 1, step 1 specifies that * a secret value for the seed-key must be chosen before the * generator can begin. The size of XKEY is b bits, so fill it - * with the first b bits sent to RNG_RandomUpdate(). + * with the b-bit hash of the input to the first RNG_RandomUpdate() + * call. */ if (rng->seedCount == 0) { /* This is the first call to RandomUpdate(). Use a hash - * of the input to set the seed, XKEY. + * of the input to set the seed-key, XKEY. * - * <Step 1> copy seed bytes into context's XKEY - */ - memcpy(rng->XKEY, inputhash, BSIZE); - /* - * Now continue with algorithm. Since the input was used to - * initialize XKEY, the "optional user input" at this stage - * will be a pad of zeros, XSEEDj = 0. + * <Step 1> copy hash of seed bytes into context's XKEY */ + SHA256_HashBuf(rng->XKEY, data, bytes); + /* Now continue with algorithm. */ rv = alg_fips186_2_cn_1(rng, NULL); /* As per FIPS 140-2 continuous RNG test requirement, the first * iteration of output is discarded. So here there is really @@ -401,17 +446,28 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) * before any bytes can be extracted from the generator. */ rng->avail = 0; + } else if (bytes == BSIZE && memcmp(rng->XKEY, data, BSIZE) == 0) { + /* Should we add the error code SEC_ERROR_BAD_RNG_SEED? */ + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; } else { - /* Execute the algorithm from FIPS 186-2 Change Notice 1 */ - rv = alg_fips186_2_cn_1(rng, inputhash); + /* + * FIPS 186-2 does not specify how to reseed the RNG. We retrofit + * our RNG with a reseed function from NIST SP 800-90. + * + * Use a hash of the seed-key and the input to reseed the RNG. + */ + SHA256Context ctx; + SHA256_Begin(&ctx); + SHA256_Update(&ctx, rng->XKEY, BSIZE); + SHA256_Update(&ctx, data, bytes); + SHA256_End(&ctx, rng->XKEY, NULL, BSIZE); } /* If got this far, have added bytes of seed data. */ if (rv == SECSuccess) rng->seedCount += bytes; PZ_Unlock(rng->lock); /* --- UNLOCKED --- */ - /* housekeeping */ - memset(inputhash, 0, BSIZE); return rv; } @@ -429,7 +485,7 @@ RNG_RandomUpdate(const void *data, size_t bytes) ** Generate some random bytes, using the global random number generator ** object. */ -SECStatus +static SECStatus prng_GenerateGlobalRandomBytes(RNGContext *rng, void *dest, size_t len) { @@ -501,8 +557,8 @@ RNG_RNGShutdown(void) } /* clear */ freeRNGContext(); - /* zero the callonce struct to allow a new call to RNG_RNGInit() */ - memset(&coRNGInit, 0, sizeof coRNGInit); + /* reset the callonce struct to allow a new call to RNG_RNGInit() */ + coRNGInit = pristineCallOnce; } /* @@ -581,6 +637,6 @@ DSA_GenerateGlobalRandomBytes(void *dest, size_t len, const unsigned char *q) if (rv != SECSuccess) { return rv; } - dsa_reduce_mod_q(w, q, (unsigned char *)dest); + FIPS186Change_ReduceModQForDSA(w, q, (unsigned char *)dest); return rv; } diff --git a/security/nss/lib/freebl/secrng.h b/security/nss/lib/freebl/secrng.h index d3e97c927..036a3f71a 100644 --- a/security/nss/lib/freebl/secrng.h +++ b/security/nss/lib/freebl/secrng.h @@ -51,11 +51,14 @@ #include "blapi.h" +/* the number of bytes to read from the system random number generator */ +#define SYSTEM_RNG_SEED_COUNT 1024 + SEC_BEGIN_PROTOS /* -** The following 3 functions are provided by the security library -** but are differently implemented for the UNIX, Mac and Win +** The following functions are provided by the security library +** but are differently implemented for the UNIX, Win, and OS/2 ** versions */ @@ -80,6 +83,17 @@ extern void RNG_SystemInfoForRNG(void); */ extern void RNG_FileForRNG(const char *filename); +/* +** Get maxbytes bytes of random data from the system random number +** generator. +** Returns the number of bytes copied into buf -- maxbytes if success +** or zero if error. +** Errors: +** PR_NOT_IMPLEMENTED_ERROR There is no system RNG on the platform. +** SEC_ERROR_NEED_RANDOM The system RNG failed. +*/ +extern size_t RNG_SystemRNG(void *buf, size_t maxbytes); + SEC_END_PROTOS #endif /* _SECRNG_H_ */ diff --git a/security/nss/lib/freebl/sha256.h b/security/nss/lib/freebl/sha256.h new file mode 100644 index 000000000..f59813257 --- /dev/null +++ b/security/nss/lib/freebl/sha256.h @@ -0,0 +1,51 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _SHA_256_H_ +#define _SHA_256_H_ + +#include "prtypes.h" + +struct SHA256ContextStr { + union { + PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */ + PRUint8 b[256]; + } u; + PRUint32 h[8]; /* 8 state variables */ + PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */ +}; + +#endif /* _SHA_256_H_ */ diff --git a/security/nss/lib/freebl/sha512.c b/security/nss/lib/freebl/sha512.c index 672aa9a0f..a25b83d6d 100644 --- a/security/nss/lib/freebl/sha512.c +++ b/security/nss/lib/freebl/sha512.c @@ -45,6 +45,7 @@ #include "prtypes.h" /* for PRUintXX */ #include "secport.h" /* for PORT_XXX */ #include "blapi.h" +#include "sha256.h" /* for struct SHA256ContextStr */ /* ============= Common constants and defines ======================= */ @@ -92,15 +93,6 @@ static const PRUint32 H256[8] = { 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; -struct SHA256ContextStr { - union { - PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */ - PRUint8 b[256]; - } u; - PRUint32 h[8]; /* 8 state variables */ - PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */ -}; - #if defined(_MSC_VER) && defined(_X86_) #ifndef FORCEINLINE #if (MSC_VER >= 1200) diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c index f61da8b29..13617b1e7 100644 --- a/security/nss/lib/freebl/unix_rand.c +++ b/security/nss/lib/freebl/unix_rand.c @@ -43,8 +43,9 @@ #include <sys/time.h> #include <sys/wait.h> #include <sys/stat.h> -#include <assert.h> #include "secrng.h" +#include "secerr.h" +#include "prerror.h" size_t RNG_FileUpdate(const char *fileName, size_t limit); @@ -80,6 +81,108 @@ static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen) return dstlen; } +#ifdef SOLARIS + +#include <kstat.h> + +static const PRUint32 entropy_buf_len = 4096; /* buffer up to 4 KB */ + +/* Buffer entropy data, and feed it to the RNG, entropy_buf_len bytes at a time. + * Returns error if RNG_RandomUpdate fails. Also increments *total_fed + * by the number of bytes successfully buffered. + */ +static SECStatus BufferEntropy(char* inbuf, PRUint32 inlen, + char* entropy_buf, PRUint32* entropy_buffered, + PRUint32* total_fed) +{ + PRUint32 tocopy = 0; + PRUint32 avail = 0; + SECStatus rv = SECSuccess; + + while (inlen) { + avail = entropy_buf_len - *entropy_buffered; + if (!avail) { + /* Buffer is full, time to feed it to the RNG. */ + rv = RNG_RandomUpdate(entropy_buf, entropy_buf_len); + if (SECSuccess != rv) { + break; + } + *entropy_buffered = 0; + avail = entropy_buf_len; + } + tocopy = PR_MIN(avail, inlen); + memcpy(entropy_buf + *entropy_buffered, inbuf, tocopy); + *entropy_buffered += tocopy; + inlen -= tocopy; + inbuf += tocopy; + *total_fed += tocopy; + } + return rv; +} + +/* Feed kernel statistics structures and ks_data field to the RNG. + * Returns status as well as the number of bytes successfully fed to the RNG. + */ +static SECStatus RNG_kstat(PRUint32* fed) +{ + kstat_ctl_t* kc = NULL; + kstat_t* ksp = NULL; + PRUint32 entropy_buffered = 0; + char* entropy_buf = NULL; + SECStatus rv = SECSuccess; + + PORT_Assert(fed); + if (!fed) { + return SECFailure; + } + *fed = 0; + + kc = kstat_open(); + PORT_Assert(kc); + if (!kc) { + return SECFailure; + } + entropy_buf = (char*) PORT_Alloc(entropy_buf_len); + PORT_Assert(entropy_buf); + if (entropy_buf) { + for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { + if (-1 == kstat_read(kc, ksp, NULL)) { + /* missing data from a single kstat shouldn't be fatal */ + continue; + } + rv = BufferEntropy((char*)ksp, sizeof(kstat_t), + entropy_buf, &entropy_buffered, + fed); + if (SECSuccess != rv) { + break; + } + + if (ksp->ks_data && ksp->ks_data_size>0 && ksp->ks_ndata>0) { + rv = BufferEntropy((char*)ksp->ks_data, ksp->ks_data_size, + entropy_buf, &entropy_buffered, + fed); + if (SECSuccess != rv) { + break; + } + } + } + if (SECSuccess == rv && entropy_buffered) { + /* Buffer is not empty, time to feed it to the RNG */ + rv = RNG_RandomUpdate(entropy_buf, entropy_buffered); + } + PORT_Free(entropy_buf); + } else { + rv = SECFailure; + } + if (kstat_close(kc)) { + PORT_Assert(0); + rv = SECFailure; + } + return rv; +} + +#endif + #if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) \ || defined(NETBSD) || defined(NTO) || defined(DARWIN) || defined(OPENBSD) #include <sys/times.h> @@ -277,7 +380,7 @@ GiveSystemInfo(void) #endif /* IBM R2 */ #if defined(LINUX) -#include <linux/kernel.h> +#include <sys/sysinfo.h> static size_t GetHighResClock(void *buf, size_t maxbytes) @@ -288,14 +391,10 @@ GetHighResClock(void *buf, size_t maxbytes) static void GiveSystemInfo(void) { - /* XXX sysinfo() does not seem be implemented anywhwere */ -#if 0 struct sysinfo si; - char hn[2000]; if (sysinfo(&si) == 0) { RNG_RandomUpdate(&si, sizeof(si)); } -#endif } #endif /* LINUX */ @@ -774,6 +873,11 @@ safe_pclose(FILE *fp) #include <crt_externs.h> #endif +/* Fork netstat to collect its output by default. Do not unset this unless + * another source of entropy is available + */ +#define DO_NETSTAT 1 + void RNG_SystemInfoForRNG(void) { FILE *fp; @@ -842,13 +946,13 @@ for the small amount of entropy it provides. } /* Give in system information */ - if (gethostname(buf, sizeof(buf)) > 0) { + if (gethostname(buf, sizeof(buf)) == 0) { RNG_RandomUpdate(buf, strlen(buf)); } GiveSystemInfo(); /* grab some data from system's PRNG before any other files. */ - bytes = RNG_FileUpdate("/dev/urandom", 1024); + bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT); /* If the user points us to a random file, pass it through the rng */ randfile = getenv("NSRANDFILE"); @@ -872,6 +976,29 @@ for the small amount of entropy it provides. return; #endif +#ifdef SOLARIS + +/* + * On Solaris, NSS may be initialized automatically from libldap in + * applications that are unaware of the use of NSS. safe_popen forks, and + * sometimes creates issues with some applications' pthread_atfork handlers. + * We always have /dev/urandom on Solaris 9 and above as an entropy source, + * and for Solaris 8 we have the libkstat interface, so we don't need to + * fork netstat. + */ + +#undef DO_NETSTAT + if (!bytes) { + /* On Solaris 8, /dev/urandom isn't available, so we use libkstat. */ + PRUint32 kstat_bytes = 0; + if (SECSuccess != RNG_kstat(&kstat_bytes)) { + PORT_Assert(0); + } + bytes += kstat_bytes; + PORT_Assert(bytes); + } +#endif + #ifdef DO_PS fp = safe_popen(ps_cmd); if (fp != NULL) { @@ -880,12 +1007,15 @@ for the small amount of entropy it provides. safe_pclose(fp); } #endif + +#ifdef DO_NETSTAT fp = safe_popen(netstat_ni_cmd); if (fp != NULL) { while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0) RNG_RandomUpdate(buf, bytes); safe_pclose(fp); } +#endif } #else @@ -959,6 +1089,9 @@ size_t RNG_FileUpdate(const char *fileName, size_t limit) unsigned char buffer[BUFSIZ]; static size_t totalFileBytes = 0; + /* suppress valgrind warnings due to holes in struct stat */ + memset(&stat_buf, 0, sizeof(stat_buf)); + if (stat((char *)fileName, &stat_buf) < 0) return fileBytes; RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); @@ -994,3 +1127,31 @@ void RNG_FileForRNG(const char *fileName) { RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); } + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + FILE *file; + size_t bytes; + size_t fileBytes = 0; + unsigned char *buffer = dest; + + file = fopen("/dev/urandom", "r"); + if (file == NULL) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return fileBytes; + } + while (maxLen > fileBytes) { + bytes = maxLen - fileBytes; + bytes = fread(buffer, 1, bytes, file); + if (bytes == 0) + break; + fileBytes += bytes; + buffer += bytes; + } + fclose(file); + if (fileBytes != maxLen) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + fileBytes = 0; + } + return fileBytes; +} diff --git a/security/nss/lib/freebl/win_rand.c b/security/nss/lib/freebl/win_rand.c index 20218b967..286ad3522 100644 --- a/security/nss/lib/freebl/win_rand.c +++ b/security/nss/lib/freebl/win_rand.c @@ -35,6 +35,7 @@ * ***** END LICENSE BLOCK ***** */ #include "secrng.h" +#include "secerr.h" #ifdef XP_WIN #include <windows.h> @@ -56,6 +57,7 @@ #endif #include "prio.h" +#include "prerror.h" static PRInt32 filesToRead; static DWORD totalFileBytes; @@ -545,4 +547,96 @@ void RNG_FileForRNG(const char *filename) } #endif /* not WinCE */ + +/* + * CryptoAPI requires Windows NT 4.0 or Windows 95 OSR2 and later. + * Until we drop support for Windows 95, we need to emulate some + * definitions and declarations in <wincrypt.h> and look up the + * functions in advapi32.dll at run time. + */ + +typedef unsigned long HCRYPTPROV; + +#define CRYPT_VERIFYCONTEXT 0xF0000000 + +#define PROV_RSA_FULL 1 + +typedef BOOL +(WINAPI *CryptAcquireContextAFn)( + HCRYPTPROV *phProv, + LPCSTR pszContainer, + LPCSTR pszProvider, + DWORD dwProvType, + DWORD dwFlags); + +typedef BOOL +(WINAPI *CryptReleaseContextFn)( + HCRYPTPROV hProv, + DWORD dwFlags); + +typedef BOOL +(WINAPI *CryptGenRandomFn)( + HCRYPTPROV hProv, + DWORD dwLen, + BYTE *pbBuffer); + +/* + * Windows XP and Windows Server 2003 and later have RtlGenRandom, + * which must be looked up by the name SystemFunction036. + */ +typedef BOOLEAN +(APIENTRY *RtlGenRandomFn)( + PVOID RandomBuffer, + ULONG RandomBufferLength); + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + HMODULE hModule; + RtlGenRandomFn pRtlGenRandom; + CryptAcquireContextAFn pCryptAcquireContextA; + CryptReleaseContextFn pCryptReleaseContext; + CryptGenRandomFn pCryptGenRandom; + HCRYPTPROV hCryptProv; + size_t bytes = 0; + + hModule = LoadLibrary("advapi32.dll"); + if (hModule == NULL) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return 0; + } + pRtlGenRandom = (RtlGenRandomFn) + GetProcAddress(hModule, "SystemFunction036"); + if (pRtlGenRandom) { + if (pRtlGenRandom(dest, maxLen)) { + bytes = maxLen; + } else { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + } + goto done; + } + pCryptAcquireContextA = (CryptAcquireContextAFn) + GetProcAddress(hModule, "CryptAcquireContextA"); + pCryptReleaseContext = (CryptReleaseContextFn) + GetProcAddress(hModule, "CryptReleaseContext"); + pCryptGenRandom = (CryptGenRandomFn) + GetProcAddress(hModule, "CryptGenRandom"); + if (!pCryptAcquireContextA || !pCryptReleaseContext || !pCryptGenRandom) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + goto done; + } + if (pCryptAcquireContextA(&hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + if (pCryptGenRandom(hCryptProv, maxLen, dest)) { + bytes = maxLen; + } + pCryptReleaseContext(hCryptProv, 0); + } + if (bytes == 0) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + } +done: + FreeLibrary(hModule); + return bytes; +} + #endif /* is XP_WIN */ diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk index 5cdb444e5..9ba5ce176 100644 --- a/security/nss/lib/nss/config.mk +++ b/security/nss/lib/nss/config.mk @@ -122,6 +122,14 @@ MKSHLIB += -R '$$ORIGIN' endif endif +ifeq ($(OS_ARCH), HP-UX) +ifneq ($(OS_TEST), ia64) +# pa-risc +ifeq ($(USE_64), 1) +MKSHLIB += +b '$$ORIGIN' +endif +endif +endif ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET))) ifndef NS_USE_GCC diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index b02dd61ef..622614da5 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -872,3 +872,18 @@ SECMOD_OpenUserDB; ;+ local: ;+ *; ;+}; +;+NSS_3.11.1 { +;+ global: +NSS_RegisterShutdown; +NSS_UnregisterShutdown; +SEC_ASN1EncodeUnsignedInteger; +SEC_RegisterDefaultHttpClient; +;+ local: +;+ *; +;+}; +;+NSS_3.11.2 { +;+ global: +SECKEY_SignatureLen; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 18245f52d..07329658c 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -45,20 +45,30 @@ SEC_BEGIN_PROTOS +/* The private macro _NSS_ECC_STRING is for NSS internal use only. */ +#ifdef NSS_ENABLE_ECC +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#define _NSS_ECC_STRING " Extended ECC" +#else +#define _NSS_ECC_STRING " Basic ECC" +#endif +#else +#define _NSS_ECC_STRING "" +#endif + /* * NSS's major version, minor version, patch level, and whether * this is a beta release. * * The format of the version string should be - * "<major version>.<minor version>[.<patch level>] [<Beta>]" + * "<major version>.<minor version>[.<patch level>][ <ECC>][ <Beta>]" */ -#define NSS_VERSION "3.11" +#define NSS_VERSION "3.11.5" _NSS_ECC_STRING #define NSS_VMAJOR 3 #define NSS_VMINOR 11 -#define NSS_VPATCH 0 +#define NSS_VPATCH 5 #define NSS_BETA PR_FALSE - /* * Return a boolean that indicates whether the underlying library * will perform as the caller expects. @@ -184,6 +194,31 @@ extern SECStatus NSS_Initialize(const char *configdir, */ SECStatus NSS_NoDB_Init(const char *configdir); +/* + * Allow applications and libraries to register with NSS so that they are called + * when NSS shuts down. + * + * void *appData application specific data passed in by the application at + * NSS_RegisterShutdown() time. + * void *nssData is NULL in this release, but is reserved for future versions of + * NSS to pass some future status information * back to the shutdown function. + * + * If the shutdown function returns SECFailure, + * Shutdown will still complete, but NSS_Shutdown() will return SECFailure. + */ +typedef SECStatus (*NSS_ShutdownFunc)(void *appData, void *nssData); + +/* + * Register a shutdown function. + */ +SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Remove an existing shutdown function (you may do this if your library is + * complete and going away, but NSS is still running). + */ +SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + /* * Close the Cert, Key databases. */ diff --git a/security/nss/lib/nss/nss.rc b/security/nss/lib/nss/nss.rc index be82dab75..156309e6a 100644 --- a/security/nss/lib/nss/nss.rc +++ b/security/nss/lib/nss/nss.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c index adf3efb04..fc36e78e1 100644 --- a/security/nss/lib/nss/nssinit.c +++ b/security/nss/lib/nss/nssinit.c @@ -57,6 +57,7 @@ #include "pki3hack.h" #include "certi.h" #include "secmodi.h" +#include "ocspi.h" /* * On Windows nss3.dll needs to export the symbol 'mktemp' to be @@ -300,14 +301,15 @@ static const char *dllname = /* Should we have platform ifdefs here??? */ #define FILE_SEP '/' -static void nss_FindExternalRootPaths(const char *dbpath, const char* secmodprefix, +static void nss_FindExternalRootPaths(const char *dbpath, + const char* secmodprefix, char** retoldpath, char** retnewpath) { char *path, *oldpath = NULL, *lastsep; int len, path_len, secmod_len, dll_len; path_len = PORT_Strlen(dbpath); - secmod_len = PORT_Strlen(secmodprefix); + secmod_len = secmodprefix ? PORT_Strlen(secmodprefix) : 0; dll_len = PORT_Strlen(dllname); len = path_len + secmod_len + dll_len + 2; /* FILE_SEP + NULL */ @@ -320,7 +322,7 @@ static void nss_FindExternalRootPaths(const char *dbpath, const char* secmodpref path[path_len++] = FILE_SEP; } PORT_Strcpy(&path[path_len],dllname); - if (secmodprefix) { + if (secmod_len > 0) { lastsep = PORT_Strrchr(secmodprefix, FILE_SEP); if (lastsep) { int secmoddir_len = lastsep-secmodprefix+1; /* FILE_SEP */ @@ -395,6 +397,11 @@ nss_FindExternalRoot(const char *dbpath, const char* secmodprefix) static PRBool nss_IsInitted = PR_FALSE; extern SECStatus secoid_Init(void); +static SECStatus nss_InitShutdownList(void); + +#ifdef DEBUG +static CERTCertificate dummyCert; +#endif static SECStatus nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, @@ -416,9 +423,16 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, return SECSuccess; } + /* New option bits must not change the size of CERTCertificate. */ + PORT_Assert(sizeof(dummyCert.options) == sizeof(void *)); + if (SECSuccess != InitCRLCache()) { return SECFailure; } + + if (SECSuccess != InitOCSPGlobal()) { + return SECFailure; + } flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen, pk11_password_required, optimizeSpace); @@ -479,6 +493,9 @@ loser: if (STAN_LoadDefaultNSS3TrustDomain() != PR_SUCCESS) { return SECFailure; } + if (nss_InitShutdownList() != SECSuccess) { + return SECFailure; + } CERT_SetDefaultCertDB((CERTCertDBHandle *) STAN_GetDefaultTrustDomain()); #ifndef XP_MAC @@ -586,28 +603,207 @@ NSS_NoDB_Init(const char * configdir) PR_FALSE,PR_FALSE,PR_FALSE); } + +#define NSS_SHUTDOWN_STEP 10 + +struct NSSShutdownFuncPair { + NSS_ShutdownFunc func; + void *appData; +}; + +static struct NSSShutdownListStr { + PZLock *lock; + int maxFuncs; + int numFuncs; + struct NSSShutdownFuncPair *funcs; +} nssShutdownList = { 0 }; + +/* + * find and existing shutdown function + */ +static int +nss_GetShutdownEntry(NSS_ShutdownFunc sFunc, void *appData) +{ + int count, i; + count = nssShutdownList.numFuncs; + /* expect the list to be short, just do a linear search */ + for (i=0; i < count; i++) { + if ((nssShutdownList.funcs[i].func == sFunc) && + (nssShutdownList.funcs[i].appData == appData)){ + return i; + } + } + return -1; +} + +/* + * register a callback to be called when NSS shuts down + */ +SECStatus +NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData) +{ + int i; + + if (!nss_IsInitted) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + if (sFunc == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + PORT_Assert(nssShutdownList.lock); + PZ_Lock(nssShutdownList.lock); + + /* make sure we don't have a duplicate */ + i = nss_GetShutdownEntry(sFunc, appData); + if (i > 0) { + PZ_Unlock(nssShutdownList.lock); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + /* find an empty slot */ + i = nss_GetShutdownEntry(NULL, NULL); + if (i > 0) { + nssShutdownList.funcs[i].func = sFunc; + nssShutdownList.funcs[i].appData = appData; + PZ_Unlock(nssShutdownList.lock); + return SECFailure; + } + if (nssShutdownList.maxFuncs == nssShutdownList.numFuncs) { + struct NSSShutdownFuncPair *funcs = + (struct NSSShutdownFuncPair *)PORT_Realloc + (nssShutdownList.funcs, + (nssShutdownList.maxFuncs + NSS_SHUTDOWN_STEP) + *sizeof(struct NSSShutdownFuncPair)); + if (!funcs) { + return SECFailure; + } + nssShutdownList.funcs = funcs; + nssShutdownList.maxFuncs += NSS_SHUTDOWN_STEP; + } + nssShutdownList.funcs[nssShutdownList.numFuncs].func = sFunc; + nssShutdownList.funcs[nssShutdownList.numFuncs].appData = appData; + nssShutdownList.numFuncs++; + PZ_Unlock(nssShutdownList.lock); + return SECSuccess; +} + +/* + * unregister a callback so it won't get called on shutdown. + */ +SECStatus +NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData) +{ + int i; + if (!nss_IsInitted) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + PORT_Assert(nssShutdownList.lock); + PZ_Lock(nssShutdownList.lock); + i = nss_GetShutdownEntry(sFunc, appData); + if (i > 0) { + nssShutdownList.funcs[i].func = NULL; + nssShutdownList.funcs[i].appData = NULL; + } + PZ_Unlock(nssShutdownList.lock); + + if (i < 0) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + return SECSuccess; +} + +/* + * bring up and shutdown the shutdown list + */ +static SECStatus +nss_InitShutdownList(void) +{ + nssShutdownList.lock = PZ_NewLock(nssILockOther); + if (nssShutdownList.lock == NULL) { + return SECFailure; + } + nssShutdownList.funcs = PORT_ZNewArray(struct NSSShutdownFuncPair, + NSS_SHUTDOWN_STEP); + if (nssShutdownList.funcs == NULL) { + PZ_DestroyLock(nssShutdownList.lock); + nssShutdownList.lock = NULL; + return SECFailure; + } + nssShutdownList.maxFuncs = NSS_SHUTDOWN_STEP; + nssShutdownList.numFuncs = 0; + + return SECSuccess; +} + +static SECStatus +nss_ShutdownShutdownList(void) +{ + SECStatus rv = SECSuccess; + int i; + + /* call all the registerd functions first */ + for (i=0; i < nssShutdownList.numFuncs; i++) { + struct NSSShutdownFuncPair *funcPair = &nssShutdownList.funcs[i]; + if (funcPair->func) { + if ((*funcPair->func)(funcPair->appData,NULL) != SECSuccess) { + rv = SECFailure; + } + } + } + + nssShutdownList.numFuncs = 0; + nssShutdownList.maxFuncs = 0; + PORT_Free(nssShutdownList.funcs); + nssShutdownList.funcs = NULL; + if (nssShutdownList.lock) { + PZ_DestroyLock(nssShutdownList.lock); + } + nssShutdownList.lock = NULL; + return rv; +} + + extern const NSSError NSS_ERROR_BUSY; SECStatus NSS_Shutdown(void) { + SECStatus shutdownRV = SECSuccess; SECStatus rv; PRStatus status; + if (!nss_IsInitted) { + PORT_SetError(SEC_ERROR_NOT_INITIALIZED); + return SECFailure; + } + + rv = nss_ShutdownShutdownList(); + if (rv != SECSuccess) { + shutdownRV = SECFailure; + } ShutdownCRLCache(); SECOID_Shutdown(); status = STAN_Shutdown(); cert_DestroySubjectKeyIDHashTable(); rv = SECMOD_Shutdown(); + if (rv != SECSuccess) { + shutdownRV = SECFailure; + } pk11sdr_Shutdown(); if (status == PR_FAILURE) { if (NSS_GetError() == NSS_ERROR_BUSY) { PORT_SetError(SEC_ERROR_BUSY); } - rv = SECFailure; + shutdownRV = SECFailure; } nss_IsInitted = PR_FALSE; - return rv; + return shutdownRV; } PRBool diff --git a/security/nss/lib/pk11wrap/Makefile b/security/nss/lib/pk11wrap/Makefile index 95766f79e..0b3017de6 100644 --- a/security/nss/lib/pk11wrap/Makefile +++ b/security/nss/lib/pk11wrap/Makefile @@ -96,8 +96,8 @@ endif ifdef XP_OS2_VACPP $(OBJDIR)/pk11skey.obj: pk11skey.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) $(OBJDIR)/pk11slot.obj: pk11slot.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) endif diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c index a6189cf43..707989d9f 100644 --- a/security/nss/lib/pk11wrap/pk11akey.c +++ b/security/nss/lib/pk11wrap/pk11akey.c @@ -1313,68 +1313,6 @@ PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx) return NULL; } -static int -pk11_private_key_encrypt_buffer_length(SECKEYPrivateKey *key) - -{ - CK_ATTRIBUTE rsaTemplate = { CKA_MODULUS, NULL, 0 }; - CK_ATTRIBUTE dsaTemplate = { CKA_PRIME, NULL, 0 }; - /* XXX We should normally choose an attribute such that - * factor times its size is enough to hold the private key. - * For EC keys, we have no choice but to use CKA_EC_PARAMS, - * CKA_VALUE is not available for token keys. But for named - * curves, the number of bytes needed to represent the params - * is quite small so we bump up factor from 10 to 15. - */ - CK_ATTRIBUTE ecTemplate = { CKA_EC_PARAMS, NULL, 0 }; - CK_ATTRIBUTE_PTR pTemplate; - CK_RV crv; - int length; - int factor = 10; - - if(!key) { - return -1; - } - - switch (key->keyType) { - case rsaKey: - pTemplate = &rsaTemplate; - break; - case dsaKey: - case dhKey: - pTemplate = &dsaTemplate; - break; - case ecKey: - pTemplate = &ecTemplate; - factor = 15; - break; - case fortezzaKey: - default: - pTemplate = NULL; - } - - if(!pTemplate) { - return -1; - } - - crv = PK11_GetAttributes(NULL, key->pkcs11Slot, key->pkcs11ID, - pTemplate, 1); - if(crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return -1; - } - - length = pTemplate->ulValueLen; - length *= factor; - - - if(pTemplate->pValue != NULL) { - PORT_Free(pTemplate->pValue); - } - - return length; -} - SECKEYEncryptedPrivateKeyInfo * PK11_ExportEncryptedPrivKeyInfo( PK11SlotInfo *slot, /* optional, encrypt key in this slot */ @@ -1390,14 +1328,12 @@ PK11_ExportEncryptedPrivKeyInfo( SECItem *pbe_param = NULL; PK11SymKey *key = NULL; SECStatus rv = SECSuccess; - int encryptBufLen; CK_RV crv; - CK_ULONG encBufLenPtr; + CK_ULONG encBufLen; CK_MECHANISM_TYPE mechanism; CK_MECHANISM pbeMech; CK_MECHANISM cryptoMech; SECItem crypto_param; - SECItem encryptedKey = {siBuffer, NULL, 0}; if (!pwitem || !pk) { PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -1461,20 +1397,6 @@ PK11_ExportEncryptedPrivKeyInfo( crypto_param.data = (unsigned char *)cryptoMech.pParameter; crypto_param.len = cryptoMech.ulParameterLen; - - encryptBufLen = pk11_private_key_encrypt_buffer_length(pk); - if(encryptBufLen == -1) { - rv = SECFailure; - goto loser; - } - encryptedKey.len = (unsigned int)encryptBufLen; - encBufLenPtr = (CK_ULONG) encryptBufLen; - encryptedKey.data = (unsigned char *)PORT_ZAlloc(encryptedKey.len); - if(!encryptedKey.data) { - rv = SECFailure; - goto loser; - } - /* If the key isn't in the private key slot, move it */ if (key->slot != pk->pkcs11Slot) { PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot, @@ -1488,30 +1410,40 @@ PK11_ExportEncryptedPrivKeyInfo( PK11_FreeSymKey(key); key = newkey; } - + /* we are extracting an encrypted privateKey structure. * which needs to be freed along with the buffer into which it is * returned. eventually, we should retrieve an encrypted key using * pkcs8/pkcs5. */ + encBufLen = 0; PK11_EnterSlotMonitor(pk->pkcs11Slot); crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, - &cryptoMech, key->objectID, pk->pkcs11ID, encryptedKey.data, - &encBufLenPtr); + &cryptoMech, key->objectID, pk->pkcs11ID, NULL, + &encBufLen); PK11_ExitSlotMonitor(pk->pkcs11Slot); - encryptedKey.len = (unsigned int) encBufLenPtr; - if(crv != CKR_OK) { + if (crv != CKR_OK) { rv = SECFailure; goto loser; } - - if(!encryptedKey.len) { + epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen); + if (!epki->encryptedData.data) { + rv = SECFailure; + goto loser; + } + PK11_EnterSlotMonitor(pk->pkcs11Slot); + crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, + &cryptoMech, key->objectID, pk->pkcs11ID, + epki->encryptedData.data, &encBufLen); + PK11_ExitSlotMonitor(pk->pkcs11Slot); + epki->encryptedData.len = (unsigned int) encBufLen; + if(crv != CKR_OK) { rv = SECFailure; goto loser; } - - rv = SECITEM_CopyItem(arena, &epki->encryptedData, &encryptedKey); - if(rv != SECSuccess) { + + if(!epki->encryptedData.len) { + rv = SECFailure; goto loser; } @@ -1739,18 +1671,17 @@ SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force) { CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey); + SECStatus rv = SECWouldBlock; - /* found a cert matching the private key?. */ - if (!force && cert != NULL) { - /* yes, don't delete the key */ - CERT_DestroyCertificate(cert); - SECKEY_DestroyPrivateKey(privKey); - return SECWouldBlock; + if (!cert || force) { + /* now, then it's safe for the key to go away */ + rv = PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID); + } + if (cert) { + CERT_DestroyCertificate(cert); } - /* now, then it's safe for the key to go away */ - PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID); SECKEY_DestroyPrivateKey(privKey); - return SECSuccess; + return rv; } /* @@ -1787,6 +1718,9 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) SECStatus rv = SECSuccess; SECKEYPrivateKey *privKey; pk11KeyCallback *keycb = (pk11KeyCallback *) arg; + if (!arg) { + return SECFailure; + } privKey = PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,keycb->wincx); @@ -1794,7 +1728,7 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) return SECFailure; } - if (keycb && (keycb->callback)) { + if (keycb->callback) { rv = (*keycb->callback)(privKey,keycb->callbackArg); } @@ -2026,6 +1960,7 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname) keys = SECKEY_NewPublicKeyList(); if (keys == NULL) { PORT_Free(key_ids); + return NULL; } for (i=0; i < objCount ; i++) { @@ -2071,6 +2006,7 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) keys = SECKEY_NewPrivateKeyList(); if (keys == NULL) { PORT_Free(key_ids); + return NULL; } for (i=0; i < objCount ; i++) { diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 08c0af2db..eb1a358b1 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -273,7 +273,7 @@ static CERTCertificate } /* Create a PKI object from the cryptoki instance */ - pkio = nssPKIObject_Create(NULL, co, td, NULL); + pkio = nssPKIObject_Create(NULL, co, td, NULL, nssPKIMonitor); if (!pkio) { nssCryptokiObject_Destroy(co); return NULL; @@ -481,7 +481,7 @@ PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *), struct nss3_cert_cbstr pk11cb; /* authenticate to the tokens first */ - (void) pk11_TraverseAllSlots( NULL, NULL, wincx); + (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, wincx); fda.callback = callback; fda.arg = arg; @@ -702,7 +702,30 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) &status); nssPKIObjectCollection_AddInstances(collection, instances, 0); nss_ZFreeIf(instances); - nssList_Destroy(nameList); + + /* if it wasn't found, repeat the process for email address */ + if (nssPKIObjectCollection_Count(collection) == 0 && + PORT_Strchr(nickname, '@') != NULL) + { + char* lowercaseName = CERT_FixupEmailAddr(nickname); + if (lowercaseName) { + (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD, + lowercaseName, + nameList); + transfer_token_certs_to_collection(nameList, token, collection); + instances = nssToken_FindCertificatesByEmail(token, + NULL, + lowercaseName, + tokenOnly, + 0, + &status); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); + PORT_Free(lowercaseName); + } + } + + nssList_Destroy(nameList); foundCerts = nssPKIObjectCollection_GetCertificates(collection, NULL, 0, NULL); nssPKIObjectCollection_Destroy(collection); @@ -796,6 +819,8 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, NSSToken *token = PK11Slot_GetNSSToken(slot); SECItem *keyID = pk11_mkcertKeyID(cert); char *emailAddr = NULL; + nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; if (keyID == NULL) { goto loser; @@ -815,9 +840,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, if (c->object.cryptoContext) { /* Delete the temp instance */ NSSCryptoContext *cc = c->object.cryptoContext; - nssCertificateStore_Lock(cc->certStore); + nssCertificateStore_Lock(cc->certStore, &lockTrace); nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); - nssCertificateStore_Unlock(cc->certStore); + nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); c->object.cryptoContext = NULL; cert->istemp = PR_FALSE; cert->isperm = PR_TRUE; @@ -925,6 +951,7 @@ pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert, SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx) { + int err; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_ATTRIBUTE theTemplate[] = { { CKA_VALUE, NULL, 0 }, @@ -935,6 +962,7 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, CK_OBJECT_HANDLE certh; CK_OBJECT_HANDLE keyh; CK_ATTRIBUTE *attrs = theTemplate; + PRBool needLogin; SECStatus rv; PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, @@ -953,10 +981,18 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, if (certh == CK_INVALID_HANDLE) { return NULL; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * PK11_MatchItem. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY); - if ((keyh == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot, wincx)) { + if ((keyh == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* try it again authenticated */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) { @@ -983,6 +1019,7 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, CK_OBJECT_HANDLE key; PK11SlotInfo *slot = NULL; SECStatus rv; + int err; keyID = pk11_mkcertKeyID(cert); /* get them all! */ @@ -995,10 +1032,18 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, /* Look for the slot that holds the Key */ for (le = list->head ; le; le = le->next) { + /* + * prevent a login race condition. If le->slot is logged in between + * our call to pk11_LoginStillRequired and the + * pk11_FindPrivateKeyFromCertID, the find will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + PRBool needLogin = pk11_LoginStillRequired(le->slot,wincx); key = pk11_FindPrivateKeyFromCertID(le->slot,keyID); - if ((key == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(le->slot,wincx)) { + if ((key == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* authenticate and try again */ rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); if (rv != SECSuccess) continue; @@ -1084,7 +1129,6 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr, /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1159,7 +1203,7 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot, if (!instance) { goto loser; } - object = nssPKIObject_Create(NULL, instance, td, NULL); + object = nssPKIObject_Create(NULL, instance, td, NULL, nssPKIMonitor); if (!object) { goto loser; } @@ -1248,7 +1292,6 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1319,7 +1362,6 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr, /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1553,16 +1595,26 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx) CK_OBJECT_HANDLE keyHandle; PK11SlotInfo *slot = NULL; SECKEYPrivateKey *privKey = NULL; + PRBool needLogin; SECStatus rv; + int err; certHandle = PK11_FindObjectForCert(cert, wincx, &slot); if (certHandle == CK_INVALID_HANDLE) { return NULL; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * PK11_MatchItem. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY); - if ((keyHandle == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot,wincx)) { + if ((keyHandle == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err ) ) { /* authenticate and try again */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv == SECSuccess) { @@ -1947,6 +1999,8 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, SECItem *keyID; CK_OBJECT_HANDLE key; SECStatus rv; + PRBool needLogin; + int err; if((slot == NULL) || (cert == NULL)) { return CK_INVALID_HANDLE; @@ -1957,10 +2011,18 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, return CK_INVALID_HANDLE; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * pk11_FindPrivateKeyFromCerID. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); key = pk11_FindPrivateKeyFromCertID(slot, keyID); - if ((key == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot,wincx)) { + if ((key == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* authenticate and try again */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) goto loser; @@ -2284,7 +2346,7 @@ PK11_ListCerts(PK11CertListType type, void *pwarg) listCerts.certList = certList; /* authenticate to the slots */ - (void) pk11_TraverseAllSlots( NULL, NULL, pwarg); + (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, pwarg); NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback, &listCerts); return certList; @@ -2348,6 +2410,9 @@ listCertsCallback(CERTCertificate* cert, void*arg) NSSCertificate *c = STAN_GetNSSCertificate(cert); instances = nssPKIObject_GetInstances(&c->object); + if (!instances) { + return SECFailure; + } instance = NULL; for (ci = instances; *ci; ci++) { if ((*ci)->token->pk11slot == cdata->slot) { diff --git a/security/nss/lib/pk11wrap/pk11cxt.c b/security/nss/lib/pk11wrap/pk11cxt.c index 4428fda9b..d4ce2b68d 100644 --- a/security/nss/lib/pk11wrap/pk11cxt.c +++ b/security/nss/lib/pk11wrap/pk11cxt.c @@ -249,7 +249,7 @@ static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type, SECStatus rv; PORT_Assert(slot != NULL); - if (!slot) { + if (!slot || (!symKey && operation != CKA_DIGEST)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } @@ -325,15 +325,15 @@ __PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, SECItem *param, void *wincx) { - PK11SymKey *symKey; - PK11Context *context; + PK11SymKey *symKey = NULL; + PK11Context *context = NULL; /* first get a slot */ if (slot == NULL) { slot = PK11_GetBestSlot(type,wincx); if (slot == NULL) { PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; + goto loser; } } else { PK11_ReferenceSlot(slot); @@ -341,12 +341,17 @@ __PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, /* now import the key */ symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx); - if (symKey == NULL) return NULL; + if (symKey == NULL) goto loser; context = PK11_CreateContextBySymKey(type, operation, symKey, param); - PK11_FreeSymKey(symKey); - PK11_FreeSlot(slot); +loser: + if (symKey) { + PK11_FreeSymKey(symKey); + } + if (slot) { + PK11_FreeSlot(slot); + } return context; } diff --git a/security/nss/lib/pk11wrap/pk11err.c b/security/nss/lib/pk11wrap/pk11err.c index a63475636..588d6512c 100644 --- a/security/nss/lib/pk11wrap/pk11err.c +++ b/security/nss/lib/pk11wrap/pk11err.c @@ -113,7 +113,7 @@ PK11_MapError(CK_RV rv) { MAPERROR(CKR_UNWRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY) MAPERROR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY) MAPERROR(CKR_USER_ALREADY_LOGGED_IN, 0) - MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_LIBRARY_FAILURE) /* XXXX */ + MAPERROR(CKR_USER_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) diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c index a0db40729..7664d8071 100644 --- a/security/nss/lib/pk11wrap/pk11kea.c +++ b/security/nss/lib/pk11wrap/pk11kea.c @@ -152,82 +152,6 @@ rsa_failed: return newSymKey; } - /* KEA */ - if (PK11_DoesMechanism(symKey->slot, CKM_KEA_KEY_DERIVE) && - PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) { - CERTCertificate *certSource = NULL; - CERTCertificate *certTarget = NULL; - SECKEYPublicKey *pubKeySource = NULL; - SECKEYPublicKey *pubKeyTarget = NULL; - SECKEYPrivateKey *privKeySource = NULL; - SECKEYPrivateKey *privKeyTarget = NULL; - PK11SymKey *tekSource = NULL; - PK11SymKey *tekTarget = NULL; - SECItem Ra,wrap; - - /* can only exchange skipjack keys */ - if ((type != CKM_SKIPJACK_CBC64) || (isPerm)) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - /* find a pair of certs we can use */ - rv = PK11_GetKEAMatchedCerts(symKey->slot,slot,&certSource,&certTarget); - if (rv != SECSuccess) goto kea_failed; - - /* get all the key pairs */ - pubKeyTarget = CERT_ExtractPublicKey(certSource); - pubKeySource = CERT_ExtractPublicKey(certTarget); - privKeySource = - PK11_FindKeyByDERCert(symKey->slot,certSource,symKey->cx); - privKeyTarget = - PK11_FindKeyByDERCert(slot,certTarget,symKey->cx); - - if ((pubKeySource == NULL) || (pubKeyTarget == NULL) || - (privKeySource == NULL) || (privKeyTarget == NULL)) goto kea_failed; - - /* generate the wrapping TEK's */ - Ra.data = (unsigned char*)PORT_Alloc(128 /* FORTEZZA RA MAGIC */); - Ra.len = 128; - if (Ra.data == NULL) goto kea_failed; - - tekSource = PK11_PubDerive(privKeySource,pubKeyTarget,PR_TRUE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - tekTarget = PK11_PubDerive(privKeyTarget,pubKeySource,PR_FALSE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - PORT_Free(Ra.data); - - if ((tekSource == NULL) || (tekTarget == NULL)) { goto kea_failed; } - - /* wrap the key out of Source into target */ - wrap.data = (unsigned char*)PORT_Alloc(12); /* MAGIC SKIPJACK LEN */ - wrap.len = 12; - - /* paranoia to prevent infinite recursion on bugs */ - PORT_Assert(tekSource->slot == symKey->slot); - if (tekSource->slot != symKey->slot) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP,NULL,tekSource,symKey,&wrap); - if (rv == SECSuccess) { - newSymKey = PK11_UnwrapSymKeyWithFlags(tekTarget, - CKM_SKIPJACK_WRAP, NULL, - &wrap, type, operation, flags, symKey->size); - } - PORT_Free(wrap.data); -kea_failed: - if (certSource == NULL) CERT_DestroyCertificate(certSource); - if (certTarget == NULL) CERT_DestroyCertificate(certTarget); - if (pubKeySource == NULL) SECKEY_DestroyPublicKey(pubKeySource); - if (pubKeyTarget == NULL) SECKEY_DestroyPublicKey(pubKeyTarget); - if (privKeySource == NULL) SECKEY_DestroyPrivateKey(privKeySource); - if (privKeyTarget == NULL) SECKEY_DestroyPrivateKey(privKeyTarget); - if (tekSource == NULL) PK11_FreeSymKey(tekSource); - if (tekTarget == NULL) PK11_FreeSymKey(tekTarget); - return newSymKey; - } PORT_SetError( SEC_ERROR_NO_MODULE ); return NULL; } diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c index 1f8f2a372..fe106de50 100644 --- a/security/nss/lib/pk11wrap/pk11mech.c +++ b/security/nss/lib/pk11wrap/pk11mech.c @@ -823,7 +823,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) rc5_cbc_params = (CK_RC5_CBC_PARAMS *) PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0)); if (rc5_cbc_params == NULL) break; - if (iv && iv->data) { + if (iv && iv->data && iv->len) { rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) + sizeof(CK_RC5_CBC_PARAMS); PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len); @@ -832,7 +832,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) } else { rc5_cbc_params->ulWordsize = 4; rc5_cbc_params->pIv = NULL; - rc5_cbc_params->ulIvLen = iv->len; + rc5_cbc_params->ulIvLen = 0; } rc5_cbc_params->ulRounds = 16; param->data = (unsigned char *) rc5_cbc_params; diff --git a/security/nss/lib/pk11wrap/pk11nobj.c b/security/nss/lib/pk11wrap/pk11nobj.c index db9aa6ba9..3a88ef4ae 100644 --- a/security/nss/lib/pk11wrap/pk11nobj.c +++ b/security/nss/lib/pk11wrap/pk11nobj.c @@ -270,7 +270,7 @@ PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) { creater.findTemplate = theTemplate; creater.templateCount = (attrs - theTemplate); - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); + return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx); } struct crlOptionsStr { @@ -421,7 +421,7 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, creater.findTemplate = theTemplate; creater.templateCount = (attrs - theTemplate); - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); + return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx); } /* @@ -429,12 +429,15 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, */ SECItem * PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, - SECItem *name, int type, char **url) + SECItem *name, int type, char **pUrl) { - NSSCRL **crls, **crlp, *crl; + 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; @@ -443,7 +446,7 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, NSSToken *token = PK11Slot_GetNSSToken(*slot); collection = nssCRLCollection_Create(td, NULL); if (!collection) { - return NULL; + goto loser; } instances = nssToken_FindCRLsBySubject(token, NULL, &subject, tokenOnly, 0, NULL); @@ -461,9 +464,8 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, if (NSS_GetError() == NSS_ERROR_NOT_FOUND) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } - return NULL; + goto loser; } - crl = NULL; for (crlp = crls; *crlp; crlp++) { if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) || ((*crlp)->isKRL && type != SEC_CRL_TYPE)) @@ -477,28 +479,34 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, /* CRL collection was found, but no interesting CRL's were on it. * Not an error */ PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); - return NULL; + goto loser; } if (crl->url) { - *url = PORT_Strdup(crl->url); - if (!*url) { - nssCRL_Destroy(crl); - return NULL; + url = PORT_Strdup(crl->url); + if (!url) { + goto loser; } - } else { - *url = NULL; } rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size); if (!rvItem) { - PORT_Free(*url); - nssCRL_Destroy(crl); - return NULL; + 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 diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c index 65b47ef96..91a28321e 100644 --- a/security/nss/lib/pk11wrap/pk11obj.c +++ b/security/nss/lib/pk11wrap/pk11obj.c @@ -571,11 +571,14 @@ PK11_SignatureLen(SECKEYPrivateKey *key) if (theTemplate.pValue != NULL) { params.len = theTemplate.ulValueLen; params.data = (unsigned char *) theTemplate.pValue; - length = SECKEY_ECParamsToKeySize(¶ms); + length = SECKEY_ECParamsToBasePointOrderLen(¶ms); PORT_Free(theTemplate.pValue); + if (length == 0) { + return pk11_backupGetSignLength(key); + } + length = ((length + 7)/8) * 2; + return length; } - length = ((length + 7)/8) * 2; - return length; } break; default: @@ -948,7 +951,9 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, sizeof(cktrue)); attrs++; PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse, sizeof(cktrue)); attrs++; - PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; + if (label && label->data) { + PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; + } PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); attrs++; for (i=0; i < usageCount; i++) { PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue)); attrs++; @@ -1568,8 +1573,8 @@ PK11_TraverseSlot(PK11SlotInfo *slot, void *arg) * Traverse all the objects in all slots. */ SECStatus -pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *arg,void *wincx) { +pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), + void *arg, PRBool forceLogin, void *wincx) { PK11SlotList *list; PK11SlotListElement *le; SECStatus rv; @@ -1580,9 +1585,11 @@ pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), /* look at each slot and authenticate as necessary */ for (le = list->head ; le; le = le->next) { - rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); - if (rv != SECSuccess) { - continue; + if (forceLogin) { + rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); + if (rv != SECSuccess) { + continue; + } } if (callback) { (*callback)(le->slot,arg); diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c index 1234af856..07ac7dff4 100644 --- a/security/nss/lib/pk11wrap/pk11pbe.c +++ b/security/nss/lib/pk11wrap/pk11pbe.c @@ -704,10 +704,10 @@ pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params) { if (pbe_params) { if (pbe_params->pPassword) - PORT_ZFree(pbe_params->pPassword, PR_FALSE); + PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen); if (pbe_params->pSalt) - PORT_ZFree(pbe_params->pSalt, PR_FALSE); - PORT_ZFree(pbe_params, PR_TRUE); + PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen); + PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS)); } } @@ -716,30 +716,49 @@ PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations) { CK_PBE_PARAMS *pbe_params = NULL; SECItem *paramRV = NULL; - pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)); + + paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); + if (!paramRV ) { + goto loser; + } + /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */ + PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS)); + + pbe_params = (CK_PBE_PARAMS *)paramRV->data; pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len); - if (pbe_params->pPassword != NULL) { - PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); - pbe_params->ulPasswordLen = pwd->len; - } else goto loser; + if (!pbe_params->pPassword) { + goto loser; + } + PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); + pbe_params->ulPasswordLen = pwd->len; + pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len); - if (pbe_params->pSalt != NULL) { - PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); - pbe_params->ulSaltLen = salt->len; - } else goto loser; + if (!pbe_params->pSalt) { + goto loser; + } + PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); + pbe_params->ulSaltLen = salt->len; + pbe_params->ulIteration = (CK_ULONG)iterations; - paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); - paramRV->data = (unsigned char *)pbe_params; return paramRV; + loser: - pk11_destroy_ck_pbe_params(pbe_params); + if (pbe_params) + pk11_destroy_ck_pbe_params(pbe_params); + if (paramRV) + PORT_ZFree(paramRV, sizeof(SECItem)); return NULL; } void -PK11_DestroyPBEParams(SECItem *params) +PK11_DestroyPBEParams(SECItem *pItem) { - pk11_destroy_ck_pbe_params((CK_PBE_PARAMS *)params->data); + if (pItem) { + CK_PBE_PARAMS * params = (CK_PBE_PARAMS *)(pItem->data); + if (params) + pk11_destroy_ck_pbe_params(params); + PORT_ZFree(pItem, sizeof(SECItem)); + } } SECAlgorithmID * @@ -766,6 +785,9 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, } pbe_params = (CK_PBE_PARAMS *)mech->data; + if (!pbe_params) { + return NULL; + } pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwitem->len); if(pbe_params->pPassword != NULL) { PORT_Memcpy(pbe_params->pPassword, pwitem->data, pwitem->len); @@ -775,7 +797,8 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, return NULL; } - symKey = PK11_KeyGen(slot, type, mech, 0, wincx); + symKey = PK11_TokenKeyGenWithFlags(slot, type, mech, 0, NULL, + CKF_SIGN|CKF_ENCRYPT|CKF_DECRYPT|CKF_UNWRAP|CKF_WRAP, 0, wincx); PORT_ZFree(pbe_params->pPassword, pwitem->len); pbe_params->pPassword = NULL; diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c index 35a4cbc07..9c8afdf4e 100644 --- a/security/nss/lib/pk11wrap/pk11pk12.c +++ b/security/nss/lib/pk11wrap/pk11pk12.c @@ -250,7 +250,13 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, 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, @@ -263,10 +269,8 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, publicValue, isPerm, isPrivate, keyUsage, privk, wincx); finish: - if( pki != NULL ) { - /* this zeroes the key and frees the arena */ - SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); - } + /* this zeroes the key and frees the arena */ + SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); return rv; } diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c index 62afc7756..711818639 100644 --- a/security/nss/lib/pk11wrap/pk11pqg.c +++ b/security/nss/lib/pk11wrap/pk11pqg.c @@ -119,6 +119,10 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, } 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) ); @@ -145,6 +149,10 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, 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) ); diff --git a/security/nss/lib/pk11wrap/pk11priv.h b/security/nss/lib/pk11wrap/pk11priv.h index 6d0b012b0..feef1959a 100644 --- a/security/nss/lib/pk11wrap/pk11priv.h +++ b/security/nss/lib/pk11wrap/pk11priv.h @@ -207,7 +207,7 @@ SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, /* private */ SECStatus pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *cbArg, void *pwArg); + void *cbArg, PRBool forceLogin, void *pwArg); /* fetch multiple CRLs for a specific issuer */ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h index 8a933cc93..4c674d48e 100644 --- a/security/nss/lib/pk11wrap/pk11pub.h +++ b/security/nss/lib/pk11wrap/pk11pub.h @@ -582,6 +582,14 @@ CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, /********************************************************************** * 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, SECItem *hash); diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c index ce5cbd811..f7cb05411 100644 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ b/security/nss/lib/pk11wrap/pk11skey.c @@ -929,6 +929,13 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, count = attrs - genTemplate; PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); + /* Initialize the Key Gen Mechanism */ + mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize); + if (mechanism.mechanism == CKM_FAKE_RANDOM) { + PORT_SetError( SEC_ERROR_NO_MODULE ); + return NULL; + } + /* find a slot to generate the key into */ /* Only do slot management if this is not a token key */ if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) { @@ -951,13 +958,6 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, symKey->size = keySize; symKey->origin = PK11_OriginGenerated; - /* Initialize the Key Gen Mechanism */ - mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize); - if (mechanism.mechanism == CKM_FAKE_RANDOM) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - /* Set the parameters for the key gen if provided */ mechanism.pParameter = NULL; mechanism.ulParameterLen = 0; @@ -1646,17 +1646,35 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, return NULL; } -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) +static PK11SymKey * +pk11_PubDeriveECKeyWithKDF( + 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) { - PK11SlotInfo *slot = privKey->pkcs11Slot; - PK11SymKey *symKey; - CK_MECHANISM mechanism; - CK_RV crv; + PK11SlotInfo *slot = privKey->pkcs11Slot; + PK11SymKey *symKey; + CK_MECHANISM mechanism; + CK_RV crv; + CK_BBOOL cktrue = CK_TRUE; + CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; + CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; + CK_ULONG key_size = 0; + CK_ATTRIBUTE keyTemplate[4]; + int templateCount; + CK_ATTRIBUTE *attrs = keyTemplate; + CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; + + if (pubKey->keyType != ecKey) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return NULL; + } + if ((kdf < CKD_NULL) || (kdf > CKD_SHA1_KDF)) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } /* get our key Structure */ symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); @@ -1666,6 +1684,62 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, symKey->origin = PK11_OriginDerive; + PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++; + PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; + PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; + PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); attrs++; + templateCount = attrs - keyTemplate; + PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); + + keyType = PK11_GetKeyType(target,keySize); + key_size = keySize; + symKey->size = keySize; + if (key_size == 0) + templateCount--; + + mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); + if (!mechParams) { + PK11_FreeSymKey(symKey); + return NULL; + } + mechParams->kdf = kdf; + if (sharedData == NULL) { + mechParams->ulSharedDataLen = 0; + mechParams->pSharedData = NULL; + } else { + mechParams->ulSharedDataLen = sharedData->len; + mechParams->pSharedData = sharedData->data; + } + mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; + mechParams->pPublicData = pubKey->u.ec.publicValue.data; + + mechanism.mechanism = derive; + mechanism.pParameter = mechParams; + mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); + + pk11_EnterKeyMonitor(symKey); + crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, + privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID); + pk11_ExitKeyMonitor(symKey); + + PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); + + if (crv != CKR_OK) { + PK11_FreeSymKey(symKey); + symKey = NULL; + PORT_SetError( PK11_MapError(crv) ); + } + return symKey; +} + +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) +{ + switch (privKey->keyType) { case rsaKey: case nullKey: @@ -1673,75 +1747,16 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, case keaKey: case fortezzaKey: case dhKey: - PK11_FreeSymKey(symKey); return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB, derive, target, operation, keySize, wincx); case ecKey: - { - CK_BBOOL cktrue = CK_TRUE; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_ULONG key_size = 0; - CK_ATTRIBUTE keyTemplate[4]; - int templateCount; - CK_ATTRIBUTE *attrs = keyTemplate; - CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; - - if (pubKey->keyType != ecKey) { - PORT_SetError(SEC_ERROR_BAD_KEY); - break; - } - - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); - attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); - attrs++; - PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); - attrs++; - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); - - keyType = PK11_GetKeyType(target,keySize); - key_size = keySize; - symKey->size = keySize; - if (key_size == 0) templateCount--; - - mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); - if ((kdf < CKD_NULL) || (kdf > CKD_SHA1_KDF)) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - break; - } - mechParams->kdf = kdf; - if (sharedData == NULL) { - mechParams->ulSharedDataLen = 0; - mechParams->pSharedData = NULL; - } else { - mechParams->ulSharedDataLen = sharedData->len; - mechParams->pSharedData = sharedData->data; - } - mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; - mechParams->pPublicData = pubKey->u.ec.publicValue.data; - - mechanism.mechanism = derive; - mechanism.pParameter = mechParams; - mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); - - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, - &mechanism, privKey->pkcs11ID, keyTemplate, - templateCount, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); - - PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); - - if (crv == CKR_OK) return symKey; - PORT_SetError( PK11_MapError(crv) ); - } - } + return pk11_PubDeriveECKeyWithKDF( privKey, pubKey, isSender, + randomA, randomB, derive, target, operation, keySize, + kdf, sharedData, wincx); + default: break; + } - PK11_FreeSymKey(symKey); - return NULL; + return NULL; } /* diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index a92fbf7df..94d4ffaba 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -354,7 +354,7 @@ PK11_NewSlotInfo(SECMODModule *mod) PZ_NewLock(nssILockSession) : mod->refLock; if (slot->sessionLock == NULL) { PORT_Free(slot); - return slot; + return NULL; } slot->freeListLock = PZ_NewLock(nssILockFreelist); if (slot->freeListLock == NULL) { @@ -362,7 +362,7 @@ PK11_NewSlotInfo(SECMODModule *mod) PZ_DestroyLock(slot->sessionLock); } PORT_Free(slot); - return slot; + return NULL; } slot->freeSymKeysWithSessionHead = NULL; slot->freeSymKeysHead = NULL; diff --git a/security/nss/lib/pk11wrap/secmod.h b/security/nss/lib/pk11wrap/secmod.h index 83545f5e3..68ac59f27 100644 --- a/security/nss/lib/pk11wrap/secmod.h +++ b/security/nss/lib/pk11wrap/secmod.h @@ -55,6 +55,9 @@ #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_RANDOM_FLAG 0x08000000ul #define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul @@ -62,7 +65,7 @@ #define PUBLIC_DISABLE_FLAG 0x40000000ul /* warning: reserved means reserved */ -#define PUBLIC_MECH_RESERVED_FLAGS 0x87FFE000ul +#define PUBLIC_MECH_RESERVED_FLAGS 0x87FF0000ul /* These cipher flags are visible to all other libraries, */ /* But they must be converted before used in functions */ diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c index 2d4d29cae..bcbea25a5 100644 --- a/security/nss/lib/pkcs12/p12d.c +++ b/security/nss/lib/pkcs12/p12d.c @@ -543,15 +543,15 @@ sec_pkcs12_decoder_safe_contents_init_decode(SEC_PKCS12DecoderContext *p12dcx, if(!p12dcx->safeContentsCnt) { p12dcx->safeContentsList = (sec_PKCS12SafeContentsContext**)PORT_ArenaZAlloc(p12dcx->arena, - sizeof(sec_PKCS12SafeContentsContext *)); + 2 * sizeof(sec_PKCS12SafeContentsContext *)); } else { p12dcx->safeContentsList = (sec_PKCS12SafeContentsContext **) PORT_ArenaGrow(p12dcx->arena, p12dcx->safeContentsList, - (p12dcx->safeContentsCnt * - sizeof(sec_PKCS12SafeContentsContext *)), - (1 + p12dcx->safeContentsCnt * - sizeof(sec_PKCS12SafeContentsContext *))); + (1 + p12dcx->safeContentsCnt) * + sizeof(sec_PKCS12SafeContentsContext *), + (2 + p12dcx->safeContentsCnt) * + sizeof(sec_PKCS12SafeContentsContext *)); } if(!p12dcx->safeContentsList) { p12dcx->errorValue = SEC_ERROR_NO_MEMORY; @@ -2561,7 +2561,7 @@ CERTCertList * SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx) { CERTCertList *certList = NULL; - sec_PKCS12SafeBag **safeBags = p12dcx->safeBags; + sec_PKCS12SafeBag **safeBags; int i; if (!p12dcx || !p12dcx->safeBags || !p12dcx->safeBags[0]) { @@ -2721,7 +2721,7 @@ SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx, { SECStatus rv; int i, noInstallCnt, probCnt, bagCnt, errorVal = 0; - if(!p12dcx || p12dcx->error) { + if(!p12dcx || p12dcx->error || !p12dcx->safeBags) { return SECFailure; } diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c index 37a0c5b40..df3919975 100644 --- a/security/nss/lib/pkcs7/p7decode.c +++ b/security/nss/lib/pkcs7/p7decode.c @@ -1665,7 +1665,9 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, algiddata = SECOID_FindOID (&(signerinfo->digestEncAlg.algorithm)); if (algiddata == NULL || ((algiddata->offset != SEC_OID_PKCS1_RSA_ENCRYPTION) && +#ifdef NSS_ECC_MORE_THAN_SUITE_B (algiddata->offset != SEC_OID_ANSIX962_EC_PUBLIC_KEY) && +#endif (algiddata->offset != SEC_OID_ANSIX9_DSA_SIGNATURE))) { PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); goto done; diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index 3abca38c1..8c7609a8b 100644 --- a/security/nss/lib/pki/certificate.c +++ b/security/nss/lib/pki/certificate.c @@ -79,6 +79,7 @@ nssCertificate_Create ( /* mark? */ NSSArena *arena = object->arena; PR_ASSERT(object->instances != NULL && object->numInstances > 0); + PR_ASSERT(object->lockType == nssPKIMonitor); rvCert = nss_ZNEW(arena, NSSCertificate); if (!rvCert) { return (NSSCertificate *)NULL; @@ -120,6 +121,10 @@ nssCertificate_Destroy ( NSSCertificate *c ) { + nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + PRBool locked = PR_FALSE; + if (c) { PRUint32 i; nssDecodedCert *dc = c->decoding; @@ -130,7 +135,8 @@ nssCertificate_Destroy ( /* --- LOCK storage --- */ if (cc) { - nssCertificateStore_Lock(cc->certStore); + nssCertificateStore_Lock(cc->certStore, &lockTrace); + locked = PR_TRUE; } else { nssTrustDomain_LockCertCache(td); } @@ -138,7 +144,10 @@ nssCertificate_Destroy ( /* --- remove cert and UNLOCK storage --- */ if (cc) { nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); - nssCertificateStore_Unlock(cc->certStore); + nssCertificateStore_Unlock(cc->certStore, &lockTrace, + &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); + } else { nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); nssTrustDomain_UnlockCertCache(td); @@ -147,18 +156,24 @@ nssCertificate_Destroy ( for (i=0; i<c->object.numInstances; i++) { nssCryptokiObject_Destroy(c->object.instances[i]); } - PZ_DestroyLock(c->object.lock); + nssPKIObject_DestroyLock(&c->object); nssArena_Destroy(c->object.arena); nssDecodedCert_Destroy(dc); } else { /* --- UNLOCK storage --- */ if (cc) { - nssCertificateStore_Unlock(cc->certStore); + nssCertificateStore_Unlock(cc->certStore, + &lockTrace, + &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); } else { nssTrustDomain_UnlockCertCache(td); } } } + if (locked) { + nssCertificateStore_Check(&lockTrace, &unlockTrace); + } return PR_SUCCESS; } @@ -304,25 +319,17 @@ nssCertificate_GetDecoding ( NSSCertificate *c ) { - /* There is a race in assigning c->decoding. - ** This is a workaround. Bugzilla bug 225525. - */ + nssDecodedCert* deco = NULL; + nssPKIObject_Lock(&c->object); if (!c->decoding) { - nssDecodedCert * deco = - nssDecodedCert_Create(NULL, &c->encoding, c->type); - /* Once this race is fixed, an assertion should be put - ** here to detect any regressions. + deco = nssDecodedCert_Create(NULL, &c->encoding, c->type); PORT_Assert(!c->decoding); - */ - if (!c->decoding) { - /* we won the race. Use our copy. */ - c->decoding = deco; - } else { - /* we lost the race. discard deco. */ - nssDecodedCert_Destroy(deco); - } + c->decoding = deco; + } else { + deco = c->decoding; } - return c->decoding; + nssPKIObject_Unlock(&c->object); + return deco; } static NSSCertificate ** @@ -896,7 +903,7 @@ nssSMIMEProfile_Create ( if (!arena) { return NULL; } - object = nssPKIObject_Create(arena, NULL, td, cc); + object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock); if (!object) { goto loser; } @@ -916,7 +923,8 @@ nssSMIMEProfile_Create ( } return rvProfile; loser: - nssPKIObject_Destroy(object); + if (object) nssPKIObject_Destroy(object); + else if (arena) nssArena_Destroy(arena); return (nssSMIMEProfile *)NULL; } @@ -991,7 +999,7 @@ nssTrust_Create ( sha1_hash.data = sha1_hashin; sha1_hash.size = sizeof (sha1_hashin); /* trust has to peek into the base object members */ - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { instance = object->instances[i]; myTrustOrder = nssToken_GetTrustOrder(instance->token); @@ -1003,11 +1011,11 @@ nssTrust_Create ( &emailProtection, &stepUp); if (status != PR_SUCCESS) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } if (PORT_Memcmp(sha1_hashin,sha1_hashcmp,SHA1_LENGTH) != 0) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } if (rvt->serverAuth == nssTrustLevel_Unknown || @@ -1033,7 +1041,7 @@ nssTrust_Create ( rvt->stepUpApproved = stepUp; lastTrustOrder = myTrustOrder; } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return rvt; } diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c index 6b8a724c3..5e1be597e 100644 --- a/security/nss/lib/pki/cryptocontext.c +++ b/security/nss/lib/pki/cryptocontext.c @@ -65,6 +65,7 @@ struct NSSCryptoContextStr #endif extern const NSSError NSS_ERROR_NOT_FOUND; +extern const NSSError NSS_ERROR_INVALID_ARGUMENT; NSS_IMPLEMENT NSSCryptoContext * nssCryptoContext_Create ( @@ -84,6 +85,12 @@ nssCryptoContext_Create ( } rvCC->td = td; rvCC->arena = arena; + rvCC->certStore = nssCertificateStore_Create(rvCC->arena); + if (!rvCC->certStore) { + nssArena_Destroy(arena); + return NULL; + } + return rvCC; } @@ -93,11 +100,14 @@ NSSCryptoContext_Destroy ( ) { PRStatus status = PR_SUCCESS; + PORT_Assert(cc->certStore); if (cc->certStore) { status = nssCertificateStore_Destroy(cc->certStore); if (status == PR_FAILURE) { return status; } + } else { + status = PR_FAILURE; } nssArena_Destroy(cc->arena); return status; @@ -133,24 +143,33 @@ NSSCryptoContext_GetTrustDomain ( return NULL; } -NSS_IMPLEMENT PRStatus -NSSCryptoContext_ImportCertificate ( + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindOrImportCertificate ( NSSCryptoContext *cc, NSSCertificate *c ) { - PRStatus nssrv; + NSSCertificate *rvCert = NULL; + + PORT_Assert(cc->certStore); if (!cc->certStore) { - cc->certStore = nssCertificateStore_Create(cc->arena); - if (!cc->certStore) { - return PR_FAILURE; - } + nss_SetError(NSS_ERROR_INVALID_ARGUMENT); + return rvCert; } - nssrv = nssCertificateStore_Add(cc->certStore, c); - if (nssrv == PR_SUCCESS) { + rvCert = nssCertificateStore_FindOrAdd(cc->certStore, c); + if (rvCert == c && c->object.cryptoContext != cc) { + PORT_Assert(!c->object.cryptoContext); c->object.cryptoContext = cc; + } + if (rvCert) { + /* an NSSCertificate cannot be part of two crypto contexts + ** simultaneously. If this assertion fails, then there is + ** a serious Stan design flaw. + */ + PORT_Assert(cc == c->object.cryptoContext); } - return nssrv; + return rvCert; } NSS_IMPLEMENT NSSCertificate * @@ -190,11 +209,9 @@ nssCryptoContext_ImportTrust ( ) { PRStatus nssrv; + PORT_Assert(cc->certStore); if (!cc->certStore) { - cc->certStore = nssCertificateStore_Create(cc->arena); - if (!cc->certStore) { - return PR_FAILURE; - } + return PR_FAILURE; } nssrv = nssCertificateStore_AddTrust(cc->certStore, trust); #if 0 @@ -212,11 +229,9 @@ nssCryptoContext_ImportSMIMEProfile ( ) { PRStatus nssrv; + PORT_Assert(cc->certStore); if (!cc->certStore) { - cc->certStore = nssCertificateStore_Create(cc->arena); - if (!cc->certStore) { - return PR_FAILURE; - } + return PR_FAILURE; } nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile); #if 0 @@ -238,6 +253,7 @@ NSSCryptoContext_FindBestCertificateByNickname ( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -264,6 +280,7 @@ NSSCryptoContext_FindCertificatesByNickname ( ) { NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -282,6 +299,7 @@ NSSCryptoContext_FindCertificateByIssuerAndSerialNumber ( NSSDER *serialNumber ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -302,6 +320,7 @@ NSSCryptoContext_FindBestCertificateBySubject ( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -328,6 +347,7 @@ nssCryptoContext_FindCertificatesBySubject ( ) { NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -385,6 +405,7 @@ NSSCryptoContext_FindCertificateByEncodedCertificate ( NSSBER *encodedCertificate ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -404,6 +425,8 @@ NSSCryptoContext_FindBestCertificateByEmail ( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; + + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -430,6 +453,7 @@ NSSCryptoContext_FindCertificatesByEmail ( ) { NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -546,6 +570,7 @@ nssCryptoContext_FindTrustForCertificate ( NSSCertificate *cert ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -558,6 +583,7 @@ nssCryptoContext_FindSMIMEProfileForCertificate ( NSSCertificate *cert ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } diff --git a/security/nss/lib/pki/nsspki.h b/security/nss/lib/pki/nsspki.h index f50433620..689e4c240 100644 --- a/security/nss/lib/pki/nsspki.h +++ b/security/nss/lib/pki/nsspki.h @@ -2235,15 +2235,24 @@ NSSCryptoContext_GetTrustDomain /* Importing things */ /* - * NSSCryptoContext_ImportCertificate + * NSSCryptoContext_FindOrImportCertificate * - * If there's not a "distinguished certificate" for this context, this - * sets the specified one to be it. + * If the certificate store already contains this DER cert, return the + * address of the matching NSSCertificate that is already in the store, + * and bump its reference count. + * + * If this DER cert is NOT already in the store, then add the new + * NSSCertificate to the store and bump its reference count, + * then return its address. + * + * if this DER cert is not in the store and cannot be added to it, + * return NULL; + * + * Record the associated crypto context in the certificate. */ -NSS_EXTERN PRStatus -NSSCryptoContext_ImportCertificate -( +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindOrImportCertificate ( NSSCryptoContext *cc, NSSCertificate *c ); diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index bbbeb5d4b..559d7c5bd 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -146,9 +146,12 @@ STAN_LoadDefaultNSS3TrustDomain ( * we hold the tokensLock. We can use the NSSRWLock Rank feature to * guarrentee this. tokensLock have a higher rank than module lock. */ + td->tokenList = nssList_Create(td->arena, PR_TRUE); + if (!td->tokenList) { + goto loser; + } SECMOD_GetReadLock(moduleLock); NSSRWLock_LockWrite(td->tokensLock); - td->tokenList = nssList_Create(td->arena, PR_TRUE); for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) { for (i=0; i < mlp->module->slotCount; i++) { STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]); @@ -157,9 +160,19 @@ STAN_LoadDefaultNSS3TrustDomain ( td->tokens = nssList_CreateIterator(td->tokenList); NSSRWLock_UnlockWrite(td->tokensLock); SECMOD_ReleaseReadLock(moduleLock); - g_default_trust_domain = td; + if (!td->tokens) { + goto loser; + } g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL); + if (!g_default_crypto_context) { + goto loser; + } + g_default_trust_domain = td; return PR_SUCCESS; + + loser: + NSSTrustDomain_Destroy(td); + return PR_FAILURE; } /* @@ -693,17 +706,30 @@ STAN_GetCERTCertificateNameForInstance ( char * STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c) { + char * result; nssCryptokiInstance *instance = get_cert_instance(c); - return STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance); + /* It's OK to call this function, even if instance is NULL */ + result = STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance); + if (instance) + nssCryptokiObject_Destroy(instance); + return result; } static void fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced) { + CERTCertTrust* trust = NULL; NSSTrust *nssTrust; NSSCryptoContext *context = c->object.cryptoContext; - nssCryptokiInstance *instance = get_cert_instance(c); + nssCryptokiInstance *instance; NSSUTF8 *stanNick = NULL; + + /* We are holding the base class object's lock on entry of this function + * This lock protects writes to fields of the CERTCertificate . + * It is also needed by some functions to compute values such as trust. + */ + instance = get_cert_instance(c); + if (instance) { stanNick = instance->label; } else if (context) { @@ -725,15 +751,16 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced if (stanNick) { nicklen = nssUTF8_Size(stanNick, &nssrv); len = tokenlen + nicklen; - cc->nickname = PORT_ArenaAlloc(cc->arena, len); - nick = cc->nickname; + nick = PORT_ArenaAlloc(cc->arena, len); if (tokenName) { memcpy(nick, tokenName, tokenlen-1); - nick += tokenlen-1; - *nick++ = ':'; + nick[tokenlen-1] = ':'; + memcpy(nick+tokenlen, stanNick, nicklen-1); + } else { + memcpy(nick, stanNick, nicklen-1); } - memcpy(nick, stanNick, nicklen-1); - cc->nickname[len-1] = '\0'; + nick[len-1] = '\0'; + cc->nickname = nick; } else { cc->nickname = NULL; } @@ -742,7 +769,13 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced /* trust */ nssTrust = nssCryptoContext_FindTrustForCertificate(context, c); if (nssTrust) { - cc->trust = cert_trust_from_stan_trust(nssTrust, cc->arena); + trust = cert_trust_from_stan_trust(nssTrust, cc->arena); + if (trust) { + /* we should destroy cc->trust before replacing it, but it's + allocated in cc->arena, so memory growth will occur on each + refresh */ + cc->trust = trust; + } nssTrust_Destroy(nssTrust); } } else if (instance) { @@ -757,7 +790,13 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced /* pkcs11ID */ cc->pkcs11ID = instance->handle; /* trust */ - cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); + trust = nssTrust_GetCERTCertTrustForCert(c, cc); + if (trust) { + /* we should destroy cc->trust before replacing it, but it's + allocated in cc->arena, so memory growth will occur on each + refresh */ + cc->trust = trust; + } nssCryptokiObject_Destroy(instance); } /* database handle is now the trust domain */ @@ -773,52 +812,54 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced static CERTCertificate * stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) { - nssDecodedCert *dc = c->decoding; - CERTCertificate *cc; + nssDecodedCert *dc = NULL; + CERTCertificate *cc = NULL; - /* There is a race in assigning c->decoding. - ** This is a workaround. Bugzilla bug 225525. - */ + nssPKIObject_Lock(&c->object); + + dc = c->decoding; if (!dc) { dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding); - if (!dc) - return NULL; + if (!dc) { + goto loser; + } cc = (CERTCertificate *)dc->data; PORT_Assert(cc); /* software error */ if (!cc) { nssDecodedPKIXCertificate_Destroy(dc); nss_SetError(NSS_ERROR_INTERNAL_ERROR); - return NULL; + goto loser; } - /* Once this race is fixed, an assertion should be put - ** here to detect any regressions. PORT_Assert(!c->decoding); - */ if (!c->decoding) { c->decoding = dc; } else { - /* Reduce the leaks here, until the race is fixed. */ + /* this should never happen. Fail. */ nssDecodedPKIXCertificate_Destroy(dc); - dc = c->decoding; + nss_SetError(NSS_ERROR_INTERNAL_ERROR); + goto loser; } } cc = (CERTCertificate *)dc->data; PORT_Assert(cc); - /* When c->decoding is non-NULL on input, but dc->data is - * NULL, we don't destroy dc because some other errant - * code allocated it . - */ - if (cc) { - if (!cc->nssCertificate || forceUpdate) { - fill_CERTCertificateFields(c, cc, forceUpdate); - } else if (!cc->trust && !c->object.cryptoContext) { - /* if it's a perm cert, it might have been stored before the - * trust, so look for the trust again. But a temp cert can be - * ignored. - */ - cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); - } + if (!cc) { + nss_SetError(NSS_ERROR_INTERNAL_ERROR); + goto loser; + } + if (!cc->nssCertificate || forceUpdate) { + fill_CERTCertificateFields(c, cc, forceUpdate); + } else if (!cc->trust && !c->object.cryptoContext) { + /* if it's a perm cert, it might have been stored before the + * trust, so look for the trust again. But a temp cert can be + * ignored. + */ + CERTCertTrust* trust = NULL; + trust = nssTrust_GetCERTCertTrustForCert(c, cc); + cc->trust = trust; } + + loser: + nssPKIObject_Unlock(&c->object); return cc; } @@ -903,7 +944,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc) } NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); c->type = NSSCertificateType_PKIX; - pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL); + pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKIMonitor); if (!pkiob) { nssArena_Destroy(arena); return NULL; @@ -1023,7 +1064,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) arena = nssArena_Create(); if (!arena) return PR_FAILURE; nssTrust = nss_ZNEW(arena, NSSTrust); - pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL); + pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKILock); if (!pkiob) { nssArena_Destroy(arena); return PR_FAILURE; @@ -1165,6 +1206,9 @@ nssTrustDomain_TraverseCertificatesBySubject ( NSSCertificate *c; PRIntn i; tmpArena = NSSArena_Create(); + if (!tmpArena) { + return PR_FAILURE; + } subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL, 0, tmpArena); if (subjectCerts) { @@ -1192,6 +1236,9 @@ nssTrustDomain_TraverseCertificatesByNickname ( NSSCertificate *c; PRIntn i; tmpArena = NSSArena_Create(); + if (!tmpArena) { + return PR_FAILURE; + } nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL, 0, tmpArena); if (nickCerts) { diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c index deef58b52..f8b5a47ed 100644 --- a/security/nss/lib/pki/pkibase.c +++ b/security/nss/lib/pki/pkibase.c @@ -52,12 +52,79 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; extern const NSSError NSS_ERROR_NOT_FOUND; +NSS_IMPLEMENT void +nssPKIObject_Lock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_EnterMonitor(object->sync.mlock); + break; + case nssPKILock: + PZ_Lock(object->sync.lock); + break; + default: + PORT_Assert(0); + } +} + +NSS_IMPLEMENT void +nssPKIObject_Unlock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_ExitMonitor(object->sync.mlock); + break; + case nssPKILock: + PZ_Unlock(object->sync.lock); + break; + default: + PORT_Assert(0); + } +} + +NSS_IMPLEMENT PRStatus +nssPKIObject_NewLock(nssPKIObject * object, nssPKILockType lockType) +{ + object->lockType = lockType; + switch (lockType) { + case nssPKIMonitor: + object->sync.mlock = PZ_NewMonitor(nssILockSSL); + return (object->sync.mlock ? PR_SUCCESS : PR_FAILURE); + case nssPKILock: + object->sync.lock = PZ_NewLock(nssILockSSL); + return (object->sync.lock ? PR_SUCCESS : PR_FAILURE); + default: + PORT_Assert(0); + return PR_FAILURE; + } +} + +NSS_IMPLEMENT void +nssPKIObject_DestroyLock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_DestroyMonitor(object->sync.mlock); + object->sync.mlock = NULL; + break; + case nssPKILock: + PZ_DestroyLock(object->sync.lock); + object->sync.lock = NULL; + break; + default: + PORT_Assert(0); + } +} + + + NSS_IMPLEMENT nssPKIObject * nssPKIObject_Create ( NSSArena *arenaOpt, nssCryptokiObject *instanceOpt, NSSTrustDomain *td, - NSSCryptoContext *cc + NSSCryptoContext *cc, + nssPKILockType lockType ) { NSSArena *arena; @@ -79,8 +146,7 @@ nssPKIObject_Create ( object->arena = arena; object->trustDomain = td; /* XXX */ object->cryptoContext = cc; - object->lock = PZ_NewLock(nssILockOther); - if (!object->lock) { + if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) { goto loser; } if (instanceOpt) { @@ -113,7 +179,7 @@ nssPKIObject_Destroy ( for (i=0; i<object->numInstances; i++) { nssCryptokiObject_Destroy(object->instances[i]); } - PZ_DestroyLock(object->lock); + nssPKIObject_DestroyLock(object); nssArena_Destroy(object->arena); return PR_TRUE; } @@ -135,7 +201,7 @@ nssPKIObject_AddInstance ( nssCryptokiObject *instance ) { - PZ_Lock(object->lock); + nssPKIObject_Lock(object); if (object->numInstances == 0) { object->instances = nss_ZNEWARRAY(object->arena, nssCryptokiObject *, @@ -144,7 +210,7 @@ nssPKIObject_AddInstance ( PRUint32 i; for (i=0; i<object->numInstances; i++) { if (nssCryptokiObject_Equal(object->instances[i], instance)) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); if (instance->label) { if (!object->instances[i]->label || !nssUTF8_Equal(instance->label, @@ -171,11 +237,11 @@ nssPKIObject_AddInstance ( object->numInstances + 1); } if (!object->instances) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_FAILURE; } object->instances[object->numInstances++] = instance; - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_SUCCESS; } @@ -187,14 +253,14 @@ nssPKIObject_HasInstance ( { PRUint32 i; PRBool hasIt = PR_FALSE;; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { if (nssCryptokiObject_Equal(object->instances[i], instance)) { hasIt = PR_TRUE; break; } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return hasIt; } @@ -206,9 +272,9 @@ nssPKIObject_RemoveInstanceForToken ( { PRUint32 i; nssCryptokiObject *instanceToRemove = NULL; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); if (object->numInstances == 0) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_SUCCESS; } for (i=0; i<object->numInstances; i++) { @@ -230,7 +296,7 @@ nssPKIObject_RemoveInstanceForToken ( nss_ZFreeIf(object->instances); } nssCryptokiObject_Destroy(instanceToRemove); - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_SUCCESS; } @@ -253,7 +319,7 @@ nssPKIObject_DeleteStoredObject ( nssTrustDomain_GetDefaultCallback(td, NULL); #endif numNotDestroyed = 0; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { nssCryptokiObject *instance = object->instances[i]; #ifndef NSS_3_4_CODE @@ -288,7 +354,7 @@ nssPKIObject_DeleteStoredObject ( } else { object->numInstances = numNotDestroyed; } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return status; } @@ -299,7 +365,7 @@ nssPKIObject_GetTokens ( ) { NSSToken **tokens = NULL; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); if (object->numInstances > 0) { tokens = nss_ZNEWARRAY(NULL, NSSToken *, object->numInstances + 1); if (tokens) { @@ -309,7 +375,7 @@ nssPKIObject_GetTokens ( } } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); if (statusOpt) *statusOpt = PR_SUCCESS; /* until more logic here */ return tokens; } @@ -322,7 +388,7 @@ nssPKIObject_GetNicknameForToken ( { PRUint32 i; NSSUTF8 *nickname = NULL; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { if ((!tokenOpt && object->instances[i]->label) || (object->instances[i]->token == tokenOpt)) @@ -332,7 +398,7 @@ nssPKIObject_GetNicknameForToken ( break; } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return nickname; } @@ -347,7 +413,7 @@ nssPKIObject_GetInstances ( if (object->numInstances == 0) { return (nssCryptokiObject **)NULL; } - PZ_Lock(object->lock); + nssPKIObject_Lock(object); instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *, object->numInstances + 1); if (instances) { @@ -355,7 +421,7 @@ nssPKIObject_GetInstances ( instances[i] = nssCryptokiObject_Clone(object->instances[i]); } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return instances; } #endif @@ -595,12 +661,14 @@ struct nssPKIObjectCollectionStr PRStatus (* getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid, NSSArena *arena); nssPKIObject * (* createObject)(nssPKIObject *o); + nssPKILockType lockType; /* type of lock to use for new proto-objects */ }; static nssPKIObjectCollection * nssPKIObjectCollection_Create ( NSSTrustDomain *td, - NSSCryptoContext *ccOpt + NSSCryptoContext *ccOpt, + nssPKILockType lockType ) { NSSArena *arena; @@ -617,6 +685,7 @@ nssPKIObjectCollection_Create ( rvCollection->arena = arena; rvCollection->td = td; /* XXX */ rvCollection->cc = ccOpt; + rvCollection->lockType = lockType; return rvCollection; loser: nssArena_Destroy(arena); @@ -763,7 +832,7 @@ add_object_instance ( */ node = find_object_in_collection(collection, uid); if (node) { - /* This is a object with multiple instances */ + /* This is an object with multiple instances */ status = nssPKIObject_AddInstance(node->object, instance); } else { /* This is a completely new object. Create a node for it. */ @@ -772,7 +841,8 @@ add_object_instance ( goto loser; } node->object = nssPKIObject_Create(NULL, instance, - collection->td, collection->cc); + collection->td, collection->cc, + collection->lockType); if (!node->object) { goto loser; } @@ -1059,7 +1129,7 @@ nssCertificateCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKIMonitor); collection->objectType = pkiObjectType_Certificate; collection->destroyObject = cert_destroyObject; collection->getUIDFromObject = cert_getUIDFromObject; @@ -1162,7 +1232,7 @@ nssCRLCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); collection->objectType = pkiObjectType_CRL; collection->destroyObject = crl_destroyObject; collection->getUIDFromObject = crl_getUIDFromObject; @@ -1264,7 +1334,7 @@ nssPrivateKeyCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); collection->objectType = pkiObjectType_PrivateKey; collection->destroyObject = privkey_destroyObject; collection->getUIDFromObject = privkey_getUIDFromObject; @@ -1365,7 +1435,7 @@ nssPublicKeyCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); collection->objectType = pkiObjectType_PublicKey; collection->destroyObject = pubkey_destroyObject; collection->getUIDFromObject = pubkey_getUIDFromObject; diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h index 5fad8a13f..4e4268b77 100644 --- a/security/nss/lib/pki/pkim.h +++ b/security/nss/lib/pki/pkim.h @@ -72,6 +72,12 @@ PR_BEGIN_EXTERN_C * nssPKIObject_DeleteStoredObject */ +NSS_EXTERN void nssPKIObject_Lock (nssPKIObject * object); +NSS_EXTERN void nssPKIObject_Unlock (nssPKIObject * object); +NSS_EXTERN PRStatus nssPKIObject_NewLock (nssPKIObject * object, + nssPKILockType lockType); +NSS_EXTERN void nssPKIObject_DestroyLock(nssPKIObject * object); + /* nssPKIObject_Create * * A generic PKI object. It must live in a trust domain. It may be @@ -83,7 +89,8 @@ nssPKIObject_Create NSSArena *arenaOpt, nssCryptokiObject *instanceOpt, NSSTrustDomain *td, - NSSCryptoContext *ccOpt + NSSCryptoContext *ccOpt, + nssPKILockType lockType ); /* nssPKIObject_AddRef diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c index ed35c9749..e44051b9e 100644 --- a/security/nss/lib/pki/pkistore.c +++ b/security/nss/lib/pki/pkistore.c @@ -89,6 +89,14 @@ struct certificate_hash_entry_str nssSMIMEProfile *profile; }; +/* forward static declarations */ +static NSSCertificate * +nssCertStore_FindCertByIssuerAndSerialNumberLocked ( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +); + NSS_IMPLEMENT nssCertificateStore * nssCertificateStore_Create ( NSSArena *arenaOpt @@ -225,29 +233,46 @@ remove_certificate_entry ( NSSCertificate *cert ); -NSS_IMPLEMENT PRStatus -nssCertificateStore_Add ( +/* Caller must hold store->lock */ +static PRStatus +nssCertificateStore_AddLocked ( nssCertificateStore *store, NSSCertificate *cert ) { - PRStatus nssrv; - PZ_Lock(store->lock); - if (nssHash_Exists(store->issuer_and_serial, cert)) { - PZ_Unlock(store->lock); - return PR_SUCCESS; - } - nssrv = add_certificate_entry(store, cert); + PRStatus nssrv = add_certificate_entry(store, cert); if (nssrv == PR_SUCCESS) { nssrv = add_subject_entry(store, cert); if (nssrv == PR_FAILURE) { remove_certificate_entry(store, cert); } } - PZ_Unlock(store->lock); return nssrv; } + +NSS_IMPLEMENT NSSCertificate * +nssCertificateStore_FindOrAdd ( + nssCertificateStore *store, + NSSCertificate *c +) +{ + PRStatus nssrv; + NSSCertificate *rvCert = NULL; + + PZ_Lock(store->lock); + rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked( + store, &c->issuer, &c->serial); + if (!rvCert) { + nssrv = nssCertificateStore_AddLocked(store, c); + if (PR_SUCCESS == nssrv) { + rvCert = nssCertificate_AddRef(c); + } + } + PZ_Unlock(store->lock); + return rvCert; +} + static void remove_certificate_entry ( nssCertificateStore *store, @@ -313,18 +338,41 @@ nssCertificateStore_RemoveCertLOCKED ( NSS_IMPLEMENT void nssCertificateStore_Lock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* out ) { +#ifdef DEBUG + PORT_Assert(out); + out->store = store; + out->lock = store->lock; + out->locked = PR_TRUE; + PZ_Lock(out->lock); +#else PZ_Lock(store->lock); +#endif } NSS_IMPLEMENT void nssCertificateStore_Unlock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* in, + nssCertificateStoreTrace* out ) { +#ifdef DEBUG + PORT_Assert(in); + PORT_Assert(out); + out->store = store; + out->lock = store->lock; + out->unlocked = PR_TRUE; + + PORT_Assert(in->store == out->store); + PORT_Assert(in->lock == out->lock); + PORT_Assert(in->locked); + + PZ_Unlock(out->lock); +#else PZ_Unlock(store->lock); +#endif } static NSSCertificate ** @@ -501,24 +549,40 @@ nssCertificateStore_FindCertificatesByEmail ( return rvArray; } -NSS_IMPLEMENT NSSCertificate * -nssCertificateStore_FindCertificateByIssuerAndSerialNumber ( +/* Caller holds store->lock */ +static NSSCertificate * +nssCertStore_FindCertByIssuerAndSerialNumberLocked ( nssCertificateStore *store, NSSDER *issuer, NSSDER *serial ) { certificate_hash_entry *entry; - NSSCertificate index; NSSCertificate *rvCert = NULL; + NSSCertificate index; + index.issuer = *issuer; index.serial = *serial; - PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, &index); if (entry) { rvCert = nssCertificate_AddRef(entry->cert); } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +nssCertificateStore_FindCertificateByIssuerAndSerialNumber ( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +) +{ + NSSCertificate *rvCert = NULL; + + PZ_Lock(store->lock); + rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked ( + store, issuer, serial); PZ_Unlock(store->lock); return rvCert; } diff --git a/security/nss/lib/pki/pkistore.h b/security/nss/lib/pki/pkistore.h index d2f222a1c..0c347296f 100644 --- a/security/nss/lib/pki/pkistore.h +++ b/security/nss/lib/pki/pkistore.h @@ -81,11 +81,14 @@ nssCertificateStore_Destroy nssCertificateStore *store ); -NSS_EXTERN PRStatus -nssCertificateStore_Add +/* Atomic Find cert in store, or add this cert to the store. +** Ref counts properly maintained. +*/ +NSS_EXTERN NSSCertificate * +nssCertificateStore_FindOrAdd ( nssCertificateStore *store, - NSSCertificate *cert + NSSCertificate *c ); NSS_EXTERN void @@ -95,14 +98,36 @@ nssCertificateStore_RemoveCertLOCKED NSSCertificate *cert ); +struct nssCertificateStoreTraceStr { + nssCertificateStore* store; + PZLock* lock; + PRBool locked; + PRBool unlocked; +}; + +typedef struct nssCertificateStoreTraceStr nssCertificateStoreTrace; + +static void nssCertificateStore_Check(nssCertificateStoreTrace* a, + nssCertificateStoreTrace* b) { + PORT_Assert(a->locked); + PORT_Assert(b->unlocked); + + PORT_Assert(!a->unlocked); + PORT_Assert(!b->locked); + + PORT_Assert(a->lock == b->lock); + PORT_Assert(a->store == b->store); +}; + NSS_EXTERN void nssCertificateStore_Lock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* out ); NSS_EXTERN void nssCertificateStore_Unlock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* in, + nssCertificateStoreTrace* out ); NSS_EXTERN NSSCertificate ** diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h index fb04cbaed..46ae1a3b2 100644 --- a/security/nss/lib/pki/pkit.h +++ b/security/nss/lib/pki/pkit.h @@ -93,6 +93,11 @@ PR_BEGIN_EXTERN_C * for each object. */ +typedef enum { + nssPKILock = 1, + nssPKIMonitor = 2 +} nssPKILockType; + /* nssPKIObject * * This is the base object class, common to all PKI objects defined in @@ -105,7 +110,11 @@ struct nssPKIObjectStr /* Atomically incremented/decremented reference counting */ PRInt32 refCount; /* lock protects the array of nssCryptokiInstance's of the object */ - PZLock *lock; + union { + PZLock* lock; + PZMonitor *mlock; + } sync; + nssPKILockType lockType; /* XXX with LRU cache, this cannot be guaranteed up-to-date. It cannot * be compared against the update level of the trust domain, since it is * also affected by import/export. Where is this array needed? diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index 90727d011..3c3e0eeb1 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -429,7 +429,7 @@ remove_token_certs(const void *k, void *v, void *a) nssPKIObject *object = &c->object; struct token_cert_dtor *dtor = a; PRUint32 i; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { if (object->instances[i]->token == dtor->token) { nssCryptokiObject_Destroy(object->instances[i]); @@ -446,7 +446,7 @@ remove_token_certs(const void *k, void *v, void *a) break; } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return; } @@ -1150,6 +1150,9 @@ nssTrustDomain_GetCertsFromCache ( certList = certListOpt; } else { certList = nssList_Create(NULL, PR_FALSE); + if (!certList) { + return NULL; + } } PZ_Lock(td->cache->lock); nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList); diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c index 0ecb8846d..7e93bd092 100644 --- a/security/nss/lib/pki/trustdomain.c +++ b/security/nss/lib/pki/trustdomain.c @@ -134,10 +134,15 @@ NSSTrustDomain_Destroy ( /* Destroy each token in the list of tokens */ if (td->tokens) { nssListIterator_Destroy(td->tokens); + td->tokens = NULL; + } + if (td->tokenList) { nssList_Clear(td->tokenList, token_destructor); nssList_Destroy(td->tokenList); + td->tokenList = NULL; } NSSRWLock_Destroy(td->tokensLock); + td->tokensLock = NULL; status = nssTrustDomain_DestroyCache(td); if (status == PR_FAILURE) { return status; @@ -1217,7 +1222,7 @@ nssTrustDomain_FindTrustForCertificate ( nssTokenSearchType_TokenOnly); if (to) { if (!pkio) { - pkio = nssPKIObject_Create(NULL, to, td, NULL); + pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock); if (!pkio) { nssToken_Destroy(token); nssCryptokiObject_Destroy(to); diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c index 00042937a..071e56538 100644 --- a/security/nss/lib/smime/cmscipher.c +++ b/security/nss/lib/smime/cmscipher.c @@ -224,8 +224,9 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori } cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext)); - if (cc == NULL) - return NULL; + if (cc == NULL) { + goto loser; + } /* now find pad and block sizes for our mechanism */ cc->pad_size = PK11_GetBlockSize(mechanism,param); diff --git a/security/nss/lib/smime/cmsencode.c b/security/nss/lib/smime/cmsencode.c index 34e097cf2..7e5d2b514 100644 --- a/security/nss/lib/smime/cmsencode.c +++ b/security/nss/lib/smime/cmsencode.c @@ -563,8 +563,10 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg, rv = SECFailure; break; } - if (rv != SECSuccess) + if (rv != SECSuccess) { + PORT_Free(p7ecx); return NULL; + } /* Initialize the BER encoder. * Note that this will not encode anything until the first call to SEC_ASN1EncoderUpdate */ diff --git a/security/nss/lib/smime/cmsrecinfo.c b/security/nss/lib/smime/cmsrecinfo.c index 07236adc1..c77d113ad 100644 --- a/security/nss/lib/smime/cmsrecinfo.c +++ b/security/nss/lib/smime/cmsrecinfo.c @@ -187,24 +187,6 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type, rv = SECFailure; } break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA: - PORT_Assert(type == NSSCMSRecipientID_IssuerSN); - if (type != NSSCMSRecipientID_IssuerSN) { - rv = SECFailure; - break; - } - /* backward compatibility - this is not really a keytrans operation */ - ri->recipientInfoType = NSSCMSRecipientInfoID_KeyTrans; - /* hardcoded issuerSN choice for now */ - ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType = NSSCMSRecipientID_IssuerSN; - ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert); - if (ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN == NULL) { - rv = SECFailure; - break; - } - break; case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */ PORT_Assert(type == NSSCMSRecipientID_IssuerSN); if (type != NSSCMSRecipientID_IssuerSN) { @@ -295,6 +277,9 @@ done: return ri; loser: + if (ri && ri->cert) { + CERT_DestroyCertificate(ri->cert); + } if (freeSpki) { SECKEY_DestroySubjectPublicKeyInfo(freeSpki); } @@ -527,20 +512,6 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL); break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA: - rv = NSS_CMSUtil_EncryptSymKey_MISSI(poolp, cert, bulkkey, - bulkalgtag, - &ri->ri.keyTransRecipientInfo.encKey, - ¶ms, ri->cmsg->pwfn_arg); - if (rv != SECSuccess) - break; - - /* here, we DO need to pass the params to the wrap function because, with - * RSA, there is no funny stuff going on with generation of IV vectors or so */ - rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, params); - break; case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */ rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0]; if (rek == NULL) { diff --git a/security/nss/lib/smime/cmsreclist.c b/security/nss/lib/smime/cmsreclist.c index 34e31d582..61eb260be 100644 --- a/security/nss/lib/smime/cmsreclist.c +++ b/security/nss/lib/smime/cmsreclist.c @@ -66,25 +66,33 @@ nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipien switch (ri->recipientInfoType) { case NSSCMSRecipientInfoID_KeyTrans: if (recipient_list) { + NSSCMSRecipientIdentifier *recipId = + &ri->ri.keyTransRecipientInfo.recipientIdentifier; + + if (recipId->identifierType != NSSCMSRecipientID_IssuerSN && + recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return -1; + } /* alloc one & fill it out */ rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); - if (rle == NULL) + if (!rle) return -1; rle->riIndex = i; rle->subIndex = -1; - switch (ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType) { + switch (recipId->identifierType) { case NSSCMSRecipientID_IssuerSN: rle->kind = RLIssuerSN; - rle->id.issuerAndSN = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN; + rle->id.issuerAndSN = recipId->id.issuerAndSN; break; case NSSCMSRecipientID_SubjectKeyID: rle->kind = RLSubjKeyID; - rle->id.subjectKeyID = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.subjectKeyID; + rle->id.subjectKeyID = recipId->id.subjectKeyID; + break; + default: /* we never get here because of identifierType check + we done before. Leaving it to kill compiler warning */ break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return -1; } recipient_list[rlindex++] = rle; } else { @@ -99,7 +107,7 @@ nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipien rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j]; /* alloc one & fill it out */ rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); - if (rle == NULL) + if (!rle) return -1; rle->riIndex = i; diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c index 675040b66..508632f69 100644 --- a/security/nss/lib/smime/cmssiginfo.c +++ b/security/nss/lib/smime/cmssiginfo.c @@ -386,7 +386,9 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: +#ifdef NSS_ECC_MORE_THAN_SUITE_B case SEC_OID_ANSIX962_EC_PUBLIC_KEY: +#endif /* ok */ break; case SEC_OID_UNKNOWN: diff --git a/security/nss/lib/smime/cmsutil.c b/security/nss/lib/smime/cmsutil.c index 1765655bb..710a749c6 100644 --- a/security/nss/lib/smime/cmsutil.c +++ b/security/nss/lib/smime/cmsutil.c @@ -259,7 +259,13 @@ NSS_CMSUtil_MakeSignatureAlgorithm(SECOidTag hashalg, SECOidTag encalg) case SEC_OID_ANSIX962_EC_PUBLIC_KEY: switch (hashalg) { case SEC_OID_SHA1: - return SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; + return SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; + case SEC_OID_SHA256: + return SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; + case SEC_OID_SHA384: + return SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; + case SEC_OID_SHA512: + return SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; default: return SEC_OID_UNKNOWN; } diff --git a/security/nss/lib/smime/smime.rc b/security/nss/lib/smime/smime.rc index 05fb11bfa..7fd7298d1 100644 --- a/security/nss/lib/smime/smime.rc +++ b/security/nss/lib/smime/smime.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/smime/smimeutil.c b/security/nss/lib/smime/smimeutil.c index 6fb10ec07..c26330ba5 100644 --- a/security/nss/lib/smime/smimeutil.c +++ b/security/nss/lib/smime/smimeutil.c @@ -116,15 +116,18 @@ static const SEC_ASN1Template smime_encryptionkeypref_template[] = { { SEC_ASN1_CHOICE, offsetof(NSSSMIMEEncryptionKeyPreference,selector), NULL, sizeof(NSSSMIMEEncryptionKeyPreference) }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, + { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0 + | SEC_ASN1_CONSTRUCTED, offsetof(NSSSMIMEEncryptionKeyPreference,id.issuerAndSN), SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), NSSSMIMEEncryptionKeyPref_IssuerSN }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1, + { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1 + | SEC_ASN1_CONSTRUCTED, offsetof(NSSSMIMEEncryptionKeyPreference,id.recipientKeyID), NSSCMSRecipientKeyIdentifierTemplate, - NSSSMIMEEncryptionKeyPref_IssuerSN }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, + NSSSMIMEEncryptionKeyPref_RKeyID }, + { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2 + | SEC_ASN1_CONSTRUCTED, offsetof(NSSSMIMEEncryptionKeyPreference,id.subjectKeyID), SEC_ASN1_SUB(SEC_OctetStringTemplate), NSSSMIMEEncryptionKeyPref_SubjectKeyID }, diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk index 2e097c8a5..bc48130aa 100644 --- a/security/nss/lib/softoken/config.mk +++ b/security/nss/lib/softoken/config.mk @@ -91,6 +91,7 @@ ifeq ($(OS_TARGET),SunOS) # The -R '$ORIGIN' linker option instructs this library to search for its # dependencies in the same directory where it resides. MKSHLIB += -R '$$ORIGIN' +OS_LIBS += -lbsm endif ifeq ($(OS_TARGET),WINCE) diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c index 2b7f81a73..d1f7fd303 100644 --- a/security/nss/lib/softoken/dbinit.c +++ b/security/nss/lib/softoken/dbinit.c @@ -291,6 +291,7 @@ sftk_freeCertDB(NSSLOWCERTCertDBHandle *certHandle) PRInt32 ref = PR_AtomicDecrement(&certHandle->ref); if (ref == 0) { nsslowcert_ClosePermCertDB(certHandle); + PORT_Free(certHandle); } } diff --git a/security/nss/lib/softoken/dbmshim.c b/security/nss/lib/softoken/dbmshim.c index 04c291d7f..f75f4d70d 100644 --- a/security/nss/lib/softoken/dbmshim.c +++ b/security/nss/lib/softoken/dbmshim.c @@ -406,14 +406,6 @@ dbs_readBlob(DBS *dbsp, DBT *data) loser: /* preserve the error code */ error = PR_GetError(); - if (addr) { - if (mapfile) { - PORT_Assert(len != -1); - PR_MemUnmap(addr,len); - } else { - PORT_Free(addr); - } - } if (mapfile) { PR_CloseFileMap(mapfile); } diff --git a/security/nss/lib/softoken/ecdecode.c b/security/nss/lib/softoken/ecdecode.c index e649ff899..dbf1cb3f8 100644 --- a/security/nss/lib/softoken/ecdecode.c +++ b/security/nss/lib/softoken/ecdecode.c @@ -49,7 +49,12 @@ #define CHECK_OK(func) if (func == NULL) goto cleanup #define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup -/* Initializes a SECItem from a hexadecimal string */ +/* + * Initializes a SECItem from a hexadecimal string + * + * Warning: This function ignores leading 00's, so any leading 00's + * in the hexadecimal string must be optional. + */ static SECItem * hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str) { @@ -59,6 +64,12 @@ hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str) if ((tmp % 2) != 0) return NULL; + /* skip leading 00's unless the hex string is "00" */ + while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { + str += 2; + tmp -= 2; + } + item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2); if (item->data == NULL) return NULL; item->len = tmp/2; @@ -136,7 +147,8 @@ EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams, SECOidTag tag; SECItem oid = { siBuffer, NULL, 0}; const ECCurveParams *curveParams; - char genenc[2 + 2 * 2 * MAX_ECKEY_LEN]; + /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */ + char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; #if EC_DEBUG int i; diff --git a/security/nss/lib/softoken/fipsaudt.c b/security/nss/lib/softoken/fipsaudt.c new file mode 100644 index 000000000..d17496deb --- /dev/null +++ b/security/nss/lib/softoken/fipsaudt.c @@ -0,0 +1,351 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 Network Security Services (NSS). + * + * The Initial Developer of the Original Code is + * Red Hat, Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * This file implements audit logging required by FIPS 140-2 Security + * Level 2. + */ + +#include "prprf.h" +#include "softoken.h" + +/* + * Print the value of the returned object handle in the output buffer + * on a successful return of the PKCS #11 function. If the PKCS #11 + * function failed or the pointer to object handle is NULL (which is + * the case for C_DeriveKey with CKM_TLS_KEY_AND_MAC_DERIVE), an empty + * string is stored in the output buffer. + * + * out: the output buffer + * outlen: the length of the output buffer + * argName: the name of the "pointer to object handle" argument + * phObject: the pointer to object handle + * rv: the return value of the PKCS #11 function + */ +static void sftk_PrintReturnedObjectHandle(char *out, PRUint32 outlen, + const char *argName, CK_OBJECT_HANDLE_PTR phObject, CK_RV rv) +{ + if ((rv == CKR_OK) && phObject) { + PR_snprintf(out, outlen, + " *%s=0x%08lX", argName, (PRUint32)*phObject); + } else { + PORT_Assert(outlen != 0); + out[0] = '\0'; + } +} + +/* + * MECHANISM_BUFSIZE needs to be large enough for sftk_PrintMechanism, + * which uses <= 49 bytes. + */ +#define MECHANISM_BUFSIZE 64 + +static void sftk_PrintMechanism(char *out, PRUint32 outlen, + CK_MECHANISM_PTR pMechanism) +{ + if (pMechanism) { + /* + * If we change the format string, we need to make sure + * MECHANISM_BUFSIZE is still large enough. We allow + * 20 bytes for %p on a 64-bit platform. + */ + PR_snprintf(out, outlen, "%p {mechanism=0x%08lX, ...}", + pMechanism, (PRUint32)pMechanism->mechanism); + } else { + PR_snprintf(out, outlen, "%p", pMechanism); + } +} + +void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject, CK_RV rv) +{ + char msg[256]; + char shObject[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintReturnedObjectHandle(shObject, sizeof shObject, + "phObject", phObject, rv); + PR_snprintf(msg, sizeof msg, + "C_CreateObject(hSession=0x%08lX, pTemplate=%p, ulCount=%lu, " + "phObject=%p)=0x%08lX%s", + (PRUint32)hSession, pTemplate, (PRUint32)ulCount, + phObject, (PRUint32)rv, shObject); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv) +{ + char msg[256]; + char shNewObject[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintReturnedObjectHandle(shNewObject, sizeof shNewObject, + "phNewObject", phNewObject, rv); + PR_snprintf(msg, sizeof msg, + "C_CopyObject(hSession=0x%08lX, hObject=0x%08lX, " + "pTemplate=%p, ulCount=%lu, phNewObject=%p)=0x%08lX%s", + (PRUint32)hSession, (PRUint32)hObject, + pTemplate, (PRUint32)ulCount, phNewObject, (PRUint32)rv, shNewObject); + sftk_LogAuditMessage(severity, msg); +} + +/* WARNING: hObject has been destroyed and can only be printed. */ +void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_DestroyObject(hSession=0x%08lX, hObject=0x%08lX)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_GetObjectSize(hSession=0x%08lX, hObject=0x%08lX, " + "pulSize=%p)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, + pulSize, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_GetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, " + "pTemplate=%p, ulCount=%lu)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, + pTemplate, (PRUint32)ulCount, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_SetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, " + "pTemplate=%p, ulCount=%lu)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, + pTemplate, (PRUint32)ulCount, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditCryptInit(const char *opName, CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + PR_snprintf(msg, sizeof msg, + "C_%sInit(hSession=0x%08lX, pMechanism=%s, " + "hKey=0x%08lX)=0x%08lX", + opName, (PRUint32)hSession, mech, + (PRUint32)hKey, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + char shKey[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); + PR_snprintf(msg, sizeof msg, + "C_GenerateKey(hSession=0x%08lX, pMechanism=%s, " + "pTemplate=%p, ulCount=%lu, phKey=%p)=0x%08lX%s", + (PRUint32)hSession, mech, + pTemplate, (PRUint32)ulCount, phKey, (PRUint32)rv, shKey); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv) +{ + char msg[512]; + char mech[MECHANISM_BUFSIZE]; + char shPublicKey[32]; + char shPrivateKey[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shPublicKey, sizeof shPublicKey, + "phPublicKey", phPublicKey, rv); + sftk_PrintReturnedObjectHandle(shPrivateKey, sizeof shPrivateKey, + "phPrivateKey", phPrivateKey, rv); + PR_snprintf(msg, sizeof msg, + "C_GenerateKeyPair(hSession=0x%08lX, pMechanism=%s, " + "pPublicKeyTemplate=%p, ulPublicKeyAttributeCount=%lu, " + "pPrivateKeyTemplate=%p, ulPrivateKeyAttributeCount=%lu, " + "phPublicKey=%p, phPrivateKey=%p)=0x%08lX%s%s", + (PRUint32)hSession, mech, + pPublicKeyTemplate, (PRUint32)ulPublicKeyAttributeCount, + pPrivateKeyTemplate, (PRUint32)ulPrivateKeyAttributeCount, + phPublicKey, phPrivateKey, (PRUint32)rv, shPublicKey, shPrivateKey); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + PR_snprintf(msg, sizeof msg, + "C_WrapKey(hSession=0x%08lX, pMechanism=%s, hWrappingKey=0x%08lX, " + "hKey=0x%08lX, pWrappedKey=%p, pulWrappedKeyLen=%p)=0x%08lX", + (PRUint32)hSession, mech, (PRUint32)hWrappingKey, + (PRUint32)hKey, pWrappedKey, pulWrappedKeyLen, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + char shKey[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); + PR_snprintf(msg, sizeof msg, + "C_UnwrapKey(hSession=0x%08lX, pMechanism=%s, " + "hUnwrappingKey=0x%08lX, pWrappedKey=%p, ulWrappedKeyLen=%lu, " + "pTemplate=%p, ulAttributeCount=%lu, phKey=%p)=0x%08lX%s", + (PRUint32)hSession, mech, + (PRUint32)hUnwrappingKey, pWrappedKey, (PRUint32)ulWrappedKeyLen, + pTemplate, (PRUint32)ulAttributeCount, phKey, (PRUint32)rv, shKey); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) +{ + char msg[512]; + char mech[MECHANISM_BUFSIZE]; + char shKey[32]; + char sTlsKeys[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); + if ((rv == CKR_OK) && + (pMechanism->mechanism == CKM_TLS_KEY_AND_MAC_DERIVE)) { + CK_SSL3_KEY_MAT_PARAMS *param = + (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; + CK_SSL3_KEY_MAT_OUT *keymat = param->pReturnedKeyMaterial; + PR_snprintf(sTlsKeys, sizeof sTlsKeys, + " hClientMacSecret=0x%08lX hServerMacSecret=0x%08lX" + " hClientKey=0x%08lX hServerKey=0x%08lX", + (PRUint32)keymat->hClientMacSecret, + (PRUint32)keymat->hServerMacSecret, + (PRUint32)keymat->hClientKey, + (PRUint32)keymat->hServerKey); + } else { + sTlsKeys[0] = '\0'; + } + PR_snprintf(msg, sizeof msg, + "C_DeriveKey(hSession=0x%08lX, pMechanism=%s, " + "hBaseKey=0x%08lX, pTemplate=%p, ulAttributeCount=%lu, " + "phKey=%p)=0x%08lX%s%s", + (PRUint32)hSession, mech, + (PRUint32)hBaseKey, pTemplate,(PRUint32)ulAttributeCount, + phKey, (PRUint32)rv, shKey, sTlsKeys); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hKey, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_DigestKey(hSession=0x%08lX, hKey=0x%08lX)=0x%08lX", + (PRUint32)hSession, (PRUint32)hKey, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c index acee77676..942bd4034 100644 --- a/security/nss/lib/softoken/fipstest.c +++ b/security/nss/lib/softoken/fipstest.c @@ -42,10 +42,21 @@ /* DES-CBC, DES3-ECB, DES3-CBC, RSA */ /* and DSA. */ #include "seccomon.h" /* Required for RSA and DSA. */ -#include "lowkeyi.h" /* Required for RSA and DSA. */ +#include "lowkeyi.h" /* Required for RSA and DSA. */ #include "pkcs11.h" /* Required for PKCS #11. */ #include "secerr.h" +#ifdef NSS_ENABLE_ECC +#include "secdert.h" /* Required for ECDSA */ +#include "ec.h" /* Required for ECDSA */ +extern SECStatus +EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); +extern SECStatus +EC_CopyParams(PRArenaPool *arena, ECParams *dstParams, + const ECParams *srcParams); +#endif + + /* FIPS preprocessor directives for RC2-ECB and RC2-CBC. */ #define FIPS_RC2_KEY_LENGTH 5 /* 40-bits */ #define FIPS_RC2_ENCRYPT_LENGTH 8 /* 64-bits */ @@ -81,31 +92,33 @@ #define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */ -/* FIPS preprocessor directives for RSA. */ +/* FIPS preprocessor directives for RSA. */ #define FIPS_RSA_TYPE siBuffer -#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 1 /* 8-bits */ -#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */ -#define FIPS_RSA_MESSAGE_LENGTH 16 /* 128-bits */ -#define FIPS_RSA_COEFFICIENT_LENGTH 32 /* 256-bits */ -#define FIPS_RSA_PRIME0_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_PRIME1_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_EXPONENT0_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_EXPONENT1_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_ENCRYPT_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_DECRYPT_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_CRYPTO_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_SIGNATURE_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_MODULUS_LENGTH 65 /* 520-bits */ +#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 3 /* 24-bits */ +#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */ +#define FIPS_RSA_MESSAGE_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_COEFFICIENT_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_PRIME0_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_PRIME1_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_EXPONENT0_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_EXPONENT1_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_ENCRYPT_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_DECRYPT_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_SIGNATURE_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_MODULUS_LENGTH 128 /* 1024-bits */ /* FIPS preprocessor directives for DSA. */ #define FIPS_DSA_TYPE siBuffer -#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */ -#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */ -#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */ -#define FIPS_DSA_PRIME_LENGTH 64 /* 512-bits */ -#define FIPS_DSA_BASE_LENGTH 64 /* 512-bits */ +#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */ +#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */ +#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */ +#define FIPS_DSA_PRIME_LENGTH 128 /* 1024-bits */ +#define FIPS_DSA_BASE_LENGTH 128 /* 1024-bits */ + +/* FIPS preprocessor directives for RNG. */ +#define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */ static CK_RV sftk_fips_RC2_PowerUpSelfTest( void ) @@ -1046,121 +1059,324 @@ sftk_fips_SHA_PowerUpSelfTest( void ) return( CKR_OK ); } +/* +* Single round RSA Signature Known Answer Test +*/ +static SECStatus +sftk_fips_RSA_PowerUpSigSelfTest (HASH_HashType shaAlg, + NSSLOWKEYPublicKey *rsa_public_key, + NSSLOWKEYPrivateKey *rsa_private_key, + const unsigned char *rsa_known_msg, + const unsigned int rsa_kmsg_length, + const unsigned char *rsa_known_signature) +{ + SECOidTag shaOid; /* SHA OID */ + unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */ + unsigned int shaLength = 0; /* length of SHA */ + unsigned int rsa_bytes_signed; + unsigned char rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH]; + SECStatus rv; + + if (shaAlg == HASH_AlgSHA1) { + if (SHA1_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA1_LENGTH; + shaOid = SEC_OID_SHA1; + } else if (shaAlg == HASH_AlgSHA256) { + if (SHA256_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA256_LENGTH; + shaOid = SEC_OID_SHA256; + } else if (shaAlg == HASH_AlgSHA384) { + if (SHA384_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA384_LENGTH; + shaOid = SEC_OID_SHA384; + } else if (shaAlg == HASH_AlgSHA512) { + if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA512_LENGTH; + shaOid = SEC_OID_SHA512; + } else { + goto loser; + } + + /*************************************************/ + /* RSA Single-Round Known Answer Signature Test. */ + /*************************************************/ + + /* Perform RSA signature with the RSA private key. */ + rv = RSA_HashSign( shaOid, + rsa_private_key, + rsa_computed_signature, + &rsa_bytes_signed, + FIPS_RSA_SIGNATURE_LENGTH, + sha, + shaLength); + + if( ( rv != SECSuccess ) || + ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) || + ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature, + FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) ) { + goto loser; + } + + /****************************************************/ + /* RSA Single-Round Known Answer Verification Test. */ + /****************************************************/ + + /* Perform RSA verification with the RSA public key. */ + rv = RSA_HashCheckSign( shaOid, + rsa_public_key, + rsa_computed_signature, + rsa_bytes_signed, + sha, + shaLength); + + if( rv != SECSuccess ) { + goto loser; + } + return( SECSuccess ); + +loser: + + return( SECFailure ); + +} static CK_RV sftk_fips_RSA_PowerUpSelfTest( void ) { - /* RSA Known Modulus used in both Public/Private Key Values (520-bits). */ + /* RSA Known Modulus used in both Public/Private Key Values (1024-bits). */ static const PRUint8 rsa_modulus[FIPS_RSA_MODULUS_LENGTH] = { - 0x00,0xa1,0xe9,0x5e,0x66,0x88,0xe2,0xf2, - 0x2b,0xe7,0x70,0x36,0x33,0xbc,0xeb,0x55, - 0x55,0xf1,0x60,0x18,0x3c,0xfb,0xd2,0x79, - 0xf6,0xc4,0xb8,0x09,0xe3,0x12,0xf6,0x63, - 0x6d,0xc7,0x8e,0x19,0xc0,0x0e,0x10,0x78, - 0xc1,0xfe,0x2a,0x41,0x74,0x2d,0xf7,0xc4, - 0x69,0xa7,0x3c,0xbc,0x8a,0xc8,0x31,0x2b, - 0x4f,0x60,0xf0,0xf1,0xec,0x5a,0x29,0xec, - 0x6b}; - - /* RSA Known Public Key Values (8-bits). */ - static const PRUint8 rsa_public_exponent[] = { 0x03 }; - - /* RSA Known Private Key Values (version is 8-bits), */ - /* (private exponent is 512-bits), */ - /* (private prime0 is 264-bits), */ - /* (private prime1 is 264-bits), */ - /* (private prime exponent0 is 264-bits), */ - /* (private prime exponent1 is 264-bits), */ - /* and (private coefficient is 256-bits). */ + 0xd5, 0x84, 0x95, 0x07, 0xf4, 0xd0, 0x1f, 0x82, + 0xf3, 0x79, 0xf4, 0x99, 0x48, 0x10, 0xe1, 0x71, + 0xa5, 0x62, 0x22, 0xa3, 0x4b, 0x00, 0xe3, 0x5b, + 0x3a, 0xcc, 0x10, 0x83, 0xe0, 0xaf, 0x61, 0x13, + 0x54, 0x6a, 0xa2, 0x6a, 0x2c, 0x5e, 0xb3, 0xcc, + 0xa3, 0x71, 0x9a, 0xb2, 0x3e, 0x78, 0xec, 0xb5, + 0x0e, 0x6e, 0x31, 0x3b, 0x77, 0x1f, 0x6e, 0x94, + 0x41, 0x60, 0xd5, 0x6e, 0xd9, 0xc6, 0xf9, 0x29, + 0xc3, 0x40, 0x36, 0x25, 0xdb, 0xea, 0x0b, 0x07, + 0xae, 0x76, 0xfd, 0x99, 0x29, 0xf4, 0x22, 0xc1, + 0x1a, 0x8f, 0x05, 0xfe, 0x98, 0x09, 0x07, 0x05, + 0xc2, 0x0f, 0x0b, 0x11, 0x83, 0x39, 0xca, 0xc7, + 0x43, 0x63, 0xff, 0x33, 0x80, 0xe7, 0xc3, 0x78, + 0xae, 0xf1, 0x73, 0x52, 0x98, 0x1d, 0xde, 0x5c, + 0x53, 0x6e, 0x01, 0x73, 0x0d, 0x12, 0x7e, 0x77, + 0x03, 0xf1, 0xef, 0x1b, 0xc8, 0xa8, 0x0f, 0x97}; + + /* RSA Known Public Key Values (24-bits). */ + static const PRUint8 rsa_public_exponent[FIPS_RSA_PUBLIC_EXPONENT_LENGTH] + = { 0x01, 0x00, 0x01 }; + /* RSA Known Private Key Values (version is 8-bits), */ + /* (private exponent is 1024-bits), */ + /* (private prime0 is 512-bits), */ + /* (private prime1 is 512-bits), */ + /* (private prime exponent0 is 512-bits), */ + /* (private prime exponent1 is 512-bits), */ + /* and (private coefficient is 512-bits). */ static const PRUint8 rsa_version[] = { 0x00 }; - static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH] = { - 0x6b,0xf0,0xe9,0x99,0xb0,0x97,0x4c,0x1d, - 0x44,0xf5,0x79,0x77,0xd3,0x47,0x8e,0x39, - 0x4b,0x95,0x65,0x7d,0xfd,0x36,0xfb,0xf9, - 0xd8,0x7a,0xb1,0x42,0x0c,0xa4,0x42,0x48, - 0x20,0x1c,0x6b,0x7d,0x5d,0xa3,0x58,0xd6, - 0x95,0xd6,0x41,0xe3,0xd6,0x73,0xad,0xdb, - 0x3b,0x89,0x00,0x8a,0xcd,0x1d,0xb9,0x06, - 0xac,0xac,0x0e,0x02,0x72,0x1c,0xf8,0xab }; + + static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH] + = { 0x85, 0x27, 0x47, 0x61, 0x4c, 0xd4, 0xb5, 0xb2, + 0x0e, 0x70, 0x91, 0x8f, 0x3d, 0x97, 0xf9, 0x5f, + 0xcc, 0x09, 0x65, 0x1c, 0x7c, 0x5b, 0xb3, 0x6d, + 0x63, 0x3f, 0x7b, 0x55, 0x22, 0xbb, 0x7c, 0x48, + 0x77, 0xae, 0x80, 0x56, 0xc2, 0x10, 0xd5, 0x03, + 0xdb, 0x31, 0xaf, 0x8d, 0x54, 0xd4, 0x48, 0x99, + 0xa8, 0xc4, 0x23, 0x43, 0xb8, 0x48, 0x0b, 0xc7, + 0xbc, 0xf5, 0xcc, 0x64, 0x72, 0xbf, 0x59, 0x06, + 0x04, 0x1c, 0x32, 0xf5, 0x14, 0x2e, 0x6e, 0xe2, + 0x0f, 0x5c, 0xde, 0x36, 0x3c, 0x6e, 0x7c, 0x4d, + 0xcc, 0xd3, 0x00, 0x6e, 0xe5, 0x45, 0x46, 0xef, + 0x4d, 0x25, 0x46, 0x6d, 0x7f, 0xed, 0xbb, 0x4f, + 0x4d, 0x9f, 0xda, 0x87, 0x47, 0x8f, 0x74, 0x44, + 0xb7, 0xbe, 0x9d, 0xf5, 0xdd, 0xd2, 0x4c, 0xa5, + 0xab, 0x74, 0xe5, 0x29, 0xa1, 0xd2, 0x45, 0x3b, + 0x33, 0xde, 0xd5, 0xae, 0xf7, 0x03, 0x10, 0x21}; + static const PRUint8 rsa_prime0[FIPS_RSA_PRIME0_LENGTH] = { - 0x00,0xd2,0x2c,0x9d,0xef,0x7c,0x8f,0x58, - 0x93,0x19,0xa1,0x77,0x0e,0x38,0x3e,0x85, - 0xb4,0xaf,0xcc,0x99,0xa5,0x43,0xbf,0x97, - 0xdc,0x46,0xb8,0x3f,0x6e,0x85,0x18,0x00, - 0x81}; + 0xf9, 0x74, 0x8f, 0x16, 0x02, 0x6b, 0xa0, 0xee, + 0x7f, 0x28, 0x97, 0x91, 0xdc, 0xec, 0xc0, 0x7c, + 0x49, 0xc2, 0x85, 0x76, 0xee, 0x66, 0x74, 0x2d, + 0x1a, 0xb8, 0xf7, 0x2f, 0x11, 0x5b, 0x36, 0xd8, + 0x46, 0x33, 0x3b, 0xd8, 0xf3, 0x2d, 0xa1, 0x03, + 0x83, 0x2b, 0xec, 0x35, 0x43, 0x32, 0xff, 0xdd, + 0x81, 0x7c, 0xfd, 0x65, 0x13, 0x04, 0x7c, 0xfc, + 0x03, 0x97, 0xf0, 0xd5, 0x62, 0xdc, 0x0d, 0xbf}; static const PRUint8 rsa_prime1[FIPS_RSA_PRIME1_LENGTH] = { - 0x00,0xc5,0x36,0xda,0x94,0x85,0x0c,0x1a, - 0xed,0x03,0xc7,0x67,0x90,0x34,0x0b,0xb9, - 0xec,0x1e,0x22,0xa2,0x15,0x50,0xc4,0xfd, - 0xe9,0x17,0x36,0x9d,0x7a,0x29,0xe6,0x76, - 0xeb}; + 0xdb, 0x1e, 0xa7, 0x3d, 0xe7, 0xfa, 0x8b, 0x04, + 0x83, 0x48, 0xf3, 0xa5, 0x31, 0x9d, 0x35, 0x5e, + 0x4d, 0x54, 0x77, 0xcc, 0x84, 0x09, 0xf3, 0x11, + 0x0d, 0x54, 0xed, 0x85, 0x39, 0xa9, 0xca, 0xa8, + 0xea, 0xae, 0x19, 0x9c, 0x75, 0xdb, 0x88, 0xb8, + 0x04, 0x8d, 0x54, 0xc6, 0xa4, 0x80, 0xf8, 0x93, + 0xf0, 0xdb, 0x19, 0xef, 0xd7, 0x87, 0x8a, 0x8f, + 0x5a, 0x09, 0x2e, 0x54, 0xf3, 0x45, 0x24, 0x29}; static const PRUint8 rsa_exponent0[FIPS_RSA_EXPONENT0_LENGTH] = { - 0x00,0x8c,0x1d,0xbe,0x9f,0xa8, - 0x5f,0x90,0x62,0x11,0x16,0x4f, - 0x5e,0xd0,0x29,0xae,0x78,0x75, - 0x33,0x11,0x18,0xd7,0xd5,0x0f, - 0xe8,0x2f,0x25,0x7f,0x9f,0x03, - 0x65,0x55,0xab}; + 0x6a, 0xd1, 0x25, 0x80, 0x18, 0x33, 0x3c, 0x2b, + 0x44, 0x19, 0xfe, 0xa5, 0x40, 0x03, 0xc4, 0xfc, + 0xb3, 0x9c, 0xef, 0x07, 0x99, 0x58, 0x17, 0xc1, + 0x44, 0xa3, 0x15, 0x7d, 0x7b, 0x22, 0x22, 0xdf, + 0x03, 0x58, 0x66, 0xf5, 0x24, 0x54, 0x52, 0x91, + 0x2d, 0x76, 0xfe, 0x63, 0x64, 0x4e, 0x0f, 0x50, + 0x2b, 0x65, 0x79, 0x1f, 0xf1, 0xbf, 0xc7, 0x41, + 0x26, 0xcc, 0xc6, 0x1c, 0xa9, 0x83, 0x6f, 0x03}; static const PRUint8 rsa_exponent1[FIPS_RSA_EXPONENT1_LENGTH] = { - 0x00,0x83,0x79,0xe7,0x0d,0xae, - 0x08,0x11,0xf3,0x57,0xda,0x45, - 0x0a,0xcd,0x5d,0x26,0x9d,0x69, - 0x6c,0x6c,0x0e,0x35,0xd8,0xa9, - 0x46,0x0f,0x79,0xbe,0x51,0x71, - 0x44,0x4f,0x47}; + 0x12, 0x84, 0x1a, 0x99, 0xce, 0x9a, 0x8b, 0x58, + 0xcc, 0x47, 0x43, 0xdf, 0x77, 0xbb, 0xd3, 0x20, + 0xae, 0xe4, 0x2e, 0x63, 0x67, 0xdc, 0xf7, 0x5f, + 0x3f, 0x83, 0x27, 0xb7, 0x14, 0x52, 0x56, 0xbf, + 0xc3, 0x65, 0x06, 0xe1, 0x03, 0xcc, 0x93, 0x57, + 0x09, 0x7b, 0x6f, 0xe8, 0x81, 0x4a, 0x2c, 0xb7, + 0x43, 0xa9, 0x20, 0x1d, 0xf6, 0x56, 0x8b, 0xcc, + 0xe5, 0x4c, 0xd5, 0x4f, 0x74, 0x67, 0x29, 0x51}; static const PRUint8 rsa_coefficient[FIPS_RSA_COEFFICIENT_LENGTH] = { - 0x54,0x8d,0xb8,0xdc,0x8b,0xde,0xbb, - 0x08,0xc9,0x67,0xb7,0xa9,0x5f,0xa5, - 0xc4,0x5e,0x67,0xaa,0xfe,0x1a,0x08, - 0xeb,0x48,0x43,0xcb,0xb0,0xb9,0x38, - 0x3a,0x31,0x39,0xde}; - - - /* RSA Known Plaintext (512-bits). */ - static const PRUint8 rsa_known_plaintext[] = { - "Known plaintext utilized for RSA" - " Encryption and Decryption test." }; - - /* RSA Known Ciphertext (512-bits). */ + 0x23, 0xab, 0xf4, 0x03, 0x2f, 0x29, 0x95, 0x74, + 0xac, 0x1a, 0x33, 0x96, 0x62, 0xed, 0xf7, 0xf6, + 0xae, 0x07, 0x2a, 0x2e, 0xe8, 0xab, 0xfb, 0x1e, + 0xb9, 0xb2, 0x88, 0x1e, 0x85, 0x05, 0x42, 0x64, + 0x03, 0xb2, 0x8b, 0xc1, 0x81, 0x75, 0xd7, 0xba, + 0xaa, 0xd4, 0x31, 0x3c, 0x8a, 0x96, 0x23, 0x9d, + 0x3f, 0x06, 0x3e, 0x44, 0xa9, 0x62, 0x2f, 0x61, + 0x5a, 0x51, 0x82, 0x2c, 0x04, 0x85, 0x73, 0xd1}; + + /* RSA Known Plaintext Message (1024-bits). */ + static const PRUint8 rsa_known_plaintext_msg[FIPS_RSA_MESSAGE_LENGTH] = { + "Known plaintext message utilized" + "for RSA Encryption & Decryption" + "block, SHA1, SHA256, SHA384 and" + "SHA512 RSA Signature KAT tests."}; + + /* RSA Known Ciphertext (1024-bits). */ static const PRUint8 rsa_known_ciphertext[] = { - 0x12,0x80,0x3a,0x53,0xee,0x93,0x81,0xa5, - 0xf7,0x40,0xc5,0xb1,0xef,0xd9,0x27,0xaf, - 0xef,0x4b,0x87,0x44,0x00,0xd0,0xda,0xcf, - 0x10,0x57,0x4c,0xd5,0xc3,0xed,0x84,0xdc, - 0x74,0x03,0x19,0x69,0x2c,0xd6,0x54,0x3e, - 0xd2,0xe3,0x90,0xb6,0x67,0x91,0x2f,0x1f, - 0x54,0x13,0x99,0x00,0x0b,0xfd,0x52,0x7f, - 0xd8,0xc6,0xdb,0x8a,0xfe,0x06,0xf3,0xb1}; - - /* RSA Known Message (128-bits). */ - static const PRUint8 rsa_known_message[] = { "Netscape Forever" }; - - /* RSA Known Signed Hash (512-bits). */ - static const PRUint8 rsa_known_signature[] = { - 0x27,0x23,0xa6,0x71,0x57,0xc8,0x70,0x5f, - 0x70,0x0e,0x06,0x7b,0x96,0x6a,0xaa,0x41, - 0x6e,0xab,0x67,0x4b,0x5f,0x76,0xc4,0x53, - 0x23,0xd7,0x57,0x7a,0x3a,0xbc,0x4c,0x27, - 0x65,0xca,0xde,0x9f,0xd3,0x1d,0xa4,0x5a, - 0xf9,0x8f,0xb2,0x05,0xa3,0x86,0xf9,0x66, - 0x55,0x4c,0x68,0x50,0x66,0xa4,0xe9,0x17, - 0x45,0x11,0xb8,0x1a,0xfc,0xbc,0x79,0x3b}; - - - static const RSAPublicKey bl_public_key = { NULL, - { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, FIPS_RSA_MODULUS_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH } + 0x1e, 0x7e, 0x12, 0xbb, 0x15, 0x62, 0xd0, 0x23, + 0x53, 0x4c, 0x51, 0x97, 0x77, 0x06, 0xa0, 0xbb, + 0x26, 0x99, 0x9a, 0x8f, 0x39, 0xad, 0x88, 0x5c, + 0xc4, 0xce, 0x33, 0x40, 0x94, 0x92, 0xb4, 0x0e, + 0xab, 0x71, 0xa9, 0x5d, 0x9a, 0x37, 0xe3, 0x9a, + 0x24, 0x95, 0x13, 0xea, 0x0f, 0xbb, 0xf7, 0xff, + 0xdf, 0x31, 0x33, 0x23, 0x1d, 0xce, 0x26, 0x9e, + 0xd1, 0xde, 0x98, 0x40, 0xde, 0x57, 0x86, 0x12, + 0xf1, 0xe6, 0x5a, 0x3f, 0x08, 0x02, 0x81, 0x85, + 0xe0, 0xd9, 0xad, 0x3c, 0x8c, 0x71, 0xf8, 0xcf, + 0x0a, 0x98, 0xc5, 0x08, 0xdc, 0xc4, 0xca, 0x8c, + 0x23, 0x1b, 0x4d, 0x9b, 0xb5, 0x13, 0x44, 0xe1, + 0x5f, 0xf9, 0x30, 0x80, 0x25, 0xe0, 0x1e, 0x94, + 0xa3, 0x0c, 0xdc, 0x82, 0x2e, 0xfb, 0x30, 0xbe, + 0x89, 0xba, 0x76, 0xb6, 0x23, 0xf7, 0xda, 0x7c, + 0xca, 0xe6, 0x02, 0xbd, 0x92, 0xce, 0x64, 0xfc}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha1_signature[] = { + 0xd2, 0xa4, 0xe0, 0x2b, 0xc7, 0x03, 0x7f, 0xc6, + 0x06, 0x9e, 0xa2, 0x82, 0x19, 0xe9, 0x2b, 0xaf, + 0xe3, 0x48, 0x88, 0xc1, 0xf3, 0xb5, 0x0d, 0xe4, + 0x52, 0x9e, 0xad, 0xd5, 0x58, 0xb5, 0x9f, 0xe8, + 0x40, 0xe9, 0xb7, 0x2e, 0xc6, 0x71, 0x58, 0x56, + 0x04, 0xac, 0xb0, 0xf3, 0x3a, 0x42, 0x38, 0x08, + 0xc4, 0x43, 0x39, 0xba, 0x19, 0xce, 0xb1, 0x99, + 0xf1, 0x8d, 0x89, 0xd8, 0x50, 0x07, 0x14, 0x3d, + 0xcf, 0xd0, 0xb6, 0x79, 0xde, 0x9c, 0x89, 0x32, + 0xb0, 0x73, 0x3f, 0xed, 0x03, 0x0b, 0xdf, 0x6d, + 0x7e, 0xc9, 0x1c, 0x39, 0xe8, 0x2b, 0x16, 0x09, + 0xbb, 0x5f, 0x99, 0x2f, 0xeb, 0xf3, 0x37, 0x73, + 0x0d, 0x0e, 0xcc, 0x95, 0xad, 0x90, 0x80, 0x03, + 0x1d, 0x80, 0x55, 0x37, 0xa1, 0x2a, 0x71, 0x76, + 0x23, 0x87, 0x8c, 0x9b, 0x41, 0x07, 0xc6, 0x3d, + 0xc6, 0xa3, 0x7d, 0x1b, 0xff, 0x4e, 0x11, 0x19}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha256_signature[] = { + 0x27, 0x35, 0xdd, 0xc4, 0xf8, 0xe2, 0x0b, 0xa3, + 0xef, 0x63, 0x57, 0x3b, 0xe1, 0x58, 0x9a, 0xbc, + 0x20, 0x9c, 0x25, 0x12, 0x01, 0xbf, 0xbb, 0x29, + 0x80, 0x1a, 0xb1, 0x37, 0x9c, 0xcd, 0x67, 0xc7, + 0x0d, 0xf8, 0x64, 0x10, 0x9f, 0xe2, 0xa1, 0x9b, + 0x21, 0x90, 0xcc, 0xda, 0x8b, 0x76, 0x5e, 0x79, + 0x00, 0x9d, 0x58, 0x8b, 0x8a, 0xb3, 0xc3, 0xb5, + 0xf1, 0x54, 0xc5, 0x8c, 0x72, 0xba, 0xde, 0x51, + 0x3c, 0x6b, 0x94, 0xd6, 0xf3, 0x1b, 0xa2, 0x53, + 0xe6, 0x1a, 0x46, 0x1d, 0x7f, 0x14, 0x86, 0xcc, + 0xa6, 0x30, 0x92, 0x96, 0xc0, 0x96, 0x24, 0xf0, + 0x42, 0x53, 0x4c, 0xdd, 0x27, 0xdf, 0x1d, 0x2e, + 0x8b, 0x83, 0xbe, 0xed, 0x85, 0x1d, 0x50, 0x46, + 0xa3, 0x7d, 0x20, 0xea, 0x3e, 0x91, 0xfb, 0xf6, + 0x86, 0x51, 0xfd, 0x8c, 0xe5, 0x31, 0xe6, 0x7e, + 0x60, 0x08, 0x0e, 0xec, 0xa6, 0xea, 0x24, 0x8d}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha384_signature[] = { + 0x0b, 0x03, 0x94, 0x4f, 0x94, 0x78, 0x9b, 0x96, + 0x76, 0xeb, 0x72, 0x58, 0xe1, 0xc5, 0xc7, 0x5f, + 0x85, 0x01, 0xa8, 0xc4, 0xf6, 0x1a, 0xb5, 0x2c, + 0xd1, 0xd8, 0x87, 0xde, 0x3a, 0x9c, 0x9f, 0x57, + 0x81, 0x2a, 0x1e, 0x23, 0x07, 0x70, 0xb0, 0xf9, + 0x28, 0x3d, 0xfa, 0xe5, 0x2e, 0x1b, 0x9a, 0x72, + 0xc3, 0x74, 0xb3, 0x42, 0x1c, 0x9a, 0x13, 0xdc, + 0xc9, 0xd6, 0xd5, 0x88, 0xc9, 0x9c, 0x46, 0xf1, + 0x0c, 0xa6, 0xf7, 0xd8, 0x06, 0xa3, 0x1b, 0xdf, + 0x55, 0xb3, 0x1b, 0x7b, 0x58, 0x1d, 0xff, 0x19, + 0xc7, 0xe0, 0xdd, 0x59, 0xac, 0x2f, 0x78, 0x71, + 0xe7, 0xe0, 0x17, 0xa3, 0x1c, 0x5c, 0x92, 0xef, + 0xb6, 0x75, 0xed, 0xbe, 0x18, 0x39, 0x6b, 0xd7, + 0xc9, 0x08, 0x62, 0x55, 0x62, 0xac, 0x5d, 0xa1, + 0x9b, 0xd5, 0xb8, 0x98, 0x15, 0xc0, 0xf5, 0x41, + 0x85, 0x44, 0x96, 0xca, 0x10, 0xdc, 0x57, 0x21}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha512_signature[] = { + 0xa5, 0xd0, 0x80, 0x04, 0x22, 0xfc, 0x80, 0x73, + 0x7d, 0x46, 0xc8, 0x7b, 0xac, 0x44, 0x7b, 0xe6, + 0x07, 0xe5, 0x61, 0x4c, 0x33, 0x7f, 0x6f, 0x46, + 0x7c, 0x30, 0xe3, 0x75, 0x59, 0x4b, 0x42, 0xf3, + 0x9f, 0x35, 0x3c, 0x10, 0x56, 0xdb, 0xd2, 0x69, + 0x43, 0xcb, 0x77, 0xe9, 0x7d, 0xcd, 0x07, 0x43, + 0xc5, 0xd4, 0x0c, 0x9d, 0xf5, 0x92, 0xbd, 0x0e, + 0x3b, 0xb7, 0x68, 0x88, 0x84, 0xca, 0xae, 0x0d, + 0xab, 0x71, 0x10, 0xad, 0xab, 0x27, 0xe4, 0xa3, + 0x24, 0x41, 0xeb, 0x1c, 0xa6, 0x5f, 0xf1, 0x85, + 0xd0, 0xf6, 0x22, 0x74, 0x3d, 0x81, 0xbe, 0xdd, + 0x1b, 0x2a, 0x4c, 0xd1, 0x6c, 0xb5, 0x6d, 0x7a, + 0xbb, 0x99, 0x69, 0x01, 0xa6, 0xc0, 0x98, 0xfa, + 0x97, 0xa3, 0xd1, 0xb0, 0xdf, 0x09, 0xe3, 0x3d, + 0x88, 0xee, 0x90, 0xf3, 0x10, 0x41, 0x0f, 0x06, + 0x31, 0xe9, 0x60, 0x2d, 0xbf, 0x63, 0x7b, 0xf8}; + + static const RSAPublicKey bl_public_key = { NULL, + { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, + FIPS_RSA_MODULUS_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, + FIPS_RSA_PUBLIC_EXPONENT_LENGTH } }; static const RSAPrivateKey bl_private_key = { NULL, - { FIPS_RSA_TYPE, (unsigned char *)rsa_version, FIPS_RSA_PRIVATE_VERSION_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, FIPS_RSA_MODULUS_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent, FIPS_RSA_PRIVATE_EXPONENT_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0, FIPS_RSA_PRIME0_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1, FIPS_RSA_PRIME1_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0, FIPS_RSA_EXPONENT0_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1, FIPS_RSA_EXPONENT1_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient, FIPS_RSA_COEFFICIENT_LENGTH } + { FIPS_RSA_TYPE, (unsigned char *)rsa_version, + FIPS_RSA_PRIVATE_VERSION_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, + FIPS_RSA_MODULUS_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, + FIPS_RSA_PUBLIC_EXPONENT_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent, + FIPS_RSA_PRIVATE_EXPONENT_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0, + FIPS_RSA_PRIME0_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1, + FIPS_RSA_PRIME1_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0, + FIPS_RSA_EXPONENT0_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1, + FIPS_RSA_EXPONENT1_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient, + FIPS_RSA_COEFFICIENT_LENGTH } }; /* RSA variables. */ @@ -1170,14 +1386,12 @@ sftk_fips_RSA_PowerUpSelfTest( void ) #endif NSSLOWKEYPublicKey * rsa_public_key; NSSLOWKEYPrivateKey * rsa_private_key; - unsigned int rsa_bytes_signed; SECStatus rsa_status; NSSLOWKEYPublicKey low_public_key = { NULL, NSSLOWKEYRSAKey, }; NSSLOWKEYPrivateKey low_private_key = { NULL, NSSLOWKEYRSAKey, }; PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH]; PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH]; - PRUint8 rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH]; /****************************************/ /* Compose RSA Public/Private Key Pair. */ @@ -1216,8 +1430,9 @@ sftk_fips_RSA_PowerUpSelfTest( void ) /**************************************************/ /* Perform RSA Public Key Encryption. */ - rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa, - rsa_computed_ciphertext, rsa_known_plaintext); + rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa, + rsa_computed_ciphertext, + rsa_known_plaintext_msg); if( ( rsa_status != SECSuccess ) || ( PORT_Memcmp( rsa_computed_ciphertext, rsa_known_ciphertext, @@ -1229,44 +1444,40 @@ sftk_fips_RSA_PowerUpSelfTest( void ) /**************************************************/ /* Perform RSA Private Key Decryption. */ - rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa, - rsa_computed_plaintext, rsa_known_ciphertext); + rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa, + rsa_computed_plaintext, + rsa_known_ciphertext); if( ( rsa_status != SECSuccess ) || - ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext, + ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext_msg, FIPS_RSA_DECRYPT_LENGTH ) != 0 ) ) goto rsa_loser; - - /*************************************************/ - /* RSA Single-Round Known Answer Signature Test. */ - /*************************************************/ - - /* Perform RSA signature with the RSA private key. */ - rsa_status = RSA_Sign( rsa_private_key, rsa_computed_signature, - &rsa_bytes_signed, - FIPS_RSA_SIGNATURE_LENGTH, - (unsigned char *)rsa_known_message, - FIPS_RSA_MESSAGE_LENGTH ); - - if( ( rsa_status != SECSuccess ) || - ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) || - ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature, - FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) ) + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA1, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha1_signature); + if( rsa_status != SECSuccess ) goto rsa_loser; + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA256, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha256_signature); + if( rsa_status != SECSuccess ) + goto rsa_loser; - /****************************************************/ - /* RSA Single-Round Known Answer Verification Test. */ - /****************************************************/ - - /* Perform RSA verification with the RSA public key. */ - rsa_status = RSA_CheckSign( rsa_public_key, - rsa_computed_signature, - FIPS_RSA_SIGNATURE_LENGTH, - (unsigned char *)rsa_known_message, - FIPS_RSA_MESSAGE_LENGTH ); + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA384, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha384_signature); + if( rsa_status != SECSuccess ) + goto rsa_loser; + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA512, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha512_signature); if( rsa_status != SECSuccess ) goto rsa_loser; @@ -1276,7 +1487,6 @@ sftk_fips_RSA_PowerUpSelfTest( void ) return( CKR_OK ); - rsa_loser: nsslowkey_DestroyPublicKey( rsa_public_key ); @@ -1285,33 +1495,235 @@ rsa_loser: return( CKR_DEVICE_ERROR ); } +#ifdef NSS_ENABLE_ECC + +static CK_RV +sftk_fips_ECDSA_Test(const PRUint8 *encodedParams, + unsigned int encodedParamsLen, + const PRUint8 *knownSignature, + unsigned int knownSignatureLen) { + + /* ECDSA Known Seed info for curves nistp256 and nistk283 */ + static const PRUint8 ecdsa_Known_Seed[] = { + 0x6a, 0x9b, 0xf6, 0xf7, 0xce, 0xed, 0x79, 0x11, + 0xf0, 0xc7, 0xc8, 0x9a, 0xa5, 0xd1, 0x57, 0xb1, + 0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc, + 0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f}; + + static const PRUint8 msg[] = { + "Firefox and ThunderBird are awesome!"}; + + unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */ + unsigned char sig[2*MAX_ECKEY_LEN]; + SECItem signature, digest; + SECItem encodedparams; + ECParams *ecparams = NULL; + ECPrivateKey *ecdsa_private_key = NULL; + ECPublicKey ecdsa_public_key; + SECStatus ecdsaStatus = SECSuccess; + + /* construct the ECDSA private/public key pair */ + encodedparams.type = siBuffer; + encodedparams.data = (unsigned char *) encodedParams; + encodedparams.len = encodedParamsLen; + + if (EC_DecodeParams(&encodedparams, &ecparams) != SECSuccess) { + return( CKR_DEVICE_ERROR ); + } + + /* Generates a new EC key pair. The private key is a supplied + * random value (in seed) and the public key is the result of + * performing a scalar point multiplication of that value with + * the curve's base point. + */ + ecdsaStatus = EC_NewKeyFromSeed(ecparams, &ecdsa_private_key, + ecdsa_Known_Seed, + sizeof(ecdsa_Known_Seed)); + /* free the ecparams they are no longer needed */ + PORT_FreeArena(ecparams->arena, PR_FALSE); + ecparams = NULL; + if (ecdsaStatus != SECSuccess) { + return ( CKR_DEVICE_ERROR ); + } + + /* construct public key from private key. */ + ecdsaStatus = EC_CopyParams(ecdsa_private_key->ecParams.arena, + &ecdsa_public_key.ecParams, + &ecdsa_private_key->ecParams); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + ecdsa_public_key.publicValue = ecdsa_private_key->publicValue; + + /* validate public key value */ + ecdsaStatus = EC_ValidatePublicKey(&ecdsa_public_key.ecParams, + &ecdsa_public_key.publicValue); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + + /* validate public key value */ + ecdsaStatus = EC_ValidatePublicKey(&ecdsa_private_key->ecParams, + &ecdsa_private_key->publicValue); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + + /***************************************************/ + /* ECDSA Single-Round Known Answer Signature Test. */ + /***************************************************/ + + ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + digest.type = siBuffer; + digest.data = sha1; + digest.len = SHA1_LENGTH; + + memset(sig, 0, sizeof sig); + signature.type = siBuffer; + signature.data = sig; + signature.len = sizeof sig; + + ecdsaStatus = ECDSA_SignDigestWithSeed(ecdsa_private_key, &signature, + &digest, ecdsa_Known_Seed, sizeof ecdsa_Known_Seed); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + + if( ( signature.len != knownSignatureLen ) || + ( PORT_Memcmp( signature.data, knownSignature, + knownSignatureLen ) != 0 ) ) { + ecdsaStatus = SECFailure; + goto loser; + } + + /******************************************************/ + /* ECDSA Single-Round Known Answer Verification Test. */ + /******************************************************/ + + /* Perform ECDSA verification process. */ + ecdsaStatus = ECDSA_VerifyDigest(&ecdsa_public_key, &signature, &digest); + +loser: + /* free the memory for the private key arena*/ + if (ecdsa_private_key != NULL) { + PORT_FreeArena(ecdsa_private_key->ecParams.arena, PR_FALSE); + } + + if (ecdsaStatus != SECSuccess) { + return CKR_DEVICE_ERROR ; + } + return( CKR_OK ); +} + +static CK_RV +sftk_fips_ECDSA_PowerUpSelfTest() { + + /* ECDSA Known curve nistp256 == SEC_OID_SECG_EC_SECP256R1 params */ + static const PRUint8 ecdsa_known_P256_EncodedParams[] = { + 0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03, + 0x01,0x07}; + + static const PRUint8 ecdsa_known_P256_signature[] = { + 0x07,0xb1,0xcb,0x57,0x20,0xa7,0x10,0xd6, + 0x9d,0x37,0x4b,0x1c,0xdc,0x35,0x90,0xff, + 0x1a,0x2d,0x98,0x95,0x1b,0x2f,0xeb,0x7f, + 0xbb,0x81,0xca,0xc0,0x69,0x75,0xea,0xc5, + 0x59,0x6a,0x62,0x49,0x3d,0x50,0xc9,0xe1, + 0x27,0x3b,0xff,0x9b,0x13,0x66,0x67,0xdd, + 0x7d,0xd1,0x0d,0x2d,0x7c,0x44,0x04,0x1b, + 0x16,0x21,0x12,0xc5,0xcb,0xbd,0x9e,0x75}; + +#ifdef NSS_ECC_MORE_THAN_SUITE_B + /* ECDSA Known curve nistk283 == SEC_OID_SECG_EC_SECT283K1 params */ + static const PRUint8 ecdsa_known_K283_EncodedParams[] = { + 0x06,0x05,0x2b,0x81,0x04,0x00,0x10}; + + static const PRUint8 ecdsa_known_K283_signature[] = { + 0x00,0x45,0x88,0xc0,0x79,0x09,0x07,0xd1, + 0x4e,0x88,0xe6,0xd5,0x2f,0x22,0x04,0x74, + 0x35,0x24,0x65,0xe8,0x15,0xde,0x90,0x66, + 0x94,0x70,0xdd,0x3a,0x14,0x70,0x02,0xd1, + 0xef,0x86,0xbd,0x15,0x00,0xd9,0xdc,0xfc, + 0x87,0x2e,0x7c,0x99,0xe2,0xe3,0x79,0xb8, + 0xd9,0x10,0x49,0x78,0x4b,0x59,0x8b,0x05, + 0x77,0xec,0x6c,0xe8,0x35,0xe6,0x2e,0xa9, + 0xf9,0x77,0x1f,0x71,0x86,0xa5,0x4a,0xd0}; +#endif + + CK_RV crv; + + /* ECDSA GF(p) prime field curve test */ + crv = sftk_fips_ECDSA_Test(ecdsa_known_P256_EncodedParams, + sizeof ecdsa_known_P256_EncodedParams, + ecdsa_known_P256_signature, + sizeof ecdsa_known_P256_signature ); + if (crv != CKR_OK) { + return( CKR_DEVICE_ERROR ); + } + +#ifdef NSS_ECC_MORE_THAN_SUITE_B + /* ECDSA GF(2m) binary field curve test */ + crv = sftk_fips_ECDSA_Test(ecdsa_known_K283_EncodedParams, + sizeof ecdsa_known_K283_EncodedParams, + ecdsa_known_K283_signature, + sizeof ecdsa_known_K283_signature ); + if (crv != CKR_OK) { + return( CKR_DEVICE_ERROR ); + } +#endif + + return( CKR_OK ); +} + +#endif /* NSS_ENABLE_ECC */ static CK_RV sftk_fips_DSA_PowerUpSelfTest( void ) { - /* DSA Known P (512-bits), Q (160-bits), and G (512-bits) Values. */ + /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */ static const PRUint8 dsa_P[] = { - 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa, - 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb, - 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, - 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5, - 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf, - 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac, - 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2, - 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91}; + 0x80,0xb0,0xd1,0x9d,0x6e,0xa4,0xf3,0x28, + 0x9f,0x24,0xa9,0x8a,0x49,0xd0,0x0c,0x63, + 0xe8,0x59,0x04,0xf9,0x89,0x4a,0x5e,0xc0, + 0x6d,0xd2,0x67,0x6b,0x37,0x81,0x83,0x0c, + 0xfe,0x3a,0x8a,0xfd,0xa0,0x3b,0x08,0x91, + 0x1c,0xcb,0xb5,0x63,0xb0,0x1c,0x70,0xd0, + 0xae,0xe1,0x60,0x2e,0x12,0xeb,0x54,0xc7, + 0xcf,0xc6,0xcc,0xae,0x97,0x52,0x32,0x63, + 0xd3,0xeb,0x55,0xea,0x2f,0x4c,0xd5,0xd7, + 0x3f,0xda,0xec,0x49,0x27,0x0b,0x14,0x56, + 0xc5,0x09,0xbe,0x4d,0x09,0x15,0x75,0x2b, + 0xa3,0x42,0x0d,0x03,0x71,0xdf,0x0f,0xf4, + 0x0e,0xe9,0x0c,0x46,0x93,0x3d,0x3f,0xa6, + 0x6c,0xdb,0xca,0xe5,0xac,0x96,0xc8,0x64, + 0x5c,0xec,0x4b,0x35,0x65,0xfc,0xfb,0x5a, + 0x1b,0x04,0x1b,0xa1,0x0e,0xfd,0x88,0x15}; + static const PRUint8 dsa_Q[] = { - 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee, - 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e, - 0xda,0xce,0x91,0x5f}; + 0xad,0x22,0x59,0xdf,0xe5,0xec,0x4c,0x6e, + 0xf9,0x43,0xf0,0x4b,0x2d,0x50,0x51,0xc6, + 0x91,0x99,0x8b,0xcf}; + static const PRUint8 dsa_G[] = { - 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13, - 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00, - 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb, - 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e, - 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf, - 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c, - 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c, - 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02}; + 0x78,0x6e,0xa9,0xd8,0xcd,0x4a,0x85,0xa4, + 0x45,0xb6,0x6e,0x5d,0x21,0x50,0x61,0xf6, + 0x5f,0xdf,0x5c,0x7a,0xde,0x0d,0x19,0xd3, + 0xc1,0x3b,0x14,0xcc,0x8e,0xed,0xdb,0x17, + 0xb6,0xca,0xba,0x86,0xa9,0xea,0x51,0x2d, + 0xc1,0xa9,0x16,0xda,0xf8,0x7b,0x59,0x8a, + 0xdf,0xcb,0xa4,0x67,0x00,0x44,0xea,0x24, + 0x73,0xe5,0xcb,0x4b,0xaf,0x2a,0x31,0x25, + 0x22,0x28,0x3f,0x16,0x10,0x82,0xf7,0xeb, + 0x94,0x0d,0xdd,0x09,0x22,0x14,0x08,0x79, + 0xba,0x11,0x0b,0xf1,0xff,0x2d,0x67,0xac, + 0xeb,0xb6,0x55,0x51,0x69,0x97,0xa7,0x25, + 0x6b,0x9c,0xa0,0x9b,0xd5,0x08,0x9b,0x27, + 0x42,0x1c,0x7a,0x69,0x57,0xe6,0x2e,0xed, + 0xa9,0x5b,0x25,0xe8,0x1f,0xd2,0xed,0x1f, + 0xdf,0xe7,0x80,0x17,0xba,0x0d,0x4d,0x38}; /* DSA Known Random Values (known random key block is 160-bits) */ /* and (known random signature block is 160-bits). */ @@ -1325,11 +1737,11 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* DSA Known Signature (320-bits). */ static const PRUint8 dsa_known_signature[] = { - 0x39,0x0d,0x84,0xb1,0xf7,0x52,0x89,0xba, - 0xec,0x1e,0xa8,0xe2,0x00,0x8e,0x37,0x8f, - 0xc2,0xf5,0xf8,0x70,0x11,0xa8,0xc7,0x02, - 0x0e,0x75,0xcf,0x6b,0x54,0x4a,0x52,0xe8, - 0xd8,0x6d,0x4a,0xe8,0xee,0x56,0x8e,0x59}; + 0x25,0x7c,0x3a,0x79,0x32,0x45,0xb7,0x32, + 0x70,0xca,0x62,0x63,0x2b,0xf6,0x29,0x2c, + 0x22,0x2a,0x03,0xce,0x48,0x15,0x11,0x72, + 0x7b,0x7e,0xf5,0x7a,0xf3,0x10,0x3b,0xde, + 0x34,0xc1,0x9e,0xd7,0x27,0x9e,0x77,0x38}; /* DSA variables. */ DSAPrivateKey * dsa_private_key; @@ -1348,12 +1760,11 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /*******************************************/ /* Generate a DSA public/private key pair. */ - dsa_status = DSA_NewKeyFromSeed(&dsa_pqg, dsa_known_random_key_block, &dsa_private_key); if( dsa_status != SECSuccess ) - return( CKR_HOST_MEMORY ); + return( CKR_HOST_MEMORY ); /* construct public key from private key. */ dsa_public_key.params = dsa_private_key->params; @@ -1372,8 +1783,8 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* Perform DSA signature process. */ dsa_status = DSA_SignDigestWithSeed( dsa_private_key, &dsa_signature_item, - &dsa_digest_item, - dsa_known_random_signature_block ); + &dsa_digest_item, + dsa_known_random_signature_block ); if( ( dsa_status != SECSuccess ) || ( dsa_signature_item.len != FIPS_DSA_SIGNATURE_LENGTH ) || @@ -1389,7 +1800,7 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* Perform DSA verification process. */ dsa_status = DSA_VerifyDigest( &dsa_public_key, &dsa_signature_item, - &dsa_digest_item); + &dsa_digest_item); } PORT_FreeArena(dsa_private_key->params.arena, PR_TRUE); @@ -1404,6 +1815,79 @@ sftk_fips_DSA_PowerUpSelfTest( void ) } +static CK_RV +sftk_fips_RNG_PowerUpSelfTest( void ) +{ + static const PRUint8 XKeyValue[] = { + 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa, + 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb, + 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, + 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5}; + static const PRUint8 XSeed[] = { + 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, + 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5, + 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf, + 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac}; + static const PRUint8 Q[] = { + 0x85,0x89,0x9c,0x77,0xa3,0x79,0xff,0x1a, + 0x86,0x6f,0x2f,0x3e,0x2e,0xf9,0x8c,0x9c, + 0x9d,0xef,0xeb,0xed}; + static const PRUint8 rng_known_GENX[] = { + 0x65,0x48,0xe3,0xca,0xac,0x64,0x2d,0xf7, + 0x7b,0xd3,0x4e,0x79,0xc9,0x7d,0xa6,0xa8, + 0xa2,0xc2,0x1f,0x8f,0xe9,0xb9,0xd3,0xa1, + 0x3f,0xf7,0x0c,0xcd,0xa6,0xca,0xbf,0xce, + 0x84,0x0e,0xb6,0xf1,0x0d,0xbe,0xa9,0xa3}; + static const PRUint8 rng_known_DSAX[] = { + 0x7a,0x86,0xf1,0x7f,0xbd,0x4e,0x6e,0xd9, + 0x0a,0x26,0x21,0xd0,0x19,0xcb,0x86,0x73, + 0x10,0x1f,0x60,0xd7}; + + SECStatus rng_status = SECSuccess; + PRUint8 GENX[2*SHA1_LENGTH]; + PRUint8 DSAX[FIPS_DSA_SUBPRIME_LENGTH]; + PRUint8 XKey[FIPS_RNG_XKEY_LENGTH]; + + PORT_Memcpy (XKey, XKeyValue, FIPS_RNG_XKEY_LENGTH); + + /*******************************************/ + /* Generate X with a known seed. */ + /*******************************************/ + rng_status = FIPS186Change_GenerateX(XKey, XSeed, GENX); + + /* Verify GENX to perform the RNG integrity check */ + if( ( rng_status != SECSuccess ) || + ( PORT_Memcmp( GENX, rng_known_GENX, + (2*SHA1_LENGTH) ) != 0 ) ) + return( CKR_DEVICE_ERROR ); + + /*******************************************/ + /* Generate DSAX fow given Q. */ + /*******************************************/ + + rng_status = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX); + + /* Verify DSAX to perform the RNG integrity check */ + if( ( rng_status != SECSuccess ) || + ( PORT_Memcmp( DSAX, rng_known_DSAX, + (FIPS_DSA_SUBPRIME_LENGTH) ) != 0 ) ) + return( CKR_DEVICE_ERROR ); + + return( CKR_OK ); +} + +static CK_RV +sftk_fipsSoftwareIntegrityTest(void) +{ + CK_RV crv = CKR_OK; + + /* make sure that our check file signatures are OK */ + if( !BLAPI_VerifySelf( NULL ) || + !BLAPI_SHVerify( SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_fips_HMAC ) ) { + crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */ + } + return crv; +} CK_RV sftk_fipsPowerUpSelfTest( void ) @@ -1488,6 +1972,26 @@ sftk_fipsPowerUpSelfTest( void ) if( rv != CKR_OK ) return rv; + /* RNG Power-Up SelfTest(s). */ + rv = sftk_fips_RNG_PowerUpSelfTest(); + + if( rv != CKR_OK ) + return rv; + +#ifdef NSS_ENABLE_ECC + /* ECDSA Power-Up SelfTest(s). */ + rv = sftk_fips_ECDSA_PowerUpSelfTest(); + + if( rv != CKR_OK ) + return rv; +#endif + + /* Software/Firmware Integrity Test. */ + rv = sftk_fipsSoftwareIntegrityTest(); + + if( rv != CKR_OK ) + return rv; + /* Passed Power-Up SelfTest(s). */ return( CKR_OK ); } diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c index 9ef144cb8..6cfcfcb05 100644 --- a/security/nss/lib/softoken/fipstokn.c +++ b/security/nss/lib/softoken/fipstokn.c @@ -55,15 +55,77 @@ #include "pcert.h" #include "pkcs11.h" #include "pkcs11i.h" +#include "prenv.h" +#include "prprf.h" #include <ctype.h> +#ifdef XP_UNIX +#define NSS_AUDIT_WITH_SYSLOG 1 +#include <syslog.h> +#include <unistd.h> +#endif + +#ifdef SOLARIS +#include <bsm/libbsm.h> +#define AUE_FIPS_AUDIT 34444 +#endif + +#ifdef LINUX +#include <pthread.h> +#include <dlfcn.h> +#define LIBAUDIT_NAME "libaudit.so.0" +#ifndef AUDIT_USER +#define AUDIT_USER 1005 /* message type: message from userspace */ +#endif +static void *libaudit_handle; +static int (*audit_open_func)(void); +static void (*audit_close_func)(int fd); +static int (*audit_log_user_message_func)(int audit_fd, int type, + const char *message, const char *hostname, const char *addr, + const char *tty, int result); +static int (*audit_send_user_message_func)(int fd, int type, + const char *message); + +static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT; + +static void +libaudit_init(void) +{ + libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY); + if (!libaudit_handle) { + return; + } + audit_open_func = dlsym(libaudit_handle, "audit_open"); + audit_close_func = dlsym(libaudit_handle, "audit_close"); + /* + * audit_send_user_message is the older function. + * audit_log_user_message, if available, is preferred. + */ + audit_log_user_message_func = dlsym(libaudit_handle, + "audit_log_user_message"); + if (!audit_log_user_message_func) { + audit_send_user_message_func = dlsym(libaudit_handle, + "audit_send_user_message"); + } + if (!audit_open_func || !audit_close_func || + (!audit_log_user_message_func && !audit_send_user_message_func)) { + dlclose(libaudit_handle); + libaudit_handle = NULL; + audit_open_func = NULL; + audit_close_func = NULL; + audit_log_user_message_func = NULL; + audit_send_user_message_func = NULL; + } +} +#endif /* LINUX */ + /* * ******************** Password Utilities ******************************* */ static PRBool isLoggedIn = PR_FALSE; -static PRBool fatalError = PR_FALSE; +PRBool sftk_fatalError = PR_FALSE; /* * This function returns @@ -161,10 +223,10 @@ static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { /* FIPS required checks before any useful cryptographic services */ static CK_RV sftk_fipsCheck(void) { - if (isLoggedIn != PR_TRUE) - return CKR_USER_NOT_LOGGED_IN; - if (fatalError) + if (sftk_fatalError) return CKR_DEVICE_ERROR; + if (!isLoggedIn) + return CKR_USER_NOT_LOGGED_IN; return CKR_OK; } @@ -174,7 +236,7 @@ static CK_RV sftk_fipsCheck(void) { if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; #define SFTK_FIPSFATALCHECK() \ - if (fatalError) return CKR_DEVICE_ERROR; + if (sftk_fatalError) return CKR_DEVICE_ERROR; /* grab an attribute out of a raw template */ @@ -233,24 +295,135 @@ static CK_FUNCTION_LIST sftk_fipsTable = { #undef __PASTE +/* CKO_NOT_A_KEY can be any object class that's not a key object. */ +#define CKO_NOT_A_KEY CKO_DATA + +#define SFTK_IS_KEY_OBJECT(objClass) \ + (((objClass) == CKO_PUBLIC_KEY) || \ + ((objClass) == CKO_PRIVATE_KEY) || \ + ((objClass) == CKO_SECRET_KEY)) + +#define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \ + (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY)) + static CK_RV -fips_login_if_key_object(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) +sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass) { CK_RV rv; - CK_OBJECT_CLASS objClass; CK_ATTRIBUTE class; class.type = CKA_CLASS; - class.pValue = &objClass; - class.ulValueLen = sizeof(objClass); + class.pValue = pObjClass; + class.ulValueLen = sizeof(*pObjClass); rv = NSC_GetAttributeValue(hSession, hObject, &class, 1); - if (rv == CKR_OK) { - if ((objClass == CKO_PRIVATE_KEY) || (objClass == CKO_SECRET_KEY)) { - rv = sftk_fipsCheck(); - } + if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) { + rv = sftk_fipsCheck(); } return rv; } +/********************************************************************** + * + * FIPS 140 auditable event logging + * + **********************************************************************/ + +PRBool sftk_audit_enabled = PR_FALSE; + +/* + * Each audit record must have the following information: + * - Date and time of the event + * - Type of event + * - user (subject) identity + * - outcome (success or failure) of the event + * - process ID + * - name (ID) of the object + * - for changes to data (except for authentication data and CSPs), the new + * and old values of the data + * - for authentication attempts, the origin of the attempt (e.g., terminal + * identifier) + * - for assuming a role, the type of role, and the location of the request + */ +void +sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg) +{ +#ifdef NSS_AUDIT_WITH_SYSLOG + int level; + + switch (severity) { + case NSS_AUDIT_ERROR: + level = LOG_ERR; + break; + case NSS_AUDIT_WARNING: + level = LOG_WARNING; + break; + default: + level = LOG_INFO; + break; + } + /* timestamp is provided by syslog in the message header */ + syslog(level | LOG_USER /* facility */, + "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s", + (int)getpid(), (int)getuid(), msg); +#ifdef LINUX + if (pthread_once(&libaudit_once_control, libaudit_init) != 0) { + return; + } + if (libaudit_handle) { + int audit_fd; + int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */ + char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); + if (!message) { + return; + } + audit_fd = audit_open_func(); + if (audit_fd < 0) { + PR_smprintf_free(message); + return; + } + if (audit_log_user_message_func) { + audit_log_user_message_func(audit_fd, AUDIT_USER, message, + NULL, NULL, NULL, result); + } else { + audit_send_user_message_func(audit_fd, AUDIT_USER, message); + } + audit_close_func(audit_fd); + PR_smprintf_free(message); + } +#endif /* LINUX */ +#ifdef SOLARIS + { + int rd; + char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); + + if (!message) { + return; + } + + /* open the record descriptor */ + if ((rd = au_open()) == -1) { + PR_smprintf_free(message); + return; + } + + /* write the audit tokens to the audit record */ + if (au_write(rd, au_to_text(message))) { + (void)au_close(rd, AU_TO_NO_WRITE, AUE_FIPS_AUDIT); + PR_smprintf_free(message); + return; + } + + /* close the record and send it to the audit trail */ + (void)au_close(rd, AU_TO_WRITE, AUE_FIPS_AUDIT); + + PR_smprintf_free(message); + } +#endif /* SOLARIS */ +#else + /* do nothing */ +#endif +} + /********************************************************************** * @@ -268,26 +441,39 @@ PRBool nsf_init = PR_FALSE; /* FC_Initialize initializes the PKCS #11 library. */ CK_RV FC_Initialize(CK_VOID_PTR pReserved) { + const char *envp; CK_RV crv; if (nsf_init) { return CKR_CRYPTOKI_ALREADY_INITIALIZED; } + if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) { + sftk_audit_enabled = (atoi(envp) == 1); + } + crv = nsc_CommonInitialize(pReserved, PR_TRUE); /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/ if (crv != CKR_OK) { - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; return crv; } - fatalError = PR_FALSE; /* any error has been reset */ + sftk_fatalError = PR_FALSE; /* any error has been reset */ crv = sftk_fipsPowerUpSelfTest(); if (crv != CKR_OK) { nsc_CommonFinalize(NULL, PR_TRUE); - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; + if (sftk_audit_enabled) { + char msg[128]; + PR_snprintf(msg,sizeof msg, + "C_Initialize()=0x%08lX " + "power-up self-tests failed", + (PRUint32)crv); + sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg); + } return crv; } nsf_init = PR_TRUE; @@ -321,15 +507,7 @@ CK_RV FC_GetSlotList(CK_BBOOL tokenPresent, /* FC_GetSlotInfo obtains information about a particular slot in the system. */ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { - - CK_RV crv; - - crv = NSC_GetSlotInfo(slotID,pInfo); - if (crv != CKR_OK) { - return crv; - } - - return CKR_OK; + return NSC_GetSlotInfo(slotID,pInfo); } @@ -338,7 +516,8 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV crv; crv = NSC_GetTokenInfo(slotID,pInfo); - pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED; + if (crv == CKR_OK) + pInfo->flags |= CKF_LOGIN_REQUIRED; return crv; } @@ -369,7 +548,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* FC_InitToken initializes a token. */ CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin, CK_ULONG usPinLen,CK_CHAR_PTR pLabel) { - return NSC_InitToken(slotID,pPin,usPinLen,pLabel); + CK_RV crv; + + crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel); + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (crv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + /* pLabel points to a 32-byte label, which is not null-terminated */ + PR_snprintf(msg,sizeof msg, + "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX", + (PRUint32)slotID,pLabel,(PRUint32)crv); + sftk_LogAuditMessage(severity, msg); + } + return crv; } @@ -377,9 +569,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { CK_RV rv; - SFTK_FIPSFATALCHECK(); - if ((rv = sftk_newPinCheck(pPin,ulPinLen)) != CKR_OK) return rv; - return NSC_InitPIN(hSession,pPin,ulPinLen); + if (sftk_fatalError) return CKR_DEVICE_ERROR; + if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) { + rv = NSC_InitPIN(hSession,pPin,ulPinLen); + } + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_InitPIN(hSession=0x%08lX)=0x%08lX", + (PRUint32)hSession,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); + } + return rv; } @@ -388,9 +591,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) { CK_RV rv; - if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; - if ((rv = sftk_newPinCheck(pNewPin,usNewLen)) != CKR_OK) return rv; - return NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen); + if ((rv = sftk_fipsCheck()) == CKR_OK && + (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) { + rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen); + } + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_SetPIN(hSession=0x%08lX)=0x%08lX", + (PRUint32)hSession,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); + } + return rv; } /* FC_OpenSession opens a session between an application and a token. */ @@ -435,30 +649,40 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen) { CK_RV rv; - SFTK_FIPSFATALCHECK(); + PRBool successful; + if (sftk_fatalError) return CKR_DEVICE_ERROR; rv = NSC_Login(hSession,userType,pPin,usPinLen); - if (rv == CKR_OK) + successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); + if (successful) isLoggedIn = PR_TRUE; - else if (rv == CKR_USER_ALREADY_LOGGED_IN) - { - isLoggedIn = PR_TRUE; - - /* Provide FIPS PUB 140-1 power-up self-tests on demand. */ - rv = sftk_fipsPowerUpSelfTest(); - if (rv == CKR_OK) - return CKR_USER_ALREADY_LOGGED_IN; - else - fatalError = PR_TRUE; + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity; + severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX", + (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); } return rv; } /* FC_Logout logs a user out from a token. */ CK_RV FC_Logout(CK_SESSION_HANDLE hSession) { - SFTK_FIPSCHECK(); - - rv = NSC_Logout(hSession); - isLoggedIn = PR_FALSE; + CK_RV rv; + if ((rv = sftk_fipsCheck()) == CKR_OK) { + rv = NSC_Logout(hSession); + isLoggedIn = PR_FALSE; + } + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_Logout(hSession=0x%08lX)=0x%08lX", + (PRUint32)hSession,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); + } return rv; } @@ -473,10 +697,15 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE; /* FIPS can't create keys from raw key material */ - if ((*classptr == CKO_SECRET_KEY) || (*classptr == CKO_PRIVATE_KEY)) { - return CKR_ATTRIBUTE_VALUE_INVALID; + if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) { + rv = CKR_ATTRIBUTE_VALUE_INVALID; + } else { + rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject); } - return NSC_CreateObject(hSession,pTemplate,ulCount,phObject); + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) { + sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv); + } + return rv; } @@ -485,15 +714,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* FC_CopyObject copies an object, creating a new object for the copy. */ CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject); } - return NSC_CopyObject(hSession,hObject,pTemplate,usCount,phNewObject); + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditCopyObject(hSession, + hObject,pTemplate,ulCount,phNewObject,rv); + } + return rv; } @@ -501,51 +735,67 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_DestroyObject(hSession,hObject); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditDestroyObject(hSession,hObject,rv); } - return NSC_DestroyObject(hSession,hObject); + return rv; } /* FC_GetObjectSize gets the size of an object in bytes. */ CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize) { + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_GetObjectSize(hSession, hObject, pulSize); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv); } - return NSC_GetObjectSize(hSession, hObject, pusSize); + return rv; } /* FC_GetAttributeValue obtains the value of one or more object attributes. */ CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) { + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); } - return NSC_GetAttributeValue(hSession,hObject,pTemplate,usCount); + return rv; } /* FC_SetAttributeValue modifies the value of one or more object attributes */ CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) { + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); } - return NSC_SetAttributeValue(hSession,hObject,pTemplate,usCount); + return rv; } @@ -605,7 +855,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_EncryptInit(hSession,pMechanism,hKey); + rv = NSC_EncryptInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv); + } + return rv; } /* FC_Encrypt encrypts single-part data. */ @@ -646,7 +900,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_DecryptInit(hSession,pMechanism,hKey); + rv = NSC_DecryptInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv); + } + return rv; } /* FC_Decrypt decrypts encrypted data in a single part. */ @@ -724,7 +982,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_SignInit(hSession,pMechanism,hKey); + rv = NSC_SignInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -766,7 +1028,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_SignRecoverInit(hSession,pMechanism,hKey); + rv = NSC_SignRecoverInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -789,7 +1055,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_VerifyInit(hSession,pMechanism,hKey); + rv = NSC_VerifyInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -832,7 +1102,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_VerifyRecoverInit(hSession,pMechanism,hKey); + rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -868,7 +1142,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { } } - return NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); + rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); + if (sftk_audit_enabled) { + sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv); + } + return rv; } @@ -898,7 +1176,12 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { usPrivateKeyAttributeCount,phPublicKey,phPrivateKey); if (crv == CKR_GENERAL_ERROR) { /* pairwise consistency check failed. */ - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; + } + if (sftk_audit_enabled) { + sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate, + usPublicKeyAttributeCount,pPrivateKeyTemplate, + usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv); } return crv; } @@ -908,18 +1191,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, - CK_ULONG_PTR pusWrappedKeyLen) { + CK_ULONG_PTR pulWrappedKeyLen) { SFTK_FIPSCHECK(); - return NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, - pusWrappedKeyLen); + rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, + pulWrappedKeyLen); + if (sftk_audit_enabled) { + sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, + pulWrappedKeyLen,rv); + } + return rv; } /* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, - CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_BBOOL *boolptr; @@ -928,21 +1216,26 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* all secret keys must be sensitive, if the upper level code tries to say * otherwise, reject it. */ boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - usAttributeCount, CKA_SENSITIVE); + ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID; } } - return NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, - usWrappedKeyLen,pTemplate,usAttributeCount,phKey); + rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, + ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey); + if (sftk_audit_enabled) { + sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, + ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv); + } + return rv; } /* FC_DeriveKey derives a key from a base key, creating a new key object. */ CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_BBOOL *boolptr; @@ -951,14 +1244,19 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* all secret keys must be sensitive, if the upper level code tries to say * otherwise, reject it. */ boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - usAttributeCount, CKA_SENSITIVE); + ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID; } } - return NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, - usAttributeCount, phKey); + rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, + ulAttributeCount, phKey); + if (sftk_audit_enabled) { + sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate, + ulAttributeCount,phKey,rv); + } + return rv; } /* @@ -974,7 +1272,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { SFTK_FIPSFATALCHECK(); crv = NSC_SeedRandom(hSession,pSeed,usSeedLen); if (crv != CKR_OK) { - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; } return crv; } @@ -982,13 +1280,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* FC_GenerateRandom generates random data. */ CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen) { + CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) { CK_RV crv; SFTK_FIPSFATALCHECK(); - crv = NSC_GenerateRandom(hSession,pRandomData,usRandomLen); + crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen); if (crv != CKR_OK) { - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; + if (sftk_audit_enabled) { + char msg[128]; + PR_snprintf(msg,sizeof msg, + "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, " + "ulRandomLen=%lu)=0x%08lX " + "self-test: continuous RNG test failed", + (PRUint32)hSession,pRandomData, + (PRUint32)ulRandomLen,(PRUint32)crv); + sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg); + } } return crv; } @@ -1091,7 +1399,11 @@ CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, */ CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_DigestKey(hSession,hKey); + rv = NSC_DigestKey(hSession,hKey); + if (sftk_audit_enabled) { + sftk_AuditDigestKey(hSession,hKey,rv); + } + return rv; } diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c index 2f685a5a6..df17f7f4b 100644 --- a/security/nss/lib/softoken/keydb.c +++ b/security/nss/lib/softoken/keydb.c @@ -52,12 +52,8 @@ #include "nsslocks.h" #include "keydbi.h" +#include "softoken.h" -#ifdef NSS_ENABLE_ECC -extern SECStatus EC_FillParams(PRArenaPool *arena, - const SECItem *encodedParams, - ECParams *params); -#endif /* * Record keys for keydb @@ -584,13 +580,18 @@ makeGlobalSalt(NSSLOWKEYDBHandle *handle) DBT saltData; unsigned char saltbuf[16]; int status; + SECStatus rv; saltKey.data = SALT_STRING; saltKey.size = sizeof(SALT_STRING) - 1; saltData.data = (void *)saltbuf; saltData.size = sizeof(saltbuf); - RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf)); + rv = RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf)); + if ( rv != SECSuccess ) { + sftk_fatalError = PR_TRUE; + return(rv); + } /* put global salt into the database now */ status = keydb_Put(handle, &saltKey, &saltData, 0); @@ -717,7 +718,6 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle) DBT key; DBT data; unsigned char version; - SECItem *rc4key = NULL; NSSLOWKEYDBKey *dbkey = NULL; NSSLOWKEYDBHandle *update = NULL; SECItem *oldSalt = NULL; @@ -886,10 +886,6 @@ done: nsslowkey_CloseKeyDB(update); - if ( rc4key ) { - SECITEM_FreeItem(rc4key, PR_TRUE); - } - if ( oldSalt ) { SECITEM_FreeItem(oldSalt, PR_TRUE); } @@ -942,7 +938,7 @@ openNewDB(const char *appName, const char *prefix, const char *dbname, * local database we can update from. */ if (appName) { - NSSLOWKEYDBHandle *updateHandle = nsslowkey_NewHandle(updatedb); + NSSLOWKEYDBHandle *updateHandle; updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 ); if (!updatedb) { goto noupdate; @@ -1429,50 +1425,6 @@ nsslowkey_DeriveKeyDBPassword(NSSLOWKEYDBHandle *keydb, char *pw) return nsslowkey_HashPassword(pw, keydb->global_salt); } -#if 0 -/* Appears obsolete - TNH */ -/* get the algorithm with which a private key - * is encrypted. - */ -SECOidTag -seckey_get_private_key_algorithm(NSSLOWKEYDBHandle *keydb, DBT *index) -{ - NSSLOWKEYDBKey *dbkey = NULL; - SECOidTag algorithm = SEC_OID_UNKNOWN; - NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL; - PLArenaPool *poolp = NULL; - SECStatus rv; - - poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if(poolp == NULL) - return (SECOidTag)SECFailure; /* TNH - this is bad */ - - dbkey = get_dbkey(keydb, index); - if(dbkey == NULL) - return (SECOidTag)SECFailure; - - epki = (NSSLOWKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(poolp, - sizeof(NSSLOWKEYEncryptedPrivateKeyInfo)); - if(epki == NULL) - goto loser; - rv = SEC_ASN1DecodeItem(poolp, epki, - nsslowkey_EncryptedPrivateKeyInfoTemplate, &dbkey->derPK); - if(rv == SECFailure) - goto loser; - - algorithm = SECOID_GetAlgorithmTag(&epki->algorithm); - - /* let success fall through */ -loser: - if(poolp != NULL) - PORT_FreeArena(poolp, PR_TRUE);\ - if(dbkey != NULL) - sec_destroy_dbkey(dbkey); - - return algorithm; -} -#endif - /* * Derive an RC4 key from a password key and a salt. This * was the method to used to encrypt keys in the version 2? @@ -1531,11 +1483,12 @@ seckey_create_rc4_salt(void) if(salt->data != NULL) { salt->len = SALT_LENGTH; - RNG_GenerateGlobalRandomBytes(salt->data, salt->len); - rv = SECSuccess; + rv = RNG_GenerateGlobalRandomBytes(salt->data, salt->len); + if(rv != SECSuccess) + sftk_fatalError = PR_TRUE; } - if(rv == SECFailure) + if(rv != SECSuccess) { SECITEM_FreeItem(salt, PR_TRUE); salt = NULL; @@ -1816,7 +1769,7 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, { NSSLOWKEYDBKey *dbkey = NULL; NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL; - PLArenaPool *temparena = NULL, *permarena = NULL; + PLArenaPool *arena = NULL; SECItem *dummy = NULL; SECItem *salt = NULL; SECStatus rv = SECFailure; @@ -1825,14 +1778,14 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, (pk == NULL)) return SECFailure; - permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if(permarena == NULL) + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if(arena == NULL) return SECFailure; - dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(permarena, sizeof(NSSLOWKEYDBKey)); + dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey)); if(dbkey == NULL) goto loser; - dbkey->arena = permarena; + dbkey->arena = arena; dbkey->nickname = nickname; /* TNH - for RC4, the salt should be created here */ @@ -1840,15 +1793,14 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm, &salt); if(epki == NULL) goto loser; - temparena = epki->arena; if(salt != NULL) { - rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt); + rv = SECITEM_CopyItem(arena, &(dbkey->salt), salt); SECITEM_ZfreeItem(salt, PR_TRUE); } - dummy = SEC_ASN1EncodeItem(permarena, &(dbkey->derPK), epki, + dummy = SEC_ASN1EncodeItem(arena, &(dbkey->derPK), epki, nsslowkey_EncryptedPrivateKeyInfoTemplate); if(dummy == NULL) rv = SECFailure; @@ -1857,11 +1809,10 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, /* let success fall through */ loser: - if(rv != SECSuccess) - if(permarena != NULL) - PORT_FreeArena(permarena, PR_TRUE); - if(temparena != NULL) - PORT_FreeArena(temparena, PR_TRUE); + if(arena != NULL) + PORT_FreeArena(arena, PR_TRUE); + if(epki != NULL) + PORT_FreeArena(epki->arena, PR_TRUE); return rv; } @@ -2046,6 +1997,9 @@ seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki, rv = EC_FillParams(permarena, &pk->u.ec.ecParams.DEREncoding, &pk->u.ec.ecParams); + if (rv != SECSuccess) + goto loser; + /* * NOTE: Encoding of the publicValue is optional * so we need to be able to regenerate the publicValue diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c index cb048307d..008687e52 100644 --- a/security/nss/lib/softoken/lowcert.c +++ b/security/nss/lib/softoken/lowcert.c @@ -51,12 +51,8 @@ #include "secasn1.h" #include "secoid.h" #include "secerr.h" +#include "softoken.h" -#ifdef NSS_ENABLE_ECC -extern SECStatus EC_FillParams(PRArenaPool *arena, - const SECItem *encodedParams, - ECParams *params); -#endif static const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) }, diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c index fb6e30fdc..9c984b4d3 100644 --- a/security/nss/lib/softoken/lowkey.c +++ b/security/nss/lib/softoken/lowkey.c @@ -295,7 +295,6 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) if (rv == SECSuccess) return pubk; } - nsslowkey_DestroyPublicKey (pubk); } else { PORT_SetError (SEC_ERROR_NO_MEMORY); } diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c index 81a0cb06b..6b4605b4e 100644 --- a/security/nss/lib/softoken/lowpbe.c +++ b/security/nss/lib/softoken/lowpbe.c @@ -546,13 +546,15 @@ loser: PORT_FreeArena(arena, PR_TRUE); } - /* if i != c, then we didn't complete the loop above and must of failed - * somwhere along the way */ - if (i != c) { - SECITEM_ZfreeItem(A,PR_TRUE); - A = NULL; - } else { - A->len = bytesNeeded; + if (A) { + /* if i != c, then we didn't complete the loop above and must of failed + * somwhere along the way */ + if (i != c) { + SECITEM_ZfreeItem(A,PR_TRUE); + A = NULL; + } else { + A->len = bytesNeeded; + } } return A; @@ -634,7 +636,7 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PORT_Memcpy(key->data, hash->data, key->len); } - SECITEM_FreeItem(hash, PR_TRUE); + SECITEM_ZfreeItem(hash, PR_TRUE); return key; loser: @@ -822,7 +824,7 @@ void nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param) { if (pbe_param != NULL) { - PORT_FreeArena(pbe_param->poolp, PR_TRUE); + PORT_FreeArena(pbe_param->poolp, PR_FALSE); } } diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn index 52d1f75cd..983d66887 100644 --- a/security/nss/lib/softoken/manifest.mn +++ b/security/nss/lib/softoken/manifest.mn @@ -59,12 +59,18 @@ EXPORTS = \ PRIVATE_EXPORTS = \ pk11pars.h \ pkcs11ni.h \ + lowkeyi.h \ + lowkeyti.h \ + pcertt.h \ + softoken.h \ + softoknt.h \ $(NULL) CSRCS = \ dbinit.c \ dbmshim.c \ ecdecode.c \ + fipsaudt.c \ fipstest.c \ fipstokn.c \ keydb.c \ diff --git a/security/nss/lib/softoken/nss.h b/security/nss/lib/softoken/nss.h new file mode 100644 index 000000000..d0f72fb07 --- /dev/null +++ b/security/nss/lib/softoken/nss.h @@ -0,0 +1,253 @@ +/*********************************************************************** + * + * A copy of nss.h from NSS 3.11.4 for the directories that make up the + * NSS cryptographic module (lib/freebl and lib/softoken). + * + * When compiling in these directories, the compiler uses the local copy + * of nss.h, allowing the NSS cryptographic module to stay at version + * 3.11.4 (the version submitted to NIST for FIPS 140-2 validation). + * + * DO NOT CHANGE THIS FILE. + * + ***********************************************************************/ +/* + * NSS utility functions + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +/* $Id$ */ + +#ifndef __nss_h_ +#define __nss_h_ + +#include "seccomon.h" + +SEC_BEGIN_PROTOS + +/* + * NSS's major version, minor version, patch level, and whether + * this is a beta release. + * + * The format of the version string should be + * "<major version>.<minor version>[.<patch level>] [<Beta>]" + */ +/* ***** DO NOT CHANGE THIS FILE. ***** */ +#ifdef NSS_ENABLE_ECC +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#define NSS_VERSION "3.11.4 Extended ECC" +#else +#define NSS_VERSION "3.11.4 Basic ECC" +#endif +#else +#define NSS_VERSION "3.11.4" +#endif +#define NSS_VMAJOR 3 +#define NSS_VMINOR 11 +#define NSS_VPATCH 4 +#define NSS_BETA PR_FALSE + +/* + * Return a boolean that indicates whether the underlying library + * will perform as the caller expects. + * + * The only argument is a string, which should be the verson + * identifier of the NSS library. That string will be compared + * against a string that represents the actual build version of + * the NSS library. It also invokes the version checking functions + * of the dependent libraries such as NSPR. + */ +extern PRBool NSS_VersionCheck(const char *importedVersion); + +/* + * Open the Cert, Key, and Security Module databases, read only. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_Init(const char *configdir); + +/* + * Returns whether NSS has already been initialized or not. + */ +extern PRBool NSS_IsInitialized(void); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_InitReadWrite(const char *configdir); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + * + * This allows using application defined prefixes for the cert and key db's + * and an alternate name for the secmod database. NOTE: In future releases, + * the database prefixes my not necessarily map to database names. + * + * configdir - base directory where all the cert, key, and module datbases live. + * certPrefix - prefix added to the beginning of the cert database example: " + * "https-server1-" + * keyPrefix - prefix added to the beginning of the key database example: " + * "https-server1-" + * secmodName - name of the security module database (usually "secmod.db"). + * flags - change the open options of NSS_Initialize as follows: + * NSS_INIT_READONLY - Open the databases read only. + * NSS_INIT_NOCERTDB - Don't open the cert DB and key DB's, just + * initialize the volatile certdb. + * NSS_INIT_NOMODDB - Don't open the security module DB, just + * initialize the PKCS #11 module. + * NSS_INIT_FORCEOPEN - Continue to force initializations even if the + * databases cannot be opened. + * NSS_INIT_NOROOTINIT - Don't try to look for the root certs module + * automatically. + * NSS_INIT_OPTIMIZESPACE - Use smaller tables and caches. + * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are + * thread-safe, ie. that support locking - either OS + * locking or NSS-provided locks . If a PKCS#11 + * module isn't thread-safe, don't serialize its + * calls; just don't load it instead. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example the Java SunPKCS11 provider. + * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED + * error when loading PKCS#11 modules. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example Java SunPKCS11 provider. + * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any + * PKCS#11 module. This may be necessary in order to + * ensure continuous operation and proper shutdown + * sequence if another piece of code is using the same + * PKCS#11 modules that NSS is accessing without going + * through NSS, for example Java SunPKCS11 provider. + * The following limitation applies when this is set : + * SECMOD_WaitForAnyTokenEvent will not use + * C_WaitForSlotEvent, in order to prevent the need for + * C_Finalize. This call will be emulated instead. + * NSS_INIT_RESERVED - Currently has no effect, but may be used in the + * future to trigger better cooperation between PKCS#11 + * modules used by both NSS and the Java SunPKCS11 + * provider. This should occur after a new flag is defined + * for C_Initialize by the PKCS#11 working group. + * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that + * use both NSS and the Java SunPKCS11 provider. + * + * Also NOTE: This is not the recommended method for initializing NSS. + * The prefered method is NSS_init(). + */ +#define NSS_INIT_READONLY 0x1 +#define NSS_INIT_NOCERTDB 0x2 +#define NSS_INIT_NOMODDB 0x4 +#define NSS_INIT_FORCEOPEN 0x8 +#define NSS_INIT_NOROOTINIT 0x10 +#define NSS_INIT_OPTIMIZESPACE 0x20 +#define NSS_INIT_PK11THREADSAFE 0x40 +#define NSS_INIT_PK11RELOAD 0x80 +#define NSS_INIT_NOPK11FINALIZE 0x100 +#define NSS_INIT_RESERVED 0x200 + +#define NSS_INIT_COOPERATE NSS_INIT_PK11THREADSAFE | \ + NSS_INIT_PK11RELOAD | \ + NSS_INIT_NOPK11FINALIZE | \ + NSS_INIT_RESERVED + +#ifdef macintosh +#define SECMOD_DB "Security Modules" +#else +#define SECMOD_DB "secmod.db" +#endif + +extern SECStatus NSS_Initialize(const char *configdir, + const char *certPrefix, const char *keyPrefix, + const char *secmodName, PRUint32 flags); + +/* + * initialize NSS without a creating cert db's, key db's, or secmod db's. + */ +SECStatus NSS_NoDB_Init(const char *configdir); + +/* + * Allow applications and libraries to register with NSS so that they are called + * when NSS shuts down. + * + * void *appData application specific data passed in by the application at + * NSS_RegisterShutdown() time. + * void *nssData is NULL in this release, but is reserved for future versions of + * NSS to pass some future status information * back to the shutdown function. + * + * If the shutdown function returns SECFailure, + * Shutdown will still complete, but NSS_Shutdown() will return SECFailure. + */ +typedef SECStatus (*NSS_ShutdownFunc)(void *appData, void *nssData); + +/* + * Register a shutdown function. + */ +SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Remove an existing shutdown function (you may do this if your library is + * complete and going away, but NSS is still running). + */ +SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Close the Cert, Key databases. + */ +extern SECStatus NSS_Shutdown(void); + +/* + * set the PKCS #11 strings for the internal token. + */ +void PK11_ConfigurePKCS11(const char *man, const char *libdes, + const char *tokdes, const char *ptokdes, const char *slotdes, + const char *pslotdes, const char *fslotdes, const char *fpslotdes, + int minPwd, int pwRequired); + +/* + * Dump the contents of the certificate cache and the temporary cert store. + * Use to detect leaked references of certs at shutdown time. + */ +void nss_DumpCertificateCacheInfo(void); + +SEC_END_PROTOS + +#endif /* __nss_h_ */ diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h index a808373d8..d4314f634 100644 --- a/security/nss/lib/softoken/pcert.h +++ b/security/nss/lib/softoken/pcert.h @@ -41,9 +41,16 @@ #include "prlong.h" #include "pcertt.h" +#include "lowkeyti.h" /* for struct NSSLOWKEYPublicKeyStr */ + SEC_BEGIN_PROTOS /* + * initialize any global certificate locks + */ +SECStatus nsslowcert_InitLocks(void); + +/* ** Add a DER encoded certificate to the permanent database. ** "derCert" is the DER encoded certificate. ** "nickname" is the nickname to use for the cert @@ -244,6 +251,11 @@ pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space, int spaceLen); NSSLOWCERTCertificate * nsslowcert_CreateCert(void); + +certDBEntry * +nsslowcert_DecodeAnyDBEntry(SECItem *dbData, SECItem *dbKey, + certDBEntryType entryType, void *pdata); + SEC_END_PROTOS #endif /* _PCERTDB_H_ */ diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c index 4a7706378..3c9959a30 100644 --- a/security/nss/lib/softoken/pcertdb.c +++ b/security/nss/lib/softoken/pcertdb.c @@ -91,6 +91,9 @@ static int entryListCount = 0; * a global lock to make the database thread safe. */ static PZLock *dbLock = NULL; +static PZLock *certRefCountLock = NULL; +static PZLock *certTrustLock = NULL; +static PZLock *freeListLock = NULL; void certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle) @@ -99,8 +102,31 @@ certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle) nss_InitLock(&dbLock, nssILockCertDB); PORT_Assert(dbLock != NULL); } +} - return; +SECStatus +nsslowcert_InitLocks(void) +{ + if (freeListLock == NULL) { + nss_InitLock(&freeListLock, nssILockRefLock); + if (freeListLock == NULL) { + return SECFailure; + } + } + if (certRefCountLock == NULL) { + nss_InitLock(&certRefCountLock, nssILockRefLock); + if (certRefCountLock == NULL) { + return SECFailure; + } + } + if (certTrustLock == NULL ) { + nss_InitLock(&certTrustLock, nssILockCertDB); + if (certTrustLock == NULL) { + return SECFailure; + } + } + + return SECSuccess; } /* @@ -133,7 +159,6 @@ nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle) return; } -static PZLock *certRefCountLock = NULL; /* * Acquire the cert reference count lock @@ -144,10 +169,7 @@ static PZLock *certRefCountLock = NULL; static void nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert) { - if ( certRefCountLock == NULL ) { - nss_InitLock(&certRefCountLock, nssILockRefLock); - PORT_Assert(certRefCountLock != NULL); - } + PORT_Assert(certRefCountLock != NULL); PZ_Lock(certRefCountLock); return; @@ -170,8 +192,6 @@ nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert) return; } -static PZLock *certTrustLock = NULL; - /* * Acquire the cert trust lock * There is currently one global lock for all certs, but I'm putting a cert @@ -181,11 +201,8 @@ static PZLock *certTrustLock = NULL; void nsslowcert_LockCertTrust(NSSLOWCERTCertificate *cert) { - if ( certTrustLock == NULL ) { - nss_InitLock(&certTrustLock, nssILockCertDB); - PORT_Assert(certTrustLock != NULL); - } - + PORT_Assert(certTrustLock != NULL); + PZ_Lock(certTrustLock); return; } @@ -207,7 +224,6 @@ nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert) return; } -static PZLock *freeListLock = NULL; /* * Acquire the cert reference count lock @@ -218,10 +234,7 @@ static PZLock *freeListLock = NULL; static void nsslowcert_LockFreeList(void) { - if ( freeListLock == NULL ) { - nss_InitLock(&freeListLock, nssILockRefLock); - PORT_Assert(freeListLock != NULL); - } + PORT_Assert(freeListLock != NULL); PZ_Lock(freeListLock); return; @@ -825,8 +838,7 @@ NewDBCertEntry(SECItem *derCert, char *nickname, goto loser; } - entry = (certDBEntryCert *)PORT_ArenaZAlloc(arena, sizeof(certDBEntryCert)); - + entry = PORT_ArenaZNew(arena, certDBEntryCert); if ( entry == NULL ) { goto loser; } @@ -917,21 +929,6 @@ DecodeV4DBCertEntry(unsigned char *buf, int len) goto loser; } - entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen); - if ( !entry->derCert.data ) { - goto loser; - } - entry->derCert.len = certlen; - - if ( nnlen ) { - entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen); - if ( !entry->nickname ) { - goto loser; - } - } else { - entry->nickname = 0; - } - entry->common.arena = arena; entry->common.version = CERT_DB_FILE_VERSION; entry->common.type = certDBEntryTypeCert; @@ -940,11 +937,25 @@ DecodeV4DBCertEntry(unsigned char *buf, int len) entry->trust.emailFlags = buf[1]; entry->trust.objectSigningFlags = buf[2]; + entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen); + if ( !entry->derCert.data ) { + goto loser; + } + entry->derCert.len = certlen; PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen); - PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen); - if (PORT_Strcmp(entry->nickname,"Server-Cert") == 0) { - entry->trust.sslFlags |= CERTDB_USER; + if ( nnlen ) { + entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen); + if ( !entry->nickname ) { + goto loser; + } + PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen); + + if (PORT_Strcmp(entry->nickname, "Server-Cert") == 0) { + entry->trust.sslFlags |= CERTDB_USER; + } + } else { + entry->nickname = 0; } return(entry); @@ -1056,7 +1067,7 @@ CreateCertEntry(void) return entry; } - return PORT_ZAlloc(sizeof(certDBEntryCert)); + return PORT_ZNew(certDBEntryCert); } static void @@ -1121,9 +1132,8 @@ loser: pkcs11_freeStaticData(dbkey.data,buf); dbkey.data = NULL; if ( entry ) { - + DestroyDBEntry((certDBEntry *)entry); } - DestroyDBEntry((certDBEntry *)entry); return(NULL); } @@ -1245,9 +1255,7 @@ NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags) goto loser; } - entry = (certDBEntryRevocation*) - PORT_ArenaZAlloc(arena, sizeof(certDBEntryRevocation)); - + entry = PORT_ArenaZNew(arena, certDBEntryRevocation); if ( entry == NULL ) { goto loser; } @@ -1457,7 +1465,6 @@ EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena, dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } @@ -2706,36 +2713,37 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle, entry = ReadDBSubjectEntry(dbhandle,derSubject); if (entry == NULL) { - goto loser; + rv = SECFailure; + goto done; } - if ( entry->emailAddrs ) { - for (i=0; i < (int)(entry->nemailAddrs); i++) { - if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) { - index = i; - } + for (i=0; i < (int)(entry->nemailAddrs); i++) { + if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) { + index = i; } } - if (updateType == nsslowcert_remove) { if (index == -1) { - return SECSuccess; + rv = SECSuccess; + goto done; } - entry->nemailAddrs--; for (i=index; i < (int)(entry->nemailAddrs); i++) { entry->emailAddrs[i] = entry->emailAddrs[i+1]; } } else { char **newAddrs = NULL; + if (index != -1) { - return SECSuccess; + rv = SECSuccess; + goto done; } newAddrs = (char **)PORT_ArenaAlloc(entry->common.arena, (entry->nemailAddrs+1)* sizeof(char *)); if (!newAddrs) { - goto loser; + rv = SECFailure; + goto done; } for (i=0; i < (int)(entry->nemailAddrs); i++) { newAddrs[i] = entry->emailAddrs[i]; @@ -2743,7 +2751,8 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle, newAddrs[entry->nemailAddrs] = PORT_ArenaStrdup(entry->common.arena,emailAddr); if (!newAddrs[entry->nemailAddrs]) { - goto loser; + rv = SECFailure; + goto done; } entry->emailAddrs = newAddrs; entry->nemailAddrs++; @@ -2754,18 +2763,11 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle, /* write the new one */ rv = WriteDBSubjectEntry(dbhandle, entry); - if ( rv != SECSuccess ) { - goto loser; - } - - DestroyDBEntry((certDBEntry *)entry); - if (emailAddr) PORT_Free(emailAddr); - return(SECSuccess); -loser: + done: if (entry) DestroyDBEntry((certDBEntry *)entry); if (emailAddr) PORT_Free(emailAddr); - return(SECFailure); + return rv; } /* @@ -2794,8 +2796,7 @@ AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle, goto loser; } - entry->nickname = (nickname) ? - PORT_ArenaStrdup(entry->common.arena, nickname) : NULL; + entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname); if ( entry->nickname == NULL ) { goto loser; @@ -2876,8 +2877,7 @@ ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle) goto loser; } - entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryVersion)); + entry = PORT_ArenaZNew(arena, certDBEntryVersion); if ( entry == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; @@ -3070,6 +3070,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert, } if ( nsslowcert_IsNewer(cert, cmpcert) ) { + nsslowcert_DestroyCertificate(cmpcert); /* insert before cmpcert */ rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i], &cert->certKey); @@ -3097,6 +3098,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert, added = PR_TRUE; break; } + nsslowcert_DestroyCertificate(cmpcert); /* copy this cert entry */ newCertKeys[new_i] = entry->certKeys[i]; newKeyIDs[new_i] = entry->keyIDs[i]; @@ -3849,6 +3851,8 @@ UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb) updatehandle.permCertDB = updatedb; updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB); + updatehandle.dbVerify = 0; + updatehandle.ref = 1; /* prevent premature close */ rv = nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback, (void *)handle); @@ -4298,7 +4302,8 @@ nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle, keybuf = (unsigned char *)key.data; keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN]; keyitem.type = siBuffer; - + /* type should equal keybuf[0]. */ + rv = (* callback)(&dataitem, &keyitem, type, udata); if ( rv != SECSuccess ) { return(rv); @@ -4352,7 +4357,7 @@ CreateTrust(void) return trust; } - return PORT_ZAlloc(sizeof(NSSLOWCERTTrust)); + return PORT_ZNew(NSSLOWCERTTrust); } static void @@ -5079,7 +5084,7 @@ nsslowcert_CreateCert(void) if (cert) { return cert; } - return (NSSLOWCERTCertificate *) PORT_ZAlloc(sizeof(NSSLOWCERTCertificate)); + return PORT_ZNew(NSSLOWCERTCertificate); } static void @@ -5106,6 +5111,9 @@ nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust) if ( entry ) { DestroyDBEntry((certDBEntry *)entry); } + if (trust->dbhandle) { + sftk_freeCertDB(trust->dbhandle); + } pkcs11_freeStaticData(trust->dbKey.data,trust->dbKeySpace); PORT_Memset(trust, 0, sizeof(*trust)); @@ -5338,9 +5346,6 @@ nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr, return(rv); } -/* If the freeListLock doesn't exist when this function is called, -** this function will create it, use it 3 times, and delete it. -*/ void nsslowcert_DestroyFreeLists(void) { @@ -5368,3 +5373,77 @@ nsslowcert_DestroyGlobalLocks(void) } } +certDBEntry * +nsslowcert_DecodeAnyDBEntry(SECItem *dbData, SECItem *dbKey, + certDBEntryType entryType, void *pdata) +{ + PLArenaPool *arena = NULL; + certDBEntry *entry; + SECStatus rv; + SECItem dbEntry; + + + if ((dbData->len < SEC_DB_ENTRY_HEADER_LEN) || (dbKey->len == 0)) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto loser; + } + dbEntry.data = &dbData->data[SEC_DB_ENTRY_HEADER_LEN]; + dbEntry.len = dbData->len - SEC_DB_ENTRY_HEADER_LEN; + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) { + goto loser; + } + entry = PORT_ArenaZNew(arena, certDBEntry); + if (!entry) + goto loser; + + entry->common.version = (unsigned int)dbData->data[0]; + entry->common.flags = (unsigned int)dbData->data[2]; + entry->common.type = entryType; + entry->common.arena = arena; + + switch (entryType) { + case certDBEntryTypeContentVersion: /* This type appears to be unused */ + case certDBEntryTypeVersion: /* This type has only the common hdr */ + rv = SECSuccess; + break; + + case certDBEntryTypeSubject: + rv = DecodeDBSubjectEntry(&entry->subject, &dbEntry, dbKey); + break; + + case certDBEntryTypeNickname: + rv = DecodeDBNicknameEntry(&entry->nickname, &dbEntry, + (char *)dbKey->data); + break; + + /* smime profiles need entries created after the certs have + * been imported, loop over them in a second run */ + case certDBEntryTypeSMimeProfile: + rv = DecodeDBSMimeEntry(&entry->smime, &dbEntry, (char *)dbKey->data); + break; + + case certDBEntryTypeCert: + rv = DecodeDBCertEntry(&entry->cert, &dbEntry); + break; + + case certDBEntryTypeKeyRevocation: + case certDBEntryTypeRevocation: + rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry); + break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; + } + + if (rv == SECSuccess) + return entry; + +loser: + if (arena) + PORT_FreeArena(arena, PR_FALSE); + return NULL; +} + diff --git a/security/nss/lib/softoken/pcertt.h b/security/nss/lib/softoken/pcertt.h index e805950e1..848fe69e9 100644 --- a/security/nss/lib/softoken/pcertt.h +++ b/security/nss/lib/softoken/pcertt.h @@ -410,12 +410,14 @@ typedef struct { #define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY) typedef union { - certDBEntryCommon common; - certDBEntryVersion version; - certDBEntryCert cert; - certDBEntryNickname nickname; - certDBEntrySubject subject; - certDBEntryRevocation revocation; + certDBEntryCommon common; + certDBEntryCert cert; + certDBEntryContentVersion content; + certDBEntryNickname nickname; + certDBEntryRevocation revocation; + certDBEntrySMime smime; + certDBEntrySubject subject; + certDBEntryVersion version; } certDBEntry; /* length of the fixed part of a database entry */ diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c index c60e87780..30584c91e 100644 --- a/security/nss/lib/softoken/pk11db.c +++ b/security/nss/lib/softoken/pk11db.c @@ -868,7 +868,7 @@ secmod_ReadPermDB(const char *appName, const char *filename, DBT key,data; int ret; DB *pkcs11db = NULL; - char **moduleList = NULL; + char **moduleList = NULL, **newModuleList = NULL; int moduleCount = 1; int useCount = SECMOD_STEP; @@ -888,9 +888,10 @@ secmod_ReadPermDB(const char *appName, const char *filename, PRBool internal = PR_FALSE; if ((moduleCount+1) >= useCount) { useCount += SECMOD_STEP; - moduleList = + newModuleList = (char **)PORT_Realloc(moduleList,useCount*sizeof(char *)); - if (moduleList == NULL) goto done; + if (newModuleList == NULL) goto done; + moduleList = newModuleList; PORT_Memset(&moduleList[moduleCount+1],0, sizeof(char *)*SECMOD_STEP); } diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 10a7bcfb7..f913735a4 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -67,9 +67,8 @@ #include "keydbi.h" -#ifdef NSS_ENABLE_ECC -extern SECStatus EC_FillParams(PRArenaPool *arena, - const SECItem *encodedParams, ECParams *params); +#ifdef DEBUG +#include "cdbhdl.h" #endif /* @@ -77,7 +76,7 @@ extern SECStatus EC_FillParams(PRArenaPool *arena, */ /* The next three strings must be exactly 32 characters long */ -static char *manufacturerID = "mozilla.org "; +static char *manufacturerID = "Mozilla Foundation "; static char manufacturerID_space[33]; static char *libraryDescription = "NSS Internal Crypto Services "; static char libraryDescription_space[33]; @@ -1228,6 +1227,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE { CK_BBOOL cktrue = CK_TRUE; CK_BBOOL encrypt = CK_TRUE; + CK_BBOOL sign = CK_FALSE; CK_BBOOL recover = CK_TRUE; CK_BBOOL wrap = CK_TRUE; CK_BBOOL derive = CK_FALSE; @@ -1268,15 +1268,18 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE sftk_item_expand(&mod)); if (mod.data) PORT_Free(mod.data); if (crv != CKR_OK) return crv; - + + sign = CK_TRUE; break; case CKK_DSA: if ( !sftk_hasAttribute(object, CKA_SUBPRIME)) { return CKR_TEMPLATE_INCOMPLETE; } - if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { + if (sftk_isTrue(object,CKA_TOKEN) && + !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { return CKR_TEMPLATE_INCOMPLETE; } + sign = CK_TRUE; /* fall through */ case CKK_DH: if ( !sftk_hasAttribute(object, CKA_PRIME)) { @@ -1300,10 +1303,12 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE if ( !sftk_hasAttribute(object, CKA_VALUE)) { return CKR_TEMPLATE_INCOMPLETE; } - if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { + if (sftk_isTrue(object,CKA_TOKEN) && + !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { return CKR_TEMPLATE_INCOMPLETE; } encrypt = CK_FALSE; + sign = CK_TRUE; recover = CK_FALSE; wrap = CK_FALSE; derive = CK_TRUE; @@ -1320,7 +1325,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE if (crv != CKR_OK) return crv; crv = sftk_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL)); if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_SIGN,&cktrue,sizeof(CK_BBOOL)); + crv = sftk_defaultAttribute(object,CKA_SIGN,&sign,sizeof(CK_BBOOL)); if (crv != CKR_OK) return crv; crv = sftk_defaultAttribute(object,CKA_SIGN_RECOVER,&recover, sizeof(CK_BBOOL)); @@ -1532,6 +1537,9 @@ sftk_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label) (++retries <= SFTK_KEY_MAX_RETRIES)); if ((rv != SECSuccess) || (retries > SFTK_KEY_MAX_RETRIES)) { + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + } crv = CKR_DEVICE_ERROR; /* random number generator is bad */ PORT_Free(id->data); id->data = NULL; @@ -1644,6 +1652,9 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object) /* get the key type */ attribute = sftk_FindAttribute(object,CKA_KEY_TYPE); + if (!attribute) { + return CKR_ATTRIBUTE_VALUE_INVALID; + } key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; sftk_FreeAttribute(attribute); @@ -1750,6 +1761,9 @@ sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object) /* get the key type */ attribute = sftk_FindAttribute(object,CKA_KEY_TYPE); + if (!attribute) { + return CKR_ATTRIBUTE_VALUE_INVALID; + } key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; sftk_FreeAttribute(attribute); @@ -1952,7 +1966,10 @@ NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,CK_KEY_TYPE key_type, * based on the encoded params */ if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding, - &pubKey->u.ec.ecParams) != SECSuccess) break; + &pubKey->u.ec.ecParams) != SECSuccess) { + crv = CKR_DOMAIN_PARAMS_INVALID; + break; + } crv = sftk_Attribute2SSecItem(arena,&pubKey->u.ec.publicValue, object,CKA_EC_POINT); @@ -2045,9 +2062,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.privateValue, object,CKA_VALUE); if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.publicValue, - object,CKA_NETSCAPE_DB); - /* can't set the public value.... */ + if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) { + crv = sftk_Attribute2SSecItem(arena, &privKey->u.dsa.publicValue, + object,CKA_NETSCAPE_DB); + /* privKey was zero'd so public value is already set to NULL, 0 + * if we don't set it explicitly */ + } break; case CKK_DH: @@ -2061,8 +2081,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.privateValue, object,CKA_VALUE); if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.publicValue, - object,CKA_NETSCAPE_DB); + if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) { + crv = sftk_Attribute2SSecItem(arena, &privKey->u.dh.publicValue, + object,CKA_NETSCAPE_DB); + /* privKey was zero'd so public value is already set to NULL, 0 + * if we don't set it explicitly */ + } break; #ifdef NSS_ENABLE_ECC @@ -2077,13 +2101,20 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) * based on the encoded params */ if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding, - &privKey->u.ec.ecParams) != SECSuccess) break; + &privKey->u.ec.ecParams) != SECSuccess) { + crv = CKR_DOMAIN_PARAMS_INVALID; + break; + } crv = sftk_Attribute2SSecItem(arena,&privKey->u.ec.privateValue, object,CKA_VALUE); if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue, + if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) { + crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue, object,CKA_NETSCAPE_DB); - if (crv != CKR_OK) break; + if (crv != CKR_OK) break; + /* privKey was zero'd so public value is already set to NULL, 0 + * if we don't set it explicitly */ + } rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version, NSSLOWKEY_EC_PRIVATE_KEY_VERSION); if (rv != SECSuccess) crv = CKR_HOST_MEMORY; @@ -2333,7 +2364,7 @@ sftk_getDefTokName(CK_SLOT_ID slotID) case PRIVATE_KEY_SLOT_ID: return "NSS Certificate DB "; case FIPS_SLOT_ID: - return "NSS FIPS-140-1 Certificate DB "; + return "NSS FIPS 140-2 Certificate DB "; default: break; } @@ -2355,7 +2386,7 @@ sftk_getDefSlotName(CK_SLOT_ID slotID) "NSS User Private Key and Certificate Services "; case FIPS_SLOT_ID: return - "Netscape FIPS-140-1 User Private Key Services "; + "NSS FIPS 140-2 User Private Key Services "; default: break; } @@ -2388,6 +2419,8 @@ sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all) { SFTKSlot *slot; int index = sftk_GetModuleIndex(slotID); + + if (nscSlotHashTable[index] == NULL) return NULL; slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index], (void *)slotID); /* cleared slots shouldn't 'show up' */ @@ -2756,9 +2789,11 @@ sftk_DBShutdown(SFTKSlot *slot) slot->keyDB = NULL; PZ_Unlock(slot->slotLock); if (certHandle) { + PORT_Assert(certHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID); sftk_freeCertDB(certHandle); } if (keyHandle) { + PORT_Assert(keyHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID); sftk_freeKeyDB(keyHandle); } } @@ -2953,13 +2988,6 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) if (isFIPS) { - /* make sure that our check file signatures are OK */ - if (!BLAPI_VerifySelf(NULL) || - !BLAPI_SHVerify(SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_closePeer)) { - crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */ - return crv; - } - loginWaitTime = PR_SecondsToInterval(1); } @@ -2976,6 +3004,12 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) } RNG_SystemInfoForRNG(); + rv = nsslowcert_InitLocks(); + if (rv != SECSuccess) { + crv = CKR_DEVICE_ERROR; + return crv; + } + /* NOTE: * we should be getting out mutexes from this list, not statically binding @@ -3022,6 +3056,13 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) * don't clobber each other. */ if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) { sftk_closePeer(isFIPS); + if (sftk_audit_enabled) { + if (isFIPS && nsc_init) { + sftk_LogAuditMessage(NSS_AUDIT_INFO, "enabled FIPS mode"); + } else { + sftk_LogAuditMessage(NSS_AUDIT_INFO, "disabled FIPS mode"); + } + } } for (i=0; i < paramStrings.token_count; i++) { @@ -3076,21 +3117,13 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS) nsslowcert_DestroyFreeLists(); nsslowcert_DestroyGlobalLocks(); -#ifdef LEAK_TEST - /* - * do we really want to throw away all our hard earned entropy here!!? - * No we don't! Not calling RNG_RNGShutdown only 'leaks' data on the - * initial call to RNG_Init(). So the only reason to call this is to clean - * up leak detection warnings on shutdown. In many cases we *don't* want - * to free up the global RNG context because the application has Finalized - * simply to swap profiles. We don't want to loose the entropy we've - * already collected. - */ + /* This function does not discard all our previously aquired entropy. */ RNG_RNGShutdown(); -#endif /* tell freeBL to clean up after itself */ BL_Cleanup(); + /* unload freeBL shared library from memory */ + BL_Unload(); /* clean up the default OID table */ SECOID_Shutdown(); nsc_init = PR_FALSE; @@ -3178,7 +3211,6 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) return CKR_OK; } -#define CKF_THREAD_SAFE 0x8000 /* for now */ /* * check the current state of the 'needLogin' flag in case the database has * been changed underneath us. @@ -3206,14 +3238,17 @@ sftk_checkNeedLogin(SFTKSlot *slot, NSSLOWKEYDBHandle *keyHandle) * the system. */ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) { - SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); + SFTKSlot *slot; NSSLOWKEYDBHandle *handle; + if (!nsc_init && !nsf_init) return CKR_CRYPTOKI_NOT_INITIALIZED; + slot = sftk_SlotFromID(slotID, PR_FALSE); if (slot == NULL) return CKR_SLOT_ID_INVALID; PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32); PORT_Memcpy(pInfo->model,"NSS 3 ",16); PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16); + PORT_Memcpy(pInfo->utcTime,"0000000000000000",16); pInfo->ulMaxSessionCount = 0; /* arbitrarily large */ pInfo->ulSessionCount = slot->sessionCount; pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */ @@ -3222,8 +3257,9 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) pInfo->firmwareVersion.minor = 0; PORT_Memcpy(pInfo->label,slot->tokDescription,32); handle = sftk_getKeyDB(slot); + pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS; if (handle == NULL) { - pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE; + pInfo->flags |= CKF_WRITE_PROTECTED; pInfo->ulMaxPinLen = 0; pInfo->ulMinPinLen = 0; pInfo->ulTotalPublicMemory = 0; @@ -3243,12 +3279,11 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) * we will need to prompt for it. */ if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) { - pInfo->flags = CKF_THREAD_SAFE | CKF_LOGIN_REQUIRED; + pInfo->flags |= CKF_LOGIN_REQUIRED; } else if (!sftk_checkNeedLogin(slot,handle)) { - pInfo->flags = CKF_THREAD_SAFE | CKF_USER_PIN_INITIALIZED; + pInfo->flags |= CKF_USER_PIN_INITIALIZED; } else { - pInfo->flags = CKF_THREAD_SAFE | - CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED; + pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED; } pInfo->ulMaxPinLen = SFTK_MAX_PIN; pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen; @@ -3260,6 +3295,18 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) pInfo->hardwareVersion.minor = handle->version; sftk_freeKeyDB(handle); } + /* + * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED + * should be set + * 0 0 1 + * 1 0 0 + * 0 1 1 + * 1 1 1 + */ + if (!(pInfo->flags & CKF_LOGIN_REQUIRED) || + (pInfo->flags & CKF_USER_PIN_INITIALIZED)) { + pInfo->flags |= CKF_TOKEN_INITIALIZED; + } return CKR_OK; } @@ -3551,7 +3598,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, handle = sftk_getKeyDB(slot); if (handle == NULL) { sftk_FreeSession(sp); - return CKR_PIN_LEN_RANGE; + return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */ } if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) { @@ -3927,7 +3974,7 @@ static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class, if (attribute == NULL) { return CKR_TEMPLATE_INCOMPLETE; } - paramString = (unsigned char *)attribute->attrib.pValue; + paramString = (char *)attribute->attrib.pValue; crv = secmod_parseParameters(paramString, ¶mStrings, isFIPS); if (crv != CKR_OK) { goto loser; @@ -3990,7 +4037,9 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession, SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); SFTKSession *session; SFTKObject *object; - CK_OBJECT_CLASS class; + /* make sure class isn't randomly CKO_NETSCAPE_NEWSLOT or + * CKO_NETSCPE_DELSLOT. */ + CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED; CK_RV crv; int i; diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 56eb1814c..b722d3d4c 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -73,6 +73,7 @@ #include "pcert.h" #include "ssl3prot.h" /* for SSL3_RANDOM_LENGTH */ +#include "prprf.h" #define __PASTE(x,y) x##y @@ -441,17 +442,23 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, break; } context->multi = PR_FALSE; - context->cipherInfo = isEncrypt ? - (void *)sftk_GetPubKey(key,CKK_RSA,&crv) : - (void *)sftk_GetPrivKey(key,CKK_RSA,&crv); - if (context->cipherInfo == NULL) { - break; - } if (isEncrypt) { + NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv); + if (pubKey == NULL) { + break; + } + context->maxLen = nsslowkey_PublicModulusLen(pubKey); + context->cipherInfo = (void *)pubKey; context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509 ? RSA_EncryptRaw : RSA_EncryptBlock); } else { + NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv); + if (privKey == NULL) { + break; + } + context->maxLen = nsslowkey_PrivateModulusLen(privKey); + context->cipherInfo = (void *)privKey; context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509 ? RSA_DecryptRaw : RSA_DecryptBlock); @@ -717,6 +724,18 @@ CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession, crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL); if (crv != CKR_OK) return crv; + if (!pEncryptedPart) { + if (context->doPad) { + CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength; + CK_ULONG blocksToSend = totalDataAvailable/context->blockSize; + + *pulEncryptedPartLen = blocksToSend * context->blockSize; + return CKR_OK; + } + *pulEncryptedPartLen = ulPartLen; + return CKR_OK; + } + /* do padding */ if (context->doPad) { /* deal with previous buffered data */ @@ -837,7 +856,8 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (crv != CKR_OK) return crv; if (!pEncryptedData) { - *pulEncryptedDataLen = ulDataLen + 2 * context->blockSize; + *pulEncryptedDataLen = context->multi ? + ulDataLen + 2 * context->blockSize : context->maxLen; goto finish; } @@ -923,6 +943,35 @@ CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL); if (crv != CKR_OK) return crv; + /* this can only happen on an NSS programming error */ + PORT_Assert((context->padDataLength == 0) + || context->padDataLength == context->blockSize); + + + if (!pPart) { + if (context->doPad) { + /* we can check the data length here because if we are padding, + * then we must be using a block cipher. In the non-padding case + * the error will be returned by the underlying decryption + * function when do do the actual decrypt. We need to do the + * check here to avoid returning a negative length to the caller. + */ + if ((ulEncryptedPartLen == 0) || + (ulEncryptedPartLen % context->blockSize) != 0) { + return CKR_ENCRYPTED_DATA_LEN_RANGE; + } + *pulPartLen = + ulEncryptedPartLen + context->padDataLength - context->blockSize; + return CKR_OK; + } + /* for stream ciphers there is are no constraints on ulEncryptedPartLen. + * for block ciphers, it must be a multiple of blockSize. The error is + * detected when this function is called again do decrypt the output. + */ + *pulPartLen = ulEncryptedPartLen; + return CKR_OK; + } + if (context->doPad) { /* first decrypt our saved buffer */ if (context->padDataLength != 0) { @@ -957,7 +1006,6 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, unsigned int maxout = *pulLastPartLen; CK_RV crv; SECStatus rv = SECSuccess; - PRBool contextFinished = PR_TRUE; /* make sure we're legal */ crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session); @@ -967,9 +1015,9 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, if (!pLastPart) { /* caller is checking the amount of remaining data */ if (context->padDataLength > 0) { - *pulLastPartLen = 2 * context->blockSize; - contextFinished = PR_FALSE; /* still have padding to go */ + *pulLastPartLen = context->padDataLength; } + rv = SECSuccess; goto finish; } @@ -992,11 +1040,9 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, } } + sftk_SetContextByType(session, SFTK_DECRYPT, NULL); + sftk_FreeContext(context); finish: - if (contextFinished) { - sftk_SetContextByType(session, SFTK_DECRYPT, NULL); - sftk_FreeContext(context); - } sftk_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; } @@ -1247,7 +1293,7 @@ static SECStatus sftk_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen, unsigned char *hash, unsigned int hashLen) { - return PORT_Memcmp(sig,hash,*copyLen) ? SECSuccess : SECFailure ; + return (PORT_Memcmp(sig,hash,*copyLen) == 0) ? SECSuccess : SECFailure ; } /* @@ -1548,6 +1594,15 @@ static SECStatus sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, unsigned int maxLen,unsigned char *hash, unsigned int hashLen) { + return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen, + hash,hashLen); +} + +SECStatus +RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key, + unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, + unsigned char *hash, unsigned int hashLen) +{ SECStatus rv = SECFailure; SECItem digder; @@ -1560,7 +1615,7 @@ sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, if ( !arena ) { goto loser; } /* Construct digest info */ - di = SGN_CreateDigestInfo(info->hashOid, hash, hashLen); + di = SGN_CreateDigestInfo(hashOid, hash, hashLen); if (!di) { goto loser; } /* Der encode the digest as a DigestInfo */ @@ -1573,7 +1628,7 @@ sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, ** Encrypt signature after constructing appropriate PKCS#1 signature ** block */ - rv = RSA_Sign(info->key,sig,sigLen,maxLen,digder.data,digder.len); + rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len); loser: SGN_DestroyDigestInfo(di); @@ -1611,6 +1666,9 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf, digest.data = (unsigned char *)dataBuf; digest.len = dataLen; rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *sigLen = signature.len; return rv; } @@ -1644,6 +1702,9 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf, digest.data = (unsigned char *)dataBuf; digest.len = dataLen; rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *sigLen = signature.len; return rv; } @@ -1857,7 +1918,7 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, SECStatus rv; /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,type,PR_FALSE,NULL); + crv = sftk_GetContext(hSession,&context,type,PR_TRUE,NULL); if (crv != CKR_OK) return crv; if (context->hashInfo) { @@ -2055,11 +2116,20 @@ CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ************** Crypto Functions: verify ************************ */ -/* Handle RSA Signature formating */ +/* Handle RSA Signature formatting */ static SECStatus sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, unsigned int sigLen, unsigned char *digest, unsigned int digestLen) { + return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, + digest, digestLen); +} + +SECStatus +RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key, + unsigned char *sig, unsigned int sigLen, + unsigned char *digest, unsigned int digestLen) +{ SECItem it; SGNDigestInfo *di = NULL; @@ -2067,16 +2137,16 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, it.data = NULL; - if (info->key == NULL) goto loser; + if (key == NULL) goto loser; - it.len = nsslowkey_PublicModulusLen(info->key); + it.len = nsslowkey_PublicModulusLen(key); if (!it.len) goto loser; it.data = (unsigned char *) PORT_Alloc(it.len); if (it.data == NULL) goto loser; /* decrypt the block */ - rv = RSA_CheckSignRecover(info->key, it.data, &it.len, it.len, sig, sigLen); + rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen); if (rv != SECSuccess) goto loser; di = SGN_DecodeDigestInfo(&it); @@ -2084,7 +2154,11 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, if (di->digest.len != digestLen) goto loser; /* make sure the tag is OK */ - if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != info->hashOid) { + if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) { + goto loser; + } + /* make sure the "parameters" are not too bogus. */ + if (di->digestAlgorithm.parameters.len > 2) { goto loser; } /* Now check the signature */ @@ -2093,6 +2167,7 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, } loser: + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); rv = SECFailure; done: @@ -2202,7 +2277,6 @@ finish_rsa: crv = CKR_KEY_TYPE_INCONSISTENT; break; } - context->multi = PR_FALSE; pubKey = sftk_GetPubKey(key,CKK_EC,&crv); if (pubKey == NULL) { crv = CKR_HOST_MEMORY; @@ -2246,6 +2320,7 @@ finish_rsa: } if (crv != CKR_OK) { + if (info) PORT_Free(info); PORT_Free(context); sftk_FreeSession(session); return crv; @@ -2263,13 +2338,22 @@ CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, { SFTKSession *session; SFTKSessionContext *context; - CK_RV crv; + CK_RV crv, crv2; SECStatus rv; /* make sure we're legal */ crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session); if (crv != CKR_OK) return crv; + /* multi part Verifying are completely implemented by VerifyUpdate and + * VerifyFinal */ + if (context->multi) { + sftk_FreeSession(session); + crv = NSC_VerifyUpdate(hSession, pData, ulDataLen); + crv2 = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen); + return crv == CKR_OK ? crv2 :crv; + } + rv = (*context->verify)(context->cipherInfo,pSignature, ulSignatureLen, pData, ulDataLen); sftk_FreeContext(context); @@ -2414,14 +2498,23 @@ CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession, crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER, PR_FALSE,&session); if (crv != CKR_OK) return crv; + if (pData == NULL) { + /* to return the actual size, we need to do the decrypt, just return + * the max size, which is the size of the input signature. */ + *pulDataLen = ulSignatureLen; + rv = SECSuccess; + goto finish; + } rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, pSignature, ulSignatureLen); *pulDataLen = (CK_ULONG) outlen; + sftk_FreeContext(context); sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, NULL); +finish: sftk_FreeSession(session); - return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; + return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID; } /* @@ -2482,9 +2575,13 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism, SECITEM_ZfreeItem(pbe_key, PR_TRUE); pbe_key = NULL; - if (iv.data && pbe_params->pInitVector != NULL) { - PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); + if (iv.data) { + if (pbe_params->pInitVector != NULL) { + PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); + } + PORT_Free(iv.data); } + return CKR_OK; } static CK_RV @@ -2527,6 +2624,9 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key) } if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } return CKR_DEVICE_ERROR; } crv = sftk_AddAttributeType(key,CKA_PRIME, @@ -3355,6 +3455,9 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession, rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp); PORT_Free(pubExp.data); if (rsaPriv == NULL) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } crv = CKR_DEVICE_ERROR; break; } @@ -3471,7 +3574,13 @@ kpg_done: PORT_Free(pqgParam.subPrime.data); PORT_Free(pqgParam.base.data); - if (rv != SECSuccess) { crv = CKR_DEVICE_ERROR; break; } + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } + crv = CKR_DEVICE_ERROR; + break; + } /* store the generated key into the attributes */ crv = sftk_AddAttributeType(publicKey,CKA_VALUE, @@ -3539,6 +3648,9 @@ dsagn_done: PORT_Free(dhParam.prime.data); PORT_Free(dhParam.base.data); if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } crv = CKR_DEVICE_ERROR; break; } @@ -3588,8 +3700,11 @@ dhgn_done: rv = EC_NewKey(ecParams, &ecPriv); PORT_FreeArena(ecParams->arena, PR_TRUE); if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - break; + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } + crv = CKR_DEVICE_ERROR; + break; } crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, @@ -3695,6 +3810,16 @@ ecgn_done: sftk_FreeObject(publicKey); NSC_DestroyObject(hSession,privateKey->handle); sftk_FreeObject(privateKey); + if (sftk_audit_enabled) { + char msg[128]; + PR_snprintf(msg,sizeof msg, + "C_GenerateKeyPair(hSession=0x%08lX, " + "pMechanism->mechanism=0x%08lX)=0x%08lX " + "self-test: pair-wise consistency test failed", + (PRUint32)hSession,(PRUint32)pMechanism->mechanism, + (PRUint32)crv); + sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg); + } return crv; } @@ -3937,6 +4062,17 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data, pText.len, pWrappedKey, pulWrappedKeyLen); + /* always force a finalize, both on errors and when + * we are just getting the size */ + if (crv != CKR_OK || pWrappedKey == NULL) { + CK_RV lcrv ; + lcrv = sftk_GetContext(hSession,&context, + SFTK_ENCRYPT,PR_FALSE,NULL); + sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); + if (lcrv == CKR_OK && context) { + sftk_FreeContext(context); + } + } if (pText.data != (unsigned char *)attribute->attrib.pValue) PORT_ZFree(pText.data, pText.len); @@ -3947,6 +4083,7 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, case CKO_PRIVATE_KEY: { SECItem *bpki = sftk_PackagePrivateKey(key, &crv); + SFTKSessionContext *context = NULL; if(!bpki) { break; @@ -3962,6 +4099,16 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, crv = NSC_Encrypt(hSession, bpki->data, bpki->len, pWrappedKey, pulWrappedKeyLen); + /* always force a finalize */ + if (crv != CKR_OK || pWrappedKey == NULL) { + CK_RV lcrv ; + lcrv = sftk_GetContext(hSession,&context, + SFTK_ENCRYPT,PR_FALSE,NULL); + sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); + if (lcrv == CKR_OK && context) { + sftk_FreeContext(context); + } + } SECITEM_ZfreeItem(bpki, PR_TRUE); break; } @@ -3989,7 +4136,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) PLArenaPool *arena; NSSLOWKEYPrivateKey *lpk = NULL; NSSLOWKEYPrivateKeyInfo *pki = NULL; - SECItem *ck_id = NULL; CK_RV crv = CKR_KEY_TYPE_INCONSISTENT; arena = PORT_NewArena(2048); @@ -4000,13 +4146,13 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPrivateKeyInfo)); if(!pki) { - PORT_FreeArena(arena, PR_TRUE); + PORT_FreeArena(arena, PR_FALSE); return SECFailure; } if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) != SECSuccess) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); return SECFailure; } @@ -4197,10 +4343,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) } loser: - if(ck_id) { - SECITEM_ZfreeItem(ck_id, PR_TRUE); - } - if(lpk) { nsslowkey_DestroyPrivateKey(lpk); } @@ -4605,14 +4747,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, return CKR_KEY_HANDLE_INVALID; } - /* don't use key derive to expose sensitive keys */ - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) { - sftk_FreeObject(key); - sftk_FreeObject(sourceKey); - return crv; - } - /* get the value of the base key */ att = sftk_FindAttribute(sourceKey,CKA_VALUE); if (att == NULL) { @@ -4633,7 +4767,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, case CKM_SSL3_MASTER_KEY_DERIVE_DH: { CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master; - SSL3RSAPreMasterSecret *rsa_pms; + SSL3RSAPreMasterSecret * rsa_pms; + unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; + if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) || (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH)) isDH = PR_TRUE; @@ -4660,10 +4796,15 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, break; } - /* finally do the key gen */ ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) pMechanism->pParameter; + + PORT_Memcpy(crsrdata, + ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, + ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + if (ssl3_master->pVersion) { SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue; @@ -4686,23 +4827,17 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, } if (isTLS) { - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - SECItem crsr = { siBuffer, NULL, 0 }; - SECItem master = { siBuffer, NULL, 0 }; - SECItem pms = { siBuffer, NULL, 0 }; SECStatus status; + SECItem crsr = { siBuffer, NULL, 0 }; + SECItem master = { siBuffer, NULL, 0 }; + SECItem pms = { siBuffer, NULL, 0 }; - pms.data = (unsigned char*)att->attrib.pValue; - pms.len = att->attrib.ulValueLen; - master.data = key_block; - master.len = SSL3_MASTER_SECRET_LENGTH; - crsr.data = crsrdata; - crsr.len = sizeof(crsrdata); - - PORT_Memcpy(crsrdata, ssl3_master->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + crsr.data = crsrdata; + crsr.len = sizeof crsrdata; + master.data = key_block; + master.len = SSL3_MASTER_SECRET_LENGTH; + pms.data = (unsigned char*)att->attrib.pValue; + pms.len = att->attrib.ulValueLen; status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); if (status != SECSuccess) { @@ -4727,12 +4862,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); - SHA1_Update(sha, ssl3_master->RandomInfo.pClientRandom, - ssl3_master->RandomInfo.ulClientRandomLen); - SHA1_Update(sha, ssl3_master->RandomInfo.pServerRandom, - ssl3_master->RandomInfo.ulServerRandomLen); + SHA1_Update(sha, crsrdata, sizeof crsrdata); SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); PORT_Assert(outLen == SHA1_LENGTH); + MD5_Begin(md5); MD5_Update(md5, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); @@ -4773,6 +4906,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, CK_SSL3_KEY_MAT_PARAMS *ssl3_keys; CK_SSL3_KEY_MAT_OUT * ssl3_keys_out; CK_ULONG effKeySize; + unsigned int block_needed; + unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; + unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; crv = sftk_DeriveSensitiveCheck(sourceKey,key); if (crv != CKR_OK) break; @@ -4801,6 +4937,17 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, break; } ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter; + + PORT_Memcpy(srcrdata, + ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, + ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + + PORT_Memcpy(crsrdata, + ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, + ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + /* * clear out our returned keys so we can recover on failure */ @@ -4811,29 +4958,36 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ssl3_keys_out->hServerKey = CK_INVALID_HANDLE; /* + * How much key material do we need? + */ + macSize = ssl3_keys->ulMacSizeInBits/8; + effKeySize = ssl3_keys->ulKeySizeInBits/8; + IVSize = ssl3_keys->ulIVSizeInBits/8; + if (keySize == 0) { + effKeySize = keySize; + } + block_needed = 2 * (macSize + effKeySize + + ((!ssl3_keys->bIsExport) * IVSize)); + PORT_Assert(block_needed <= sizeof key_block); + if (block_needed > sizeof key_block) + block_needed = sizeof key_block; + + /* * generate the key material: This looks amazingly similar to the * PMS code, and is clearly crying out for a function to provide it. */ if (isTLS) { SECStatus status; - SECItem master = { siBuffer, NULL, 0 }; SECItem srcr = { siBuffer, NULL, 0 }; SECItem keyblk = { siBuffer, NULL, 0 }; - unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; + SECItem master = { siBuffer, NULL, 0 }; - master.data = (unsigned char*)att->attrib.pValue; - master.len = att->attrib.ulValueLen; srcr.data = srcrdata; srcr.len = sizeof srcrdata; keyblk.data = key_block; - keyblk.len = sizeof key_block; - - PORT_Memcpy(srcrdata, - ssl3_keys->RandomInfo.pServerRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); + keyblk.len = block_needed; + master.data = (unsigned char*)att->attrib.pValue; + master.len = att->attrib.ulValueLen; status = TLS_PRF(&master, "key expansion", &srcr, &keyblk, isFIPS); @@ -4841,6 +4995,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, goto key_and_mac_derive_fail; } } else { + unsigned int block_bytes = 0; /* key_block = * MD5(master_secret + SHA('A' + master_secret + * ServerHello.random + ClientHello.random)) + @@ -4850,15 +5005,12 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, * ServerHello.random + ClientHello.random)) + * [...]; */ - for (i = 0; i < NUM_MIXERS; i++) { + for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) { SHA1_Begin(sha); SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); - SHA1_Update(sha, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - SHA1_Update(sha, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + SHA1_Update(sha, srcrdata, sizeof srcrdata); SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); PORT_Assert(outLen == SHA1_LENGTH); MD5_Begin(md5); @@ -4867,6 +5019,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, MD5_Update(md5, sha_out, outLen); MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH); PORT_Assert(outLen == MD5_LENGTH); + block_bytes += outLen; } } @@ -4874,12 +5027,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, * Put the key material where it goes. */ i = 0; /* now shows how much consumed */ - macSize = ssl3_keys->ulMacSizeInBits/8; - effKeySize = ssl3_keys->ulKeySizeInBits/8; - IVSize = ssl3_keys->ulIVSizeInBits/8; - if (keySize == 0) { - effKeySize = keySize; - } /* * The key_block is partitioned as follows: @@ -4954,10 +5101,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, */ MD5_Begin(md5); MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); + MD5_Update(md5, crsrdata, sizeof crsrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); i += effKeySize; crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, @@ -4973,10 +5117,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, */ MD5_Begin(md5); MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + MD5_Update(md5, srcrdata, sizeof srcrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); i += effKeySize; crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, @@ -4990,10 +5131,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ** MD5(ClientHello.random + ServerHello.random); */ MD5_Begin(md5); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); + MD5_Update(md5, crsrdata, sizeof crsrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize); @@ -5002,10 +5140,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ** MD5(ServerHello.random + ClientHello.random); */ MD5_Begin(md5); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + MD5_Update(md5, srcrdata, sizeof srcrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize); @@ -5018,18 +5153,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, SECItem secret = { siBuffer, NULL, 0 }; SECItem crsr = { siBuffer, NULL, 0 }; SECItem keyblk = { siBuffer, NULL, 0 }; - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - - crsr.data = crsrdata; - crsr.len = sizeof crsrdata; - - PORT_Memcpy(crsrdata, - ssl3_keys->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pServerRandom, - SSL3_RANDOM_LENGTH); - /* ** client_write_key[CipherSpec.key_material] @@ -5040,6 +5163,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, secret.data = &key_block[i]; secret.len = effKeySize; i += effKeySize; + crsr.data = crsrdata; + crsr.len = sizeof crsrdata; keyblk.data = key_block2; keyblk.len = sizeof key_block2; status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, @@ -5177,6 +5302,9 @@ key_and_mac_derive_fail: } case CKM_CONCATENATE_BASE_AND_DATA: + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen; if (keySize == 0) keySize = tmpKeySize; @@ -5198,6 +5326,9 @@ key_and_mac_derive_fail: PORT_ZFree(buf,tmpKeySize); break; case CKM_CONCATENATE_DATA_AND_BASE: + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen; if (keySize == 0) keySize = tmpKeySize; @@ -5219,6 +5350,9 @@ key_and_mac_derive_fail: PORT_ZFree(buf,tmpKeySize); break; case CKM_XOR_BASE_AND_DATA: + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen); if (keySize == 0) keySize = tmpKeySize; @@ -5249,6 +5383,9 @@ key_and_mac_derive_fail: CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */ CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */ + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + if (keySize == 0) { crv = CKR_TEMPLATE_INCOMPLETE; break; @@ -5382,6 +5519,7 @@ key_and_mac_derive_fail: PRBool withCofactor = PR_FALSE; unsigned char secret_hash[20]; unsigned char *secret; + unsigned char *keyData = NULL; int secretlen; CK_ECDH1_DERIVE_PARAMS *mechParams; NSSLOWKEYPrivateKey *privKey; @@ -5435,26 +5573,59 @@ key_and_mac_derive_fail: break; } + /* + * tmp is the raw data created by ECDH_Derive, + * secret and secretlen are the values we will eventually pass as our + * generated key. + */ secret = tmp.data; secretlen = tmp.len; + + /* + * apply the kdf function. + */ if (mechParams->kdf == CKD_SHA1_KDF) { /* Compute SHA1 hash */ - memset(secret_hash, 0, 20); + PORT_Memset(secret_hash, 0, 20); rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len); if (rv != SECSuccess) { PORT_ZFree(tmp.data, tmp.len); + crv = CKR_HOST_MEMORY; + break; + } + secret = secret_hash; + secretlen = 20; + } + + /* + * if keySize is supplied, then we are generating a key of a specific + * length. This is done by taking the least significant 'keySize' + * bytes from the unsigned value calculated by ECDH. Note: this may + * mean padding temp with extra leading zeros from what ECDH_Derive + * already returned (which itself may contain leading zeros). + */ + if (keySize) { + if (secretlen < keySize) { + keyData = PORT_ZAlloc(keySize); + if (!keyData) { + PORT_ZFree(tmp.data, tmp.len); + crv = CKR_HOST_MEMORY; + break; + } + PORT_Memcpy(&keyData[keySize-secretlen],secret,secretlen); + secret = keyData; } else { - secret = secret_hash; - secretlen = 20; + secret += (secretlen - keySize); } + secretlen = keySize; } - if (rv == SECSuccess) { - sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); - PORT_ZFree(tmp.data, tmp.len); - memset(secret_hash, 0, 20); - } else - crv = CKR_HOST_MEMORY; + sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); + PORT_ZFree(tmp.data, tmp.len); + if (keyData) { + PORT_ZFree(keyData, keySize); + } + PORT_Memset(secret_hash, 0, 20); break; } @@ -5700,7 +5871,9 @@ CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) /* get the key value */ att = sftk_FindAttribute(key,CKA_VALUE); sftk_FreeObject(key); - + if (!att) { + return CKR_KEY_HANDLE_INVALID; + } crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue, att->attrib.ulValueLen); sftk_FreeAttribute(att); diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index 0eaf5bf37..6f77994fd 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -555,8 +555,8 @@ typedef struct sftk_parametersStr { SEC_BEGIN_PROTOS -/* shared functions between PKCS11.c and SFTKFIPS.c */ -extern int nsf_init; +/* shared functions between pkcs11.c and fipstokn.c */ +extern PRBool nsf_init; extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS); extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS); extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent, diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index 8e68587ce..9790f0ca3 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -67,6 +67,7 @@ sftk_NewAttribute(SFTKObject *object, if (so == NULL) { /* allocate new attribute in a buffer */ PORT_Assert(0); + return NULL; } /* * We attempt to keep down contention on Malloc and Arena locks by @@ -891,6 +892,11 @@ sftk_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, case CKA_BASE: return sftk_NewTokenAttributeSigned(type,key->u.dsa.params.base.data, key->u.dsa.params.base.len, PR_FALSE); + case CKA_NETSCAPE_DB: + return sftk_NewTokenAttributeSigned(type, + key->u.dsa.publicValue.data, + key->u.dsa.publicValue.len, + PR_FALSE); default: break; } @@ -925,6 +931,11 @@ sftk_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type) case CKA_BASE: return sftk_NewTokenAttributeSigned(type,key->u.dh.base.data, key->u.dh.base.len, PR_FALSE); + case CKA_NETSCAPE_DB: + return sftk_NewTokenAttributeSigned(type, + key->u.dh.publicValue.data, + key->u.dh.publicValue.len, + PR_FALSE); default: break; } @@ -960,6 +971,11 @@ sftk_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type) key->u.ec.ecParams.DEREncoding.data, key->u.ec.ecParams.DEREncoding.len, PR_FALSE); + case CKA_NETSCAPE_DB: + return sftk_NewTokenAttributeSigned(type, + key->u.ec.publicValue.data, + key->u.ec.publicValue.len, + PR_FALSE); default: break; } @@ -1502,7 +1518,6 @@ sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute) sessObject->head, sessObject->hashSize); } PZ_Unlock(sessObject->attributeLock); - sftk_FreeAttribute(attribute); } /* @@ -2749,7 +2764,7 @@ stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to) } /* copy the common attributes for all private keys next */ crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs, - commonKeyAttrsCount); + commonPrivKeyAttrsCount); if (crv != CKR_OK) { goto fail; } diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c index b40a30d80..c60c71344 100644 --- a/security/nss/lib/softoken/rsawrapr.c +++ b/security/nss/lib/softoken/rsawrapr.c @@ -193,6 +193,7 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, unsigned char *bp; int padLen; int i; + SECStatus rv; block = (unsigned char *) PORT_Alloc(modulusLen); if (block == NULL) @@ -254,8 +255,13 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, for (i = 0; i < padLen; i++) { /* Pad with non-zero random data. */ do { - RNG_GenerateGlobalRandomBytes(bp + i, 1); - } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET); + rv = RNG_GenerateGlobalRandomBytes(bp + i, 1); + } while (rv == SECSuccess && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET); + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + PORT_Free (block); + return NULL; + } } bp += padLen; *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; @@ -292,7 +298,12 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, /* * Salt */ - RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN); + rv = RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN); + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + PORT_Free (block); + return NULL; + } bp += OAEP_SALT_LEN; /* @@ -310,8 +321,14 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, /* * Pad2 */ - if (bp < (block + modulusLen)) - RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen); + if (bp < (block + modulusLen)) { + rv = RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen); + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + PORT_Free (block); + return NULL; + } + } /* * Now we have the following: @@ -463,6 +480,9 @@ RSA_Sign(NSSLOWKEYPrivateKey *key, goto done; rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *output_len = modulus_len; goto done; @@ -489,7 +509,13 @@ RSA_CheckSign(NSSLOWKEYPublicKey *key, modulus_len = nsslowkey_PublicModulusLen(key); if (sign_len != modulus_len) goto failure; - if (hash_len > modulus_len - 8) + /* + * 0x00 || BT || Pad || 0x00 || ActualData + * + * The "3" below is the first octet + the second octet + the 0x00 + * octet that always comes just before the ActualData. + */ + if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN)) goto failure; PORT_Assert(key->keyType == NSSLOWKEYRSAKey); if (key->keyType != NSSLOWKEYRSAKey) @@ -509,11 +535,11 @@ RSA_CheckSign(NSSLOWKEYPublicKey *key, if (buffer[0] != 0 || buffer[1] != 1) goto loser; for (i = 2; i < modulus_len - hash_len - 1; i++) { - if (buffer[i] == 0) - break; if (buffer[i] != 0xff) goto loser; } + if (buffer[i] != 0) + goto loser; /* * make sure we get the same results @@ -659,8 +685,12 @@ RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, goto failure; rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input); - if (rv != SECSuccess) + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } goto loser; + } if (buffer[0] != 0 || buffer[1] != 2) goto loser; @@ -719,6 +749,9 @@ RSA_SignRaw(NSSLOWKEYPrivateKey *key, goto done; rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *output_len = modulus_len; done: @@ -868,8 +901,12 @@ RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, goto failure; rv = RSA_PrivateKeyOp(&key->u.rsa, output, input); - if (rv != SECSuccess) + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } goto failure; + } *output_len = modulus_len; return SECSuccess; diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h index b89546e53..ed9108dcc 100644 --- a/security/nss/lib/softoken/softoken.h +++ b/security/nss/lib/softoken/softoken.h @@ -81,7 +81,7 @@ extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen, /* * convenience wrappers for doing single RSA operations. They create the * RSA context internally and take care of the formatting - * requirements. Blinding happens automagically within RSA_SignHash and + * requirements. Blinding happens automagically within RSA_Sign and * RSA_DecryptBlock. */ extern @@ -89,10 +89,20 @@ SECStatus RSA_Sign(NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, unsigned char *input, unsigned int inputLen); extern +SECStatus RSA_HashSign(SECOidTag hashOid, + NSSLOWKEYPrivateKey *key, unsigned char *sig, + unsigned int *sigLen, unsigned int maxLen, + unsigned char *hash, unsigned int hashLen); +extern SECStatus RSA_CheckSign(NSSLOWKEYPublicKey *key, unsigned char *sign, unsigned int signLength, unsigned char *hash, unsigned int hashLength); extern +SECStatus RSA_HashCheckSign(SECOidTag hashOid, + NSSLOWKEYPublicKey *key, unsigned char *sig, + unsigned int sigLen, unsigned char *digest, + unsigned int digestLen); +extern SECStatus RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data, unsigned int *data_len,unsigned int max_output_len, unsigned char *sign, unsigned int sign_len); @@ -131,6 +141,14 @@ SECStatus RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *output_len, unsigned int max_output_len, unsigned char *input, unsigned int input_len); +#ifdef NSS_ENABLE_ECC +/* +** pepare an ECParam structure from DEREncoded params + */ +extern SECStatus EC_FillParams(PRArenaPool *arena, + const SECItem *encodedParams, ECParams *params); +#endif + /* ** Prepare a buffer for DES encryption, growing to the appropriate boundary, @@ -159,6 +177,83 @@ extern CK_RV sftk_fipsPowerUpSelfTest( void ); */ unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType); +/* +** FIPS 140-2 auditing +*/ +extern PRBool sftk_audit_enabled; + +extern void sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg); + +extern void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject, CK_RV rv); + +extern void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv); + +extern void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_RV rv); + +extern void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, + CK_RV rv); + +extern void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv); + +extern void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv); + +extern void sftk_AuditCryptInit(const char *opName, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey, CK_RV rv); + +extern void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); + +extern void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv); + +extern void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv); + +extern void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); + +extern void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); + +extern void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hKey, CK_RV rv); + +/* +** FIPS 140-2 Error state +*/ +extern PRBool sftk_fatalError; + SEC_END_PROTOS #endif /* _SOFTOKEN_H_ */ diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc index 0fcaa1219..bbf8905a0 100644 --- a/security/nss/lib/softoken/softokn.rc +++ b/security/nss/lib/softoken/softokn.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h index b499eb6b0..3af94e286 100644 --- a/security/nss/lib/softoken/softoknt.h +++ b/security/nss/lib/softoken/softoknt.h @@ -61,4 +61,13 @@ typedef enum { #define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048 +/* + * FIPS 140-2 auditing + */ +typedef enum { + NSS_AUDIT_ERROR = 3, /* errors */ + NSS_AUDIT_WARNING = 2, /* warning messages */ + NSS_AUDIT_INFO = 1 /* informational messages */ +} NSSAuditSeverity; + #endif /* _SOFTOKNT_H_ */ diff --git a/security/nss/lib/ssl/derive.c b/security/nss/lib/ssl/derive.c index c00822bee..9e7727398 100644 --- a/security/nss/lib/ssl/derive.c +++ b/security/nss/lib/ssl/derive.c @@ -52,6 +52,7 @@ buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result) result->type = siBuffer; result->data = keyBlock; result->len = keyLen; + PRINT_BUF(100, (NULL, "key value", keyBlock, keyLen)); } #else #define buildSSLKey(keyBlock, keyLen, result) \ @@ -59,6 +60,7 @@ buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result) (result)->type = siBuffer; \ (result)->data = keyBlock; \ (result)->len = keyLen; \ + PRINT_BUF(100, (NULL, "key value", keyBlock, keyLen)); \ } #endif @@ -122,6 +124,9 @@ ssl3_KeyAndMacDeriveBypass( return rv; } + PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, + pwSpec->msItem.len)); + /* figure out how much is needed */ macSize = pwSpec->mac_size; keySize = cipher_def->key_size; @@ -153,6 +158,7 @@ ssl3_KeyAndMacDeriveBypass( crsr.len = sizeof crsrdata; PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); + PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len)); /* * generate the key material: @@ -203,6 +209,7 @@ ssl3_KeyAndMacDeriveBypass( } PORT_Assert(block_bytes >= block_needed); PORT_Assert(block_bytes <= sizeof pwSpec->key_block); + PRINT_BUF(100, (NULL, "key block", key_block, block_bytes)); /* * Put the key material where it goes. @@ -395,7 +402,9 @@ key_and_mac_derive_fail: /* derive the Master Secret from the PMS */ -/* Presently, this is only done wtih RSA PMS, os isRSA is always true. */ +/* Presently, this is only done wtih RSA PMS, and only on the server side, + * so isRSA is always true. + */ SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec, @@ -434,6 +443,7 @@ ssl3_MasterKeyDeriveBypass( crsr.len = sizeof crsrdata; PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); + PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); /* finally do the key gen */ if (isTLS) { @@ -474,6 +484,8 @@ ssl3_MasterKeyDeriveBypass( SSL3_MASTER_SECRET_LENGTH); pwSpec->msItem.data = pwSpec->raw_master_secret; pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; + PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, + pwSpec->msItem.len)); return rv; } diff --git a/security/nss/lib/ssl/emulate.c b/security/nss/lib/ssl/emulate.c deleted file mode 100644 index a381cd7d2..000000000 --- a/security/nss/lib/ssl/emulate.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Functions that emulate PR_AcceptRead and PR_TransmitFile for SSL sockets. - * Each Layered NSPR protocol (like SSL) must unfortunately contain its - * own implementation of these functions. This code was taken from NSPR. - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#include "nspr.h" - -#if defined( XP_UNIX ) || defined( XP_BEOS ) -#include <fcntl.h> -#endif -#if defined(WIN32) -#include <windef.h> -#include <winbase.h> -#endif -#include <string.h> - -#define AMASK 7 /* mask for alignment of PRNetAddr */ - -/* - * _PR_EmulateAcceptRead - * - * Accept an incoming connection on sd, set *nd to point to the - * newly accepted socket, read 'amount' bytes from the accepted - * socket. - * - * buf is a buffer of length = amount + (2 * sizeof(PRNetAddr)) + 32 - * *raddr points to the PRNetAddr of the accepted connection upon - * return - * - * return number of bytes read or -1 on error - * - */ -PRInt32 -ssl_EmulateAcceptRead( PRFileDesc * sd, - PRFileDesc ** nd, - PRNetAddr ** raddr, - void * buf, - PRInt32 amount, - PRIntervalTime timeout) -{ - PRFileDesc * newsockfd; - PRInt32 rv; - PRNetAddr remote; - - if (!(newsockfd = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT))) { - return -1; - } - - rv = PR_Recv(newsockfd, buf, amount, 0, timeout); - if (rv >= 0) { - ptrdiff_t pNetAddr = (((ptrdiff_t)buf) + amount + AMASK) & ~AMASK; - - *nd = newsockfd; - *raddr = (PRNetAddr *)pNetAddr; - memcpy((void *)pNetAddr, &remote, sizeof(PRNetAddr)); - return rv; - } - - PR_Close(newsockfd); - return -1; -} - - -#if !defined( XP_UNIX ) && !defined( WIN32 ) && !defined( XP_BEOS ) -/* - * _PR_EmulateTransmitFile - * - * Send file fd across socket sd. If headers is non-NULL, 'hlen' - * bytes of headers is sent before sending the file. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ -#define _TRANSMITFILE_BUFSIZE (16 * 1024) - -PRInt32 -ssl_EmulateTransmitFile( PRFileDesc * sd, - PRFileDesc * fd, - const void * headers, - PRInt32 hlen, - PRTransmitFileFlags flags, - PRIntervalTime timeout) -{ - char * buf = NULL; - PRInt32 count = 0; - PRInt32 rlen; - PRInt32 rv; - - buf = PR_MALLOC(_TRANSMITFILE_BUFSIZE); - if (buf == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - - /* - * send headers, first - */ - while (hlen) { - rv = PR_Send(sd, headers, hlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } - count += rv; - headers = (const void*) ((const char*)headers + rv); - hlen -= rv; - } - /* - * send file, next - */ - while ((rlen = PR_Read(fd, buf, _TRANSMITFILE_BUFSIZE)) > 0) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen,0,PR_INTERVAL_NO_TIMEOUT); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } - count += rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - if (rlen == 0) { - /* - * end-of-file - */ - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) - PR_Close(sd); - rv = count; - } else { - PR_ASSERT(rlen < 0); - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - } - -done: - if (buf) - PR_DELETE(buf); - return rv; -} -#else - -#define TRANSMITFILE_MMAP_CHUNK (256 * 1024) - -/* - * _PR_UnixTransmitFile - * - * Send file fd across socket sd. If headers is non-NULL, 'hlen' - * bytes of headers is sent before sending the file. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ - -PRInt32 -ssl_EmulateTransmitFile( PRFileDesc * sd, - PRFileDesc * fd, - const void * headers, - PRInt32 hlen, - PRTransmitFileFlags flags, - PRIntervalTime timeout) -{ - void * addr = NULL; - PRFileMap * mapHandle = NULL; - PRInt32 count = 0; - PRInt32 index = 0; - PRInt32 len = 0; - PRInt32 rv; - struct PRFileInfo info; - struct PRIOVec iov[2]; - - /* Get file size */ - if (PR_SUCCESS != PR_GetOpenFileInfo(fd, &info)) { - count = -1; - goto done; - } - if (hlen) { - iov[index].iov_base = (char *) headers; - iov[index].iov_len = hlen; - index++; - } - if (info.size > 0) { - mapHandle = PR_CreateFileMap(fd, info.size, PR_PROT_READONLY); - if (mapHandle == NULL) { - count = -1; - goto done; - } - /* - * If the file is large, mmap and send the file in chunks so as - * to not consume too much virtual address space - */ - len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK ); - /* - * Map in (part of) file. Take care of zero-length files. - */ - if (len) { - addr = PR_MemMap(mapHandle, 0, len); - if (addr == NULL) { - count = -1; - goto done; - } - } - iov[index].iov_base = (char*)addr; - iov[index].iov_len = len; - index++; - } - if (!index) - goto done; - rv = PR_Writev(sd, iov, index, timeout); - if (len) { - PR_MemUnmap(addr, len); - } - if (rv >= 0) { - PR_ASSERT(rv == hlen + len); - info.size -= len; - count += rv; - } else { - count = -1; - goto done; - } - /* - * send remaining bytes of the file, if any - */ - len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK ); - while (len > 0) { - /* - * Map in (part of) file - */ - PR_ASSERT((count - hlen) % TRANSMITFILE_MMAP_CHUNK == 0); - addr = PR_MemMap(mapHandle, count - hlen, len); - if (addr == NULL) { - count = -1; - goto done; - } - rv = PR_Send(sd, addr, len, 0, timeout); - PR_MemUnmap(addr, len); - if (rv >= 0) { - PR_ASSERT(rv == len); - info.size -= rv; - count += rv; - len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK ); - } else { - count = -1; - goto done; - } - } -done: - if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - if (mapHandle != NULL) - PR_CloseFileMap(mapHandle); - return count; -} -#endif /* XP_UNIX || WIN32 || XP_BEOS */ - - - - -#if !defined( XP_UNIX ) && !defined( WIN32 ) && !defined( XP_BEOS ) -/* - * _PR_EmulateSendFile - * - * Send file sfd->fd across socket sd. The header and trailer buffers - * specified in the 'sfd' argument are sent before and after the file, - * respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ - -PRInt32 -ssl_EmulateSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - char * buf = NULL; - const void * buffer; - PRInt32 rv; - PRInt32 count = 0; - PRInt32 rlen; - PRInt32 buflen; - PRInt32 sendbytes; - PRInt32 readbytes; - -#define _SENDFILE_BUFSIZE (16 * 1024) - - buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE); - if (buf == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - - /* - * send header, first - */ - buflen = sfd->hlen; - buffer = sfd->header; - while (buflen) { - rv = PR_Send(sd, buffer, buflen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - buffer = (const void*) ((const char*)buffer + rv); - buflen -= rv; - } - } - /* - * send file, next - */ - - if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) { - rv = -1; - goto done; - } - sendbytes = sfd->file_nbytes; - if (sendbytes == 0) { - /* send entire file */ - while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - } - if (rlen < 0) { - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - goto done; - } - } else { - readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); - while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - sendbytes -= rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); - } - if (rlen < 0) { - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else if (sendbytes != 0) { - /* - * there are fewer bytes in file to send than specified - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = -1; - goto done; - } - } - /* - * send trailer, last - */ - buflen = sfd->tlen; - buffer = sfd->trailer; - while (buflen) { - rv = PR_Send(sd, buffer, buflen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - buffer = (const void*) ((const char*)buffer + rv); - buflen -= rv; - } - } - rv = count; - -done: - if (buf) - PR_DELETE(buf); - if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - return rv; -} - -#else /* UNIX, NT, and BEOS handled below */ - -/* - * _PR_UnixSendFile - * - * Send file sfd->fd across socket sd. If header/trailer are specified - * they are sent before and after the file, respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ -#define SENDFILE_MMAP_CHUNK (256 * 1024) - -PRInt32 -ssl_EmulateSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - void * addr = NULL; - PRFileMap * mapHandle = NULL; - PRInt32 count = 0; - PRInt32 file_bytes; - PRInt32 index = 0; - PRInt32 len; - PRInt32 rv; - PRUint32 addr_offset; - PRUint32 file_mmap_offset; - PRUint32 mmap_len; - PRUint32 pagesize; - struct PRFileInfo info; - struct PRIOVec iov[3]; - - /* Get file size */ - if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) { - count = -1; - goto done; - } - if (sfd->file_nbytes && - (info.size < (sfd->file_offset + sfd->file_nbytes))) { - /* - * there are fewer bytes in file to send than specified - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - count = -1; - goto done; - } - if (sfd->file_nbytes) - file_bytes = sfd->file_nbytes; - else - file_bytes = info.size - sfd->file_offset; - -#if defined(WIN32) - { - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - pagesize = sysinfo.dwAllocationGranularity; - } -#else - pagesize = PR_GetPageSize(); -#endif - /* - * If the file is large, mmap and send the file in chunks so as - * to not consume too much virtual address space - */ - if (!sfd->file_offset || !(sfd->file_offset & (pagesize - 1))) { - /* - * case 1: page-aligned file offset - */ - mmap_len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - len = mmap_len; - file_mmap_offset = sfd->file_offset; - addr_offset = 0; - } else { - /* - * case 2: non page-aligned file offset - */ - /* find previous page boundary */ - file_mmap_offset = (sfd->file_offset & ~(pagesize - 1)); - - /* number of initial bytes to skip in mmap'd segment */ - addr_offset = sfd->file_offset - file_mmap_offset; - PR_ASSERT(addr_offset > 0); - mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK); - len = mmap_len - addr_offset; - } - /* - * OK I've convinced myself that length has to be possitive (file_bytes is - * negative or SENDFILE_MMAP_CHUNK is less than pagesize). Just assert - * that this is the case so we catch problems in debug builds. - */ - PR_ASSERT(len >= 0); - - /* - * Map in (part of) file. Take care of zero-length files. - */ - if (len > 0) { - mapHandle = PR_CreateFileMap(sfd->fd, info.size, PR_PROT_READONLY); - if (!mapHandle) { - count = -1; - goto done; - } - addr = PR_MemMap(mapHandle, file_mmap_offset, mmap_len); - if (!addr) { - count = -1; - goto done; - } - } - /* - * send headers, first, followed by the file - */ - if (sfd->hlen) { - iov[index].iov_base = (char *) sfd->header; - iov[index].iov_len = sfd->hlen; - index++; - } - if (len) { - iov[index].iov_base = (char*)addr + addr_offset; - iov[index].iov_len = len; - index++; - } - if ((file_bytes == len) && (sfd->tlen)) { - /* - * all file data is mapped in; send the trailer too - */ - iov[index].iov_base = (char *) sfd->trailer; - iov[index].iov_len = sfd->tlen; - index++; - } - rv = PR_Writev(sd, iov, index, timeout); - if (len) - PR_MemUnmap(addr, mmap_len); - if (rv < 0) { - count = -1; - goto done; - } - - PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0)); - - file_bytes -= len; - count += rv; - if (!file_bytes) /* header, file and trailer are sent */ - goto done; - - /* - * send remaining bytes of the file, if any - */ - len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - while (len > 0) { - /* - * Map in (part of) file - */ - file_mmap_offset = sfd->file_offset + count - sfd->hlen; - PR_ASSERT((file_mmap_offset % pagesize) == 0); - - addr = PR_MemMap(mapHandle, file_mmap_offset, len); - if (!addr) { - count = -1; - goto done; - } - rv = PR_Send(sd, addr, len, 0, timeout); - PR_MemUnmap(addr, len); - if (rv < 0) { - count = -1; - goto done; - } - - PR_ASSERT(rv == len); - file_bytes -= rv; - count += rv; - len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - } - PR_ASSERT(0 == file_bytes); - if (sfd->tlen) { - rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout); - if (rv >= 0) { - PR_ASSERT(rv == sfd->tlen); - count += rv; - } else - count = -1; - } -done: - if (mapHandle) - PR_CloseFileMap(mapHandle); - if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - return count; -} -#endif /* UNIX, NT, and BEOS */ diff --git a/security/nss/lib/ssl/manifest.mn b/security/nss/lib/ssl/manifest.mn index 6428ce5c7..06e2eb118 100644 --- a/security/nss/lib/ssl/manifest.mn +++ b/security/nss/lib/ssl/manifest.mn @@ -56,7 +56,6 @@ MAPFILE = $(OBJDIR)/ssl.def CSRCS = \ derive.c \ - emulate.c \ prelib.c \ ssl3con.c \ ssl3gthr.c \ diff --git a/security/nss/lib/ssl/ssl.def b/security/nss/lib/ssl/ssl.def index 745934e92..ae12b2bf5 100644 --- a/security/nss/lib/ssl/ssl.def +++ b/security/nss/lib/ssl/ssl.def @@ -126,3 +126,10 @@ SSL_ShutdownServerSessionIDCache; ;+ local: ;+*; ;+}; +;+NSS_3.11.4 { # NSS 3.11.4 release +;+ global: +SSL_ForceHandshakeWithTimeout; +SSL_ReHandshakeWithTimeout; +;+ local: +;+*; +;+}; diff --git a/security/nss/lib/ssl/ssl.rc b/security/nss/lib/ssl/ssl.rc index b20493219..b7d827de7 100644 --- a/security/nss/lib/ssl/ssl.rc +++ b/security/nss/lib/ssl/ssl.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 2b34b9519..bf37f19d3 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -74,7 +74,7 @@ static void ssl3_CleanupPeerCerts(sslSocket *ss); static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, PK11SlotInfo * serverKeySlot); -static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms); +static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss); static SECStatus ssl3_HandshakeFailure( sslSocket *ss); static SECStatus ssl3_InitState( sslSocket *ss); @@ -103,6 +103,10 @@ static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, */ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { /* cipher_suite policy enabled is_present*/ +#ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, +#endif /* NSS_ENABLE_ECC */ { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #ifdef NSS_ENABLE_ECC @@ -112,7 +116,9 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #endif /* NSS_ENABLE_ECC */ { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, @@ -128,6 +134,10 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, +#ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, +#endif /* NSS_ENABLE_ECC */ { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #ifdef NSS_ENABLE_ECC @@ -140,10 +150,6 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, -#ifdef NSS_ENABLE_ECC - { TLS_ECDH_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, - { TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, -#endif /* NSS_ENABLE_ECC */ { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, @@ -153,6 +159,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, #ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, #endif /* NSS_ENABLE_ECC */ @@ -236,6 +244,7 @@ static const ssl3KEADef kea_defs[] = {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE}, {kea_ecdh_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE}, {kea_ecdhe_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE}, + {kea_ecdh_anon, kt_ecdh, sign_null, PR_FALSE, 0, PR_FALSE}, #endif /* NSS_ENABLE_ECC */ }; @@ -315,24 +324,37 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips}, #ifdef NSS_ENABLE_ECC - /* Experimental TLS cipher suites using Elliptic Curves */ {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa}, - {TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_rsa}, - {TLS_ECDH_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_rsa}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_rsa}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa}, +#if 0 + {TLS_ECDH_anon_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_anon}, +#endif #endif /* NSS_ENABLE_ECC */ }; @@ -395,6 +417,29 @@ const char * const ssl3_cipherName[] = { "missing" }; +#ifdef NSS_ENABLE_ECC +/* The ECCWrappedKeyInfo structure defines how various pieces of + * information are laid out within wrappedSymmetricWrappingkey + * for ECDH key exchange. Since wrappedSymmetricWrappingkey is + * a 512-byte buffer (see sslimpl.h), the variable length field + * in ECCWrappedKeyInfo can be at most (512 - 8) = 504 bytes. + * + * XXX For now, NSS only supports named elliptic curves of size 571 bits + * or smaller. The public value will fit within 145 bytes and EC params + * will fit within 12 bytes. We'll need to revisit this when NSS + * supports arbitrary curves. + */ +#define MAX_EC_WRAPPED_KEY_BUFLEN 504 + +typedef struct ECCWrappedKeyInfoStr { + PRUint16 size; /* EC public key size in bits */ + PRUint16 encodedParamLen; /* length (in bytes) of DER encoded EC params */ + PRUint16 pubValueLen; /* length (in bytes) of EC public value */ + PRUint16 wrappedKeyLen; /* length (in bytes) of the wrapped key */ + PRUint8 var[MAX_EC_WRAPPED_KEY_BUFLEN]; /* this buffer contains the */ + /* EC public-key params, the EC public value and the wrapped key */ +} ECCWrappedKeyInfo; +#endif /* NSS_ENABLE_ECC */ #if defined(TRACE) @@ -450,6 +495,26 @@ SSL_GetStatistics(void) return &ssl3stats; } +typedef struct tooLongStr { +#if defined(IS_LITTLE_ENDIAN) + PRInt32 low; + PRInt32 high; +#else + PRInt32 high; + PRInt32 low; +#endif +} tooLong; + +static void SSL_AtomicIncrementLong(long * x) +{ + if ((sizeof *x) == sizeof(PRInt32)) { + PR_AtomicIncrement((PRInt32 *)x); + } else { + tooLong * tl = (tooLong *)x; + PR_AtomicIncrement(&tl->low) || PR_AtomicIncrement(&tl->high); + } +} + /* return pointer to ssl3CipherSuiteDef for suite, or NULL */ /* XXX This does a linear search. A binary search would be better. */ static const ssl3CipherSuiteDef * @@ -504,10 +569,15 @@ ssl3_config_match_init(sslSocket *ss) PRBool isServer; sslServerCerts *svrAuth; + PORT_Assert(ss); + if (!ss) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return 0; + } if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) { return 0; } - isServer = (PRBool)( ss && ss->sec.isServer ); + isServer = (PRBool)(ss->sec.isServer != 0); for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { suite = &ss->cipherSuites[i]; @@ -536,7 +606,15 @@ ssl3_config_match_init(sslSocket *ss) */ switch (cipher_def->key_exchange_alg) { case kea_ecdhe_rsa: +#if NSS_SERVER_DHE_IMPLEMENTED + /* XXX NSS does not yet implement the server side of _DHE_ + * cipher suites. Correcting the computation for svrAuth, + * as the case below does, causes NSS SSL servers to begin to + * negotiate cipher suites they do not implement. So, until + * server side _DHE_ is implemented, keep this disabled. + */ case kea_dhe_rsa: +#endif svrAuth = ss->serverCerts + kt_rsa; break; case kea_ecdh_ecdsa: @@ -715,7 +793,7 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf, } buf->len = (unsigned)signatureLen; - buf->data = (unsigned char *)PORT_Alloc(signatureLen + 1); + buf->data = (unsigned char *)PORT_Alloc(signatureLen); if (!buf->data) goto done; /* error code was set. */ @@ -749,7 +827,7 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf, SECItem derSig = {siBuffer, NULL, 0}; /* This also works for an ECDSA signature */ - rv = DSAU_EncodeDerSigWithLen(&derSig, buf, (unsigned) signatureLen); + rv = DSAU_EncodeDerSigWithLen(&derSig, buf, buf->len); if (rv == SECSuccess) { PORT_Free(buf->data); /* discard unencoded signature. */ *buf = derSig; /* give caller encoded signature. */ @@ -818,7 +896,7 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, * using ASN (unlike DSA where ASN encoding is used * with TLS but not with SSL3) */ - len = SECKEY_PublicKeyStrength(key) * 2; + len = SECKEY_SignatureLen(key); if (len == 0) { SECKEY_DestroyPublicKey(key); PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); @@ -1693,32 +1771,164 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) { return isPresent; } +static SECStatus +ssl3_CompressMACEncryptRecord(sslSocket * ss, + SSL3ContentType type, + const SSL3Opaque * pIn, + PRUint32 contentLen) +{ + ssl3CipherSpec * cwSpec; + const ssl3BulkCipherDef * cipher_def; + sslBuffer * wrBuf = &ss->sec.writeBuf; + SECStatus rv; + PRUint32 macLen = 0; + PRUint32 fragLen; + PRUint32 p1Len, p2Len, oddLen = 0; + PRInt32 cipherBytes = 0; + + /* + * null compression is easy to do + PORT_Memcpy(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, pIn, contentLen); + */ + + ssl_GetSpecReadLock(ss); /********************************/ + + cwSpec = ss->ssl3.cwSpec; + cipher_def = cwSpec->cipher_def; + /* + * Add the MAC + */ + rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer), + type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen, + wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen); + if (rv != SECSuccess) { + ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); + goto spec_locked_loser; + } + p1Len = contentLen; + p2Len = macLen; + fragLen = contentLen + macLen; /* needs to be encrypted */ + PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024); + + /* + * Pad the text (if we're doing a block cipher) + * then Encrypt it + */ + if (cipher_def->type == type_block) { + unsigned char * pBuf; + int padding_length; + int i; + + oddLen = contentLen % cipher_def->block_size; + /* Assume blockSize is a power of two */ + padding_length = cipher_def->block_size - 1 - + ((fragLen) & (cipher_def->block_size - 1)); + fragLen += padding_length + 1; + PORT_Assert((fragLen % cipher_def->block_size) == 0); + + /* Pad according to TLS rules (also acceptable to SSL3). */ + pBuf = &wrBuf->buf[fragLen + SSL3_RECORD_HEADER_LENGTH - 1]; + for (i = padding_length + 1; i > 0; --i) { + *pBuf-- = padding_length; + } + /* now, if contentLen is not a multiple of block size, fix it */ + p2Len = fragLen - p1Len; + } + if (p1Len < 256) { + oddLen = p1Len; + p1Len = 0; + } else { + p1Len -= oddLen; + } + if (oddLen) { + p2Len += oddLen; + PORT_Assert( (cipher_def->block_size < 2) || \ + (p2Len % cipher_def->block_size) == 0); + memcpy(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, + pIn + p1Len, oddLen); + } + if (p1Len > 0) { + rv = cwSpec->encode( cwSpec->encodeContext, + wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, /* output */ + &cipherBytes, /* actual outlen */ + p1Len, /* max outlen */ + pIn, p1Len); /* input, and inputlen */ + PORT_Assert(rv == SECSuccess && cipherBytes == p1Len); + if (rv != SECSuccess || cipherBytes != p1Len) { + PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); + goto spec_locked_loser; + } + } + if (p2Len > 0) { + PRInt32 cipherBytesPart2 = -1; + rv = cwSpec->encode( cwSpec->encodeContext, + wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, + &cipherBytesPart2, /* output and actual outLen */ + p2Len, /* max outlen */ + wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, + p2Len); /* input and inputLen*/ + PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len); + if (rv != SECSuccess || cipherBytesPart2 != p2Len) { + PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); + goto spec_locked_loser; + } + cipherBytes += cipherBytesPart2; + } + PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024); + + ssl3_BumpSequenceNumber(&cwSpec->write_seq_num); + + wrBuf->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH; + wrBuf->buf[0] = type; + wrBuf->buf[1] = MSB(cwSpec->version); + wrBuf->buf[2] = LSB(cwSpec->version); + wrBuf->buf[3] = MSB(cipherBytes); + wrBuf->buf[4] = LSB(cipherBytes); + + ssl_ReleaseSpecReadLock(ss); /************************************/ + + return SECSuccess; + +spec_locked_loser: + ssl_ReleaseSpecReadLock(ss); + return SECFailure; +} + /* Process the plain text before sending it. * Returns the number of bytes of plaintext that were succesfully sent * plus the number of bytes of plaintext that were copied into the * output (write) buffer. * Returns SECFailure on a hard IO error, memory error, or crypto error. * Does NOT return SECWouldBlock. + * + * Notes on the use of the private ssl flags: + * (no private SSL flags) + * Attempt to make and send SSL records for all plaintext + * If non-blocking and a send gets WOULD_BLOCK, + * or if the pending (ciphertext) buffer is not empty, + * then buffer remaining bytes of ciphertext into pending buf, + * and continue to do that for all succssive records until all + * bytes are used. + * ssl_SEND_FLAG_FORCE_INTO_BUFFER + * As above, except this suppresses all write attempts, and forces + * all ciphertext into the pending ciphertext buffer. + * */ static PRInt32 ssl3_SendRecord( sslSocket * ss, SSL3ContentType type, - const SSL3Opaque * buf, - PRInt32 bytes, + const SSL3Opaque * pIn, /* input buffer */ + PRInt32 nIn, /* bytes of input */ PRInt32 flags) { - ssl3CipherSpec * cwSpec; - sslBuffer * write = &ss->sec.writeBuf; - const ssl3BulkCipherDef * cipher_def; + sslBuffer * wrBuf = &ss->sec.writeBuf; SECStatus rv; - PRUint32 bufSize = 0; - PRInt32 sent = 0; - PRBool isBlocking = ssl_SocketIsBlocking(ss); + PRInt32 totalSent = 0; - SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s bytes=%d", + SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), - bytes)); - PRINT_BUF(3, (ss, "Send record (plain text)", buf, bytes)); + nIn)); + PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); @@ -1740,149 +1950,30 @@ ssl3_SendRecord( sslSocket * ss, return SECFailure; } - while (bytes > 0) { - PRInt32 count; - PRUint32 contentLen; - PRUint32 fragLen; - PRUint32 macLen; - PRInt32 cipherBytes = 0; - PRUint32 p1Len, p2Len, oddLen = 0; + while (nIn > 0) { + PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); - contentLen = PR_MIN(bytes, MAX_FRAGMENT_LENGTH); - if (write->space < contentLen + SSL3_BUFFER_FUDGE) { - rv = sslBuffer_Grow(write, contentLen + SSL3_BUFFER_FUDGE); + if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) { + PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen); + newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH); + newSpace += SSL3_BUFFER_FUDGE; + rv = sslBuffer_Grow(wrBuf, newSpace); if (rv != SECSuccess) { SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", - SSL_GETPID(), ss->fd, contentLen + SSL3_BUFFER_FUDGE)); + SSL_GETPID(), ss->fd, newSpace)); return SECFailure; /* sslBuffer_Grow set a memory error code. */ } } - /* This variable records the actual size of the buffer allocated above. - * Some algorithms may expand the number of bytes needed to send data. - * If we only supply the output buffer with the same number - * of bytes as the input buffer, we will fail. - */ - bufSize = contentLen + SSL3_BUFFER_FUDGE; - - /* - * null compression is easy to do - PORT_Memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH, buf, contentLen); - */ - - ssl_GetSpecReadLock(ss); /********************************/ - - cwSpec = ss->ssl3.cwSpec; - cipher_def = cwSpec->cipher_def; - /* - * Add the MAC - */ - rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer), - type, cwSpec->version, cwSpec->write_seq_num, buf, contentLen, - write->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen); - if (rv != SECSuccess) { - ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); - goto spec_locked_loser; - } - p1Len = contentLen; - p2Len = macLen; - fragLen = contentLen + macLen; /* needs to be encrypted */ - PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024); - - /* - * Pad the text (if we're doing a block cipher) - * then Encrypt it - */ - if (cipher_def->type == type_block) { - unsigned char * pBuf; - int padding_length; - int i; - - oddLen = contentLen % cipher_def->block_size; - /* Assume blockSize is a power of two */ - padding_length = cipher_def->block_size - 1 - - ((fragLen) & (cipher_def->block_size - 1)); - fragLen += padding_length + 1; - PORT_Assert((fragLen % cipher_def->block_size) == 0); - - /* Pad according to TLS rules (also acceptable to SSL3). */ - pBuf = &write->buf[fragLen + SSL3_RECORD_HEADER_LENGTH - 1]; - for (i = padding_length + 1; i > 0; --i) { - *pBuf-- = padding_length; - } - /* now, if contentLen is not a multiple of block size, fix it */ - p2Len = fragLen - p1Len; - } - if (p1Len < 256) { - oddLen = p1Len; - p1Len = 0; - } else { - p1Len -= oddLen; - } - if (oddLen) { - p2Len += oddLen; - PORT_Assert( (cipher_def->block_size < 2) || \ - (p2Len % cipher_def->block_size) == 0); - memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, - buf + p1Len, oddLen); - } - if (p1Len > 0) { - rv = cwSpec->encode( cwSpec->encodeContext, - write->buf + SSL3_RECORD_HEADER_LENGTH, /* output */ - &cipherBytes, /* actual outlen */ - p1Len, /* max outlen */ - buf, p1Len); /* input, and inputlen */ - PORT_Assert(rv == SECSuccess && cipherBytes == p1Len); - if (rv != SECSuccess || cipherBytes != p1Len) { - PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); - goto spec_locked_loser; - } - } - if (p2Len > 0) { - PRInt32 cipherBytesPart2 = -1; - rv = cwSpec->encode( cwSpec->encodeContext, - write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, - &cipherBytesPart2, /* output and actual outLen */ - p2Len, /* max outlen */ - write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, - p2Len); /* input and inputLen*/ - PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len); - if (rv != SECSuccess || cipherBytesPart2 != p2Len) { - PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); - goto spec_locked_loser; - } - cipherBytes += cipherBytesPart2; - } - if (rv != SECSuccess) { - ssl_MapLowLevelError(SSL_ERROR_ENCRYPTION_FAILURE); -spec_locked_loser: - ssl_ReleaseSpecReadLock(ss); + rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen); + if (rv != SECSuccess) return SECFailure; - } - PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024); - /* - * XXX should we zero out our copy of the buffer after compressing - * and encryption ?? - */ - - ssl3_BumpSequenceNumber(&cwSpec->write_seq_num); - - ssl_ReleaseSpecReadLock(ss); /************************************/ - - buf += contentLen; - bytes -= contentLen; - PORT_Assert( bytes >= 0 ); + pIn += contentLen; + nIn -= contentLen; + PORT_Assert( nIn >= 0 ); - /* PORT_Assert(fragLen == cipherBytes); */ - write->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH; - write->buf[0] = type; - write->buf[1] = MSB(cwSpec->version); - write->buf[2] = LSB(cwSpec->version); - write->buf[3] = MSB(cipherBytes); - write->buf[4] = LSB(cipherBytes); - - PRINT_BUF(50, (ss, "send (encrypted) record data:", write->buf, write->len)); + PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len)); /* If there's still some previously saved ciphertext, * or the caller doesn't want us to send the data yet, @@ -1891,59 +1982,57 @@ spec_locked_loser: if ((ss->pendingBuf.len > 0) || (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { - rv = ssl_SaveWriteData(ss, &ss->pendingBuf, - write->buf, write->len); + rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ return SECFailure; } - write->len = 0; /* All cipher text is saved away. */ + wrBuf->len = 0; /* All cipher text is saved away. */ if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { - + PRInt32 sent; ss->handshakeBegun = 1; - count = ssl_SendSavedWriteData(ss, &ss->pendingBuf, - &ssl_DefSend); - if (count < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) { + sent = ssl_SendSavedWriteData(ss); + if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) { ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); return SECFailure; } + if (ss->pendingBuf.len) { + flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER; + } } - } else if (write->len > 0) { + } else if (wrBuf->len > 0) { + PRInt32 sent; ss->handshakeBegun = 1; - count = ssl_DefSend(ss, write->buf, write->len, - flags & ~ssl_SEND_FLAG_MASK); - if (count < 0) { + sent = ssl_DefSend(ss, wrBuf->buf, wrBuf->len, + flags & ~ssl_SEND_FLAG_MASK); + if (sent < 0) { if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); - return (sent > 0) ? sent : SECFailure; + return SECFailure; } /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */ - count = 0; + sent = 0; } - /* now take all the remaining unsent newly-generated ciphertext and - * append it to the buffer of previously unsent ciphertext. - */ - if ((unsigned)count < write->len) { - rv = ssl_SaveWriteData(ss, &ss->pendingBuf, - write->buf + (unsigned)count, - write->len - (unsigned)count); + wrBuf->len -= sent; + if (wrBuf->len) { + /* now take all the remaining unsent new ciphertext and + * append it to the buffer of previously unsent ciphertext. + */ + rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ return SECFailure; } } - write->len = 0; - } - sent += contentLen; - if ((flags & ssl_SEND_FLAG_NO_BUFFER) && - (isBlocking || (ss->pendingBuf.len > 0))) { - break; } + totalSent += contentLen; } - return sent; + return totalSent; } +#define SSL3_PENDING_HIGH_WATER 1024 + /* Attempt to send the content of "in" in an SSL application_data record. * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess. */ @@ -1951,14 +2040,36 @@ int ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, PRInt32 len, PRInt32 flags) { - PRInt32 sent = 0; + PRInt32 totalSent = 0; + PRInt32 discarded = 0; PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); + if (len < 0 || !in) { + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); + return SECFailure; + } + + if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && + !ssl_SocketIsBlocking(ss)) { + PORT_Assert(!ssl_SocketIsBlocking(ss)); + PORT_SetError(PR_WOULD_BLOCK_ERROR); + return SECFailure; + } - while (len > 0) { - PRInt32 count; + if (ss->appDataBuffered && len) { + PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); + if (in[0] != (unsigned char)(ss->appDataBuffered)) { + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); + return SECFailure; + } + in++; + len--; + discarded = 1; + } + while (len > totalSent) { + PRInt32 sent, toSend; - if (sent > 0) { + if (totalSent > 0) { /* * The thread yield is intended to give the reader thread a * chance to get some cycles while the writer thread is in @@ -1969,23 +2080,45 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */ ssl_GetXmitBufLock(ss); } - count = ssl3_SendRecord(ss, content_application_data, in, len, - flags | ssl_SEND_FLAG_NO_BUFFER); - if (count < 0) { - return (sent > 0) ? sent : count; - /* error code set by ssl3_SendRecord */ + toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH); + sent = ssl3_SendRecord(ss, content_application_data, + in + totalSent, toSend, flags); + if (sent < 0) { + if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) { + PORT_Assert(ss->lastWriteBlocked); + break; + } + return SECFailure; /* error code set by ssl3_SendRecord */ + } + totalSent += sent; + if (ss->pendingBuf.len) { + /* must be a non-blocking socket */ + PORT_Assert(!ssl_SocketIsBlocking(ss)); + PORT_Assert(ss->lastWriteBlocked); + break; } - sent += count; - len -= count; - in += count; } - return sent; + if (ss->pendingBuf.len) { + /* Must be non-blocking. */ + PORT_Assert(!ssl_SocketIsBlocking(ss)); + if (totalSent > 0) { + ss->appDataBuffered = 0x100 | in[totalSent - 1]; + } + + totalSent = totalSent + discarded - 1; + if (totalSent <= 0) { + PORT_SetError(PR_WOULD_BLOCK_ERROR); + totalSent = SECFailure; + } + return totalSent; + } + ss->appDataBuffered = 0; + return totalSent + discarded; } /* Attempt to send the content of sendBuf buffer in an SSL handshake record. * This function returns SECSuccess or SECFailure, never SECWouldBlock. - * It used to always set sendBuf.len to 0, even when returning SECFailure. - * Now it does not. + * Always set sendBuf.len to 0, even when returning SECFailure. * * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(), * ssl3_AppendHandshake(), ssl3_SendClientHello(), @@ -1995,21 +2128,41 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, static SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags) { - PRInt32 rv; + PRInt32 rv = SECSuccess; PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) - return SECSuccess; + return rv; - rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf, - ss->sec.ci.sendBuf.len, flags); - if (rv < 0) { - return (SECStatus)rv; /* error code set by ssl3_SendRecord */ + /* only this flag is allowed */ + PORT_Assert(!(flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER)); + if ((flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER) != 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; + } else { + rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf, + ss->sec.ci.sendBuf.len, flags); } + if (rv < 0) { + int err = PORT_GetError(); + PORT_Assert(err != PR_WOULD_BLOCK_ERROR); + if (err == PR_WOULD_BLOCK_ERROR) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + } + } else if (rv < ss->sec.ci.sendBuf.len) { + /* short write should never happen */ + PORT_Assert(rv >= ss->sec.ci.sendBuf.len); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = SECFailure; + } else { + rv = SECSuccess; + } + + /* Whether we succeeded or failed, toss the old handshake data. */ ss->sec.ci.sendBuf.len = 0; - return SECSuccess; + return rv; } /* @@ -2218,7 +2371,19 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) case internal_error: error = SSL_ERROR_INTERNAL_ERROR_ALERT; break; case user_canceled: error = SSL_ERROR_USER_CANCELED_ALERT; break; case no_renegotiation: error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break; - default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; + + /* Alerts for TLS client hello extensions */ + case unsupported_extension: + error = SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT; break; + case certificate_unobtainable: + error = SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT; break; + case unrecognized_name: + error = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; break; + case bad_certificate_status_response: + error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break; + case bad_certificate_hash_value: + error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break; + default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; } if (level == alert_fatal) { ss->sec.uncache(ss->sec.ci.sid); @@ -2348,7 +2513,7 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) ss->ssl3.prSpec = ss->ssl3.crSpec; ss->ssl3.crSpec = prSpec; - ss->ssl3.hs.ws = wait_finished; + ss->ssl3.hs.ws = wait_finished; SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending", SSL_GETPID(), ss->fd )); @@ -2369,7 +2534,7 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) ** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec. */ static SECStatus -ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms) +ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) { ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec; const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def; @@ -2419,9 +2584,20 @@ ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms) } if (pms != NULL) { - pwSpec->master_secret = PK11_DeriveWithFlags((PK11SymKey *)pms, - master_derive, ¶ms, key_derive, - CKA_DERIVE, 0, keyFlags); +#if defined(TRACE) + if (ssl_trace >= 100) { + SECStatus extractRV = PK11_ExtractKeyValue(pms); + if (extractRV == SECSuccess) { + SECItem * keyData = PK11_GetKeyData(pms); + if (keyData && keyData->data && keyData->len) { + ssl_PrintBuf(ss, "Pre-Master Secret", + keyData->data, keyData->len); + } + } + } +#endif + pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive, + ¶ms, key_derive, CKA_DERIVE, 0, keyFlags); if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) { SSL3ProtocolVersion client_version; client_version = pms_version.major << 8 | pms_version.minor; @@ -2715,7 +2891,7 @@ ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes) return SECSuccess; } -static SECStatus +SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize) { SECStatus rv; @@ -2820,7 +2996,7 @@ ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b, * Thus, the largest value that may be sent this way is 0x7fffffff. * On error, an alert has been sent, and a generic error code has been set. */ -static PRInt32 +PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b, PRUint32 *length) { @@ -3192,6 +3368,7 @@ ssl3_SendClientHello(sslSocket *ss) int length; int num_suites; int actual_count = 0; + PRInt32 total_exten_len = 0; SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(), ss->fd)); @@ -3269,7 +3446,7 @@ ssl3_SendClientHello(sslSocket *ss) } if (!sidOK) { - ++ssl3stats.sch_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok ); (*ss->sec.uncache)(sid); ssl_FreeSID(sid); sid = NULL; @@ -3277,7 +3454,7 @@ ssl3_SendClientHello(sslSocket *ss) } if (sid) { - ++ssl3stats.sch_sid_cache_hits; + SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); rv = ssl3_NegotiateVersion(ss, sid->version); if (rv != SECSuccess) @@ -3288,7 +3465,7 @@ ssl3_SendClientHello(sslSocket *ss) ss->ssl3.policy = sid->u.ssl3.policy; } else { - ++ssl3stats.sch_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_3_1_TLS); if (rv != SECSuccess) @@ -3327,6 +3504,26 @@ ssl3_SendClientHello(sslSocket *ss) if (!num_suites) return SECFailure; /* ssl3_config_match_init has set error code. */ + if (ss->opt.enableTLS) { + PRUint32 maxBytes = 65535; /* 2^16 - 1 */ + PRInt32 extLen; + + extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL); + if (extLen < 0) { + return SECFailure; + } + maxBytes -= extLen; + total_exten_len += extLen; + + if (total_exten_len > 0) + total_exten_len += 2; + } +#if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B) + else { /* SSL3 only */ + ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ + } +#endif + /* how many suites are permitted by policy and user preference? */ num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE); if (!num_suites) @@ -3335,7 +3532,7 @@ ssl3_SendClientHello(sslSocket *ss) length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) + 2 + num_suites*sizeof(ssl3CipherSuite) + - 1 + compressionMethodsCount; + 1 + compressionMethodsCount + total_exten_len; rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); if (rv != SECSuccess) { @@ -3409,6 +3606,24 @@ ssl3_SendClientHello(sslSocket *ss) } } + if (total_exten_len) { + PRUint32 maxBytes = total_exten_len - 2; + PRInt32 extLen; + + rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2); + if (rv != SECSuccess) { + return rv; /* err set by AppendHandshake. */ + } + + extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL); + if (extLen < 0) { + return SECFailure; + } + maxBytes -= extLen; + PORT_Assert(!maxBytes); + } + + rv = ssl3_FlushHandshake(ss, 0); if (rv != SECSuccess) { return rv; /* error code set by ssl3_FlushHandshake */ @@ -3470,6 +3685,7 @@ static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = { CKM_CDMF_ECB, CKM_SKIPJACK_WRAP, CKM_SKIPJACK_CBC64, + CKM_AES_ECB, UNKNOWN_WRAP_MECHANISM }; @@ -3495,6 +3711,11 @@ ssl_UnwrapSymWrappingKey( { PK11SymKey * unwrappedWrappingKey = NULL; SECItem wrappedKey; +#ifdef NSS_ENABLE_ECC + PK11SymKey * Ks; + SECKEYPublicKey pubWrapKey; + ECCWrappedKeyInfo *ecWrapped; +#endif /* NSS_ENABLE_ECC */ /* found the wrapping key on disk. */ PORT_Assert(pWswk->symWrapMechanism == masterWrapMech); @@ -3515,6 +3736,60 @@ ssl_UnwrapSymWrappingKey( PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey, masterWrapMech, CKA_UNWRAP, 0); break; + +#ifdef NSS_ENABLE_ECC + case kt_ecdh: + /* + * For kt_ecdh, we first create an EC public key based on + * data stored with the wrappedSymmetricWrappingkey. Next, + * we do an ECDH computation involving this public key and + * the SSL server's (long-term) EC private key. The resulting + * shared secret is treated the same way as Fortezza's Ks, i.e., + * it is used to recover the symmetric wrapping key. + * + * The data in wrappedSymmetricWrappingkey is laid out as defined + * in the ECCWrappedKeyInfo structure. + */ + ecWrapped = (ECCWrappedKeyInfo *) pWswk->wrappedSymmetricWrappingkey; + + PORT_Assert(ecWrapped->encodedParamLen + ecWrapped->pubValueLen + + ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN); + + if (ecWrapped->encodedParamLen + ecWrapped->pubValueLen + + ecWrapped->wrappedKeyLen > MAX_EC_WRAPPED_KEY_BUFLEN) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + goto loser; + } + + pubWrapKey.keyType = ecKey; + pubWrapKey.u.ec.size = ecWrapped->size; + pubWrapKey.u.ec.DEREncodedParams.len = ecWrapped->encodedParamLen; + pubWrapKey.u.ec.DEREncodedParams.data = ecWrapped->var; + pubWrapKey.u.ec.publicValue.len = ecWrapped->pubValueLen; + pubWrapKey.u.ec.publicValue.data = ecWrapped->var + + ecWrapped->encodedParamLen; + + wrappedKey.len = ecWrapped->wrappedKeyLen; + wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + + ecWrapped->pubValueLen; + + /* Derive Ks using ECDH */ + Ks = PK11_PubDeriveWithKDF(svrPrivKey, &pubWrapKey, PR_FALSE, NULL, + NULL, CKM_ECDH1_DERIVE, masterWrapMech, + CKA_DERIVE, 0, CKD_NULL, NULL, NULL); + if (Ks == NULL) { + goto loser; + } + + /* Use Ks to unwrap the wrapping key */ + unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL, + &wrappedKey, masterWrapMech, + CKA_UNWRAP, 0); + PK11_FreeSymKey(Ks); + + break; +#endif + default: /* Assert? */ SET_ERROR_CODE @@ -3580,7 +3855,6 @@ getWrappingKey( sslSocket * ss, CK_MECHANISM_TYPE masterWrapMech, void * pwArg) { - CERTCertificate * svrCert; SECKEYPrivateKey * svrPrivKey; SECKEYPublicKey * svrPubKey = NULL; PK11SymKey * unwrappedWrappingKey = NULL; @@ -3650,12 +3924,12 @@ getWrappingKey( sslSocket * ss, */ PORT_Memset(&wswk, 0, sizeof wswk); /* eliminate UMRs. */ - svrCert = ss->serverCerts[exchKeyType].serverCert; - svrPubKey = CERT_ExtractPublicKey(svrCert); + if (ss->serverCerts[exchKeyType].serverKeyPair) { + svrPubKey = ss->serverCerts[exchKeyType].serverKeyPair->pubKey; + } if (svrPubKey == NULL) { - /* CERT_ExtractPublicKey doesn't set error code */ - PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); - goto loser; + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + goto loser; } wrappedKey.type = siBuffer; wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey); @@ -3667,6 +3941,12 @@ getWrappingKey( sslSocket * ss, /* wrap symmetric wrapping key in server's public key. */ switch (exchKeyType) { +#ifdef NSS_ENABLE_ECC + PK11SymKey * Ks; + SECKEYPublicKey *pubWrapKey = NULL; + SECKEYPrivateKey *privWrapKey = NULL; + ECCWrappedKeyInfo *ecWrapped; +#endif /* NSS_ENABLE_ECC */ case kt_rsa: asymWrapMechanism = CKM_RSA_PKCS; @@ -3674,6 +3954,94 @@ getWrappingKey( sslSocket * ss, unwrappedWrappingKey, &wrappedKey); break; +#ifdef NSS_ENABLE_ECC + case kt_ecdh: + /* + * We generate an ephemeral EC key pair. Perform an ECDH + * computation involving this ephemeral EC public key and + * the SSL server's (long-term) EC private key. The resulting + * shared secret is treated in the same way as Fortezza's Ks, + * i.e., it is used to wrap the wrapping key. To facilitate + * unwrapping in ssl_UnwrapWrappingKey, we also store all + * relevant info about the ephemeral EC public key in + * wswk.wrappedSymmetricWrappingkey and lay it out as + * described in the ECCWrappedKeyInfo structure. + */ + PORT_Assert(svrPubKey->keyType == ecKey); + if (svrPubKey->keyType != ecKey) { + /* something is wrong in sslsecur.c if this isn't an ecKey */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = SECFailure; + goto ec_cleanup; + } + + privWrapKey = SECKEY_CreateECPrivateKey( + &svrPubKey->u.ec.DEREncodedParams, &pubWrapKey, NULL); + if ((privWrapKey == NULL) || (pubWrapKey == NULL)) { + rv = SECFailure; + goto ec_cleanup; + } + + /* Set the key size in bits */ + if (pubWrapKey->u.ec.size == 0) { + pubWrapKey->u.ec.size = SECKEY_PublicKeyStrengthInBits(svrPubKey); + } + + PORT_Assert(pubWrapKey->u.ec.DEREncodedParams.len + + pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN); + if (pubWrapKey->u.ec.DEREncodedParams.len + + pubWrapKey->u.ec.publicValue.len >= MAX_EC_WRAPPED_KEY_BUFLEN) { + PORT_SetError(SEC_ERROR_INVALID_KEY); + rv = SECFailure; + goto ec_cleanup; + } + + /* Derive Ks using ECDH */ + Ks = PK11_PubDeriveWithKDF(svrPrivKey, pubWrapKey, PR_FALSE, NULL, + NULL, CKM_ECDH1_DERIVE, masterWrapMech, + CKA_DERIVE, 0, CKD_NULL, NULL, NULL); + if (Ks == NULL) { + rv = SECFailure; + goto ec_cleanup; + } + + ecWrapped = (ECCWrappedKeyInfo *) (wswk.wrappedSymmetricWrappingkey); + ecWrapped->size = pubWrapKey->u.ec.size; + ecWrapped->encodedParamLen = pubWrapKey->u.ec.DEREncodedParams.len; + PORT_Memcpy(ecWrapped->var, pubWrapKey->u.ec.DEREncodedParams.data, + pubWrapKey->u.ec.DEREncodedParams.len); + + ecWrapped->pubValueLen = pubWrapKey->u.ec.publicValue.len; + PORT_Memcpy(ecWrapped->var + ecWrapped->encodedParamLen, + pubWrapKey->u.ec.publicValue.data, + pubWrapKey->u.ec.publicValue.len); + + wrappedKey.len = MAX_EC_WRAPPED_KEY_BUFLEN - + (ecWrapped->encodedParamLen + ecWrapped->pubValueLen); + wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + + ecWrapped->pubValueLen; + + /* wrap symmetricWrapping key with the local Ks */ + rv = PK11_WrapSymKey(masterWrapMech, NULL, Ks, + unwrappedWrappingKey, &wrappedKey); + + if (rv != SECSuccess) { + goto ec_cleanup; + } + + /* Write down the length of wrapped key in the buffer + * wswk.wrappedSymmetricWrappingkey at the appropriate offset + */ + ecWrapped->wrappedKeyLen = wrappedKey.len; + +ec_cleanup: + if (privWrapKey) SECKEY_DestroyPrivateKey(privWrapKey); + if (pubWrapKey) SECKEY_DestroyPublicKey(pubWrapKey); + if (Ks) PK11_FreeSymKey(Ks); + asymWrapMechanism = masterWrapMech; + break; +#endif /* NSS_ENABLE_ECC */ + default: rv = SECFailure; break; @@ -3716,10 +4084,6 @@ install: loser: done: - if (svrPubKey) { - SECKEY_DestroyPublicKey(svrPubKey); - svrPubKey = NULL; - } PZ_Unlock(symWrapKeysLock); return unwrappedWrappingKey; } @@ -3749,6 +4113,19 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) goto loser; } +#if defined(TRACE) + if (ssl_trace >= 100) { + SECStatus extractRV = PK11_ExtractKeyValue(pms); + if (extractRV == SECSuccess) { + SECItem * keyData = PK11_GetKeyData(pms); + if (keyData && keyData->data && keyData->len) { + ssl_PrintBuf(ss, "Pre-Master Secret", + keyData->data, keyData->len); + } + } + } +#endif + /* Get the wrapped (encrypted) pre-master secret, enc_pms */ enc_pms.len = SECKEY_PublicKeyStrength(svrPubKey); enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); @@ -3818,6 +4195,10 @@ sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) /* Copy DH parameters from server key */ + if (svrPubKey->keyType != dhKey) { + PORT_SetError(SEC_ERROR_BAD_KEY); + goto loser; + } dhParam.prime.data = svrPubKey->u.dh.prime.data; dhParam.prime.len = svrPubKey->u.dh.prime.len; dhParam.base.data = svrPubKey->u.dh.base.data; @@ -4260,7 +4641,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } /* Got a Match */ - ++ssl3stats.hsh_sid_cache_hits; + SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits ); ss->ssl3.hs.ws = wait_change_cipher; ss->ssl3.hs.isResuming = PR_TRUE; @@ -4279,9 +4660,9 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } while (0); if (sid_match) - ++ssl3stats.hsh_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok ); else - ++ssl3stats.hsh_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_misses ); /* throw the old one away */ sid->u.ssl3.keys.resumable = PR_FALSE; @@ -4576,6 +4957,14 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) CERT_DestroyCertificateList(ss->ssl3.clientCertChain); ss->ssl3.clientCertChain = NULL; } + if (ss->ssl3.clientCertificate != NULL) { + CERT_DestroyCertificate(ss->ssl3.clientCertificate); + ss->ssl3.clientCertificate = NULL; + } + if (ss->ssl3.clientPrivateKey != NULL) { + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); + ss->ssl3.clientPrivateKey = NULL; + } isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length); @@ -5101,11 +5490,6 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) goto loser; /* malformed */ } - /* It's OK for length to be non-zero here. - * Non-zero length means that some new protocol revision has extended - * the client hello message. - */ - desc = handshake_failure; if (sid != NULL) { @@ -5121,33 +5505,54 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ((ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE) && !ss->firstHsDone))) { - ++ssl3stats.hch_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok ); ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; } } +#ifdef NSS_ENABLE_ECC + /* Disable any ECC cipher suites for which we have no cert. */ + ssl3_FilterECCipherSuitesByServerCerts(ss); +#endif + +#ifdef PARANOID /* Look for a matching cipher suite. */ j = ssl3_config_match_init(ss); if (j <= 0) { /* no ciphers are working/supported by PK11 */ errCode = PORT_GetError(); /* error code is already set. */ goto alert_loser; } +#endif + /* If we already have a session for this client, be sure to pick the ** same cipher suite we picked before. ** This is not a loop, despite appearances. */ if (sid) do { ssl3CipherSuiteCfg *suite = ss->cipherSuites; + /* Find the entry for the cipher suite used in the cached session. */ for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) { if (suite->cipher_suite == sid->u.ssl3.cipherSuite) break; } - if (!j) + PORT_Assert(j > 0); + if (j <= 0) break; +#ifdef PARANOID + /* Double check that the cached cipher suite is still enabled, + * implemented, and allowed by policy. Might have been disabled. + * The product policy won't change during the process lifetime. + * Implemented ("isPresent") shouldn't change for servers. + */ if (!config_match(suite, ss->ssl3.policy, PR_TRUE)) break; +#else + if (!suite->enabled) + break; +#endif + /* Double check that the cached cipher suite is in the client's list */ for (i = 0; i < suites.len; i += 2) { if ((suites.data[i] == MSB(suite->cipher_suite)) && (suites.data[i + 1] == LSB(suite->cipher_suite))) { @@ -5160,6 +5565,37 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } } while (0); + /* START A NEW SESSION */ + + /* Handle TLS hello extensions, for SSL3 & TLS, + * only if we're not restarting a previous session. + */ + if (length) { + /* Get length of hello extensions */ + PRInt32 extension_length; + extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); + if (extension_length < 0) { + goto loser; /* alert already sent */ + } + if (extension_length != length) { + ssl3_DecodeError(ss); /* send alert */ + goto loser; + } + rv = ssl3_HandleClientHelloExtensions(ss, &b, &length); + if (rv != SECSuccess) { + goto loser; /* malformed */ + } + } + +#ifndef PARANOID + /* Look for a matching cipher suite. */ + j = ssl3_config_match_init(ss); + if (j <= 0) { /* no ciphers are working/supported by PK11 */ + errCode = PORT_GetError(); /* error code is already set. */ + goto alert_loser; + } +#endif + /* Select a cipher suite. ** NOTE: This suite selection algorithm should be the same as the one in ** ssl3_HandleV2ClientHello(). @@ -5294,7 +5730,7 @@ compression_found: * * XXX make sure compression still matches */ - ++ssl3stats.hch_sid_cache_hits; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_hits ); ss->ssl3.hs.isResuming = PR_TRUE; ss->sec.authAlgorithm = sid->authAlgorithm; @@ -5356,12 +5792,12 @@ compression_found: } if (sid) { /* we had a sid, but it's no longer valid, free it */ - ++ssl3stats.hch_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok ); ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; } - ++ssl3stats.hch_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses ); sid = ssl3_NewSessionID(ss, PR_TRUE); if (sid == NULL) { @@ -5488,7 +5924,10 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length) PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0], SSL3_RANDOM_LENGTH)); - +#ifdef NSS_ENABLE_ECC + /* Disable any ECC cipher suites for which we have no cert. */ + ssl3_FilterECCipherSuitesByServerCerts(ss); +#endif i = ssl3_config_match_init(ss); if (i <= 0) { errCode = PORT_GetError(); /* error code is already set. */ @@ -5524,7 +5963,7 @@ suite_found: ss->sec.send = ssl3_SendApplicationData; /* we don't even search for a cache hit here. It's just a miss. */ - ++ssl3stats.hch_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses ); sid = ssl3_NewSessionID(ss, PR_TRUE); if (sid == NULL) { errCode = PORT_GetError(); @@ -5577,7 +6016,9 @@ ssl3_SendServerHello(sslSocket *ss) { sslSessionID *sid; SECStatus rv; + PRUint32 maxBytes = 65535; PRUint32 length; + PRInt32 extensions_len = 0; SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(), ss->fd)); @@ -5592,9 +6033,15 @@ ssl3_SendServerHello(sslSocket *ss) } sid = ss->sec.ci.sid; + + extensions_len = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, + &ss->serverExtensionSenders[0]); + if (extensions_len > 0) + extensions_len += 2; /* Add sizeof total extension length */ + length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 + ((sid == NULL) ? 0: SSL3_SESSIONID_BYTES) + - sizeof(ssl3CipherSuite) + 1; + sizeof(ssl3CipherSuite) + 1 + extensions_len; rv = ssl3_AppendHandshakeHeader(ss, server_hello, length); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ @@ -5632,6 +6079,22 @@ ssl3_SendServerHello(sslSocket *ss) if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } + if (extensions_len) { + PRInt32 sent_len; + + extensions_len -= 2; + rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2); + if (rv != SECSuccess) + return rv; /* err set by ssl3_SetupPendingCipherSpec */ + sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, extensions_len, + &ss->serverExtensionSenders[0]); + PORT_Assert(sent_len == extensions_len); + if (sent_len != extensions_len) { + if (sent_len >= 0) + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + } rv = ssl3_SetupPendingCipherSpec(ss); if (rv != SECSuccess) { return rv; /* err set by ssl3_SetupPendingCipherSpec */ @@ -6085,6 +6548,7 @@ ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) SECKEYPrivateKey *serverKey = NULL; SECStatus rv; const ssl3KEADef * kea_def; + ssl3KeyPair *serverKeyPair = NULL; #ifdef NSS_ENABLE_ECC SECKEYPublicKey *serverPubKey = NULL; #endif /* NSS_ENABLE_ECC */ @@ -6103,6 +6567,20 @@ const ssl3KEADef * kea_def; kea_def = ss->ssl3.hs.kea_def; + if (ss->ssl3.hs.usedStepDownKey) { + PORT_Assert(kea_def->is_limited /* XXX OR cert is signing only */ + && kea_def->exchKeyType == kt_rsa + && ss->stepDownKeyPair != NULL); + if (!kea_def->is_limited || + kea_def->exchKeyType != kt_rsa || + ss->stepDownKeyPair == NULL) { + /* shouldn't happen, don't use step down if it does */ + goto skip; + } + serverKeyPair = ss->stepDownKeyPair; + ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB; + } else +skip: #ifdef NSS_ENABLE_ECC /* XXX Using SSLKEAType to index server certifiates * does not work for (EC)DHE ciphers. Until we have @@ -6111,42 +6589,25 @@ const ssl3KEADef * kea_def; * one seprately. */ if ((kea_def->kea == kea_ecdhe_rsa) || - (kea_def->kea == kea_ecdhe_ecdsa)) { - if (ss->ephemeralECDHKeyPair != NULL) { - serverKey = ss->ephemeralECDHKeyPair->privKey; - ss->sec.keaKeyBits = - SECKEY_PublicKeyStrengthInBits(ss->ephemeralECDHKeyPair->pubKey); - } - } else { -#endif /* NSS_ENABLE_ECC */ - - serverKey = (ss->ssl3.hs.usedStepDownKey -#ifdef DEBUG - && kea_def->is_limited /* XXX OR cert is signing only */ - && kea_def->exchKeyType == kt_rsa - && ss->stepDownKeyPair != NULL -#endif - ) ? ss->stepDownKeyPair->privKey - : ss->serverCerts[kea_def->exchKeyType].SERVERKEY; - - if (ss->ssl3.hs.usedStepDownKey -#ifdef DEBUG - && kea_def->is_limited /* XXX OR cert is signing only */ - && kea_def->exchKeyType == kt_rsa - && ss->stepDownKeyPair != NULL + (kea_def->kea == kea_ecdhe_ecdsa)) { + if (ss->ephemeralECDHKeyPair != NULL) { + serverKeyPair = ss->ephemeralECDHKeyPair; + if (serverKeyPair->pubKey) { + ss->sec.keaKeyBits = + SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey); + } + } + } else #endif - ) { - serverKey = ss->stepDownKeyPair->privKey; - ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB; - } else { + { sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType; - serverKey = sc->SERVERKEY; + serverKeyPair = sc->serverKeyPair; ss->sec.keaKeyBits = sc->serverKeyBits; } -#ifdef NSS_ENABLE_ECC + if (serverKeyPair) { + serverKey = serverKeyPair->privKey; } -#endif /* NSS_ENABLE_ECC */ if (serverKey == NULL) { SEND_ALERT @@ -6168,19 +6629,14 @@ const ssl3KEADef * kea_def; #ifdef NSS_ENABLE_ECC case kt_ecdh: - /* XXX We really ought to be able to store multiple + /* XXX We really ought to be able to store multiple * EC certs (a requirement if we wish to support both * ECDH-RSA and ECDH-ECDSA key exchanges concurrently). * When we make that change, we'll need an index other * than kt_ecdh to pick the right EC certificate. */ - if (((kea_def->kea == kea_ecdhe_ecdsa) || - (kea_def->kea == kea_ecdhe_rsa)) && - (ss->ephemeralECDHKeyPair != NULL)) { - serverPubKey = ss->ephemeralECDHKeyPair->pubKey; - } else { - serverPubKey = CERT_ExtractPublicKey( - ss->serverCerts[kt_ecdh].serverCert); + if (serverKeyPair) { + serverPubKey = serverKeyPair->pubKey; } if (serverPubKey == NULL) { /* XXX Is this the right error code? */ @@ -6358,23 +6814,25 @@ ssl3_SendCertificate(sslSocket *ss) if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } - for (i = 0; i < certChain->len; i++) { + if (certChain) { + for (i = 0; i < certChain->len; i++) { #ifdef NISCC_TEST - if (fakeCert.len > 0 && i == ndex) { - rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data, fakeCert.len, - 3); - SECITEM_FreeItem(&fakeCert, PR_FALSE); - } else { - rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, - certChain->certs[i].len, 3); - } + if (fakeCert.len > 0 && i == ndex) { + rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data, + fakeCert.len, 3); + SECITEM_FreeItem(&fakeCert, PR_FALSE); + } else { + rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, + certChain->certs[i].len, 3); + } #else - rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, - certChain->certs[i].len, 3); + rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, + certChain->certs[i].len, 3); #endif - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } + if (rv != SECSuccess) { + return rv; /* err set by AppendHandshake. */ + } + } } return SECSuccess; @@ -7066,6 +7524,9 @@ xmit_loser: sid->u.ssl3.cipherSuite = ss->ssl3.hs.cipher_suite; sid->u.ssl3.compression = ss->ssl3.hs.compression; sid->u.ssl3.policy = ss->ssl3.policy; +#ifdef NSS_ENABLE_ECC + sid->u.ssl3.negotiatedECCurves = ss->ssl3.hs.negotiatedECCurves; +#endif sid->u.ssl3.exchKeyType = effectiveExchKeyType; sid->version = ss->version; sid->authAlgorithm = ss->sec.authAlgorithm; @@ -7596,9 +8057,9 @@ process_it: case content_handshake: rv = ssl3_HandleHandshake(ss, databuf); break; - case content_application_data: - rv = SECSuccess; - break; + /* + case content_application_data is handled before this switch + */ default: SSL_DBG(("%d: SSL3[%d]: bogus content type=%d", SSL_GETPID(), ss->fd, cText->type)); @@ -7688,6 +8149,9 @@ ssl3_InitState(sslSocket *ss) ssl3_InitCipherSpec(ss, ss->ssl3.prSpec); ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; +#ifdef NSS_ENABLE_ECC + ss->ssl3.hs.negotiatedECCurves = SSL3_SUPPORTED_CURVES_MASK; +#endif ssl_ReleaseSpecWriteLock(ss); /* @@ -7742,8 +8206,7 @@ ssl3_NewKeyPair( SECKEYPrivateKey * privKey, SECKEYPublicKey * pubKey) { ssl3KeyPair * pair; - if (!privKey && !pubKey) { - /* one or the other may be NULL, but not both. */ + if (!privKey || !pubKey) { PORT_SetError(PR_INVALID_ARGUMENT_ERROR); return NULL; } diff --git a/security/nss/lib/ssl/ssl3ecc.c b/security/nss/lib/ssl/ssl3ecc.c index af7cdb30f..ab2e96144 100644 --- a/security/nss/lib/ssl/ssl3ecc.c +++ b/security/nss/lib/ssl/ssl3ecc.c @@ -42,9 +42,8 @@ /* ECC code moved here from ssl3con.c */ /* $Id$ */ -#ifdef NSS_ENABLE_ECC - #include "nssrenam.h" +#include "nss.h" #include "cert.h" #include "ssl.h" #include "cryptohi.h" /* for DSAU_ stuff */ @@ -60,6 +59,7 @@ #include "prerror.h" #include "pratom.h" #include "prthread.h" +#include "prinit.h" #include "pk11func.h" #include "secmod.h" @@ -69,38 +69,59 @@ #include <stdio.h> -/* - line 297: implicit function declaration: ssl3_InitPendingCipherSpec - line 305: implicit function declaration: ssl3_AppendHandshakeHeader - line 311: implicit function declaration: ssl3_AppendHandshakeVariable - line 356: implicit function declaration: ssl3_ConsumeHandshakeVariable -*/ - +#ifdef NSS_ENABLE_ECC #ifndef PK11_SETATTRS #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ (x)->pValue=(v); (x)->ulValueLen = (l); #endif +#define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \ + (ss->serverCerts[type].serverKeyPair ? \ + ss->serverCerts[type].serverKeyPair->pubKey : NULL) + +#define SSL_IS_CURVE_NEGOTIATED(ss, curveName) \ + ((curveName > ec_noName) && \ + (curveName < ec_pastLastName) && \ + ((1UL << curveName) & ss->ssl3.hs.negotiatedECCurves) != 0) + /* Types and names of elliptic curves used in TLS */ -typedef enum { ec_type_explicitPrime = 1, - ec_type_explicitChar2Curve, +typedef enum { ec_type_explicitPrime = 1, + ec_type_explicitChar2Curve = 2, ec_type_named } ECType; -typedef enum { ec_noName = 0, - ec_sect163k1, ec_sect163r1, ec_sect163r2, - ec_sect193r1, ec_sect193r2, ec_sect233k1, - ec_sect233r1, ec_sect239k1, ec_sect283k1, - ec_sect283r1, ec_sect409k1, ec_sect409r1, - ec_sect571k1, ec_sect571r1, ec_secp160k1, - ec_secp160r1, ec_secp160r2, ec_secp192k1, - ec_secp192r1, ec_secp224k1, ec_secp224r1, - ec_secp256k1, ec_secp256r1, ec_secp384r1, - ec_secp521r1, +typedef enum { ec_noName = 0, + ec_sect163k1 = 1, + ec_sect163r1 = 2, + ec_sect163r2 = 3, + ec_sect193r1 = 4, + ec_sect193r2 = 5, + ec_sect233k1 = 6, + ec_sect233r1 = 7, + ec_sect239k1 = 8, + ec_sect283k1 = 9, + ec_sect283r1 = 10, + ec_sect409k1 = 11, + ec_sect409r1 = 12, + ec_sect571k1 = 13, + ec_sect571r1 = 14, + ec_secp160k1 = 15, + ec_secp160r1 = 16, + ec_secp160r2 = 17, + ec_secp192k1 = 18, + ec_secp192r1 = 19, + ec_secp224k1 = 20, + ec_secp224r1 = 21, + ec_secp256k1 = 22, + ec_secp256r1 = 23, + ec_secp384r1 = 24, + ec_secp521r1 = 25, ec_pastLastName } ECName; +static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve); + #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName)) /* Table containing OID tags for elliptic curves named in the @@ -135,6 +156,79 @@ static const SECOidTag ecName2OIDTag[] = { SEC_OID_SECG_EC_SECP521R1, /* 25 */ }; +static const PRUint16 curve2bits[] = { + 0, /* ec_noName = 0, */ + 163, /* ec_sect163k1 = 1, */ + 163, /* ec_sect163r1 = 2, */ + 163, /* ec_sect163r2 = 3, */ + 193, /* ec_sect193r1 = 4, */ + 193, /* ec_sect193r2 = 5, */ + 233, /* ec_sect233k1 = 6, */ + 233, /* ec_sect233r1 = 7, */ + 239, /* ec_sect239k1 = 8, */ + 283, /* ec_sect283k1 = 9, */ + 283, /* ec_sect283r1 = 10, */ + 409, /* ec_sect409k1 = 11, */ + 409, /* ec_sect409r1 = 12, */ + 571, /* ec_sect571k1 = 13, */ + 571, /* ec_sect571r1 = 14, */ + 160, /* ec_secp160k1 = 15, */ + 160, /* ec_secp160r1 = 16, */ + 160, /* ec_secp160r2 = 17, */ + 192, /* ec_secp192k1 = 18, */ + 192, /* ec_secp192r1 = 19, */ + 224, /* ec_secp224k1 = 20, */ + 224, /* ec_secp224r1 = 21, */ + 256, /* ec_secp256k1 = 22, */ + 256, /* ec_secp256r1 = 23, */ + 384, /* ec_secp384r1 = 24, */ + 521, /* ec_secp521r1 = 25, */ + 65535 /* ec_pastLastName */ +}; + +typedef struct Bits2CurveStr { + PRUint16 bits; + ECName curve; +} Bits2Curve; + +static const Bits2Curve bits2curve [] = { + { 192, ec_secp192r1 /* = 19, fast */ }, + { 160, ec_secp160r2 /* = 17, fast */ }, + { 160, ec_secp160k1 /* = 15, */ }, + { 160, ec_secp160r1 /* = 16, */ }, + { 163, ec_sect163k1 /* = 1, */ }, + { 163, ec_sect163r1 /* = 2, */ }, + { 163, ec_sect163r2 /* = 3, */ }, + { 192, ec_secp192k1 /* = 18, */ }, + { 193, ec_sect193r1 /* = 4, */ }, + { 193, ec_sect193r2 /* = 5, */ }, + { 224, ec_secp224r1 /* = 21, fast */ }, + { 224, ec_secp224k1 /* = 20, */ }, + { 233, ec_sect233k1 /* = 6, */ }, + { 233, ec_sect233r1 /* = 7, */ }, + { 239, ec_sect239k1 /* = 8, */ }, + { 256, ec_secp256r1 /* = 23, fast */ }, + { 256, ec_secp256k1 /* = 22, */ }, + { 283, ec_sect283k1 /* = 9, */ }, + { 283, ec_sect283r1 /* = 10, */ }, + { 384, ec_secp384r1 /* = 24, fast */ }, + { 409, ec_sect409k1 /* = 11, */ }, + { 409, ec_sect409r1 /* = 12, */ }, + { 521, ec_secp521r1 /* = 25, fast */ }, + { 571, ec_sect571k1 /* = 13, */ }, + { 571, ec_sect571r1 /* = 14, */ }, + { 65535, ec_noName } +}; + +typedef struct ECDHEKeyPairStr { + ssl3KeyPair * pair; + int error; /* error code of the call-once function */ + PRCallOnceType once; +} ECDHEKeyPair; + +/* arrays of ECDHE KeyPairs */ +static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName]; + static SECStatus ecName2params(PRArenaPool * arena, ECName curve, SECKEYECParams * params) { @@ -229,7 +323,6 @@ ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint, PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH)); PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH)); -done: if (hashBuf != buf && hashBuf != NULL) PORT_Free(hashBuf); return rv; @@ -246,7 +339,6 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) CK_MECHANISM_TYPE target; SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */ SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */ - CK_EC_KDF_TYPE kdf; PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); @@ -254,6 +346,11 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); /* Generate ephemeral EC keypair */ + if (svrPubKey->keyType != ecKey) { + PORT_SetError(SEC_ERROR_BAD_KEY); + goto loser; + } + /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, &pubKey, NULL); if (!privKey || !pubKey) { @@ -268,21 +365,14 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; - /* If field size is not more than 24 octets, then use SHA-1 hash of result; - * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt). - */ - if ((pubKey->u.ec.publicValue.len - 1) / 2 <= 24) { - kdf = CKD_SHA1_KDF; - } else { - kdf = CKD_NULL; - } - /* Determine the PMS */ pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, - kdf, NULL, NULL); + CKD_NULL, NULL, NULL); if (pms == NULL) { + SSL3AlertDescription desc = illegal_parameter; + (void)SSL3_SendAlert(ss, alert_fatal, desc); ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser; } @@ -338,7 +428,6 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, SECKEYPublicKey clntPubKey; CK_MECHANISM_TYPE target; PRBool isTLS; - CK_EC_KDF_TYPE kdf; PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); @@ -361,19 +450,10 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; - /* If field size is not more than 24 octets, then use SHA-1 hash of result; - * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt). - */ - if (srvrPubKey->u.ec.size <= 24 * 8) { - kdf = CKD_SHA1_KDF; - } else { - kdf = CKD_NULL; - } - /* Determine the PMS */ pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, - kdf, NULL, NULL); + CKD_NULL, NULL, NULL); if (pms == NULL) { /* last gasp. */ @@ -390,38 +470,174 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, return SECSuccess; } +/* find the "weakest link". Get strength of signature key and of sym key. + * choose curve for the weakest of those two. + */ +ECName +ssl3_GetCurveNameForServerSocket(sslSocket *ss) +{ + SECKEYPublicKey * svrPublicKey = NULL; + ECName ec_curve = ec_noName; + int signatureKeyStrength = 521; + int requiredECCbits = ss->sec.secretKeyBits * 2; + int i; + + if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) { + svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh); + if (svrPublicKey) + ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams); + if (!SSL_IS_CURVE_NEGOTIATED(ss, ec_curve)) { + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return ec_noName; + } + signatureKeyStrength = curve2bits[ ec_curve ]; + } else { + /* RSA is our signing cert */ + int serverKeyStrengthInBits; + + svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa); + if (!svrPublicKey) { + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return ec_noName; + } + + /* currently strength in bytes */ + serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len; + if (svrPublicKey->u.rsa.modulus.data[0] == 0) { + serverKeyStrengthInBits--; + } + /* convert to strength in bits */ + serverKeyStrengthInBits *= BPB; + + if (serverKeyStrengthInBits <= 1024) { + signatureKeyStrength = 160; + } else if (serverKeyStrengthInBits <= 2048) { + signatureKeyStrength = 224; + } else if (serverKeyStrengthInBits <= 3072) { + signatureKeyStrength = 256; + } else if (serverKeyStrengthInBits <= 7168) { + signatureKeyStrength = 384; + } else { + signatureKeyStrength = 521; + } + } + if ( requiredECCbits > signatureKeyStrength ) + requiredECCbits = signatureKeyStrength; + + for ( i = 0; bits2curve[i].curve != ec_noName; i++) { + if (bits2curve[i].bits < requiredECCbits) + continue; + if (SSL_IS_CURVE_NEGOTIATED(ss, bits2curve[i].curve)) { + return bits2curve[i].curve; + } + } + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return ec_noName; +} + +/* function to clear out the lists */ +static SECStatus +ssl3_ShutdownECDHECurves(void *appData, void *nssData) +{ + int i; + ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0]; + + for (i=0; i < ec_pastLastName; i++, keyPair++) { + if (keyPair->pair) { + ssl3_FreeKeyPair(keyPair->pair); + } + } + memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs); + return SECSuccess; +} + +static PRStatus +ssl3_ECRegister(void) +{ + SECStatus rv; + rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs); + if (rv != SECSuccess) { + gECDHEKeyPairs[ec_noName].error = PORT_GetError(); + } + return (PRStatus)rv; +} + +/* CallOnce function, called once for each named curve. */ +static PRStatus +ssl3_CreateECDHEphemeralKeyPair(void * arg) +{ + SECKEYPrivateKey * privKey = NULL; + SECKEYPublicKey * pubKey = NULL; + ssl3KeyPair * keyPair = NULL; + ECName ec_curve = (ECName)arg; + SECKEYECParams ecParams = { siBuffer, NULL, 0 }; + + PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); + + /* ok, no one has generated a global key for this curve yet, do so */ + if (ecName2params(NULL, ec_curve, &ecParams) != SECSuccess) { + gECDHEKeyPairs[ec_curve].error = PORT_GetError(); + return PR_FAILURE; + } + + privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); + SECITEM_FreeItem(&ecParams, PR_FALSE); + + if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) { + if (privKey) { + SECKEY_DestroyPrivateKey(privKey); + } + if (pubKey) { + SECKEY_DestroyPublicKey(pubKey); + } + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); + gECDHEKeyPairs[ec_curve].error = PORT_GetError(); + return PR_FAILURE; + } + + gECDHEKeyPairs[ec_curve].pair = keyPair; + return PR_SUCCESS; +} /* * Creates the ephemeral public and private ECDH keys used by * server in ECDHE_RSA and ECDHE_ECDSA handshakes. - * XXX For now, the elliptic curve is hardcoded to NIST P-224. + * For now, the elliptic curve is chosen to be the same + * strength as the signing certificate (ECC or RSA). * We need an API to specify the curve. This won't be a real * issue until we further develop server-side support for ECC * cipher suites. */ -SECStatus -ssl3_CreateECDHEphemeralKeys(sslSocket *ss) +static SECStatus +ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve) { - SECStatus rv = SECSuccess; - SECKEYPrivateKey * privKey; - SECKEYPublicKey * pubKey; - SECKEYECParams ecParams = { siBuffer, NULL, 0 }; + ssl3KeyPair * keyPair = NULL; - if (ss->ephemeralECDHKeyPair) - ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); - ss->ephemeralECDHKeyPair = NULL; + /* if there's no global key for this curve, make one. */ + if (gECDHEKeyPairs[ec_curve].pair == NULL) { + PRStatus status; - if (ecName2params(NULL, ec_secp224r1, &ecParams) == SECFailure) - return SECFailure; - privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); - if (!privKey || !pubKey || - !(ss->ephemeralECDHKeyPair = ssl3_NewKeyPair(privKey, pubKey))) { - ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); - rv = SECFailure; + status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister); + if (status != PR_SUCCESS) { + PORT_SetError(gECDHEKeyPairs[ec_noName].error); + return SECFailure; + } + status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once, + ssl3_CreateECDHEphemeralKeyPair, + (void *)ec_curve); + if (status != PR_SUCCESS) { + PORT_SetError(gECDHEKeyPairs[ec_curve].error); + return SECFailure; + } } - PORT_Free(ecParams.data); - return rv; + keyPair = gECDHEKeyPairs[ec_curve].pair; + PORT_Assert(keyPair != NULL); + if (!keyPair) + return SECFailure; + ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair); + + return SECSuccess; } SECStatus @@ -438,24 +654,24 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) SECItem ec_params = {siBuffer, NULL, 0}; SECItem ec_point = {siBuffer, NULL, 0}; - unsigned char paramBuf[2]; + unsigned char paramBuf[3]; /* only for curve_type == named_curve */ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); /* XXX This works only for named curves, revisit this when * we support generic curves. */ - ec_params.len = 2; + ec_params.len = sizeof paramBuf; ec_params.data = paramBuf; - rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, - &b, &length); + rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); if (rv != SECSuccess) { goto loser; /* malformed. */ } /* Fail if the curve is not a named curve */ if ((ec_params.data[0] != ec_type_named) || - !supportedCurve(ec_params.data[1])) { + (ec_params.data[1] != 0) || + !supportedCurve(ec_params.data[2])) { errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; desc = handshake_failure; goto alert_loser; @@ -526,7 +742,7 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) peerKey->keyType = ecKey; /* set up EC parameters in peerKey */ - if (ecName2params(arena, ec_params.data[1], + if (ecName2params(arena, ec_params.data[2], &peerKey->u.ec.DEREncodedParams) != SECSuccess) { /* we should never get here since we already * checked that we are dealing with a supported curve @@ -572,12 +788,17 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; SECKEYPublicKey * ecdhePub; SECItem ec_params = {siBuffer, NULL, 0}; + unsigned char paramBuf[3]; ECName curve; SSL3KEAType certIndex; /* Generate ephemeral ECDH key pair and send the public key */ - rv = ssl3_CreateECDHEphemeralKeys(ss); + curve = ssl3_GetCurveNameForServerSocket(ss); + if (curve == ec_noName) { + goto loser; + } + rv = ssl3_CreateECDHEphemeralKeys(ss, curve); if (rv != SECSuccess) { goto loser; /* err set by AppendHandshake. */ } @@ -588,12 +809,13 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; return SECFailure; } - ec_params.len = 2; - ec_params.data = (unsigned char*)PORT_Alloc(ec_params.len); + ec_params.len = sizeof paramBuf; + ec_params.data = paramBuf; curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams); if (curve != ec_noName) { ec_params.data[0] = ec_type_named; - ec_params.data[1] = curve; + ec_params.data[1] = 0x00; + ec_params.data[2] = curve; } else { PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); goto loser; @@ -656,18 +878,512 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; goto loser; /* err set by AppendHandshake. */ } - PORT_Free(ec_params.data); PORT_Free(signed_hash.data); return SECSuccess; loser: - if (ec_params.data != NULL) - PORT_Free(ec_params.data); if (signed_hash.data != NULL) PORT_Free(signed_hash.data); return SECFailure; } +/* Lists of ECC cipher suites for searching and disabling. */ + +static const ssl3CipherSuite ecdh_suites[] = { + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdh_ecdsa_suites[] = { + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdh_rsa_suites[] = { + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdhe_rsa_suites[] = { + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +/* List of all ECC cipher suites */ +static const ssl3CipherSuite ecSuites[] = { + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +/* On this socket, Disable the ECC cipher suites in the argument's list */ +SECStatus +ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite) +{ + if (!suite) + suite = ecSuites; + for (; *suite; ++suite) { + SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE); + + PORT_Assert(rv == SECSuccess); /* else is coding error */ + } + return SECSuccess; +} + +/* Look at the server certs configured on this socket, and disable any + * ECC cipher suites that are not supported by those certs. + */ +void +ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss) +{ + CERTCertificate * svrCert; + + svrCert = ss->serverCerts[kt_rsa].serverCert; + if (!svrCert) { + ssl3_DisableECCSuites(ss, ecdhe_rsa_suites); + } + + svrCert = ss->serverCerts[kt_ecdh].serverCert; + if (!svrCert) { + ssl3_DisableECCSuites(ss, ecdh_suites); + ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); + } else { + SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature); + + switch (sigTag) { + case SEC_OID_PKCS1_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: + ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); + break; + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + ssl3_DisableECCSuites(ss, ecdh_rsa_suites); + break; + default: + ssl3_DisableECCSuites(ss, ecdh_suites); + break; + } + } +} + +/* Ask: is ANY ECC cipher suite enabled on this socket? */ +/* Order(N^2). Yuk. Also, this ignores export policy. */ +PRBool +ssl3_IsECCEnabled(sslSocket * ss) +{ + const ssl3CipherSuite * suite; + + for (suite = ecSuites; *suite; ++suite) { + PRBool enabled = PR_FALSE; + SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled); + + PORT_Assert(rv == SECSuccess); /* else is coding error */ + if (rv == SECSuccess && enabled) + return PR_TRUE; + } + return PR_FALSE; +} + +#define BE(n) 0, n + +#ifndef NSS_ECC_MORE_THAN_SUITE_B +/* Prefabricated TLS client hello extension, Elliptic Curves List, + * offers only 3 curves, the Suite B curves, 23-25 + */ +static const PRUint8 EClist[12] = { + BE(10), /* Extension type */ + BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */ + BE( 6), /* octets that follow ( 3 pairs) */ + BE(23), BE(24), BE(25) +}; +#else +/* Prefabricated TLS client hello extension, Elliptic Curves List, + * offers curves 1-25. + */ +static const PRUint8 EClist[56] = { + BE(10), /* Extension type */ + BE(52), /* octets that follow (25 pairs + 1 length pair) */ + BE(50), /* octets that follow (25 pairs) */ + BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7), + BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15), + BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23), + BE(24), BE(25) +}; +#endif + +static const PRUint8 ECPtFmt[6] = { + BE(11), /* Extension type */ + BE( 2), /* octets that follow */ + 1, /* octets that follow */ + 0 /* uncompressed type only */ +}; + +/* Send our "canned" (precompiled) Supported Elliptic Curves extension, + * which says that we support all TLS-defined named curves. + */ +PRInt32 +ssl3_SendSupportedEllipticCurvesExtension( + sslSocket * ss, + PRBool append, + PRUint32 maxBytes) +{ + if (!ss || !ssl3_IsECCEnabled(ss)) + return 0; + if (append && maxBytes >= (sizeof EClist)) { + SECStatus rv = ssl3_AppendHandshake(ss, EClist, (sizeof EClist)); + } + return (sizeof EClist); +} + +/* Send our "canned" (precompiled) Supported Point Formats extension, + * which says that we only support uncompressed points. + */ +PRInt32 +ssl3_SendSupportedPointFormatsExtension( + sslSocket * ss, + PRBool append, + PRUint32 maxBytes) +{ + if (!ss || !ssl3_IsECCEnabled(ss)) + return 0; + if (append && maxBytes >= (sizeof ECPtFmt)) { + SECStatus rv = ssl3_AppendHandshake(ss, ECPtFmt, (sizeof ECPtFmt)); + } + return (sizeof ECPtFmt); +} + +/* Just make sure that the remote client supports uncompressed points, + * Since that is all we support. Disable ECC cipher suites if it doesn't. + */ +static SECStatus +ssl3_HandleSupportedPointFormatsExtension(sslSocket * ss, PRUint16 ex_type, + SECItem *data) +{ + int i; + + if (data->len < 2 || data->len > 255 || !data->data || + data->len != (unsigned int)data->data[0] + 1) { + /* malformed */ + goto loser; + } + for (i = data->len; --i > 0; ) { + if (data->data[i] == 0) { + /* indicate that we should send a reply */ + SECStatus rv; + rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, + &ssl3_SendSupportedPointFormatsExtension); + return rv; + } + } +loser: + /* evil client doesn't support uncompressed */ + ssl3_DisableECCSuites(ss, ecSuites); + return SECFailure; +} + + +#define SSL3_GET_SERVER_PUBLICKEY(sock, type) \ + (ss->serverCerts[type].serverKeyPair ? \ + ss->serverCerts[type].serverKeyPair->pubKey : NULL) + +/* Extract the TLS curve name for the public key in our EC server cert. */ +ECName ssl3_GetSvrCertCurveName(sslSocket *ss) +{ + SECKEYPublicKey *srvPublicKey; + ECName ec_curve = ec_noName; + + srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh); + if (srvPublicKey) { + ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams); + } + return ec_curve; +} + +/* Ensure that the curve in our server cert is one of the ones suppored + * by the remote client, and disable all ECC cipher suites if not. + */ +static SECStatus +ssl3_HandleSupportedEllipticCurvesExtension(sslSocket * ss, PRUint16 ex_type, + SECItem *data) +{ + PRInt32 list_len; + PRUint32 peerCurves = 0; + PRUint32 mutualCurves = 0; + PRUint16 svrCertCurveName; + + if (!data->data || data->len < 4 || data->len > 65535) + goto loser; + /* get the length of elliptic_curve_list */ + list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { + /* malformed */ + goto loser; + } + /* build bit vector of peer's supported curve names */ + while (data->len) { + PRInt32 curve_name = + ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + if (curve_name > ec_noName && curve_name < ec_pastLastName) { + peerCurves |= (1U << curve_name); + } + } + /* What curves do we support in common? */ + mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves; + if (!mutualCurves) { /* no mutually supported EC Curves */ + goto loser; + } + + /* if our ECC cert doesn't use one of these supported curves, + * disable ECC cipher suites that require an ECC cert. + */ + svrCertCurveName = ssl3_GetSvrCertCurveName(ss); + if (svrCertCurveName != ec_noName && + (mutualCurves & (1U << svrCertCurveName)) != 0) { + return SECSuccess; + } + /* Our EC cert doesn't contain a mutually supported curve. + * Disable all ECC cipher suites that require an EC cert + */ + ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); + ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); + return SECFailure; + +loser: + /* no common curve supported */ + ssl3_DisableECCSuites(ss, ecSuites); + return SECFailure; +} #endif /* NSS_ENABLE_ECC */ +/* Format an SNI extension, using the name from the socket's URL, + * unless that name is a dotted decimal string. + */ +PRInt32 +ssl3_SendServerNameIndicationExtension( + sslSocket * ss, + PRBool append, + PRUint32 maxBytes) +{ + PRUint32 len, span; + /* must have a hostname */ + if (!ss || !ss->url || !ss->url[0]) + return 0; + /* must have at lest one character other than [0-9\.] */ + len = PORT_Strlen(ss->url); + span = strspn(ss->url, "0123456789."); + if (len == span) { + /* is a dotted decimal IP address */ + return 0; + } + if (append && maxBytes >= len + 9) { + SECStatus rv; + /* extension_type */ + rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + if (rv != SECSuccess) return 0; + /* length of extension_data */ + rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); + if (rv != SECSuccess) return 0; + /* length of server_name_list */ + rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2); + if (rv != SECSuccess) return 0; + /* Name Type (host_name) */ + rv = ssl3_AppendHandshake(ss, "\0", 1); + if (rv != SECSuccess) return 0; + /* HostName (length and value) */ + rv = ssl3_AppendHandshakeVariable(ss, ss->url, len, 2); + if (rv != SECSuccess) return 0; + } + return len + 9; +} + +/* handle an incoming SNI extension, by ignoring it. */ +SECStatus +ssl3_HandleServerNameIndicationExtension(sslSocket * ss, PRUint16 ex_type, + SECItem *data) +{ + /* For now, we ignore this, as if we didn't understand it. :-) */ + return SECSuccess; +} + +/* Table of handlers for received TLS hello extensions, one per extension. + * In the second generation, this table will be dynamic, and functions + * will be registered here. + */ +static const ssl3HelloExtensionHandler handlers[] = { + { 0, &ssl3_HandleServerNameIndicationExtension }, +#ifdef NSS_ENABLE_ECC + { 10, &ssl3_HandleSupportedEllipticCurvesExtension }, + { 11, &ssl3_HandleSupportedPointFormatsExtension }, +#endif + { -1, NULL } +}; + +/* Table of functions to format TLS hello extensions, one per extension. + * This static table is for the formatting of client hello extensions. + * The server's table of hello senders is dynamic, in the socket struct, + * and sender functions are registered there. + */ +static const +ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSION_SENDERS] = { + { 0, &ssl3_SendServerNameIndicationExtension }, +#ifdef NSS_ENABLE_ECC + { 10, &ssl3_SendSupportedEllipticCurvesExtension }, + { 11, &ssl3_SendSupportedPointFormatsExtension }, +#else + { -1, NULL } +#endif +}; + +/* go through hello extensions in buffer "b". + * For each one, find the extension handler in the table above, and + * if present, invoke that handler. + * ignore any extensions with unknown extension types. + */ +SECStatus +ssl3_HandleClientHelloExtensions(sslSocket *ss, + SSL3Opaque **b, + PRUint32 *length) +{ + while (*length) { + const ssl3HelloExtensionHandler * handler; + SECStatus rv; + PRInt32 extension_type; + SECItem extension_data; + + /* Get the extension's type field */ + extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); + if (extension_type < 0) /* failure to decode extension_type */ + return SECFailure; /* alert already sent */ + + /* get the data for this extension, so we can pass it or skip it. */ + rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length); + if (rv != SECSuccess) + return rv; + + /* find extension_type in table of Client Hello Extension Handlers */ + for (handler = handlers; handler->ex_type >= 0; handler++) { + if (handler->ex_type == extension_type) + break; + } + + /* if found, Call this handler */ + if (handler->ex_type == extension_type) { + rv = (*handler->ex_handler)(ss, (PRUint16)extension_type, + &extension_data); + /* Ignore this result */ + /* Essentially, treat all bad extensions as unrecognized types. */ + } + } + return SECSuccess; +} + +/* Add a callback function to the table of senders of server hello extensions. + */ +SECStatus +ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, + ssl3HelloExtensionSenderFunc cb) +{ + int i; + ssl3HelloExtensionSender *sender = &ss->serverExtensionSenders[0]; + + for (i = 0; i < MAX_EXTENSION_SENDERS; ++i, ++sender) { + if (!sender->ex_sender) { + sender->ex_type = ex_type; + sender->ex_sender = cb; + return SECSuccess; + } + /* detect duplicate senders */ + PORT_Assert(sender->ex_type != ex_type); + if (sender->ex_type == ex_type) { + /* duplicate */ + break; + } + } + PORT_Assert(i < MAX_EXTENSION_SENDERS); /* table needs to grow */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +} + +/* call each of the extension senders and return the accumulated length */ +PRInt32 +ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, + const ssl3HelloExtensionSender *sender) +{ + PRInt32 total_exten_len = 0; + int i; + + if (!sender) + sender = &clientHelloSenders[0]; + + for (i = 0; i < MAX_EXTENSION_SENDERS; ++i, ++sender) { + if (sender->ex_sender) { + PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); + if (extLen < 0) + return -1; + maxBytes -= extLen; + total_exten_len += extLen; + } + } + return total_exten_len; +} + diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h index d466c614d..b57314005 100644 --- a/security/nss/lib/ssl/ssl3prot.h +++ b/security/nss/lib/ssl/ssl3prot.h @@ -130,7 +130,14 @@ typedef enum { insufficient_security = 71, internal_error = 80, user_canceled = 90, - no_renegotiation = 100 + no_renegotiation = 100, + +/* Alerts for client hello extensions */ + unsupported_extension = 110, + certificate_unobtainable = 111, + unrecognized_name = 112, + bad_certificate_status_response = 113, + bad_certificate_hash_value = 114 } SSL3AlertDescription; @@ -210,7 +217,8 @@ typedef enum { kea_ecdh_ecdsa, kea_ecdhe_ecdsa, kea_ecdh_rsa, - kea_ecdhe_rsa + kea_ecdhe_rsa, + kea_ecdh_anon } SSL3KeyExchangeAlgorithm; typedef struct { @@ -250,13 +258,9 @@ typedef enum { ct_DSS_fixed_DH = 4, ct_RSA_ephemeral_DH = 5, ct_DSS_ephemeral_DH = 6, - /* XXX The numbers assigned to the following EC-based - * certificate types might change before the ECC in TLS - * draft becomes an IETF RFC. - */ - ct_ECDSA_sign = 7, - ct_RSA_fixed_ECDH = 8, - ct_ECDSA_fixed_ECDH = 9 + ct_ECDSA_sign = 64, + ct_RSA_fixed_ECDH = 65, + ct_ECDSA_fixed_ECDH = 66 } SSL3ClientCertificateType; diff --git a/security/nss/lib/ssl/sslauth.c b/security/nss/lib/ssl/sslauth.c index 848f5aa63..45108afd7 100644 --- a/security/nss/lib/ssl/sslauth.c +++ b/security/nss/lib/ssl/sslauth.c @@ -116,11 +116,14 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, } else { cipherName = ssl3_cipherName[ss->sec.cipherType]; } - if (cipherName && PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE; - - if (cp) { - *cp = PORT_Strdup(cipherName); - } + PORT_Assert(cipherName); + if (cipherName) { + if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE; + + if (cp) { + *cp = PORT_Strdup(cipherName); + } + } if (kp0) { *kp0 = ss->sec.keyBits; diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c index 06ec09813..1cfe54220 100644 --- a/security/nss/lib/ssl/sslcon.c +++ b/security/nss/lib/ssl/sslcon.c @@ -230,7 +230,7 @@ ssl2_ConstructCipherSpecs(sslSocket *ss) (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) { const PRUint8 * hs = implementedCipherSuites + i; - int ok = allowed & (1U << hs[0]); + unsigned int ok = allowed & (1U << hs[0]); if (ok) { cs[0] = hs[0]; cs[1] = hs[1]; @@ -679,7 +679,7 @@ done: * Acquires and releases the socket's xmitBufLock. */ static SECStatus -ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, +ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keyBits, PRUint8 *ca, int caLen, PRUint8 *ck, int ckLen, PRUint8 *ek, int ekLen) @@ -704,8 +704,8 @@ ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_CLIENT_MASTER_KEY; msg[1] = cipher; - msg[2] = MSB(keySize); - msg[3] = LSB(keySize); + msg[2] = MSB(keyBits); + msg[3] = LSB(keyBits); msg[4] = MSB(ckLen); msg[5] = LSB(ckLen); msg[6] = MSB(ekLen); @@ -926,8 +926,8 @@ ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) if ((unsigned)rv < (amount + 2)) { /* Short write. Save the data and return. */ - if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv, - amount + 2 - rv) == SECFailure) { + if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) + == SECFailure) { count = SECFailure; } else { count += amount; @@ -1023,8 +1023,7 @@ ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) if ((unsigned)rv < buflen) { /* Short write. Save the data and return. */ - if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv, - buflen - rv) == SECFailure) { + if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) { count = SECFailure; } else { count += amount; @@ -1152,8 +1151,7 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) if (rv < (op - out)) { /* Short write. Save the data and return. */ - if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv, - op - out - rv) == SECFailure) { + if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) { count = SECFailure; } else { count += amount; @@ -1581,15 +1579,17 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, PRUint8 *ek, unsigned int ekLen, PRUint8 *ca, unsigned int caLen) { - PRUint8 *kk = NULL; + PRUint8 * dk = NULL; /* decrypted master key */ sslSessionID * sid; + sslServerCerts * sc = ss->serverCerts + kt_rsa; PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */ - unsigned int el1; /* length of RSA decrypted data in kbuf */ + unsigned int ddLen; /* length of RSA decrypted data in kbuf */ unsigned int keySize; - unsigned int modulusLen; + unsigned int dkLen; /* decrypted key length in bytes */ + int modulusLen; SECStatus rv; + PRUint16 allowed; /* cipher kinds enabled and allowed by policy */ PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES]; - sslServerCerts * sc = ss->serverCerts + kt_rsa; PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); @@ -1597,18 +1597,6 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, PORT_Assert((ss->sec.ci.sid != 0)); sid = ss->sec.ci.sid; - keySize = (keyBits + 7) >> 3; - /* Is the message just way too big? */ - if (keySize > SSL_MAX_MASTER_KEY_BYTES) { - /* bummer */ - SSL_DBG(("%d: SSL[%d]: keySize=%d ckLen=%d max session key size=%d", - SSL_GETPID(), ss->fd, keySize, ckLen, - SSL_MAX_MASTER_KEY_BYTES)); - PORT_SetError(SSL_ERROR_BAD_CLIENT); - goto loser; - } - - /* Trying to cut down on all these switch statements that should be tables. * So, test cipherType once, here, and then use tables below. */ @@ -1628,50 +1616,72 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, goto loser; } - /* For export ciphers, make sure they didn't send too much key data. */ + allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; + if (!(allowed & (1U << cipher))) { + /* client chose a kind we don't allow! */ + SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d", + SSL_GETPID(), ss->fd, cipher)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + + keySize = ssl_Specs[cipher].keyLen; + if (keyBits != keySize * BPB) { + SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!", + SSL_GETPID(), ss->fd, keyBits)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + if (ckLen != ssl_Specs[cipher].pubLen) { - SSL_DBG(("%d: SSL[%d]: odd secret key size, keySize=%d ckLen=%d!", - SSL_GETPID(), ss->fd, keySize, ckLen)); - /* Somebody tried to sneak by a strange secret key */ + SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!", + SSL_GETPID(), ss->fd, ckLen)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + + if (caLen != ssl_Specs[cipher].ivLen) { + SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!", + SSL_GETPID(), ss->fd, caLen)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + + modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); + if (modulusLen == -1) { + /* If the key is bad, then PK11_PubDecryptRaw will fail below. */ + modulusLen = ekLen; + } + /* RSA modulus size presently limited to 8k bits maximum */ + if (ekLen > modulusLen || ekLen > 1024 || ekLen + ckLen < keySize) { + SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!", + SSL_GETPID(), ss->fd, ekLen)); PORT_SetError(SSL_ERROR_BAD_CLIENT); goto loser; } /* allocate the buffer to hold the decrypted portion of the key. */ - /* XXX Haven't done any range check on ekLen. */ - kbuf = (PRUint8*) PORT_Alloc(ekLen); + kbuf = (PRUint8*)PORT_Alloc(modulusLen); if (!kbuf) { goto loser; } + dkLen = keySize - ckLen; + dk = kbuf + modulusLen - dkLen; - /* - ** Decrypt encrypted half of the key. Note that encrypted half has - ** been made to match the modulus size of our public key using - ** PKCS#1. keySize is the real size of the data that is interesting. + /* Decrypt encrypted half of the key. ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is ** desired behavior here. */ - rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &el1, ekLen, ek, ekLen); + rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen); if (rv != SECSuccess) goto hide_loser; - modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); - if (modulusLen == -1) { - /* If the key was really bad, then PK11_pubDecryptRaw - * would have failed, therefore the we must assume that the card - * is just being a pain and not giving us the modulus... but it - * should be the same size as the encrypted key length, so use it - * and keep cranking */ - modulusLen = ekLen; - } - /* Is the length of the decrypted data (el1) the expected value? */ - if (modulusLen != el1) + /* Is the length of the decrypted data (ddLen) the expected value? */ + if (modulusLen != ddLen) goto hide_loser; /* Cheaply verify that PKCS#1 was used to format the encryption block */ - kk = kbuf + modulusLen - (keySize - ckLen); - if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (kk[-1] != 0x00)) { - /* Tsk tsk. */ + if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) { SSL_DBG(("%d: SSL[%d]: strange encryption block", SSL_GETPID(), ss->fd)); PORT_SetError(SSL_ERROR_BAD_CLIENT); @@ -1680,10 +1690,10 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, /* Make sure we're not subject to a version rollback attack. */ if (ss->opt.enableSSL3 || ss->opt.enableTLS) { - PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03 }; + static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03 }; - if (PORT_Memcmp(kk - 8 - 1, threes, 8) == 0) { + if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) { PORT_SetError(SSL_ERROR_BAD_CLIENT); goto hide_loser; } @@ -1695,10 +1705,7 @@ hide_loser: * was erroneous. Don't send any error messages. * Instead, Generate a completely bogus master key . */ - PK11_GenerateRandom(kbuf, ekLen); - if (!kk) { - kk = kbuf + ekLen - (keySize-ckLen); - } + PK11_GenerateRandom(dk, dkLen); } /* @@ -1707,7 +1714,7 @@ hide_loser: if (ckLen) { PORT_Memcpy(mkbuf, ck, ckLen); } - PORT_Memcpy(mkbuf+ckLen, kk, keySize-ckLen); + PORT_Memcpy(mkbuf + ckLen, dk, dkLen); /* Fill in session-id */ rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen, @@ -1750,6 +1757,8 @@ hide_loser: * in the first byte, and none of the SSLv2 ciphers do. * * Called from ssl2_HandleClientHelloMessage(). +* Returns the number of bytes of "qualified cipher specs", +* which is typically a multiple of 3, but will be zero if there are none. */ static int ssl2_QualifyCypherSpecs(sslSocket *ss, @@ -1767,7 +1776,9 @@ ssl2_QualifyCypherSpecs(sslSocket *ss, PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); if (!ss->cipherSpecs) { - ssl2_ConstructCipherSpecs(ss); + SECStatus rv = ssl2_ConstructCipherSpecs(ss); + if (rv != SECSuccess || !ss->cipherSpecs) + return 0; } PRINT_BUF(10, (ss, "specs from client:", cs, csLen)); @@ -1823,19 +1834,23 @@ ssl2_ChooseSessionCypher(sslSocket *ss, int keySize; int realKeySize; PRUint8 * ohs = hs; + const PRUint8 * preferred; + static const PRUint8 noneSuch[3] = { 0, 0, 0 }; PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); if (!ss->cipherSpecs) { - ssl2_ConstructCipherSpecs(ss); + SECStatus rv = ssl2_ConstructCipherSpecs(ss); + if (rv != SECSuccess || !ss->cipherSpecs) + goto loser; } if (!ss->preferredCipher) { - const PRUint8 * preferred = implementedCipherSuites; - unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & + unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; if (allowed) { + preferred = implementedCipherSuites; for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) { if (0 != (allowed & (1U << preferred[0]))) { ss->preferredCipher = preferred; @@ -1845,6 +1860,7 @@ ssl2_ChooseSessionCypher(sslSocket *ss, } } } + preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch; /* ** Scan list of ciphers recieved from peer and look for a match in ** our list. @@ -1857,9 +1873,9 @@ ssl2_ChooseSessionCypher(sslSocket *ss, bestCypher = -1; while (--hc >= 0) { for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) { - if ((hs[0] == ss->preferredCipher[0]) && - (hs[1] == ss->preferredCipher[1]) && - (hs[2] == ss->preferredCipher[2]) && + if ((hs[0] == preferred[0]) && + (hs[1] == preferred[1]) && + (hs[2] == preferred[2]) && hs[0] != 0) { /* Pick this cipher immediately! */ *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3; @@ -1974,7 +1990,10 @@ ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data) SECStatus rv; int i; - PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))); + if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return NULL; + } block = (unsigned char *) PORT_Alloc(modulusLen); if (block == NULL) return NULL; @@ -3113,7 +3132,16 @@ ssl2_BeginClientHandshake(sslSocket *ss) return rv; } - +#if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B) + /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */ + ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ + if (ss->cipherSpecs != NULL) { + PORT_Free(ss->cipherSpecs); + ss->cipherSpecs = NULL; + ss->sizeCipherSpecs = 0; + } +#endif + if (!ss->cipherSpecs) { rv = ssl2_ConstructCipherSpecs(ss); if (rv < 0) { @@ -3207,7 +3235,7 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) unsigned int caLen; unsigned int ckLen; unsigned int ekLen; - unsigned int keySize; + unsigned int keyBits; int cipher; SECStatus rv; @@ -3222,13 +3250,13 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) goto bad_client; } cipher = data[1]; - keySize = (data[2] << 8) | data[3]; + keyBits = (data[2] << 8) | data[3]; ckLen = (data[4] << 8) | data[5]; ekLen = (data[6] << 8) | data[7]; caLen = (data[8] << 8) | data[9]; - SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keySize=%d ckLen=%d ekLen=%d caLen=%d", - SSL_GETPID(), ss->fd, cipher, keySize, ckLen, ekLen, caLen)); + SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d", + SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen)); if (ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) { @@ -3238,8 +3266,7 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) } /* Use info from client to setup session key */ - /* XXX should validate cipher&keySize are in our array */ - rv = ssl2_ServerSetupSessionCypher(ss, cipher, keySize, + rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen); @@ -3266,7 +3293,8 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) } SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d", - SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); + SSL_GETPID(), ss->fd, + ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); ss->handshake = ssl_GatherRecord1stHandshake; ss->nextHandshake = ssl2_HandleMessage; @@ -3742,7 +3770,8 @@ ssl2_BeginServerHandshake(sslSocket *ss) ss->sec.rcvSequence = 0; /* don't turn on SSL2 if we don't have an RSA key and cert */ - if (!rsaAuth->SERVERKEY || !rsaAuth->serverCert) { + if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || + !rsaAuth->serverCert) { ss->opt.enableSSL2 = PR_FALSE; } diff --git a/security/nss/lib/ssl/ssldef.c b/security/nss/lib/ssl/ssldef.c index 23ef9cafe..9a473380e 100644 --- a/security/nss/lib/ssl/ssldef.c +++ b/security/nss/lib/ssl/ssldef.c @@ -104,14 +104,15 @@ int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) } /* Default (unencrypted) send. - * Returns SECSuccess or SECFailure, NOT SECWouldBlock. - * Returns positive count if any data was written. - * ALWAYS check for a short write after calling ssl_DefSend. + * For blocking sockets, always returns len or SECFailure, no short writes. + * For non-blocking sockets: + * Returns positive count if any data was written, else returns SECFailure. + * Short writes may occur. Does not return SECWouldBlock. */ int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) { PRFileDesc *lower = ss->fd->lower; - int rv, count; + int sent = 0; #if NSS_DISABLE_NAGLE_DELAYS /* Although this is overkill, we disable Nagle delays completely for @@ -122,32 +123,24 @@ int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) ss->delayDisabled = 1; } #endif - count = 0; - for (;;) { - rv = lower->methods->send(lower, (const void *)buf, len, - flags, ss->wTimeout); + do { + int rv = lower->methods->send(lower, (const void *)(buf + sent), + len - sent, flags, ss->wTimeout); if (rv < 0) { PRErrorCode err = PR_GetError(); if (err == PR_WOULD_BLOCK_ERROR) { ss->lastWriteBlocked = 1; - return count ? count : rv; + return sent ? sent : SECFailure; } ss->lastWriteBlocked = 0; MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) /* Loser */ return rv; } - count += rv; - if (rv < len) { - /* Short send. Send the rest in the next call */ - buf += rv; - len -= rv; - continue; - } - break; - } + sent += rv; + } while (len > sent); ss->lastWriteBlocked = 0; - return count; + return sent; } int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) @@ -166,33 +159,26 @@ int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len) { PRFileDesc *lower = ss->fd->lower; - int rv, count; + int sent = 0; - count = 0; - for (;;) { - rv = lower->methods->write(lower, (void *)buf, len); + do { + int rv = lower->methods->write(lower, (const void *)(buf + sent), + len - sent); if (rv < 0) { PRErrorCode err = PR_GetError(); if (err == PR_WOULD_BLOCK_ERROR) { ss->lastWriteBlocked = 1; - return count ? count : rv; + return sent ? sent : SECFailure; } ss->lastWriteBlocked = 0; MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) /* Loser */ return rv; } - count += rv; - if (rv != len) { - /* Short write. Send the rest in the next call */ - buf += rv; - len -= rv; - continue; - } - break; - } + sent += rv; + } while (len > sent); ss->lastWriteBlocked = 0; - return count; + return sent; } int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name) diff --git a/security/nss/lib/ssl/sslenum.c b/security/nss/lib/ssl/sslenum.c index d28d689b7..f53bd2268 100644 --- a/security/nss/lib/ssl/sslenum.c +++ b/security/nss/lib/ssl/sslenum.c @@ -47,6 +47,10 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* 256-bit */ +#ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, +#endif /* NSS_ENABLE_ECC */ TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, #ifdef NSS_ENABLE_ECC @@ -57,7 +61,9 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* 128-bit */ #ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, #endif /* NSS_ENABLE_ECC */ TLS_DHE_DSS_WITH_RC4_128_SHA, @@ -74,6 +80,10 @@ const PRUint16 SSL_ImplementedCiphers[] = { TLS_RSA_WITH_AES_128_CBC_SHA, /* 112-bit 3DES */ +#ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, +#endif /* NSS_ENABLE_ECC */ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, #ifdef NSS_ENABLE_ECC @@ -86,10 +96,6 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* 56-bit DES "domestic" cipher suites */ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, -#ifdef NSS_ENABLE_ECC - TLS_ECDH_RSA_WITH_DES_CBC_SHA, - TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, -#endif /* NSS_ENABLE_ECC */ SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, @@ -103,6 +109,8 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* ciphersuites with no encryption */ #ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, TLS_ECDH_RSA_WITH_NULL_SHA, TLS_ECDH_ECDSA_WITH_NULL_SHA, #endif /* NSS_ENABLE_ECC */ diff --git a/security/nss/lib/ssl/sslerr.h b/security/nss/lib/ssl/sslerr.h index be808b8bc..c17014c24 100644 --- a/security/nss/lib/ssl/sslerr.h +++ b/security/nss/lib/ssl/sslerr.h @@ -186,6 +186,12 @@ SSL_ERROR_NO_RENEGOTIATION_ALERT = (SSL_ERROR_BASE + 102), SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED = (SSL_ERROR_BASE + 103), +SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT = (SSL_ERROR_BASE + 104), +SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT = (SSL_ERROR_BASE + 105), +SSL_ERROR_UNRECOGNIZED_NAME_ALERT = (SSL_ERROR_BASE + 106), +SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT = (SSL_ERROR_BASE + 107), +SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT = (SSL_ERROR_BASE + 108), + SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ } SSLErrorCodes; #endif /* NO_SECURITY_ERROR_ENUM */ diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index 45e7fa552..26c353b29 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -170,13 +170,22 @@ typedef enum { SSLAppOpRead = 0, #define SSL3_MASTER_SECRET_LENGTH 48 /* number of wrap mechanisms potentially used to wrap master secrets. */ -#define SSL_NUM_WRAP_MECHS 13 +#define SSL_NUM_WRAP_MECHS 14 /* This makes the cert cache entry exactly 4k. */ #define SSL_MAX_CACHED_CERT_LEN 4060 +#define MAX_EXTENSION_SENDERS 3 + #define NUM_MIXERS 9 +/* Mask of the 25 named curves we support. */ +#ifndef NSS_ECC_MORE_THAN_SUITE_B +#define SSL3_SUPPORTED_CURVES_MASK 0x3800000 /* only 3 curves, suite B*/ +#else +#define SSL3_SUPPORTED_CURVES_MASK 0x3fffffe +#endif + #ifndef BPB #define BPB 8 /* Bits Per Byte */ #endif @@ -217,6 +226,38 @@ typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr, unsigned int sidLen, CERTCertDBHandle * dbHandle); +/* registerable callback function that either appends extension to buffer + * or returns length of data that it would have appended. + */ +typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(sslSocket *ss, PRBool append, + PRUint32 maxBytes); + +/* registerable callback function that handles a received extension, + * of the given type. + */ +typedef SECStatus (* ssl3HelloExtensionHandlerFunc)(sslSocket *ss, + PRUint16 ex_type, + SECItem * data); + +/* row in a table of hello extension senders */ +typedef struct { + PRInt32 ex_type; + ssl3HelloExtensionSenderFunc ex_sender; +} ssl3HelloExtensionSender; + +/* row in a table of hello extension handlers */ +typedef struct { + PRInt32 ex_type; + ssl3HelloExtensionHandlerFunc ex_handler; +} ssl3HelloExtensionHandler; + +extern SECStatus +ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, + ssl3HelloExtensionSenderFunc cb); + +extern PRInt32 +ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, + const ssl3HelloExtensionSender *sender); /* Socket ops */ struct sslSocketOpsStr { @@ -270,9 +311,9 @@ typedef struct { } ssl3CipherSuiteCfg; #ifdef NSS_ENABLE_ECC -#define ssl_V3_SUITES_IMPLEMENTED 40 +#define ssl_V3_SUITES_IMPLEMENTED 43 #else -#define ssl_V3_SUITES_IMPLEMENTED 26 +#define ssl_V3_SUITES_IMPLEMENTED 23 #endif /* NSS_ENABLE_ECC */ typedef struct sslOptionsStr { @@ -552,6 +593,9 @@ struct sslSessionIDStr { SSL3KEAType exchKeyType; /* key type used in exchange algorithm, * and to wrap the sym wrapping key. */ +#ifdef NSS_ENABLE_ECC + PRUint32 negotiatedECCurves; +#endif /* NSS_ENABLE_ECC */ /* The following values are NOT restored from the server's on-disk * session cache, but are restored from the client's cache. @@ -677,6 +721,9 @@ const ssl3CipherSuiteDef *suite_def; PRBool usedStepDownKey; /* we did a server key exchange. */ sslBuffer msgState; /* current state for handshake messages*/ /* protected by recvBufLock */ +#ifdef NSS_ENABLE_ECC + PRUint32 negotiatedECCurves; /* bit mask */ +#endif /* NSS_ENABLE_ECC */ } SSL3HandshakeState; @@ -727,8 +774,8 @@ typedef struct { } SSL3Ciphertext; struct ssl3KeyPairStr { - SECKEYPrivateKey * privKey; /* RSA step down key */ - SECKEYPublicKey * pubKey; /* RSA step down key */ + SECKEYPrivateKey * privKey; + SECKEYPublicKey * pubKey; PRInt32 refCount; /* use PR_Atomic calls for this. */ }; @@ -897,6 +944,7 @@ struct sslSocketStr { unsigned long lastWriteBlocked; unsigned long recvdCloseNotify; /* received SSL EOF. */ unsigned long TCPconnected; + unsigned long appDataBuffered; /* version of the protocol to use */ SSL3ProtocolVersion version; @@ -911,6 +959,9 @@ struct sslSocketStr { sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/ sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/ + /* registered callbacks that send server hello extensions */ + ssl3HelloExtensionSender serverExtensionSenders[MAX_EXTENSION_SENDERS]; + /* the following variable is only used with socks or other proxies. */ char * peerID; /* String uniquely identifies target server. */ @@ -1084,9 +1135,8 @@ extern sslSocket * ssl_DupSocket(sslSocket *old); extern void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *cp, int len); extern void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len); -extern int ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf, - sslSendFunc fp); -extern SECStatus ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, +extern int ssl_SendSavedWriteData(sslSocket *ss); +extern SECStatus ssl_SaveWriteData(sslSocket *ss, const void* p, unsigned int l); extern SECStatus ssl2_BeginClientHandshake(sslSocket *ss); extern SECStatus ssl2_BeginServerHandshake(sslSocket *ss); @@ -1222,7 +1272,10 @@ int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags); extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss); #ifdef NSS_ENABLE_ECC -extern SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss); +extern void ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss); +extern PRBool ssl3_IsECCEnabled(sslSocket *ss); +extern SECStatus ssl3_DisableECCSuites(sslSocket * ss, + const ssl3CipherSuite * suite); #endif /* NSS_ENABLE_ECC */ extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on); @@ -1276,10 +1329,14 @@ extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes); extern SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length); +extern SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, + PRInt32 lenSize); extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize); extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b, PRUint32 *length); +extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length); extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes, SSL3Opaque **b, PRUint32 *length); extern SECStatus ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, @@ -1288,6 +1345,14 @@ extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, SECItem *buf, PRBool isTLS, void *pwArg); +/* functions that append extensions to hello messages. */ +extern PRInt32 ssl3_SendServerNameIndicationExtension( sslSocket * ss, + PRBool append, PRUint32 maxBytes); + +/* call the registered extension handlers. */ +extern SECStatus ssl3_HandleClientHelloExtensions(sslSocket *ss, + SSL3Opaque **b, PRUint32 *length); + /* Construct a new NSPR socket for the app to use */ extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd); extern void ssl_FreePRSocket(PRFileDesc *fd); @@ -1338,27 +1403,6 @@ extern int ssl_MapLowLevelError(int hiLevelError); extern PRUint32 ssl_Time(void); -/* emulation of NSPR routines. */ -extern PRInt32 -ssl_EmulateAcceptRead( PRFileDesc * sd, - PRFileDesc ** nd, - PRNetAddr ** raddr, - void * buf, - PRInt32 amount, - PRIntervalTime timeout); -extern PRInt32 -ssl_EmulateTransmitFile( PRFileDesc * sd, - PRFileDesc * fd, - const void * headers, - PRInt32 hlen, - PRTransmitFileFlags flags, - PRIntervalTime timeout); -extern PRInt32 -ssl_EmulateSendFile( PRFileDesc * sd, - PRSendFileData * sfd, - PRTransmitFileFlags flags, - PRIntervalTime timeout); - SECStatus SSL_DisableDefaultExportCipherSuites(void); SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd); diff --git a/security/nss/lib/ssl/sslinfo.c b/security/nss/lib/ssl/sslinfo.c index d3a9735f0..020c892e9 100644 --- a/security/nss/lib/ssl/sslinfo.c +++ b/security/nss/lib/ssl/sslinfo.c @@ -163,21 +163,27 @@ static const SSLCipherSuiteInfo suiteInfo[] = { /* ECC cipher suites */ {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, }, -{0,CS(TLS_ECDH_ECDSA_WITH_DES_CBC_SHA), S_ECDSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, }, + {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, }, -{0,CS(TLS_ECDH_RSA_WITH_DES_CBC_SHA), S_RSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, }, -{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, - +{0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, }, #endif /* NSS_ENABLE_ECC */ /* SSL 2 table */ diff --git a/security/nss/lib/ssl/sslmutex.c b/security/nss/lib/ssl/sslmutex.c index 0c5ae4cee..77860b3fa 100644 --- a/security/nss/lib/ssl/sslmutex.c +++ b/security/nss/lib/ssl/sslmutex.c @@ -143,17 +143,6 @@ sslMutex_Init(sslMutex *pMutex, int shared) if (err) { return err; } - /* close-on-exec is false by default */ - if (!shared) { - err = fcntl(pMutex->u.pipeStr.mPipes[0], F_SETFD, FD_CLOEXEC); - if (err) - goto loser; - - err = fcntl(pMutex->u.pipeStr.mPipes[1], F_SETFD, FD_CLOEXEC); - if (err) - goto loser; - } - #if NONBLOCKING_POSTS err = setNonBlocking(pMutex->u.pipeStr.mPipes[1], 1); if (err) diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h index e7a998126..f94359cb4 100644 --- a/security/nss/lib/ssl/sslproto.h +++ b/security/nss/lib/ssl/sslproto.h @@ -165,28 +165,35 @@ #define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065 #define TLS_DHE_DSS_WITH_RC4_128_SHA 0x0066 -#ifdef NSS_ENABLE_ECC -/* "Experimental" ECC cipher suites. -** XXX These numbers might change before the current IETF draft -** on ECC cipher suites for TLS becomes an RFC. -*/ -#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0x0047 -#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0x0048 -#define TLS_ECDH_ECDSA_WITH_DES_CBC_SHA 0x0049 -#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0x004A -#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x004B -#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x004C - -#define TLS_ECDH_RSA_WITH_NULL_SHA 0x004D -#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0x004E -#define TLS_ECDH_RSA_WITH_DES_CBC_SHA 0x004F -#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0x0050 -#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0051 -#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0052 - -#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0077 -#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0078 -#endif /* NSS_ENABLE_ECC */ +#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 +#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 +#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 + +#define TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 +#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 +#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 +#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 +#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A + +#define TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B +#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C +#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F + +#define TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 +#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 +#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 + +#define TLS_ECDH_anon_WITH_NULL_SHA 0xC015 +#define TLS_ECDH_anon_WITH_RC4_128_SHA 0xC016 +#define TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA 0xC017 +#define TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 +#define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 /* Netscape "experimental" cipher suites. */ #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0 diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c index a30b062df..0d395f64e 100644 --- a/security/nss/lib/ssl/sslsecur.c +++ b/security/nss/lib/ssl/sslsecur.c @@ -440,24 +440,23 @@ sslBuffer_Grow(sslBuffer *b, unsigned int newLen) ** Caller must hold xmitBufLock */ SECStatus -ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, const void *data, - unsigned int len) +ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len) { unsigned int newlen; SECStatus rv; PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); - newlen = buf->len + len; - if (newlen > buf->space) { - rv = sslBuffer_Grow(buf, newlen); + newlen = ss->pendingBuf.len + len; + if (newlen > ss->pendingBuf.space) { + rv = sslBuffer_Grow(&ss->pendingBuf, newlen); if (rv) { return rv; } } SSL_TRC(5, ("%d: SSL[%d]: saving %d bytes of data (%d total saved so far)", SSL_GETPID(), ss->fd, len, newlen)); - PORT_Memcpy(buf->buf + buf->len, data, len); - buf->len = newlen; + PORT_Memcpy(ss->pendingBuf.buf + ss->pendingBuf.len, data, len); + ss->pendingBuf.len = newlen; return SECSuccess; } @@ -468,28 +467,23 @@ ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, const void *data, ** Caller must hold xmitBufLock */ int -ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf, sslSendFunc send) +ssl_SendSavedWriteData(sslSocket *ss) { int rv = 0; - int len = buf->len; PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); - if (len != 0) { + if (ss->pendingBuf.len != 0) { SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data", - SSL_GETPID(), ss->fd, len)); - rv = (*send)(ss, buf->buf, len, 0); + SSL_GETPID(), ss->fd, ss->pendingBuf.len)); + rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0); if (rv < 0) { return rv; } - if (rv < len) { - /* UGH !! This shifts the whole buffer down by copying it, and - ** it depends on PORT_Memmove doing overlapping moves correctly! - ** It should advance the pointer offset instead !! - */ - PORT_Memmove(buf->buf, buf->buf + rv, len - rv); - buf->len = len - rv; - } else { - buf->len = 0; + ss->pendingBuf.len -= rv; + if (ss->pendingBuf.len > 0 && rv > 0) { + /* UGH !! This shifts the whole buffer down by copying it */ + PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv, + ss->pendingBuf.len); } } return rv; @@ -632,6 +626,7 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, SECStatus rv; sslSocket *ss; sslServerCerts *sc; + SECKEYPublicKey * pubKey = NULL; ss = ssl_FindSocket(fd); if (!ss) { @@ -664,7 +659,6 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, sc->serverCert = NULL; } if (cert) { - SECKEYPublicKey * pubKey; sc->serverCert = CERT_DupCertificate(cert); if (!sc->serverCert) goto loser; @@ -673,8 +667,6 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, if (!pubKey) goto loser; sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey); - SECKEY_DestroyPublicKey(pubKey); - pubKey = NULL; } @@ -723,11 +715,12 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, if (keyCopy == NULL) goto loser; SECKEY_CacheStaticFlags(keyCopy); - sc->serverKeyPair = ssl3_NewKeyPair(keyCopy, NULL); + sc->serverKeyPair = ssl3_NewKeyPair(keyCopy, pubKey); if (sc->serverKeyPair == NULL) { SECKEY_DestroyPrivateKey(keyCopy); goto loser; } + pubKey = NULL; /* adopted by serverKeyPair */ } if (kea == kt_rsa && cert && sc->serverKeyBits > 512) { @@ -748,6 +741,10 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, return SECSuccess; loser: + if (pubKey) { + SECKEY_DestroyPublicKey(pubKey); + pubKey = NULL; + } if (sc->serverCert != NULL) { CERT_DestroyCertificate(sc->serverCert); sc->serverCert = NULL; @@ -1017,7 +1014,7 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) { ssl_GetXmitBufLock(ss); if (ss->pendingBuf.len != 0) { - rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend); + rv = ssl_SendSavedWriteData(ss); if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { ssl_ReleaseXmitBufLock(ss); return SECFailure; @@ -1072,7 +1069,7 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) ssl_GetXmitBufLock(ss); if (ss->pendingBuf.len != 0) { PORT_Assert(ss->pendingBuf.len > 0); - rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend); + rv = ssl_SendSavedWriteData(ss); if (rv >= 0 && ss->pendingBuf.len != 0) { PORT_Assert(ss->pendingBuf.len > 0); PORT_SetError(PR_WOULD_BLOCK_ERROR); @@ -1106,6 +1103,10 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) return 0; } PORT_Assert(buf != NULL); + if (!buf) { + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); + return PR_FAILURE; + } SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", SSL_GETPID(), ss->fd, len)); diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c index 877a5a995..b0649f76e 100644 --- a/security/nss/lib/ssl/sslsnce.c +++ b/security/nss/lib/ssl/sslsnce.c @@ -224,6 +224,7 @@ struct cacheDescStr { struct cacheDescStr * sharedCache; /* shared copy of this struct */ PRFileMap * cacheMemMap; PRThread * poller; + PRUint32 mutexTimeout; PRBool shared; }; typedef struct cacheDescStr cacheDesc; @@ -270,6 +271,7 @@ static PRUint32 ssl_max_sid_cache_locks = MAX_SID_CACHE_LOCKS; static PRUint32 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl); static SECStatus LaunchLockPoller(cacheDesc *cache); +static SECStatus StopLockPoller(cacheDesc *cache); struct inheritanceStr { @@ -750,12 +752,14 @@ ServerSessionIDCache(sslSessionID *sid) if (sid->cached == never_cached || sid->cached == invalid_cache) { PRUint32 set; - PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0); + PORT_Assert(sid->creationTime != 0); if (!sid->creationTime) sid->lastAccessTime = sid->creationTime = ssl_Time(); if (version < SSL_LIBRARY_VERSION_3_0) { - if (!sid->expirationTime) - sid->expirationTime = sid->creationTime + ssl_sid_timeout; + /* override caller's expiration time, which uses client timeout + * duration, not server timeout duration. + */ + sid->expirationTime = sid->creationTime + cache->ssl2Timeout; SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x " "cipher=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], @@ -769,8 +773,10 @@ ServerSessionIDCache(sslSessionID *sid) sid->u.ssl2.cipherArg.len)); } else { - if (!sid->expirationTime) - sid->expirationTime = sid->creationTime + ssl3_sid_timeout; + /* override caller's expiration time, which uses client timeout + * duration, not server timeout duration. + */ + sid->expirationTime = sid->creationTime + cache->ssl3Timeout; SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x " "cipherSuite=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], @@ -888,7 +894,8 @@ CloseCache(cacheDesc *cache) ** be) in use by multiple processes. We do not wish to destroy ** the mutexes while they are still in use. */ - if (PR_FALSE == cache->sharedCache->everInherited) { + if (cache->sharedCache && + PR_FALSE == cache->sharedCache->everInherited) { sidCacheLock *pLock = cache->sidCacheLocks; for (; locks_initialized > 0; --locks_initialized, ++pLock ) { sslMutex_Destroy(&pLock->mutex); @@ -937,6 +944,13 @@ InitCache(cacheDesc *cache, int maxCacheEntries, PRUint32 ssl2_timeout, cache->cacheMemMap = cacheMemMap = NULL; cache->sharedCache = (cacheDesc *)0; + cache->numSIDCacheLocksInitialized = 0; + cache->nextCertCacheEntry = 0; + cache->stopPolling = PR_FALSE; + cache->everInherited = PR_FALSE; + cache->poller = NULL; + cache->mutexTimeout = 0; + cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries : DEF_SID_CACHE_ENTRIES; cache->numSIDCacheSets = @@ -1185,6 +1199,10 @@ SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache) SECStatus SSL_ShutdownServerSessionIDCache(void) { +#if defined(XP_UNIX) || defined(XP_BEOS) + /* Stop the thread that polls cache for expired locks on Unix */ + StopLockPoller(&globalCache); +#endif SSL3_ShutdownServerCache(); return SSL_ShutdownServerSessionIDCacheInstance(&globalCache); } @@ -1436,23 +1454,12 @@ LockPoller(void * arg) cacheDesc * cache = (cacheDesc *)arg; cacheDesc * sharedCache = cache->sharedCache; sidCacheLock * pLock; - const char * timeoutString; PRIntervalTime timeout; PRUint32 now; PRUint32 then; int locks_polled = 0; int locks_to_poll = cache->numSIDCacheLocks + 2; - PRUint32 expiration = SID_LOCK_EXPIRATION_TIMEOUT; - - timeoutString = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT"); - if (timeoutString) { - long newTime = strtol(timeoutString, 0, 0); - if (newTime == 0) - return; /* application doesn't want this function */ - if (newTime > 0) - expiration = (PRUint32)newTime; - /* if error (newTime < 0) ignore it and use default */ - } + PRUint32 expiration = cache->mutexTimeout; timeout = PR_SecondsToInterval(expiration); while(!sharedCache->stopPolling) { @@ -1494,17 +1501,47 @@ LockPoller(void * arg) static SECStatus LaunchLockPoller(cacheDesc *cache) { - PRThread * pollerThread; + const char * timeoutString; + PRThread * pollerThread; + + cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT; + timeoutString = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT"); + if (timeoutString) { + long newTime = strtol(timeoutString, 0, 0); + if (newTime == 0) + return SECSuccess; /* application doesn't want poller thread */ + if (newTime > 0) + cache->mutexTimeout = (PRUint32)newTime; + /* if error (newTime < 0) ignore it and use default */ + } pollerThread = PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (!pollerThread) { return SECFailure; } cache->poller = pollerThread; return SECSuccess; } + +/* Stop the thread that polls cache for expired locks */ +static SECStatus +StopLockPoller(cacheDesc *cache) +{ + if (!cache->poller) { + return SECSuccess; + } + cache->sharedCache->stopPolling = PR_TRUE; + if (PR_Interrupt(cache->poller) != PR_SUCCESS) { + return SECFailure; + } + if (PR_JoinThread(cache->poller) != PR_SUCCESS) { + return SECFailure; + } + cache->poller = NULL; + return SECSuccess; +} #endif /************************************************************************ diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 6344c99c5..924d993d0 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -48,6 +48,9 @@ #include "sslimpl.h" #include "sslproto.h" #include "nspr.h" +#include "private/pprio.h" +#include "blapi.h" +#include "nss.h" #define SET_ERROR_CODE /* reminder */ @@ -97,18 +100,24 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */ #ifdef NSS_ENABLE_ECC { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, - { TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, { TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, - { TLS_ECDH_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, - { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, #endif /* NSS_ENABLE_ECC */ { 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED } }; @@ -291,6 +300,8 @@ ssl_DupSocket(sslSocket *os) } ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL : ssl3_GetKeyPairRef(os->stepDownKeyPair); + ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL : + ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair); /* * XXX the preceeding CERT_ and SECKEY_ functions can fail and return NULL. * XXX We should detect this, and not just march on with NULL pointers. @@ -396,6 +407,10 @@ ssl_DestroySocketContents(sslSocket *ss) ssl3_FreeKeyPair(ss->stepDownKeyPair); ss->stepDownKeyPair = NULL; } + if (ss->ephemeralECDHKeyPair) { + ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); + ss->ephemeralECDHKeyPair = NULL; + } } /* @@ -488,6 +503,29 @@ SSL_Enable(PRFileDesc *fd, int which, PRBool on) return SSL_OptionSet(fd, which, on); } +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType setupBypassOnce; + +static SECStatus SSL_BypassShutdown(void* appData, void* nssData) +{ + /* unload freeBL shared library from memory */ + BL_Unload(); + setupBypassOnce = pristineCallOnce; + return SECSuccess; +} + +static PRStatus SSL_BypassRegisterShutdown(void) +{ + SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL); + PORT_Assert(SECSuccess == rv); + return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE; +} + +static PRStatus SSL_BypassSetup(void) +{ + return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown); +} + SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) { @@ -612,7 +650,15 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) PORT_SetError(PR_INVALID_STATE_ERROR); rv = SECFailure; } else { - ss->opt.bypassPKCS11 = on; + if (PR_FALSE != on) { + if (PR_SUCCESS == SSL_BypassSetup() ) { + ss->opt.bypassPKCS11 = on; + } else { + rv = SECFailure; + } + } else { + ss->opt.bypassPKCS11 = PR_FALSE; + } } break; @@ -833,7 +879,15 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) break; case SSL_BYPASS_PKCS11: - ssl_defaults.bypassPKCS11 = on; + if (PR_FALSE != on) { + if (PR_SUCCESS == SSL_BypassSetup()) { + ssl_defaults.bypassPKCS11 = on; + } else { + return SECFailure; + } + } else { + ssl_defaults.bypassPKCS11 = PR_FALSE; + } break; case SSL_NO_LOCKS: @@ -1586,6 +1640,24 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags) return new_flags; } +static PRInt32 PR_CALLBACK +ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, + const void *headers, PRInt32 hlen, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PRSendFileData sfd; + + sfd.fd = fd; + sfd.file_offset = 0; + sfd.file_nbytes = 0; + sfd.header = headers; + sfd.hlen = hlen; + sfd.trailer = NULL; + sfd.tlen = 0; + + return sd->methods->sendfile(sd, &sfd, flags, timeout); +} + PRBool ssl_FdIsBlocking(PRFileDesc *fd) @@ -1646,7 +1718,7 @@ ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors, } \ /* Only a nonblocking socket can have partial sends */ \ PR_ASSERT(!blocking); \ - return sent; \ + return sent + rv; \ } #define SEND(bfr, len) \ do { \ @@ -1842,15 +1914,15 @@ static const PRIOMethods ssl_methods = { ssl_RecvFrom, /* recvfrom */ ssl_SendTo, /* sendto */ ssl_Poll, /* poll */ - ssl_EmulateAcceptRead, /* acceptread */ - ssl_EmulateTransmitFile, /* transmitfile */ + PR_EmulateAcceptRead, /* acceptread */ + ssl_TransmitFile, /* transmitfile */ ssl_GetSockName, /* getsockname */ ssl_GetPeerName, /* getpeername */ NULL, /* getsockopt OBSOLETE */ NULL, /* setsockopt OBSOLETE */ NULL, /* getsocketoption */ NULL, /* setsocketoption */ - ssl_EmulateSendFile, /* Send a (partial) file with header/trailer*/ + PR_EmulateSendFile, /* Send a (partial) file with header/trailer*/ NULL, /* reserved for future use */ NULL, /* reserved for future use */ NULL, /* reserved for future use */ diff --git a/security/nss/lib/util/derenc.c b/security/nss/lib/util/derenc.c index c894ed729..3470f74f7 100644 --- a/security/nss/lib/util/derenc.c +++ b/security/nss/lib/util/derenc.c @@ -124,6 +124,7 @@ header_length(DERTemplate *dtemplate, uint32 contents_len) under_kind = dtemplate->arg; } } else if (encode_kind & DER_INLINE) { + PORT_Assert (dtemplate->sub != NULL); under_kind = dtemplate->sub->kind; if (universal) { encode_kind = under_kind; @@ -229,9 +230,8 @@ contents_length(DERTemplate *dtemplate, void *src) if (under_kind & DER_INDEFINITE) { uint32 sub_len; - void **indp; + void **indp = *(void ***)src; - indp = *(void ***)src; if (indp == NULL) return 0; @@ -239,13 +239,11 @@ contents_length(DERTemplate *dtemplate, void *src) under_kind &= ~DER_INDEFINITE; if (under_kind == DER_SET || under_kind == DER_SEQUENCE) { - DERTemplate *tmpt; - void *sub_src; - - tmpt = dtemplate->sub; + DERTemplate *tmpt = dtemplate->sub; + PORT_Assert (tmpt != NULL); for (; *indp != NULL; indp++) { - sub_src = (void *)((char *)(*indp) + tmpt->offset); + void *sub_src = (void *)((char *)(*indp) + tmpt->offset); sub_len = contents_length (tmpt, sub_src); len += sub_len + header_length (tmpt, sub_len); } @@ -255,8 +253,7 @@ contents_length(DERTemplate *dtemplate, void *src) * DER_INDEFINITE | DER_OCTET_STRING) is right. */ for (; *indp != NULL; indp++) { - SECItem *item; - item = (SECItem *)(*indp); + SECItem *item = (SECItem *)(*indp); sub_len = item->len; if (under_kind == DER_BIT_STRING) { sub_len = (sub_len + 7) >> 3; @@ -391,12 +388,10 @@ der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src) under_kind &= ~DER_INDEFINITE; if (under_kind == DER_SET || under_kind == DER_SEQUENCE) { - DERTemplate *tmpt; - void *sub_src; - - tmpt = dtemplate->sub; + DERTemplate *tmpt = dtemplate->sub; + PORT_Assert (tmpt != NULL); for (; *indp != NULL; indp++) { - sub_src = (void *)((char *)(*indp) + tmpt->offset); + void *sub_src = (void *)((char *)(*indp) + tmpt->offset); buf = der_encode (buf, tmpt, sub_src); } } else { diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c index ab0914b5d..068d52ed6 100644 --- a/security/nss/lib/util/secasn1d.c +++ b/security/nss/lib/util/secasn1d.c @@ -1256,6 +1256,12 @@ regular_string_type: struct subitem *subitem; int len; + PORT_Assert (item); + if (!item) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return; + } PORT_Assert (item->len == 0 && item->data == NULL); /* * Check for and handle an ANY which has stashed aside the @@ -1408,7 +1414,7 @@ sec_asn1d_free_child (sec_asn1d_state *state, PRBool error) if (state->child != NULL) { PORT_Assert (error || state->child->consumed == 0); PORT_Assert (state->our_mark != NULL); - PORT_ArenaRelease (state->top->our_pool, state->our_mark); + PORT_ArenaZRelease (state->top->our_pool, state->our_mark); if (error && state->top->their_pool == NULL) { /* * XXX We need to free anything allocated. @@ -1664,6 +1670,8 @@ sec_asn1d_add_to_subitems (sec_asn1d_state *state, copy = sec_asn1d_alloc (state->top->our_pool, len); if (copy == NULL) { state->top->status = decodeError; + if (!state->top->our_pool) + PORT_Free(thing); return NULL; } PORT_Memcpy (copy, data, len); @@ -2841,7 +2849,7 @@ SEC_ASN1DecoderFinish (SEC_ASN1DecoderContext *cx) * XXX anything else that needs to be finished? */ - PORT_FreeArena (cx->our_pool, PR_FALSE); + PORT_FreeArena (cx->our_pool, PR_TRUE); return rv; } diff --git a/security/nss/lib/util/secasn1e.c b/security/nss/lib/util/secasn1e.c index db7792cb1..2300060df 100644 --- a/security/nss/lib/util/secasn1e.c +++ b/security/nss/lib/util/secasn1e.c @@ -1639,7 +1639,7 @@ SEC_ASN1EncodeInteger(PRArenaPool *poolp, SECItem *dest, long value) } -extern SECItem * +SECItem * SEC_ASN1EncodeUnsignedInteger(PRArenaPool *poolp, SECItem *dest, unsigned long value) { diff --git a/security/nss/lib/util/secdig.c b/security/nss/lib/util/secdig.c index 263c8030f..07c136a74 100644 --- a/security/nss/lib/util/secdig.c +++ b/security/nss/lib/util/secdig.c @@ -166,21 +166,26 @@ SGN_DecodeDigestInfo(SECItem *didata) PRArenaPool *arena; SGNDigestInfo *di; SECStatus rv = SECFailure; + SECItem diCopy = {siBuffer, NULL, 0}; arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); if(arena == NULL) return NULL; + rv = SECITEM_CopyItem(arena, &diCopy, didata); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + return NULL; + } + di = (SGNDigestInfo *)PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo)); - if(di != NULL) - { + if (di != NULL) { di->arena = arena; - rv = SEC_ASN1DecodeItem(arena, di, sgn_DigestInfoTemplate, didata); + rv = SEC_QuickDERDecodeItem(arena, di, sgn_DigestInfoTemplate, &diCopy); } - if((di == NULL) || (rv != SECSuccess)) - { - PORT_FreeArena(arena, PR_TRUE); + if ((di == NULL) || (rv != SECSuccess)) { + PORT_FreeArena(arena, PR_FALSE); di = NULL; } diff --git a/security/nss/lib/util/secerr.h b/security/nss/lib/util/secerr.h index 2cc1bcef3..d47734fe1 100644 --- a/security/nss/lib/util/secerr.h +++ b/security/nss/lib/util/secerr.h @@ -204,6 +204,8 @@ SEC_ERROR_UNKNOWN_OBJECT_TYPE = (SEC_ERROR_BASE + 150), SEC_ERROR_INCOMPATIBLE_PKCS11 = (SEC_ERROR_BASE + 151), SEC_ERROR_NO_EVENT = (SEC_ERROR_BASE + 152), SEC_ERROR_CRL_ALREADY_EXISTS = (SEC_ERROR_BASE + 153), +SEC_ERROR_NOT_INITIALIZED = (SEC_ERROR_BASE + 154), +SEC_ERROR_TOKEN_NOT_LOGGED_IN = (SEC_ERROR_BASE + 155), /* Add new error codes above here. */ SEC_ERROR_END_OF_LIST diff --git a/security/nss/lib/util/secitem.h b/security/nss/lib/util/secitem.h index b73083f2b..fee905c2f 100644 --- a/security/nss/lib/util/secitem.h +++ b/security/nss/lib/util/secitem.h @@ -53,7 +53,8 @@ SEC_BEGIN_PROTOS ** Allocate an item. If "arena" is not NULL, then allocate from there, ** otherwise allocate from the heap. If "item" is not NULL, allocate ** only the data for the item, not the item itself. The item structure -** is allocated zero-filled; the data buffer is not zeroed. +** is allocated zero-filled; the data buffer is not zeroed. The caller +** is responsible for initializing the type field of the item. ** ** The resulting item is returned; NULL if any error occurs. ** diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c index 550f09b4f..79536ad11 100644 --- a/security/nss/lib/util/secoid.c +++ b/security/nss/lib/util/secoid.c @@ -166,6 +166,8 @@ #define ANSI_X962_CURVE_OID ANSI_X962_OID, 0x03 #define ANSI_X962_GF2m_OID ANSI_X962_CURVE_OID, 0x00 #define ANSI_X962_GFp_OID ANSI_X962_CURVE_OID, 0x01 +#define ANSI_X962_SIGNATURE_OID ANSI_X962_OID, 0x04 +#define ANSI_X962_SPECIFY_OID ANSI_X962_SIGNATURE_OID, 0x03 #define CONST_OID static const unsigned char @@ -453,8 +455,14 @@ CONST_OID sha256[] = { SHAXXX, 1 }; CONST_OID sha384[] = { SHAXXX, 2 }; CONST_OID sha512[] = { SHAXXX, 3 }; -CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 }; -CONST_OID ansix962ECDSASignaturewithSHA1Digest[] = { ANSI_X962_OID, 0x04, 0x01 }; +CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 }; +CONST_OID ansix962SignaturewithSHA1Digest[] = { ANSI_X962_SIGNATURE_OID, 0x01 }; +CONST_OID ansix962SignatureRecommended[] = { ANSI_X962_SIGNATURE_OID, 0x02 }; +CONST_OID ansix962SignatureSpecified[] = { ANSI_X962_SPECIFY_OID }; +CONST_OID ansix962SignaturewithSHA224Digest[] = { ANSI_X962_SPECIFY_OID, 0x01 }; +CONST_OID ansix962SignaturewithSHA256Digest[] = { ANSI_X962_SPECIFY_OID, 0x02 }; +CONST_OID ansix962SignaturewithSHA384Digest[] = { ANSI_X962_SPECIFY_OID, 0x03 }; +CONST_OID ansix962SignaturewithSHA512Digest[] = { ANSI_X962_SPECIFY_OID, 0x04 }; /* ANSI X9.62 prime curve OIDs */ /* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the @@ -1150,8 +1158,8 @@ const static SECOidData oids[] = { OD( ansix962ECPublicKey, SEC_OID_ANSIX962_EC_PUBLIC_KEY, "X9.62 elliptic curve public key", CKM_ECDH1_DERIVE, INVALID_CERT_EXTENSION ), - OD( ansix962ECDSASignaturewithSHA1Digest, - SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST, + OD( ansix962SignaturewithSHA1Digest, + SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE, "X9.62 ECDSA signature with SHA1", CKM_ECDSA_SHA1, INVALID_CERT_EXTENSION ), @@ -1435,6 +1443,32 @@ const static SECOidData oids[] = { OD( pkcs9ExtensionRequest, SEC_OID_PKCS9_EXTENSION_REQUEST, "PKCS #9 Extension Request", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ), + + /* more ECC Signature Oids */ + OD( ansix962SignatureRecommended, + SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST, + "X9.62 ECDSA signature with recommended digest", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignatureSpecified, + SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, + "X9.62 ECDSA signature with specified digest", CKM_ECDSA, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA224Digest, + SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE, + "X9.62 ECDSA signature with SHA224", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA256Digest, + SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, + "X9.62 ECDSA signature with SHA256", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA384Digest, + SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE, + "X9.62 ECDSA signature with SHA384", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA512Digest, + SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE, + "X9.62 ECDSA signature with SHA512", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), }; /* diff --git a/security/nss/lib/util/secoidt.h b/security/nss/lib/util/secoidt.h index e1072c5bb..64e75c720 100644 --- a/security/nss/lib/util/secoidt.h +++ b/security/nss/lib/util/secoidt.h @@ -314,7 +314,10 @@ typedef enum { /* Elliptic Curve Cryptography (ECC) OIDs */ SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200, - SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST = 201, + SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE = 201, + +#define SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST \ + SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE /* ANSI X9.62 named elliptic curves (prime field) */ SEC_OID_ANSIX962_EC_PRIME192V1 = 202, @@ -403,6 +406,13 @@ typedef enum { SEC_OID_PKIX_CA_ISSUERS = 273, SEC_OID_PKCS9_EXTENSION_REQUEST = 274, + /* new EC Signature oids */ + SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST = 275, + SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST = 276, + SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE = 277, + SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE = 278, + SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE = 279, + SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE = 280, SEC_OID_TOTAL } SECOidTag; diff --git a/security/nss/lib/util/secport.c b/security/nss/lib/util/secport.c index 4ad02ba91..9b9fda1c5 100644 --- a/security/nss/lib/util/secport.c +++ b/security/nss/lib/util/secport.c @@ -271,7 +271,9 @@ PORT_ArenaZAlloc(PLArenaPool *arena, size_t size) return(p); } -/* XXX - need to zeroize!! - jsw */ +/* + * If zero is true, zeroize the arena memory before freeing it. + */ void PORT_FreeArena(PLArenaPool *arena, PRBool zero) { @@ -303,6 +305,13 @@ PORT_FreeArena(PLArenaPool *arena, PRBool zero) if (!ev) doFreeArenaPool = PR_TRUE; } } + if (zero) { + PLArena *a; + for (a = arena->first.next; a; a = a->next) { + PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); + memset((void *)a->base, 0, a->avail - a->base); + } + } if (doFreeArenaPool) { PL_FreeArenaPool(arena); } else { @@ -385,8 +394,32 @@ PORT_ArenaMark(PLArenaPool *arena) return result; } -void -PORT_ArenaRelease(PLArenaPool *arena, void *mark) +static void +port_ArenaZeroAfterMark(PLArenaPool *arena, void *mark) +{ + PLArena *a = arena->current; + if (a->base <= (PRUword)mark && (PRUword)mark <= a->avail) { + /* fast path: mark falls in the current arena */ + memset(mark, 0, a->avail - (PRUword)mark); + } else { + /* slow path: need to find the arena that mark falls in */ + for (a = arena->first.next; a; a = a->next) { + PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); + if (a->base <= (PRUword)mark && (PRUword)mark <= a->avail) { + memset(mark, 0, a->avail - (PRUword)mark); + a = a->next; + break; + } + } + for (; a; a = a->next) { + PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); + memset((void *)a->base, 0, a->avail - a->base); + } + } +} + +static void +port_ArenaRelease(PLArenaPool *arena, void *mark, PRBool zero) { PORTArenaPool *pool = (PORTArenaPool *)arena; if (ARENAPOOL_MAGIC == pool->magic ) { @@ -418,6 +451,9 @@ PORT_ArenaRelease(PLArenaPool *arena, void *mark) tm = *pw; *pw = (threadmark_mark *)NULL; + if (zero) { + port_ArenaZeroAfterMark(arena, mark); + } PL_ARENA_RELEASE(arena, mark); if (! pool->first_mark ) { @@ -425,15 +461,36 @@ PORT_ArenaRelease(PLArenaPool *arena, void *mark) } } #else /* THREADMARK */ + if (zero) { + port_ArenaZeroAfterMark(arena, mark); + } PL_ARENA_RELEASE(arena, mark); #endif /* THREADMARK */ PZ_Unlock(pool->lock); } else { + if (zero) { + port_ArenaZeroAfterMark(arena, mark); + } PL_ARENA_RELEASE(arena, mark); } } void +PORT_ArenaRelease(PLArenaPool *arena, void *mark) +{ + port_ArenaRelease(arena, mark, PR_FALSE); +} + +/* + * Zeroize the arena memory before releasing it. + */ +void +PORT_ArenaZRelease(PLArenaPool *arena, void *mark) +{ + port_ArenaRelease(arena, mark, PR_TRUE); +} + +void PORT_ArenaUnmark(PLArenaPool *arena, void *mark) { #ifdef THREADMARK diff --git a/security/nss/lib/util/secport.h b/security/nss/lib/util/secport.h index 65c14def0..d30328de0 100644 --- a/security/nss/lib/util/secport.h +++ b/security/nss/lib/util/secport.h @@ -137,6 +137,7 @@ extern void *PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize); extern void *PORT_ArenaMark(PLArenaPool *arena); extern void PORT_ArenaRelease(PLArenaPool *arena, void *mark); +extern void PORT_ArenaZRelease(PLArenaPool *arena, void *mark); extern void PORT_ArenaUnmark(PLArenaPool *arena, void *mark); extern char *PORT_ArenaStrdup(PLArenaPool *arena, const char *str); |