| Index: net/third_party/nss/ssl/ssl3ext.c
|
| diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
|
| index b93671e10447c8431e92673a134bf6db34aed5ff..c2a27b4361e2a3bf58338595c23298a9efca8c7c 100644
|
| --- a/net/third_party/nss/ssl/ssl3ext.c
|
| +++ b/net/third_party/nss/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;
|
| +}
|
|
|