/*
* Hotspot 2.0 OSU client
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2014, Qualcomm Atheros, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
xml_node_get_text_free(ctx->xml, hash);
write_summary(ctx, "Download certificate from %s", url);
+ ctx->no_osu_cert_validation = 1;
+ http_ocsp_set(ctx->http, 1);
res = http_download_file(ctx->http, url, TMP_CERT_DL_FILE, NULL);
+ http_ocsp_set(ctx->http,
+ (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
+ ctx->no_osu_cert_validation = 0;
xml_node_get_text_free(ctx->xml, url);
if (res < 0)
return -1;
}
node = get_child_node(ctx->xml, pps,
- "PolicyUpdate/TrustRoot");
+ "Policy/PolicyUpdate/TrustRoot");
if (node == NULL) {
- wpa_printf(MSG_INFO, "No PolicyUpdate/TrustRoot/CertURL found from PPS");
+ wpa_printf(MSG_INFO, "No Policy/PolicyUpdate/TrustRoot/CertURL found from PPS");
xml_node_free(ctx->xml, pps);
return -1;
}
static int osu_connect(struct hs20_osu_client *ctx, const char *bssid,
- const char *ssid, const char *url, const char *ca_fname,
+ const char *ssid, const char *url,
unsigned int methods, int no_prod_assoc,
const char *osu_nai)
{
ctx->no_reconnect = 1;
if (methods & 0x02)
- res = cmd_prov(ctx, url, ca_fname);
+ res = cmd_prov(ctx, url);
else if (methods & 0x01)
- res = cmd_oma_dm_prov(ctx, url, ca_fname);
+ res = cmd_oma_dm_prov(ctx, url);
wpa_printf(MSG_INFO, "Remove OSU network connection");
write_summary(ctx, "Remove OSU network connection");
static int cmd_osu_select(struct hs20_osu_client *ctx, const char *dir,
- int connect, const char *ca_fname, int no_prod_assoc,
+ int connect, int no_prod_assoc,
const char *friendly_name)
{
char fname[255];
if (connect == 2) {
if (last->methods & 0x02)
- ret = cmd_prov(ctx, last->url, ca_fname);
+ ret = cmd_prov(ctx, last->url);
else if (last->methods & 0x01)
- ret = cmd_oma_dm_prov(ctx, last->url, ca_fname);
+ ret = cmd_oma_dm_prov(ctx, last->url);
else
ret = -1;
} else if (connect)
ret = osu_connect(ctx, last->bssid, last->osu_ssid,
- last->url, ca_fname, last->methods,
+ last->url, last->methods,
no_prod_assoc, last->osu_nai);
} else
ret = -1;
}
-static int cmd_signup(struct hs20_osu_client *ctx, const char *ca_fname,
- int no_prod_assoc, const char *friendly_name)
+static int cmd_signup(struct hs20_osu_client *ctx, int no_prod_assoc,
+ const char *friendly_name)
{
char dir[255];
char fname[300], buf[400];
}
wpa_printf(MSG_INFO, "OSU provider fetch completed");
- return cmd_osu_select(ctx, fname, 1, ca_fname, no_prod_assoc,
- friendly_name);
+ return cmd_osu_select(ctx, fname, 1, no_prod_assoc, friendly_name);
}
-static void cmd_sub_rem(struct hs20_osu_client *ctx, const char *address,
- const char *pps_fname, const char *ca_fname)
+static int cmd_sub_rem(struct hs20_osu_client *ctx, const char *address,
+ const char *pps_fname, const char *ca_fname)
{
xml_node_t *pps, *node;
char pps_fname_buf[300];
char *client_key = NULL;
int spp;
- ctx->ca_fname = ca_fname;
-
wpa_printf(MSG_INFO, "Subscription remediation requested with Server URL: %s",
address);
} else if (get_wpa_status(ctx->ifname, "provisioning_sp", buf,
sizeof(buf)) < 0) {
wpa_printf(MSG_INFO, "Could not get provisioning Home SP FQDN from wpa_supplicant");
- return;
+ return -1;
}
os_free(ctx->fqdn);
ctx->fqdn = os_strdup(buf);
if (ctx->fqdn == NULL)
- return;
+ return -1;
wpa_printf(MSG_INFO, "Home SP FQDN for current credential: %s",
buf);
os_snprintf(pps_fname_buf, sizeof(pps_fname_buf),
if (!os_file_exists(pps_fname)) {
wpa_printf(MSG_INFO, "PPS file '%s' does not exist or is not accessible",
pps_fname);
- return;
+ return -1;
}
wpa_printf(MSG_INFO, "Using PPS file: %s", pps_fname);
if (ca_fname && !os_file_exists(ca_fname)) {
wpa_printf(MSG_INFO, "CA file '%s' does not exist or is not accessible",
ca_fname);
- return;
+ return -1;
}
wpa_printf(MSG_INFO, "Using server trust root: %s", ca_fname);
+ ctx->ca_fname = ca_fname;
pps = node_from_file(ctx->xml, pps_fname);
if (pps == NULL) {
wpa_printf(MSG_INFO, "Could not read PPS MO");
- return;
+ return -1;
}
if (!ctx->fqdn) {
node = get_child_node(ctx->xml, pps, "HomeSP/FQDN");
if (node == NULL) {
wpa_printf(MSG_INFO, "No HomeSP/FQDN found from PPS");
- return;
+ return -1;
}
tmp = xml_node_get_text(ctx->xml, node);
if (tmp == NULL) {
wpa_printf(MSG_INFO, "No HomeSP/FQDN text found from PPS");
- return;
+ return -1;
}
ctx->fqdn = os_strdup(tmp);
xml_node_get_text_free(ctx->xml, tmp);
if (!ctx->fqdn) {
wpa_printf(MSG_INFO, "No FQDN known");
- return;
+ return -1;
}
}
}
if (!address) {
wpa_printf(MSG_INFO, "Server URL not known");
- return;
+ return -1;
}
write_summary(ctx, "Wait for IP address for subscriptiom remediation");
}
if (spp)
- spp_sub_rem(ctx, address, pps_fname, ca_fname,
+ spp_sub_rem(ctx, address, pps_fname,
client_cert, client_key,
cred_username, cred_password, pps);
else
- oma_dm_sub_rem(ctx, address, pps_fname, ca_fname,
+ oma_dm_sub_rem(ctx, address, pps_fname,
client_cert, client_key,
cred_username, cred_password, pps);
xml_node_get_text_free(ctx->xml, sub_rem_uri);
xml_node_get_text_free(ctx->xml, cred_username);
- os_free(cred_password);
+ str_clear_free(cred_password);
xml_node_free(ctx->xml, pps);
+ return 0;
}
return -1;
}
wpa_printf(MSG_INFO, "Using server trust root: %s", ca_fname);
+ ctx->ca_fname = ca_fname;
pps = node_from_file(ctx->xml, pps_fname);
if (pps == NULL) {
}
if (spp)
- spp_pol_upd(ctx, address, pps_fname, ca_fname,
+ spp_pol_upd(ctx, address, pps_fname,
client_cert, client_key,
cred_username, cred_password, pps);
else
- oma_dm_pol_upd(ctx, address, pps_fname, ca_fname,
+ oma_dm_pol_upd(ctx, address, pps_fname,
client_cert, client_key,
cred_username, cred_password, pps);
xml_node_get_text_free(ctx->xml, uri);
xml_node_get_text_free(ctx->xml, cred_username);
- os_free(cred_password);
+ str_clear_free(cred_password);
xml_node_free(ctx->xml, pps);
return 0;
int found;
char *host = NULL;
- wpa_printf(MSG_INFO, "osu_cert_cb");
+ wpa_printf(MSG_INFO, "osu_cert_cb(osu_cert_validation=%d)",
+ !ctx->no_osu_cert_validation);
host = get_hostname(ctx->server_url);
}
}
- for (j = 0; j < ctx->friendly_name_count; j++) {
+ for (j = 0; !ctx->no_osu_cert_validation &&
+ j < ctx->friendly_name_count; j++) {
int found = 0;
for (i = 0; i < cert->num_othername; i++) {
if (os_strcmp(cert->othername[i].oid,
logo->hash, logo->hash_len);
}
- for (j = 0; j < ctx->icon_count; j++) {
+ for (j = 0; !ctx->no_osu_cert_validation && j < ctx->icon_count; j++) {
int found = 0;
char *name = ctx->icon_filename[j];
size_t name_len = os_strlen(name);
}
}
- for (j = 0; j < ctx->icon_count; j++) {
+ for (j = 0; !ctx->no_osu_cert_validation && j < ctx->icon_count; j++) {
int found = 0;
for (i = 0; i < cert->num_logo; i++) {
"- dl_polupd_ca <PPS> <CA file>\n"
"- dl_aaa_ca <PPS> <CA file>\n"
"- browser <URL>\n"
+ "- parse_cert <X.509 certificate (DER)>\n"
"- osu_select <OSU info directory> [CA cert]\n");
}
if (argc - optind < 2)
wpa_printf(MSG_ERROR, "Server URL missing from command line");
else
- cmd_sub_rem(&ctx, argv[optind + 1],
- argc > optind + 2 ? argv[optind + 2] : NULL,
- argc > optind + 3 ? argv[optind + 3] :
- NULL);
+ ret = cmd_sub_rem(&ctx, argv[optind + 1],
+ argc > optind + 2 ?
+ argv[optind + 2] : NULL,
+ argc > optind + 3 ?
+ argv[optind + 3] : NULL);
} else if (strcmp(argv[optind], "pol_upd") == 0) {
if (argc - optind < 2) {
usage();
usage();
exit(0);
}
- cmd_prov(&ctx, argv[optind + 1], argv[optind + 2]);
+ ctx.ca_fname = argv[optind + 2];
+ cmd_prov(&ctx, argv[optind + 1]);
} else if (strcmp(argv[optind], "sim_prov") == 0) {
if (argc - optind < 2) {
usage();
exit(0);
}
- cmd_sim_prov(&ctx, argv[optind + 1], argv[optind + 2]);
+ ctx.ca_fname = argv[optind + 2];
+ cmd_sim_prov(&ctx, argv[optind + 1]);
} else if (strcmp(argv[optind], "dl_osu_ca") == 0) {
if (argc - optind < 2) {
usage();
usage();
exit(0);
}
- cmd_osu_select(&ctx, argv[optind + 1], 2,
- argc > optind + 2 ? argv[optind + 2] : NULL,
- 1, NULL);
+ ctx.ca_fname = argc > optind + 2 ? argv[optind + 2] : NULL;
+ cmd_osu_select(&ctx, argv[optind + 1], 2, 1, NULL);
} else if (strcmp(argv[optind], "signup") == 0) {
- ret = cmd_signup(&ctx,
- argc > optind + 1 ? argv[optind + 1] : NULL,
- no_prod_assoc, friendly_name);
+ ctx.ca_fname = argc > optind + 1 ? argv[optind + 1] : NULL;
+ ret = cmd_signup(&ctx, no_prod_assoc, friendly_name);
} else if (strcmp(argv[optind], "set_pps") == 0) {
if (argc - optind < 2) {
usage();
usage();
exit(0);
}
- cmd_oma_dm_prov(&ctx, argv[optind + 1], argv[optind + 2]);
+ ctx.ca_fname = argv[optind + 2];
+ cmd_oma_dm_prov(&ctx, argv[optind + 1]);
} else if (strcmp(argv[optind], "oma_dm_sim_prov") == 0) {
if (argc - optind < 2) {
usage();
exit(0);
}
- if (cmd_oma_dm_sim_prov(&ctx, argv[optind + 1],
- argv[optind + 2]) < 0) {
+ ctx.ca_fname = argv[optind + 2];
+ if (cmd_oma_dm_sim_prov(&ctx, argv[optind + 1]) < 0) {
write_summary(&ctx, "Failed to complete OMA DM SIM provisioning");
return -1;
}
argv[optind + 1]);
ret = hs20_web_browser(argv[optind + 1]);
wpa_printf(MSG_INFO, "Web browser result: %d", ret);
+ } else if (strcmp(argv[optind], "parse_cert") == 0) {
+ if (argc - optind < 2) {
+ usage();
+ exit(0);
+ }
+
+ wpa_debug_level = MSG_MSGDUMP;
+ http_parse_x509_certificate(ctx.http, argv[optind + 1]);
+ wpa_debug_level = MSG_INFO;
} else {
wpa_printf(MSG_INFO, "Unknown command '%s'", argv[optind]);
}
+ deinit_ctx(&ctx);
wpa_printf(MSG_DEBUG,
"===[hs20-osu-client END ]======================");
wpa_debug_close_file();
- deinit_ctx(&ctx);
return ret;
}