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