1 diff --git a/ssl/ssl.h b/ssl/ssl.h
2 index e9f5fb0..be6d88e 100644
5 @@ -295,6 +295,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);
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,
16 /* SSLChannelBindingType enumerates the types of supported channel binding
17 * values. See RFC 5929. */
18 typedef enum SSLChannelBindingType {
19 diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
20 index 54c5b80..26b87c6 100644
23 @@ -12631,6 +12631,46 @@ ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
28 +ssl3_CipherOrderSet(sslSocket *ss, const ssl3CipherSuite *ciphers, unsigned int len)
30 + /* |i| iterates over |ciphers| while |done| and |j| iterate over
31 + * |ss->cipherSuites|. */
32 + unsigned int i, done;
34 + for (i = done = 0; i < len; i++) {
35 + PRUint16 id = ciphers[i];
36 + unsigned int existingIndex, j;
37 + PRBool found = PR_FALSE;
39 + for (j = done; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
40 + if (ss->cipherSuites[j].cipher_suite == id) {
51 + if (existingIndex != done) {
52 + const ssl3CipherSuiteCfg temp = ss->cipherSuites[done];
53 + ss->cipherSuites[done] = ss->cipherSuites[existingIndex];
54 + ss->cipherSuites[existingIndex] = temp;
59 + /* Disable all cipher suites that weren't included. */
60 + for (; done < ssl_V3_SUITES_IMPLEMENTED; done++) {
61 + ss->cipherSuites[done].enabled = 0;
67 /* copy global default policy into socket. */
69 ssl3_InitSocketPolicy(sslSocket *ss)
70 diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
71 index 0fd0a89..d12228e 100644
74 @@ -1754,6 +1754,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,
81 extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy);
82 extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy);
83 diff --git a/ssl/sslsock.c b/ssl/sslsock.c
84 index 72058f5..09a0fb5 100644
87 @@ -1316,6 +1316,19 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
91 +SSL_CipherOrderSet(PRFileDesc *fd, const PRUint16 *ciphers, unsigned int len)
93 + sslSocket *ss = ssl_FindSocket(fd);
96 + SSL_DBG(("%d: SSL[%d]: bad socket in CipherOrderSet", SSL_GETPID(),
100 + return ssl3_CipherOrderSet(ss, ciphers, len);
104 SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)