Skip to content

Commit 412a531

Browse files
authored
Merge pull request #517 from gstarovo/point_extension
EC point format extension
2 parents 4e16574 + c1b7ff2 commit 412a531

10 files changed

+343
-54
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ coverage.xml
99
pylint_report.txt
1010
build/
1111
docs/_build/
12-
htmlcov/
12+
htmlcov/

scripts/tls.py

+1
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ def printGoodConnection(connection, seconds):
406406
if connection.server_cert_compression_algo:
407407
print(" Server compression algorithm used: {0}".format(
408408
connection.server_cert_compression_algo))
409+
print(" Session used ec point format extension: {0}".format(connection.session.ec_point_format))
409410

410411
def printExporter(connection, expLabel, expLength):
411412
if expLabel is None:

test

Whitespace-only changes.

tests/tlstest.py

+147-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
from xmlrpc import client as xmlrpclib
4545
import ssl
4646
from tlslite import *
47-
from tlslite.constants import KeyUpdateMessageType, SignatureScheme
47+
from tlslite.constants import KeyUpdateMessageType, ECPointFormat, SignatureScheme
4848

4949
try:
5050
from tack.structures.Tack import Tack
@@ -303,6 +303,77 @@ def connect():
303303

304304
test_no += 1
305305

306+
print("Test {0} - client compressed/uncompressed - uncompressed, TLSv1.2".format(test_no))
307+
synchro.recv(1)
308+
connection = connect()
309+
settings = HandshakeSettings()
310+
settings.minVersion = (3, 3)
311+
settings.maxVersion = (3, 3)
312+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
313+
settings.keyShares = ["secp256r1"]
314+
connection.handshakeClientCert(settings=settings)
315+
testConnClient(connection)
316+
assert connection.session.ec_point_format == ECPointFormat.uncompressed
317+
connection.close()
318+
319+
test_no += 1
320+
321+
print("Test {0} - client compressed - compressed, TLSv1.2".format(test_no))
322+
synchro.recv(1)
323+
connection = connect()
324+
settings = HandshakeSettings()
325+
settings.minVersion = (3, 3)
326+
settings.maxVersion = (3, 3)
327+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
328+
settings.keyShares = ["secp256r1"]
329+
settings.ec_point_formats = [ECPointFormat.ansiX962_compressed_prime, ECPointFormat.uncompressed]
330+
connection.handshakeClientCert(settings=settings)
331+
testConnClient(connection)
332+
assert connection.session.ec_point_format == ECPointFormat.ansiX962_compressed_prime
333+
connection.close()
334+
335+
test_no += 1
336+
337+
print("Test {0} - client missing uncompressed - error, TLSv1.2".format(test_no))
338+
synchro.recv(1)
339+
connection = connect()
340+
settings = HandshakeSettings()
341+
settings.minVersion = (3, 3)
342+
settings.maxVersion = (3, 3)
343+
settings.ec_point_formats = [ECPointFormat.ansiX962_compressed_prime]
344+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
345+
settings.keyShares = ["secp256r1"]
346+
try:
347+
connection.handshakeClientCert(settings=settings)
348+
assert False
349+
except ValueError as e:
350+
assert "Uncompressed EC point format is not provided" in str(e)
351+
except TLSAbruptCloseError as e:
352+
pass
353+
connection.close()
354+
355+
test_no += 1
356+
357+
print("Test {0} - client comppressed char2 - error, TLSv1.2".format(test_no))
358+
synchro.recv(1)
359+
connection = connect()
360+
settings = HandshakeSettings()
361+
settings.minVersion = (3, 3)
362+
settings.maxVersion = (3, 3)
363+
settings.ec_point_formats = [ECPointFormat.ansiX962_compressed_char2]
364+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
365+
settings.keyShares = ["secp256r1"]
366+
try:
367+
connection.handshakeClientCert(settings=settings)
368+
assert False
369+
except ValueError as e:
370+
assert "Unknown EC point format provided: ['ansiX962_compressed_char2']" in str(e)
371+
except TLSAbruptCloseError as e:
372+
pass
373+
connection.close()
374+
375+
test_no += 1
376+
306377
print("Test {0} - mismatched ECDSA curve, TLSv1.2".format(test_no))
307378
synchro.recv(1)
308379
connection = connect()
@@ -2220,6 +2291,79 @@ def connect():
22202291

22212292
test_no += 1
22222293

