OLD | NEW |
| (Empty) |
1 diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlsl
ite/constants.py | |
2 index e5b88af..6d78a20 100644 | |
3 --- a/third_party/tlslite/tlslite/constants.py | |
4 +++ b/third_party/tlslite/tlslite/constants.py | |
5 @@ -76,6 +76,14 @@ class SignatureAlgorithm: | |
6 class NameType: | |
7 host_name = 0 | |
8 | |
9 +class ECCurveType: | |
10 + explicit_prime = 1 | |
11 + explicit_char2 = 2 | |
12 + named_curve = 3 | |
13 + | |
14 +class NamedCurve: | |
15 + secp256r1 = 23 | |
16 + | |
17 class AlertLevel: | |
18 warning = 1 | |
19 fatal = 2 | |
20 @@ -178,11 +186,19 @@ class CipherSuite: | |
21 TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C | |
22 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E | |
23 | |
24 + TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xc011 | |
25 + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xc012 | |
26 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xc013 | |
27 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xc014 | |
28 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xc027 | |
29 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f | |
30 + | |
31 tripleDESSuites = [] | |
32 tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) | |
33 tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) | |
34 tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA) | |
35 tripleDESSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) | |
36 + tripleDESSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) | |
37 | |
38 aes128Suites = [] | |
39 aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA) | |
40 @@ -192,6 +208,8 @@ class CipherSuite: | |
41 aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) | |
42 aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256) | |
43 aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256) | |
44 + aes128Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) | |
45 + aes128Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) | |
46 | |
47 aes256Suites = [] | |
48 aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA) | |
49 @@ -201,14 +219,17 @@ class CipherSuite: | |
50 aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) | |
51 aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256) | |
52 aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256) | |
53 + aes256Suites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) | |
54 | |
55 aes128GcmSuites = [] | |
56 aes128GcmSuites.append(TLS_RSA_WITH_AES_128_GCM_SHA256) | |
57 aes128GcmSuites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) | |
58 + aes128GcmSuites.append(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) | |
59 | |
60 rc4Suites = [] | |
61 rc4Suites.append(TLS_RSA_WITH_RC4_128_SHA) | |
62 rc4Suites.append(TLS_RSA_WITH_RC4_128_MD5) | |
63 + rc4Suites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA) | |
64 | |
65 shaSuites = [] | |
66 shaSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) | |
67 @@ -226,6 +247,10 @@ class CipherSuite: | |
68 shaSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) | |
69 shaSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) | |
70 shaSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) | |
71 + shaSuites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA) | |
72 + shaSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) | |
73 + shaSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) | |
74 + shaSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) | |
75 | |
76 sha256Suites = [] | |
77 sha256Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256) | |
78 @@ -234,6 +259,9 @@ class CipherSuite: | |
79 sha256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256) | |
80 sha256Suites.append(TLS_RSA_WITH_AES_128_GCM_SHA256) | |
81 sha256Suites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) | |
82 + sha256Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) | |
83 + sha256Suites.append(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) | |
84 + | |
85 | |
86 aeadSuites = aes128GcmSuites | |
87 | |
88 @@ -275,6 +303,8 @@ class CipherSuite: | |
89 keyExchangeSuites += CipherSuite.certSuites | |
90 if "dhe_rsa" in keyExchangeNames: | |
91 keyExchangeSuites += CipherSuite.dheCertSuites | |
92 + if "ecdhe_rsa" in keyExchangeNames: | |
93 + keyExchangeSuites += CipherSuite.ecdheCertSuites | |
94 if "srp_sha" in keyExchangeNames: | |
95 keyExchangeSuites += CipherSuite.srpSuites | |
96 if "srp_sha_rsa" in keyExchangeNames: | |
97 @@ -335,7 +365,19 @@ class CipherSuite: | |
98 def getDheCertSuites(settings, version=None): | |
99 return CipherSuite._filterSuites(CipherSuite.dheCertSuites, settings, v
ersion) | |
100 | |
101 - certAllSuites = srpCertSuites + certSuites + dheCertSuites | |
102 + ecdheCertSuites = [] | |
103 + ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) | |
104 + ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) | |
105 + ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) | |
106 + ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) | |
107 + ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) | |
108 + ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA) | |
109 + | |
110 + @staticmethod | |
111 + def getEcdheCertSuites(settings, version=None): | |
112 + return CipherSuite._filterSuites(CipherSuite.ecdheCertSuites, settings,
version) | |
113 + | |
114 + certAllSuites = srpCertSuites + certSuites + dheCertSuites + ecdheCertSuite
s | |
115 | |
116 anonSuites = [] | |
117 anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) | |
118 @@ -346,6 +388,7 @@ class CipherSuite: | |
119 return CipherSuite._filterSuites(CipherSuite.anonSuites, settings, vers
ion) | |
120 | |
121 dhAllSuites = dheCertSuites + anonSuites | |
122 + ecdhAllSuites = ecdheCertSuites | |
123 | |
124 @staticmethod | |
125 def canonicalCipherName(ciphersuite): | |
126 diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlsl
ite/tlslite/handshakesettings.py | |
127 index e752834..605ed42 100644 | |
128 --- a/third_party/tlslite/tlslite/handshakesettings.py | |
129 +++ b/third_party/tlslite/tlslite/handshakesettings.py | |
130 @@ -14,7 +14,7 @@ from .utils import cipherfactory | |
131 CIPHER_NAMES = ["aes128gcm", "rc4", "aes256", "aes128", "3des"] | |
132 MAC_NAMES = ["sha", "sha256", "aead"] # Don't allow "md5" by default. | |
133 ALL_MAC_NAMES = MAC_NAMES + ["md5"] | |
134 -KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"] | |
135 +KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "ecdhe_rsa", "srp_sha", "srp_sha_rsa",
"dh_anon"] | |
136 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] | |
137 CERTIFICATE_TYPES = ["x509"] | |
138 TLS_INTOLERANCE_TYPES = ["alert", "close", "reset"] | |
139 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlsli
te/messages.py | |
140 index f2e2cfc..9aeff6d 100644 | |
141 --- a/third_party/tlslite/tlslite/messages.py | |
142 +++ b/third_party/tlslite/tlslite/messages.py | |
143 @@ -509,10 +509,13 @@ class ServerKeyExchange(HandshakeMsg): | |
144 self.srp_g = 0 | |
145 self.srp_s = bytearray(0) | |
146 self.srp_B = 0 | |
147 - # Anon DH params: | |
148 + # DH params: | |
149 self.dh_p = 0 | |
150 self.dh_g = 0 | |
151 self.dh_Ys = 0 | |
152 + # ECDH params: | |
153 + self.ecdhCurve = 0 | |
154 + self.ecdhPublic = bytearray(0) | |
155 self.signature = bytearray(0) | |
156 | |
157 def createSRP(self, srp_N, srp_g, srp_s, srp_B): | |
158 @@ -528,6 +531,11 @@ class ServerKeyExchange(HandshakeMsg): | |
159 self.dh_Ys = dh_Ys | |
160 return self | |
161 | |
162 + def createECDH(self, ecdhCurve, ecdhPublic): | |
163 + self.ecdhCurve = ecdhCurve | |
164 + self.ecdhPublic = ecdhPublic | |
165 + return self | |
166 + | |
167 def parse(self, p): | |
168 p.startLengthCheck(3) | |
169 if self.cipherSuite in CipherSuite.srpAllSuites: | |
170 @@ -555,6 +563,10 @@ class ServerKeyExchange(HandshakeMsg): | |
171 w.addVarSeq(numberToByteArray(self.dh_p), 1, 2) | |
172 w.addVarSeq(numberToByteArray(self.dh_g), 1, 2) | |
173 w.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2) | |
174 + elif self.cipherSuite in CipherSuite.ecdhAllSuites: | |
175 + w.add(ECCurveType.named_curve, 1) | |
176 + w.add(self.ecdhCurve, 2) | |
177 + w.addVarSeq(self.ecdhPublic, 1, 1) | |
178 else: | |
179 assert(False) | |
180 return w.bytes | |
181 @@ -626,7 +638,9 @@ class ClientKeyExchange(HandshakeMsg): | |
182 else: | |
183 raise AssertionError() | |
184 elif self.cipherSuite in CipherSuite.dhAllSuites: | |
185 - self.dh_Yc = bytesToNumber(p.getVarBytes(2)) | |
186 + self.dh_Yc = bytesToNumber(p.getVarBytes(2)) | |
187 + elif self.cipherSuite in CipherSuite.ecdhAllSuites: | |
188 + self.ecdh_Yc = p.getVarBytes(1) | |
189 else: | |
190 raise AssertionError() | |
191 p.stopLengthCheck() | |
192 diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/
tlslite/tlsconnection.py | |
193 index 0a85d3c..dfac274 100644 | |
194 --- a/third_party/tlslite/tlslite/tlsconnection.py | |
195 +++ b/third_party/tlslite/tlslite/tlsconnection.py | |
196 @@ -24,6 +24,7 @@ from .mathtls import * | |
197 from .handshakesettings import HandshakeSettings | |
198 from .utils.tackwrapper import * | |
199 from .utils.rsakey import RSAKey | |
200 +from .utils import p256 | |
201 | |
202 class KeyExchange(object): | |
203 def __init__(self, cipherSuite, clientHello, serverHello, privateKey): | |
204 @@ -127,6 +128,25 @@ DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 | |
205 S = powMod(dh_Yc, self.dh_Xs, self.dh_p) | |
206 return numberToByteArray(S) | |
207 | |
208 +class ECDHE_RSAKeyExchange(KeyExchange): | |
209 + def makeServerKeyExchange(self): | |
210 + public, self.private = p256.generatePublicPrivate() | |
211 + | |
212 + version = self.serverHello.server_version | |
213 + serverKeyExchange = ServerKeyExchange(self.cipherSuite, version) | |
214 + serverKeyExchange.createECDH(NamedCurve.secp256r1, bytearray(public)) | |
215 + hashBytes = serverKeyExchange.hash(self.clientHello.random, | |
216 + self.serverHello.random) | |
217 + if version >= (3,3): | |
218 + # TODO: Signature algorithm negotiation not supported. | |
219 + hashBytes = RSAKey.addPKCS1SHA1Prefix(hashBytes) | |
220 + serverKeyExchange.signature = self.privateKey.sign(hashBytes) | |
221 + return serverKeyExchange | |
222 + | |
223 + def processClientKeyExchange(self, clientKeyExchange): | |
224 + ecdh_Yc = clientKeyExchange.ecdh_Yc | |
225 + return bytearray(p256.generateSharedValue(bytes(ecdh_Yc), self.private)
) | |
226 + | |
227 class TLSConnection(TLSRecordLayer): | |
228 """ | |
229 This class wraps a socket and provides TLS handshaking and data | |
230 @@ -1321,9 +1341,8 @@ class TLSConnection(TLSRecordLayer): | |
231 else: break | |
232 premasterSecret = result | |
233 | |
234 - # Perform the RSA or DHE_RSA key exchange | |
235 - elif (cipherSuite in CipherSuite.certSuites or | |
236 - cipherSuite in CipherSuite.dheCertSuites): | |
237 + # Perform a certificate-based key exchange | |
238 + elif cipherSuite in CipherSuite.certAllSuites: | |
239 if cipherSuite in CipherSuite.certSuites: | |
240 keyExchange = RSAKeyExchange(cipherSuite, | |
241 clientHello, | |
242 @@ -1334,6 +1353,11 @@ class TLSConnection(TLSRecordLayer): | |
243 clientHello, | |
244 serverHello, | |
245 privateKey) | |
246 + elif cipherSuite in CipherSuite.ecdheCertSuites: | |
247 + keyExchange = ECDHE_RSAKeyExchange(cipherSuite, | |
248 + clientHello, | |
249 + serverHello, | |
250 + privateKey) | |
251 else: | |
252 assert(False) | |
253 for result in self._serverCertKeyExchange(clientHello, serverHello,
| |
254 @@ -1450,6 +1474,7 @@ class TLSConnection(TLSRecordLayer): | |
255 CipherSuite.getSrpCertSuites(settings, self.version) | |
256 cipherSuites += CipherSuite.getSrpSuites(settings, self.version) | |
257 elif certChain: | |
258 + cipherSuites += CipherSuite.getEcdheCertSuites(settings, self.versi
on) | |
259 cipherSuites += CipherSuite.getDheCertSuites(settings, self.version
) | |
260 cipherSuites += CipherSuite.getCertSuites(settings, self.version) | |
261 elif anon: | |
262 diff --git a/third_party/tlslite/tlslite/utils/p256.py b/third_party/tlslite/tls
lite/utils/p256.py | |
263 index e69de29..6eb9a77 100644 | |
264 --- a/third_party/tlslite/tlslite/utils/p256.py | |
265 +++ b/third_party/tlslite/tlslite/utils/p256.py | |
266 @@ -0,0 +1,162 @@ | |
267 +# Author: Google | |
268 +# See the LICENSE file for legal information regarding use of this file. | |
269 + | |
270 +import os | |
271 + | |
272 +p = ( | |
273 + 115792089210356248762697446949407573530086143415290314195533631308867097853
951) | |
274 +order = ( | |
275 + 115792089210356248762697446949407573529996955224135760342422259061068512044
369) | |
276 +p256B = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b | |
277 + | |
278 +baseX = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 | |
279 +baseY = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 | |
280 +basePoint = (baseX, baseY) | |
281 + | |
282 + | |
283 +def _pointAdd(a, b): | |
284 + Z1Z1 = (a[2] * a[2]) % p | |
285 + Z2Z2 = (b[2] * b[2]) % p | |
286 + U1 = (a[0] * Z2Z2) % p | |
287 + U2 = (b[0] * Z1Z1) % p | |
288 + S1 = (a[1] * b[2] * Z2Z2) % p | |
289 + S2 = (b[1] * a[2] * Z1Z1) % p | |
290 + if U1 == U2 and S1 == S2: | |
291 + return pointDouble(a) | |
292 + H = (U2 - U1) % p | |
293 + I = (4 * H * H) % p | |
294 + J = (H * I) % p | |
295 + r = (2 * (S2 - S1)) % p | |
296 + V = (U1 * I) % p | |
297 + X3 = (r * r - J - 2 * V) % p | |
298 + Y3 = (r * (V - X3) - 2 * S1 * J) % p | |
299 + Z3 = (((a[2] + b[2]) * (a[2] + b[2]) - Z1Z1 - Z2Z2) * H) % p | |
300 + | |
301 + return (X3, Y3, Z3) | |
302 + | |
303 + | |
304 +def _pointDouble(a): | |
305 + delta = (a[2] * a[2]) % p | |
306 + gamma = (a[1] * a[1]) % p | |
307 + beta = (a[0] * gamma) % p | |
308 + alpha = (3 * (a[0] - delta) * (a[0] + delta)) % p | |
309 + X3 = (alpha * alpha - 8 * beta) % p | |
310 + Z3 = ((a[1] + a[2]) * (a[1] + a[2]) - gamma - delta) % p | |
311 + Y3 = (alpha * (4 * beta - X3) - 8 * gamma * gamma) % p | |
312 + | |
313 + return (X3, Y3, Z3) | |
314 + | |
315 + | |
316 +def _square(n): | |
317 + return (n * n) | |
318 + | |
319 + | |
320 +def _modpow(a, n, p): | |
321 + if n == 0: | |
322 + return 1 | |
323 + if n == 1: | |
324 + return a | |
325 + r = _square(_modpow(a, n >> 1, p)) % p | |
326 + if n & 1 == 1: | |
327 + r = (r * a) % p | |
328 + return r | |
329 + | |
330 + | |
331 +def _scalarMult(k, point): | |
332 + accum = (0, 0, 0) | |
333 + accumIsInfinity = True | |
334 + jacobianPoint = (point[0], point[1], 1) | |
335 + | |
336 + for bit in range(255, -1, -1): | |
337 + if not accumIsInfinity: | |
338 + accum = _pointDouble(accum) | |
339 + | |
340 + if (k >> bit) & 1 == 1: | |
341 + if accumIsInfinity: | |
342 + accum = jacobianPoint | |
343 + accumIsInfinity = False | |
344 + else: | |
345 + accum = _pointAdd(accum, jacobianPoint) | |
346 + | |
347 + if accumIsInfinity: | |
348 + return (0, 0) | |
349 + | |
350 + zInv = _modpow(accum[2], p - 2, p) | |
351 + return ((accum[0] * zInv * zInv) % p, (accum[1] * zInv * zInv * zInv) % p) | |
352 + | |
353 + | |
354 +def _scalarBaseMult(k): | |
355 + return _scalarMult(k, basePoint) | |
356 + | |
357 + | |
358 +def _decodeBigEndian(b): | |
359 + return sum([ord(b[len(b) - i - 1]) << 8 * i for i in range(len(b))]) | |
360 + | |
361 + | |
362 +def _encodeBigEndian(n): | |
363 + b = [] | |
364 + while n != 0: | |
365 + b.append(chr(n & 0xff)) | |
366 + n >>= 8 | |
367 + | |
368 + if len(b) == 0: | |
369 + b.append(0) | |
370 + b.reverse() | |
371 + | |
372 + return "".join(b) | |
373 + | |
374 + | |
375 +def _zeroPad(b, length): | |
376 + if len(b) < length: | |
377 + return ("\x00" * (length - len(b))) + b | |
378 + return b | |
379 + | |
380 + | |
381 +def _encodePoint(point): | |
382 + x = point[0] | |
383 + y = point[1] | |
384 + if (y * y) % p != (x * x * x - 3 * x + p256B) % p: | |
385 + raise "point not on curve" | |
386 + return "\x04" + _zeroPad(_encodeBigEndian(point[0]), 32) + _zeroPad( | |
387 + _encodeBigEndian(point[1]), 32) | |
388 + | |
389 + | |
390 +def _decodePoint(b): | |
391 + if len(b) != 1 + 32 + 32 or ord(b[0]) != 4: | |
392 + raise "invalid encoded ec point" | |
393 + x = _decodeBigEndian(b[1:33]) | |
394 + y = _decodeBigEndian(b[33:65]) | |
395 + if (y * y) % p != (x * x * x - 3 * x + p256B) % p: | |
396 + raise "point not on curve" | |
397 + return (x, y) | |
398 + | |
399 + | |
400 +def generatePublicPrivate(): | |
401 + """generatePublicPrivate returns a tuple of (X9.62 encoded public point, | |
402 + private value), where the private value is generated from os.urandom.""" | |
403 + private = _decodeBigEndian(os.urandom(40)) % order | |
404 + return _encodePoint(_scalarBaseMult(private)), private | |
405 + | |
406 + | |
407 +def generateSharedValue(theirPublic, private): | |
408 + """generateSharedValue returns the encoded x-coordinate of the | |
409 + multiplication of a peer's X9.62 encoded point and a private value.""" | |
410 + return _zeroPad( | |
411 + _encodeBigEndian(_scalarMult(private, _decodePoint(theirPublic))[0]), | |
412 + 32) | |
413 + | |
414 +if __name__ == "__main__": | |
415 + alice, alicePrivate = generatePublicPrivate() | |
416 + bob, bobPrivate = generatePublicPrivate() | |
417 + | |
418 + if generateSharedValue(alice, bobPrivate) != generateSharedValue( | |
419 + bob, alicePrivate): | |
420 + raise "simple DH test failed" | |
421 + | |
422 + (x, _) = _scalarBaseMult(1) | |
423 + | |
424 + for i in range(1000): | |
425 + (x, _) = _scalarBaseMult(x) | |
426 + | |
427 + if x != 2428281965257598569040586318034812501729437946720808289049534492833
635302706: | |
428 + raise "loop test failed" | |
OLD | NEW |