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)
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;
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];
/*
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 */
/*
/* 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
__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);
* 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;
}
break;
}
/* Allow fallback to SHA1 if not strict mode */
- if (i == sent_sigslen
- && (tls_sigalg_get_hash(sig) != NID_sha1
- || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
+ 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;
* 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;
}