]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
HS 2.0: Crypto engine support for creds
authorDamien Dejean <damiendejean@chromium.org>
Wed, 8 Dec 2021 07:45:30 +0000 (07:45 +0000)
committerJouni Malinen <j@w1.fi>
Sun, 12 Dec 2021 14:47:47 +0000 (16:47 +0200)
Add the support of engine, engine_id, ca_cert_id, cert_id, and key_id
parameters to credential blocks for Hotspot 2.0.

Signed-off-by: Damien Dejean <damiendejean@chromium.org>
wpa_supplicant/README-HS20
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/interworking.c
wpa_supplicant/wpa_cli.c

index 484e4cbf4724f4a1eb46dc62e3fcb1a65c0d5ca0..b076621db5270a9afa08e8bdd3f0914aa338a23d 100644 (file)
@@ -286,6 +286,12 @@ Credentials can be pre-configured for automatic network selection:
 #
 # sim_num: Identifier for which SIM to use in multi-SIM devices
 #
+# engine: Whether to use an engine for private key operations (0/1)
+# engine_id: String identifying the engine to use
+# ca_cert_id: The CA certificate identifier when using an engine
+# cert_id: The certificate identifier when using an engine
+# key_id: The private key identifier when using an engine
+#
 # for example:
 #
 #cred={
index c5177d915524f960a7c664d964274c4980b72ed7..a316e38d4991d0fcfaeca55f4cf073a31512079d 100644 (file)
@@ -2855,6 +2855,10 @@ void wpa_config_free_cred(struct wpa_cred *cred)
        os_free(cred->client_cert);
        os_free(cred->private_key);
        str_clear_free(cred->private_key_passwd);
+       os_free(cred->engine_id);
+       os_free(cred->ca_cert_id);
+       os_free(cred->cert_id);
+       os_free(cred->key_id);
        os_free(cred->imsi);
        str_clear_free(cred->milenage);
        for (i = 0; i < cred->num_domain; i++)
@@ -3618,6 +3622,11 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
                return 0;
        }
 
