1diff --git a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h 2index 4cf02aa..24627ed 100644 3--- a/nss/lib/ssl/ssl.h 4+++ b/nss/lib/ssl/ssl.h 5@@ -265,6 +265,13 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled); 6 SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy); 7 SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy); 8 9+/* SSL_CipherOrderSet sets the cipher suite preference order from |ciphers|, 10+ * which must be an array of cipher suite ids of length |len|. All the given 11+ * cipher suite ids must appear in the array that is returned by 12+ * |SSL_GetImplementedCiphers| and may only appear once, at most. */ 13+SSL_IMPORT SECStatus SSL_CipherOrderSet(PRFileDesc *fd, const PRUint16 *ciphers, 14+ unsigned int len); 15+ 16 /* SSLChannelBindingType enumerates the types of supported channel binding 17 * values. See RFC 5929. */ 18 typedef enum SSLChannelBindingType { 19diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c 20index c2d9eeb..350d09c 100644 21--- a/nss/lib/ssl/ssl3con.c 22+++ b/nss/lib/ssl/ssl3con.c 23@@ -12423,6 +12423,46 @@ ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled) 24 return rv; 25 } 26 27+SECStatus 28+ssl3_CipherOrderSet(sslSocket *ss, const ssl3CipherSuite *ciphers, unsigned int len) 29+{ 30+ /* |i| iterates over |ciphers| while |done| and |j| iterate over 31+ * |ss->cipherSuites|. */ 32+ unsigned int i, done; 33+ 34+ for (i = done = 0; i < len; i++) { 35+ PRUint16 id = ciphers[i]; 36+ unsigned int existingIndex, j; 37+ PRBool found = PR_FALSE; 38+ 39+ for (j = done; j < ssl_V3_SUITES_IMPLEMENTED; j++) { 40+ if (ss->cipherSuites[j].cipher_suite == id) { 41+ existingIndex = j; 42+ found = PR_TRUE; 43+ break; 44+ } 45+ } 46+ 47+ if (!found) { 48+ continue; 49+ } 50+ 51+ if (existingIndex != done) { 52+ const ssl3CipherSuiteCfg temp = ss->cipherSuites[done]; 53+ ss->cipherSuites[done] = ss->cipherSuites[existingIndex]; 54+ ss->cipherSuites[existingIndex] = temp; 55+ } 56+ done++; 57+ } 58+ 59+ /* Disable all cipher suites that weren't included. */ 60+ for (; done < ssl_V3_SUITES_IMPLEMENTED; done++) { 61+ ss->cipherSuites[done].enabled = 0; 62+ } 63+ 64+ return SECSuccess; 65+} 66+ 67 /* copy global default policy into socket. */ 68 void 69 ssl3_InitSocketPolicy(sslSocket *ss) 70diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h 71index 1e4655f..7521dba 100644 72--- a/nss/lib/ssl/sslimpl.h 73+++ b/nss/lib/ssl/sslimpl.h 74@@ -1711,6 +1711,8 @@ extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool 75 extern SECStatus ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *on); 76 extern SECStatus ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled); 77 extern SECStatus ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled); 78+extern SECStatus ssl3_CipherOrderSet(sslSocket *ss, const ssl3CipherSuite *cipher, 79+ unsigned int len); 80 81 extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy); 82 extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy); 83diff --git a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c 84index 965215d..9f8286c 100644 85--- a/nss/lib/ssl/sslsock.c 86+++ b/nss/lib/ssl/sslsock.c 87@@ -1344,6 +1344,19 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled) 88 return rv; 89 } 90 91+SECStatus 92+SSL_CipherOrderSet(PRFileDesc *fd, const PRUint16 *ciphers, unsigned int len) 93+{ 94+ sslSocket *ss = ssl_FindSocket(fd); 95+ 96+ if (!ss) { 97+ SSL_DBG(("%d: SSL[%d]: bad socket in CipherOrderSet", SSL_GETPID(), 98+ fd)); 99+ return SECFailure; 100+ } 101+ return ssl3_CipherOrderSet(ss, ciphers, len); 102+} 103+ 104 SECStatus 105 SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled) 106 { 107