Revise server-side ECDSA certificate checks.
This is in preparation for simplifying tls1_check_group_id, called by
tls1_check_ec_cert, which, in turn, is in preparation for moving the
peer group list to SSL_HANDSHAKE.
It also helps with bug #55. Move the key usage check to the certificate
configuration sanity check. There's no sense in doing it late. Also
remove the ECDSA peer curve check as we configure certificates
externally. With only one certificate, there's no sense in trying to
remove it.
BUG=55
Change-Id: I8c116337770d96cc9cfd4b4f0ca7939a4f05a1a9
Reviewed-on: https://boringssl-review.googlesource.com/11524
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 3a64deb..9c9a0df 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -151,7 +151,6 @@
#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
-#include <openssl/x509v3.h>
#include "internal.h"
#include "../crypto/internal.h"
@@ -2046,17 +2045,7 @@
mask_k |= SSL_kRSA;
mask_a |= SSL_aRSA;
} else if (ssl_is_ecdsa_key_type(type)) {
- /* An ECC certificate may be usable for ECDSA cipher suites depending on
- * the key usage extension and on the client's group preferences. */
- X509 *x = ssl->cert->x509;
- /* This call populates extension flags (ex_flags). */
- X509_check_purpose(x, -1, 0);
- int ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
- ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
- : 1;
- if (ecdsa_ok && tls1_check_ec_cert(ssl, x)) {
- mask_a |= SSL_aECDSA;
- }
+ mask_a |= SSL_aECDSA;
}
}
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index 6f8ceae..03f6441 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -65,6 +65,7 @@
#include <openssl/mem.h>
#include <openssl/type_check.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include "internal.h"
@@ -217,6 +218,19 @@
return 0;
}
+ /* An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
+ * certificates, so sanity-check the key usage extension. */
+ if (pkey->type == EVP_PKEY_EC) {
+ /* This call populates extension flags (ex_flags). */
+ X509_check_purpose(x, -1, 0);
+ if ((x->ex_flags & EXFLAG_KUSAGE) &&
+ !(x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ EVP_PKEY_free(pkey);
+ return 0;
+ }
+ }
+
if (c->privatekey != NULL) {
/* Sanity-check that the private key and the certificate match, unless the
* key is opaque (in case of, say, a smartcard). */