+       if (os_strcmp(var, "engine") == 0) {
+               cred->engine = atoi(value);
+               return 0;
+       }
+
        val = wpa_config_parse_string(value, &len);
        if (val == NULL ||
            (os_strcmp(var, "excluded_ssid") != 0 &&
@@ -3673,6 +3682,30 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
                return 0;
        }
 
+       if (os_strcmp(var, "engine_id") == 0) {
+               os_free(cred->engine_id);
+               cred->engine_id = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "ca_cert_id") == 0) {
+               os_free(cred->ca_cert_id);
+               cred->ca_cert_id = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "cert_id") == 0) {
+               os_free(cred->cert_id);
+               cred->cert_id = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "key_id") == 0) {
+               os_free(cred->key_id);
+               cred->key_id = val;
+               return 0;
+       }
+
        if (os_strcmp(var, "imsi") == 0) {
                os_free(cred->imsi);
                cred->imsi = val;
index 0320d9eebb57e1f41cb7a03cf257b740c709922d..de48436fd1c49feb043c9ab28aac11b54e38e8b2 100644 (file)
@@ -179,6 +179,31 @@ struct wpa_cred {
         */
        char *milenage;
 
+       /**
+        * engine - Use an engine for private key operations
+        */
+       int engine;
+
+       /**
+        * engine_id - String identifying the engine to use
+        */
+       char *engine_id;
+
+       /**
+        * ca_cert_id - The CA certificate identifier when using an engine
+        */
+       char *ca_cert_id;
+
+       /**
+        * cert_id - The certificate identifier when using an engine
+        */
+       char *cert_id;
+
+       /**
+        * key_id - The private key identifier when using an engine
+        */
+       char *key_id;
+
        /**
         * domain_suffix_match - Constraint for server domain name
         *
index 54fb72d8c1f7326b02267ecbddddfcaa4f533f61..f307a29d00dee2b11030e0935ed80834be7e383f 100644 (file)
@@ -1026,6 +1026,17 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
 
        if (cred->sim_num != DEFAULT_USER_SELECTED_SIM)
                fprintf(f, "\tsim_num=%d\n", cred->sim_num);
+
+       if (cred->engine)
+               fprintf(f, "\tengine=%d\n", cred->engine);
+       if (cred->engine_id)
+               fprintf(f, "\tengine_id=\"%s\"\n", cred->engine_id);
+       if (cred->key_id)
+               fprintf(f, "\tkey_id=\"%s\"\n", cred->key_id);
+       if (cred->cert_id)
+               fprintf(f, "\tcert_id=\"%s\"\n", cred->cert_id);
+       if (cred->ca_cert_id)
+               fprintf(f, "\tca_cert_id=\"%s\"\n", cred->ca_cert_id);
 }
 
 
index 1c82d2117ab0f63b69a892a0f543cc7ca3d14024..5ae71ca1ca852ecdefeccae50d7ba9ed6a2c9da0 100644 (file)
@@ -702,12 +702,14 @@ static struct nai_realm_eap * nai_realm_find_eap(struct wpa_supplicant *wpa_s,
            ((cred->password == NULL ||
              cred->password[0] == '\0') &&
             (cred->private_key == NULL ||
-             cred->private_key[0] == '\0'))) {
+             cred->private_key[0] == '\0') &&
+            (!cred->key_id || cred->key_id[0] == '\0'))) {
                wpa_msg(wpa_s, MSG_DEBUG,
-                       "nai-realm-find-eap: incomplete cred info: username: %s  password: %s private_key: %s",
+                       "nai-realm-find-eap: incomplete cred info: username: %s  password: %s private_key: %s key_id: %s",
                        cred->username ? cred->username : "NULL",
                        cred->password ? cred->password : "NULL",
-                       cred->private_key ? cred->private_key : "NULL");
+                       cred->private_key ? cred->private_key : "NULL",
+                       cred->key_id ? cred->key_id : "NULL");
                return NULL;
        }
 
@@ -716,7 +718,8 @@ static struct nai_realm_eap * nai_realm_find_eap(struct wpa_supplicant *wpa_s,
                if (cred->password && cred->password[0] &&
                    nai_realm_cred_username(wpa_s, eap))
                        return eap;
-               if (cred->private_key && cred->private_key[0] &&
+               if (((cred->private_key && cred->private_key[0]) ||
+                    (cred->key_id && cred->key_id[0])) &&
                    nai_realm_cred_cert(wpa_s, eap))
                        return eap;
        }
@@ -1539,6 +1542,24 @@ static int interworking_set_eap_params(struct wpa_ssid *ssid,
                                  cred->private_key_passwd) < 0)
                return -1;
 
+       if (cred->ca_cert_id && cred->ca_cert_id[0] &&
+           wpa_config_set_quoted(ssid, "ca_cert_id", cred->ca_cert_id) < 0)
+               return -1;
+
+       if (cred->cert_id && cred->cert_id[0] &&
+           wpa_config_set_quoted(ssid, "cert_id", cred->cert_id) < 0)
+               return -1;
+
+       if (cred->key_id && cred->key_id[0] &&
+           wpa_config_set_quoted(ssid, "key_id", cred->key_id) < 0)
+               return -1;
+
+       if (cred->engine_id && cred->engine_id[0] &&
+           wpa_config_set_quoted(ssid, "engine_id", cred->engine_id) < 0)
+               return -1;
+
+       ssid->eap.cert.engine = cred->engine;
+
        if (cred->phase1) {
                os_free(ssid->eap.phase1);
                ssid->eap.phase1 = os_strdup(cred->phase1);
index b72983e9c3f7c8c44c57a91935499450784ed709..17b14c824ddb3bb22fabe7d55eca3b84bce82b3e 100644 (file)
@@ -1591,6 +1591,7 @@ static const char * const cred_fields[] = {
        "min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load",
        "req_conn_capab", "ocsp", "sim_num", "realm", "username", "password",
        "ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi",
+       "ca_cert_id", "cert_id", "key_id", "engine_id", "engine",
        "milenage", "domain_suffix_match", "domain", "phase1", "phase2",
        "roaming_consortium", "required_roaming_consortium", "excluded_ssid",
        "roaming_partner", "provisioning_sp"