Skip to content

SSLContext.set_ecdh_curve() not accepting x25519 #77063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sruester mannequin opened this issue Feb 20, 2018 · 8 comments
Open

SSLContext.set_ecdh_curve() not accepting x25519 #77063

sruester mannequin opened this issue Feb 20, 2018 · 8 comments
Assignees
Labels
3.7 (EOL) end of life 3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes topic-SSL type-bug An unexpected behavior, bug, or error

Comments

@sruester
Copy link
Mannequin

sruester mannequin commented Feb 20, 2018

BPO 32882
Nosy @tiran, @sruester
PRs
  • bpo-32882: Added support for X25519 in SSLContext.set_ecdh_curve() #5770
  • gh-77063: Added support for X25519 in SSLContext.set_ecdh_curve() #5771
  • Superseder
  • bpo-32858: Improve OpenSSL ECDH support
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/tiran'
    closed_at = None
    created_at = <Date 2018-02-20.09:49:54.078>
    labels = ['expert-SSL', 'type-bug', '3.8', '3.9', '3.10', '3.11', '3.7']
    title = 'SSLContext.set_ecdh_curve() not accepting x25519'
    updated_at = <Date 2021-04-21.09:29:10.670>
    user = 'https://github.com/sruester'

    bugs.python.org fields:

    activity = <Date 2021-04-21.09:29:10.670>
    actor = 'sruester'
    assignee = 'christian.heimes'
    closed = False
    closed_date = None
    closer = None
    components = ['SSL']
    creation = <Date 2018-02-20.09:49:54.078>
    creator = 'sruester'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 32882
    keywords = ['patch']
    message_count = 3.0
    messages = ['312405', '312408', '391504']
    nosy_count = 2.0
    nosy_names = ['christian.heimes', 'sruester']
    pr_nums = ['5770', '5771']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = '32858'
    type = 'behavior'
    url = 'https://bugs.python.org/issue32882'
    versions = ['Python 2.7', 'Python 3.6', 'Python 3.7', 'Python 3.8', 'Python 3.9', 'Python 3.10', 'Python 3.11']

    @sruester
    Copy link
    Mannequin Author

    sruester mannequin commented Feb 20, 2018

    Using SSLContext.set_ecdh_curve() it is neither possible to choose X25519, nor to choose a list of curves to be used for key agreement.

    @sruester sruester mannequin assigned tiran Feb 20, 2018
    @sruester sruester mannequin added the topic-SSL label Feb 20, 2018
    @tiran
    Copy link
    Member

    tiran commented Feb 20, 2018

    This bug was originally the more generic issue bpo-32858.

    SSLContext.set_ecdh_curve() uses EC_KEY_new_by_curve_name() and SSL_CTX_set_tmp_ecdh() to configure the ECDH curve parameters. The current approach has multiple downsides. It doesn't work with X25519 and can only set one curve. OpenSSL 1.0.2+ has SSL_CTX_set1_curves_list(), which supports a list of curve names.

    Proposal:

    SSLContext.set_ecdh_curve() is changed from taking one curve name to an *arg of curve names. With OpenSSL 1.0.2+, 1..n curves are supported. For OpenSSL < 1.0.2 on 2.7-3.6, one curve is supported. Perhaps it makes sense to map an empty *arg to auto-configuration?

    I like to cover the issue in PEP-543, too.

    Cory,
    what do you think about another enum of IANA groups of EC groups, https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 ?

    @tiran tiran added 3.7 (EOL) end of life 3.8 (EOL) end of life type-bug An unexpected behavior, bug, or error labels Feb 20, 2018
    @sruester
    Copy link
    Mannequin Author

    sruester mannequin commented Apr 21, 2021

    PEP-543 was withdrawn in the meantime. Any suggestion how to proceed with this?

    @sruester sruester mannequin added 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes labels Apr 21, 2021
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @OrionCodeDev
    Copy link

    Any updates?

    @sla-te
    Copy link

    sla-te commented Jun 24, 2022

    +

    @gschaffner
    Copy link

    GH-103378 partially fixed this: set_ecdh_curve("X25519") now works on OpenSSL 3! it still doesn't work on OpenSSL 1, however. set_ecdh_curve also still only supports one group.

    @martinschmatz
    Copy link

    Is there interest in a PR which would add SSLContext.set_ecdh_curves_list() which under the hood would use (for e.g OpenSSL >v3) SSL_CTX_set1_curves_list() (actually the more modern SSL_CTX_set1_groups_list())?

    This would add the possibility to specify one or several curves (aka 'groups') by a colon separated string of curve names.

    As an alternative, one could change the existing code to avoid the somewhat cumbersome "string -> NID --> set single group" approach, but rather directly use the string value from the PyObject *name function argument and SSL_CTX_set1_groups_list().

    I'm fine either way, with a slight preference for the former: It introduces a new function, hence is guaranteed not to interfere with legacy code. But it's a new function which must be maintained going forward....

    @martinschmatz
    Copy link

    For the latter approach above, code would be replaced with this (tested on v3.11.5):

    static PyObject *
    _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name)
    /*[clinic end generated code: output=23022c196e40d7d2 input=c2bafb6f6e34726b]*/
    {
        PyObject *name_bytes;
    
        if (!PyUnicode_FSConverter(name, &name_bytes))
            return NULL;
        assert(PyBytes_Check(name_bytes));
    #if OPENSSL_VERSION_MAJOR < 3
        int nid;
        nid = OBJ_sn2nid(PyBytes_AS_STRING(name_bytes));
        Py_DECREF(name_bytes);
        if (nid == 0) {
            PyErr_Format(PyExc_ValueError,
                         "unknown elliptic curve name %R", name);
            return NULL;
        }
        EC_KEY *key = EC_KEY_new_by_curve_name(nid);
        if (key == NULL) {
            _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__);
            return NULL;
        }
        SSL_CTX_set_tmp_ecdh(self->ctx, key);
        EC_KEY_free(key);
    #else
        int res = SSL_CTX_set1_groups_list(self->ctx, PyBytes_AS_STRING(name_bytes));
        Py_DECREF(name_bytes);
        if (!res) {
            _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__);
            return NULL;
        }
    #endif
        Py_RETURN_NONE;
    }
    

    Remark: This will also enable to use the OQS OpenSSL provider to achieve a 'quantum-hard' TLS key agreement, e.g. using x25519_kyber768.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.7 (EOL) end of life 3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes topic-SSL type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    5 participants