Moving ssl_check_leaf_certificate to ssl_cert.
Change-Id: I9ec1a8c87e29ffd4fabef68beb6d094aa7d9a215 Reviewed-on: https://boringssl-review.googlesource.com/8795 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
parent
2aad406b1b
commit
bf5aa846d6
@ -922,49 +922,6 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ssl3_check_leaf_certificate returns one if |leaf| is a suitable leaf server
|
|
||||||
* certificate for |ssl|. Otherwise, it returns zero and pushes an error on the
|
|
||||||
* error queue. */
|
|
||||||
static int ssl3_check_leaf_certificate(SSL *ssl, X509 *leaf) {
|
|
||||||
int ret = 0;
|
|
||||||
EVP_PKEY *pkey = X509_get_pubkey(leaf);
|
|
||||||
if (pkey == NULL) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the certificate's type matches the cipher. */
|
|
||||||
const SSL_CIPHER *cipher = ssl->s3->tmp.new_cipher;
|
|
||||||
int expected_type = ssl_cipher_get_key_type(cipher);
|
|
||||||
assert(expected_type != EVP_PKEY_NONE);
|
|
||||||
if (pkey->type != expected_type) {
|
|
||||||
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cipher->algorithm_auth & SSL_aECDSA) {
|
|
||||||
/* TODO(davidben): This behavior is preserved from upstream. Should key
|
|
||||||
* usages be checked in other cases as well? */
|
|
||||||
/* This call populates the ex_flags field correctly */
|
|
||||||
X509_check_purpose(leaf, -1, 0);
|
|
||||||
if ((leaf->ex_flags & EXFLAG_KUSAGE) &&
|
|
||||||
!(leaf->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
|
|
||||||
OPENSSL_PUT_ERROR(SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tls1_check_ec_cert(ssl, leaf)) {
|
|
||||||
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
err:
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssl3_get_server_certificate(SSL *ssl) {
|
static int ssl3_get_server_certificate(SSL *ssl) {
|
||||||
int ret =
|
int ret =
|
||||||
ssl->method->ssl_get_message(ssl, SSL3_MT_CERTIFICATE, ssl_hash_message);
|
ssl->method->ssl_get_message(ssl, SSL3_MT_CERTIFICATE, ssl_hash_message);
|
||||||
@ -988,7 +945,7 @@ static int ssl3_get_server_certificate(SSL *ssl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
X509 *leaf = sk_X509_value(chain, 0);
|
X509 *leaf = sk_X509_value(chain, 0);
|
||||||
if (!ssl3_check_leaf_certificate(ssl, leaf)) {
|
if (!ssl_check_leaf_certificate(ssl, leaf)) {
|
||||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -768,6 +768,11 @@ STACK_OF(X509_NAME) *
|
|||||||
* on error. */
|
* on error. */
|
||||||
int ssl_add_client_CA_list(SSL *ssl, CBB *cbb);
|
int ssl_add_client_CA_list(SSL *ssl, CBB *cbb);
|
||||||
|
|
||||||
|
/* ssl_check_leaf_certificate returns one if |leaf| is a suitable leaf server
|
||||||
|
* certificate for |ssl|. Otherwise, it returns zero and pushes an error on the
|
||||||
|
* error queue. */
|
||||||
|
int ssl_check_leaf_certificate(SSL *ssl, X509 *leaf);
|
||||||
|
|
||||||
|
|
||||||
/* Underdocumented functions.
|
/* Underdocumented functions.
|
||||||
*
|
*
|
||||||
|
@ -114,6 +114,7 @@
|
|||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
@ -727,3 +728,43 @@ int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
|
|||||||
*out_chain = ssl->cert->chain;
|
*out_chain = ssl->cert->chain;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ssl_check_leaf_certificate(SSL *ssl, X509 *leaf) {
|
||||||
|
int ret = 0;
|
||||||
|
EVP_PKEY *pkey = X509_get_pubkey(leaf);
|
||||||
|
if (pkey == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the certificate's type matches the cipher. */
|
||||||
|
const SSL_CIPHER *cipher = ssl->s3->tmp.new_cipher;
|
||||||
|
int expected_type = ssl_cipher_get_key_type(cipher);
|
||||||
|
assert(expected_type != EVP_PKEY_NONE);
|
||||||
|
if (pkey->type != expected_type) {
|
||||||
|
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cipher->algorithm_auth & SSL_aECDSA) {
|
||||||
|
/* TODO(davidben): This behavior is preserved from upstream. Should key
|
||||||
|
* usages be checked in other cases as well? */
|
||||||
|
/* This call populates the ex_flags field correctly */
|
||||||
|
X509_check_purpose(leaf, -1, 0);
|
||||||
|
if ((leaf->ex_flags & EXFLAG_KUSAGE) &&
|
||||||
|
!(leaf->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
|
||||||
|
OPENSSL_PUT_ERROR(SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tls1_check_ec_cert(ssl, leaf)) {
|
||||||
|
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user