Add no signing flag.
authorDr. Stephen Henson <steve@openssl.org>
Tue, 23 Feb 2016 15:02:34 +0000 (15:02 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 28 Feb 2016 22:54:53 +0000 (22:54 +0000)
Add a flag to EC_METHOD for curves which do not support signing.
New function EC_KEY_can_sign() returns 1 is key can be used for signing.
Return an explicit error is an attempt is made to sign with
no signing curves.

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Emilia Käsper <emilia@openssl.org>
crypto/ec/ec_25519.c
crypto/ec/ec_key.c
crypto/ec/ec_lcl.h
crypto/ec/ecdsa_ossl.c
include/openssl/ec.h

index 539a8e1..3e6609a 100644 (file)
@@ -326,7 +326,7 @@ static int x25519_compute_key(void *out, size_t outlen,
 const EC_METHOD *ec_x25519_meth(void)
 {
     static const EC_METHOD ret = {
-        EC_FLAGS_CUSTOM_CURVE,
+        EC_FLAGS_CUSTOM_CURVE | EC_FLAGS_NO_SIGN,
         NID_undef,
         x25519_group_init,      /* group_init */
         0,                      /* group_finish */
index f09edbb..e59d2c6 100644 (file)
@@ -631,3 +631,11 @@ size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
     *pbuf = buf;
     return len;
 }
+
+int EC_KEY_can_sign(const EC_KEY *eckey)
+{
+    if (eckey->group == NULL || eckey->group->meth == NULL
+        || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
+        return 0;
+    return 1;
+}
index efdfabe..42cf079 100644 (file)
@@ -86,6 +86,9 @@
 /* Use custom formats for EC_GROUP, EC_POINT and EC_KEY */
 #define EC_FLAGS_CUSTOM_CURVE   0x2
 
+/* Curve does not support signing operations */
+#define EC_FLAGS_NO_SIGN        0x4
+
 /*
  * Structure details are not part of the exported interface, so all this may
  * change in future versions.
index 3e755fb..113bcdf 100644 (file)
@@ -95,6 +95,11 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
         return 0;
     }
 
+    if (!EC_KEY_can_sign(eckey)) {
+        ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+        return 0;
+    }
+
     if (ctx_in == NULL) {
         if ((ctx = BN_CTX_new()) == NULL) {
             ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
@@ -254,6 +259,11 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
         return NULL;
     }
 
+    if (!EC_KEY_can_sign(eckey)) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+        return NULL;
+    }
+
     ret = ECDSA_SIG_new();
     if (ret == NULL) {
         ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
@@ -391,6 +401,11 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
         return -1;
     }
 
+    if (!EC_KEY_can_sign(eckey)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+        return -1;
+    }
+
     ctx = BN_CTX_new();
     if (ctx == NULL) {
         ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
index 8530c56..ccd410f 100644 (file)
@@ -901,6 +901,12 @@ int EC_KEY_generate_key(EC_KEY *key);
  */
 int EC_KEY_check_key(const EC_KEY *key);
 
+/** Indicates if an EC_KEY can be used for signing.
+ *  \param  key  the EC_KEY object
+ *  \return 1 if can can sign and 0 otherwise.
+ */
+int EC_KEY_can_sign(const EC_KEY *eckey);
+
 /** Sets a public key from affine coordindates performing
  *  necessary NIST PKV tests.
  *  \param  key  the EC_KEY object