summaryrefslogtreecommitdiff
path: root/security/nss/lib
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib')
-rw-r--r--security/nss/lib/base/arena.c8
-rw-r--r--security/nss/lib/certdb/certdb.c3
-rw-r--r--security/nss/lib/certdb/certt.h8
-rw-r--r--security/nss/lib/certdb/crl.c90
-rw-r--r--security/nss/lib/certdb/stanpcertdb.c60
-rw-r--r--security/nss/lib/certdb/xauthkid.c4
-rw-r--r--security/nss/lib/certhigh/certhigh.c19
-rw-r--r--security/nss/lib/certhigh/certvfy.c53
-rw-r--r--security/nss/lib/certhigh/manifest.mn1
-rw-r--r--security/nss/lib/certhigh/ocsp.c279
-rw-r--r--security/nss/lib/certhigh/ocsp.h12
-rw-r--r--security/nss/lib/certhigh/ocspi.h47
-rw-r--r--security/nss/lib/certhigh/ocspt.h231
-rw-r--r--security/nss/lib/ckfw/builtins/binst.c5
-rw-r--r--security/nss/lib/ckfw/builtins/certdata.c1472
-rw-r--r--security/nss/lib/ckfw/builtins/certdata.txt1340
-rw-r--r--security/nss/lib/ckfw/builtins/constants.c2
-rw-r--r--security/nss/lib/ckfw/builtins/nssckbi.h4
-rw-r--r--security/nss/lib/ckfw/builtins/nssckbi.rc3
-rw-r--r--security/nss/lib/ckfw/capi/nsscapi.rc1
-rw-r--r--security/nss/lib/ckfw/dbm/Makefile60
-rw-r--r--security/nss/lib/ckfw/dbm/anchor.c63
-rw-r--r--security/nss/lib/ckfw/dbm/ckdbm.h63
-rw-r--r--security/nss/lib/ckfw/dbm/config.mk60
-rw-r--r--security/nss/lib/ckfw/dbm/db.c63
-rw-r--r--security/nss/lib/ckfw/dbm/find.c63
-rw-r--r--security/nss/lib/ckfw/dbm/instance.c65
-rw-r--r--security/nss/lib/ckfw/dbm/manifest.mn60
-rw-r--r--security/nss/lib/ckfw/dbm/object.c63
-rw-r--r--security/nss/lib/ckfw/dbm/session.c63
-rw-r--r--security/nss/lib/ckfw/dbm/slot.c63
-rw-r--r--security/nss/lib/ckfw/dbm/token.c63
-rw-r--r--security/nss/lib/ckfw/find.c28
-rw-r--r--security/nss/lib/ckfw/session.c2
-rw-r--r--security/nss/lib/ckfw/wrap.c12
-rw-r--r--security/nss/lib/crmf/challcli.c51
-rw-r--r--security/nss/lib/crmf/crmf.h2
-rw-r--r--security/nss/lib/crmf/crmfcont.c25
-rw-r--r--security/nss/lib/crmf/crmfit.h2
-rw-r--r--security/nss/lib/crmf/crmfpop.c120
-rw-r--r--security/nss/lib/crmf/crmfreq.c27
-rw-r--r--security/nss/lib/crmf/crmftmpl.c2
-rw-r--r--security/nss/lib/crmf/respcmn.c57
-rw-r--r--security/nss/lib/crmf/servget.c14
-rw-r--r--security/nss/lib/cryptohi/cryptohi.h19
-rw-r--r--security/nss/lib/cryptohi/keyhi.h21
-rw-r--r--security/nss/lib/cryptohi/seckey.c417
-rw-r--r--security/nss/lib/cryptohi/secsign.c58
-rw-r--r--security/nss/lib/cryptohi/secvfy.c212
-rw-r--r--security/nss/lib/freebl/GF2m_ecl.c540
-rw-r--r--security/nss/lib/freebl/GF2m_ecl.h97
-rw-r--r--security/nss/lib/freebl/GFp_ecl.c648
-rw-r--r--security/nss/lib/freebl/GFp_ecl.h127
-rw-r--r--security/nss/lib/freebl/Makefile100
-rw-r--r--security/nss/lib/freebl/arcfour-amd64-gas.s4
-rw-r--r--security/nss/lib/freebl/blapi.h46
-rw-r--r--security/nss/lib/freebl/config.mk4
-rw-r--r--security/nss/lib/freebl/des.c2
-rw-r--r--security/nss/lib/freebl/ec.c289
-rw-r--r--security/nss/lib/freebl/ecl/Makefile5
-rw-r--r--security/nss/lib/freebl/ecl/ec2_aff.c1
-rw-r--r--security/nss/lib/freebl/ecl/ecl-curve.h634
-rw-r--r--security/nss/lib/freebl/ecl/ecl-priv.h70
-rw-r--r--security/nss/lib/freebl/ecl/ecl.c124
-rw-r--r--security/nss/lib/freebl/ecl/ecl_curve.c5
-rw-r--r--security/nss/lib/freebl/ecl/ecl_gf.c699
-rw-r--r--security/nss/lib/freebl/ecl/ecl_mult.c34
-rw-r--r--security/nss/lib/freebl/ecl/ecp_192.c469
-rw-r--r--security/nss/lib/freebl/ecl/ecp_224.c394
-rw-r--r--security/nss/lib/freebl/ecl/ecp_256.c429
-rw-r--r--security/nss/lib/freebl/ecl/ecp_384.c293
-rw-r--r--security/nss/lib/freebl/ecl/ecp_521.c170
-rw-r--r--security/nss/lib/freebl/ecl/tests/ec2_test.c43
-rw-r--r--security/nss/lib/freebl/ecl/tests/ecp_test.c25
-rw-r--r--security/nss/lib/freebl/freebl.rc3
-rw-r--r--security/nss/lib/freebl/ldvector.c5
-rw-r--r--security/nss/lib/freebl/loader.c187
-rw-r--r--security/nss/lib/freebl/loader.h11
-rw-r--r--security/nss/lib/freebl/manifest.mn9
-rw-r--r--security/nss/lib/freebl/mpi/Makefile4
-rw-r--r--security/nss/lib/freebl/mpi/mp_gf2m.c2
-rw-r--r--security/nss/lib/freebl/mpi/mpi.c6
-rw-r--r--security/nss/lib/freebl/mpi/mpi_amd64_gas.s4
-rw-r--r--security/nss/lib/freebl/mpi/mpi_sparc.c118
-rw-r--r--security/nss/lib/freebl/mpi/mpi_x86.asm356
-rw-r--r--security/nss/lib/freebl/mpi/mpi_x86_asm.c368
-rw-r--r--security/nss/lib/freebl/mpi/mpmontg.c185
-rw-r--r--security/nss/lib/freebl/mpi/mpprime.c13
-rw-r--r--security/nss/lib/freebl/mpi/target.mk18
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-7.c2
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-8.c2
-rw-r--r--security/nss/lib/freebl/nss.h253
-rw-r--r--security/nss/lib/freebl/os2_rand.c9
-rw-r--r--security/nss/lib/freebl/pqg.c21
-rw-r--r--security/nss/lib/freebl/prng_fips1861.c184
-rw-r--r--security/nss/lib/freebl/secrng.h18
-rw-r--r--security/nss/lib/freebl/sha256.h51
-rw-r--r--security/nss/lib/freebl/sha512.c10
-rw-r--r--security/nss/lib/freebl/unix_rand.c177
-rw-r--r--security/nss/lib/freebl/win_rand.c94
-rw-r--r--security/nss/lib/nss/config.mk8
-rw-r--r--security/nss/lib/nss/nss.def15
-rw-r--r--security/nss/lib/nss/nss.h43
-rw-r--r--security/nss/lib/nss/nss.rc3
-rw-r--r--security/nss/lib/nss/nssinit.c206
-rw-r--r--security/nss/lib/pk11wrap/Makefile4
-rw-r--r--security/nss/lib/pk11wrap/pk11akey.c134
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c109
-rw-r--r--security/nss/lib/pk11wrap/pk11cxt.c19
-rw-r--r--security/nss/lib/pk11wrap/pk11err.c2
-rw-r--r--security/nss/lib/pk11wrap/pk11kea.c76
-rw-r--r--security/nss/lib/pk11wrap/pk11mech.c4
-rw-r--r--security/nss/lib/pk11wrap/pk11nobj.c42
-rw-r--r--security/nss/lib/pk11wrap/pk11obj.c25
-rw-r--r--security/nss/lib/pk11wrap/pk11pbe.c59
-rw-r--r--security/nss/lib/pk11wrap/pk11pk12.c12
-rw-r--r--security/nss/lib/pk11wrap/pk11pqg.c8
-rw-r--r--security/nss/lib/pk11wrap/pk11priv.h2
-rw-r--r--security/nss/lib/pk11wrap/pk11pub.h8
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c179
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c4
-rw-r--r--security/nss/lib/pk11wrap/secmod.h5
-rw-r--r--security/nss/lib/pkcs12/p12d.c14
-rw-r--r--security/nss/lib/pkcs7/p7decode.c2
-rw-r--r--security/nss/lib/pki/certificate.c60
-rw-r--r--security/nss/lib/pki/cryptocontext.c62
-rw-r--r--security/nss/lib/pki/nsspki.h21
-rw-r--r--security/nss/lib/pki/pki3hack.c129
-rw-r--r--security/nss/lib/pki/pkibase.c126
-rw-r--r--security/nss/lib/pki/pkim.h9
-rw-r--r--security/nss/lib/pki/pkistore.c96
-rw-r--r--security/nss/lib/pki/pkistore.h35
-rw-r--r--security/nss/lib/pki/pkit.h11
-rw-r--r--security/nss/lib/pki/tdcache.c7
-rw-r--r--security/nss/lib/pki/trustdomain.c7
-rw-r--r--security/nss/lib/smime/cmscipher.c5
-rw-r--r--security/nss/lib/smime/cmsencode.c4
-rw-r--r--security/nss/lib/smime/cmsrecinfo.c35
-rw-r--r--security/nss/lib/smime/cmsreclist.c24
-rw-r--r--security/nss/lib/smime/cmssiginfo.c2
-rw-r--r--security/nss/lib/smime/cmsutil.c8
-rw-r--r--security/nss/lib/smime/smime.rc3
-rw-r--r--security/nss/lib/smime/smimeutil.c11
-rw-r--r--security/nss/lib/softoken/config.mk1
-rw-r--r--security/nss/lib/softoken/dbinit.c1
-rw-r--r--security/nss/lib/softoken/dbmshim.c8
-rw-r--r--security/nss/lib/softoken/ecdecode.c16
-rw-r--r--security/nss/lib/softoken/fipsaudt.c351
-rw-r--r--security/nss/lib/softoken/fipstest.c876
-rw-r--r--security/nss/lib/softoken/fipstokn.c514
-rw-r--r--security/nss/lib/softoken/keydb.c98
-rw-r--r--security/nss/lib/softoken/lowcert.c6
-rw-r--r--security/nss/lib/softoken/lowkey.c1
-rw-r--r--security/nss/lib/softoken/lowpbe.c20
-rw-r--r--security/nss/lib/softoken/manifest.mn6
-rw-r--r--security/nss/lib/softoken/nss.h253
-rw-r--r--security/nss/lib/softoken/pcert.h12
-rw-r--r--security/nss/lib/softoken/pcertdb.c231
-rw-r--r--security/nss/lib/softoken/pcertt.h14
-rw-r--r--security/nss/lib/softoken/pk11db.c7
-rw-r--r--security/nss/lib/softoken/pkcs11.c143
-rw-r--r--security/nss/lib/softoken/pkcs11c.c429
-rw-r--r--security/nss/lib/softoken/pkcs11i.h4
-rw-r--r--security/nss/lib/softoken/pkcs11u.c19
-rw-r--r--security/nss/lib/softoken/rsawrapr.c57
-rw-r--r--security/nss/lib/softoken/softoken.h97
-rw-r--r--security/nss/lib/softoken/softokn.rc3
-rw-r--r--security/nss/lib/softoken/softoknt.h9
-rw-r--r--security/nss/lib/ssl/derive.c14
-rw-r--r--security/nss/lib/ssl/emulate.c636
-rw-r--r--security/nss/lib/ssl/manifest.mn1
-rw-r--r--security/nss/lib/ssl/ssl.def7
-rw-r--r--security/nss/lib/ssl/ssl.rc3
-rw-r--r--security/nss/lib/ssl/ssl3con.c1067
-rw-r--r--security/nss/lib/ssl/ssl3ecc.c868
-rw-r--r--security/nss/lib/ssl/ssl3prot.h22
-rw-r--r--security/nss/lib/ssl/sslauth.c13
-rw-r--r--security/nss/lib/ssl/sslcon.c181
-rw-r--r--security/nss/lib/ssl/ssldef.c54
-rw-r--r--security/nss/lib/ssl/sslenum.c16
-rw-r--r--security/nss/lib/ssl/sslerr.h6
-rw-r--r--security/nss/lib/ssl/sslimpl.h104
-rw-r--r--security/nss/lib/ssl/sslinfo.c14
-rw-r--r--security/nss/lib/ssl/sslmutex.c11
-rw-r--r--security/nss/lib/ssl/sslproto.h51
-rw-r--r--security/nss/lib/ssl/sslsecur.c55
-rw-r--r--security/nss/lib/ssl/sslsnce.c77
-rw-r--r--security/nss/lib/ssl/sslsock.c90
-rw-r--r--security/nss/lib/util/derenc.c23
-rw-r--r--security/nss/lib/util/secasn1d.c12
-rw-r--r--security/nss/lib/util/secasn1e.c2
-rw-r--r--security/nss/lib/util/secdig.c17
-rw-r--r--security/nss/lib/util/secerr.h2
-rw-r--r--security/nss/lib/util/secitem.h3
-rw-r--r--security/nss/lib/util/secoid.c42
-rw-r--r--security/nss/lib/util/secoidt.h12
-rw-r--r--security/nss/lib/util/secport.c63
-rw-r--r--security/nss/lib/util/secport.h1
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,
+ &registeredHttpClient->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, &copyk->u.rsa.modulus,
- &pubk->u.rsa.modulus);
- if (rv == SECSuccess) {
- rv = SECITEM_CopyItem (arena, &copyk->u.rsa.publicExponent,
- &pubk->u.rsa.publicExponent);
- if (rv == SECSuccess)
- return copyk;
- }
- break;
- case dsaKey:
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.publicValue,
- &pubk->u.dsa.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.prime,
- &pubk->u.dsa.params.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.subPrime,
- &pubk->u.dsa.params.subPrime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.base,
- &pubk->u.dsa.params.base);
- break;
- case keaKey:
- rv = SECITEM_CopyItem(arena, &copyk->u.kea.publicValue,
- &pubk->u.kea.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->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, &copyk->u.fortezza.clearance,
- &pubk->u.fortezza.clearance);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.KEApriviledge,
- &pubk->u.fortezza.KEApriviledge);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.DSSpriviledge,
- &pubk->u.fortezza.DSSpriviledge);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.KEAKey,
- &pubk->u.fortezza.KEAKey);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.DSSKey,
- &pubk->u.fortezza.DSSKey);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.prime,
- &pubk->u.fortezza.params.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.subPrime,
- &pubk->u.fortezza.params.subPrime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.base,
- &pubk->u.fortezza.params.base);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.prime,
- &pubk->u.fortezza.keaParams.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.subPrime,
- &pubk->u.fortezza.keaParams.subPrime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.base,
- &pubk->u.fortezza.keaParams.base);
- break;
- case dhKey:
- rv = SECITEM_CopyItem(arena,&copyk->u.dh.prime,&pubk->u.dh.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena,&copyk->u.dh.base,&pubk->u.dh.base);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
- &pubk->u.dh.publicValue);
- break;
- case ecKey:
- copyk->u.ec.size = pubk->u.ec.size;
- rv = SECITEM_CopyItem(arena,&copyk->u.ec.DEREncodedParams,
- &pubk->u.ec.DEREncodedParams);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena,&copyk->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, &copyk->u.rsa.modulus,
+ &pubk->u.rsa.modulus);
+ if (rv == SECSuccess) {
+ rv = SECITEM_CopyItem (arena, &copyk->u.rsa.publicExponent,
+ &pubk->u.rsa.publicExponent);
+ if (rv == SECSuccess)
+ return copyk;
+ }
+ break;
+ case dsaKey:
+ rv = SECITEM_CopyItem(arena, &copyk->u.dsa.publicValue,
+ &pubk->u.dsa.publicValue);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.prime,
+ &pubk->u.dsa.params.prime);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.subPrime,
+ &pubk->u.dsa.params.subPrime);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.base,
+ &pubk->u.dsa.params.base);
+ break;
+ case keaKey:
+ rv = SECITEM_CopyItem(arena, &copyk->u.kea.publicValue,
+ &pubk->u.kea.publicValue);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->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, &copyk->u.fortezza.clearance,
+ &pubk->u.fortezza.clearance);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.KEApriviledge,
+ &pubk->u.fortezza.KEApriviledge);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.DSSpriviledge,
+ &pubk->u.fortezza.DSSpriviledge);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.KEAKey,
+ &pubk->u.fortezza.KEAKey);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.DSSKey,
+ &pubk->u.fortezza.DSSKey);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.prime,
+ &pubk->u.fortezza.params.prime);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.subPrime,
+ &pubk->u.fortezza.params.subPrime);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.base,
+ &pubk->u.fortezza.params.base);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.prime,
+ &pubk->u.fortezza.keaParams.prime);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.subPrime,
+ &pubk->u.fortezza.keaParams.subPrime);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.base,
+ &pubk->u.fortezza.keaParams.base);
+ break;
+ case dhKey:
+ rv = SECITEM_CopyItem(arena,&copyk->u.dh.prime,&pubk->u.dh.prime);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena,&copyk->u.dh.base,&pubk->u.dh.base);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
+ &pubk->u.dh.publicValue);
+ break;
+ case ecKey:
+ copyk->u.ec.size = pubk->u.ec.size;
+ rv = SECITEM_CopyItem(arena,&copyk->u.ec.DEREncodedParams,
+ &pubk->u.ec.DEREncodedParams);
+ if (rv != SECSuccess) break;
+ rv = SECITEM_CopyItem(arena,&copyk->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(&params);
+ length = SECKEY_ECParamsToBasePointOrderLen(&params);
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,
- &params, 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, &paramStrings, 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, &params, 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,
+ &params, 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);