Commit 703bcee0 authored by Matt Caswell's avatar Matt Caswell
Browse files

Convert Sigalgs processing to use ints



In TLSv1.2 an individual sig alg is represented by 1 byte for the hash
and 1 byte for the signature. In TLSv1.3 each sig alg is represented by
two bytes, where the two bytes together represent a single hash and
signature combination. This converts the internal representation of sigalgs
to use a single int for the pair, rather than a pair of bytes.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2157)
parent 5f9b64a2
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -141,20 +141,23 @@ CERT *ssl_cert_dup(CERT *cert)

    /* Configured sigalgs copied across */
    if (cert->conf_sigalgs) {
        ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
        ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen
                                           * sizeof(*cert->conf_sigalgs));
        if (ret->conf_sigalgs == NULL)
            goto err;
        memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen);
        memcpy(ret->conf_sigalgs, cert->conf_sigalgs,
               cert->conf_sigalgslen * sizeof(*cert->conf_sigalgs));
        ret->conf_sigalgslen = cert->conf_sigalgslen;
    } else
        ret->conf_sigalgs = NULL;

    if (cert->client_sigalgs) {
        ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen);
        ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen
                                             * sizeof(*cert->client_sigalgs));
        if (ret->client_sigalgs == NULL)
            goto err;
        memcpy(ret->client_sigalgs, cert->client_sigalgs,
               cert->client_sigalgslen);
               cert->client_sigalgslen * sizeof(*cert->client_sigalgs));
        ret->client_sigalgslen = cert->client_sigalgslen;
    } else
        ret->client_sigalgs = NULL;
+32 −8
Original line number Diff line number Diff line
@@ -1243,7 +1243,7 @@ typedef struct ssl3_state_st {
         * algorithms extension for server or as part of a certificate
         * request for client.
         */
        unsigned char *peer_sigalgs;
        unsigned int *peer_sigalgs;
        /* Size of above array */
        size_t peer_sigalgslen;
        /* Digest peer uses for signing */
@@ -1512,7 +1512,7 @@ typedef struct cert_st {
     * the client hello as the supported signature algorithms extension. For
     * servers it represents the signature algorithms we are willing to use.
     */
    unsigned char *conf_sigalgs;
    unsigned int *conf_sigalgs;
    /* Size of above array */
    size_t conf_sigalgslen;
    /*
@@ -1522,7 +1522,7 @@ typedef struct cert_st {
     * represents the signature algortithms we are willing to use for client
     * authentication.
     */
    unsigned char *client_sigalgs;
    unsigned int *client_sigalgs;
    /* Size of above array */
    size_t client_sigalgslen;
    /*
@@ -1683,6 +1683,30 @@ typedef enum tlsext_index_en {
 */
#define TLSEXT_STATUSTYPE_nothing  -1

/* Sigalgs values */
#define TLSEXT_SIGALG_ecdsa_secp256r1_sha256                    0x0403
#define TLSEXT_SIGALG_ecdsa_secp384r1_sha384                    0x0503
#define TLSEXT_SIGALG_ecdsa_secp521r1_sha512                    0x0603
#define TLSEXT_SIGALG_ecdsa_sha1                                0x0203
#define TLSEXT_SIGALG_rsa_pss_sha256                            0x0804
#define TLSEXT_SIGALG_rsa_pss_sha384                            0x0805
#define TLSEXT_SIGALG_rsa_pss_sha512                            0x0806
#define TLSEXT_SIGALG_rsa_pkcs1_sha256                          0x0401
#define TLSEXT_SIGALG_rsa_pkcs1_sha384                          0x0501
#define TLSEXT_SIGALG_rsa_pkcs1_sha512                          0x0601
#define TLSEXT_SIGALG_rsa_pkcs1_sha1                            0x0201
#define TLSEXT_SIGALG_dsa_sha256                                0x0402
#define TLSEXT_SIGALG_dsa_sha384                                0x0502
#define TLSEXT_SIGALG_dsa_sha512                                0x0602
#define TLSEXT_SIGALG_dsa_sha1                                  0x0202
#define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256       0xeeee
#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512       0xefef
#define TLSEXT_SIGALG_gostr34102001_gostr3411                   0xeded

/* A dummy signature value not valid for TLSv1.2 signature algs */
#define TLSEXT_signature_rsa_pss                                0x0101


#define MAX_COMPRESSIONS_SIZE   255

typedef struct {
@@ -2152,12 +2176,12 @@ __owur EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md);
void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
__owur long ssl_get_algorithm2(SSL *s);
__owur int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
                              const unsigned char *psig, size_t psiglen);
__owur int tls1_save_sigalgs(SSL *s, const unsigned char *data, size_t dsize);
                              const unsigned int *psig, size_t psiglen);
