#ifdef ANDROID_KEYSTORE
static BIO *BIO_from_keystore(struct openconnect_info *vpninfo, const char *item)
{
- char content[KEYSTORE_MESSAGE_SIZE];
+ unsigned char *content;
BIO *b;
int len;
const char *p = item + 9;
p++;
if (*p == '/')
p++;
- len = keystore_get(p, strlen(p), content);
+
+ len = keystore_fetch(p, &content);
if (len < 0) {
vpn_progress(vpninfo, PRG_ERR,
- _("Failed to lead item '%s' from keystore\n"),
- p);
+ _("Failed to load item '%s' from keystore: %s\n"),
+ p, keystore_strerror(len));
return NULL;
}
if (!(b = BIO_new(BIO_s_mem())) || BIO_write(b, content, len) != len) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to create BIO for keystore item '%s'\n"),
p);
+ free(content);
BIO_free(b);
return NULL;
}
+ free(content);
return b;
}
#endif
vpn_progress(vpninfo, PRG_ERR,
_("Failed to load X509 certificate from keystore\n"));
openconnect_report_ssl_errors(vpninfo);
- BIO_free(b);
return -EINVAL;
}
if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) {
#endif
SSL_CTX_set_default_verify_paths(vpninfo->https_ctx);
+#ifdef ANDROID_KEYSTORE
+ if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
+ STACK_OF(X509_INFO) *stack;
+ X509_STORE *store;
+ X509_INFO *info;
+ BIO *b = BIO_from_keystore(vpninfo, vpninfo->cafile);
+
+ if (!b) {
+ close(ssl_sock);
+ return -EINVAL;
+ }
+
+ stack = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
+ BIO_free(b);
+
+ if (!stack) {
+ vpn_progress(vpninfo, PRG_ERR,
+ _("Failed to read certs from CA file '%s'\n"),
+ vpninfo->cafile);
+ openconnect_report_ssl_errors(vpninfo);
+ close(ssl_sock);
+ return -ENOENT;
+ }
+
+ store = SSL_CTX_get_cert_store(vpninfo->https_ctx);
+
+ while ((info = sk_X509_INFO_pop(stack))) {
+ if (info->x509)
+ X509_STORE_add_cert(store, info->x509);
+ if (info->crl)
+ X509_STORE_add_crl(store, info->crl);
+ X509_INFO_free(info);
+ }
+ sk_X509_INFO_free(stack);
+ } else
+#endif
if (vpninfo->cafile) {
if (!SSL_CTX_load_verify_locations(vpninfo->https_ctx, vpninfo->cafile, NULL)) {
vpn_progress(vpninfo, PRG_ERR,