On 9/12/2013 10:46 AM, Dr. Stephen Henson wrote:
On Thu, Sep 12, 2013, Douglas E. Engert wrote:



On 9/11/2013 2:01 PM, Stephen Henson via RT wrote:

[snip]

Yes similar to that but with a few minor changes.

The analogous functions for EVP_PKEY_METHOD are called "set" and not "put".
For consistency we could use something like ECDSA_METHOD_set_sign() and so on.

I'd suggest a flag to indicate the structure has been malloced so a call to
ECDSA_METHOD_free with a static structure ends up a no op instead of
undefined.

ECDSA_METHOD_new could take a ECDSA_METHOD * argument which is an optional
method which is copied into the result. If things like crypto accelerators
start implementing their own default methods then ECDSA_get_default_method
might not be what you expect (it can already change for the FIPS versions of
OpenSSL). Applications could use ECDSA_OpenSSL() to avoid such surprises.

Steve.

OK, here is a new patch, using your suggestions. It is to 1.0.1e
and has been tested with additional mods to the OpenSC libp11 and OpenSC
engine_pkcs11.

Only the ECDSA_METHOD_new, ECDSA_METHOD_set_do_sign and ECDSA_METHOD_set_do_sign
have been tested.

The ECDSA_METHOD structure also has an apps_data that is not used.



--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org


--

 Douglas E. Engert  <deeng...@anl.gov>
 Argonne National Laboratory
 9700 South Cass Avenue
 Argonne, Illinois  60439
 (630) 252-5444
--- openssl-1.0.1e/crypto/ecdsa/,ecdsa.h	Mon Feb 11 09:26:04 2013
+++ openssl-1.0.1e/crypto/ecdsa/ecdsa.h	Mon Sep 16 09:27:08 2013
@@ -229,6 +229,48 @@
 void 	  *ECDSA_get_ex_data(EC_KEY *d, int idx);
 
 
+/** Allocates and initialize a ECDSA_METHOD structure
+ *  \param ecdsa_method pointer to ECDSA_METRHOD to copy.  (May be NULL)
+ *  \return pointer to a ECDSA_METHOD structure or NULL if an error occurred
+ */
+
+ECDSA_METHOD *ECDSA_METHOD_new(ECDSA_METHOD *ecdsa_method);
+
+/** frees a ECDSA_METHOD structure
+ *  \param  ecdsa_method  pointer to the ECDSA_METHOD structure
+ */
+void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method);
+
+/**  Set the ECDSA_do_sign function in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  ecdsa_do_sign a funtion of type ECDSA_do_sign
+ *   \return 1 on success and 0 otherwise
+ */
+
+int ECDSA_METHOD_set_do_sign(ECDSA_METHOD *ecdsa_method,
+        ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len,
+                const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey));
+
+/**  Set the  ECDSA_sign_setup function in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  ecdsa_sign_setup a funtion of type ECDSA_sign_setup
+ *   \return 1 on success and 0 otherwise
+ */
+
+int ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method,
+        int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
+                BIGNUM **r));
+
+/**  Set the ECDSA_do_verify function in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  ecdsa_do_verify a funtion of type ECDSA_do_verify
+ *   \return 1 on success and 0 otherwise
+ */
+
+int ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method,
+        int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len,
+                const ECDSA_SIG *sig, EC_KEY *eckey));
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -243,6 +285,7 @@
 #define ECDSA_F_ECDSA_DO_SIGN				 101
 #define ECDSA_F_ECDSA_DO_VERIFY				 102
 #define ECDSA_F_ECDSA_SIGN_SETUP			 103
+#define ECDSA_F_ECDSA_METHOD_NEW	                 105
 
 /* Reason codes. */
 #define ECDSA_R_BAD_SIGNATURE				 100
--- openssl-1.0.1e/crypto/ecdsa/,ecs_locl.h	Mon Feb 11 09:26:04 2013
+++ openssl-1.0.1e/crypto/ecdsa/ecs_locl.h	Thu Sep 12 14:19:09 2013
@@ -82,6 +82,11 @@
 	char *app_data;
 	};
 
+/* The ECDSA_METHOD was allocated and can be freed */
+
+#define ECDSA_METHOD_FLAG_ALLOCATED 0x1
+
+
 /* If this flag is set the ECDSA method is FIPS compliant and can be used
  * in FIPS mode. This is set in the validated module method. If an
  * application sets this flag in its own methods it is its responsibility
--- openssl-1.0.1e/crypto/ecdsa/,ecs_ossl.c	Mon Feb 11 09:26:04 2013
+++ openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c	Mon Sep 16 09:30:53 2013
@@ -481,3 +481,75 @@
 		EC_POINT_free(point);
 	return ret;
 }
+
+ECDSA_METHOD *ECDSA_METHOD_new(ECDSA_METHOD *ecdsa_meth)
+{
+	ECDSA_METHOD  *ret;
+
+	ret=(ECDSA_METHOD *)OPENSSL_malloc(sizeof(ECDSA_METHOD));
+	if (ret == NULL)
+	{
+		ECDSAerr(ECDSA_F_ECDSA_METHOD_NEW, ERR_R_MALLOC_FAILURE);
+		return(NULL);
+        }
+
+	if (ecdsa_meth)
+	{
+		*ret = *ecdsa_meth;
+	}
+	else
+	{
+		*ret = *ECDSA_get_default_method();
+		ret->app_data = NULL;
+	}
+	ret->name = "Cloned OpenSSL ECDSA method"; 
+	ret->flags |= ECDSA_METHOD_FLAG_ALLOCATED;
+
+	return ret;
+}
+
+
+int ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method,
+	ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len,
+		const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey))
+{
+	if (ecdsa_method)
+	{
+		ecdsa_method->ecdsa_do_sign = ecdsa_do_sign;
+		return 0;
+	}
+	return 1;
+}
+
+int ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method,
+	int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
+		BIGNUM **r))
+{
+	if (ecdsa_method)
+	{
+		ecdsa_method->ecdsa_sign_setup = ecdsa_sign_setup;
+		return 0;
+	}
+	return 1;
+
+}
+
+int ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method,
+	int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len,
+		const ECDSA_SIG *sig, EC_KEY *eckey))
+{
+	if (ecdsa_method)
+	{
+		ecdsa_method->ecdsa_do_verify = ecdsa_do_verify;
+		return 0;
+	}
+	return 1;
+}
+
+void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method)
+{
+	if (ecdsa_method->flags & ECDSA_METHOD_FLAG_ALLOCATED)
+		OPENSSL_free(ecdsa_method);
+}
+
+

Reply via email to