__owur int tls1_save_sigalgs(SSL *s, PACKET *pkt);
__owur int tls1_process_sigalgs(SSL *s);
__owur size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs);
__owur int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
                                   const unsigned char *sig, EVP_PKEY *pkey);
__owur size_t tls12_get_psigalgs(SSL *s, const unsigned int **psigs);
__owur int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig,
                                   EVP_PKEY *pkey);
void ssl_set_client_disabled(SSL *s);
__owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);

+1 −1
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
                                int *al)
{
    size_t salglen;
    const unsigned char *salg;
    const unsigned int *salg;

    if (!SSL_CLIENT_USE_SIGALGS(s))
        return 1;
+2 −4
Original line number Diff line number Diff line
@@ -204,15 +204,13 @@ int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
    PACKET supported_sig_algs;

    if (!PACKET_as_length_prefixed_2(pkt, &supported_sig_algs)
            || (PACKET_remaining(&supported_sig_algs) % 2) != 0
            || PACKET_remaining(&supported_sig_algs) == 0) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    if (!s->hit && !tls1_save_sigalgs(s, PACKET_data(&supported_sig_algs),
                                      PACKET_remaining(&supported_sig_algs))) {
        *al = TLS1_AD_INTERNAL_ERROR;
    if (!s->hit && !tls1_save_sigalgs(s, &supported_sig_algs)) {
        *al = TLS1_AD_DECODE_ERROR;
        return 0;
    }

+8 −6
Original line number Diff line number Diff line
@@ -1880,14 +1880,15 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
        }

        if (SSL_USE_SIGALGS(s)) {
            const unsigned char *sigalgs;
            unsigned int sigalg;
            int rv;
            if (!PACKET_get_bytes(pkt, &sigalgs, 2)) {

            if (!PACKET_get_net_2(pkt, &sigalg)) {
                al = SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
                goto err;
            }
            rv = tls12_check_peer_sigalg(&md, s, sigalgs, pkey);
            rv = tls12_check_peer_sigalg(&md, s, sigalg, pkey);
            if (rv == -1) {
                al = SSL_AD_INTERNAL_ERROR;
                goto err;
@@ -2026,8 +2027,9 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
        s->s3->tmp.ctype[i] = data[i];

    if (SSL_USE_SIGALGS(s)) {
        if (!PACKET_get_net_2(pkt, &list_len)
            || !PACKET_get_bytes(pkt, &data, list_len)) {
        PACKET sigalgs;

        if (!PACKET_get_length_prefixed_2(pkt, &sigalgs)) {
            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                   SSL_R_LENGTH_MISMATCH);
@@ -2039,7 +2041,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
            s->s3->tmp.md[i] = NULL;
            s->s3->tmp.valid_flags[i] = 0;
        }
        if ((list_len & 1) || !tls1_save_sigalgs(s, data, list_len)) {
        if (!tls1_save_sigalgs(s, &sigalgs)) {
            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                   SSL_R_SIGNATURE_ALGORITHMS_ERROR);
Loading