1d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/* 2d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * HTTP wrapper for libcurl 36cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt * Copyright (c) 2012-2014, Qualcomm Atheros, Inc. 4d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * 5d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * This software may be distributed under the terms of the BSD license. 6d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * See README for more details. 7d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */ 8d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 9d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "includes.h" 10d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <curl/curl.h> 11d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#ifdef EAP_TLS_OPENSSL 12d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <openssl/ssl.h> 13d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <openssl/asn1.h> 14d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <openssl/asn1t.h> 15d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <openssl/x509v3.h> 16d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 17d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#ifdef SSL_set_tlsext_status_type 18d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#ifndef OPENSSL_NO_TLSEXT 19d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define HAVE_OCSP 20d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <openssl/err.h> 21d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <openssl/ocsp.h> 22d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif /* OPENSSL_NO_TLSEXT */ 23d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif /* SSL_set_tlsext_status_type */ 24d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif /* EAP_TLS_OPENSSL */ 25d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 26d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "common.h" 27d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "xml-utils.h" 28d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "http-utils.h" 29d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#ifdef EAP_TLS_OPENSSL 30d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#include "crypto/tls_openssl.h" 31d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#endif /* EAP_TLS_OPENSSL */ 32d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 33d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 34d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstruct http_ctx { 35d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt void *ctx; 36d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct xml_node_ctx *xml; 37d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt CURL *curl; 38d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct curl_slist *curl_hdr; 39d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *svc_address; 40d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *svc_ca_fname; 41d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *svc_username; 42d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *svc_password; 43d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *svc_client_cert; 44d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *svc_client_key; 45d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *curl_buf; 46d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt size_t curl_buf_len; 47d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 48d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int (*cert_cb)(void *ctx, struct http_cert *cert); 49d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt void *cert_cb_ctx; 50d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 51d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt enum { 52d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt NO_OCSP, OPTIONAL_OCSP, MANDATORY_OCSP 53d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } ocsp; 54d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *peer_cert; 55d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *peer_issuer; 56d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *peer_issuer_issuer; 57d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 58d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *last_err; 59d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}; 60d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 61d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 62d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void clear_curl(struct http_ctx *ctx) 63d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 64d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->curl) { 65d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_cleanup(ctx->curl); 66d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl = NULL; 67d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->curl_hdr) { 69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_slist_free_all(ctx->curl_hdr); 70d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_hdr = NULL; 71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 72d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void clone_str(char **dst, const char *src) 76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(*dst); 78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (src) 79d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *dst = os_strdup(src); 80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt else 81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *dst = NULL; 82d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 84d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 85d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void debug_dump(struct http_ctx *ctx, const char *title, 86d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *buf, size_t len) 87d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 886cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt char *txt; 896cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt size_t i; 906cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt 916cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt for (i = 0; i < len; i++) { 926cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt if (buf[i] < 32 && buf[i] != '\t' && buf[i] != '\n' && 936cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt buf[i] != '\r') { 946cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, title, buf, len); 956cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt return; 966cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt } 976cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt } 986cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt 996cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt txt = os_malloc(len + 1); 100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (txt == NULL) 101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memcpy(txt, buf, len); 103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt txt[len] = '\0'; 104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt while (len > 0) { 105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt len--; 1066cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt if (txt[len] == '\n' || txt[len] == '\r') 1076cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt txt[len] = '\0'; 1086cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt else 1096cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt break; 110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_MSGDUMP, "%s[%s]", title, txt); 112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(txt); 113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int curl_cb_debug(CURL *curl, curl_infotype info, char *buf, size_t len, 117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt void *userdata) 118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_ctx *ctx = userdata; 120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt switch (info) { 121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_TEXT: 122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump(ctx, "CURLINFO_TEXT", buf, len); 123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_HEADER_IN: 125d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump(ctx, "CURLINFO_HEADER_IN", buf, len); 126d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 127d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_HEADER_OUT: 128d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump(ctx, "CURLINFO_HEADER_OUT", buf, len); 129d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 130d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_DATA_IN: 131d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump(ctx, "CURLINFO_DATA_IN", buf, len); 132d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 133d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_DATA_OUT: 134d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump(ctx, "CURLINFO_DATA_OUT", buf, len); 135d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 136d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_SSL_DATA_IN: 137d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "debug - CURLINFO_SSL_DATA_IN - %d", 138d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt (int) len); 139d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 140d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_SSL_DATA_OUT: 141d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "debug - CURLINFO_SSL_DATA_OUT - %d", 142d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt (int) len); 143d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 144d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case CURLINFO_END: 145d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "debug - CURLINFO_END - %d", 146d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt (int) len); 147d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 148d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 149d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 150d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 151d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 152d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 153d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic size_t curl_cb_write(void *ptr, size_t size, size_t nmemb, 154d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt void *userdata) 155d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 156d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_ctx *ctx = userdata; 157d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *n; 158d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n = os_realloc(ctx->curl_buf, ctx->curl_buf_len + size * nmemb + 1); 159d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (n == NULL) 160d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 161d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_buf = n; 162d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memcpy(n + ctx->curl_buf_len, ptr, size * nmemb); 163d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n[ctx->curl_buf_len + size * nmemb] = '\0'; 164d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_buf_len += size * nmemb; 165d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return size * nmemb; 166d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 167d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 168d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 169d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#ifdef EAP_TLS_OPENSSL 170d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 171d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void debug_dump_cert(const char *title, X509 *cert) 172d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 173d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO *out; 174d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *txt; 175d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt size_t rlen; 176d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 177d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt out = BIO_new(BIO_s_mem()); 178d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!out) 179d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 180d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 181d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_print_ex(out, cert, XN_FLAG_COMPAT, X509_FLAG_COMPAT); 182d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt rlen = BIO_ctrl_pending(out); 183d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt txt = os_malloc(rlen + 1); 184d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (txt) { 185d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res = BIO_read(out, txt, rlen); 186d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res > 0) { 187d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt txt[res] = '\0'; 188d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_MSGDUMP, "%s:\n%s", title, txt); 189d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 190d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(txt); 191d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 192d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_free(out); 193d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 194d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 195d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 196d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_alt_name_othername(struct http_ctx *ctx, struct http_cert *cert, 197d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OTHERNAME *o) 198d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 199d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char txt[100]; 200d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res; 201d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_othername *on; 202d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_TYPE *val; 203d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 204d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt on = os_realloc_array(cert->othername, cert->num_othername + 1, 205d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sizeof(struct http_othername)); 206d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (on == NULL) 207d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 208d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert->othername = on; 209d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt on = &on[cert->num_othername]; 210d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memset(on, 0, sizeof(*on)); 211d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 212d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = OBJ_obj2txt(txt, sizeof(txt), o->type_id, 1); 213d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res < 0 || res >= (int) sizeof(txt)) 214d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 215d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 216d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt on->oid = os_strdup(txt); 217d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (on->oid == NULL) 218d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 219d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 220d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt val = o->value; 221d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt on->data = val->value.octet_string->data; 222d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt on->len = val->value.octet_string->length; 223d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 224d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert->num_othername++; 225d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 226d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 227d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 228d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_alt_name_dns(struct http_ctx *ctx, struct http_cert *cert, 229d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_STRING *name) 230d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 231d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *buf; 232d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char **n; 233d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 234d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt buf = NULL; 235d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ASN1_STRING_to_UTF8((unsigned char **) &buf, name) < 0) 236d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 237d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 238d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n = os_realloc_array(cert->dnsname, cert->num_dnsname + 1, 239d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sizeof(char *)); 240d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (n == NULL) 241d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 242d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 243d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert->dnsname = n; 244d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n[cert->num_dnsname] = buf; 245d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert->num_dnsname++; 246d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 247d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 248d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 249d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_alt_name(struct http_ctx *ctx, struct http_cert *cert, 250d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const GENERAL_NAME *name) 251d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 252d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt switch (name->type) { 253d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case GEN_OTHERNAME: 254d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_alt_name_othername(ctx, cert, name->d.otherName); 255d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 256d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case GEN_DNS: 257d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_alt_name_dns(ctx, cert, name->d.dNSName); 258d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 259d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 260d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 261d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 262d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 263d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_alt_names(struct http_ctx *ctx, struct http_cert *cert, 264d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt GENERAL_NAMES *names) 265d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 266d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int num, i; 267d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 268d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = sk_GENERAL_NAME_num(names); 269d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 270d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const GENERAL_NAME *name; 271d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name = sk_GENERAL_NAME_value(names, i); 272d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_alt_name(ctx, cert, name); 273d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 274d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 275d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 276d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 277d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/* RFC 3709 */ 278d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 279d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 280d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_ALGOR *hashAlg; 281d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_OCTET_STRING *hashValue; 282d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} HashAlgAndValue; 283d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 284d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 285d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(HashAlgAndValue) *refStructHash; 286d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(ASN1_IA5STRING) *refStructURI; 287d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeReference; 288d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 289d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 290d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IA5STRING *mediaType; 291d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(HashAlgAndValue) *logotypeHash; 292d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(ASN1_IA5STRING) *logotypeURI; 293d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeDetails; 294d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 295d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 296d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int type; 297d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt union { 298d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *numBits; 299d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *tableSize; 300d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } d; 301d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeImageResolution; 302d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 303d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 304d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *type; /* LogotypeImageType ::= INTEGER */ 305d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *fileSize; 306d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *xSize; 307d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *ySize; 308d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeImageResolution *resolution; 309d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IA5STRING *language; 310d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeImageInfo; 311d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 312d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 313d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeDetails *imageDetails; 314d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeImageInfo *imageInfo; 315d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeImage; 316d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 317d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 318d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *fileSize; 319d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *playTime; 320d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *channels; 321d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_INTEGER *sampleRate; 322d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IA5STRING *language; 323d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeAudioInfo; 324d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 325d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 326d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeDetails *audioDetails; 327d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeAudioInfo *audioInfo; 328d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeAudio; 329d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 330d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 331d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(LogotypeImage) *image; 332d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(LogotypeAudio) *audio; 333d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeData; 334d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 335d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 336d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int type; 337d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt union { 338d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeData *direct; 339d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeReference *indirect; 340d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } d; 341d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeInfo; 342d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 343d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 344d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_OBJECT *logotypeType; 345d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeInfo *info; 346d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} OtherLogotypeInfo; 347d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 348d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidttypedef struct { 349d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(LogotypeInfo) *communityLogos; 350d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeInfo *issuerLogo; 351d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeInfo *subjectLogo; 352d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(OtherLogotypeInfo) *otherLogos; 353d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} LogotypeExtn; 354d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 355d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(HashAlgAndValue) = { 356d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(HashAlgAndValue, hashAlg, X509_ALGOR), 357d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(HashAlgAndValue, hashValue, ASN1_OCTET_STRING) 358d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(HashAlgAndValue); 359d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 360d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeReference) = { 361d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SEQUENCE_OF(LogotypeReference, refStructHash, HashAlgAndValue), 362d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SEQUENCE_OF(LogotypeReference, refStructURI, ASN1_IA5STRING) 363d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeReference); 364d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 365d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeDetails) = { 366d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeDetails, mediaType, ASN1_IA5STRING), 367d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SEQUENCE_OF(LogotypeDetails, logotypeHash, HashAlgAndValue), 368d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SEQUENCE_OF(LogotypeDetails, logotypeURI, ASN1_IA5STRING) 369d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeDetails); 370d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 371d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_CHOICE(LogotypeImageResolution) = { 372d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP(LogotypeImageResolution, d.numBits, ASN1_INTEGER, 1), 373d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP(LogotypeImageResolution, d.tableSize, ASN1_INTEGER, 2) 374d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_CHOICE_END(LogotypeImageResolution); 375d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 376d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeImageInfo) = { 377d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP_OPT(LogotypeImageInfo, type, ASN1_INTEGER, 0), 378d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeImageInfo, fileSize, ASN1_INTEGER), 379d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeImageInfo, xSize, ASN1_INTEGER), 380d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeImageInfo, ySize, ASN1_INTEGER), 381d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_OPT(LogotypeImageInfo, resolution, LogotypeImageResolution), 382d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP_OPT(LogotypeImageInfo, language, ASN1_IA5STRING, 4), 383d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeImageInfo); 384d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 385d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeImage) = { 386d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeImage, imageDetails, LogotypeDetails), 387d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_OPT(LogotypeImage, imageInfo, LogotypeImageInfo) 388d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeImage); 389d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 390d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeAudioInfo) = { 391d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeAudioInfo, fileSize, ASN1_INTEGER), 392d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeAudioInfo, playTime, ASN1_INTEGER), 393d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeAudioInfo, channels, ASN1_INTEGER), 394d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP_OPT(LogotypeAudioInfo, sampleRate, ASN1_INTEGER, 3), 395d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP_OPT(LogotypeAudioInfo, language, ASN1_IA5STRING, 4) 396d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeAudioInfo); 397d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 398d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeAudio) = { 399d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(LogotypeAudio, audioDetails, LogotypeDetails), 400d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_OPT(LogotypeAudio, audioInfo, LogotypeAudioInfo) 401d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeAudio); 402d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 403d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeData) = { 404d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SEQUENCE_OF_OPT(LogotypeData, image, LogotypeImage), 405d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP_SEQUENCE_OF_OPT(LogotypeData, audio, LogotypeAudio, 1) 406d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeData); 407d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 408d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_CHOICE(LogotypeInfo) = { 409d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP(LogotypeInfo, d.direct, LogotypeData, 0), 410d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IMP(LogotypeInfo, d.indirect, LogotypeReference, 1) 411d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_CHOICE_END(LogotypeInfo); 412d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 413d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(OtherLogotypeInfo) = { 414d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(OtherLogotypeInfo, logotypeType, ASN1_OBJECT), 415d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_SIMPLE(OtherLogotypeInfo, info, LogotypeInfo) 416d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(OtherLogotypeInfo); 417d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 418d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtASN1_SEQUENCE(LogotypeExtn) = { 419d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_EXP_SEQUENCE_OF_OPT(LogotypeExtn, communityLogos, LogotypeInfo, 0), 420d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_EXP_OPT(LogotypeExtn, issuerLogo, LogotypeInfo, 1), 421d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_EXP_OPT(LogotypeExtn, issuerLogo, LogotypeInfo, 2), 422d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_EXP_SEQUENCE_OF_OPT(LogotypeExtn, otherLogos, OtherLogotypeInfo, 3) 423d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} ASN1_SEQUENCE_END(LogotypeExtn); 424d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 425d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry ShmidtIMPLEMENT_ASN1_FUNCTIONS(LogotypeExtn); 426d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 427d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 428d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_LogotypeInfo_num(st) \ 429d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_num(CHECKED_CAST(_STACK *, STACK_OF(LogotypeInfo) *, (st))) 430d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_LogotypeInfo_value(st, i) (LogotypeInfo *) \ 431d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_value(CHECKED_CAST(_STACK *, const STACK_OF(LogotypeInfo) *, (st)), (i)) 432d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_LogotypeImage_num(st) \ 433d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_num(CHECKED_CAST(_STACK *, STACK_OF(LogotypeImage) *, (st))) 434d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_LogotypeImage_value(st, i) (LogotypeImage *) \ 435d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_value(CHECKED_CAST(_STACK *, const STACK_OF(LogotypeImage) *, (st)), (i)) 436d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_LogotypeAudio_num(st) \ 437d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_num(CHECKED_CAST(_STACK *, STACK_OF(LogotypeAudio) *, (st))) 438d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_LogotypeAudio_value(st, i) (LogotypeAudio *) \ 439d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_value(CHECK_CAST(_STACK *, const STACK_OF(LogotypeAudio) *, (st)), (i)) 440d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_HashAlgAndValue_num(st) \ 441d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_num(CHECKED_CAST(_STACK *, STACK_OF(HashAlgAndValue) *, (st))) 442d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_HashAlgAndValue_value(st, i) (HashAlgAndValue *) \ 443d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_value(CHECKED_CAST(_STACK *, const STACK_OF(HashAlgAndValue) *, (st)), (i)) 444d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_ASN1_IA5STRING_num(st) \ 445d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_num(CHECKED_CAST(_STACK *, STACK_OF(ASN1_IA5STRING) *, (st))) 446d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define sk_ASN1_IA5STRING_value(st, i) (ASN1_IA5STRING *) \ 447d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsk_value(CHECKED_CAST(_STACK *, const STACK_OF(ASN1_IA5STRING) *, (st)), (i)) 448d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* OPENSSL_IS_BORINGSSL */ 449d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_LogotypeInfo_num(st) SKM_sk_num(LogotypeInfo, (st)) 450d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_LogotypeInfo_value(st, i) SKM_sk_value(LogotypeInfo, (st), (i)) 451d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_LogotypeImage_num(st) SKM_sk_num(LogotypeImage, (st)) 452d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_LogotypeImage_value(st, i) SKM_sk_value(LogotypeImage, (st), (i)) 453d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_LogotypeAudio_num(st) SKM_sk_num(LogotypeAudio, (st)) 454d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_LogotypeAudio_value(st, i) SKM_sk_value(LogotypeAudio, (st), (i)) 455d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_HashAlgAndValue_num(st) SKM_sk_num(HashAlgAndValue, (st)) 456d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_HashAlgAndValue_value(st, i) SKM_sk_value(HashAlgAndValue, (st), (i)) 457d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_ASN1_IA5STRING_num(st) SKM_sk_num(ASN1_IA5STRING, (st)) 458d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define sk_ASN1_IA5STRING_value(st, i) SKM_sk_value(ASN1_IA5STRING, (st), (i)) 459d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 460d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 461d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 462d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_logo(struct http_ctx *ctx, struct http_cert *hcert, 463d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt HashAlgAndValue *hash, ASN1_IA5STRING *uri) 464d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 465d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char txt[100]; 466d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res, len; 467d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_logo *n; 468d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 469d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hash == NULL || uri == NULL) 470d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 471d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 472d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = OBJ_obj2txt(txt, sizeof(txt), hash->hashAlg->algorithm, 1); 473d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res < 0 || res >= (int) sizeof(txt)) 474d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 475d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 476d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n = os_realloc_array(hcert->logo, hcert->num_logo + 1, 477d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sizeof(struct http_logo)); 478d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (n == NULL) 479d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 480d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert->logo = n; 481d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n = &hcert->logo[hcert->num_logo]; 482d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memset(n, 0, sizeof(*n)); 483d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 484d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n->alg_oid = os_strdup(txt); 485d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (n->alg_oid == NULL) 486d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 487d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 488d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n->hash_len = ASN1_STRING_length(hash->hashValue); 489d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n->hash = os_malloc(n->hash_len); 490d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (n->hash == NULL) { 491d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(n->alg_oid); 492d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 493d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 494d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memcpy(n->hash, ASN1_STRING_data(hash->hashValue), n->hash_len); 495d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 496d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt len = ASN1_STRING_length(uri); 497d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n->uri = os_malloc(len + 1); 498d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (n->uri == NULL) { 499d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(n->alg_oid); 500d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(n->hash); 501d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 502d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 503d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memcpy(n->uri, ASN1_STRING_data(uri), len); 504d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n->uri[len] = '\0'; 505d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 506d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert->num_logo++; 507d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 508d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 509d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 510d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_logo_direct(struct http_ctx *ctx, struct http_cert *hcert, 511d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeData *data) 512d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 513d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int i, num; 514d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 515d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (data->image == NULL) 516d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 517d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 518d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = sk_LogotypeImage_num(data->image); 519d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 520d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeImage *image; 521d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeDetails *details; 522d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int j, hash_num, uri_num; 523d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt HashAlgAndValue *found_hash = NULL; 524d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 525d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt image = sk_LogotypeImage_value(data->image, i); 526d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (image == NULL) 527d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt continue; 528d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 529d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt details = image->imageDetails; 530d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (details == NULL) 531d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt continue; 532d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 533d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash_num = sk_HashAlgAndValue_num(details->logotypeHash); 534d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (j = 0; j < hash_num; j++) { 535d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt HashAlgAndValue *hash; 536d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char txt[100]; 537d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res; 538d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash = sk_HashAlgAndValue_value(details->logotypeHash, 539d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt j); 540d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hash == NULL) 541d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt continue; 542d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = OBJ_obj2txt(txt, sizeof(txt), 543d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash->hashAlg->algorithm, 1); 544d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res < 0 || res >= (int) sizeof(txt)) 545d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt continue; 546d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (os_strcmp(txt, "2.16.840.1.101.3.4.2.1") == 0) { 547d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt found_hash = hash; 548d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 549d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 550d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 551d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 552d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!found_hash) { 553d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: No SHA256 hash found for the logo"); 554d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt continue; 555d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 556d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 557d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri_num = sk_ASN1_IA5STRING_num(details->logotypeURI); 558d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (j = 0; j < uri_num; j++) { 559d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IA5STRING *uri; 560d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri = sk_ASN1_IA5STRING_value(details->logotypeURI, j); 561d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_logo(ctx, hcert, found_hash, uri); 562d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 563d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 564d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 565d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 566d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 567d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_logo_indirect(struct http_ctx *ctx, struct http_cert *hcert, 568d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeReference *ref) 569d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 570d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int j, hash_num, uri_num; 571d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 572d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash_num = sk_HashAlgAndValue_num(ref->refStructHash); 573d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri_num = sk_ASN1_IA5STRING_num(ref->refStructURI); 574d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hash_num != uri_num) { 575d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Unexpected LogotypeReference array size difference %d != %d", 576d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash_num, uri_num); 577d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 578d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 579d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 580d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (j = 0; j < hash_num; j++) { 581d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt HashAlgAndValue *hash; 582d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IA5STRING *uri; 583d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash = sk_HashAlgAndValue_value(ref->refStructHash, j); 584d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri = sk_ASN1_IA5STRING_value(ref->refStructURI, j); 585d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_logo(ctx, hcert, hash, uri); 586d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 587d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 588d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 589d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 590d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void i2r_HashAlgAndValue(HashAlgAndValue *hash, BIO *out, int indent) 591d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 592d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int i; 593d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const unsigned char *data; 594d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 595d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*shashAlg: ", indent, ""); 596d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2a_ASN1_OBJECT(out, hash->hashAlg->algorithm); 597d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "\n"); 598d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 599d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*shashValue: ", indent, ""); 600d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt data = hash->hashValue->data; 601d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < hash->hashValue->length; i++) 602d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%s%02x", i > 0 ? ":" : "", data[i]); 603d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "\n"); 604d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 605d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 606d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void i2r_LogotypeDetails(LogotypeDetails *details, BIO *out, int indent) 607d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 608d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int i, num; 609d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 610d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*sLogotypeDetails\n", indent, ""); 611d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (details->mediaType) { 612d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*smediaType: ", indent, ""); 613d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_STRING_print(out, details->mediaType); 614d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "\n"); 615d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 616d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 617d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = details->logotypeHash ? 618d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sk_HashAlgAndValue_num(details->logotypeHash) : 0; 619d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 620d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt HashAlgAndValue *hash; 621d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash = sk_HashAlgAndValue_value(details->logotypeHash, i); 622d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_HashAlgAndValue(hash, out, indent); 623d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 624d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 625d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = details->logotypeURI ? 626d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sk_ASN1_IA5STRING_num(details->logotypeURI) : 0; 627d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 628d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IA5STRING *uri; 629d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri = sk_ASN1_IA5STRING_value(details->logotypeURI, i); 630d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*slogotypeURI: ", indent, ""); 631d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_STRING_print(out, uri); 632d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "\n"); 633d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 634d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 635d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 636d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void i2r_LogotypeImageInfo(LogotypeImageInfo *info, BIO *out, int indent) 637d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 638d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt long val; 639d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 640d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*sLogotypeImageInfo\n", indent, ""); 641d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (info->type) { 642d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt val = ASN1_INTEGER_get(info->type); 643d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*stype: %ld\n", indent, "", val); 644d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 645d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*stype: default (1)\n", indent, ""); 646d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 647b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt val = ASN1_INTEGER_get(info->fileSize); 648b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO_printf(out, "%*sfileSize: %ld\n", indent, "", val); 649d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt val = ASN1_INTEGER_get(info->xSize); 650d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*sxSize: %ld\n", indent, "", val); 651d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt val = ASN1_INTEGER_get(info->ySize); 652d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*sySize: %ld\n", indent, "", val); 653d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (info->resolution) { 654b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO_printf(out, "%*sresolution [%d]\n", indent, "", 655b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt info->resolution->type); 656b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt switch (info->resolution->type) { 657b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt case 0: 658b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt val = ASN1_INTEGER_get(info->resolution->d.numBits); 659b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO_printf(out, "%*snumBits: %ld\n", indent, "", val); 660b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt break; 661b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt case 1: 662b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt val = ASN1_INTEGER_get(info->resolution->d.tableSize); 663b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO_printf(out, "%*stableSize: %ld\n", indent, "", val); 664b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt break; 665b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 666d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 667d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (info->language) { 668d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*slanguage: ", indent, ""); 669d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_STRING_print(out, info->language); 670d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "\n"); 671d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 672d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 673d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 674d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void i2r_LogotypeImage(LogotypeImage *image, BIO *out, int indent) 675d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 676d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*sLogotypeImage\n", indent, ""); 677d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (image->imageDetails) { 678d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeDetails(image->imageDetails, out, indent + 4); 679d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 680d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (image->imageInfo) { 681d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeImageInfo(image->imageInfo, out, indent + 4); 682d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 683d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 684d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 685d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void i2r_LogotypeData(LogotypeData *data, const char *title, BIO *out, 686d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int indent) 687d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 688d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int i, num; 689d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 690d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*s%s - LogotypeData\n", indent, "", title); 691d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 692d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = data->image ? sk_LogotypeImage_num(data->image) : 0; 693d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 694d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeImage *image = sk_LogotypeImage_value(data->image, i); 695d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeImage(image, out, indent + 4); 696d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 697d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 698d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = data->audio ? sk_LogotypeAudio_num(data->audio) : 0; 699d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 700d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*saudio: TODO\n", indent, ""); 701d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 702d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 703d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 704d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void i2r_LogotypeReference(LogotypeReference *ref, const char *title, 705d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO *out, int indent) 706d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 707d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int i, hash_num, uri_num; 708d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 709d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*s%s - LogotypeReference\n", indent, "", title); 710d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 711d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash_num = ref->refStructHash ? 712d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sk_HashAlgAndValue_num(ref->refStructHash) : 0; 713d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri_num = ref->refStructURI ? 714d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sk_ASN1_IA5STRING_num(ref->refStructURI) : 0; 715d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hash_num != uri_num) { 716d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*sUnexpected LogotypeReference array size difference %d != %d\n", 717d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt indent, "", hash_num, uri_num); 718d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 719d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 720d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 721d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < hash_num; i++) { 722d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt HashAlgAndValue *hash; 723d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_IA5STRING *uri; 724d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 725d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hash = sk_HashAlgAndValue_value(ref->refStructHash, i); 726d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_HashAlgAndValue(hash, out, indent); 727d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 728d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri = sk_ASN1_IA5STRING_value(ref->refStructURI, i); 729d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*srefStructURI: ", indent, ""); 730d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_STRING_print(out, uri); 731d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "\n"); 732d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 733d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 734d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 735d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void i2r_LogotypeInfo(LogotypeInfo *info, const char *title, BIO *out, 736d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int indent) 737d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 738d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt switch (info->type) { 739d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case 0: 740d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeData(info->d.direct, title, out, indent); 741d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 742d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case 1: 743d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeReference(info->d.indirect, title, out, indent); 744d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 745d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 746d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 747d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 748d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void debug_print_logotypeext(LogotypeExtn *logo) 749d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 750d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO *out; 751d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int i, num; 752d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int indent = 0; 753d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 754d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt out = BIO_new_fp(stdout, BIO_NOCLOSE); 755d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (out == NULL) 756d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 757d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 758d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (logo->communityLogos) { 759d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = sk_LogotypeInfo_num(logo->communityLogos); 760d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 761d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeInfo *info; 762d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt info = sk_LogotypeInfo_value(logo->communityLogos, i); 763d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeInfo(info, "communityLogo", out, indent); 764d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 765d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 766d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 767d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (logo->issuerLogo) { 768d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeInfo(logo->issuerLogo, "issuerLogo", out, indent ); 769d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 770d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 771d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (logo->subjectLogo) { 772d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt i2r_LogotypeInfo(logo->subjectLogo, "subjectLogo", out, indent); 773d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 774d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 775d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (logo->otherLogos) { 776d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_printf(out, "%*sotherLogos - TODO\n", indent, ""); 777d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 778d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 779d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_free(out); 780d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 781d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 782d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 783d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_logotype_ext(struct http_ctx *ctx, struct http_cert *hcert, 784d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *cert) 785d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 786d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_OBJECT *obj; 787d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int pos; 788d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_EXTENSION *ext; 789d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_OCTET_STRING *os; 790d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeExtn *logo; 791d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const unsigned char *data; 792d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int i, num; 793d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 794d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt obj = OBJ_txt2obj("1.3.6.1.5.5.7.1.12", 0); 795d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (obj == NULL) 796d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 797d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 798d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pos = X509_get_ext_by_OBJ(cert, obj, -1); 799d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (pos < 0) { 800d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No logotype extension included"); 801d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 802d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 803d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 804d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Parsing logotype extension"); 805d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ext = X509_get_ext(cert, pos); 806d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ext) { 807d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not get logotype extension"); 808d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 809d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 810d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 811d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os = X509_EXTENSION_get_data(ext); 812d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (os == NULL) { 813d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not get logotype extension data"); 814d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 815d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 816d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 817d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_hexdump(MSG_DEBUG, "logotypeExtn", 818d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_STRING_data(os), ASN1_STRING_length(os)); 819d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 820d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt data = ASN1_STRING_data(os); 821d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt logo = d2i_LogotypeExtn(NULL, &data, ASN1_STRING_length(os)); 822d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (logo == NULL) { 823d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Failed to parse logotypeExtn"); 824d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 825d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 826d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 827d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (wpa_debug_level < MSG_INFO) 828d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_print_logotypeext(logo); 829d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 830d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!logo->communityLogos) { 831d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No communityLogos included"); 832d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeExtn_free(logo); 833d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 834d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 835d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 836d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt num = sk_LogotypeInfo_num(logo->communityLogos); 837d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < num; i++) { 838d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeInfo *info; 839d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt info = sk_LogotypeInfo_value(logo->communityLogos, i); 840d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt switch (info->type) { 841d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case 0: 842d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_logo_direct(ctx, hcert, info->d.direct); 843d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 844d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt case 1: 845d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_logo_indirect(ctx, hcert, info->d.indirect); 846d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 847d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 848d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 849d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 850d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt LogotypeExtn_free(logo); 851d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 852d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 853d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 854d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void parse_cert(struct http_ctx *ctx, struct http_cert *hcert, 855d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *cert, GENERAL_NAMES **names) 856d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 857d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memset(hcert, 0, sizeof(*hcert)); 858d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 859d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 860d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt if (*names) 861d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_alt_names(ctx, hcert, *names); 862d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 863d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_logotype_ext(ctx, hcert, cert); 864d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 865d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 866d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 867d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void parse_cert_free(struct http_cert *hcert, GENERAL_NAMES *names) 868d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 869d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt unsigned int i; 870d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 871d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < hcert->num_dnsname; i++) 872d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OPENSSL_free(hcert->dnsname[i]); 873d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(hcert->dnsname); 874d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 875d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < hcert->num_othername; i++) 876d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(hcert->othername[i].oid); 877d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(hcert->othername); 878d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 879d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < hcert->num_logo; i++) { 880d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(hcert->logo[i].alg_oid); 881d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(hcert->logo[i].hash); 882d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(hcert->logo[i].uri); 883d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 884d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(hcert->logo); 885d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 886d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); 887d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 888d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 889d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 890d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int validate_server_cert(struct http_ctx *ctx, X509 *cert) 891d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 892d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt GENERAL_NAMES *names; 893d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_cert hcert; 894d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 895d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 896912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (ctx->cert_cb == NULL) { 897912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: no cert_cb configured", __func__); 898d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 899912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } 900d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 901d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (0) { 902d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO *out; 903d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt out = BIO_new_fp(stdout, BIO_NOCLOSE); 904d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_print_ex(out, cert, XN_FLAG_COMPAT, X509_FLAG_COMPAT); 905d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_free(out); 906d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 907d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 908d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt parse_cert(ctx, &hcert, cert, &names); 909d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = ctx->cert_cb(ctx->cert_cb_ctx, &hcert); 910d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt parse_cert_free(&hcert, names); 911d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 912d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret; 913d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 914d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 915d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 916d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid http_parse_x509_certificate(struct http_ctx *ctx, const char *fname) 917d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 918d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO *in, *out; 919d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *cert; 920d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt GENERAL_NAMES *names; 921d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_cert hcert; 922d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt unsigned int i; 923d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 924d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt in = BIO_new_file(fname, "r"); 925d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (in == NULL) { 926d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "Could not read '%s'", fname); 927d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 928d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 929d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 930d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert = d2i_X509_bio(in, NULL); 931d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_free(in); 932d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 933d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (cert == NULL) { 934d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "Could not parse certificate"); 935d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 936d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 937d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 938d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt out = BIO_new_fp(stdout, BIO_NOCLOSE); 939d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (out) { 940d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_print_ex(out, cert, XN_FLAG_COMPAT, 941d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_FLAG_COMPAT); 942d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_free(out); 943d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 944d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 945d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Additional parsing information:"); 946d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt parse_cert(ctx, &hcert, cert, &names); 947d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (i = 0; i < hcert.num_othername; i++) { 948d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (os_strcmp(hcert.othername[i].oid, 949d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "1.3.6.1.4.1.40808.1.1.1") == 0) { 950d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *name = os_zalloc(hcert.othername[i].len + 1); 951d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (name) { 952d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memcpy(name, hcert.othername[i].data, 953d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert.othername[i].len); 954d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, 955d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "id-wfa-hotspot-friendlyName: %s", 956d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name); 957d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(name); 958d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 959d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_hexdump_ascii(MSG_INFO, 960d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "id-wfa-hotspot-friendlyName", 961d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert.othername[i].data, 962d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert.othername[i].len); 963d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 964d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "subjAltName[othername]: oid=%s", 965d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert.othername[i].oid); 966d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_hexdump_ascii(MSG_INFO, "unknown othername", 967d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert.othername[i].data, 968d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hcert.othername[i].len); 969d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 970d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 971d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt parse_cert_free(&hcert, names); 972d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 973d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_free(cert); 974d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 975d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 976d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 977d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int curl_cb_ssl_verify(int preverify_ok, X509_STORE_CTX *x509_ctx) 978d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 979d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_ctx *ctx; 980d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *cert; 981d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int err, depth; 982d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char buf[256]; 983d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_NAME *name; 984d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *err_str; 985d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL *ssl; 986d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_CTX *ssl_ctx; 987d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 988d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 989d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_get_ex_data_X509_STORE_CTX_idx()); 990d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ssl_ctx = ssl->ctx; 991d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx = SSL_CTX_get_app_data(ssl_ctx); 992d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 993912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt wpa_printf(MSG_DEBUG, "curl_cb_ssl_verify, preverify_ok: %d", 994912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt preverify_ok); 995d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 996d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt err = X509_STORE_CTX_get_error(x509_ctx); 997d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt err_str = X509_verify_cert_error_string(err); 998d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt depth = X509_STORE_CTX_get_error_depth(x509_ctx); 999d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert = X509_STORE_CTX_get_current_cert(x509_ctx); 1000d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!cert) { 1001d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No server certificate available"); 1002d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "No server certificate available"; 1003d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1004d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1005d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1006d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (depth == 0) 1007d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->peer_cert = cert; 1008d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt else if (depth == 1) 1009d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->peer_issuer = cert; 1010d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt else if (depth == 2) 1011d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->peer_issuer_issuer = cert; 1012d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1013d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name = X509_get_subject_name(cert); 1014d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_NAME_oneline(name, buf, sizeof(buf)); 1015d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Server certificate chain - depth=%d err=%d (%s) subject=%s", 1016d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt depth, err, err_str, buf); 1017d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_cert("Server certificate chain - certificate", cert); 1018d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1019d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (depth == 0 && preverify_ok && validate_server_cert(ctx, cert) < 0) 1020d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1021d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1022d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 1023d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (depth == 0 && ctx->ocsp != NO_OCSP && preverify_ok) { 1024d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt enum ocsp_result res; 1025d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt 1026d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt res = check_ocsp_resp(ssl_ctx, ssl, cert, ctx->peer_issuer, 1027d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt ctx->peer_issuer_issuer); 1028d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (res == OCSP_REVOKED) { 1029d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt preverify_ok = 0; 1030d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt wpa_printf(MSG_INFO, "OCSP: certificate revoked"); 1031d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (err == X509_V_OK) 1032d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt X509_STORE_CTX_set_error( 1033d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt x509_ctx, X509_V_ERR_CERT_REVOKED); 1034d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt } else if (res != OCSP_GOOD && (ctx->ocsp == MANDATORY_OCSP)) { 1035d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt preverify_ok = 0; 1036d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt wpa_printf(MSG_INFO, 1037d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt "OCSP: bad certificate status response"); 1038d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt } 1039d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt } 1040d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 1041d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt 1042d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!preverify_ok) 1043d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "TLS validation failed"; 1044d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1045d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return preverify_ok; 1046d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1047d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1048d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1049d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#ifdef HAVE_OCSP 1050d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1051d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void ocsp_debug_print_resp(OCSP_RESPONSE *rsp) 1052d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1053d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO *out; 1054d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt size_t rlen; 1055d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *txt; 1056d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res; 1057d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1058d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt out = BIO_new(BIO_s_mem()); 1059d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!out) 1060d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 1061d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1062d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_print(out, rsp, 0); 1063d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt rlen = BIO_ctrl_pending(out); 1064d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt txt = os_malloc(rlen + 1); 1065d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!txt) { 1066d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_free(out); 1067d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 1068d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1069d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1070d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = BIO_read(out, txt, rlen); 1071d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res > 0) { 1072d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt txt[res] = '\0'; 1073d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_MSGDUMP, "OpenSSL: OCSP Response\n%s", txt); 1074d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1075d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(txt); 1076d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt BIO_free(out); 1077d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1078d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1079d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1080d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void tls_show_errors(const char *func, const char *txt) 1081d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1082d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt unsigned long err; 1083d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1084d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - %s %s", 1085d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt func, txt, ERR_error_string(ERR_get_error(), NULL)); 1086d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1087d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt while ((err = ERR_get_error())) { 1088d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: pending error: %s", 1089d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ERR_error_string(err, NULL)); 1090d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1091d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1092d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1093d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1094d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int ocsp_resp_cb(SSL *s, void *arg) 1095d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1096d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_ctx *ctx = arg; 1097d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const unsigned char *p; 1098d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int len, status, reason; 1099d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE *rsp; 1100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP *basic; 1101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_CERTID *id; 1102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update; 1103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_STORE *store; 1104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt STACK_OF(X509) *certs = NULL; 1105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt len = SSL_get_tlsext_status_ocsp_resp(s, &p); 1107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!p) { 1108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received"); 1109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->ocsp == MANDATORY_OCSP) 1110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "No OCSP response received"; 1111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return (ctx->ocsp == MANDATORY_OCSP) ? 0 : 1; 1112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len); 1115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt rsp = d2i_OCSP_RESPONSE(NULL, &p, len); 1117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!rsp) { 1118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response"); 1119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Failed to parse OCSP response"; 1120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ocsp_debug_print_resp(rsp); 1124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1125d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status = OCSP_response_status(rsp); 1126d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 1127d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)", 1128d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status, OCSP_response_status_str(status)); 1129d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "OCSP responder error"; 1130d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1131d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1132d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1133d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt basic = OCSP_response_get1_basic(rsp); 1134d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!basic) { 1135d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse"); 1136d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Could not find BasicOCSPResponse"; 1137d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1138d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1139d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1140d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt store = SSL_CTX_get_cert_store(s->ctx); 1141d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->peer_issuer) { 1142d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Add issuer"); 1143d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_cert("OpenSSL: Issuer certificate", 1144d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->peer_issuer); 1145d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1146d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (X509_STORE_add_cert(store, ctx->peer_issuer) != 1) { 1147d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tls_show_errors(__func__, 11487f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to certificate store"); 1149d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1150d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt certs = sk_X509_new_null(); 1151d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (certs) { 1152d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509 *cert; 1153d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert = X509_dup(ctx->peer_issuer); 1154d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 1155d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tls_show_errors( 1156d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt __func__, 11577f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to OCSP responder trust store"); 1158d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_free(cert); 1159d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sk_X509_free(certs); 1160d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt certs = NULL; 1161d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 11627f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (certs && ctx->peer_issuer_issuer) { 1163d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cert = X509_dup(ctx->peer_issuer_issuer); 1164d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 1165d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tls_show_errors( 1166d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt __func__, 11677f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer's issuer to OCSP responder trust store"); 1168d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt X509_free(cert); 1169d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1170d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1171d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1172d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1173d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1174d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER); 1175d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt sk_X509_pop_free(certs, X509_free); 1176d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (status <= 0) { 1177d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tls_show_errors(__func__, 1178d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "OpenSSL: OCSP response failed verification"); 1179d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP_free(basic); 1180d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_free(rsp); 1181d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "OCSP response failed verification"; 1182d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1183d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1184d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1185d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded"); 1186d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1187d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ctx->peer_cert) { 1188d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check"); 1189d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP_free(basic); 1190d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_free(rsp); 1191d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Peer certificate not available for OCSP status check"; 1192d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1193d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1194d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1195d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ctx->peer_issuer) { 1196d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check"); 1197d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP_free(basic); 1198d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_free(rsp); 1199d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Peer issuer certificate not available for OCSP status check"; 1200d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1201d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1202d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1203d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt id = OCSP_cert_to_id(NULL, ctx->peer_cert, ctx->peer_issuer); 1204d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!id) { 1205d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Could not create OCSP certificate identifier"); 1206d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP_free(basic); 1207d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_free(rsp); 1208d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Could not create OCSP certificate identifier"; 1209d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1210d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1211d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1212d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!OCSP_resp_find_status(basic, id, &status, &reason, &produced_at, 1213d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt &this_update, &next_update)) { 1214d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s", 1215d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt (ctx->ocsp == MANDATORY_OCSP) ? "" : 1216d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt " (OCSP not required)"); 121757c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt OCSP_CERTID_free(id); 1218d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP_free(basic); 1219d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_free(rsp); 1220d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->ocsp == MANDATORY_OCSP) 1221d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1222d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Could not find current server certificate from OCSP response"; 1223d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return (ctx->ocsp == MANDATORY_OCSP) ? 0 : 1; 1224d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 122557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt OCSP_CERTID_free(id); 1226d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1227d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) { 1228d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tls_show_errors(__func__, "OpenSSL: OCSP status times invalid"); 1229d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP_free(basic); 1230d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_free(rsp); 1231d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "OCSP status times invalid"; 1232d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1233d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1234d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1235d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_BASICRESP_free(basic); 1236d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_RESPONSE_free(rsp); 1237d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1238d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s", 1239d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt OCSP_cert_status_str(status)); 1240d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1241d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (status == V_OCSP_CERTSTATUS_GOOD) 1242d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 1; 1243661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (status == V_OCSP_CERTSTATUS_REVOKED) { 1244d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Server certificate has been revoked"; 1245d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1246661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 1247d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->ocsp == MANDATORY_OCSP) { 1248d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required"); 1249d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "OCSP status unknown"; 1250d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1251d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1252d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue"); 1253d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 1; 1254d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1255d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1256d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1257d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic SSL_METHOD patch_ssl_method; 1258d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic const SSL_METHOD *real_ssl_method; 1259d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1260d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int curl_patch_ssl_new(SSL *s) 1261d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1262d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_CTX *ssl = s->ctx; 1263d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 1264d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1265d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ssl->method = real_ssl_method; 1266d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt s->method = real_ssl_method; 1267d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1268d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = s->method->ssl_new(s); 1269d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_set_tlsext_status_type(s, TLSEXT_STATUSTYPE_ocsp); 1270d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1271d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret; 1272d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1273d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1274d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif /* HAVE_OCSP */ 1275d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1276d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1277d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic CURLcode curl_cb_ssl(CURL *curl, void *sslctx, void *parm) 1278d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1279d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_ctx *ctx = parm; 1280d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_CTX *ssl = sslctx; 1281d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1282d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "curl_cb_ssl"); 1283d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_CTX_set_app_data(ssl, ctx); 1284d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_CTX_set_verify(ssl, SSL_VERIFY_PEER, curl_cb_ssl_verify); 1285d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1286d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#ifdef HAVE_OCSP 1287d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->ocsp != NO_OCSP) { 1288d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_CTX_set_tlsext_status_cb(ssl, ocsp_resp_cb); 1289d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SSL_CTX_set_tlsext_status_arg(ssl, ctx); 1290d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1291d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt /* 1292d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Use a temporary SSL_METHOD to get a callback on SSL_new() 1293d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * from libcurl since there is no proper callback registration 1294d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * available for this. 1295d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */ 1296d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memset(&patch_ssl_method, 0, sizeof(patch_ssl_method)); 1297d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt patch_ssl_method.ssl_new = curl_patch_ssl_new; 1298d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt real_ssl_method = ssl->method; 1299d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ssl->method = &patch_ssl_method; 1300d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1301d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif /* HAVE_OCSP */ 1302d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1303d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return CURLE_OK; 1304d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1305d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1306d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif /* EAP_TLS_OPENSSL */ 1307d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1308d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1309d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic CURL * setup_curl_post(struct http_ctx *ctx, const char *address, 1310d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *ca_fname, const char *username, 1311d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *password, const char *client_cert, 1312d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *client_key) 1313d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1314d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt CURL *curl; 1315912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt#ifdef EAP_TLS_OPENSSL 1316912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt const char *extra = " tls=openssl"; 1317912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt#else /* EAP_TLS_OPENSSL */ 1318912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt const char *extra = ""; 1319912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt#endif /* EAP_TLS_OPENSSL */ 1320d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1321d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "Start HTTP client: address=%s ca_fname=%s " 1322912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt "username=%s%s", address, ca_fname, username, extra); 1323d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1324d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl = curl_easy_init(); 1325d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (curl == NULL) 1326d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1327d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1328d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_URL, address); 1329d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_POST, 1L); 1330d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ca_fname) { 1331d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_CAINFO, ca_fname); 1332d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); 1333d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#ifdef EAP_TLS_OPENSSL 1334d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, curl_cb_ssl); 1335d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, ctx); 1336d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 1337d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt /* For now, using the CURLOPT_SSL_VERIFYSTATUS option only 1338d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * with BoringSSL since the OpenSSL specific callback hack to 1339d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * enable OCSP is not available with BoringSSL. The OCSP 1340d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * implementation within libcurl is not sufficient for the 1341d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * Hotspot 2.0 OSU needs, so cannot use this with OpenSSL. 1342d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt */ 1343d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (ctx->ocsp != NO_OCSP) 1344d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L); 1345d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 1346d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif /* EAP_TLS_OPENSSL */ 1347d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 1348d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 1349d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1350d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (client_cert && client_key) { 1351d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSLCERT, client_cert); 1352d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSLKEY, client_key); 1353d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1354d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt /* TODO: use curl_easy_getinfo() with CURLINFO_CERTINFO to fetch 1355d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * information about the server certificate */ 1356d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L); 1357d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug); 1358d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx); 1359d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_cb_write); 1360d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_WRITEDATA, ctx); 1361d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 1362d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (username) { 1363d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); 1364d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_USERNAME, username); 1365d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_PASSWORD, password); 1366d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1367d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1368d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return curl; 1369d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1370d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1371d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1372d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int post_init_client(struct http_ctx *ctx, const char *address, 1373d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *ca_fname, const char *username, 1374d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *password, const char *client_cert, 1375d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *client_key) 1376d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1377d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *pos; 1378d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int count; 1379d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1380d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&ctx->svc_address, address); 1381d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&ctx->svc_ca_fname, ca_fname); 1382d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&ctx->svc_username, username); 1383d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&ctx->svc_password, password); 1384d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&ctx->svc_client_cert, client_cert); 1385d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&ctx->svc_client_key, client_key); 1386d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1387d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt /* 1388d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Workaround for Apache "Hostname 'FOO' provided via SNI and hostname 1389d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * 'foo' provided via HTTP are different. 1390d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */ 1391d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt for (count = 0, pos = ctx->svc_address; count < 3 && pos && *pos; 1392d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pos++) { 1393d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (*pos == '/') 1394d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt count++; 1395d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *pos = tolower(*pos); 1396d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1397d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1398d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl = setup_curl_post(ctx, ctx->svc_address, ca_fname, username, 1399d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt password, client_cert, client_key); 1400d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->curl == NULL) 1401d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 1402d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1403d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1404d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1405d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1406d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1407d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint soap_init_client(struct http_ctx *ctx, const char *address, 1408d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *ca_fname, const char *username, 1409d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *password, const char *client_cert, 1410d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *client_key) 1411d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1412d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (post_init_client(ctx, address, ca_fname, username, password, 1413d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt client_cert, client_key) < 0) 1414d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 1415d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1416d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_hdr = curl_slist_append(ctx->curl_hdr, 1417d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Content-Type: application/soap+xml"); 1418d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_hdr = curl_slist_append(ctx->curl_hdr, "SOAPAction: "); 1419d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_hdr = curl_slist_append(ctx->curl_hdr, "Expect:"); 1420d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->curl_hdr); 1421d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1422d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1423d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1424d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1425d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1426d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint soap_reinit_client(struct http_ctx *ctx) 1427d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1428d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *address = NULL; 1429d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *ca_fname = NULL; 1430d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *username = NULL; 1431d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *password = NULL; 1432d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *client_cert = NULL; 1433d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *client_key = NULL; 1434d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 1435d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1436d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clear_curl(ctx); 1437d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1438d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&address, ctx->svc_address); 1439d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&ca_fname, ctx->svc_ca_fname); 1440d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&username, ctx->svc_username); 1441d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&password, ctx->svc_password); 1442d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&client_cert, ctx->svc_client_cert); 1443d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clone_str(&client_key, ctx->svc_client_key); 1444d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1445d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = soap_init_client(ctx, address, ca_fname, username, password, 1446d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt client_cert, client_key); 1447d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(address); 1448d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ca_fname); 1449c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt str_clear_free(username); 1450c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt str_clear_free(password); 1451d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(client_cert); 1452d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(client_key); 1453d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret; 1454d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1455d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1456d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1457d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void free_curl_buf(struct http_ctx *ctx) 1458d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1459d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->curl_buf); 1460d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_buf = NULL; 1461d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_buf_len = 0; 1462d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1463d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1464d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1465d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtxml_node_t * soap_send_receive(struct http_ctx *ctx, xml_node_t *node) 1466d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1467d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *str; 1468d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *envelope, *ret, *resp, *n; 1469d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt CURLcode res; 1470d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt long http = 0; 1471d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1472d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = NULL; 1473d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1474d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "SOAP: Sending message"); 1475d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt envelope = soap_build_envelope(ctx->xml, node); 1476d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt str = xml_node_to_str(ctx->xml, envelope); 1477d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, envelope); 1478d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_MSGDUMP, "SOAP[%s]", str); 1479d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1480d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDS, str); 1481d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free_curl_buf(ctx); 1482d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1483d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = curl_easy_perform(ctx->curl); 1484d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res != CURLE_OK) { 1485d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ctx->last_err) 1486d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = curl_easy_strerror(res); 1487d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s", 1488d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err); 1489d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(str); 1490d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free_curl_buf(ctx); 1491d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1492d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1493d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(str); 1494d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1495d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_getinfo(ctx->curl, CURLINFO_RESPONSE_CODE, &http); 1496d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "SOAP: Server response code %ld", http); 1497d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (http != 200) { 1498d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "HTTP download failed"; 1499d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "HTTP download failed - code %ld", http); 1500d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free_curl_buf(ctx); 1501d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1502d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1503d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1504d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->curl_buf == NULL) 1505d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1506d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1507d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Server response:\n%s", ctx->curl_buf); 1508d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt resp = xml_node_from_buf(ctx->xml, ctx->curl_buf); 1509d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free_curl_buf(ctx); 1510d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (resp == NULL) { 1511d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not parse SOAP response"); 1512d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Could not parse SOAP response"; 1513d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1514d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1515d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1516d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = soap_get_body(ctx->xml, resp); 1517d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret == NULL) { 1518d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not get SOAP body"); 1519d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "Could not get SOAP body"; 1520d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1521d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1522d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1523d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "SOAP body localname: '%s'", 1524d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_localname(ctx->xml, ret)); 1525d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt n = xml_node_copy(ctx->xml, ret); 1526d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, resp); 1527d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1528d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return n; 1529d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1530d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1531d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1532d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstruct http_ctx * http_init_ctx(void *upper_ctx, struct xml_node_ctx *xml_ctx) 1533d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1534d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_ctx *ctx; 1535d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1536d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 1537d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx == NULL) 1538d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1539d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->ctx = upper_ctx; 1540d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->xml = xml_ctx; 1541d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->ocsp = OPTIONAL_OCSP; 1542d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1543d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_global_init(CURL_GLOBAL_ALL); 1544d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1545d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ctx; 1546d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1547d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1548d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1549d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid http_ocsp_set(struct http_ctx *ctx, int val) 1550d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1551d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (val == 0) 1552d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->ocsp = NO_OCSP; 1553d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt else if (val == 1) 1554d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->ocsp = OPTIONAL_OCSP; 1555d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (val == 2) 1556d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->ocsp = MANDATORY_OCSP; 1557d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1558d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1559d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1560d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid http_deinit_ctx(struct http_ctx *ctx) 1561d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1562d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt clear_curl(ctx); 1563d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->curl_buf); 1564d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_global_cleanup(); 1565d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1566d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->svc_address); 1567d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->svc_ca_fname); 1568c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt str_clear_free(ctx->svc_username); 1569c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt str_clear_free(ctx->svc_password); 1570d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->svc_client_cert); 1571d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->svc_client_key); 1572d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1573d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx); 1574d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1575d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1576d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1577d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint http_download_file(struct http_ctx *ctx, const char *url, 1578d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *fname, const char *ca_fname) 1579d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1580d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt CURL *curl; 1581d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt FILE *f; 1582d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt CURLcode res; 1583d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt long http = 0; 1584d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1585d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = NULL; 1586d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1587d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "curl: Download file from %s to %s (ca=%s)", 1588d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt url, fname, ca_fname); 1589d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl = curl_easy_init(); 1590d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (curl == NULL) 1591d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 1592d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1593d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt f = fopen(fname, "wb"); 1594d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (f == NULL) { 1595d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_cleanup(curl); 1596d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 1597d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1598d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1599d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_URL, url); 1600d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ca_fname) { 1601d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_CAINFO, ca_fname); 1602d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); 1603d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L); 1604d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 1605d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 1606d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1607d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug); 1608d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx); 1609d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); 1610d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_WRITEDATA, f); 1611d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 1612d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1613d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = curl_easy_perform(curl); 1614d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res != CURLE_OK) { 1615d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ctx->last_err) 1616d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = curl_easy_strerror(res); 1617d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s", 1618d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err); 1619d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_cleanup(curl); 1620d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt fclose(f); 1621d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 1622d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1623d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1624d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http); 1625d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "curl: Server response code %ld", http); 1626d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (http != 200) { 1627d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "HTTP download failed"; 1628d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "HTTP download failed - code %ld", http); 1629d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_cleanup(curl); 1630d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt fclose(f); 1631d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 1632d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1633d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1634d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_cleanup(curl); 1635d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt fclose(f); 1636d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1637d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 1638d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1639d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1640d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1641d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtchar * http_post(struct http_ctx *ctx, const char *url, const char *data, 1642d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *content_type, const char *ext_hdr, 1643d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *ca_fname, 1644d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *username, const char *password, 1645d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *client_cert, const char *client_key, 1646d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt size_t *resp_len) 1647d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1648d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt long http = 0; 1649d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt CURLcode res; 1650d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *ret; 1651d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt CURL *curl; 1652d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct curl_slist *curl_hdr = NULL; 1653d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1654d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = NULL; 1655d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "curl: HTTP POST to %s", url); 1656d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl = setup_curl_post(ctx, url, ca_fname, username, password, 1657d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt client_cert, client_key); 1658d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (curl == NULL) 1659d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1660d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1661d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (content_type) { 1662d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char ct[200]; 1663d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt snprintf(ct, sizeof(ct), "Content-Type: %s", content_type); 1664d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_hdr = curl_slist_append(curl_hdr, ct); 1665d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1666d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ext_hdr) 1667d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_hdr = curl_slist_append(curl_hdr, ext_hdr); 1668d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_hdr); 1669d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1670d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); 1671d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free_curl_buf(ctx); 1672d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1673d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = curl_easy_perform(curl); 1674d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res != CURLE_OK) { 1675d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ctx->last_err) 1676d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = curl_easy_strerror(res); 1677d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s", 1678d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err); 1679d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free_curl_buf(ctx); 1680d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1681d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1682d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1683d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http); 1684d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "curl: Server response code %ld", http); 1685d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (http != 200) { 1686d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->last_err = "HTTP POST failed"; 1687d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "HTTP POST failed - code %ld", http); 1688d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free_curl_buf(ctx); 1689d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1690d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 1691d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1692d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->curl_buf == NULL) 1693d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 1694d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1695d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = ctx->curl_buf; 1696d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (resp_len) 1697d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *resp_len = ctx->curl_buf_len; 1698d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_buf = NULL; 1699d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->curl_buf_len = 0; 1700d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1701d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Server response:\n%s", ret); 1702d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1703d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret; 1704d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1705d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1706d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1707d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid http_set_cert_cb(struct http_ctx *ctx, 1708d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int (*cb)(void *ctx, struct http_cert *cert), 1709d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt void *cb_ctx) 1710d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1711d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->cert_cb = cb; 1712d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->cert_cb_ctx = cb_ctx; 1713d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1714d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1715d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1716d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtconst char * http_get_err(struct http_ctx *ctx) 1717d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 1718d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ctx->last_err; 1719d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1720