Commit 03f44b97 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Initial incomplete TLS 1.3 certificate request support.



This adds partial support for TLS 1.3 certificate request message.

The request context and extensions are currently ignored on receive
and set to zero length on send.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2728)
parent 013bc448
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2503,6 +2503,7 @@ int ERR_load_SSL_strings(void);
# define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN             204
# define SSL_R_EXCESSIVE_MESSAGE_SIZE                     152
# define SSL_R_EXTRA_DATA_IN_MESSAGE                      153
# define SSL_R_EXT_LENGTH_MISMATCH                        162
# define SSL_R_FAILED_TO_INIT_ASYNC                       405
# define SSL_R_FRAGMENTED_CLIENT_HELLO                    401
# define SSL_R_GOT_A_FIN_BEFORE_A_CCS                     154
+1 −0
Original line number Diff line number Diff line
@@ -565,6 +565,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
     "error setting tlsa base domain"},
    {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"},
    {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"},
    {ERR_REASON(SSL_R_EXT_LENGTH_MISMATCH), "ext length mismatch"},
    {ERR_REASON(SSL_R_FAILED_TO_INIT_ASYNC), "failed to init async"},
    {ERR_REASON(SSL_R_FRAGMENTED_CLIENT_HELLO), "fragmented client hello"},
    {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"},
+49 −15
Original line number Diff line number Diff line
@@ -2196,21 +2196,38 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
{
    int ret = MSG_PROCESS_ERROR;
    unsigned int list_len, i, name_len;
    unsigned int i, name_len;
    X509_NAME *xn = NULL;
    const unsigned char *namestart, *namebytes;
    STACK_OF(X509_NAME) *ca_sk = NULL;
    PACKET ctypes;
    PACKET cadns;

    if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) {
        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (SSL_IS_TLS13(s)) {
        PACKET reqctx;

        /* Free and zero certificate types: it is not present in TLS 1.3 */
        OPENSSL_free(s->s3->tmp.ctype);
        s->s3->tmp.ctype = NULL;
        s->s3->tmp.ctype_len = 0;
        /* TODO(TLS1.3) need to process request context, for now ignore */
        if (!PACKET_get_length_prefixed_1(pkt, &reqctx)) {
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                   SSL_R_LENGTH_MISMATCH);
            goto err;
        }
    } else {
        PACKET ctypes;

        /* get the certificate types */
        if (!PACKET_get_length_prefixed_1(pkt, &ctypes)) {
            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                   SSL_R_LENGTH_MISMATCH);
            goto err;
        }

@@ -2218,6 +2235,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
            goto err;
        }
    }

    if (SSL_USE_SIGALGS(s)) {
        PACKET sigalgs;
@@ -2246,16 +2264,15 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
    }

    /* get the CA RDNs */
    if (!PACKET_get_net_2(pkt, &list_len)
        || PACKET_remaining(pkt) != list_len) {
    if (!PACKET_get_length_prefixed_2(pkt, &cadns)) {
        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
        goto err;
    }

    while (PACKET_remaining(pkt)) {
        if (!PACKET_get_net_2(pkt, &name_len)
            || !PACKET_get_bytes(pkt, &namebytes, name_len)) {
    while (PACKET_remaining(&cadns)) {
        if (!PACKET_get_net_2(&cadns, &name_len)
            || !PACKET_get_bytes(&cadns, &namebytes, name_len)) {
            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                   SSL_R_LENGTH_MISMATCH);
@@ -2283,6 +2300,23 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
        }
        xn = NULL;
    }
    /* TODO(TLS1.3) need to parse and process extensions, for now ignore */
    if (SSL_IS_TLS13(s)) {
        PACKET reqexts;

        if (!PACKET_get_length_prefixed_2(pkt, &reqexts)) {
            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                   SSL_R_EXT_LENGTH_MISMATCH);
            goto err;
        }
    }

    if (PACKET_remaining(pkt) != 0) {
        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
        goto err;
    }

    /* we should setup a certificate to return.... */
    s->s3->tmp.cert_req = 1;
+23 −7
Original line number Diff line number Diff line
@@ -2448,13 +2448,22 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
    int i;
    STACK_OF(X509_NAME) *sk = NULL;

    if (SSL_IS_TLS13(s)) {
        /* TODO(TLS1.3) for now send empty request context */
        if (!WPACKET_put_bytes_u8(pkt, 0)) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
                   ERR_R_INTERNAL_ERROR);
            goto err;
        }
    } else {
        /* get the list of acceptable cert types */
        if (!WPACKET_start_sub_packet_u8(pkt)
            || !ssl3_get_req_cert_type(s, pkt)
            || !WPACKET_close(pkt)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
            || !ssl3_get_req_cert_type(s, pkt) || !WPACKET_close(pkt)) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
                   ERR_R_INTERNAL_ERROR);
            goto err;
        }
    }

    if (SSL_USE_SIGALGS(s)) {
        const uint16_t *psigs;
@@ -2494,11 +2503,18 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
        }
    }
    /* else no CA names */

    if (!WPACKET_close(pkt)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    /*
     * TODO(TLS1.3) implement configurable certificate_extensions
     * For now just send zero length extensions.
     */
    if (SSL_IS_TLS13(s) && !WPACKET_put_bytes_u16(pkt, 0)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    s->s3->tmp.cert_request = 1;