OLD | NEW |
(Empty) | |
| 1 diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl
/ssl.def |
| 2 index 76417d0..0af96ba 100644 |
| 3 --- a/mozilla/security/nss/lib/ssl/ssl.def |
| 4 +++ b/mozilla/security/nss/lib/ssl/ssl.def |
| 5 @@ -136,6 +136,10 @@ SSL_ReHandshakeWithTimeout; |
| 6 ;+NSS_3.11.8 { # NSS 3.11.8 release |
| 7 ;+ global: |
| 8 SSL_CanBypass; |
| 9 + |
| 10 +SSL_SetUserLogin; |
| 11 +SSL_UserPasswdHook; |
| 12 +SSL_GetSRPParamsHook; |
| 13 ;+ local: |
| 14 ;+*; |
| 15 ;+}; |
| 16 diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/s
sl.h |
| 17 index 21d7c8d..5906ca9 100644 |
| 18 --- a/mozilla/security/nss/lib/ssl/ssl.h |
| 19 +++ b/mozilla/security/nss/lib/ssl/ssl.h |
| 20 @@ -437,6 +437,43 @@ SSL_IMPORT PRFileDesc *SSL_ReconfigFD(PRFileDesc *model, PR
FileDesc *fd); |
| 21 */ |
| 22 SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a); |
| 23 |
| 24 + |
| 25 +/* |
| 26 + * Set the client side user name and password non-interactively. |
| 27 + */ |
| 28 +SSL_IMPORT SECStatus SSL_SetUserLogin(PRFileDesc *fd, |
| 29 + const char *u, |
| 30 + const char *p); |
| 31 + |
| 32 +/* |
| 33 + * This sets the client side callback for SSL to retrieve the user password. |
| 34 + * fd - the file descriptor for the connection in question |
| 35 + * func - callback function pointer |
| 36 + * pw - user password |
| 37 + */ |
| 38 + |
| 39 +typedef SECStatus (PR_CALLBACK *SSLUserPasswdCB)(PRFileDesc *fd, |
| 40 + SECItem *pw, void *arg); |
| 41 + |
| 42 +SSL_IMPORT SECStatus SSL_UserPasswdHook(PRFileDesc *fd, SSLUserPasswdCB func, |
| 43 + void *arg); |
| 44 + |
| 45 +/* |
| 46 + * This sets the server side callback function for SSL to retrieve the SRP |
| 47 + * authentication parameters associated with a specific user login. |
| 48 + * fd - the file descriptor of the connection |
| 49 + * func - pointer to the callback function |
| 50 + * user - username to lookup in app database |
| 51 + * srp - SRP auth paramters supplied to SSL by app |
| 52 + */ |
| 53 + |
| 54 +typedef SECStatus (PR_CALLBACK *SSLGetSRPParamsCB)(PRFileDesc *fd, |
| 55 + SECKEYSRPParams *srp, |
| 56 + void *arg); |
| 57 + |
| 58 +SSL_IMPORT SECStatus SSL_GetSRPParamsHook(PRFileDesc *fd, |
| 59 + SSLGetSRPParamsCB func, void *arg); |
| 60 + |
| 61 /* |
| 62 ** This is a callback for dealing with server certs that are not authenticated |
| 63 ** by the client. The client app can decide that it actually likes the |
| 64 @@ -703,6 +740,7 @@ SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void); |
| 65 /* Report more information than SSL_SecurityStatus. |
| 66 ** Caller supplies the info struct. Function fills it in. |
| 67 */ |
| 68 +SSL_IMPORT SECStatus SSL_GetChannelUsername(PRFileDesc *fd, SECItem *user); |
| 69 SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, |
| 70 PRUintn len); |
| 71 SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, |
| 72 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s
sl/ssl3con.c |
| 73 index f5c0880..21caea4 100644 |
| 74 --- a/mozilla/security/nss/lib/ssl/ssl3con.c |
| 75 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c |
| 76 @@ -118,6 +118,9 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEME
NTED] = { |
| 77 #endif /* NSS_ENABLE_ECC */ |
| 78 { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_
FALSE}, |
| 79 { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 80 + { TLS_SRP_SHA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 81 + { TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 82 + { TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 83 |
| 84 #ifdef NSS_ENABLE_ECC |
| 85 { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 86 @@ -141,11 +144,15 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLE
MENTED] = { |
| 87 { SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, |
| 88 { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 89 { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 90 + { TLS_SRP_SHA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 91 + { TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 92 + { TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 93 |
| 94 #ifdef NSS_ENABLE_ECC |
| 95 { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 96 { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 97 #endif /* NSS_ENABLE_ECC */ |
| 98 + { TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 99 { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 100 { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 101 #ifdef NSS_ENABLE_ECC |
| 102 @@ -154,6 +161,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEME
NTED] = { |
| 103 #endif /* NSS_ENABLE_ECC */ |
| 104 { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, |
| 105 { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, |
| 106 + { TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 107 + { TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 108 |
| 109 |
| 110 { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
| 111 @@ -283,6 +292,9 @@ static const ssl3KEADef kea_defs[] = |
| 112 {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE}, |
| 113 {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE}, |
| 114 {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE }, |
| 115 + {kea_srp, kt_srp, sign_null, PR_FALSE, 0, PR_FALSE}, |
| 116 + {kea_srp_rsa, kt_srp, sign_rsa, PR_FALSE, 0, PR_FALSE}, |
| 117 + {kea_srp_dss, kt_srp, sign_dsa, PR_FALSE, 0, PR_FALSE}, |
| 118 #ifdef NSS_ENABLE_ECC |
| 119 {kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE}, |
| 120 {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE}, |
| 121 @@ -344,6 +356,21 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = |
| 122 |
| 123 |
| 124 /* New TLS cipher suites */ |
| 125 + {TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_srp}, |
| 126 + {TLS_SRP_SHA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_srp}, |
| 127 + {TLS_SRP_SHA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_srp}, |
| 128 + {TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, |
| 129 + cipher_3des, mac_sha, kea_srp_rsa}, |
| 130 + {TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, |
| 131 + cipher_3des, mac_sha, kea_srp_dss}, |
| 132 + {TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, |
| 133 + cipher_aes_128, mac_sha, kea_srp_rsa}, |
| 134 + {TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, |
| 135 + cipher_aes_128, mac_sha, kea_srp_dss}, |
| 136 + {TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, |
| 137 + cipher_aes_256, mac_sha, kea_srp_rsa}, |
| 138 + {TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, |
| 139 + cipher_aes_256, mac_sha, kea_srp_dss}, |
| 140 {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa
}, |
| 141 {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe
_dss}, |
| 142 {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe
_rsa}, |
| 143 @@ -420,7 +447,8 @@ static const CK_MECHANISM_TYPE kea_alg_defs[] = { |
| 144 CKM_RSA_PKCS, |
| 145 CKM_DH_PKCS_DERIVE, |
| 146 CKM_KEA_KEY_DERIVE, |
| 147 - CKM_ECDH1_DERIVE |
| 148 + CKM_ECDH1_DERIVE, |
| 149 + CKM_NSS_SRP_DERIVE |
| 150 }; |
| 151 |
| 152 typedef struct SSLCipher2MechStr { |
| 153 @@ -695,12 +723,27 @@ ssl3_config_match_init(sslSocket *ss) |
| 154 } |
| 155 #endif /* NSS_ENABLE_ECC */ |
| 156 |
| 157 + /* XXX this should be merged with switch(kea) from above */ |
| 158 + switch (cipher_def->key_exchange_alg) { |
| 159 + case kea_srp_rsa: |
| 160 + svrAuth = ss->serverCerts + kt_rsa; |
| 161 + break; |
| 162 + case kea_srp_dss: |
| 163 + svrAuth = ss->serverCerts + kt_null; /* don't ask me..*/ |
| 164 + break; |
| 165 + default: |
| 166 + svrAuth = ss->serverCerts + exchKeyType; |
| 167 + break; |
| 168 + } |
| 169 + |
| 170 + |
| 171 /* Mark the suites that are backed by real tokens, certs and keys */ |
| 172 suite->isPresent = (PRBool) |
| 173 (((exchKeyType == kt_null) || |
| 174 ((!isServer || (svrAuth->serverKeyPair && |
| 175 svrAuth->SERVERKEY && |
| 176 - svrAuth->serverCertChain)) && |
| 177 + svrAuth->serverCertChain) || |
| 178 + cipher_def->key_exchange_alg == kea_srp) && |
| 179 PK11_TokenExists(kea_alg_defs[exchKeyType]))) && |
| 180 ((cipher_alg == calg_null) || PK11_TokenExists(cipher_mech))); |
| 181 if (suite->isPresent) |
| 182 @@ -1080,6 +1123,57 @@ ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem pub
licExponent, |
| 183 return rv; |
| 184 } |
| 185 |
| 186 +/* Caller must set hiLevel error code. |
| 187 + * Called from ssl3_SendSRPServerKeyExchange */ |
| 188 +static SECStatus |
| 189 +ssl3_ComputeSRPKeyHash(SECItem *N, SECItem *g, SECItem *s, SECItem *B, |
| 190 + SSL3Random *client_rand, SSL3Random *server_rand, |
| 191 + SSL3Hashes *hashes, PRBool bypassPKCS11) |
| 192 +{ |
| 193 + PRUint8 * hashBuf; |
| 194 + PRUint8 * pBuf; |
| 195 + SECStatus rv = SECFailure; |
| 196 + unsigned int bufLen; |
| 197 + |
| 198 + bufLen = 2*SSL3_RANDOM_LENGTH + N->len + 2 + g->len + 2 |
| 199 + + s->len + 1 + B->len + 2; |
| 200 + |
| 201 + hashBuf = PORT_Alloc(bufLen); |
| 202 + if (!hashBuf) { |
| 203 + return SECFailure; |
| 204 + } |
| 205 + |
| 206 + memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); |
| 207 + pBuf = hashBuf + SSL3_RANDOM_LENGTH; |
| 208 + memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH); |
| 209 + pBuf += SSL3_RANDOM_LENGTH; |
| 210 + pBuf[0] = (PRUint8)(N->len >> 8); |
| 211 + pBuf[1] = (PRUint8)(N->len); |
| 212 + pBuf+=2; |
| 213 + memcpy(pBuf, N->data, N->len); |
| 214 + pBuf += N->len; |
| 215 + pBuf[0] = (PRUint8)(g->len >> 8); |
| 216 + pBuf[1] = (PRUint8)(g->len); |
| 217 + pBuf+=2; |
| 218 + memcpy(pBuf, g->data, g->len); |
| 219 + pBuf += g->len; |
| 220 + pBuf[0] = (PRUint8)(s->len); |
| 221 + pBuf+=1; |
| 222 + memcpy(pBuf, s->data, s->len); |
| 223 + pBuf += s->len; |
| 224 + pBuf[0] = (PRUint8)(B->len >> 8); |
| 225 + pBuf[1] = (PRUint8)(B->len); |
| 226 + pBuf+=2; |
| 227 + memcpy(pBuf, B->data, B->len); |
| 228 + pBuf += B->len; |
| 229 + |
| 230 + rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11); |
| 231 + |
| 232 + if (hashBuf) |
| 233 + PORT_Free(hashBuf); |
| 234 + return rv; |
| 235 +} |
| 236 + |
| 237 /* Caller must set hiLevel error code. */ |
| 238 /* Called from ssl3_HandleServerKeyExchange. */ |
| 239 static SECStatus |
| 240 @@ -2663,6 +2757,8 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) |
| 241 error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break; |
| 242 case bad_certificate_hash_value: |
| 243 error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break; |
| 244 + case unknown_psk_identity: |
| 245 + error = SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT; break; |
| 246 default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; |
| 247 } |
| 248 if (level == alert_fatal) { |
| 249 @@ -2828,7 +2924,8 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) |
| 250 * data into a 48-byte value. |
| 251 */ |
| 252 PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) || |
| 253 - (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh)); |
| 254 + (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh) || |
| 255 + (ss->ssl3.hs.kea_def->exchKeyType == kt_srp)); |
| 256 SECStatus rv = SECFailure; |
| 257 CK_MECHANISM_TYPE master_derive; |
| 258 CK_MECHANISM_TYPE key_derive; |
| 259 @@ -4733,8 +4830,241 @@ loser: |
| 260 return rv; |
| 261 } |
| 262 |
| 263 +/* Read srp values from datastream and verify the signature |
| 264 + * if requiried by cipher. Save parameters to ss->sec.peerKey. |
| 265 + * |
| 266 + * called from ssl3_HandleServerKeyExchange |
| 267 + */ |
| 268 +static SECStatus |
| 269 +ssl3_HandleSRPServerKeyExchange(sslSocket *ss, SSL3Opaque *b, |
| 270 + PRUint32 length) { |
| 271 + |
| 272 + SECItem signature = {siBuffer, NULL, 0}; |
| 273 + PRArenaPool *arena = NULL; |
| 274 + SECKEYPublicKey *peerKey = NULL; |
| 275 + SECStatus rv; |
| 276 + SSL3Hashes hashes; |
| 277 + SECItem srp_N, srp_g, srp_s, srp_ppub; |
| 278 + int errCode; |
| 279 + |
| 280 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_N, 2, &b, &length); |
| 281 + if (rv != SECSuccess) { |
| 282 + goto loser; /* malformed. */ |
| 283 + } |
| 284 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_g, 2, &b, &length); |
| 285 + if (rv != SECSuccess) { |
| 286 + goto loser; /* malformed. */ |
| 287 + } |
| 288 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_s, 1, &b, &length); |
| 289 + if (rv != SECSuccess) { |
| 290 + goto loser; /* malformed. */ |
| 291 + } |
| 292 + rv = ssl3_ConsumeHandshakeVariable(ss, &srp_ppub, 2, &b, &length); |
| 293 + if (rv != SECSuccess) { |
| 294 + goto loser; /* malformed. */ |
| 295 + } |
| 296 + |
| 297 + if (ss->ssl3.hs.kea_def->kea != kea_srp) { /* there MUST be a signature */ |
| 298 + rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
| 299 + if (rv != SECSuccess) { |
| 300 + goto loser; /* malformed. */ |
| 301 + } |
| 302 + rv = ssl3_ComputeSRPKeyHash(&srp_N, &srp_g, &srp_s, &srp_ppub, |
| 303 + &ss->ssl3.hs.client_random, |
| 304 + &ss->ssl3.hs.server_random, |
| 305 + &hashes, ss->opt.bypassPKCS11); |
| 306 + if (rv != SECSuccess) { |
| 307 + errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
); |
| 308 + goto alert_loser; |
| 309 + } |
| 310 + rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, |
| 311 + PR_TRUE, ss->pkcs11P
inArg); |
| 312 + if (rv != SECSuccess) { |
| 313 + errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
); |
| 314 + goto alert_loser; |
| 315 + } |
| 316 + } |
| 317 + |
| 318 + /* all ok, save and return */ |
| 319 + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 320 + if (arena == NULL) { |
| 321 + return SECFailure; |
| 322 + } |
| 323 + ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); |
| 324 + if (peerKey == NULL) { |
| 325 + return SECFailure; |
| 326 + } |
| 327 + peerKey->arena = arena; |
| 328 + peerKey->keyType = srpKey; |
| 329 + peerKey->pkcs11Slot = NULL; |
| 330 + peerKey->pkcs11ID = CK_INVALID_HANDLE; |
| 331 + |
| 332 + if (SECITEM_CopyItem(arena, &peerKey->u.srp.N, &srp_N) || |
| 333 + SECITEM_CopyItem(arena, &peerKey->u.srp.g, &srp_g) || |
| 334 + SECITEM_CopyItem(arena, &peerKey->u.srp.s, &srp_s) || |
| 335 + SECITEM_CopyItem(arena, &peerKey->u.srp.ppub, &srp_ppub)) { |
| 336 + return SECFailure; |
| 337 + } |
| 338 + return SECSuccess; |
| 339 + |
| 340 +alert_loser: |
| 341 + (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
| 342 +loser: |
| 343 + PORT_SetError(errCode); |
| 344 + return SECFailure; |
| 345 +} |
| 346 + |
| 347 +/* Calculate ClientKeyExchange and Pre-Master-Secret via SRP_GenKeys(), |
| 348 + * then send ClientKeyExchange and derive SSL master key |
| 349 + * |
| 350 + * called from ssl3_SendClientKeyExchange() |
| 351 + */ |
| 352 +static SECStatus |
| 353 +ssl3_SendSRPClientKeyExchange(sslSocket *ss, SECKEYPublicKey * pubKey) { |
| 354 + |
| 355 + SECKEYSRPParams *srpParam; |
| 356 + SECStatus rv; |
| 357 + |
| 358 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 359 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 360 + |
| 361 + srpParam = PORT_ZAlloc(sizeof(SECKEYSRPParams)); |
| 362 + if (!srpParam) { |
| 363 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 364 + goto loser; |
| 365 + } |
| 366 + |
| 367 + /* PW-Callback overrides SSL_SetUserLogin. If both fail to |
| 368 + * provide a password, the token must know it or fail. */ |
| 369 + if (ss->getUserPasswd) { |
| 370 + if (!ss->sec.userPasswd) |
| 371 + ss->sec.userPasswd = SECITEM_AllocItem(NULL,NULL,0); |
| 372 + SECITEM_FreeItem(ss->sec.userPasswd, PR_FALSE); |
| 373 + ss->getUserPasswd(ss->fd, ss->sec.userPasswd, ss->getUserPasswdArg); |
| 374 + } |
| 375 + if (ss->sec.userPasswd) { |
| 376 + srpParam->secret.data = ss->sec.userPasswd->data; |
| 377 + srpParam->secret.len = ss->sec.userPasswd->len; |
| 378 + ss->sec.userPasswd = NULL; |
| 379 + } |
| 380 |
| 381 + /* calculate client key pair and PMS, then send key exchange data */ |
| 382 + if (ss->opt.bypassPKCS11) { |
| 383 + SECItem pms = {0, NULL, 0}; |
| 384 + SRPPrivateKey *prvKey; |
| 385 + SRPKeyPairParams keyPairParam; |
| 386 + keyPairParam.N.data = pubKey->u.srp.N.data; |
| 387 + keyPairParam.N.len = pubKey->u.srp.N.len; |
| 388 + keyPairParam.g.data = pubKey->u.srp.g.data; |
| 389 + keyPairParam.g.len = pubKey->u.srp.g.len; |
| 390 + keyPairParam.secret.data = srpParam->secret.data; |
| 391 + keyPairParam.secret.len = srpParam->secret.len; |
| 392 + |
| 393 + rv = SRP_NewClientKeyPair(&prvKey, &keyPairParam); |
| 394 + if (rv != SECSuccess) goto loser; /* err set by SRP_ClientDerive */ |
| 395 + |
| 396 + SRPDeriveParams deriveParam; |
| 397 + deriveParam.N.data = pubKey->u.srp.N.data; |
| 398 + deriveParam.N.len = pubKey->u.srp.N.len; |
| 399 + deriveParam.g.data = pubKey->u.srp.g.data; |
| 400 + deriveParam.g.len = pubKey->u.srp.g.len; |
| 401 + deriveParam.s.data = pubKey->u.srp.s.data; |
| 402 + deriveParam.s.len = pubKey->u.srp.s.len; |
| 403 + deriveParam.u.data = ss->sec.userName->data; |
| 404 + deriveParam.u.len = ss->sec.userName->len; |
| 405 + deriveParam.ppub.data= pubKey->u.srp.ppub.data; |
| 406 + deriveParam.ppub.len = pubKey->u.srp.ppub.len; |
| 407 + |
| 408 + |
| 409 + if (SECSuccess != SRP_ClientDerive(prvKey, &deriveParam, &pms)) { |
| 410 + goto derive_fail; |
| 411 + } |
| 412 + |
| 413 + /* client key exchange data */ |
| 414 + rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, |
| 415 + prvKey->pubKey.len + 2); |
| 416 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* *
/ |
| 417 + rv = ssl3_AppendHandshakeVariable(ss, prvKey->pubKey.data, |
| 418 + prvKey->pubKey.len, 2); |
| 419 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* *
/ |
| 420 + |
| 421 + /* init pending cipher spec*/ |
| 422 + rv = ssl3_MasterKeyDeriveBypass(ss->ssl3.pwSpec, |
| 423 + (unsigned char *)&ss->ssl3.hs.client_random, |
| 424 + (unsigned char *)&ss->ssl3.hs.server_random, |
| 425 + &pms, PR_TRUE, PR_FALSE); |
| 426 + if (rv != SECSuccess) { |
| 427 + ss->ssl3.pwSpec->msItem.data = ss->ssl3.pwSpec->raw_master_secret; |
| 428 + ss->ssl3.pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; |
| 429 + PK11_GenerateRandom(ss->ssl3.pwSpec->msItem.data, |
| 430 + SSL3_MASTER_SECRET_LENGTH); |
| 431 + } |
| 432 + rv = ssl3_InitPendingCipherSpec(ss, NULL); |
| 433 + |
| 434 + SECITEM_FreeItem(&pms, PR_FALSE); |
| 435 + PORT_FreeArena(prvKey->arena, PR_TRUE); |
| 436 + } else { /* PK11 path */ |
| 437 + PK11SymKey *pms = NULL; |
| 438 + SECKEYPrivateKey *prvKey = NULL; |
| 439 + SECKEYPublicKey *newPub = NULL; |
| 440 + |
| 441 + srpParam->N.data = pubKey->u.srp.N.data; |
| 442 + srpParam->N.len = pubKey->u.srp.N.len; |
| 443 + srpParam->g.data = pubKey->u.srp.g.data; |
| 444 + srpParam->g.len = pubKey->u.srp.g.len; |
| 445 + srpParam->s.data = pubKey->u.srp.s.data; |
| 446 + srpParam->s.len = pubKey->u.srp.s.len; |
| 447 + srpParam->u.data = ss->sec.userName->data; |
| 448 + srpParam->u.len = ss->sec.userName->len; |
| 449 + |
| 450 + /* The token handles (missing) info supplied in srpParam |
| 451 + * The template not actually involved in key generation, |
| 452 + * but it's important in the server key exchange */ |
| 453 + |
| 454 + prvKey = SECKEY_CreateSRPPrivateKey(srpParam, &newPub, PR_FALSE, NULL); |
| 455 + if (!prvKey) { |
| 456 + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
| 457 + rv = SECFailure; |
| 458 + goto loser; |
| 459 + } |
| 460 + SECITEM_CopyItem(newPub->arena, &newPub->u.srp.ppub, &pubKey->u.srp.ppu
b); |
| 461 + |
| 462 + /* Now all data is in newPub and prvKey, compute pms with them */ |
| 463 + pms = PK11_PubDerive(prvKey, newPub, PR_FALSE, NULL, NULL, |
| 464 + CKM_NSS_SRP_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, CKF_D
ERIVE, 0, NULL); |
| 465 |
| 466 + if (!pms) { |
| 467 + goto derive_fail; |
| 468 + } |
| 469 + |
| 470 + /* init pending cipher spec*/ |
| 471 + rv = ssl3_InitPendingCipherSpec(ss, pms); |
| 472 + |
| 473 + |
| 474 + /* client key exchange data */ |
| 475 + rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, |
| 476 + newPub->u.srp.pub.len + 2); |
| 477 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* *
/ |
| 478 + rv = ssl3_AppendHandshakeVariable(ss, newPub->u.srp.pub.data, |
| 479 + newPub->u.srp.pub.len, 2); |
| 480 + if (rv != SECSuccess) goto loser; /* err set by ssl3_AppendHandshake* *
/ |
| 481 + |
| 482 + if (pms) PK11_FreeSymKey(pms); |
| 483 + SECKEY_DestroyPublicKey(newPub); |
| 484 + } /* end of PK11 path */ |
| 485 + |
| 486 +loser: |
| 487 + SECITEM_ZfreeItem(ss->sec.userPasswd, PR_TRUE); |
| 488 + PORT_Free(srpParam); |
| 489 + /* caller frees pubKey */ |
| 490 + return rv; |
| 491 +derive_fail: |
| 492 + if (PORT_GetError() == SEC_ERROR_SRP_UNSUPPORTED_GROUP) |
| 493 + SSL3_SendAlert(ss, alert_fatal, insufficient_security); |
| 494 + if (PORT_GetError() == SEC_ERROR_SRP_ILLEGAL_PARAMETER) |
| 495 + SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
| 496 + return SECFailure; |
| 497 +} |
| 498 |
| 499 |
| 500 /* Called from ssl3_HandleServerHelloDone(). */ |
| 501 @@ -4794,7 +5124,9 @@ ssl3_SendClientKeyExchange(sslSocket *ss) |
| 502 rv = ssl3_SendECDHClientKeyExchange(ss, serverKey); |
| 503 break; |
| 504 #endif /* NSS_ENABLE_ECC */ |
| 505 - |
| 506 + case kt_srp: |
| 507 + rv = ssl3_SendSRPClientKeyExchange(ss, serverKey); |
| 508 + break; |
| 509 default: |
| 510 /* got an unknown or unsupported Key Exchange Algorithm. */ |
| 511 SEND_ALERT |
| 512 @@ -5284,7 +5616,8 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b,
PRUint32 length) |
| 513 desc = unexpected_message; |
| 514 goto alert_loser; |
| 515 } |
| 516 - if (ss->sec.peerCert == NULL) { |
| 517 + if (ss->sec.peerCert == NULL && |
| 518 + ss->ssl3.hs.suite_def->key_exchange_alg != kea_srp) { |
| 519 errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH; |
| 520 desc = unexpected_message; |
| 521 goto alert_loser; |
| 522 @@ -5473,6 +5806,13 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b
, PRUint32 length) |
| 523 rv = ssl3_HandleECDHServerKeyExchange(ss, b, length); |
| 524 return rv; |
| 525 #endif /* NSS_ENABLE_ECC */ |
| 526 + case kt_srp: |
| 527 + rv = ssl3_HandleSRPServerKeyExchange(ss, b, length); |
| 528 + if (rv != SECSuccess) { |
| 529 + errCode = ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
); |
| 530 + goto alert_loser; |
| 531 + } |
| 532 + return rv; |
| 533 |
| 534 default: |
| 535 desc = handshake_failure; |
| 536 @@ -6034,16 +6374,20 @@ ssl3_SendServerHelloSequence(sslSocket *ss) |
| 537 if (rv != SECSuccess) { |
| 538 return rv; /* err code is set. */ |
| 539 } |
| 540 - rv = ssl3_SendCertificate(ss); |
| 541 - if (rv != SECSuccess) { |
| 542 - return rv; /* error code is set. */ |
| 543 - } |
| 544 /* We have to do this after the call to ssl3_SendServerHello, |
| 545 * because kea_def is set up by ssl3_SendServerHello(). |
| 546 */ |
| 547 kea_def = ss->ssl3.hs.kea_def; |
| 548 ss->ssl3.hs.usedStepDownKey = PR_FALSE; |
| 549 |
| 550 + |
| 551 + if (kea_def->kea != kea_srp) { /* SRP auth only */ |
| 552 + rv = ssl3_SendCertificate(ss); |
| 553 + if (rv != SECSuccess) { |
| 554 + return rv; /* error code is set. */ |
| 555 + } |
| 556 + } |
| 557 + |
| 558 if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) { |
| 559 /* see if we can legally use the key in the cert. */ |
| 560 int keyLen; /* bytes */ |
| 561 @@ -6075,6 +6419,11 @@ ssl3_SendServerHelloSequence(sslSocket *ss) |
| 562 return rv; /* err code was set. */ |
| 563 } |
| 564 #endif /* NSS_ENABLE_ECC */ |
| 565 + } else if ( kea_def->exchKeyType == kt_srp ) { |
| 566 + rv = ssl3_SendServerKeyExchange(ss); |
| 567 + if (rv != SECSuccess) { |
| 568 + return rv; /* err code was set. */ |
| 569 + } |
| 570 } |
| 571 |
| 572 if (ss->opt.requestCertificate) { |
| 573 @@ -7099,6 +7448,195 @@ ssl3_SendServerHello(sslSocket *ss) |
| 574 return SECSuccess; |
| 575 } |
| 576 |
| 577 +/* ssl3_SendSRPServerKeyExchange() |
| 578 + * called by ssl3_SendServerKeyExchange() |
| 579 + * |
| 580 + * - make sure we got a userid in the srp client hello extension |
| 581 + * - retrieve verifier and parameters for the user via callback func |
| 582 + * - if user nonexistant, CB makes something up if it wants to |
| 583 + * - continue by creating and sending the SRP key exchange data: |
| 584 + * |
| 585 + * N, g, s, v = <read from password file> |
| 586 + * b = random() |
| 587 + * k = SHA1(N | PAD(g)) |
| 588 + * B = k*v + g^b % N |
| 589 + * send (N,g,s,B) |
| 590 + * |
| 591 + * save values b,v,N for calculation of pms in ssl3_HandleSRPClientKeyExchange |
| 592 + */ |
| 593 + |
| 594 +SECStatus |
| 595 +ssl3_SendSRPServerKeyExchange(sslSocket *ss) { |
| 596 + |
| 597 + int bytes = 0; |
| 598 + const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def; |
| 599 + SECItem signed_hash = {siBuffer, NULL, 0}; |
| 600 + SECStatus rv = SECFailure; |
| 601 + SECKEYSRPPublicKey *srp = NULL; |
| 602 + SECKEYPublicKey *pubKey = NULL; |
| 603 + SECKEYPrivateKey *prvKey = NULL; |
| 604 + SECKEYSRPParams *srpParams; |
| 605 + SSL3Hashes hashes; |
| 606 + |
| 607 + /* send error if no userid was supplied in Client Hello */ |
| 608 + if (!ss->sec.userName || !ss->sec.userName->data) |
| 609 + goto unknown_id; |
| 610 + |
| 611 + /* Ask application for SRP parameters for specified username. |
| 612 + * Information provided via callback overrides data set on token. |
| 613 + * If no params provided, the token must supply them or fail. |
| 614 + * Callback may fail for nonexistant user. |
| 615 + */ |
| 616 + |
| 617 + srpParams = PORT_ZAlloc(sizeof(SECKEYSRPParams)); |
| 618 + if (!srpParams) goto no_memory; |
| 619 + |
| 620 + srpParams->u.data = ss->sec.userName->data; |
| 621 + srpParams->u.len = ss->sec.userName->len; |
| 622 + |
| 623 + if (ss->getSRPParams) { |
| 624 + rv = ss->getSRPParams(ss->fd, srpParams, ss->getSRPParamsArg); |
| 625 + if (rv != SECSuccess) { |
| 626 + SECITEM_FreeItem(&srpParams->N, PR_FALSE); |
| 627 + SECITEM_FreeItem(&srpParams->g, PR_FALSE); |
| 628 + SECITEM_FreeItem(&srpParams->s, PR_FALSE); |
| 629 + SECITEM_ZfreeItem(&srpParams->secret, PR_FALSE); |
| 630 + PORT_Free(srpParams); |
| 631 + goto unknown_id; |
| 632 + } |
| 633 + } |
| 634 + |
| 635 + /* create SRP server key pair */ |
| 636 + if (ss->opt.bypassPKCS11) { |
| 637 + /* srpParams, keyPairParams are temporary. pubKey and prvKey have |
| 638 + * own arenas and are saved for ssl3_HandleSRPClientKeyExchange */ |
| 639 + SRPPrivateKey *srpPrv; |
| 640 + SRPKeyPairParams keyPairParams; |
| 641 + |
| 642 + PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 643 + if (!arena) goto no_memory; |
| 644 + |
| 645 + keyPairParams.N.data = srpParams->N.data; |
| 646 + keyPairParams.N.len = srpParams->N.len; |
| 647 + keyPairParams.g.data = srpParams->g.data; |
| 648 + keyPairParams.g.len = srpParams->g.len; |
| 649 + keyPairParams.secret.data = srpParams->secret.data; |
| 650 + keyPairParams.secret.len = srpParams->secret.len; |
| 651 + |
| 652 + rv = SRP_NewServerKeyPair(&srpPrv, &keyPairParams); |
| 653 + if (rv != SECSuccess) { |
| 654 + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
| 655 + return rv; |
| 656 + } |
| 657 + prvKey = (SECKEYPrivateKey *)srpPrv; |
| 658 + |
| 659 + /* create pubKey from temporary stuff */ |
| 660 + pubKey = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); |
| 661 + if (!pubKey) goto no_memory; |
| 662 + pubKey->arena = arena; |
| 663 + srp = &pubKey->u.srp; |
| 664 + |
| 665 + SECITEM_CopyItem(arena, &srp->N, &srpParams->N); |
| 666 + SECITEM_CopyItem(arena, &srp->g, &srpParams->g); |
| 667 + SECITEM_CopyItem(arena, &srp->s, &srpParams->s); |
| 668 + SECITEM_CopyItem(arena, &srp->u, &srpParams->u); |
| 669 + SECITEM_CopyItem(arena, &srp->pub, &srpPrv->pubKey); |
| 670 + |
| 671 + } else { |
| 672 + |
| 673 + /* input: srpParams, output: prvKey = b,B,v, pubKey = N,g,s,u,B */ |
| 674 + prvKey = SECKEY_CreateSRPPrivateKey(srpParams, &pubKey, PR_TRUE, NULL); |
| 675 + if (!prvKey) { |
| 676 + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
| 677 + rv = SECFailure; |
| 678 + goto cleanup; |
| 679 + } |
| 680 + srp = &pubKey->u.srp; |
| 681 + } |
| 682 + |
| 683 + /* send N,g,s,B as ServerKeyExchange to Client */ |
| 684 + /* optionally include signature for additional DSS/RSA auth */ |
| 685 + |
| 686 + if (kea_def->kea != kea_srp) { /* we need a RSA/DSA signature */ |
| 687 + rv = ssl3_ComputeSRPKeyHash(&srp->N, &srp->g, &srp->s, &srp->pub, |
| 688 + &ss->ssl3.hs.client
_random, |
| 689 + &ss->ssl3.hs.server
_random, |
| 690 + &hashes, ss->opt.by
passPKCS11); |
| 691 + if (rv != SECSuccess) { |
| 692 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 693 + goto loser; |
| 694 + } |
| 695 + /* look if we have a certificate for selected algo */ |
| 696 + if (kea_def->kea == kea_srp_rsa) |
| 697 + bytes = kt_rsa; |
| 698 + else |
| 699 + bytes = kt_null; |
| 700 + |
| 701 + if (!(&ss->serverCerts[bytes])) { |
| 702 + /* ciphersuite signing algo does not match supplied certificate */ |
| 703 + PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH); |
| 704 + return SECFailure; |
| 705 + } |
| 706 + rv = ssl3_SignHashes(&hashes, ss->serverCerts[bytes].SERVERKEY, |
| 707 + &signed_hash, PR_TRUE); |
| 708 + bytes = 2 + signed_hash.len; |
| 709 + } |
| 710 + |
| 711 + bytes += srp->N.len + srp->g.len + srp->s.len + srp->pub.len + 7; |
| 712 + |
| 713 + rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, bytes); |
| 714 + if (rv != SECSuccess) |
| 715 + return rv; /* err set by AppendHandshake. */ |
| 716 + |
| 717 + rv = ssl3_AppendHandshakeVariable(ss, srp->N.data, srp->N.len, 2); |
| 718 + if (rv != SECSuccess) |
| 719 + return rv; /* err set by AppendHandshake. */ |
| 720 + |
| 721 + rv = ssl3_AppendHandshakeVariable(ss, srp->g.data, srp->g.len, 2); |
| 722 + if (rv != SECSuccess) |
| 723 + return rv; /* err set by AppendHandshake. */ |
| 724 + |
| 725 + rv = ssl3_AppendHandshakeVariable(ss, srp->s.data, srp->s.len, 1); |
| 726 + if (rv != SECSuccess) |
| 727 + return rv; /* err set by AppendHandshake. */ |
| 728 + |
| 729 + rv = ssl3_AppendHandshakeVariable(ss, srp->pub.data, srp->pub.len, 2); |
| 730 + if (rv != SECSuccess) |
| 731 + return rv; /* err set by AppendHandshake. */ |
| 732 + |
| 733 + if (kea_def->kea != kea_srp) { |
| 734 + rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, |
| 735 + signed_hash.len, 2); |
| 736 + if (rv != SECSuccess) { |
| 737 + return rv; /* err set by AppendHandshake. */ |
| 738 + } |
| 739 + SECITEM_FreeItem(&signed_hash, PR_FALSE); |
| 740 + } |
| 741 + |
| 742 + /* save prvKey / pubKey for use in HandleSRPClientExchange |
| 743 + * XXX in bypassPK11, prvKey is no PK11 object and must be casted */ |
| 744 + ssl3KeyPair *srpPair = ssl3_NewKeyPair(prvKey, pubKey); |
| 745 + ss->serverCerts[kt_srp].serverKeyPair = srpPair; |
| 746 + |
| 747 +cleanup: |
| 748 + SECITEM_FreeItem(&srpParams->N, PR_FALSE); |
| 749 + SECITEM_FreeItem(&srpParams->g, PR_FALSE); |
| 750 + SECITEM_FreeItem(&srpParams->s, PR_FALSE); |
| 751 + SECITEM_ZfreeItem(&srpParams->secret, PR_FALSE); |
| 752 + if (srpParams) PORT_Free(srpParams); |
| 753 + return rv; |
| 754 +loser: |
| 755 + PORT_SetError(SSL_ERROR_INTERNAL_ERROR_ALERT); |
| 756 + (void)SSL3_SendAlert(ss, alert_fatal, internal_error); |
| 757 + return SECFailure; |
| 758 +unknown_id: |
| 759 + PORT_SetError(SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT); |
| 760 + (void)SSL3_SendAlert(ss, alert_fatal, unknown_psk_identity); |
| 761 + return SECFailure; |
| 762 +no_memory: |
| 763 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 764 + return SECFailure; |
| 765 +} |
| 766 |
| 767 static SECStatus |
| 768 ssl3_SendServerKeyExchange(sslSocket *ss) |
| 769 @@ -7183,7 +7721,9 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
| 770 return rv; |
| 771 } |
| 772 #endif /* NSS_ENABLE_ECC */ |
| 773 - |
| 774 + case kt_srp: |
| 775 + rv = ssl3_SendSRPServerKeyExchange(ss); |
| 776 + return rv; |
| 777 case kt_dh: |
| 778 case kt_null: |
| 779 default: |
| 780 @@ -7536,6 +8076,101 @@ double_bypass: |
| 781 return SECSuccess; |
| 782 } |
| 783 |
| 784 +/* |
| 785 + * extract SRP value A from ClientKeyExchange |
| 786 + * calculate pre-master-secret and init cipher specs |
| 787 + * |
| 788 + * called by ssl3_HandleClientKeyExchange |
| 789 + */ |
| 790 +SECStatus |
| 791 +ssl3_HandleSRPClientKeyExchange(sslSocket *ss, SSL3Opaque *b, |
| 792 + PRUint32 length) { |
| 793 + |
| 794 + SECItem ppub; /* peers public key ('A') */ |
| 795 + sslServerCerts sc; |
| 796 + SECStatus rv = SECFailure; |
| 797 + SECKEYPublicKey *pubKey = NULL; |
| 798 + |
| 799 + |
| 800 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 801 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 802 + |
| 803 + rv = ssl3_ConsumeHandshakeVariable(ss, &ppub, 2, &b, &length); |
| 804 + if (rv != SECSuccess) { |
| 805 + PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
| 806 + return SECFailure; |
| 807 + } |
| 808 + |
| 809 + sc = ss->serverCerts[kt_srp]; |
| 810 + pubKey = sc.serverKeyPair->pubKey; |
| 811 + |
| 812 + SECITEM_CopyItem(pubKey->arena, &pubKey->u.srp.ppub, &ppub); |
| 813 + |
| 814 + if (ss->opt.bypassPKCS11) { |
| 815 + SRPPrivateKey *prvKey = NULL; |
| 816 + SECItem pms = { 0, NULL, 0 }; |
| 817 + SRPDeriveParams param; |
| 818 + |
| 819 + prvKey = (SRPPrivateKey *)sc.serverKeyPair->privKey; |
| 820 + |
| 821 + param.N.data = pubKey->u.srp.N.data; |
| 822 + param.N.len = pubKey->u.srp.N.len; |
| 823 + param.g.data = pubKey->u.srp.g.data; |
| 824 + param.g.len = pubKey->u.srp.g.len; |
| 825 + param.ppub.data = pubKey->u.srp.ppub.data; |
| 826 + param.ppub.len = pubKey->u.srp.ppub.len; |
| 827 + |
| 828 + if (SECSuccess != SRP_ServerDerive(prvKey, ¶m, &pms)) |
| 829 + goto derive_fail; |
| 830 + |
| 831 + ssl_GetSpecWriteLock(ss); |
| 832 + /* create MS out of MS, bypassing PKCS11 */ |
| 833 + rv = ssl3_MasterKeyDeriveBypass(ss->ssl3.pwSpec, |
| 834 + (unsigned char *)&ss->ssl3.hs.client_random, |
| 835 + (unsigned char *)&ss->ssl3.hs.server_random, |
| 836 + &pms, PR_TRUE, PR_FALSE); |
| 837 + if (rv != SECSuccess) { |
| 838 + ss->ssl3.pwSpec->msItem.data = ss->ssl3.pwSpec->raw_master_secret; |
| 839 + ss->ssl3.pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; |
| 840 + PK11_GenerateRandom(ss->ssl3.pwSpec->msItem.data, ss->ssl3.pwSpec->
msItem.len); |
| 841 + } |
| 842 + |
| 843 + rv = ssl3_InitPendingCipherSpec(ss, NULL); |
| 844 + |
| 845 + SECITEM_ZfreeItem(&pms, PR_FALSE); |
| 846 + PORT_FreeArena(prvKey->arena, PR_TRUE); /* XXX FreeArena does not zeroi
ze! */ |
| 847 + sc.serverKeyPair->privKey = NULL; |
| 848 + |
| 849 + } else { |
| 850 + SECKEYPrivateKey *prvKey = NULL; |
| 851 + PK11SymKey *pms = NULL; /* pre-master secret */ |
| 852 + |
| 853 + prvKey = sc.serverKeyPair->privKey; |
| 854 + |
| 855 + /* Calculate PMS based on clntKey and public params */ |
| 856 + pms = PK11_PubDerive(prvKey, pubKey, PR_TRUE, NULL, NULL, |
| 857 + CKM_NSS_SRP_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, CKF_D
ERIVE, 0, NULL); |
| 858 + |
| 859 + if (!pms) { |
| 860 + goto derive_fail; |
| 861 + } |
| 862 + |
| 863 + ssl_GetSpecWriteLock(ss); |
| 864 + /* derive master secret from pms */ |
| 865 + rv = ssl3_InitPendingCipherSpec(ss, pms); |
| 866 + ssl_ReleaseSpecWriteLock(ss); |
| 867 + |
| 868 + PK11_FreeSymKey(pms); |
| 869 + /*SECKEY_DestroyPrivateKey(prvKey);*/ |
| 870 + } |
| 871 + |
| 872 + return rv; |
| 873 +derive_fail: |
| 874 + if (PORT_GetError() == SEC_ERROR_SRP_ILLEGAL_PARAMETER) |
| 875 + SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
| 876 + return rv; |
| 877 +} |
| 878 + |
| 879 |
| 880 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
| 881 * ssl3 ClientKeyExchange message from the remote client |
| 882 @@ -7608,7 +8243,8 @@ skip: |
| 883 serverKey = serverKeyPair->privKey; |
| 884 } |
| 885 |
| 886 - if (serverKey == NULL) { |
| 887 + /* XXX hack, figure out this serverKey thing..*/ |
| 888 + if (serverKey == NULL && kea_def->exchKeyType != kt_srp) { |
| 889 SEND_ALERT |
| 890 PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG); |
| 891 return SECFailure; |
| 892 @@ -7649,7 +8285,12 @@ skip: |
| 893 } |
| 894 break; |
| 895 #endif /* NSS_ENABLE_ECC */ |
| 896 - |
| 897 + case kt_srp: |
| 898 + rv = ssl3_HandleSRPClientKeyExchange(ss, b, length); |
| 899 + if (rv != SECSuccess) { |
| 900 + return SECFailure; /* error code set */ |
| 901 + } |
| 902 + break; |
| 903 default: |
| 904 (void) ssl3_HandshakeFailure(ss); |
| 905 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); |
| 906 @@ -7823,8 +8464,12 @@ ssl3_SendCertificate(sslSocket *ss) |
| 907 * using EC certificates. |
| 908 */ |
| 909 if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) || |
| 910 - (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) { |
| 911 + (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) || |
| 912 + (ss->ssl3.hs.kea_def->kea == kea_srp_rsa)) { |
| 913 certIndex = kt_rsa; |
| 914 + } else if |
| 915 + (ss->ssl3.hs.kea_def->kea == kea_srp_dss) { |
| 916 + certIndex = kt_null; |
| 917 } else { |
| 918 certIndex = ss->ssl3.hs.kea_def->exchKeyType; |
| 919 } |
| 920 @@ -8244,7 +8889,9 @@ cert_block: |
| 921 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || |
| 922 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa || |
| 923 #endif /* NSS_ENABLE_ECC */ |
| 924 - ss->ssl3.hs.kea_def->exchKeyType == kt_dh) { |
| 925 + ss->ssl3.hs.kea_def->exchKeyType == kt_dh || |
| 926 + ss->ssl3.hs.kea_def->kea == kea_srp_dss || |
| 927 + ss->ssl3.hs.kea_def->kea == kea_srp_rsa) { |
| 928 ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */ |
| 929 } |
| 930 } |
| 931 diff --git a/mozilla/security/nss/lib/ssl/ssl3ecc.c b/mozilla/security/nss/lib/s
sl/ssl3ecc.c |
| 932 index 778c7ab..b899038 100644 |
| 933 --- a/mozilla/security/nss/lib/ssl/ssl3ecc.c |
| 934 +++ b/mozilla/security/nss/lib/ssl/ssl3ecc.c |
| 935 @@ -1191,3 +1191,60 @@ loser: |
| 936 } |
| 937 |
| 938 #endif /* NSS_ENABLE_ECC */ |
| 939 + |
| 940 +/* send user mapping indication using info from ss->sec.userlogin |
| 941 + * called from ssl3_CallHelloExtensionSenders */ |
| 942 +PRInt32 |
| 943 +ssl3_SendSRPHelloExtension(sslSocket * ss, PRBool append, |
| 944 + PRUint32 maxBytes) |
| 945 +{ |
| 946 + SECItem * user = ss->sec.userName; |
| 947 + |
| 948 + if (user == NULL) |
| 949 + return 0; /* no credentials, no extension */ |
| 950 + |
| 951 + if (append && maxBytes >= user->len + 5) { |
| 952 + SECStatus rv; |
| 953 + /* extension_type 6 */ |
| 954 + rv = ssl3_AppendHandshakeNumber(ss, 12, 2); |
| 955 + if (rv != SECSuccess) return 0; |
| 956 + /* length of extension */ |
| 957 + rv = ssl3_AppendHandshakeNumber(ss, user->len + 1, 2); |
| 958 + if (rv != SECSuccess) return 0; |
| 959 + /* length of data */ |
| 960 + rv = ssl3_AppendHandshakeNumber(ss, user->len, 1); |
| 961 + if (rv != SECSuccess) return 0; |
| 962 + /* extension_data = srp user name */ |
| 963 + rv = ssl3_AppendHandshake(ss, user->data, user->len); |
| 964 + if (rv != SECSuccess) return 0; |
| 965 + } |
| 966 + return user->len+5; |
| 967 +} |
| 968 + |
| 969 +SECStatus |
| 970 +ssl3_HandleSRPHelloExtension(sslSocket *ss, PRUint16 ext, SECItem *data) |
| 971 +{ |
| 972 + SECStatus rv; |
| 973 + SECItem username; |
| 974 + |
| 975 + rv = ssl3_ConsumeHandshakeVariable(ss, &username, 1, &data->data, &data-
>len); |
| 976 + if (rv != SECSuccess) |
| 977 + return rv; |
| 978 + |
| 979 + /* enforce SRP username length constrain */ |
| 980 + if (data->len > MAX_SRP_USERNAME_LENGTH) |
| 981 + data->len = MAX_SRP_USERNAME_LENGTH; |
| 982 + |
| 983 + ss->sec.userName = PORT_ZAlloc(sizeof(SECItem)); |
| 984 + if (!ss->sec.userName) |
| 985 + goto no_memory; |
| 986 + |
| 987 + rv = SECITEM_CopyItem(NULL, ss->sec.userName, &username); |
| 988 + if (rv != SECSuccess) |
| 989 + goto no_memory; |
| 990 + |
| 991 + return rv; |
| 992 +no_memory: |
| 993 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 994 + return SECFailure; |
| 995 +} |
| 996 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s
sl/ssl3ext.c |
| 997 index b93671e..c2a27b4 100644 |
| 998 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c |
| 999 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c |
| 1000 @@ -78,6 +78,11 @@ static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, |
| 1001 PRBool append, PRUint32 maxBytes); |
| 1002 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, |
| 1003 PRUint16 ex_type, SECItem *data); |
| 1004 +static SECStatus ssl3_HandleSRPHelloXtn(sslSocket *ss, PRUint16 ext, |
| 1005 + SECItem *data); |
| 1006 +PRInt32 ssl3_SendSRPHelloXtn(sslSocket * ss, PRBool append, |
| 1007 + PRUint32 maxBytes); |
| 1008 + |
| 1009 |
| 1010 /* |
| 1011 * Write bytes. Using this function means the SECItem structure |
| 1012 @@ -254,6 +259,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL
S[] = { |
| 1013 |
| 1014 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { |
| 1015 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 1016 + { ssl_srp_hello_xtn, &ssl3_HandleSRPHelloXtn }, |
| 1017 { -1, NULL } |
| 1018 }; |
| 1019 |
| 1020 @@ -272,6 +278,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN
SIONS] = { |
| 1021 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
| 1022 #endif |
| 1023 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, |
| 1024 + { ssl_srp_hello_xtn, &ssl3_SendSRPHelloXtn }, |
| 1025 { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, |
| 1026 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, |
| 1027 { ssl_snap_start_xtn, &ssl3_SendSnapStartXtn } |
| 1028 @@ -1720,3 +1727,59 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 e
x_type, SECItem *data) |
| 1029 return rv; |
| 1030 } |
| 1031 |
| 1032 +/* send user mapping indication using info from ss->sec.userlogin |
| 1033 + * called from ssl3_CallHelloExtensionSenders */ |
| 1034 +PRInt32 |
| 1035 +ssl3_SendSRPHelloXtn(sslSocket * ss, PRBool append, |
| 1036 + PRUint32 maxBytes) |
| 1037 +{ |
| 1038 + SECItem * user = ss->sec.userName; |
| 1039 + |
| 1040 + if (user == NULL) |
| 1041 + return 0; /* no credentials, no extension */ |
| 1042 + |
| 1043 + if (append && maxBytes >= user->len + 5) { |
| 1044 + SECStatus rv; |
| 1045 + /* extension_type 6 */ |
| 1046 + rv = ssl3_AppendHandshakeNumber(ss, 12, 2); |
| 1047 + if (rv != SECSuccess) return 0; |
| 1048 + /* length of extension */ |
| 1049 + rv = ssl3_AppendHandshakeNumber(ss, user->len + 1, 2); |
| 1050 + if (rv != SECSuccess) return 0; |
| 1051 + /* length of data */ |
| 1052 + rv = ssl3_AppendHandshakeNumber(ss, user->len, 1); |
| 1053 + if (rv != SECSuccess) return 0; |
| 1054 + /* extension_data = srp user name */ |
| 1055 + rv = ssl3_AppendHandshake(ss, user->data, user->len); |
| 1056 + if (rv != SECSuccess) return 0; |
| 1057 + } |
| 1058 + return user->len+5; |
| 1059 +} |
| 1060 + |
| 1061 +SECStatus |
| 1062 +ssl3_HandleSRPHelloXtn(sslSocket *ss, PRUint16 ext, SECItem *data) |
| 1063 +{ |
| 1064 + SECStatus rv; |
| 1065 + SECItem username; |
| 1066 + |
| 1067 + rv = ssl3_ConsumeHandshakeVariable(ss, &username, 1, &data->data, &data-
>len); |
| 1068 + if (rv != SECSuccess) |
| 1069 + return rv; |
| 1070 + |
| 1071 + /* enforce SRP username length constrain */ |
| 1072 + if (data->len > MAX_SRP_USERNAME_LENGTH) |
| 1073 + data->len = MAX_SRP_USERNAME_LENGTH; |
| 1074 + |
| 1075 + ss->sec.userName = PORT_ZAlloc(sizeof(SECItem)); |
| 1076 + if (!ss->sec.userName) |
| 1077 + goto no_memory; |
| 1078 + |
| 1079 + rv = SECITEM_CopyItem(NULL, ss->sec.userName, &username); |
| 1080 + if (rv != SECSuccess) |
| 1081 + goto no_memory; |
| 1082 + |
| 1083 + return rv; |
| 1084 +no_memory: |
| 1085 + ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
| 1086 + return SECFailure; |
| 1087 +} |
| 1088 diff --git a/mozilla/security/nss/lib/ssl/ssl3prot.h b/mozilla/security/nss/lib/
ssl/ssl3prot.h |
| 1089 index aeaacdd..a043577 100644 |
| 1090 --- a/mozilla/security/nss/lib/ssl/ssl3prot.h |
| 1091 +++ b/mozilla/security/nss/lib/ssl/ssl3prot.h |
| 1092 @@ -63,6 +63,8 @@ typedef uint16 ssl3CipherSuite; |
| 1093 |
| 1094 #define MAX_FRAGMENT_LENGTH 16384 |
| 1095 |
| 1096 +#define MAX_SRP_USERNAME_LENGTH 255 |
| 1097 + |
| 1098 typedef enum { |
| 1099 content_change_cipher_spec = 20, |
| 1100 content_alert = 21, |
| 1101 @@ -137,7 +139,9 @@ typedef enum { |
| 1102 certificate_unobtainable = 111, |
| 1103 unrecognized_name = 112, |
| 1104 bad_certificate_status_response = 113, |
| 1105 - bad_certificate_hash_value = 114 |
| 1106 + bad_certificate_hash_value = 114, |
| 1107 + |
| 1108 + unknown_psk_identity = 115 |
| 1109 |
| 1110 } SSL3AlertDescription; |
| 1111 |
| 1112 @@ -215,6 +219,9 @@ typedef enum { |
| 1113 kea_dh_anon, |
| 1114 kea_dh_anon_export, |
| 1115 kea_rsa_fips, |
| 1116 + kea_srp, |
| 1117 + kea_srp_rsa, |
| 1118 + kea_srp_dss, |
| 1119 kea_ecdh_ecdsa, |
| 1120 kea_ecdhe_ecdsa, |
| 1121 kea_ecdh_rsa, |
| 1122 diff --git a/mozilla/security/nss/lib/ssl/sslauth.c b/mozilla/security/nss/lib/s
sl/sslauth.c |
| 1123 index 3f4924d..8282cf8 100644 |
| 1124 --- a/mozilla/security/nss/lib/ssl/sslauth.c |
| 1125 +++ b/mozilla/security/nss/lib/ssl/sslauth.c |
| 1126 @@ -291,6 +291,80 @@ SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) |
| 1127 return SECSuccess; |
| 1128 } |
| 1129 |
| 1130 +/* register callback function to provide the user password */ |
| 1131 +SECStatus |
| 1132 +SSL_UserPasswdHook(PRFileDesc *s, SSLUserPasswdCB func, void *arg) |
| 1133 +{ |
| 1134 + sslSocket *ss; |
| 1135 + |
| 1136 + ss = ssl_FindSocket(s); |
| 1137 + if (!ss) { |
| 1138 + SSL_DBG(("%d: SSL[%d]: bad socket in UserPasswdHook", |
| 1139 + SSL_GETPID(), s)); |
| 1140 + return SECFailure; |
| 1141 + } |
| 1142 + |
| 1143 + ss->getUserPasswd = func; |
| 1144 + ss->getUserPasswdArg = arg; |
| 1145 + return SECSuccess; |
| 1146 +} |
| 1147 + |
| 1148 +/* used by client to provide user credentials non-interactively */ |
| 1149 +SECStatus |
| 1150 +SSL_SetUserLogin(PRFileDesc *s, const char *user, const char *passwd) |
| 1151 +{ |
| 1152 + sslSocket *ss = NULL; |
| 1153 + int len; |
| 1154 + |
| 1155 + ss = ssl_FindSocket(s); |
| 1156 + if (!ss) { |
| 1157 + SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", |
| 1158 + SSL_GETPID(), s)); |
| 1159 + return SECFailure; |
| 1160 + } |
| 1161 + |
| 1162 + if (user) { |
| 1163 + len = PORT_Strlen(user); |
| 1164 + if (len > MAX_SRP_USERNAME_LENGTH) |
| 1165 + len = MAX_SRP_USERNAME_LENGTH; |
| 1166 + ss->sec.userName = SECITEM_AllocItem(NULL, NULL, len); |
| 1167 + if (!ss->sec.userName) { |
| 1168 + PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 1169 + return SECFailure; |
| 1170 + } |
| 1171 + PORT_Memcpy(ss->sec.userName->data, user, ss->sec.userName->len); |
| 1172 + } |
| 1173 + |
| 1174 + if (passwd) { |
| 1175 + len = PORT_Strlen(passwd); |
| 1176 + ss->sec.userPasswd = SECITEM_AllocItem(NULL, NULL, len); |
| 1177 + if (!ss->sec.userPasswd) { |
| 1178 + PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 1179 + return SECFailure; |
| 1180 + } |
| 1181 + PORT_Memcpy(ss->sec.userPasswd->data, passwd, ss->sec.userPasswd->len); |
| 1182 + } |
| 1183 + |
| 1184 + return SECSuccess; |
| 1185 +} |
| 1186 + |
| 1187 +/* register callback function to provide SRP user authentication params */ |
| 1188 +SECStatus |
| 1189 +SSL_GetSRPParamsHook(PRFileDesc *s, SSLGetSRPParamsCB func, void *arg) |
| 1190 +{ |
| 1191 + sslSocket *ss; |
| 1192 + |
| 1193 + ss = ssl_FindSocket(s); |
| 1194 + if (!ss) { |
| 1195 + SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", |
| 1196 + SSL_GETPID(), s)); |
| 1197 + return SECFailure; |
| 1198 + } |
| 1199 + |
| 1200 + ss->getSRPParams = func; |
| 1201 + ss->getSRPParamsArg = arg; |
| 1202 + return SECSuccess; |
| 1203 +} |
| 1204 |
| 1205 /* This is the "default" authCert callback function. It is called when a |
| 1206 * certificate message is received from the peer and the local application |
| 1207 diff --git a/mozilla/security/nss/lib/ssl/sslenum.c b/mozilla/security/nss/lib/s
sl/sslenum.c |
| 1208 index b8aa8cc..196ed30 100644 |
| 1209 --- a/mozilla/security/nss/lib/ssl/sslenum.c |
| 1210 +++ b/mozilla/security/nss/lib/ssl/sslenum.c |
| 1211 @@ -74,6 +74,9 @@ const PRUint16 SSL_ImplementedCiphers[] = { |
| 1212 #endif /* NSS_ENABLE_ECC */ |
| 1213 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, |
| 1214 TLS_RSA_WITH_AES_256_CBC_SHA, |
| 1215 + TLS_SRP_SHA_WITH_AES_256_CBC_SHA, |
| 1216 + TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, |
| 1217 + TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, |
| 1218 |
| 1219 /* 128-bit */ |
| 1220 #ifdef NSS_ENABLE_ECC |
| 1221 @@ -98,12 +101,16 @@ const PRUint16 SSL_ImplementedCiphers[] = { |
| 1222 SSL_RSA_WITH_RC4_128_MD5, |
| 1223 SSL_RSA_WITH_RC4_128_SHA, |
| 1224 TLS_RSA_WITH_AES_128_CBC_SHA, |
| 1225 + TLS_SRP_SHA_WITH_AES_128_CBC_SHA, |
| 1226 + TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, |
| 1227 + TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, |
| 1228 |
| 1229 /* 112-bit 3DES */ |
| 1230 #ifdef NSS_ENABLE_ECC |
| 1231 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, |
| 1232 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, |
| 1233 #endif /* NSS_ENABLE_ECC */ |
| 1234 + TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, |
| 1235 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, |
| 1236 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, |
| 1237 #ifdef NSS_ENABLE_ECC |
| 1238 @@ -112,6 +119,8 @@ const PRUint16 SSL_ImplementedCiphers[] = { |
| 1239 #endif /* NSS_ENABLE_ECC */ |
| 1240 SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, |
| 1241 SSL_RSA_WITH_3DES_EDE_CBC_SHA, |
| 1242 + TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, |
| 1243 + TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, |
| 1244 |
| 1245 /* 56-bit DES "domestic" cipher suites */ |
| 1246 SSL_DHE_RSA_WITH_DES_CBC_SHA, |
| 1247 diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ss
l/sslerr.h |
| 1248 index eb56ea9..a0c4b9d 100644 |
| 1249 --- a/mozilla/security/nss/lib/ssl/sslerr.h |
| 1250 +++ b/mozilla/security/nss/lib/ssl/sslerr.h |
| 1251 @@ -205,6 +205,8 @@ SSL_ERROR_WEAK_SERVER_KEY = (SSL_ERROR_BASE +
115), |
| 1252 |
| 1253 SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 116), |
| 1254 |
| 1255 +SSL_ERROR_UNKNOWN_PSK_IDENTITY_ALERT = (SSL_ERROR_BASE + 116), |
| 1256 + |
| 1257 SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ |
| 1258 } SSLErrorCodes; |
| 1259 #endif /* NO_SECURITY_ERROR_ENUM */ |
| 1260 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/s
sl/sslimpl.h |
| 1261 index 1ea82da..0a0808a 100644 |
| 1262 --- a/mozilla/security/nss/lib/ssl/sslimpl.h |
| 1263 +++ b/mozilla/security/nss/lib/ssl/sslimpl.h |
| 1264 @@ -317,9 +317,9 @@ typedef struct { |
| 1265 } ssl3CipherSuiteCfg; |
| 1266 |
| 1267 #ifdef NSS_ENABLE_ECC |
| 1268 -#define ssl_V3_SUITES_IMPLEMENTED 50 |
| 1269 +#define ssl_V3_SUITES_IMPLEMENTED 59 |
| 1270 #else |
| 1271 -#define ssl_V3_SUITES_IMPLEMENTED 30 |
| 1272 +#define ssl_V3_SUITES_IMPLEMENTED 39 |
| 1273 #endif /* NSS_ENABLE_ECC */ |
| 1274 |
| 1275 typedef struct sslOptionsStr { |
| 1276 @@ -1050,6 +1050,8 @@ struct sslSecurityInfoStr { |
| 1277 CERTCertificate *localCert; /* ssl 2
& 3 */ |
| 1278 CERTCertificate *peerCert; /* ssl 2 & 3 */ |
| 1279 SECKEYPublicKey *peerKey; /* ssl3 only */ |
| 1280 + SECItem *userName; /* SSL username credential */ |
| 1281 + SECItem *userPasswd; /* SSL userpasswd credential */ |
| 1282 |
| 1283 SSLSignType authAlgorithm; |
| 1284 PRUint32 authKeyBits; |
| 1285 @@ -1159,6 +1161,10 @@ const unsigned char * preferredCipher; |
| 1286 SSLHandshakeCallback handshakeCallback; |
| 1287 void *handshakeCallbackData; |
| 1288 void *pkcs11PinArg; |
| 1289 + SSLUserPasswdCB getUserPasswd; |
| 1290 + void *getUserPasswdArg; |
| 1291 + SSLGetSRPParamsCB getSRPParams; |
| 1292 + void *getSRPParamsArg; |
| 1293 |
| 1294 PRIntervalTime rTimeout; /* timeout for NSPR I/O */ |
| 1295 PRIntervalTime wTimeout; /* timeout for NSPR I/O */ |
| 1296 diff --git a/mozilla/security/nss/lib/ssl/sslinfo.c b/mozilla/security/nss/lib/s
sl/sslinfo.c |
| 1297 index c1c3fd7..2599ef1 100644 |
| 1298 --- a/mozilla/security/nss/lib/ssl/sslinfo.c |
| 1299 +++ b/mozilla/security/nss/lib/ssl/sslinfo.c |
| 1300 @@ -54,6 +54,27 @@ ssl_GetCompressionMethodName(SSLCompressionMethod compression
) |
| 1301 } |
| 1302 } |
| 1303 |
| 1304 +SECStatus |
| 1305 +SSL_GetChannelUsername(PRFileDesc *fd, SECItem *user) |
| 1306 +{ |
| 1307 + SECItem * username; |
| 1308 + sslSocket * ss; |
| 1309 + |
| 1310 + ss = ssl_FindSocket(fd); |
| 1311 + if (!ss) { |
| 1312 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelUsername", |
| 1313 + SSL_GETPID(), fd)); |
| 1314 + return SECFailure; |
| 1315 + } |
| 1316 + |
| 1317 + if (ss->sec.userName == NULL) { |
| 1318 + PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1319 + return SECFailure; |
| 1320 + } |
| 1321 + |
| 1322 + return SECITEM_CopyItem(NULL, user, ss->sec.userName); |
| 1323 +} |
| 1324 + |
| 1325 SECStatus |
| 1326 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) |
| 1327 { |
| 1328 @@ -141,6 +162,9 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRU
intn len) |
| 1329 #define K_KEA "KEA", kt_kea |
| 1330 #define K_ECDH "ECDH", kt_ecdh |
| 1331 #define K_ECDHE "ECDHE", kt_ecdh |
| 1332 +#define K_SRP "SRP", ssl_kea_srp |
| 1333 +#define K_SRP_RSA "SRP_RSA", ssl_kea_srp_rsa |
| 1334 +#define K_SRP_DSS "SRP_DSS", ssl_kea_srp_dss |
| 1335 |
| 1336 #define C_SEED "SEED", calg_seed |
| 1337 #define C_CAMELLIA "CAMELLIA", calg_camellia |
| 1338 @@ -201,6 +225,17 @@ static const SSLCipherSuiteInfo suiteInfo[] = { |
| 1339 {0,CS(SSL_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA
, 0, 1, 0, }, |
| 1340 {0,CS(SSL_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5
, 0, 1, 0, }, |
| 1341 |
| 1342 +/* SRP cipher suites */ |
| 1343 +{0,CS(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA), S_KEA, K_SRP, C_3DES,B_3DES,M_SHA
, 0, 0, 0, }, |
| 1344 +{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, }, |
| 1345 +{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, }, |
| 1346 +{0,CS(TLS_SRP_SHA_WITH_AES_128_CBC_SHA), S_KEA, K_SRP, C_AES, B_128, M_SHA
, 0, 0, 0, }, |
| 1347 +{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, }, |
| 1348 +{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, }, |
| 1349 +{0,CS(TLS_SRP_SHA_WITH_AES_256_CBC_SHA), S_KEA, K_SRP, C_AES, B_256, M_SHA
, 0, 0, 0, }, |
| 1350 +{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, }, |
| 1351 +{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, }, |
| 1352 + |
| 1353 #ifdef NSS_ENABLE_ECC |
| 1354 /* ECC cipher suites */ |
| 1355 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_S
HA, 0, 0, 0, }, |
| 1356 diff --git a/mozilla/security/nss/lib/ssl/sslproto.h b/mozilla/security/nss/lib/
ssl/sslproto.h |
| 1357 index b534d0b..cbf6250 100644 |
| 1358 --- a/mozilla/security/nss/lib/ssl/sslproto.h |
| 1359 +++ b/mozilla/security/nss/lib/ssl/sslproto.h |
| 1360 @@ -220,6 +220,16 @@ |
| 1361 #define TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 |
| 1362 #define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 |
| 1363 |
| 1364 +#define TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0xC01A |
| 1365 +#define TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0xC01B |
| 1366 +#define TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0xC01C |
| 1367 +#define TLS_SRP_SHA_WITH_AES_128_CBC_SHA 0xC01D |
| 1368 +#define TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0xC01E |
| 1369 +#define TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0xC01F |
| 1370 +#define TLS_SRP_SHA_WITH_AES_256_CBC_SHA 0xC020 |
| 1371 +#define TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0xC021 |
| 1372 +#define TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0xC022 |
| 1373 + |
| 1374 /* Netscape "experimental" cipher suites. */ |
| 1375 #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0 |
| 1376 #define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1 |
| 1377 diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/
ssl/sslsecur.c |
| 1378 index 49a81bc..fe1465d 100644 |
| 1379 --- a/mozilla/security/nss/lib/ssl/sslsecur.c |
| 1380 +++ b/mozilla/security/nss/lib/ssl/sslsecur.c |
| 1381 @@ -902,6 +902,14 @@ ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) |
| 1382 if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data) |
| 1383 goto loser; |
| 1384 |
| 1385 + SECITEM_CopyItem(0, ss->sec.userName, os->sec.userName); |
| 1386 + if (os->sec.userName->data && !ss->sec.userName->data) |
| 1387 + goto loser; |
| 1388 + SECITEM_CopyItem(0, ss->sec.userPasswd, os->sec.userPasswd); |
| 1389 + if (os->sec.userPasswd->data && !ss->sec.userPasswd->data) |
| 1390 + goto loser; |
| 1391 + |
| 1392 + |
| 1393 /* XXX following code is wrong if either cx != 0 */ |
| 1394 PORT_Assert(os->sec.readcx == 0); |
| 1395 PORT_Assert(os->sec.writecx == 0); |
| 1396 @@ -983,6 +991,15 @@ ssl_DestroySecurityInfo(sslSecurityInfo *sec) |
| 1397 { |
| 1398 ssl_ResetSecurityInfo(sec, PR_FALSE); |
| 1399 |
| 1400 + if (sec->userName) { |
| 1401 + SECITEM_FreeItem(sec->userName, PR_TRUE); |
| 1402 + sec->userName = NULL; |
| 1403 + } |
| 1404 + if (sec->userPasswd) { |
| 1405 + SECITEM_FreeItem(sec->userPasswd, PR_TRUE); |
| 1406 + sec->userPasswd = NULL; |
| 1407 + } |
| 1408 + |
| 1409 PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); |
| 1410 sec->writeBuf.buf = 0; |
| 1411 |
| 1412 diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/s
sl/sslsock.c |
| 1413 index b14a935..18ee612 100644 |
| 1414 --- a/mozilla/security/nss/lib/ssl/sslsock.c |
| 1415 +++ b/mozilla/security/nss/lib/ssl/sslsock.c |
| 1416 @@ -102,6 +102,15 @@ static cipherPolicy ssl_ciphers[] = { /* Export
France */ |
| 1417 { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1418 { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALL
OWED }, |
| 1419 { TLS_RSA_WITH_SEED_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1420 + { TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1421 + { TLS_SRP_SHA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1422 + { TLS_SRP_SHA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1423 + { TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1424 + { TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1425 + { TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1426 + { TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1427 + { TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1428 + { TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
| 1429 { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED }, |
| 1430 { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED }, |
| 1431 #ifdef NSS_ENABLE_ECC |
| 1432 diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/
sslt.h |
| 1433 index 3fa3f9b..9cb000b 100644 |
| 1434 --- a/mozilla/security/nss/lib/ssl/sslt.h |
| 1435 +++ b/mozilla/security/nss/lib/ssl/sslt.h |
| 1436 @@ -74,6 +74,9 @@ typedef enum { |
| 1437 ssl_kea_dh = 2, |
| 1438 ssl_kea_fortezza = 3, /* deprecated, now unused */ |
| 1439 ssl_kea_ecdh = 4, |
| 1440 + ssl_kea_srp = 5, |
| 1441 + ssl_kea_srp_rsa = 6, |
| 1442 + ssl_kea_srp_dss = 7, |
| 1443 ssl_kea_size /* number of ssl_kea_ algorithms */ |
| 1444 } SSLKEAType; |
| 1445 |
| 1446 @@ -88,6 +91,7 @@ typedef enum { |
| 1447 #define kt_fortezza ssl_kea_fortezza /* deprecated, now unused */ |
| 1448 #define kt_ecdh ssl_kea_ecdh |
| 1449 #define kt_kea_size ssl_kea_size |
| 1450 +#define kt_srp ssl_kea_srp |
| 1451 |
| 1452 typedef enum { |
| 1453 ssl_sign_null = 0, |
| 1454 @@ -203,13 +207,14 @@ typedef enum { |
| 1455 ssl_elliptic_curves_xtn = 10, |
| 1456 ssl_ec_point_formats_xtn = 11, |
| 1457 #endif |
| 1458 + ssl_srp_hello_xtn = 12, |
| 1459 ssl_session_ticket_xtn = 35, |
| 1460 ssl_next_proto_neg_xtn = 13172, |
| 1461 ssl_snap_start_xtn = 13174, |
| 1462 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ |
| 1463 } SSLExtensionType; |
| 1464 |
| 1465 -#define SSL_MAX_EXTENSIONS 8 |
| 1466 +#define SSL_MAX_EXTENSIONS 9 |
| 1467 |
| 1468 typedef enum { |
| 1469 /* No Snap Start handshake was attempted. */ |
OLD | NEW |