]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
openssl: Set curve name (OID) in EC_GROUP objects
authorTobias Brunner <tobias@strongswan.org>
Mon, 16 Sep 2013 13:00:21 +0000 (15:00 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 16 Sep 2013 13:23:11 +0000 (15:23 +0200)
To do so OIDs are registered with OpenSSL as NIDs.

The cleanup function is required in case of multiple plugin load/unload
cycles (e.g. in the Android app), where invalid mappings would remain
after the actual NIDs were destroyed with OBJ_cleanup().

src/libstrongswan/crypto/ec_params.h
src/libstrongswan/plugins/openssl/openssl_ec_util.c
src/libstrongswan/plugins/openssl/openssl_ec_util.h
src/libstrongswan/plugins/openssl/openssl_plugin.c

index 9ee3982516bb0cb3d1f43983146d2cfba54f3899..8de291969e162a881851453debcec5f835d6bd5e 100644 (file)
@@ -49,6 +49,8 @@ enum ec_curve_t {
        ECC_BP_384,
        /* ECC Brainpool 512-bit curve (RFC 5639), brainpoolP512r1 */
        ECC_BP_512,
+       /* Array helper */
+       ECC_MAX,
 };
 
 /**
index d340a5962410ee3eb245075c0419263f50a29351..da090168eae6f73c8ec6dc2da57381d184d6cf48 100644 (file)
 #include "openssl_ec_util.h"
 
 #include <openssl/bn.h>
+#include <openssl/objects.h>
+
+#include <asn1/oid.h>
+
+/**
+ * This is from asn1.h, which we can't include due to conflicting constants
+ */
+char* asn1_known_oid_to_string(int oid);
+
+/**
+ * Map from curve to OpenSSL NID
+ */
+static int nid_map[ECC_MAX];
+
+/*
+ * See header
+ */
+void openssl_ec_lookup_table_cleanup()
+{
+       memset(nid_map, 0, sizeof(nid_map));
+}
+
+/**
+ * Get or allocate a NID for the given curve.
+ */
+static int get_nid(ec_curve_t curve)
+{
+       char *numeric, name[16];
+       int oid, nid;
+
+       nid = nid_map[curve];
+       if (nid)
+       {
+               return nid;
+       }
+       oid = ec_curve_to_oid(curve);
+       if (oid == OID_UNKNOWN)
+       {
+               return 0;
+       }
+       if (snprintf(name, sizeof(name), "%N", ec_curve_names, curve) >= sizeof(name))
+       {
+               return 0;
+       }
+       numeric = asn1_known_oid_to_string(oid);
+       if (!numeric)
+       {
+               return 0;
+       }
+       nid = nid_map[curve] = OBJ_create(numeric, name, name);
+       free(numeric);
+       return nid;
+}
 
 /*
  * See header
@@ -32,6 +85,7 @@ EC_GROUP *openssl_ec_group_for_curve(ec_curve_t curve)
        EC_POINT *G = NULL;
        EC_GROUP *group = NULL, *result = NULL;
        BN_CTX *ctx = NULL;
+       int nid;
 
        params = ec_get_params(curve);
        if (!params)
@@ -65,6 +119,12 @@ EC_GROUP *openssl_ec_group_for_curve(ec_curve_t curve)
        {
                goto failed;
        }
+       nid = get_nid(curve);
+       if (!nid)
+       {
+               goto failed;
+       }
+       EC_GROUP_set_curve_name(group, nid);
        result = group;
 
 failed:
index 2ff5c72692942e9b4e37cf346574b5af601acfc9..804ea4d67988b83ae78bfbd7ec52565fb5ea8f8a 100644 (file)
@@ -37,4 +37,9 @@
  */
 EC_GROUP *openssl_ec_group_for_curve(ec_curve_t curve);
 
+/**
+ * Clear lookup table to map from ec_curve_t to OpenSSL NID
+ */
+void openssl_ec_lookup_table_cleanup();
+
 #endif /** OPENSSL_EC_UTIL_H_ @}*/
index 31412c37183f2291fef62b4152a52528e351073f..ebbd5c81740468b023834be5123649118bda3026 100644 (file)
@@ -502,6 +502,9 @@ METHOD(plugin_t, destroy, void,
 {
        CONF_modules_free();
        OBJ_cleanup();
+#ifndef OPENSSL_NO_EC
+       openssl_ec_lookup_table_cleanup();
+#endif
        EVP_cleanup();
 #ifndef OPENSSL_NO_ENGINE
        ENGINE_cleanup();