• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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