2294+
print("Test {0} - server uncompressed ec format - uncompressed, TLSv1.2".format(test_no))
2295+
synchro.send(b'R')
2296+
connection = connect()
2297+
settings = HandshakeSettings()
2298+
settings.minVersion = (3, 1)
2299+
settings.maxVersion = (3, 3)
2300+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
2301+
settings.keyShares = ["secp256r1"]
2302+
settings.ec_point_formats = [ECPointFormat.uncompressed]
2303+
connection.handshakeServer(certChain=x509ecdsaChain,
2304+
privateKey=x509ecdsaKey, settings=settings)
2305+
testConnServer(connection)
2306+
assert connection.session.ec_point_format == ECPointFormat.uncompressed
2307+
connection.close()
2308+
2309+
test_no += 1
2310+
2311+
print("Test {0} - server compressed ec format - compressed, TLSv1.2".format(test_no))
2312+
synchro.send(b'R')
2313+
connection = connect()
2314+
settings = HandshakeSettings()
2315+
settings.minVersion = (3, 1)
2316+
settings.maxVersion = (3, 3)
2317+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
2318+
settings.keyShares = ["secp256r1"]
2319+
connection.handshakeServer(certChain=x509ecdsaChain,
2320+
privateKey=x509ecdsaKey, settings=settings)
2321+
testConnServer(connection)
2322+
assert connection.session.ec_point_format == ECPointFormat.ansiX962_compressed_prime
2323+
connection.close()
2324+
2325+
test_no +=1
2326+
2327+
print("Test {0} - server missing uncompressed in client - error, TLSv1.2".format(test_no))
2328+
synchro.send(b'R')
2329+
connection = connect()
2330+
settings = HandshakeSettings()
2331+
settings.minVersion = (3, 1)
2332+
settings.maxVersion = (3, 3)
2333+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
2334+
settings.keyShares = ["secp256r1"]
2335+
try:
2336+
connection.handshakeServer(certChain=x509ecdsaChain,
2337+
privateKey=x509ecdsaKey, settings=settings)
2338+
assert False
2339+
except ValueError as e:
2340+
assert "Uncompressed EC point format is not provided" in str(e)
2341+
except TLSAbruptCloseError as e:
2342+
pass
2343+
connection.close()
2344+
2345+
test_no +=1
2346+
2347+
print("Test {0} - client compressed char2 - error, TLSv1.2".format(test_no))
2348+
synchro.send(b'R')
2349+
connection = connect()
2350+
settings = HandshakeSettings()
2351+
settings.minVersion = (3, 1)
2352+
settings.maxVersion = (3, 3)
2353+
settings.eccCurves = ["secp256r1", "secp384r1", "secp521r1", "x25519", "x448"]
2354+
settings.keyShares = ["secp256r1"]
2355+
try:
2356+
connection.handshakeServer(certChain=x509ecdsaChain,
2357+
privateKey=x509ecdsaKey, settings=settings)
2358+
assert False
2359+
except ValueError as e:
2360+
assert "Unknown EC point format provided: [2]" in str(e)
2361+
except TLSAbruptCloseError as e:
2362+
pass
2363+
connection.close()
2364+
2365+
test_no +=1
2366+
22232367
print("Test {0} - mismatched ECDSA curve, TLSv1.2".format(test_no))
22242368
synchro.send(b'R')
22252369
connection = connect()
@@ -3509,7 +3653,7 @@ def heartbeat_response_check(message):
35093653
assert synchro.recv(1) == b'R'
35103654
connection.close()
35113655

3512-
test_no += 1
3656+
test_no +=1
35133657

35143658
print("Tests {0}-{1} - XMLRPXC server".format(test_no, test_no + 2))
35153659

@@ -3542,6 +3686,7 @@ def add(self, x, y): return x + y
35423686

35433687
synchro.close()
35443688
synchroSocket.close()
3689+
35453690
test_no += 2
35463691

35473692
print("Test succeeded")

tlslite/handshakesettings.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
"""Class for setting handshake parameters."""
99

10-
from .constants import CertificateType
10+
from .constants import CertificateType, ECPointFormat
1111
from .utils import cryptomath
1212
from .utils import cipherfactory
1313
from .utils.compat import ecdsaAllCurves, int_types, ML_KEM_AVAILABLE
@@ -74,7 +74,8 @@
7474
TICKET_CIPHERS = ["chacha20-poly1305", "aes256gcm", "aes128gcm", "aes128ccm",
7575
"aes128ccm_8", "aes256ccm", "aes256ccm_8"]
7676
PSK_MODES = ["psk_dhe_ke", "psk_ke"]
77-
77+
EC_POINT_FORMATS = [ECPointFormat.ansiX962_compressed_prime,
78+
ECPointFormat.uncompressed]
7879
ALL_COMPRESSION_ALGOS_SEND = ["zlib"]
7980
if compression_algo_impls["brotli_compress"]:
8081
ALL_COMPRESSION_ALGOS_SEND.append('brotli')
@@ -395,6 +396,10 @@ class HandshakeSettings(object):
395396
option is for when a certificate was received/decompressed by this
396397
peer.
397398
399+
400+
:vartype ec_point_formats: list
401+
:ivar ec_point_formats: Enabled point format extension for
402+
elliptic curves.
398403
"""
399404

400405
def _init_key_settings(self):
@@ -442,6 +447,7 @@ def _init_misc_extensions(self):
442447
# resumed connections (as tickets are single-use in TLS 1.3
443448
self.ticket_count = 2
444449
self.record_size_limit = 2**14 + 1 # TLS 1.3 includes content type
450+
self.ec_point_formats = list(EC_POINT_FORMATS)
445451

446452
# Certificate compression
447453
self.certificate_compression_send = list(ALL_COMPRESSION_ALGOS_SEND)
@@ -652,6 +658,14 @@ def _sanityCheckExtensions(other):
652658
not 64 <= other.record_size_limit <= 2**14 + 1:
653659
raise ValueError("record_size_limit cannot exceed 2**14+1 bytes")
654660

661+
bad_ec_ext = [ECPointFormat.toStr(rep) for rep in other.ec_point_formats if
662+
rep not in EC_POINT_FORMATS]
663+
if bad_ec_ext:
664+
raise ValueError("Unknown EC point format provided: "
665+
"{0}".format(bad_ec_ext))
666+
if ECPointFormat.uncompressed not in other.ec_point_formats:
667+
raise ValueError("Uncompressed EC point format is not provided")
668+
655669
HandshakeSettings._sanityCheckEMSExtension(other)
656670

657671
if other.certificate_compression_send:
@@ -746,6 +760,7 @@ def _copy_extension_settings(self, other):
746760
other.sendFallbackSCSV = self.sendFallbackSCSV
747761
other.useEncryptThenMAC = self.useEncryptThenMAC
748762
other.usePaddingExtension = self.usePaddingExtension
763+
other.ec_point_formats = self.ec_point_formats
749764
# session tickets
750765
other.padding_cb = self.padding_cb
751766
other.ticketKeys = self.ticketKeys

0 commit comments

Comments
 (0)