Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Unified Diff: net/third_party/nss/patches/tls-srp.patch

Issue 6804032: Add TLS-SRP (RFC 5054) support Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: remove "httpsv" scheme, minor NSS/OpenSSL changes Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/README.chromium ('k') | net/third_party/nss/ssl.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/third_party/nss/patches/tls-srp.patch
diff --git a/net/third_party/nss/patches/tls-srp.patch b/net/third_party/nss/patches/tls-srp.patch
new file mode 100644
index 0000000000000000000000000000000000000000..28c3bb77b5ef1395d982713ebc68bfa035cf37cf
--- /dev/null
+++ b/net/third_party/nss/patches/tls-srp.patch
@@ -0,0 +1,1469 @@
+diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def
+index 76417d0..0af96ba 100644
+--- a/mozilla/security/nss/lib/ssl/ssl.def
++++ b/mozilla/security/nss/lib/ssl/ssl.def
+@@ -136,6 +136,10 @@ SSL_ReHandshakeWithTimeout;
+ ;+NSS_3.11.8 { # NSS 3.11.8 release
+ ;+ global:
+ SSL_CanBypass;
++
++SSL_SetUserLogin;
++SSL_UserPasswdHook;
++SSL_GetSRPParamsHook;
+ ;+ local:
+ ;+*;
+ ;+};
+diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
+index 21d7c8d..5906ca9 100644
+--- a/mozilla/security/nss/lib/ssl/ssl.h
++++ b/mozilla/security/nss/lib/ssl/ssl.h
+@@ -437,6 +437,43 @@ SSL_IMPORT PRFileDesc *SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd);
+ */
+ SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
+
++
++/*
++ * Set the client side user name and password non-interactively.
++ */
++SSL_IMPORT SECStatus SSL_SetUserLogin(PRFileDesc *fd,
++ const char *u,
++ const char *p);
++
++/*
++ * This sets the client side callback for SSL to retrieve the user password.
++ * fd - the file descriptor for the connection in question
++ * func - callback function pointer
++ * pw - user password
++ */
++
++typedef SECStatus (PR_CALLBACK *SSLUserPasswdCB)(PRFileDesc *fd,
++ SECItem *pw, void *arg);
++
++SSL_IMPORT SECStatus SSL_UserPasswdHook(PRFileDesc *fd, SSLUserPasswdCB func,
++ void *arg);
++
++/*
++ * This sets the server side callback function for SSL to retrieve the SRP
++ * authentication parameters associated with a specific user login.
++ * fd - the file descriptor of the connection
++ * func - pointer to the callback function
++ * user - username to lookup in app database
++ * srp - SRP auth paramters supplied to SSL by app
++ */
++
++typedef SECStatus (PR_CALLBACK *SSLGetSRPParamsCB)(PRFileDesc *fd,
++ SECKEYSRPParams *srp,
++ void *arg);
++
++SSL_IMPORT SECStatus SSL_GetSRPParamsHook(PRFileDesc *fd,
++ SSLGetSRPParamsCB func, void *arg);
++
+ /*
+ ** This is a callback for dealing with server certs that are not authenticated
+ ** by the client. The client app can decide that it actually likes the
+@@ -703,6 +740,7 @@ SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void);
+ /* Report more information than SSL_SecurityStatus.
+ ** Caller supplies the info struct. Function fills it in.
+ */
++SSL_IMPORT SECStatus SSL_GetChannelUsername(PRFileDesc *fd, SECItem *user);
+ SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info,
+ PRUintn len);
+ SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
+diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
+index f5c0880..21caea4 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3con.c
++++ b/mozilla/security/nss/lib/ssl/ssl3con.c
+@@ -118,6 +118,9 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
+ #endif /* NSS_ENABLE_ECC */
+ { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
++ { TLS_SRP_SHA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
++ { TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
++ { TLS_SRP_SHA_DSS_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},
+@@ -141,11 +144,15 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
+ { SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
+ { 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},
++ { TLS_SRP_SHA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
++ { TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
++ { TLS_SRP_SHA_DSS_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 */
++ { TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { 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
+@@ -154,6 +161,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
+ #endif /* NSS_ENABLE_ECC */
+ { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
+ { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
++ { TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
++ { TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+
+
+ { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+@@ -283,6 +292,9 @@ static const ssl3KEADef kea_defs[] =
+ {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE},
+ {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE},
+ {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE },
++ {kea_srp, kt_srp, sign_null, PR_FALSE, 0, PR_FALSE},
++ {kea_srp_rsa, kt_srp, sign_rsa, PR_FALSE, 0, PR_FALSE},
++ {kea_srp_dss, kt_srp, sign_dsa, PR_FALSE, 0, PR_FALSE},
+ #ifdef NSS_ENABLE_ECC
+ {kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
+ {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
+@@ -344,6 +356,21 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] =
+
+
+ /* New TLS cipher suites */
++ {TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_srp},
++ {TLS_SRP_SHA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_srp},
++ {TLS_SRP_SHA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_srp},
++ {TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
++ cipher_3des, mac_sha, kea_srp_rsa},
++ {TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
++ cipher_3des, mac_sha, kea_srp_dss},
++ {TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
++ cipher_aes_128, mac_sha, kea_srp_rsa},
++ {TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
++ cipher_aes_128, mac_sha, kea_srp_dss},
++ {TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
++ cipher_aes_256, mac_sha, kea_srp_rsa},
++ {TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
++ cipher_aes_256, mac_sha, kea_srp_dss},
+ {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa},
+ {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_dss},
+ {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_rsa},
+@@ -420,7 +447,8 @@ static const CK_MECHANISM_TYPE kea_alg_defs[] = {
+ CKM_RSA_PKCS,
+ CKM_DH_PKCS_DERIVE,
+ CKM_KEA_KEY_DERIVE,
+- CKM_ECDH1_DERIVE
++ CKM_ECDH1_DERIVE,
++ CKM_NSS_SRP_DERIVE
+ };
+
+ typedef struct SSLCipher2MechStr {
+@@ -695,12 +723,27 @@ ssl3_config_match_init(sslSocket *ss)
+ }
+ #endif /* NSS_ENABLE_ECC */
+
++ /* XXX this should be merged with switch(kea) from above */
++ switch (cipher_def->key_exchange_alg) {
++ case kea_srp_rsa:
++ svrAuth = ss->serverCerts + kt_rsa;
++ break;
++ case kea_srp_dss:
++ svrAuth = ss->serverCerts + kt_null; /* don't ask me..*/
++ break;
++ default:
++ svrAuth = ss->serverCerts + exchKeyType;
++ break;
++ }
++
++
+ /* Mark the suites that are backed by real tokens, certs and keys */
+ suite->isPresent = (PRBool)
+ (((exchKeyType == kt_null) ||
+ ((!isServer || (svrAuth->serverKeyPair &&
+ svrAuth->SERVERKEY &&
+- svrAuth->serverCertChain)) &&
++ svrAuth->serverCertChain) ||
++ cipher_def->key_exchange_alg == kea_srp) &&
+ PK11_TokenExists(kea_alg_defs[exchKeyType]))) &&
+ ((cipher_alg == calg_null) || PK11_TokenExists(cipher_mech)));
+ if (suite->isPresent)
+@@ -1080,6 +1123,57 @@ ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,
+ return rv;
+ }
+
++/* Caller must set hiLevel error code.
++ * Called from ssl3_SendSRPServerKeyExchange */
++static SECStatus
++ssl3_ComputeSRPKeyHash(SECItem *N, SECItem *g, SECItem *s, SECItem *B,
++ SSL3Random *client_rand, SSL3Random *server_rand,
++ SSL3Hashes *hashes, PRBool bypassPKCS11)
++{
++ PRUint8 * hashBuf;
++ PRUint8 * pBuf;
++ SECStatus rv = SECFailure;
++ unsigned int bufLen;
++
++ bufLen = 2*SSL3_RANDOM_LENGTH + N->len + 2 + g->len + 2
++ + s->len + 1 + B->len + 2;
++
++ hashBuf = PORT_Alloc(bufLen);
++ if (!hashBuf) {
++ return SECFailure;
++ }
++
++ memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
++ pBuf = hashBuf + SSL3_RANDOM_LENGTH;
++ memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
++ pBuf += SSL3_RANDOM_LENGTH;
++ pBuf[0] = (PRUint8)(N->len >> 8);
++ pBuf[1] = (PRUint8)(N->len);
++ pBuf+=2;
++ memcpy(pBuf, N->data, N->len);
++ pBuf += N->len;
++ pBuf[0] = (PRUint8)(g->len >> 8);
++ pBuf[1] = (PRUint8)(g->len);
++ pBuf+=2;
++ memcpy(pBuf, g->data, g->len);
++ pBuf += g->len;
++ pBuf[0] = (PRUint8)(s->len);
++ pBuf+=1;
++ memcpy(pBuf, s->data, s->len);
++ pBuf += s->len;
++ pBuf[0] = (PRUint8)(B->len >> 8);
++ pBuf[1] = (PRUint8)(B->len);
++ pBuf+=2;
++ memcpy(pBuf, B->data, B->len);
++ pBuf += B->len;
++
++ rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
++
++ if (hashBuf)
++ PORT_Free(hashBuf);
++ return rv;
++}
++
+ /* Caller must set hiLevel error code. */
+ /* Called from ssl3_HandleServerKeyExchange. */
+ static SECStatus
+@@ -2663,6 +2757,8 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
+ error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break;
+ case bad_certificate_hash_value:
+ error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break;
++ case unknown_psk_identity:
++ error = SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT; break;
+ default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
+ }
+ if (level == alert_fatal) {
+@@ -2828,7 +2924,8 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
+ * data into a 48-byte value.
+ */
+ PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
+- (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
++ (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh) ||
++ (ss->ssl3.hs.kea_def->exchKeyType == kt_srp));
+ SECStatus rv = SECFailure;
+ CK_MECHANISM_TYPE master_derive;
+ CK_MECHANISM_TYPE key_derive;
+@@ -4733,8 +4830,241 @@ loser:
+ return rv;
+ }
+
++/* Read srp values from datastream and verify the signature
++ * if requiried by cipher. Save parameters to ss->sec.peerKey.
++ *
++ * called from ssl3_HandleServerKeyExchange
++ */
++static SECStatus
++ssl3_HandleSRPServerKeyExchange(sslSocket *ss, SSL3Opaque *b,
++ PRUint32 length) {
++
++ SECItem signature = {siBuffer, NULL, 0};
++ PRArenaPool *arena = NULL;
++ SECKEYPublicKey *peerKey = NULL;
++ SECStatus rv;
++ SSL3Hashes hashes;
++ SECItem srp_N, srp_g, srp_s, srp_ppub;
++ int errCode;
++
++ rv = ssl3_ConsumeHandshakeVariable(ss, &srp_N, 2, &b, &length);
++ if (rv != SECSuccess) {
++ goto loser; /* malformed. */
++ }
++ rv = ssl3_ConsumeHandshakeVariable(ss, &srp_g, 2, &b, &length);
++ if (rv != SECSuccess) {
++ goto loser; /* malformed. */
++ }
++ rv = ssl3_ConsumeHandshakeVariable(ss, &srp_s, 1, &b, &length);
++ if (rv != SECSuccess) {
++ goto loser; /* malformed. */
++ }
++ rv = ssl3_ConsumeHandshakeVariable(ss, &srp_ppub, 2, &b, &length);
++ if (rv != SECSuccess) {
++ goto loser; /* malformed. */
++ }
++
++ if (ss->ssl3.hs.kea_def->kea != kea_srp) { /* there MUST be a signature */
++ rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
++ if (rv != SECSuccess) {
++ goto loser; /* malformed. */
++ }
++ rv = ssl3_ComputeSRPKeyHash(&srp_N, &srp_g, &srp_s, &srp_ppub,
++ &ss->ssl3.hs.client_random,
++ &ss->ssl3.hs.server_random,
++ &hashes, ss->opt.bypassPKCS11);
++ if (rv != SECSuccess) {
++ errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ goto alert_loser;
++ }
++ rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
++ PR_TRUE, ss->pkcs11PinArg);
++ if (rv != SECSuccess) {
++ errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ goto alert_loser;
++ }
++ }
++
++ /* all ok, save and return */
++ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
++ if (arena == NULL) {
++ return SECFailure;
++ }
++ ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
++ if (peerKey == NULL) {
++ return SECFailure;
++ }
++ peerKey->arena = arena;
++ peerKey->keyType = srpKey;
++ peerKey->pkcs11Slot = NULL;
++ peerKey->pkcs11ID = CK_INVALID_HANDLE;
++
++ if (SECITEM_CopyItem(arena, &peerKey->u.srp.N, &srp_N) ||
++ SECITEM_CopyItem(arena, &peerKey->u.srp.g, &srp_g) ||
++ SECITEM_CopyItem(arena, &peerKey->u.srp.s, &srp_s) ||
++ SECITEM_CopyItem(arena, &peerKey->u.srp.ppub, &srp_ppub)) {
++ return SECFailure;
++ }
++ return SECSuccess;
++
++alert_loser:
++ (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
++loser:
++ PORT_SetError(errCode);
++ return SECFailure;
++}
++
++/* Calculate ClientKeyExchange and Pre-Master-Secret via SRP_GenKeys(),
++ * then send ClientKeyExchange and derive SSL master key
++ *
++ * called from ssl3_SendClientKeyExchange()
++ */
++static SECStatus
++ssl3_SendSRPClientKeyExchange(sslSocket *ss, SECKEYPublicKey * pubKey) {
++
++ SECKEYSRPParams *srpParam;
++ SECStatus rv;
++
++ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
++ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
++
++ srpParam = PORT_ZAlloc(sizeof(SECKEYSRPParams));
++ if (!srpParam) {
++ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ goto loser;
++ }
++
++ /* PW-Callback overrides SSL_SetUserLogin. If both fail to
++ * provide a password, the token must know it or fail. */
++ if (ss->getUserPasswd) {
++ if (!ss->sec.userPasswd)
++ ss->sec.userPasswd = SECITEM_AllocItem(NULL,NULL,0);
++ SECITEM_FreeItem(ss->sec.userPasswd, PR_FALSE);
++ ss->getUserPasswd(ss->fd, ss->sec.userPasswd, ss->getUserPasswdArg);
++ }
++ if (ss->sec.userPasswd) {
++ srpParam->secret.data = ss->sec.userPasswd->data;
++ srpParam->secret.len = ss->sec.userPasswd->len;
++ ss->sec.userPasswd = NULL;
++ }
+
++ /* calculate client key pair and PMS, then send key exchange data */
++ if (ss->opt.bypassPKCS11) {
++ SECItem pms = {0, NULL, 0};
++ SRPPrivateKey *prvKey;
++ SRPKeyPairParams keyPairParam;
++ keyPairParam.N.data = pubKey->u.srp.N.data;
++ keyPairParam.N.len = pubKey->u.srp.N.len;
++ keyPairParam.g.data = pubKey->u.srp.g.data;
++ keyPairParam.g.len = pubKey->u.srp.g.len;
++ keyPairParam.secret.data = srpParam->secret.data;
++ keyPairParam.secret.len = srpParam->secret.len;
++
++ rv = SRP_NewClientKeyPair(&prvKey, &keyPairParam);
++ if (rv != SECSuccess) goto loser; /* err set by SRP_ClientDerive */
++
++ SRPDeriveParams deriveParam;
++ deriveParam.N.data = pubKey->u.srp.N.data;
++ deriveParam.N.len = pubKey->u.srp.N.len;
++ deriveParam.g.data = pubKey->u.srp.g.data;
++ deriveParam.g.len = pubKey->u.srp.g.len;
++ deriveParam.s.data = pubKey->u.srp.s.data;
++ deriveParam.s.len = pubKey->u.srp.s.len;
++ deriveParam.u.data = ss->sec.userName->data;
++ deriveParam.u.len = ss->sec.userName->len;
++ deriveParam.ppub.data= pubKey->u.srp.ppub.data;
++ deriveParam.ppub.len = pubKey->u.srp.ppub.len;
++
++
++ if (SECSuccess != SRP_ClientDerive(prvKey, &deriveParam, &pms)) {
++ goto derive_fail;
++ }
++
++ /* client key exchange data */
++ rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
++ prvKey->pubKey.len + 2);
++ if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* */
++ rv = ssl3_AppendHandshakeVariable(ss, prvKey->pubKey.data,
++ prvKey->pubKey.len, 2);
++ if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* */
++
++ /* init pending cipher spec*/
++ rv = ssl3_MasterKeyDeriveBypass(ss->ssl3.pwSpec,
++ (unsigned char *)&ss->ssl3.hs.client_random,
++ (unsigned char *)&ss->ssl3.hs.server_random,
++ &pms, PR_TRUE, PR_FALSE);
++ if (rv != SECSuccess) {
++ ss->ssl3.pwSpec->msItem.data = ss->ssl3.pwSpec->raw_master_secret;
++ ss->ssl3.pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
++ PK11_GenerateRandom(ss->ssl3.pwSpec->msItem.data,
++ SSL3_MASTER_SECRET_LENGTH);
++ }
++ rv = ssl3_InitPendingCipherSpec(ss, NULL);
++
++ SECITEM_FreeItem(&pms, PR_FALSE);
++ PORT_FreeArena(prvKey->arena, PR_TRUE);
++ } else { /* PK11 path */
++ PK11SymKey *pms = NULL;
++ SECKEYPrivateKey *prvKey = NULL;
++ SECKEYPublicKey *newPub = NULL;
++
++ srpParam->N.data = pubKey->u.srp.N.data;
++ srpParam->N.len = pubKey->u.srp.N.len;
++ srpParam->g.data = pubKey->u.srp.g.data;
++ srpParam->g.len = pubKey->u.srp.g.len;
++ srpParam->s.data = pubKey->u.srp.s.data;
++ srpParam->s.len = pubKey->u.srp.s.len;
++ srpParam->u.data = ss->sec.userName->data;
++ srpParam->u.len = ss->sec.userName->len;
++
++ /* The token handles (missing) info supplied in srpParam
++ * The template not actually involved in key generation,
++ * but it's important in the server key exchange */
++
++ prvKey = SECKEY_CreateSRPPrivateKey(srpParam, &newPub, PR_FALSE, NULL);
++ if (!prvKey) {
++ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
++ rv = SECFailure;
++ goto loser;
++ }
++ SECITEM_CopyItem(newPub->arena, &newPub->u.srp.ppub, &pubKey->u.srp.ppub);
++
++ /* Now all data is in newPub and prvKey, compute pms with them */
++ pms = PK11_PubDerive(prvKey, newPub, PR_FALSE, NULL, NULL,
++ CKM_NSS_SRP_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, CKF_DERIVE, 0, NULL);
+
++ if (!pms) {
++ goto derive_fail;
++ }
++
++ /* init pending cipher spec*/
++ rv = ssl3_InitPendingCipherSpec(ss, pms);
++
++
++ /* client key exchange data */
++ rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
++ newPub->u.srp.pub.len + 2);
++ if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* */
++ rv = ssl3_AppendHandshakeVariable(ss, newPub->u.srp.pub.data,
++ newPub->u.srp.pub.len, 2);
++ if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* */
++
++ if (pms) PK11_FreeSymKey(pms);
++ SECKEY_DestroyPublicKey(newPub);
++ } /* end of PK11 path */
++
++loser:
++ SECITEM_ZfreeItem(ss->sec.userPasswd, PR_TRUE);
++ PORT_Free(srpParam);
++ /* caller frees pubKey */
++ return rv;
++derive_fail:
++ if (PORT_GetError() == SEC_ERROR_SRP_UNSUPPORTED_GROUP)
++ SSL3_SendAlert(ss, alert_fatal, insufficient_security);
++ if (PORT_GetError() == SEC_ERROR_SRP_ILLEGAL_PARAMETER)
++ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
++ return SECFailure;
++}
+
+
+ /* Called from ssl3_HandleServerHelloDone(). */
+@@ -4794,7 +5124,9 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
+ rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
+ break;
+ #endif /* NSS_ENABLE_ECC */
+-
++ case kt_srp:
++ rv = ssl3_SendSRPClientKeyExchange(ss, serverKey);
++ break;
+ default:
+ /* got an unknown or unsupported Key Exchange Algorithm. */
+ SEND_ALERT
+@@ -5284,7 +5616,8 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ desc = unexpected_message;
+ goto alert_loser;
+ }
+- if (ss->sec.peerCert == NULL) {
++ if (ss->sec.peerCert == NULL &&
++ ss->ssl3.hs.suite_def->key_exchange_alg != kea_srp) {
+ errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
+ desc = unexpected_message;
+ goto alert_loser;
+@@ -5473,6 +5806,13 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
+ return rv;
+ #endif /* NSS_ENABLE_ECC */
++ case kt_srp:
++ rv = ssl3_HandleSRPServerKeyExchange(ss, b, length);
++ if (rv != SECSuccess) {
++ errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ goto alert_loser;
++ }
++ return rv;
+
+ default:
+ desc = handshake_failure;
+@@ -6034,16 +6374,20 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
+ if (rv != SECSuccess) {
+ return rv; /* err code is set. */
+ }
+- rv = ssl3_SendCertificate(ss);
+- if (rv != SECSuccess) {
+- return rv; /* error code is set. */
+- }
+ /* We have to do this after the call to ssl3_SendServerHello,
+ * because kea_def is set up by ssl3_SendServerHello().
+ */
+ kea_def = ss->ssl3.hs.kea_def;
+ ss->ssl3.hs.usedStepDownKey = PR_FALSE;
+
++
++ if (kea_def->kea != kea_srp) { /* SRP auth only */
++ rv = ssl3_SendCertificate(ss);
++ if (rv != SECSuccess) {
++ return rv; /* error code is set. */
++ }
++ }
++
+ if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
+ /* see if we can legally use the key in the cert. */
+ int keyLen; /* bytes */
+@@ -6075,6 +6419,11 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
+ return rv; /* err code was set. */
+ }
+ #endif /* NSS_ENABLE_ECC */
++ } else if ( kea_def->exchKeyType == kt_srp ) {
++ rv = ssl3_SendServerKeyExchange(ss);
++ if (rv != SECSuccess) {
++ return rv; /* err code was set. */
++ }
+ }
+
+ if (ss->opt.requestCertificate) {
+@@ -7099,6 +7448,195 @@ ssl3_SendServerHello(sslSocket *ss)
+ return SECSuccess;
+ }
+
++/* ssl3_SendSRPServerKeyExchange()
++ * called by ssl3_SendServerKeyExchange()
++ *
++ * - make sure we got a userid in the srp client hello extension
++ * - retrieve verifier and parameters for the user via callback func
++ * - if user nonexistant, CB makes something up if it wants to
++ * - continue by creating and sending the SRP key exchange data:
++ *
++ * N, g, s, v = <read from password file>
++ * b = random()
++ * k = SHA1(N | PAD(g))
++ * B = k*v + g^b % N
++ * send (N,g,s,B)
++ *
++ * save values b,v,N for calculation of pms in ssl3_HandleSRPClientKeyExchange
++ */
++
++SECStatus
++ssl3_SendSRPServerKeyExchange(sslSocket *ss) {
++
++ int bytes = 0;
++ const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
++ SECItem signed_hash = {siBuffer, NULL, 0};
++ SECStatus rv = SECFailure;
++ SECKEYSRPPublicKey *srp = NULL;
++ SECKEYPublicKey *pubKey = NULL;
++ SECKEYPrivateKey *prvKey = NULL;
++ SECKEYSRPParams *srpParams;
++ SSL3Hashes hashes;
++
++ /* send error if no userid was supplied in Client Hello */
++ if (!ss->sec.userName || !ss->sec.userName->data)
++ goto unknown_id;
++
++ /* Ask application for SRP parameters for specified username.
++ * Information provided via callback overrides data set on token.
++ * If no params provided, the token must supply them or fail.
++ * Callback may fail for nonexistant user.
++ */
++
++ srpParams = PORT_ZAlloc(sizeof(SECKEYSRPParams));
++ if (!srpParams) goto no_memory;
++
++ srpParams->u.data = ss->sec.userName->data;
++ srpParams->u.len = ss->sec.userName->len;
++
++ if (ss->getSRPParams) {
++ rv = ss->getSRPParams(ss->fd, srpParams, ss->getSRPParamsArg);
++ if (rv != SECSuccess) {
++ SECITEM_FreeItem(&srpParams->N, PR_FALSE);
++ SECITEM_FreeItem(&srpParams->g, PR_FALSE);
++ SECITEM_FreeItem(&srpParams->s, PR_FALSE);
++ SECITEM_ZfreeItem(&srpParams->secret, PR_FALSE);
++ PORT_Free(srpParams);
++ goto unknown_id;
++ }
++ }
++
++ /* create SRP server key pair */
++ if (ss->opt.bypassPKCS11) {
++ /* srpParams, keyPairParams are temporary. pubKey and prvKey have
++ * own arenas and are saved for ssl3_HandleSRPClientKeyExchange */
++ SRPPrivateKey *srpPrv;
++ SRPKeyPairParams keyPairParams;
++
++ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
++ if (!arena) goto no_memory;
++
++ keyPairParams.N.data = srpParams->N.data;
++ keyPairParams.N.len = srpParams->N.len;
++ keyPairParams.g.data = srpParams->g.data;
++ keyPairParams.g.len = srpParams->g.len;
++ keyPairParams.secret.data = srpParams->secret.data;
++ keyPairParams.secret.len = srpParams->secret.len;
++
++ rv = SRP_NewServerKeyPair(&srpPrv, &keyPairParams);
++ if (rv != SECSuccess) {
++ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
++ return rv;
++ }
++ prvKey = (SECKEYPrivateKey *)srpPrv;
++
++ /* create pubKey from temporary stuff */
++ pubKey = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
++ if (!pubKey) goto no_memory;
++ pubKey->arena = arena;
++ srp = &pubKey->u.srp;
++
++ SECITEM_CopyItem(arena, &srp->N, &srpParams->N);
++ SECITEM_CopyItem(arena, &srp->g, &srpParams->g);
++ SECITEM_CopyItem(arena, &srp->s, &srpParams->s);
++ SECITEM_CopyItem(arena, &srp->u, &srpParams->u);
++ SECITEM_CopyItem(arena, &srp->pub, &srpPrv->pubKey);
++
++ } else {
++
++ /* input: srpParams, output: prvKey = b,B,v, pubKey = N,g,s,u,B */
++ prvKey = SECKEY_CreateSRPPrivateKey(srpParams, &pubKey, PR_TRUE, NULL);
++ if (!prvKey) {
++ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
++ rv = SECFailure;
++ goto cleanup;
++ }
++ srp = &pubKey->u.srp;
++ }
++
++ /* send N,g,s,B as ServerKeyExchange to Client */
++ /* optionally include signature for additional DSS/RSA auth */
++
++ if (kea_def->kea != kea_srp) { /* we need a RSA/DSA signature */
++ rv = ssl3_ComputeSRPKeyHash(&srp->N, &srp->g, &srp->s, &srp->pub,
++ &ss->ssl3.hs.client_random,
++ &ss->ssl3.hs.server_random,
++ &hashes, ss->opt.bypassPKCS11);
++ if (rv != SECSuccess) {
++ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ goto loser;
++ }
++ /* look if we have a certificate for selected algo */
++ if (kea_def->kea == kea_srp_rsa)
++ bytes = kt_rsa;
++ else
++ bytes = kt_null;
++
++ if (!(&ss->serverCerts[bytes])) {
++ /* ciphersuite signing algo does not match supplied certificate */
++ PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH);
++ return SECFailure;
++ }
++ rv = ssl3_SignHashes(&hashes, ss->serverCerts[bytes].SERVERKEY,
++ &signed_hash, PR_TRUE);
++ bytes = 2 + signed_hash.len;
++ }
++
++ bytes += srp->N.len + srp->g.len + srp->s.len + srp->pub.len + 7;
++
++ rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, bytes);
++ if (rv != SECSuccess)
++ return rv; /* err set by AppendHandshake. */
++
++ rv = ssl3_AppendHandshakeVariable(ss, srp->N.data, srp->N.len, 2);
++ if (rv != SECSuccess)
++ return rv; /* err set by AppendHandshake. */
++
++ rv = ssl3_AppendHandshakeVariable(ss, srp->g.data, srp->g.len, 2);
++ if (rv != SECSuccess)
++ return rv; /* err set by AppendHandshake. */
++
++ rv = ssl3_AppendHandshakeVariable(ss, srp->s.data, srp->s.len, 1);
++ if (rv != SECSuccess)
++ return rv; /* err set by AppendHandshake. */
++
++ rv = ssl3_AppendHandshakeVariable(ss, srp->pub.data, srp->pub.len, 2);
++ if (rv != SECSuccess)
++ return rv; /* err set by AppendHandshake. */
++
++ if (kea_def->kea != kea_srp) {
++ rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
++ signed_hash.len, 2);
++ if (rv != SECSuccess) {
++ return rv; /* err set by AppendHandshake. */
++ }
++ SECITEM_FreeItem(&signed_hash, PR_FALSE);
++ }
++
++ /* save prvKey / pubKey for use in HandleSRPClientExchange
++ * XXX in bypassPK11, prvKey is no PK11 object and must be casted */
++ ssl3KeyPair *srpPair = ssl3_NewKeyPair(prvKey, pubKey);
++ ss->serverCerts[kt_srp].serverKeyPair = srpPair;
++
++cleanup:
++ SECITEM_FreeItem(&srpParams->N, PR_FALSE);
++ SECITEM_FreeItem(&srpParams->g, PR_FALSE);
++ SECITEM_FreeItem(&srpParams->s, PR_FALSE);
++ SECITEM_ZfreeItem(&srpParams->secret, PR_FALSE);
++ if (srpParams) PORT_Free(srpParams);
++ return rv;
++loser:
++ PORT_SetError(SSL_ERROR_INTERNAL_ERROR_ALERT);
++ (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
++ return SECFailure;
++unknown_id:
++ PORT_SetError(SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT);
++ (void)SSL3_SendAlert(ss, alert_fatal, unknown_psk_identity);
++ return SECFailure;
++no_memory:
++ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ return SECFailure;
++}
+
+ static SECStatus
+ ssl3_SendServerKeyExchange(sslSocket *ss)
+@@ -7183,7 +7721,9 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
+ return rv;
+ }
+ #endif /* NSS_ENABLE_ECC */
+-
++ case kt_srp:
++ rv = ssl3_SendSRPServerKeyExchange(ss);
++ return rv;
+ case kt_dh:
+ case kt_null:
+ default:
+@@ -7536,6 +8076,101 @@ double_bypass:
+ return SECSuccess;
+ }
+
++/*
++ * extract SRP value A from ClientKeyExchange
++ * calculate pre-master-secret and init cipher specs
++ *
++ * called by ssl3_HandleClientKeyExchange
++ */
++SECStatus
++ssl3_HandleSRPClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
++ PRUint32 length) {
++
++ SECItem ppub; /* peers public key ('A') */
++ sslServerCerts sc;
++ SECStatus rv = SECFailure;
++ SECKEYPublicKey *pubKey = NULL;
++
++
++ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
++ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
++
++ rv = ssl3_ConsumeHandshakeVariable(ss, &ppub, 2, &b, &length);
++ if (rv != SECSuccess) {
++ PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
++ return SECFailure;
++ }
++
++ sc = ss->serverCerts[kt_srp];
++ pubKey = sc.serverKeyPair->pubKey;
++
++ SECITEM_CopyItem(pubKey->arena, &pubKey->u.srp.ppub, &ppub);
++
++ if (ss->opt.bypassPKCS11) {
++ SRPPrivateKey *prvKey = NULL;
++ SECItem pms = { 0, NULL, 0 };
++ SRPDeriveParams param;
++
++ prvKey = (SRPPrivateKey *)sc.serverKeyPair->privKey;
++
++ param.N.data = pubKey->u.srp.N.data;
++ param.N.len = pubKey->u.srp.N.len;
++ param.g.data = pubKey->u.srp.g.data;
++ param.g.len = pubKey->u.srp.g.len;
++ param.ppub.data = pubKey->u.srp.ppub.data;
++ param.ppub.len = pubKey->u.srp.ppub.len;
++
++ if (SECSuccess != SRP_ServerDerive(prvKey, &param, &pms))
++ goto derive_fail;
++
++ ssl_GetSpecWriteLock(ss);
++ /* create MS out of MS, bypassing PKCS11 */
++ rv = ssl3_MasterKeyDeriveBypass(ss->ssl3.pwSpec,
++ (unsigned char *)&ss->ssl3.hs.client_random,
++ (unsigned char *)&ss->ssl3.hs.server_random,
++ &pms, PR_TRUE, PR_FALSE);
++ if (rv != SECSuccess) {
++ ss->ssl3.pwSpec->msItem.data = ss->ssl3.pwSpec->raw_master_secret;
++ ss->ssl3.pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
++ PK11_GenerateRandom(ss->ssl3.pwSpec->msItem.data, ss->ssl3.pwSpec->msItem.len);
++ }
++
++ rv = ssl3_InitPendingCipherSpec(ss, NULL);
++
++ SECITEM_ZfreeItem(&pms, PR_FALSE);
++ PORT_FreeArena(prvKey->arena, PR_TRUE); /* XXX FreeArena does not zeroize! */
++ sc.serverKeyPair->privKey = NULL;
++
++ } else {
++ SECKEYPrivateKey *prvKey = NULL;
++ PK11SymKey *pms = NULL; /* pre-master secret */
++
++ prvKey = sc.serverKeyPair->privKey;
++
++ /* Calculate PMS based on clntKey and public params */
++ pms = PK11_PubDerive(prvKey, pubKey, PR_TRUE, NULL, NULL,
++ CKM_NSS_SRP_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, CKF_DERIVE, 0, NULL);
++
++ if (!pms) {
++ goto derive_fail;
++ }
++
++ ssl_GetSpecWriteLock(ss);
++ /* derive master secret from pms */
++ rv = ssl3_InitPendingCipherSpec(ss, pms);
++ ssl_ReleaseSpecWriteLock(ss);
++
++ PK11_FreeSymKey(pms);
++ /*SECKEY_DestroyPrivateKey(prvKey);*/
++ }
++
++ return rv;
++derive_fail:
++ if (PORT_GetError() == SEC_ERROR_SRP_ILLEGAL_PARAMETER)
++ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
++ return rv;
++}
++
+
+ /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
+ * ssl3 ClientKeyExchange message from the remote client
+@@ -7608,7 +8243,8 @@ skip:
+ serverKey = serverKeyPair->privKey;
+ }
+
+- if (serverKey == NULL) {
++ /* XXX hack, figure out this serverKey thing..*/
++ if (serverKey == NULL && kea_def->exchKeyType != kt_srp) {
+ SEND_ALERT
+ PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
+ return SECFailure;
+@@ -7649,7 +8285,12 @@ skip:
+ }
+ break;
+ #endif /* NSS_ENABLE_ECC */
+-
++ case kt_srp:
++ rv = ssl3_HandleSRPClientKeyExchange(ss, b, length);
++ if (rv != SECSuccess) {
++ return SECFailure; /* error code set */
++ }
++ break;
+ default:
+ (void) ssl3_HandshakeFailure(ss);
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+@@ -7823,8 +8464,12 @@ ssl3_SendCertificate(sslSocket *ss)
+ * using EC certificates.
+ */
+ if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
+- (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
++ (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) ||
++ (ss->ssl3.hs.kea_def->kea == kea_srp_rsa)) {
+ certIndex = kt_rsa;
++ } else if
++ (ss->ssl3.hs.kea_def->kea == kea_srp_dss) {
++ certIndex = kt_null;
+ } else {
+ certIndex = ss->ssl3.hs.kea_def->exchKeyType;
+ }
+@@ -8244,7 +8889,9 @@ cert_block:
+ ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
+ ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
+ #endif /* NSS_ENABLE_ECC */
+- ss->ssl3.hs.kea_def->exchKeyType == kt_dh) {
++ ss->ssl3.hs.kea_def->exchKeyType == kt_dh ||
++ ss->ssl3.hs.kea_def->kea == kea_srp_dss ||
++ ss->ssl3.hs.kea_def->kea == kea_srp_rsa) {
+ ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */
+ }
+ }
+diff --git a/mozilla/security/nss/lib/ssl/ssl3ecc.c b/mozilla/security/nss/lib/ssl/ssl3ecc.c
+index 778c7ab..b899038 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3ecc.c
++++ b/mozilla/security/nss/lib/ssl/ssl3ecc.c
+@@ -1191,3 +1191,60 @@ loser:
+ }
+
+ #endif /* NSS_ENABLE_ECC */
++
++/* send user mapping indication using info from ss->sec.userlogin
++ * called from ssl3_CallHelloExtensionSenders */
++PRInt32
++ssl3_SendSRPHelloExtension(sslSocket * ss, PRBool append,
++ PRUint32 maxBytes)
++{
++ SECItem * user = ss->sec.userName;
++
++ if (user == NULL)
++ return 0; /* no credentials, no extension */
++
++ if (append && maxBytes >= user->len + 5) {
++ SECStatus rv;
++ /* extension_type 6 */
++ rv = ssl3_AppendHandshakeNumber(ss, 12, 2);
++ if (rv != SECSuccess) return 0;
++ /* length of extension */
++ rv = ssl3_AppendHandshakeNumber(ss, user->len + 1, 2);
++ if (rv != SECSuccess) return 0;
++ /* length of data */
++ rv = ssl3_AppendHandshakeNumber(ss, user->len, 1);
++ if (rv != SECSuccess) return 0;
++ /* extension_data = srp user name */
++ rv = ssl3_AppendHandshake(ss, user->data, user->len);
++ if (rv != SECSuccess) return 0;
++ }
++ return user->len+5;
++}
++
++SECStatus
++ssl3_HandleSRPHelloExtension(sslSocket *ss, PRUint16 ext, SECItem *data)
++{
++ SECStatus rv;
++ SECItem username;
++
++ rv = ssl3_ConsumeHandshakeVariable(ss, &username, 1, &data->data, &data->len);
++ if (rv != SECSuccess)
++ return rv;
++
++ /* enforce SRP username length constrain */
++ if (data->len > MAX_SRP_USERNAME_LENGTH)
++ data->len = MAX_SRP_USERNAME_LENGTH;
++
++ ss->sec.userName = PORT_ZAlloc(sizeof(SECItem));
++ if (!ss->sec.userName)
++ goto no_memory;
++
++ rv = SECITEM_CopyItem(NULL, ss->sec.userName, &username);
++ if (rv != SECSuccess)
++ goto no_memory;
++
++ return rv;
++no_memory:
++ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ return SECFailure;
++}
+diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c
+index b93671e..c2a27b4 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3ext.c
++++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
+@@ -78,6 +78,11 @@ static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
+ PRBool append, PRUint32 maxBytes);
+ static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
++static SECStatus ssl3_HandleSRPHelloXtn(sslSocket *ss, PRUint16 ext,
++ SECItem *data);
++PRInt32 ssl3_SendSRPHelloXtn(sslSocket * ss, PRBool append,
++ PRUint32 maxBytes);
++
+
+ /*
+ * Write bytes. Using this function means the SECItem structure
+@@ -254,6 +259,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
+
+ static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
+ { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
++ { ssl_srp_hello_xtn, &ssl3_HandleSRPHelloXtn },
+ { -1, NULL }
+ };
+
+@@ -272,6 +278,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
+ { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
+ #endif
+ { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
++ { ssl_srp_hello_xtn, &ssl3_SendSRPHelloXtn },
+ { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
+ { ssl_snap_start_xtn, &ssl3_SendSnapStartXtn }
+@@ -1720,3 +1727,59 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
+ return rv;
+ }
+
++/* send user mapping indication using info from ss->sec.userlogin
++ * called from ssl3_CallHelloExtensionSenders */
++PRInt32
++ssl3_SendSRPHelloXtn(sslSocket * ss, PRBool append,
++ PRUint32 maxBytes)
++{
++ SECItem * user = ss->sec.userName;
++
++ if (user == NULL)
++ return 0; /* no credentials, no extension */
++
++ if (append && maxBytes >= user->len + 5) {
++ SECStatus rv;
++ /* extension_type 6 */
++ rv = ssl3_AppendHandshakeNumber(ss, 12, 2);
++ if (rv != SECSuccess) return 0;
++ /* length of extension */
++ rv = ssl3_AppendHandshakeNumber(ss, user->len + 1, 2);
++ if (rv != SECSuccess) return 0;
++ /* length of data */
++ rv = ssl3_AppendHandshakeNumber(ss, user->len, 1);
++ if (rv != SECSuccess) return 0;
++ /* extension_data = srp user name */
++ rv = ssl3_AppendHandshake(ss, user->data, user->len);
++ if (rv != SECSuccess) return 0;
++ }
++ return user->len+5;
++}
++
++SECStatus
++ssl3_HandleSRPHelloXtn(sslSocket *ss, PRUint16 ext, SECItem *data)
++{
++ SECStatus rv;
++ SECItem username;
++
++ rv = ssl3_ConsumeHandshakeVariable(ss, &username, 1, &data->data, &data->len);
++ if (rv != SECSuccess)
++ return rv;
++
++ /* enforce SRP username length constrain */
++ if (data->len > MAX_SRP_USERNAME_LENGTH)
++ data->len = MAX_SRP_USERNAME_LENGTH;
++
++ ss->sec.userName = PORT_ZAlloc(sizeof(SECItem));
++ if (!ss->sec.userName)
++ goto no_memory;
++
++ rv = SECITEM_CopyItem(NULL, ss->sec.userName, &username);
++ if (rv != SECSuccess)
++ goto no_memory;
++
++ return rv;
++no_memory:
++ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
++ return SECFailure;
++}
+diff --git a/mozilla/security/nss/lib/ssl/ssl3prot.h b/mozilla/security/nss/lib/ssl/ssl3prot.h
+index aeaacdd..a043577 100644
+--- a/mozilla/security/nss/lib/ssl/ssl3prot.h
++++ b/mozilla/security/nss/lib/ssl/ssl3prot.h
+@@ -63,6 +63,8 @@ typedef uint16 ssl3CipherSuite;
+
+ #define MAX_FRAGMENT_LENGTH 16384
+
++#define MAX_SRP_USERNAME_LENGTH 255
++
+ typedef enum {
+ content_change_cipher_spec = 20,
+ content_alert = 21,
+@@ -137,7 +139,9 @@ typedef enum {
+ certificate_unobtainable = 111,
+ unrecognized_name = 112,
+ bad_certificate_status_response = 113,
+- bad_certificate_hash_value = 114
++ bad_certificate_hash_value = 114,
++
++ unknown_psk_identity = 115
+
+ } SSL3AlertDescription;
+
+@@ -215,6 +219,9 @@ typedef enum {
+ kea_dh_anon,
+ kea_dh_anon_export,
+ kea_rsa_fips,
++ kea_srp,
++ kea_srp_rsa,
++ kea_srp_dss,
+ kea_ecdh_ecdsa,
+ kea_ecdhe_ecdsa,
+ kea_ecdh_rsa,
+diff --git a/mozilla/security/nss/lib/ssl/sslauth.c b/mozilla/security/nss/lib/ssl/sslauth.c
+index 3f4924d..8282cf8 100644
+--- a/mozilla/security/nss/lib/ssl/sslauth.c
++++ b/mozilla/security/nss/lib/ssl/sslauth.c
+@@ -291,6 +291,80 @@ SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
+ return SECSuccess;
+ }
+
++/* register callback function to provide the user password */
++SECStatus
++SSL_UserPasswdHook(PRFileDesc *s, SSLUserPasswdCB func, void *arg)
++{
++ sslSocket *ss;
++
++ ss = ssl_FindSocket(s);
++ if (!ss) {
++ SSL_DBG(("%d: SSL[%d]: bad socket in UserPasswdHook",
++ SSL_GETPID(), s));
++ return SECFailure;
++ }
++
++ ss->getUserPasswd = func;
++ ss->getUserPasswdArg = arg;
++ return SECSuccess;
++}
++
++/* used by client to provide user credentials non-interactively */
++SECStatus
++SSL_SetUserLogin(PRFileDesc *s, const char *user, const char *passwd)
++{
++ sslSocket *ss = NULL;
++ int len;
++
++ ss = ssl_FindSocket(s);
++ if (!ss) {
++ SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
++ SSL_GETPID(), s));
++ return SECFailure;
++ }
++
++ if (user) {
++ len = PORT_Strlen(user);
++ if (len > MAX_SRP_USERNAME_LENGTH)
++ len = MAX_SRP_USERNAME_LENGTH;
++ ss->sec.userName = SECITEM_AllocItem(NULL, NULL, len);
++ if (!ss->sec.userName) {
++ PORT_SetError(SEC_ERROR_NO_MEMORY);
++ return SECFailure;
++ }
++ PORT_Memcpy(ss->sec.userName->data, user, ss->sec.userName->len);
++ }
++
++ if (passwd) {
++ len = PORT_Strlen(passwd);
++ ss->sec.userPasswd = SECITEM_AllocItem(NULL, NULL, len);
++ if (!ss->sec.userPasswd) {
++ PORT_SetError(SEC_ERROR_NO_MEMORY);
++ return SECFailure;
++ }
++ PORT_Memcpy(ss->sec.userPasswd->data, passwd, ss->sec.userPasswd->len);
++ }
++
++ return SECSuccess;
++}
++
++/* register callback function to provide SRP user authentication params */
++SECStatus
++SSL_GetSRPParamsHook(PRFileDesc *s, SSLGetSRPParamsCB func, void *arg)
++{
++ sslSocket *ss;
++
++ ss = ssl_FindSocket(s);
++ if (!ss) {
++ SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
++ SSL_GETPID(), s));
++ return SECFailure;
++ }
++
++ ss->getSRPParams = func;
++ ss->getSRPParamsArg = arg;
++ return SECSuccess;
++}
+
+ /* This is the "default" authCert callback function. It is called when a
+ * certificate message is received from the peer and the local application
+diff --git a/mozilla/security/nss/lib/ssl/sslenum.c b/mozilla/security/nss/lib/ssl/sslenum.c
+index b8aa8cc..196ed30 100644
+--- a/mozilla/security/nss/lib/ssl/sslenum.c
++++ b/mozilla/security/nss/lib/ssl/sslenum.c
+@@ -74,6 +74,9 @@ const PRUint16 SSL_ImplementedCiphers[] = {
+ #endif /* NSS_ENABLE_ECC */
+ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
++ TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
++ TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
++ TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+
+ /* 128-bit */
+ #ifdef NSS_ENABLE_ECC
+@@ -98,12 +101,16 @@ const PRUint16 SSL_ImplementedCiphers[] = {
+ SSL_RSA_WITH_RC4_128_MD5,
+ SSL_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
++ TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
++ TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
++ TLS_SRP_SHA_DSS_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 */
++ TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ #ifdef NSS_ENABLE_ECC
+@@ -112,6 +119,8 @@ const PRUint16 SSL_ImplementedCiphers[] = {
+ #endif /* NSS_ENABLE_ECC */
+ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
++ TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
++ TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+
+ /* 56-bit DES "domestic" cipher suites */
+ SSL_DHE_RSA_WITH_DES_CBC_SHA,
+diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ssl/sslerr.h
+index eb56ea9..a0c4b9d 100644
+--- a/mozilla/security/nss/lib/ssl/sslerr.h
++++ b/mozilla/security/nss/lib/ssl/sslerr.h
+@@ -205,6 +205,8 @@ SSL_ERROR_WEAK_SERVER_KEY = (SSL_ERROR_BASE + 115),
+
+ SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 116),
+
++SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT = (SSL_ERROR_BASE + 116),
++
+ SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
+ } SSLErrorCodes;
+ #endif /* NO_SECURITY_ERROR_ENUM */
+diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h
+index 1ea82da..0a0808a 100644
+--- a/mozilla/security/nss/lib/ssl/sslimpl.h
++++ b/mozilla/security/nss/lib/ssl/sslimpl.h
+@@ -317,9 +317,9 @@ typedef struct {
+ } ssl3CipherSuiteCfg;
+
+ #ifdef NSS_ENABLE_ECC
+-#define ssl_V3_SUITES_IMPLEMENTED 50
++#define ssl_V3_SUITES_IMPLEMENTED 59
+ #else
+-#define ssl_V3_SUITES_IMPLEMENTED 30
++#define ssl_V3_SUITES_IMPLEMENTED 39
+ #endif /* NSS_ENABLE_ECC */
+
+ typedef struct sslOptionsStr {
+@@ -1050,6 +1050,8 @@ struct sslSecurityInfoStr {
+ CERTCertificate *localCert; /* ssl 2 & 3 */
+ CERTCertificate *peerCert; /* ssl 2 & 3 */
+ SECKEYPublicKey *peerKey; /* ssl3 only */
++ SECItem *userName; /* SSL username credential */
++ SECItem *userPasswd; /* SSL userpasswd credential */
+
+ SSLSignType authAlgorithm;
+ PRUint32 authKeyBits;
+@@ -1159,6 +1161,10 @@ const unsigned char * preferredCipher;
+ SSLHandshakeCallback handshakeCallback;
+ void *handshakeCallbackData;
+ void *pkcs11PinArg;
++ SSLUserPasswdCB getUserPasswd;
++ void *getUserPasswdArg;
++ SSLGetSRPParamsCB getSRPParams;
++ void *getSRPParamsArg;
+
+ PRIntervalTime rTimeout; /* timeout for NSPR I/O */
+ PRIntervalTime wTimeout; /* timeout for NSPR I/O */
+diff --git a/mozilla/security/nss/lib/ssl/sslinfo.c b/mozilla/security/nss/lib/ssl/sslinfo.c
+index c1c3fd7..2599ef1 100644
+--- a/mozilla/security/nss/lib/ssl/sslinfo.c
++++ b/mozilla/security/nss/lib/ssl/sslinfo.c
+@@ -54,6 +54,27 @@ ssl_GetCompressionMethodName(SSLCompressionMethod compression)
+ }
+ }
+
++SECStatus
++SSL_GetChannelUsername(PRFileDesc *fd, SECItem *user)
++{
++ SECItem * username;
++ sslSocket * ss;
++
++ ss = ssl_FindSocket(fd);
++ if (!ss) {
++ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelUsername",
++ SSL_GETPID(), fd));
++ return SECFailure;
++ }
++
++ if (ss->sec.userName == NULL) {
++ PORT_SetError(SEC_ERROR_INVALID_ARGS);
++ return SECFailure;
++ }
++
++ return SECITEM_CopyItem(NULL, user, ss->sec.userName);
++}
++
+ SECStatus
+ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
+ {
+@@ -141,6 +162,9 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
+ #define K_KEA "KEA", kt_kea
+ #define K_ECDH "ECDH", kt_ecdh
+ #define K_ECDHE "ECDHE", kt_ecdh
++#define K_SRP "SRP", ssl_kea_srp
++#define K_SRP_RSA "SRP_RSA", ssl_kea_srp_rsa
++#define K_SRP_DSS "SRP_DSS", ssl_kea_srp_dss
+
+ #define C_SEED "SEED", calg_seed
+ #define C_CAMELLIA "CAMELLIA", calg_camellia
+@@ -201,6 +225,17 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
+ {0,CS(SSL_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
+ {0,CS(SSL_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
+
++/* SRP cipher suites */
++{0,CS(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA), S_KEA, K_SRP, C_3DES,B_3DES,M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA), S_KEA, K_SRP_RSA, C_3DES,B_3DES,M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA), S_KEA, K_SRP_DSS, C_3DES,B_3DES,M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_WITH_AES_128_CBC_SHA), S_KEA, K_SRP, C_AES, B_128, M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA), S_KEA, K_SRP_RSA, C_AES, B_128, M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA), S_KEA, K_SRP_DSS, C_AES, B_128, M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_WITH_AES_256_CBC_SHA), S_KEA, K_SRP, C_AES, B_256, M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA), S_KEA, K_SRP_RSA, C_AES, B_256, M_SHA, 0, 0, 0, },
++{0,CS(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA), S_KEA, K_SRP_DSS, C_AES, B_256, M_SHA, 0, 0, 0, },
++
+ #ifdef NSS_ENABLE_ECC
+ /* ECC cipher suites */
+ {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
+diff --git a/mozilla/security/nss/lib/ssl/sslproto.h b/mozilla/security/nss/lib/ssl/sslproto.h
+index b534d0b..cbf6250 100644
+--- a/mozilla/security/nss/lib/ssl/sslproto.h
++++ b/mozilla/security/nss/lib/ssl/sslproto.h
+@@ -220,6 +220,16 @@
+ #define TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018
+ #define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019
+
++#define TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0xC01A
++#define TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0xC01B
++#define TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0xC01C
++#define TLS_SRP_SHA_WITH_AES_128_CBC_SHA 0xC01D
++#define TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0xC01E
++#define TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0xC01F
++#define TLS_SRP_SHA_WITH_AES_256_CBC_SHA 0xC020
++#define TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0xC021
++#define TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0xC022
++
+ /* Netscape "experimental" cipher suites. */
+ #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
+ #define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
+diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/ssl/sslsecur.c
+index 49a81bc..fe1465d 100644
+--- a/mozilla/security/nss/lib/ssl/sslsecur.c
++++ b/mozilla/security/nss/lib/ssl/sslsecur.c
+@@ -902,6 +902,14 @@ ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os)
+ if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data)
+ goto loser;
+
++ SECITEM_CopyItem(0, ss->sec.userName, os->sec.userName);
++ if (os->sec.userName->data && !ss->sec.userName->data)
++ goto loser;
++ SECITEM_CopyItem(0, ss->sec.userPasswd, os->sec.userPasswd);
++ if (os->sec.userPasswd->data && !ss->sec.userPasswd->data)
++ goto loser;
++
++
+ /* XXX following code is wrong if either cx != 0 */
+ PORT_Assert(os->sec.readcx == 0);
+ PORT_Assert(os->sec.writecx == 0);
+@@ -983,6 +991,15 @@ ssl_DestroySecurityInfo(sslSecurityInfo *sec)
+ {
+ ssl_ResetSecurityInfo(sec, PR_FALSE);
+
++ if (sec->userName) {
++ SECITEM_FreeItem(sec->userName, PR_TRUE);
++ sec->userName = NULL;
++ }
++ if (sec->userPasswd) {
++ SECITEM_FreeItem(sec->userPasswd, PR_TRUE);
++ sec->userPasswd = NULL;
++ }
++
+ PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space);
+ sec->writeBuf.buf = 0;
+
+diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c
+index b14a935..18ee612 100644
+--- a/mozilla/security/nss/lib/ssl/sslsock.c
++++ b/mozilla/security/nss/lib/ssl/sslsock.c
+@@ -102,6 +102,15 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */
+ { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
+ { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
+ { TLS_RSA_WITH_SEED_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
++ { TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
+ { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
+ { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
+ #ifdef NSS_ENABLE_ECC
+diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/sslt.h
+index 3fa3f9b..9cb000b 100644
+--- a/mozilla/security/nss/lib/ssl/sslt.h
++++ b/mozilla/security/nss/lib/ssl/sslt.h
+@@ -74,6 +74,9 @@ typedef enum {
+ ssl_kea_dh = 2,
+ ssl_kea_fortezza = 3, /* deprecated, now unused */
+ ssl_kea_ecdh = 4,
++ ssl_kea_srp = 5,
++ ssl_kea_srp_rsa = 6,
++ ssl_kea_srp_dss = 7,
+ ssl_kea_size /* number of ssl_kea_ algorithms */
+ } SSLKEAType;
+
+@@ -88,6 +91,7 @@ typedef enum {
+ #define kt_fortezza ssl_kea_fortezza /* deprecated, now unused */
+ #define kt_ecdh ssl_kea_ecdh
+ #define kt_kea_size ssl_kea_size
++#define kt_srp ssl_kea_srp
+
+ typedef enum {
+ ssl_sign_null = 0,
+@@ -203,13 +207,14 @@ typedef enum {
+ ssl_elliptic_curves_xtn = 10,
+ ssl_ec_point_formats_xtn = 11,
+ #endif
++ ssl_srp_hello_xtn = 12,
+ ssl_session_ticket_xtn = 35,
+ ssl_next_proto_neg_xtn = 13172,
+ ssl_snap_start_xtn = 13174,
+ ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
+ } SSLExtensionType;
+
+-#define SSL_MAX_EXTENSIONS 8
++#define SSL_MAX_EXTENSIONS 9
+
+ typedef enum {
+ /* No Snap Start handshake was attempted. */
« no previous file with comments | « net/third_party/nss/README.chromium ('k') | net/third_party/nss/ssl.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698