Skip to content

Commit feddb7d

Browse files
committed
Improved implementation for set_sigalgs
1 parent 60a9092 commit feddb7d

File tree

4 files changed

+77
-12
lines changed

4 files changed

+77
-12
lines changed

nassl/_nassl/nassl_SSL.c

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -813,20 +813,50 @@ static PyObject* nassl_SSL_set_ciphersuites(nassl_SSL_Object *self, PyObject *ar
813813
}
814814

815815

816-
// SSL_set1_sigalgs_list() is only available in OpenSSL 1.1.1
817-
static PyObject* nassl_SSL_set1_sigalgs_list(nassl_SSL_Object *self, PyObject *args)
816+
// SSL_set1_sigalgs() is only available in OpenSSL 1.1.1
817+
static PyObject* nassl_SSL_set1_sigalgs(nassl_SSL_Object *self, PyObject *args)
818818
{
819-
char *sigalgList;
820-
if (!PyArg_ParseTuple(args, "s", &sigalgList))
819+
int i = 0;
820+
PyObject *pyListOfOpensslNids;
821+
Py_ssize_t nidsCount = 0;
822+
int *listOfNids;
823+
824+
// Parse the Python list
825+
if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &pyListOfOpensslNids))
821826
{
822827
return NULL;
823828
}
824829

825-
if (!SSL_set1_sigalgs_list(self->ssl, sigalgList))
830+
// Extract each NID int from the list
831+
nidsCount = PyList_Size(pyListOfOpensslNids);
832+
listOfNids = (int *) PyMem_Malloc(nidsCount * sizeof(int));
833+
if (listOfNids == NULL)
834+
{
835+
return PyErr_NoMemory();
836+
}
837+
838+
for (i=0; i<nidsCount; i++)
839+
{
840+
PyObject *pyNid;
841+
int nid;
842+
843+
pyNid = PyList_GetItem(pyListOfOpensslNids, i);
844+
if ((pyNid == NULL) || (!PyLong_Check(pyNid)))
845+
{
846+
PyMem_Free(listOfNids);
847+
return NULL;
848+
}
849+
nid = PyLong_AsSize_t(pyNid);
850+
listOfNids[i] = nid;
851+
}
852+
853+
if (SSL_set1_sigalgs(self->ssl, listOfNids, nidsCount) != 1)
826854
{
855+
PyMem_Free(listOfNids);
827856
return raise_OpenSSL_error();
828857
}
829858

859+
PyMem_Free(listOfNids);
830860
Py_RETURN_NONE;
831861
}
832862

@@ -1199,8 +1229,8 @@ static PyMethodDef nassl_SSL_Object_methods[] =
11991229
{"set_ciphersuites", (PyCFunction)nassl_SSL_set_ciphersuites, METH_VARARGS,
12001230
"OpenSSL's SSL_set_ciphersuites()."
12011231
},
1202-
{"set1_sigalgs_list", (PyCFunction)nassl_SSL_set1_sigalgs_list, METH_VARARGS,
1203-
"OpenSSL's SSL_set1_sigalgs_list()."
1232+
{"set1_sigalgs", (PyCFunction)nassl_SSL_set1_sigalgs, METH_VARARGS,
1233+
"OpenSSL's SSL_set1_sigalgs()."
12041234
},
12051235
{"get0_verified_chain", (PyCFunction)nassl_SSL_get0_verified_chain, METH_NOARGS,
12061236
"OpenSSL's SSL_get0_verified_chain(). Returns an array of _nassl.X509 objects."

nassl/ephemeral_key_info.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ class OpenSslEvpPkeyEnum(IntEnum):
1212
EC = 408
1313
X25519 = 1034
1414
X448 = 1035
15+
RSA = 6
16+
DSA = 116
17+
RSA_PSS = 912
1518

1619

1720
class OpenSslEcNidEnum(IntEnum):

nassl/ssl_client.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from nassl._nassl import WantReadError, OpenSSLError, WantX509LookupError
77

88
from enum import IntEnum
9-
from typing import List, Any
9+
from typing import List, Any, Tuple
1010

1111
from typing import Protocol
1212

@@ -32,6 +32,17 @@ class OpenSslVerifyEnum(IntEnum):
3232
CLIENT_ONCE = 4
3333

3434

35+
class OpenSslDigestNidEnum(IntEnum):
36+
"""SSL digest algorithms used for the signature algorithm, per obj_mac.h."""
37+
38+
MD5 = 4
39+
SHA1 = 64
40+
SHA224 = 675
41+
SHA256 = 672
42+
SHA384 = 673
43+
SHA512 = 674
44+
45+
3546
class OpenSslVersionEnum(IntEnum):
3647
"""SSL version constants."""
3748

@@ -449,9 +460,10 @@ def set_ciphersuites(self, cipher_suites: str) -> None:
449460
# TODO(AD): Eventually merge this method with get/set_cipher_list()
450461
self._ssl.set_ciphersuites(cipher_suites)
451462

452-
def set_sigalgs(self, cipher_suites: str) -> None:
453-
"""Set the enabled signature algorithms, e.g. 'ECDSA+SHA256:RSA+SHA256'"""
454-
self._ssl.set1_sigalgs_list(cipher_suites)
463+
def set_sigalgs(self, sigalgs: List[Tuple[OpenSslDigestNidEnum, OpenSslEvpPkeyEnum]]) -> None:
464+
"""Set the enabled signature algorithms."""
465+
flattened_sigalgs = [item for sublist in sigalgs for item in sublist]
466+
self._ssl.set1_sigalgs(flattened_sigalgs)
455467

456468
def set_groups(self, supported_groups: List[OpenSslEcNidEnum]) -> None:
457469
"""Specify elliptic curves or DH groups that are supported by the client in descending order."""

tests/ssl_client_test.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
OpenSslVerifyEnum,
1212
SslClient,
1313
OpenSSLError,
14-
OpenSslEarlyDataStatusEnum,
14+
OpenSslEarlyDataStatusEnum, OpenSslDigestNidEnum,
1515
)
1616
from nassl.ephemeral_key_info import (
1717
OpenSslEvpPkeyEnum,
@@ -424,6 +424,26 @@ def test_set_ciphersuites(self):
424424
# And client's cipher suite was used
425425
assert "TLS_CHACHA20_POLY1305_SHA256" == ssl_client.get_current_cipher_name()
426426

427+
def test_set_sigalgs(self):
428+
with ModernOpenSslServer() as server:
429+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
430+
sock.settimeout(5)
431+
sock.connect((server.hostname, server.port))
432+
433+
ssl_client = SslClient(
434+
ssl_version=OpenSslVersionEnum.TLSV1_3,
435+
underlying_socket=sock,
436+
ssl_verify=OpenSslVerifyEnum.NONE,
437+
)
438+
# These signature algorithms are unsupported
439+
ssl_client.set_sigalgs([
440+
(OpenSslDigestNidEnum.SHA512, OpenSslEvpPkeyEnum.EC)
441+
])
442+
443+
with pytest.raises(OpenSSLError):
444+
ssl_client.do_handshake()
445+
ssl_client.shutdown()
446+
427447
@staticmethod
428448
def _create_tls_1_3_session(server_host: str, server_port: int) -> _nassl.SSL_SESSION:
429449
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

0 commit comments

Comments
 (0)