Index: net/third_party/nss/ssl/ssl3ext.c |
=================================================================== |
--- net/third_party/nss/ssl/ssl3ext.c (revision 252347) |
+++ net/third_party/nss/ssl/ssl3ext.c (working copy) |
@@ -87,6 +87,12 @@ |
static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, |
PRUint16 ex_type, |
SECItem *data); |
+static PRInt32 ssl3_ClientSendEncryptThenMACXtn(sslSocket *ss, |
+ PRBool append, |
+ PRUint32 maxBytes); |
+static SECStatus ssl3_ClientHandleEncryptThenMACXtn(sslSocket *ss, |
+ PRUint16 ex_type, |
+ SECItem *data); |
/* |
* Write bytes. Using this function means the SECItem structure |
@@ -267,6 +273,7 @@ |
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, |
{ ssl_signed_certificate_timestamp_xtn, |
&ssl3_ClientHandleSignedCertTimestampXtn }, |
+ { ssl_encrypt_then_mac_xtn, &ssl3_ClientHandleEncryptThenMACXtn }, |
{ -1, NULL } |
}; |
@@ -297,7 +304,8 @@ |
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, |
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, |
{ ssl_signed_certificate_timestamp_xtn, |
- &ssl3_ClientSendSignedCertTimestampXtn } |
+ &ssl3_ClientSendSignedCertTimestampXtn }, |
+ { ssl_encrypt_then_mac_xtn, &ssl3_ClientSendEncryptThenMACXtn } |
/* any extra entries will appear as { 0, NULL } */ |
}; |
@@ -2451,3 +2459,50 @@ |
ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
return SECSuccess; |
} |
+ |
+static PRInt32 |
+ssl3_ClientSendEncryptThenMACXtn(sslSocket *ss, PRBool append, |
+ PRUint32 maxBytes) |
+{ |
+ PRInt32 extension_length = 2 /* extension_type */ + |
+ 2 /* length(extension_data) */; |
+ |
+ /* Only send the extension if processing is enabled. */ |
+ if (!ss->opt.enableEncryptThenMAC) |
+ return 0; |
+ |
+ if (append && maxBytes >= extension_length) { |
+ SECStatus rv; |
+ /* extension_type */ |
+ rv = ssl3_AppendHandshakeNumber(ss, |
+ ssl_encrypt_then_mac_xtn, |
+ 2); |
+ if (rv != SECSuccess) |
+ goto loser; |
+ /* zero length */ |
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2); |
+ if (rv != SECSuccess) |
+ goto loser; |
+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = |
+ ssl_encrypt_then_mac_xtn; |
+ } else if (maxBytes < extension_length) { |
+ PORT_Assert(0); |
+ return 0; |
+ } |
+ |
+ return extension_length; |
+loser: |
+ return -1; |
+} |
+ |
+static SECStatus |
+ssl3_ClientHandleEncryptThenMACXtn(sslSocket *ss, PRUint16 ex_type, |
+ SECItem *data) |
+{ |
+ /* The echoed extension must be empty. */ |
+ if (data->len != 0) |
+ return SECFailure; |
+ /* Keep track of negotiated extensions. */ |
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
+ return SECSuccess; |
+} |