| Index: net/third_party/nss/ssl/sslsock.c
|
| diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
|
| index 09a0fb514b293c68d1887ba32c23183e0d447cc7..0a8fbf0fdcd600761a6785024d602527ecd4a117 100644
|
| --- a/net/third_party/nss/ssl/sslsock.c
|
| +++ b/net/third_party/nss/ssl/sslsock.c
|
| @@ -19,6 +19,7 @@
|
| #endif
|
| #include "pk11pub.h"
|
| #include "nss.h"
|
| +#include "pk11pqg.h"
|
|
|
| /* This is a bodge to allow this code to be compiled against older NSS headers
|
| * that don't contain the TLS 1.2 changes. */
|
| @@ -90,6 +91,8 @@ static sslOptions ssl_defaults = {
|
| PR_FALSE, /* enableALPN */
|
| PR_TRUE, /* reuseServerECDHEKey */
|
| PR_FALSE, /* enableFallbackSCSV */
|
| + PR_TRUE, /* enableServerDhe */
|
| + PR_FALSE, /* enableExtendedMS */
|
| PR_FALSE, /* enableSignedCertTimestamps */
|
| };
|
|
|
| @@ -232,6 +235,24 @@ ssl_DupSocket(sslSocket *os)
|
| PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
|
| sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
|
| ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
|
| + PORT_Memcpy(ss->ssl3.signatureAlgorithms, os->ssl3.signatureAlgorithms,
|
| + sizeof(ss->ssl3.signatureAlgorithms[0]) *
|
| + os->ssl3.signatureAlgorithmCount);
|
| + ss->ssl3.signatureAlgorithmCount = os->ssl3.signatureAlgorithmCount;
|
| +
|
| + ss->ssl3.dheWeakGroupEnabled = os->ssl3.dheWeakGroupEnabled;
|
| + ss->ssl3.numDHEGroups = os->ssl3.numDHEGroups;
|
| + if (os->ssl3.dheGroups) {
|
| + ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType,
|
| + os->ssl3.numDHEGroups);
|
| + if (!ss->ssl3.dheGroups) {
|
| + goto loser;
|
| + }
|
| + PORT_Memcpy(ss->ssl3.dheGroups, os->ssl3.dheGroups,
|
| + sizeof(SSLDHEGroupType) * os->ssl3.numDHEGroups);
|
| + } else {
|
| + ss->ssl3.dheGroups = NULL;
|
| + }
|
|
|
| if (os->cipherSpecs) {
|
| ss->cipherSpecs = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
|
| @@ -275,6 +296,10 @@ ssl_DupSocket(sslSocket *os)
|
| ssl3_GetKeyPairRef(os->stepDownKeyPair);
|
| ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
|
| ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
|
| + ss->dheKeyPair = !os->dheKeyPair ? NULL :
|
| + ssl3_GetKeyPairRef(os->dheKeyPair);
|
| + ss->dheParams = os->dheParams;
|
| +
|
| /*
|
| * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
|
| * XXX We should detect this, and not just march on with NULL pointers.
|
| @@ -398,8 +423,11 @@ ssl_DestroySocketContents(sslSocket *ss)
|
| ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
|
| ss->ephemeralECDHKeyPair = NULL;
|
| }
|
| + if (ss->dheKeyPair) {
|
| + ssl3_FreeKeyPair(ss->dheKeyPair);
|
| + ss->dheKeyPair = NULL;
|
| + }
|
| SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
|
| - PORT_Assert(!ss->xtnData.sniNameArr);
|
| if (ss->xtnData.sniNameArr) {
|
| PORT_Free(ss->xtnData.sniNameArr);
|
| ss->xtnData.sniNameArr = NULL;
|
| @@ -808,6 +836,14 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
|
| ss->opt.enableFallbackSCSV = on;
|
| break;
|
|
|
| + case SSL_ENABLE_SERVER_DHE:
|
| + ss->opt.enableServerDhe = on;
|
| + break;
|
| +
|
| + case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
| + ss->opt.enableExtendedMS = on;
|
| + break;
|
| +
|
| case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
|
| ss->opt.enableSignedCertTimestamps = on;
|
| break;
|
| @@ -887,6 +923,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
|
| case SSL_REUSE_SERVER_ECDHE_KEY:
|
| on = ss->opt.reuseServerECDHEKey; break;
|
| case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
|
| + case SSL_ENABLE_SERVER_DHE: on = ss->opt.enableServerDhe; break;
|
| + case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
| + on = ss->opt.enableExtendedMS; break;
|
| case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
|
| on = ss->opt.enableSignedCertTimestamps;
|
| break;
|
| @@ -959,6 +998,12 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
|
| case SSL_ENABLE_FALLBACK_SCSV:
|
| on = ssl_defaults.enableFallbackSCSV;
|
| break;
|
| + case SSL_ENABLE_SERVER_DHE:
|
| + on = ssl_defaults.enableServerDhe;
|
| + break;
|
| + case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
| + on = ssl_defaults.enableExtendedMS;
|
| + break;
|
| case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
|
| on = ssl_defaults.enableSignedCertTimestamps;
|
| break;
|
| @@ -1145,6 +1190,14 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
|
| ssl_defaults.enableFallbackSCSV = on;
|
| break;
|
|
|
| + case SSL_ENABLE_SERVER_DHE:
|
| + ssl_defaults.enableServerDhe = on;
|
| + break;
|
| +
|
| + case SSL_ENABLE_EXTENDED_MASTER_SECRET:
|
| + ssl_defaults.enableExtendedMS = on;
|
| + break;
|
| +
|
| case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
|
| ssl_defaults.enableSignedCertTimestamps = on;
|
| break;
|
| @@ -1381,6 +1434,148 @@ NSS_SetFrancePolicy(void)
|
| }
|
|
|
| SECStatus
|
| +SSL_DHEGroupPrefSet(PRFileDesc *fd,
|
| + SSLDHEGroupType *groups,
|
| + PRUint16 num_groups)
|
| +{
|
| + sslSocket *ss;
|
| +
|
| + if ((num_groups && !groups) || (!num_groups && groups)) {
|
| + PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
| + return SECFailure;
|
| + }
|
| +
|
| + ss = ssl_FindSocket(fd);
|
| + if (!ss) {
|
| + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DHEGroupPrefSet", SSL_GETPID(), fd));
|
| + return SECFailure;
|
| + }
|
| +
|
| + if (ss->ssl3.dheGroups) {
|
| + PORT_Free(ss->ssl3.dheGroups);
|
| + ss->ssl3.dheGroups = NULL;
|
| + ss->ssl3.numDHEGroups = 0;
|
| + }
|
| +
|
| + if (groups) {
|
| + ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType, num_groups);
|
| + if (!ss->ssl3.dheGroups) {
|
| + PORT_SetError(SEC_ERROR_NO_MEMORY);
|
| + return SECFailure;
|
| + }
|
| + PORT_Memcpy(ss->ssl3.dheGroups, groups,
|
| + sizeof(SSLDHEGroupType) * num_groups);
|
| + }
|
| + return SECSuccess;
|
| +}
|
| +
|
| +
|
| +PRCallOnceType gWeakDHParamsRegisterOnce;
|
| +int gWeakDHParamsRegisterError;
|
| +
|
| +PRCallOnceType gWeakDHParamsOnce;
|
| +int gWeakDHParamsError;
|
| +/* As our code allocates type PQGParams, we'll keep it around,
|
| + * even though we only make use of it's parameters through gWeakDHParam. */
|
| +static PQGParams *gWeakParamsPQG;
|
| +static ssl3DHParams *gWeakDHParams;
|
| +
|
| +static PRStatus
|
| +ssl3_CreateWeakDHParams(void)
|
| +{
|
| + PQGVerify *vfy;
|
| + SECStatus rv, passed;
|
| +
|
| + PORT_Assert(!gWeakDHParams && !gWeakParamsPQG);
|
| +
|
| + rv = PK11_PQG_ParamGenV2(1024, 160, 64 /*maximum seed that will work*/,
|
| + &gWeakParamsPQG, &vfy);
|
| + if (rv != SECSuccess) {
|
| + gWeakDHParamsError = PORT_GetError();
|
| + return PR_FAILURE;
|
| + }
|
| +
|
| + rv = PK11_PQG_VerifyParams(gWeakParamsPQG, vfy, &passed);
|
| + if (rv != SECSuccess || passed != SECSuccess) {
|
| + SSL_DBG(("%d: PK11_PQG_VerifyParams failed in ssl3_CreateWeakDHParams",
|
| + SSL_GETPID()));
|
| + gWeakDHParamsError = PORT_GetError();
|
| + return PR_FAILURE;
|
| + }
|
| +
|
| + gWeakDHParams = PORT_ArenaNew(gWeakParamsPQG->arena, ssl3DHParams);
|
| + if (!gWeakDHParams) {
|
| + gWeakDHParamsError = PORT_GetError();
|
| + return PR_FAILURE;
|
| + }
|
| +
|
| + gWeakDHParams->prime.data = gWeakParamsPQG->prime.data;
|
| + gWeakDHParams->prime.len = gWeakParamsPQG->prime.len;
|
| + gWeakDHParams->base.data = gWeakParamsPQG->base.data;
|
| + gWeakDHParams->base.len = gWeakParamsPQG->base.len;
|
| +
|
| + PK11_PQG_DestroyVerify(vfy);
|
| + return PR_SUCCESS;
|
| +}
|
| +
|
| +static SECStatus
|
| +ssl3_WeakDHParamsShutdown(void *appData, void *nssData)
|
| +{
|
| + if (gWeakParamsPQG) {
|
| + PK11_PQG_DestroyParams(gWeakParamsPQG);
|
| + gWeakParamsPQG = NULL;
|
| + gWeakDHParams = NULL;
|
| + }
|
| + return SECSuccess;
|
| +}
|
| +
|
| +static PRStatus
|
| +ssl3_WeakDHParamsRegisterShutdown(void)
|
| +{
|
| + SECStatus rv;
|
| + rv = NSS_RegisterShutdown(ssl3_WeakDHParamsShutdown, NULL);
|
| + if (rv != SECSuccess) {
|
| + gWeakDHParamsRegisterError = PORT_GetError();
|
| + }
|
| + return (PRStatus)rv;
|
| +}
|
| +
|
| +/* global init strategy inspired by ssl3_CreateECDHEphemeralKeys */
|
| +SECStatus
|
| +SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled)
|
| +{
|
| + sslSocket *ss;
|
| + PRStatus status;
|
| +
|
| + if (enabled) {
|
| + status = PR_CallOnce(&gWeakDHParamsRegisterOnce,
|
| + ssl3_WeakDHParamsRegisterShutdown);
|
| + if (status != PR_SUCCESS) {
|
| + PORT_SetError(gWeakDHParamsRegisterError);
|
| + return SECFailure;
|
| + }
|
| +
|
| + status = PR_CallOnce(&gWeakDHParamsOnce, ssl3_CreateWeakDHParams);
|
| + if (status != PR_SUCCESS) {
|
| + PORT_SetError(gWeakDHParamsError);
|
| + return SECFailure;
|
| + }
|
| + }
|
| +
|
| + if (!fd)
|
| + return SECSuccess;
|
| +
|
| + ss = ssl_FindSocket(fd);
|
| + if (!ss) {
|
| + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DHEGroupPrefSet", SSL_GETPID(), fd));
|
| + return SECFailure;
|
| + }
|
| +
|
| + ss->ssl3.dheWeakGroupEnabled = enabled;
|
| + return SECSuccess;
|
| +}
|
| +
|
| +SECStatus
|
| SSL_GetChannelBinding(PRFileDesc *fd,
|
| SSLChannelBindingType binding_type,
|
| unsigned char *out,
|
| @@ -1402,6 +1597,62 @@ SSL_GetChannelBinding(PRFileDesc *fd,
|
| return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax);
|
| }
|
|
|
| +#include "dhe-param.c"
|
| +
|
| +static const SSLDHEGroupType ssl_default_dhe_groups[] = {
|
| + ssl_ff_dhe_2048_group
|
| +};
|
| +
|
| +/* Keep this array synchronized with the index definitions in SSLDHEGroupType */
|
| +static const ssl3DHParams *all_ssl3DHParams[] = {
|
| + NULL, /* ssl_dhe_group_none */
|
| + &ff_dhe_2048,
|
| + &ff_dhe_3072,
|
| + &ff_dhe_4096,
|
| + &ff_dhe_6144,
|
| + &ff_dhe_8192,
|
| +};
|
| +
|
| +static SSLDHEGroupType
|
| +selectDHEGroup(sslSocket *ss, const SSLDHEGroupType *groups, PRUint16 num_groups)
|
| +{
|
| + if (!groups || !num_groups)
|
| + return ssl_dhe_group_none;
|
| +
|
| + /* We don't have automatic group parameter selection yet
|
| + * (potentially) based on socket parameters, e.g. key sizes.
|
| + * For now, we return the first available group from the allowed list. */
|
| + return groups[0];
|
| +}
|
| +
|
| +/* Ensure DH parameters have been selected */
|
| +SECStatus
|
| +ssl3_SelectDHParams(sslSocket *ss)
|
| +{
|
| + SSLDHEGroupType selectedGroup = ssl_dhe_group_none;
|
| +
|
| + if (ss->ssl3.dheWeakGroupEnabled) {
|
| + ss->dheParams = gWeakDHParams;
|
| + } else {
|
| + if (ss->ssl3.dheGroups) {
|
| + selectedGroup = selectDHEGroup(ss, ss->ssl3.dheGroups,
|
| + ss->ssl3.numDHEGroups);
|
| + } else {
|
| + size_t number_of_default_groups = PR_ARRAY_SIZE(ssl_default_dhe_groups);
|
| + selectedGroup = selectDHEGroup(ss, ssl_default_dhe_groups,
|
| + number_of_default_groups);
|
| + }
|
| +
|
| + if (selectedGroup == ssl_dhe_group_none ||
|
| + selectedGroup >= ssl_dhe_group_max) {
|
| + return SECFailure;
|
| + }
|
| +
|
| + ss->dheParams = all_ssl3DHParams[selectedGroup];
|
| + }
|
| +
|
| + return SECSuccess;
|
| +}
|
|
|
| /* LOCKS ??? XXX */
|
| static PRFileDesc *
|
| @@ -1699,6 +1950,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
|
| PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
|
| sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
|
| ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;
|
| + PORT_Memcpy(ss->ssl3.signatureAlgorithms, sm->ssl3.signatureAlgorithms,
|
| + sizeof(ss->ssl3.signatureAlgorithms[0]) *
|
| + sm->ssl3.signatureAlgorithmCount);
|
| + ss->ssl3.signatureAlgorithmCount = sm->ssl3.signatureAlgorithmCount;
|
|
|
| if (!ss->opt.useSecurity) {
|
| PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
| @@ -3122,6 +3377,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
|
| }
|
| ss->requestedCertTypes = NULL;
|
| ss->stepDownKeyPair = NULL;
|
| +
|
| + ss->dheParams = NULL;
|
| + ss->dheKeyPair = NULL;
|
| +
|
| ss->dbHandle = CERT_GetDefaultCertDB();
|
|
|
| /* Provide default implementation of hooks */
|
|
|