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

Store table entry to peer signature algorithm.

parent 33d93417
Loading
Loading
Loading
Loading
+3 −13
Original line number Diff line number Diff line
@@ -3177,20 +3177,10 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
        return ssl_cert_set_cert_store(s->cert, parg, 1, larg);

    case SSL_CTRL_GET_PEER_SIGNATURE_NID:
        if (SSL_USE_SIGALGS(s)) {
            if (s->session) {
                const EVP_MD *sig;
                sig = s->s3->tmp.peer_md;
                if (sig) {
                    *(int *)parg = EVP_MD_type(sig);
                    return 1;
                }
            }
            return 0;
        }
        /* Might want to do something here for other versions */
        else
        if (s->s3->tmp.peer_sigalg == NULL)
            return 0;
        *(int *)parg = s->s3->tmp.peer_sigalg->hash;
        return 1;

    case SSL_CTRL_GET_SERVER_TMP_KEY:
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
+24 −23
Original line number Diff line number Diff line
@@ -1180,6 +1180,25 @@ struct ssl_st {
    CRYPTO_RWLOCK *lock;
};

/*
 * Structure containing table entry of values associated with the signature
 * algorithms (signature scheme) extension
*/
typedef struct sigalg_lookup_st {
    /* TLS 1.3 signature scheme name */
    const char *name;
    /* Raw value used in extension */
    uint16_t sigalg;
    /* NID of hash algorithm */
    int hash;
    /* NID of signature algorithm */
    int sig;
    /* Combined hash and signature NID, if any */
    int sigandhash;
    /* Required public key curve (ECDSA only) */
    int curve;
} SIGALG_LOOKUP;

typedef struct ssl3_state_st {
    long flags;
    size_t read_mac_secret_size;
@@ -1269,10 +1288,10 @@ typedef struct ssl3_state_st {
        uint16_t *peer_sigalgs;
        /* Size of above array */
        size_t peer_sigalgslen;
        /* Sigalg peer actualy uses */
        const SIGALG_LOOKUP *peer_sigalg;
        /* Digest peer uses for signing */
        const EVP_MD *peer_md;
        /* Signature type: public key type or EVP_PKEY_RSA_PSS for PSS */
        int peer_sigtype;
        /* Array of digests used for signing */
        const EVP_MD *md[SSL_PKEY_NUM];
        /*
@@ -1509,25 +1528,6 @@ typedef struct {
    size_t meths_count;
} custom_ext_methods;

/*
 * Structure containing table entry of values associated with the signature
 * algorithms (signature scheme) extension
*/
typedef struct sigalg_lookup_st {
    /* TLS 1.3 signature scheme name */
    const char *name;
    /* Raw value used in extension */
    uint16_t sigalg;
    /* NID of hash algorithm */
    int hash;
    /* NID of signature algorithm */
    int sig;
    /* Combined hash and signature NID, if any */
    int sigandhash;
    /* Required public key curve (ECDSA only) */
    int curve;
} SIGALG_LOOKUP;

typedef struct cert_st {
    /* Current active set */
    /*
@@ -1750,7 +1750,8 @@ typedef enum tlsext_index_en {
/* An invalid index into the TLSv1.3 PSK identities */
#define TLSEXT_PSK_BAD_IDENTITY                                 -1

#define SSL_USE_PSS(s) (s->s3->tmp.peer_sigtype == EVP_PKEY_RSA_PSS)
#define SSL_USE_PSS(s) (s->s3->tmp.peer_sigalg != NULL && \
                        s->s3->tmp.peer_sigalg->sig == EVP_PKEY_RSA_PSS)

/* A dummy signature value not valid for TLSv1.2 signature algs */
#define TLSEXT_signature_rsa_pss                                0x0101
@@ -2260,7 +2261,7 @@ __owur int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
__owur int tls1_save_sigalgs(SSL *s, PACKET *pkt);
__owur int tls1_process_sigalgs(SSL *s);
__owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs);
__owur int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey);
__owur int tls12_check_peer_sigalg(SSL *s, uint16_t, EVP_PKEY *pkey);
void ssl_set_client_disabled(SSL *s);
__owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);

+15 −14
Original line number Diff line number Diff line
@@ -823,23 +823,25 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
 * algorithms and if so set relevant digest and signature scheme in
 * s.
 */
int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey)
int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
{
    const uint16_t *sent_sigs;
    const EVP_MD *md = NULL;
    char sigalgstr[2];
    size_t sent_sigslen, i;
    int pkeyid = EVP_PKEY_id(pkey);
    int peer_sigtype;
    const SIGALG_LOOKUP *lu;

    /* Should never happen */
    if (pkeyid == -1)
        return -1;
    /* Check key type is consistent with signature */
    peer_sigtype = tls_sigalg_get_sig(sig);
    /* RSA keys can be used for RSA-PSS */
    if (pkeyid != peer_sigtype
        && (peer_sigtype != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA)) {
    lu = tls1_lookup_sigalg(sig);
    /*
     * Check sigalgs is known and key type is consistent with signature:
     * RSA keys can be used for RSA-PSS
     */
    if (lu == NULL || (pkeyid != lu->sig
        && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) {
        SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
        return 0;
    }
@@ -883,13 +885,12 @@ int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey)
            break;
    }
    /* Allow fallback to SHA1 if not strict mode */
    if (i == sent_sigslen
        && (tls_sigalg_get_hash(sig) != NID_sha1
    if (i == sent_sigslen && (lu->hash != NID_sha1
        || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
        SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
        return 0;
    }
    md = tls12_get_hash(tls_sigalg_get_hash(sig));
    md = tls12_get_hash(lu->hash);
    if (md == NULL) {
        SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
        return 0;
@@ -910,15 +911,15 @@ int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey)
     * Store the digest used so applications can retrieve it if they wish.
     */
    s->s3->tmp.peer_md = md;
    s->s3->tmp.peer_sigtype = peer_sigtype;
    s->s3->tmp.peer_sigalg = lu;
    return 1;
}

int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid)
{
    if (s->s3->tmp.peer_sigtype == NID_undef)
    if (s->s3->tmp.peer_sigalg == NULL)
        return 0;
    *pnid = s->s3->tmp.peer_sigtype;
    *pnid = s->s3->tmp.peer_sigalg->sig;
    return 1;
}