diff --git a/mozilla/security/nss/lib/ssl/derive.c b/mozilla/security/nss/lib/ssl/derive.c index 7f941977ca4..a811f9a3b9a 100644 --- a/mozilla/security/nss/lib/ssl/derive.c +++ b/mozilla/security/nss/lib/ssl/derive.c @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: derive.c,v 1.3.2.1 2006-08-24 22:31:54 nelson%bolyard.com Exp $ */ +/* $Id: derive.c,v 1.3.2.2 2007-06-23 01:33:33 neil.williams%sun.com Exp $ */ #include "ssl.h" /* prereq to sslimpl.h */ #include "certt.h" /* prereq to sslimpl.h */ @@ -44,6 +44,15 @@ #include "sslimpl.h" #include "blapi.h" +#include "secutil.h" +#include "pk11func.h" +#include "secasn1.h" +#include "cert.h" +#include "secmodt.h" + +#include "sslproto.h" +#include "sslerr.h" + /* make this a macro! */ #ifdef NOT_A_MACRO static void @@ -490,4 +499,331 @@ ssl3_MasterKeyDeriveBypass( return rv; } +static SECStatus +ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp) +{ SECStatus rv; + PK11SymKey * ms = NULL; + SECItem params = {siBuffer, NULL, 0}; + CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; + unsigned char rand[SSL3_RANDOM_LENGTH]; + CK_VERSION pms_version; + CK_MECHANISM_TYPE master_derive; + CK_MECHANISM_TYPE key_derive; + CK_FLAGS keyFlags; + + if (pms == NULL) + return(SECFailure); + + PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH); + + if (isTLS) { + if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; + else master_derive = CKM_TLS_MASTER_KEY_DERIVE; + key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; + keyFlags = CKF_SIGN | CKF_VERIFY; + } else { + if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; + else master_derive = CKM_SSL3_MASTER_KEY_DERIVE; + key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; + keyFlags = 0; + } + + master_params.pVersion = &pms_version; + master_params.RandomInfo.pClientRandom = rand; + master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; + master_params.RandomInfo.pServerRandom = rand; + master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; + + params.data = (unsigned char *) &master_params; + params.len = sizeof master_params; + + ms = PK11_DeriveWithFlags(pms, master_derive, ¶ms, key_derive, + CKA_DERIVE, 0, keyFlags); + if (ms == NULL) + return(SECFailure); + + rv = PK11_ExtractKeyValue(ms); + *pcbp = (rv == SECSuccess); + PK11_FreeSymKey(ms); + + return(rv); + +} + +/* Check the key exchange algorithm for each cipher in the list to see if + * a master secret key can be extracted. If the KEA will use keys from the + * specified cert make sure the extract operation is attempted from the slot + * where the private key resides. + * If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and + * SECSuccess is returned. In all other cases but one (*pcanbypass) is + * set to FALSE and SECFailure is returned. + * In that last case Derive() has been called successfully but the MS is null, + * CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the + * arguments were all valid but the slot cannot be bypassed. + */ + +SECStatus +SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, + PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites, + PRBool *pcanbypass, void *pwArg) +{ SECStatus rv; + int i; + PRUint16 suite; + PK11SymKey * pms = NULL; + SECKEYPublicKey * srvPubkey = NULL; + KeyType privKeytype; + PK11SlotInfo * slot = NULL; + SECItem param; + CK_VERSION version; + CK_MECHANISM_TYPE mechanism_array[2]; + SECItem enc_pms = {siBuffer, NULL, 0}; + PRBool isTLS = PR_FALSE; + PRBool isDH = PR_FALSE; + SSLCipherSuiteInfo csdef; + PRBool extractable; + PRBool testrsa = PR_FALSE; + PRBool testrsa_export = PR_FALSE; + PRBool testecdh = PR_FALSE; + PRBool testecdhe = PR_FALSE; + + if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + srvPubkey = CERT_ExtractPublicKey(cert); + if (!srvPubkey) + return SECFailure; + + *pcanbypass = PR_TRUE; + rv = SECFailure; + + /* determine which KEAs to test */ + for (i=0; i < nsuites && (suite = *ciphersuites++) != NULL; i++) { + /* skip SSL2 cipher suites and ones NSS doesn't support */ + if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess + || SSL_IS_SSL2_CIPHER(suite) ) + continue; + switch (csdef.keaType) { + case ssl_kea_rsa: + switch (csdef.cipherSuite) { + case TLS_RSA_EXPORT1024_WITH_RC4_56_SHA: + case TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA: + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + testrsa_export = PR_TRUE; + } + if (!testrsa_export) + testrsa = PR_TRUE; + break; + case ssl_kea_ecdh: + if (strcmp(csdef.keaTypeName, "ECDHE") == 0) /* ephemeral? */ + testecdhe = PR_TRUE; + else + testecdh = PR_TRUE; + break; + case ssl_kea_dh: + /* this is actually DHE */ + default: + continue; + } + } + + /* For each protocol try to derive and extract an MS. + * Failure of any function except MS extract means + * continue with the next cipher test. Stop testing when the list is + * exhausted or when the first MS extract--not derive--fails. + */ + privKeytype = SECKEY_GetPrivateKeyType(srvPrivkey); + protocolmask &= SSL_CBP_SSL3|SSL_CBP_TLS1_0; + while (protocolmask) { + if (protocolmask & SSL_CBP_SSL3) { + isTLS = PR_FALSE; + protocolmask ^= SSL_CBP_SSL3; + } else { + isTLS = PR_TRUE; + protocolmask ^= SSL_CBP_TLS1_0; + } + + if (privKeytype == rsaKey && testrsa_export) { + if (PK11_GetPrivateModulusLen(srvPrivkey) > EXPORT_RSA_KEY_LENGTH) { + *pcanbypass = PR_FALSE; + rv = SECSuccess; + break; + } else + testrsa = PR_TRUE; + } + for (; privKeytype == rsaKey && testrsa; ) { + /* TLS_RSA */ + unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH]; + unsigned int outLen = 0; + CK_MECHANISM_TYPE target; + SECStatus irv; + + mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN; + mechanism_array[1] = CKM_RSA_PKCS; + + slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg); + if (slot == NULL) { + PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND); + break; + } + + /* Generate the pre-master secret ... (client side) */ + version.major = 3 /*MSB(clientHelloVersion)*/; + version.minor = 0 /*LSB(clientHelloVersion)*/; + param.data = (unsigned char *)&version; + param.len = sizeof version; + pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, ¶m, 0, pwArg); + PK11_FreeSlot(slot); + if (!pms) + break; + /* now wrap it */ + enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); + enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); + irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); + if (irv != SECSuccess) + break; + PK11_FreeSymKey(pms); + /* now do the server side--check the triple bypass first */ + rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, + sizeof rsaPmsBuf, + (unsigned char *)enc_pms.data, + enc_pms.len); + /* if decrypt worked we're done with the RSA test */ + if (rv == SECSuccess) { + *pcanbypass = PR_TRUE; + break; + } + /* check for fallback to double bypass */ + target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE + : CKM_SSL3_MASTER_KEY_DERIVE; + pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms, + target, CKA_DERIVE, 0); + rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass); + if (rv == SECSuccess && *pcanbypass == PR_FALSE) + goto done; + break; + } +#ifdef NSS_ENABLE_ECC + for (; (privKeytype == ecKey && ( testecdh || testecdhe)) || + (privKeytype == rsaKey && testecdhe); ) { + CK_MECHANISM_TYPE target; + SECKEYPublicKey *keapub = NULL; + SECKEYPrivateKey *keapriv; + SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ + SECKEYPrivateKey *cpriv = NULL; + SECKEYECParams ecParams = { siBuffer, NULL, 0 }, + *pecParams; + + if (privKeytype == ecKey && testecdhe) { + /* TLS_ECDHE_ECDSA */ + pecParams = &srvPubkey->u.ec.DEREncodedParams; + } else if (privKeytype == rsaKey && testecdhe) { + /* TLS_ECDHE_RSA */ + ECName ec_curve; + int serverKeyStrengthInBits; + int signatureKeyStrength; + int requiredECCbits; + + /* find a curve of equivalent strength to the RSA key's */ + requiredECCbits = PK11_GetPrivateModulusLen(srvPrivkey); + if (requiredECCbits < 0) + break; + requiredECCbits *= BPB; + serverKeyStrengthInBits = srvPubkey->u.rsa.modulus.len; + if (srvPubkey->u.rsa.modulus.data[0] == 0) { + serverKeyStrengthInBits--; + } + /* convert to strength in bits */ + serverKeyStrengthInBits *= BPB; + + signatureKeyStrength = + SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); + + if ( requiredECCbits > signatureKeyStrength ) + requiredECCbits = signatureKeyStrength; + + ec_curve = + ssl3_GetCurveWithECKeyStrength(SSL3_SUPPORTED_CURVES_MASK, + requiredECCbits); + rv = ssl3_ECName2Params(NULL, ec_curve, &ecParams); + if (rv == SECFailure) { + break; + } + pecParams = &ecParams; + } + + if (testecdhe) { + /* generate server's ephemeral keys */ + keapriv = SECKEY_CreateECPrivateKey(pecParams, &keapub, NULL); + if (!keapriv || !keapub) { + if (keapriv) + SECKEY_DestroyPrivateKey(keapriv); + if (keapub) + SECKEY_DestroyPublicKey(keapub); + PORT_SetError(SEC_ERROR_KEYGEN_FAIL); + rv = SECFailure; + break; + } + } else { + /* TLS_ECDH_ECDSA */ + keapub = srvPubkey; + keapriv = srvPrivkey; + pecParams = &srvPubkey->u.ec.DEREncodedParams; + } + + /* perform client side ops */ + /* generate a pair of ephemeral keys using server's parms */ + cpriv = SECKEY_CreateECPrivateKey(pecParams, &cpub, NULL); + if (!cpriv || !cpub) { + if (testecdhe) { + SECKEY_DestroyPrivateKey(keapriv); + SECKEY_DestroyPublicKey(keapub); + } + PORT_SetError(SEC_ERROR_KEYGEN_FAIL); + rv = SECFailure; + break; + } + /* now do the server side */ + /* determine the PMS using client's public value */ + target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE_DH + : CKM_SSL3_MASTER_KEY_DERIVE_DH; + pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL, + CKM_ECDH1_DERIVE, + target, + CKA_DERIVE, 0, CKD_NULL, NULL, NULL); + rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass); + SECKEY_DestroyPrivateKey(cpriv); + SECKEY_DestroyPublicKey(cpub); + if (testecdhe) { + SECKEY_DestroyPrivateKey(keapriv); + SECKEY_DestroyPublicKey(keapub); + if (privKeytype == rsaKey) + PORT_Free(ecParams.data); + } + if (rv == SECSuccess && *pcanbypass == PR_FALSE) + goto done; + break; + } +#endif /* NSS_ENABLE_ECC */ + if (pms) + PK11_FreeSymKey(pms); + } + + /* *pcanbypass has been set */ + rv = SECSuccess; + + done: + if (pms) + PK11_FreeSymKey(pms); + + if (srvPubkey) { + SECKEY_DestroyPublicKey(srvPubkey); + srvPubkey = NULL; + } + + + return rv; +} diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def index ae12b2bf5a8..eb23619b1fd 100644 --- a/mozilla/security/nss/lib/ssl/ssl.def +++ b/mozilla/security/nss/lib/ssl/ssl.def @@ -133,3 +133,9 @@ SSL_ReHandshakeWithTimeout; ;+ local: ;+*; ;+}; +;+NSS_3.11.7 { # NSS 3.11.7 release +;+ global: +SSL_CanBypass; +;+ local: +;+*; +;+}; diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h index 987ac4b25fa..92edd9b7186 100644 --- a/mozilla/security/nss/lib/ssl/ssl.h +++ b/mozilla/security/nss/lib/ssl/ssl.h @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: ssl.h,v 1.24 2005-09-16 20:33:09 julien.pierre.bugs%sun.com Exp $ */ +/* $Id: ssl.h,v 1.24.2.1 2007-06-23 01:33:33 neil.williams%sun.com Exp $ */ #ifndef __ssl_h_ #define __ssl_h_ @@ -474,6 +474,37 @@ SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, */ SSL_IMPORT CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd); +/* Test an SSL configuration to see if SSL_BYPASS_PKCS11 can be turned on. +** Check the key exchange algorithm for each cipher in the list to see if +** a master secret key can be extracted after being derived with the mechanism +** required by the protocolmask argument. If the KEA will use keys from the +** specified cert make sure the extract operation is attempted from the slot +** where the private key resides. +** If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and +** SECSuccess is returned. In all other cases but one (*pcanbypass) is +** set to FALSE and SECFailure is returned. +** In that last case Derive() has been called successfully but the MS is null, +** CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the +** arguments were all valid but the slot cannot be bypassed. +** +** Note: A TRUE return code from CanBypass means "Your configuration will perform +** NO WORSE with the bypass enabled than without"; it does NOT mean that every +** cipher suite listed will work properly with the selected protocols. +** +** Caveat: If export cipher suites are included in the argument list Canbypass +** will return FALSE. +**/ + +/* protocol mask bits */ +#define SSL_CBP_SSL3 0x0001 /* test SSL v3 mechanisms */ +#define SSL_CBP_TLS1_0 0x0002 /* test TLS v1.0 mechanisms */ + +SSL_IMPORT SECStatus SSL_CanBypass(CERTCertificate *cert, + SECKEYPrivateKey *privKey, + PRUint32 protocolmask, + PRUint16 *ciphers, int nciphers, + PRBool *pcanbypass, void *pwArg); + SEC_END_PROTOS #endif /* __ssl_h_ */ diff --git a/mozilla/security/nss/lib/ssl/ssl3ecc.c b/mozilla/security/nss/lib/ssl/ssl3ecc.c index d68e0d6cd36..fc8d70eb603 100644 --- a/mozilla/security/nss/lib/ssl/ssl3ecc.c +++ b/mozilla/security/nss/lib/ssl/ssl3ecc.c @@ -40,7 +40,7 @@ * ***** END LICENSE BLOCK ***** */ /* ECC code moved here from ssl3con.c */ -/* $Id: ssl3ecc.c,v 1.3.2.11 2007-01-04 17:48:31 wtchang%redhat.com Exp $ */ +/* $Id: ssl3ecc.c,v 1.3.2.12 2007-06-23 01:33:33 neil.williams%sun.com Exp $ */ #include "nssrenam.h" #include "nss.h" @@ -80,45 +80,12 @@ (ss->serverCerts[type].serverKeyPair ? \ ss->serverCerts[type].serverKeyPair->pubKey : NULL) -#define SSL_IS_CURVE_NEGOTIATED(ss, curveName) \ +#define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \ ((curveName > ec_noName) && \ (curveName < ec_pastLastName) && \ - ((1UL << curveName) & ss->ssl3.hs.negotiatedECCurves) != 0) + ((1UL << curveName) & curvemsk) != 0) -/* Types and names of elliptic curves used in TLS */ -typedef enum { ec_type_explicitPrime = 1, - ec_type_explicitChar2Curve = 2, - ec_type_named -} ECType; -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); @@ -229,8 +196,8 @@ typedef struct ECDHEKeyPairStr { /* arrays of ECDHE KeyPairs */ static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName]; -static SECStatus -ecName2params(PRArenaPool * arena, ECName curve, SECKEYECParams * params) +SECStatus +ssl3_ECName2Params(PRArenaPool * arena, ECName curve, SECKEYECParams * params) { SECOidData *oidData = NULL; @@ -470,6 +437,22 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, return SECSuccess; } +ECName +ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits) +{ + int i; + + for ( i = 0; bits2curve[i].curve != ec_noName; i++) { + if (bits2curve[i].bits < requiredECCbits) + continue; + if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) { + return bits2curve[i].curve; + } + } + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return ec_noName; +} + /* find the "weakest link". Get strength of signature key and of sym key. * choose curve for the weakest of those two. */ @@ -486,7 +469,7 @@ ssl3_GetCurveNameForServerSocket(sslSocket *ss) 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)) { + if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve)) { PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); return ec_noName; } @@ -509,30 +492,14 @@ ssl3_GetCurveNameForServerSocket(sslSocket *ss) /* 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; - } + signatureKeyStrength = + SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); } 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; + return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves, + requiredECCbits); } /* function to clear out the lists */ @@ -575,7 +542,7 @@ ssl3_CreateECDHEphemeralKeyPair(void * arg) 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) { + if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) { gECDHEKeyPairs[ec_curve].error = PORT_GetError(); return PR_FAILURE; } @@ -742,7 +709,7 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) peerKey->keyType = ecKey; /* set up EC parameters in peerKey */ - if (ecName2params(arena, ec_params.data[2], + if (ssl3_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 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h index c2f5cdd91c9..96d4b931988 100644 --- a/mozilla/security/nss/lib/ssl/sslimpl.h +++ b/mozilla/security/nss/lib/ssl/sslimpl.h @@ -39,7 +39,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: sslimpl.h,v 1.42.2.10 2007-05-01 06:09:31 nelson%bolyard.com Exp $ */ +/* $Id: sslimpl.h,v 1.42.2.11 2007-06-23 01:33:33 neil.williams%sun.com Exp $ */ #ifndef __sslimpl_h_ #define __sslimpl_h_ @@ -190,6 +190,8 @@ typedef enum { SSLAppOpRead = 0, #define BPB 8 /* Bits Per Byte */ #endif +#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */ + typedef struct sslBufferStr sslBuffer; typedef struct sslConnectInfoStr sslConnectInfo; typedef struct sslGatherStr sslGather; @@ -1280,6 +1282,54 @@ extern void ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss); extern PRBool ssl3_IsECCEnabled(sslSocket *ss); extern SECStatus ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite); + +/* Macro for finding a curve equivalent in strength to RSA key's */ +#define SSL_RSASTRENGTH_TO_ECSTRENGTH(s) \ + ((s <= 1024) ? 160 \ + : ((s <= 2048) ? 224 \ + : ((s <= 3072) ? 256 \ + : ((s <= 7168) ? 384 : 521 ) ) ) ) + +/* Types and names of elliptic curves used in TLS */ +typedef enum { ec_type_explicitPrime = 1, + ec_type_explicitChar2Curve = 2, + ec_type_named +} ECType; + +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; + +extern SECStatus ssl3_ECName2Params(PRArenaPool *arena, ECName curve, + SECKEYECParams *params); +ECName ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits); + + #endif /* NSS_ENABLE_ECC */ extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on); @@ -1420,6 +1470,7 @@ PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite); #endif void ssl_Trace(const char *format, ...); +ECName ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits); SEC_END_PROTOS