libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit ff4e3e20a72efa956ab1e2685fb63ad23a357d4d
parent 0876373669fb00839ccd125c9529364128d445dc
Author: lv-426 <oxcafebaby@yahoo.com>
Date:   Sat,  5 Jul 2008 00:42:25 +0000

partial support for users to query SSL/TLS sessions for negotiated settings
added querying test
removed SSLv2 code


Diffstat:
Msrc/daemon/connection.c | 24+++++++++++++++++++++---
Msrc/daemon/daemon.c | 12++++++------
Msrc/daemon/https/Makefile.am | 1+
Dsrc/daemon/https/includes/gnutlsxx.h | 393-------------------------------------------------------------------------------
Msrc/daemon/https/tls/Makefile.am | 2--
Msrc/daemon/https/tls/gnutls_handshake.c | 77+++++++++++++++++++++++++++++++++--------------------------------------------
Msrc/daemon/https/tls/gnutls_priority.c | 4++--
Dsrc/daemon/https/tls/gnutls_v2_compat.c | 259-------------------------------------------------------------------------------
Dsrc/daemon/https/tls/gnutls_v2_compat.h | 26--------------------------
Dsrc/daemon/https/tls/gnutlsxx.cpp | 907-------------------------------------------------------------------------------
Msrc/daemon/https/tls/io_debug.h | 4++--
Dsrc/daemon/https/tls/libgnutlsxx.vers | 30------------------------------
Msrc/daemon/https/x509/x509_privkey.c | 19++++++-------------
Msrc/examples/Makefile.am | 2+-
Msrc/include/microhttpd.h | 20+++++++++++++++++++-
Msrc/testcurl/Makefile.am | 1+
Msrc/testcurl/https/Makefile.am | 12++++++++++--
Msrc/testcurl/https/daemon_https_test_get.c | 13+++++++++----
Asrc/testcurl/https/mhds_test_session_info.c | 238+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19 files changed, 349 insertions(+), 1695 deletions(-)

diff --git a/src/daemon/connection.c b/src/daemon/connection.c @@ -33,6 +33,7 @@ // get opaque type #include "gnutls_int.h" + // TODO clean #undef MAX #define MAX(a,b) ((a)<(b)) ? (b) : (a) @@ -160,6 +161,23 @@ MHD_get_connection_values (struct MHD_Connection *connection, return ret; } +#if HTTPS_SUPPORT +/* get cipher spec for this connection */ +gnutls_cipher_algorithm_t MHDS_get_session_cipher (struct MHD_Connection * session ){ + return gnutls_cipher_get(session->tls_session); +} + +gnutls_mac_algorithm_t MHDS_get_session_mac (struct MHD_Connection * session ){ + return gnutls_mac_get(session->tls_session); +} +gnutls_compression_method_t MHDS_get_session_compression (struct MHD_Connection * session ){ + return gnutls_compression_get(session->tls_session); +} +gnutls_certificate_type_t MHDS_get_session_cert_type (struct MHD_Connection * session ){ + return gnutls_certificate_type_get(session->tls_session); +} +#endif + /** * Get a particular header value. If multiple * values match the kind, return any one of them. @@ -1546,7 +1564,7 @@ MHDS_connection_handle_read (struct MHD_Connection *connection) break; case GNUTLS_ALERT: - /* + /* * this call of _gnutls_recv_int expects 0 bytes read. * done to decrypt alert message */ @@ -1601,7 +1619,7 @@ MHDS_connection_handle_read (struct MHD_Connection *connection) /* forward application level content to MHD */ case GNUTLS_APPLICATION_DATA: return MHD_connection_handle_read (connection); - // TODO impl + // TODO impl case GNUTLS_HANDSHAKE: break; case GNUTLS_INNER_APPLICATION: @@ -1823,7 +1841,7 @@ MHDS_connection_handle_write (struct MHD_Connection *connection) connection->s_state = MHDS_REPLY_SENDING; do_write (connection); break; - + case MHDS_CONNECTION_CLOSED: if (connection->socket_fd != -1) connection_close_error (connection); diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c @@ -220,7 +220,7 @@ MHDS_handle_connection (void *data) con->daemon->x509_cret); /* avoid gnutls blocking recv / write calls */ - gnutls_transport_set_pull_function(tls_session, &recv); + // gnutls_transport_set_pull_function(tls_session, &recv); // gnutls_transport_set_push_function(tls_session, &send); gnutls_transport_set_ptr (tls_session, con->socket_fd); @@ -240,9 +240,9 @@ MHDS_handle_connection (void *data) con->s_state = MHDS_HANDSHAKE_FAILED; gnutls_bye (con->tls_session, GNUTLS_SHUT_WR); gnutls_deinit (tls_session); - con->socket_fd = 1; + con->socket_fd = -1; return MHD_NO; - + } MHD_handle_connection (data); @@ -338,7 +338,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) CLOSE (s); return MHD_NO; } - + /* apply connection acceptance policy if present */ if ((daemon->apc != NULL) && (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen))) @@ -415,7 +415,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) &MHDS_handle_connection, connection); else -#endif +#endif { res_thread_create = pthread_create (&connection->pid, NULL, &MHD_handle_connection, @@ -607,7 +607,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block) ds = daemon->socket_fd; if (ds == -1) return MHD_YES; - + /* select connection thread handling type */ if (__FD_ISSET (ds, &rs)) MHD_accept_connection (daemon); diff --git a/src/daemon/https/Makefile.am b/src/daemon/https/Makefile.am @@ -6,6 +6,7 @@ AM_CPPFLAGS = -I./includes \ -I$(top_srcdir)/src/daemon/https/openpgp \ -I$(top_srcdir)/src/daemon/https/opencdk \ -I$(top_srcdir)/src/daemon/https/tls \ +-I$(top_srcdir)/src/daemon/https/includes \ -I$(top_srcdir)/src/daemon/https/cfg noinst_LTLIBRARIES = libhttps.la diff --git a/src/daemon/https/includes/gnutlsxx.h b/src/daemon/https/includes/gnutlsxx.h @@ -1,393 +0,0 @@ -#ifndef GNUTLSXX_H -# define GNUTLSXX_H - -#include <exception> -#include <vector> -#include <gnutls.h> - -namespace gnutls { - -class exception: public std::exception -{ - public: - exception( int x); - const char* what() const throw(); - int get_code(); - protected: - int retcode; -}; - -class dh_params -{ - public: - dh_params(); - ~dh_params(); - void import_raw( const gnutls_datum_t & prime, - const gnutls_datum_t & generator); - void import_pkcs3( const gnutls_datum_t & pkcs3_params, - gnutls_x509_crt_fmt_t format); - void generate( unsigned int bits); - - void export_pkcs3( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size); - void export_raw( gnutls_datum_t& prime, gnutls_datum_t &generator); - - gnutls_dh_params_t get_params_t() const; - dh_params & operator=(const dh_params& src); - protected: - gnutls_dh_params_t params; -}; - - -class rsa_params -{ - public: - rsa_params(); - ~rsa_params(); - void import_raw( const gnutls_datum_t & m, - const gnutls_datum_t & e, - const gnutls_datum_t & d, - const gnutls_datum_t & p, - const gnutls_datum_t & q, - const gnutls_datum_t & u); - void import_pkcs1( const gnutls_datum_t & pkcs1_params, - gnutls_x509_crt_fmt_t format); - void generate( unsigned int bits); - - void export_pkcs1( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size); - void export_raw( gnutls_datum_t & m, gnutls_datum_t & e, - gnutls_datum_t & d, gnutls_datum_t & p, - gnutls_datum_t & q, gnutls_datum_t & u); - gnutls_rsa_params_t get_params_t() const; - rsa_params & operator=(const rsa_params& src); - - protected: - gnutls_rsa_params_t params; -}; - -class session -{ - protected: - gnutls_session_t s; - public: - session( gnutls_connection_end_t); - session( session& s); - virtual ~session(); - - int bye( gnutls_close_request_t how); - int handshake (); - - gnutls_alert_description_t get_alert() const; - - int send_alert ( gnutls_alert_level_t level, - gnutls_alert_description_t desc); - int send_appropriate_alert (int err); - - gnutls_cipher_algorithm_t get_cipher() const; - gnutls_kx_algorithm_t get_kx () const; - gnutls_mac_algorithm_t get_mac () const; - gnutls_compression_method_t get_compression () const; - gnutls_certificate_type_t get_certificate_type() const; - - // for the handshake - void set_private_extensions ( bool allow); - - gnutls_handshake_description_t get_handshake_last_out() const; - gnutls_handshake_description_t get_handshake_last_in() const; - - ssize_t send (const void *data, size_t sizeofdata); - ssize_t recv (void *data, size_t sizeofdata); - - bool get_record_direction() const; - - // maximum packet size - size_t get_max_size() const; - void set_max_size(size_t size); - - size_t check_pending() const; - - void prf (size_t label_size, const char *label, - int server_random_first, - size_t extra_size, const char *extra, - size_t outsize, char *out); - - void prf_raw ( size_t label_size, const char *label, - size_t seed_size, const char *seed, - size_t outsize, char *out); - - void set_cipher_priority (const int *list); - void set_mac_priority (const int *list); - void set_compression_priority (const int *list); - void set_kx_priority (const int *list); - void set_protocol_priority (const int *list); - void set_certificate_type_priority (const int *list); - -/* if you just want some defaults, use the following. - */ - void set_priority (const char* prio, const char** err_pos); - void set_priority (gnutls_priority_t p); - - gnutls_protocol_t get_protocol_version() const; - - // for resuming sessions - void set_data ( const void *session_data, - size_t session_data_size); - void get_data (void *session_data, - size_t * session_data_size) const; - void get_data(gnutls_session_t session, - gnutls_datum_t & data) const; - void get_id ( void *session_id, - size_t * session_id_size) const; - - bool is_resumed () const; - - void set_max_handshake_packet_length ( size_t max); - - void clear_credentials(); - void set_credentials( class credentials & cred); - - void set_transport_ptr( gnutls_transport_ptr_t ptr); - void set_transport_ptr( gnutls_transport_ptr_t recv_ptr, gnutls_transport_ptr_t send_ptr); - gnutls_transport_ptr_t get_transport_ptr() const; - void get_transport_ptr(gnutls_transport_ptr_t & recv_ptr, - gnutls_transport_ptr_t & send_ptr) const; - - void set_transport_lowat (size_t num); - void set_transport_push_function( gnutls_push_func push_func); - void set_transport_pull_function( gnutls_pull_func pull_func); - - void set_user_ptr( void* ptr); - void *get_user_ptr() const; - - void send_openpgp_cert( gnutls_openpgp_crt_status_t status); - - gnutls_credentials_type_t get_auth_type() const; - gnutls_credentials_type_t get_server_auth_type() const; - gnutls_credentials_type_t get_client_auth_type() const; - - // informational stuff - void set_dh_prime_bits( unsigned int bits); - unsigned int get_dh_secret_bits() const; - unsigned int get_dh_peers_public_bits() const; - unsigned int get_dh_prime_bits() const; - void get_dh_group( gnutls_datum_t & gen, gnutls_datum_t & prime) const; - void get_dh_pubkey( gnutls_datum_t & raw_key) const; - void get_rsa_export_pubkey( gnutls_datum_t& exponent, gnutls_datum_t& modulus) const; - unsigned int get_rsa_export_modulus_bits() const; - - void get_our_certificate(gnutls_datum_t & cert) const; - bool get_peers_certificate(std::vector<gnutls_datum_t> &out_certs) const; - bool get_peers_certificate(const gnutls_datum_t** certs, unsigned int *certs_size) const; - - time_t get_peers_certificate_activation_time() const; - time_t get_peers_certificate_expiration_time() const; - void verify_peers_certificate( unsigned int& status) const; - -}; - -// interface for databases -class DB -{ - public: - virtual ~DB()=0; - virtual bool store( const gnutls_datum_t& key, const gnutls_datum_t& data)=0; - virtual bool retrieve( const gnutls_datum_t& key, gnutls_datum_t& data)=0; - virtual bool remove( const gnutls_datum_t& key)=0; -}; - -class server_session: public session -{ - public: - server_session(); - void db_remove() const; - - void set_db_cache_expiration (unsigned int seconds); - void set_db( const DB& db); - - // returns true if session is expired - bool db_check_entry ( gnutls_datum_t &session_data) const; - - // server side only - const char *get_srp_username() const; - const char *get_psk_username() const; - - void get_server_name (void *data, size_t * data_length, - unsigned int *type, unsigned int indx) const; - - int rehandshake(); - void set_certificate_request( gnutls_certificate_request_t); -}; - -class client_session: public session -{ - public: - client_session(); - void set_server_name (gnutls_server_name_type_t type, - const void *name, size_t name_length); - - bool get_request_status(); -}; - - -class credentials -{ - public: - credentials(gnutls_credentials_type_t t); -#if defined(__APPLE__) || defined(__MACOS__) - /* FIXME: This #if is due to a compile bug in Mac OS X. Give - it some time and then remove this cruft. See also - lib/gnutlsxx.cpp. */ - credentials( credentials& c) { - type = c.type; - set_ptr( c.ptr()); - } -#else - credentials( credentials& c); -#endif - virtual ~credentials() { } - gnutls_credentials_type_t get_type() const; - protected: - friend class session; - virtual void* ptr() const=0; - virtual void set_ptr(void* ptr)=0; - gnutls_credentials_type_t type; -}; - -class certificate_credentials: public credentials -{ - public: - ~certificate_credentials(); - certificate_credentials(); - - void free_keys (); - void free_cas (); - void free_ca_names (); - void free_crls (); - - void set_dh_params ( const dh_params &params); - void set_rsa_export_params ( const rsa_params& params); - void set_verify_flags ( unsigned int flags); - void set_verify_limits ( unsigned int max_bits, unsigned int max_depth); - - void set_x509_trust_file(const char *cafile, gnutls_x509_crt_fmt_t type); - void set_x509_trust(const gnutls_datum_t & CA, gnutls_x509_crt_fmt_t type); - // FIXME: use classes instead of gnutls_x509_crt_t - void set_x509_trust ( gnutls_x509_crt_t * ca_list, int ca_list_size); - - void set_x509_crl_file( const char *crlfile, gnutls_x509_crt_fmt_t type); - void set_x509_crl(const gnutls_datum_t & CRL, gnutls_x509_crt_fmt_t type); - void set_x509_crl ( gnutls_x509_crl_t * crl_list, int crl_list_size); - - void set_x509_key_file(const char *certfile, const char *KEYFILE, gnutls_x509_crt_fmt_t type); - void set_x509_key(const gnutls_datum_t & CERT, const gnutls_datum_t & KEY, gnutls_x509_crt_fmt_t type); - // FIXME: use classes - void set_x509_key ( gnutls_x509_crt_t * cert_list, int cert_list_size, - gnutls_x509_privkey_t key); - - - void set_simple_pkcs12_file( const char *pkcs12file, - gnutls_x509_crt_fmt_t type, const char *password); - - protected: - void* ptr() const; - void set_ptr(void* p); - gnutls_certificate_credentials_t cred; -}; - -class certificate_server_credentials: public certificate_credentials -{ - certificate_server_credentials() { } - public: - void set_retrieve_function( gnutls_certificate_server_retrieve_function* func); - void set_params_function( gnutls_params_function* func); -}; - -class certificate_client_credentials: public certificate_credentials -{ - public: - certificate_client_credentials() { } - void set_retrieve_function( gnutls_certificate_client_retrieve_function* func); -}; - - - - -class anon_server_credentials: public credentials -{ - public: - anon_server_credentials(); - ~anon_server_credentials(); - void set_dh_params ( const dh_params &params); - void set_params_function ( gnutls_params_function * func); - protected: - gnutls_anon_server_credentials_t cred; -}; - -class anon_client_credentials: public credentials -{ - public: - anon_client_credentials(); - ~anon_client_credentials(); - protected: - gnutls_anon_client_credentials_t cred; -}; - - -class srp_server_credentials: public credentials -{ - public: - srp_server_credentials(); - ~srp_server_credentials(); - void set_credentials_file (const char *password_file, const char *password_conf_file); - void set_credentials_function( gnutls_srp_server_credentials_function *func); - protected: - void* ptr() const; - void set_ptr(void* p); - gnutls_srp_server_credentials_t cred; -}; - -class srp_client_credentials: public credentials -{ - public: - srp_client_credentials(); - ~srp_client_credentials(); - void set_credentials (const char *username, const char *password); - void set_credentials_function( gnutls_srp_client_credentials_function* func); - protected: - void* ptr() const; - void set_ptr(void* p); - gnutls_srp_client_credentials_t cred; -}; - - -class psk_server_credentials: public credentials -{ - public: - psk_server_credentials(); - ~psk_server_credentials(); - void set_credentials_file(const char* password_file); - void set_credentials_function( gnutls_psk_server_credentials_function* func); - void set_dh_params ( const dh_params &params); - void set_params_function (gnutls_params_function * func); - protected: - void* ptr() const; - void set_ptr(void* p); - gnutls_psk_server_credentials_t cred; -}; - -class psk_client_credentials: public credentials -{ - public: - psk_client_credentials(); - ~psk_client_credentials(); - void set_credentials (const char *username, const gnutls_datum_t& key, gnutls_psk_key_flags flags); - void set_credentials_function( gnutls_psk_client_credentials_function* func); - protected: - void* ptr() const; - void set_ptr(void* p); - gnutls_psk_client_credentials_t cred; -}; - - -}; /* namespace */ - -#endif /* GNUTLSXX_H */ diff --git a/src/daemon/https/tls/Makefile.am b/src/daemon/https/tls/Makefile.am @@ -64,10 +64,8 @@ gnutls_state.c \ gnutls_str.c \ gnutls_supplemental.c \ gnutls_ui.c \ -gnutls_v2_compat.c \ gnutls_x509.c \ pkix_asn1_tab.c \ x509_b64.c -# gnutlsxx.cpp diff --git a/src/daemon/https/tls/gnutls_handshake.c b/src/daemon/https/tls/gnutls_handshake.c @@ -41,15 +41,14 @@ #include "gnutls_extensions.h" #include "gnutls_supplemental.h" #include "gnutls_auth_int.h" -#include "gnutls_v2_compat.h" #include "auth_cert.h" #include "gnutls_cert.h" #include "gnutls_constate.h" -#include <gnutls_record.h> -#include <gnutls_state.h> -#include <gnutls_rsa_export.h> /* for gnutls_get_rsa_params() */ -#include <auth_anon.h> /* for gnutls_anon_server_credentials_t */ -#include <gc.h> +#include "gnutls_record.h" +#include "gnutls_state.h" +#include "gnutls_rsa_export.h" /* for gnutls_get_rsa_params() */ +#include "auth_anon.h" /* for gnutls_anon_server_credentials_t */ +#include "gc.h" #ifdef HANDSHAKE_DEBUG #define ERR(x, y) _gnutls_handshake_log( "HSK[%x]: %s (%d)\n", session, x,y) @@ -76,7 +75,7 @@ _gnutls_handshake_hash_buffers_clear (gnutls_session_t session) _gnutls_handshake_buffer_clear (session); } -/* this will copy the required values for resuming to +/* this will copy the required values for resuming to * internals, and to security_parameters. * this will keep as less data to security_parameters. */ @@ -91,7 +90,7 @@ resume_copy_required_values (gnutls_session_t session) client_random, session->security_parameters.client_random, TLS_RANDOM_SIZE); - /* keep the ciphersuite and compression + /* keep the ciphersuite and compression * That is because the client must see these in our * hello message. */ @@ -135,8 +134,7 @@ _gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd) memcpy (session->security_parameters.client_random, rnd, TLS_RANDOM_SIZE); } -/* Calculate The SSL3 Finished message - */ +/* Calculate The SSL3 Finished message */ #define SSL3_CLIENT_MSG "CLNT" #define SSL3_SERVER_MSG "SRVR" #define SSL_MSG_LEN 4 @@ -185,8 +183,7 @@ _gnutls_ssl3_finished (gnutls_session_t session, int type, opaque * ret) return 0; } -/* Hash the handshake messages as required by TLS 1.0 - */ +/* Hash the handshake messages as required by TLS 1.0 */ #define SERVER_MSG "server finished" #define CLIENT_MSG "client finished" #define TLS_MSG_LEN 15 @@ -331,7 +328,7 @@ _gnutls_user_hello_func (gnutls_session session, return 0; } -/* Read a client hello packet. +/* Read a client hello packet. * A client hello must be a known version client hello * or version 2.0 client hello (only for compatibility * since SSL version 2.0 is not supported). @@ -348,10 +345,6 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data, int len = datalen; opaque rnd[TLS_RANDOM_SIZE], *suite_ptr, *comp_ptr; - if (session->internals.v2_hello != 0) - { /* version 2.0 */ - return _gnutls_read_client_hello_v2 (session, data, datalen); - } DECR_LEN (len, 2); _gnutls_handshake_log ("HSK[%x]: Client's version: %d.%d\n", session, @@ -382,8 +375,7 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data, DECR_LEN (len, 1); session_id_len = data[pos++]; - /* RESUME SESSION - */ + /* RESUME SESSION */ if (session_id_len > TLS_MAX_SESSION_ID_SIZE) { gnutls_assert (); @@ -478,7 +470,7 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data, return 0; } -/* here we hash all pending data. +/* here we hash all pending data. */ inline static int _gnutls_handshake_hash_pending (gnutls_session_t session) @@ -569,7 +561,7 @@ _gnutls_send_finished (gnutls_session_t session, int again) } /* This is to be called after sending our finished message. If everything - * went fine we have negotiated a secure connection + * went fine we have negotiated a secure connection */ int _gnutls_recv_finished (gnutls_session_t session) @@ -803,7 +795,7 @@ finish: } -/* This selects the best supported compression method from the ones provided +/* This selects the best supported compression method from the ones provided */ int _gnutls_server_select_comp_method (gnutls_session_t session, @@ -875,8 +867,7 @@ _gnutls_send_empty_handshake (gnutls_session_t session, } -/* This function will hash the handshake message we sent. - */ +/* This function will hash the handshake message we sent. */ static int _gnutls_handshake_hash_add_sent (gnutls_session_t session, gnutls_handshake_description_t type, @@ -904,7 +895,7 @@ _gnutls_handshake_hash_add_sent (gnutls_session_t session, /* This function sends a handshake message of type 'type' containing the * data specified here. If the previous _gnutls_send_handshake() returned - * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again + * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again * (until it returns ok), with NULL parameters. */ int @@ -1533,8 +1524,7 @@ _gnutls_read_server_hello (gnutls_session_t session, - /* move to compression - */ + /* move to compression */ DECR_LEN (len, 1); ret = _gnutls_client_set_comp_method (session, data[pos++]); @@ -1628,7 +1618,7 @@ _gnutls_copy_ciphersuites (gnutls_session_t session, } -/* This function copies the appropriate compression methods, to a locally allocated buffer +/* This function copies the appropriate compression methods, to a locally allocated buffer * Needed in hello messages. Returns the new data length. */ static int @@ -1701,7 +1691,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) { datalen = 2 + (session_id_len + 1) + TLS_RANDOM_SIZE; - /* 2 for version, (4 for unix time + 28 for random bytes==TLS_RANDOM_SIZE) + /* 2 for version, (4 for unix time + 28 for random bytes==TLS_RANDOM_SIZE) */ data = gnutls_malloc (datalen); @@ -1731,7 +1721,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) data[pos++] = _gnutls_version_get_major (hver); data[pos++] = _gnutls_version_get_minor (hver); - /* Set the version we advertized as maximum + /* Set the version we advertized as maximum * (RSA uses it). */ _gnutls_set_adv_version (session, hver); @@ -1740,8 +1730,8 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) * different version in the record layer. * It seems they prefer to read the record's version * as the one we actually requested. - * The proper behaviour is to use the one in the client hello - * handshake packet and ignore the one in the packet's record + * The proper behaviour is to use the one in the client hello + * handshake packet and ignore the one in the packet's record * header. */ _gnutls_set_current_version (session, hver); @@ -1750,7 +1740,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) */ session->security_parameters.timestamp = time (NULL); - /* Generate random data + /* Generate random data */ _gnutls_tls_create_random (rnd); _gnutls_set_client_random (session, rnd); @@ -1758,8 +1748,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) memcpy (&data[pos], rnd, TLS_RANDOM_SIZE); pos += TLS_RANDOM_SIZE; - /* Copy the Session ID - */ + /* Copy the Session ID */ data[pos++] = session_id_len; if (session_id_len > 0) @@ -2286,7 +2275,7 @@ gnutls_handshake (gnutls_session_t session) /* - * _gnutls_handshake_client + * _gnutls_handshake_client * This function performs the client side of the handshake of the TLS/SSL protocol. */ int @@ -2348,7 +2337,7 @@ _gnutls_handshake_client (gnutls_session_t session) IMED_RET ("recv server kx message", ret); case STATE5: - /* receive the server certificate request - if any + /* receive the server certificate request - if any */ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */ @@ -2405,7 +2394,7 @@ _gnutls_handshake_client (gnutls_session_t session) return 0; } -/* This function sends the final handshake packets and initializes connection +/* This function sends the final handshake packets and initializes connection */ static int _gnutls_send_handshake_final (gnutls_session_t session, int init) @@ -2427,7 +2416,7 @@ _gnutls_send_handshake_final (gnutls_session_t session, int init) return ret; } - /* Initialize the connection session (start encryption) - in case of client + /* Initialize the connection session (start encryption) - in case of client */ if (init == TRUE) { @@ -2465,7 +2454,7 @@ _gnutls_send_handshake_final (gnutls_session_t session, int init) return 0; } -/* This function receives the final handshake packets +/* This function receives the final handshake packets * And executes the appropriate function to initialize the * read session. */ @@ -2525,7 +2514,7 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init) } /* - * _gnutls_handshake_server + * _gnutls_handshake_server * This function does the server stuff of the handshake protocol. */ @@ -2846,7 +2835,7 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session, gnutls_kx_algorithm_t *alg = NULL; int alg_size = 0; - /* if we should use a specific certificate, + /* if we should use a specific certificate, * we should remove all algorithms that are not supported * by that certificate and are on the same authentication * method (CERTIFICATE). @@ -2873,7 +2862,7 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session, } } - /* get all the key exchange algorithms that are + /* get all the key exchange algorithms that are * supported by the X509 certificate parameters. */ if ((ret = @@ -2902,7 +2891,7 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session, */ kx = _gnutls_cipher_suite_get_kx_algo (&(*cipherSuites)[i]); - /* if it is defined but had no credentials + /* if it is defined but had no credentials */ if (_gnutls_get_kx_cred (session, kx, NULL) == NULL) { diff --git a/src/daemon/https/tls/gnutls_priority.c b/src/daemon/https/tls/gnutls_priority.c @@ -193,7 +193,7 @@ gnutls_protocol_set_priority (gnutls_session_t session, const int *list) * Sets the priority on the certificate types supported by gnutls. * Priority is higher for elements specified before others. * After specifying the types you want, you must append a 0. - * Note that the certificate type priority is set on the client. + * Note that the certificate type priority is set on the client. * The server does not use the cert type priority except for disabling * types that were not specified. * @@ -215,7 +215,7 @@ gnutls_certificate_type_set_priority (gnutls_session_t session, } static const int protocol_priority[] = { GNUTLS_TLS1_1, - GNUTLS_TLS1_0, + GNUTLS_TLS1_0, GNUTLS_SSL3, 0 }; diff --git a/src/daemon/https/tls/gnutls_v2_compat.c b/src/daemon/https/tls/gnutls_v2_compat.c @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA - * - */ - -/* Functions to parse the SSLv2.0 hello message. - */ - -#include "gnutls_int.h" -#include "gnutls_errors.h" -#include "gnutls_dh.h" -#include "debug.h" -#include "gnutls_algorithms.h" -#include "gnutls_compress.h" -#include "gnutls_cipher.h" -#include "gnutls_buffers.h" -#include "gnutls_kx.h" -#include "gnutls_handshake.h" -#include "gnutls_num.h" -#include "gnutls_hash_int.h" -#include "gnutls_db.h" -#include "gnutls_extensions.h" -#include "gnutls_auth_int.h" - -/* This selects the best supported ciphersuite from the ones provided */ -static int -_gnutls_handshake_select_v2_suite (gnutls_session_t session, - opaque * data, int datalen) -{ - int i, j, ret; - opaque *_data; - int _datalen; - - _gnutls_handshake_log ("HSK[%x]: Parsing a version 2.0 client hello.\n", - session); - - _data = gnutls_malloc (datalen); - if (_data == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - if (datalen % 3 != 0) - { - gnutls_assert (); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - - i = _datalen = 0; - for (j = 0; j < datalen; j += 3) - { - if (data[j] == 0) - { - memcpy (&_data[i], &data[j + 1], 2); - i += 2; - _datalen += 2; - } - } - - ret = _gnutls_server_select_suite (session, _data, _datalen); - gnutls_free (_data); - - return ret; - -} - - -/* Read a v2 client hello. Some browsers still use that beast! - * However they set their version to 3.0 or 3.1. - */ -int -_gnutls_read_client_hello_v2 (gnutls_session_t session, opaque * data, - int datalen) -{ - uint16_t session_id_len = 0; - int pos = 0; - int ret = 0; - uint16_t sizeOfSuites; - gnutls_protocol_t adv_version; - opaque rnd[TLS_RANDOM_SIZE]; - int len = datalen; - int err; - uint16_t challenge; - opaque session_id[TLS_MAX_SESSION_ID_SIZE]; - - /* we only want to get here once - only in client hello */ - session->internals.v2_hello = 0; - - DECR_LEN (len, 2); - - _gnutls_handshake_log - ("HSK[%x]: SSL 2.0 Hello: Client's version: %d.%d\n", session, - data[pos], data[pos + 1]); - - set_adv_version (session, data[pos], data[pos + 1]); - - adv_version = _gnutls_version_get (data[pos], data[pos + 1]); - - ret = _gnutls_negotiate_version (session, adv_version); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - pos += 2; - - /* Read uint16_t cipher_spec_length */ - DECR_LEN (len, 2); - sizeOfSuites = _gnutls_read_uint16 (&data[pos]); - pos += 2; - - /* read session id length */ - DECR_LEN (len, 2); - session_id_len = _gnutls_read_uint16 (&data[pos]); - pos += 2; - - if (session_id_len > TLS_MAX_SESSION_ID_SIZE) - { - gnutls_assert (); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - - /* read challenge length */ - DECR_LEN (len, 2); - challenge = _gnutls_read_uint16 (&data[pos]); - pos += 2; - - if (challenge < 16 || challenge > TLS_RANDOM_SIZE) - { - gnutls_assert (); - return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; - } - - /* call the user hello callback - */ - ret = _gnutls_user_hello_func (session, adv_version); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - /* find an appropriate cipher suite */ - - DECR_LEN (len, sizeOfSuites); - ret = _gnutls_handshake_select_v2_suite (session, &data[pos], sizeOfSuites); - - pos += sizeOfSuites; - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - /* check if the credentials (username, public key etc.) are ok - */ - if (_gnutls_get_kx_cred - (session, - _gnutls_cipher_suite_get_kx_algo (&session->security_parameters. - current_cipher_suite), - &err) == NULL && err != 0) - { - gnutls_assert (); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - /* set the mod_auth_st to the appropriate struct - * according to the KX algorithm. This is needed since all the - * handshake functions are read from there; - */ - session->internals.auth_struct = - _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo - (&session->security_parameters. - current_cipher_suite)); - if (session->internals.auth_struct == NULL) - { - - _gnutls_handshake_log - ("HSK[%x]: SSL 2.0 Hello: Cannot find the appropriate handler for the KX algorithm\n", - session); - - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - - - /* read random new values -skip session id for now */ - DECR_LEN (len, session_id_len); /* skip session id for now */ - memcpy (session_id, &data[pos], session_id_len); - pos += session_id_len; - - DECR_LEN (len, challenge); - memset (rnd, 0, TLS_RANDOM_SIZE); - - memcpy (&rnd[TLS_RANDOM_SIZE - challenge], &data[pos], challenge); - - _gnutls_set_client_random (session, rnd); - - /* generate server random value */ - - _gnutls_tls_create_random (rnd); - _gnutls_set_server_random (session, rnd); - - session->security_parameters.timestamp = time (NULL); - - - /* RESUME SESSION */ - - DECR_LEN (len, session_id_len); - ret = _gnutls_server_restore_session (session, session_id, session_id_len); - - if (ret == 0) - { /* resumed! */ - /* get the new random values */ - memcpy (session->internals.resumed_security_parameters. - server_random, session->security_parameters.server_random, - TLS_RANDOM_SIZE); - memcpy (session->internals.resumed_security_parameters. - client_random, session->security_parameters.client_random, - TLS_RANDOM_SIZE); - - session->internals.resumed = RESUME_TRUE; - return 0; - } - else - { - _gnutls_generate_session_id (session->security_parameters. - session_id, - &session->security_parameters. - session_id_size); - session->internals.resumed = RESUME_FALSE; - } - - session->internals.compression_method = GNUTLS_COMP_NULL; - - return 0; -} diff --git a/src/daemon/https/tls/gnutls_v2_compat.h b/src/daemon/https/tls/gnutls_v2_compat.h @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA - * - */ - -int _gnutls_read_client_hello_v2 (gnutls_session_t session, opaque * data, - int datalen); diff --git a/src/daemon/https/tls/gnutlsxx.cpp b/src/daemon/https/tls/gnutlsxx.cpp @@ -1,907 +0,0 @@ -#include <gnutlsxx.h> - -using namespace gnutls; - -inline int RETWRAP_NET(int ret) -{ - if (gnutls_error_is_fatal(ret)) throw(exception(ret)); - else return ret; -} - -inline int RETWRAP(int ret) -{ - if (ret < 0) throw(exception(ret)); - return ret; -} - -session::session( gnutls_connection_end_t end) -{ - RETWRAP(gnutls_init( &this->s, end)); -} - -session::session( session& s) -{ - this->s = s.s; -} - -session::~session() -{ - gnutls_deinit( this->s); -} - -int session::bye( gnutls_close_request_t how) -{ - return RETWRAP_NET( gnutls_bye( this->s, how)); -} - -int session::handshake () -{ - return RETWRAP_NET( gnutls_handshake( this->s)); -} - - -server_session::server_session() : session( GNUTLS_SERVER) -{ -} - -int server_session::rehandshake() -{ - return RETWRAP_NET( gnutls_rehandshake( this->s)); -} - -gnutls_alert_description_t session::get_alert() const -{ - return gnutls_alert_get( this->s); -} - -int session::send_alert ( gnutls_alert_level_t level, - gnutls_alert_description_t desc) -{ - return RETWRAP_NET(gnutls_alert_send( this->s, level, desc)); -} - -int session::send_appropriate_alert (int err) -{ - return RETWRAP_NET(gnutls_alert_send_appropriate( this->s, err)); -} - -gnutls_cipher_algorithm_t session::get_cipher() const -{ - return gnutls_cipher_get( this->s); -} - -gnutls_kx_algorithm_t session::get_kx () const -{ - return gnutls_kx_get( this->s); -} - -gnutls_mac_algorithm_t session::get_mac () const -{ - return gnutls_mac_get( this->s); -} - -gnutls_compression_method_t session::get_compression() const -{ - return gnutls_compression_get( this->s); -} - -gnutls_certificate_type_t session::get_certificate_type() const -{ - return gnutls_certificate_type_get( this->s); -} - -void session::set_private_extensions ( bool allow) -{ - gnutls_handshake_set_private_extensions( this->s, (int)allow); -} - -gnutls_handshake_description_t session::get_handshake_last_out() const -{ - return gnutls_handshake_get_last_out( this->s); -} - -gnutls_handshake_description_t session::get_handshake_last_in() const -{ - return gnutls_handshake_get_last_in( this->s); -} - -ssize_t session::send (const void *data, size_t sizeofdata) -{ - return RETWRAP_NET(gnutls_record_send( this->s, data, sizeofdata)); -} - -ssize_t session::recv (void *data, size_t sizeofdata) -{ - return RETWRAP_NET(gnutls_record_recv( this->s, data, sizeofdata)); -} - -bool session::get_record_direction() const -{ - return gnutls_record_get_direction(this->s); -} - - // maximum packet size -size_t session::get_max_size () const -{ - return gnutls_record_get_max_size( this->s); -} - -void session::set_max_size(size_t size) -{ - RETWRAP( gnutls_record_set_max_size( this->s, size)); -} - -size_t session::check_pending () const -{ - return gnutls_record_check_pending( this->s); -} - - -void session::prf (size_t label_size, const char *label, - int server_random_first, - size_t extra_size, const char *extra, - size_t outsize, char *out) -{ - RETWRAP(gnutls_prf( this->s, label_size, label, server_random_first, - extra_size, extra, outsize, out)); -} - -void session::prf_raw ( size_t label_size, const char *label, - size_t seed_size, const char *seed, - size_t outsize, char *out) -{ - RETWRAP( gnutls_prf_raw( this->s, label_size, label, seed_size, seed, outsize, out)); -} - - -void session::set_cipher_priority (const int *list) -{ - RETWRAP( gnutls_cipher_set_priority( this->s, list)); -} - -void session::set_mac_priority (const int *list) -{ - RETWRAP( gnutls_mac_set_priority( this->s, list)); -} - -void session::set_compression_priority (const int *list) -{ - RETWRAP( gnutls_compression_set_priority( this->s, list)); -} - -void session::set_kx_priority (const int *list) -{ - RETWRAP( gnutls_kx_set_priority( this->s, list)); -} - -void session::set_protocol_priority (const int *list) -{ - RETWRAP( gnutls_protocol_set_priority( this->s, list)); -} - -void session::set_certificate_type_priority (const int *list) -{ - RETWRAP( gnutls_certificate_type_set_priority( this->s, list)); -} - - -/* if you just want some defaults, use the following. - */ -void session::set_priority(const char* prio, const char** err_pos) -{ - RETWRAP(gnutls_priority_set_direct( this->s, prio, err_pos)); -} - -void session::set_priority(gnutls_priority_t p) -{ - RETWRAP(gnutls_priority_set( this->s, p)); -} - -gnutls_protocol_t session::get_protocol_version() const -{ - return gnutls_protocol_get_version( this->s); -} - -void session::set_data ( const void *session_data, - size_t session_data_size) -{ - RETWRAP(gnutls_session_set_data( this->s, session_data, session_data_size)); -} - -void session::get_data (void *session_data, - size_t * session_data_size) const -{ - RETWRAP(gnutls_session_get_data( this->s, session_data, session_data_size)); -} - -void session::get_data(gnutls_session_t session, - gnutls_datum_t & data) const -{ - RETWRAP(gnutls_session_get_data2( this->s, &data)); - -} - -void session::get_id ( void *session_id, - size_t * session_id_size) const -{ - RETWRAP( gnutls_session_get_id( this->s, session_id, session_id_size)); -} - -bool session::is_resumed() const -{ - int ret = gnutls_session_is_resumed( this->s); - - if (ret != 0) return true; - return false; -} - - -bool session::get_peers_certificate(std::vector<gnutls_datum_t> &out_certs) const -{ - const gnutls_datum_t *certs; - unsigned int certs_size; - - certs = gnutls_certificate_get_peers (this->s, &certs_size); - - if (certs==NULL) return false; - - for(unsigned int i=0;i<certs_size;i++) - out_certs.push_back( certs[i]); - - return true; -} - -bool session::get_peers_certificate(const gnutls_datum_t** certs, unsigned int *certs_size) const -{ - *certs = gnutls_certificate_get_peers (this->s, certs_size); - - if (*certs==NULL) return false; - return true; -} - -void session::get_our_certificate(gnutls_datum_t& cert) const -{ -const gnutls_datum_t *d; - - d = gnutls_certificate_get_ours(this->s); - if (d==NULL) - throw(exception( GNUTLS_E_INVALID_REQUEST)); - cert = *d; -} - -time_t session::get_peers_certificate_activation_time() const -{ - return gnutls_certificate_activation_time_peers( this->s); -} - -time_t session::get_peers_certificate_expiration_time() const -{ - return gnutls_certificate_expiration_time_peers( this->s); -} -void session::verify_peers_certificate( unsigned int& status) const -{ - RETWRAP( gnutls_certificate_verify_peers2( this->s, &status)); -} - - -client_session::client_session() : session( GNUTLS_CLIENT) -{ -} - -// client session -void client_session::set_server_name (gnutls_server_name_type_t type, - const void *name, size_t name_length) -{ - RETWRAP( gnutls_server_name_set( this->s, type, name, name_length)); -} - -bool client_session::get_request_status() -{ - return RETWRAP(gnutls_certificate_client_get_request_status (this->s)); -} - -// server_session -void server_session::get_server_name (void *data, size_t * data_length, - unsigned int *type, unsigned int indx) const -{ - RETWRAP( gnutls_server_name_get( this->s, data, data_length, type, indx)); -} - -// internal DB stuff -static int store_function(void *_db, gnutls_datum_t key, gnutls_datum_t data) -{ - try { - DB* db = static_cast<DB*>(_db); - - if (db->store( key, data)==false) return -1; - } catch(...) { - return -1; - } - - return 0; -} - -const static gnutls_datum_t null_datum = { NULL, 0 }; - -static gnutls_datum_t retrieve_function(void *_db, gnutls_datum_t key) -{ - gnutls_datum_t data; - - try { - DB* db = static_cast<DB*>(_db); - - if (db->retrieve( key, data)==false) return null_datum; - - } catch(...) { - return null_datum; - } - - return data; -} - -static int remove_function(void *_db, gnutls_datum_t key) -{ - try { - DB* db = static_cast<DB*>(_db); - - if (db->remove( key)==false) return -1; - } catch(...) { - return -1; - } - - return 0; -} - -void server_session::set_db( const DB& db) -{ - gnutls_db_set_ptr( this->s, const_cast<DB*>(&db)); - gnutls_db_set_store_function( this->s, store_function); - gnutls_db_set_retrieve_function( this->s, retrieve_function); - gnutls_db_set_remove_function( this->s, remove_function); -} - -void server_session::set_db_cache_expiration (unsigned int seconds) -{ - gnutls_db_set_cache_expiration( this->s, seconds); -} - -void server_session::db_remove () const -{ - gnutls_db_remove_session( this->s); -} - -bool server_session::db_check_entry ( gnutls_datum_t &session_data) const -{ - int ret = gnutls_db_check_entry( this->s, session_data); - - if (ret != 0) return true; - return false; -} - -void session::set_max_handshake_packet_length ( size_t max) -{ - gnutls_handshake_set_max_packet_length( this->s, max); -} - -void session::clear_credentials() -{ - gnutls_credentials_clear( this->s); -} - -void session::set_credentials( credentials &cred) -{ - RETWRAP(gnutls_credentials_set( this->s, cred.get_type(), cred.ptr())); -} - -const char* server_session::get_srp_username() const -{ - return gnutls_srp_server_get_username( this->s); -} - -const char* server_session::get_psk_username() const -{ - return gnutls_psk_server_get_username( this->s); -} - - -void session::set_transport_ptr( gnutls_transport_ptr_t ptr) -{ - gnutls_transport_set_ptr( this->s, ptr); -} - -void session::set_transport_ptr( gnutls_transport_ptr_t recv_ptr, gnutls_transport_ptr_t send_ptr) -{ - gnutls_transport_set_ptr2( this->s, recv_ptr, send_ptr); -} - - -gnutls_transport_ptr_t session::get_transport_ptr () const -{ - return gnutls_transport_get_ptr (this->s); -} - -void session::get_transport_ptr( gnutls_transport_ptr_t & recv_ptr, - gnutls_transport_ptr_t & send_ptr) const -{ - gnutls_transport_get_ptr2 (this->s, &recv_ptr, &send_ptr); -} - -void session::set_transport_lowat( size_t num) -{ - gnutls_transport_set_lowat (this->s, num); -} - -void session::set_transport_push_function( gnutls_push_func push_func) -{ - gnutls_transport_set_push_function ( this->s, push_func); -} - -void session::set_transport_pull_function( gnutls_pull_func pull_func) -{ - gnutls_transport_set_pull_function ( this->s, pull_func); -} - -void session::set_user_ptr( void* ptr) -{ - gnutls_session_set_ptr( this->s, ptr); -} - -void* session::get_user_ptr( ) const -{ - return gnutls_session_get_ptr(this->s); -} - -void session::send_openpgp_cert( gnutls_openpgp_crt_status_t status) -{ - gnutls_openpgp_send_cert(this->s, status); -} - - -void session::set_dh_prime_bits( unsigned int bits) -{ - gnutls_dh_set_prime_bits( this->s, bits); -} - -unsigned int session::get_dh_secret_bits() const -{ - return RETWRAP( gnutls_dh_get_secret_bits( this->s)); -} - -unsigned int session::get_dh_peers_public_bits() const -{ - return RETWRAP(gnutls_dh_get_peers_public_bits( this->s)); -} - -unsigned int session::get_dh_prime_bits() const -{ - return RETWRAP( gnutls_dh_get_prime_bits( this->s)); -} - -void session::get_dh_group( gnutls_datum_t & gen, gnutls_datum_t & prime) const -{ - RETWRAP( gnutls_dh_get_group( this->s, &gen, &prime)); -} - -void session::get_dh_pubkey( gnutls_datum_t & raw_key) const -{ - RETWRAP(gnutls_dh_get_pubkey( this->s, &raw_key)); -} - -void session::get_rsa_export_pubkey( gnutls_datum_t& exponent, gnutls_datum_t& modulus) const -{ - RETWRAP( gnutls_rsa_export_get_pubkey( this->s, &exponent, &modulus)); -} - -unsigned int session::get_rsa_export_modulus_bits() const -{ - return RETWRAP(gnutls_rsa_export_get_modulus_bits( this->s)); -} - -void server_session::set_certificate_request( gnutls_certificate_request_t req) -{ - gnutls_certificate_server_set_request (this->s, req); -} - - - - -gnutls_credentials_type_t session::get_auth_type() const -{ - return gnutls_auth_get_type( this->s); -} - -gnutls_credentials_type_t session::get_server_auth_type() const -{ - return gnutls_auth_server_get_type( this->s); -} - -gnutls_credentials_type_t session::get_client_auth_type() const -{ - return gnutls_auth_client_get_type( this->s); -} - - -void* certificate_credentials::ptr() const -{ - return this->cred; -} - -void certificate_credentials::set_ptr(void* p) -{ - this->cred = static_cast<gnutls_certificate_credentials_t> (p); -} - -certificate_credentials::~certificate_credentials() -{ - gnutls_certificate_free_credentials (this->cred); -} - -certificate_credentials::certificate_credentials() : credentials(GNUTLS_CRD_CERTIFICATE) -{ - RETWRAP(gnutls_certificate_allocate_credentials ( &this->cred)); -} - -void certificate_server_credentials::set_params_function( gnutls_params_function* func) -{ - gnutls_certificate_set_params_function( this->cred, func); -} - -anon_server_credentials::anon_server_credentials() : credentials(GNUTLS_CRD_ANON) -{ - RETWRAP(gnutls_anon_allocate_server_credentials( &this->cred)); -} - -anon_server_credentials::~anon_server_credentials() -{ - gnutls_anon_free_server_credentials( this->cred); -} - -void anon_server_credentials::set_dh_params( const dh_params& params) -{ - gnutls_anon_set_server_dh_params (this->cred, params.get_params_t()); -} - -void anon_server_credentials::set_params_function ( gnutls_params_function * func) -{ - gnutls_anon_set_server_params_function ( this->cred, func); -} - -anon_client_credentials::anon_client_credentials() : credentials(GNUTLS_CRD_ANON) -{ - RETWRAP(gnutls_anon_allocate_client_credentials( &this->cred)); -} - -anon_client_credentials::~anon_client_credentials() -{ - gnutls_anon_free_client_credentials( this->cred); -} - -void certificate_credentials::free_keys () -{ - gnutls_certificate_free_keys( this->cred); -} - -void certificate_credentials::free_cas () -{ - gnutls_certificate_free_cas( this->cred); -} - -void certificate_credentials::free_ca_names () -{ - gnutls_certificate_free_ca_names( this->cred); -} - -void certificate_credentials::free_crls () -{ - gnutls_certificate_free_crls( this->cred); -} - - -void certificate_credentials::set_dh_params ( const dh_params& params) -{ - gnutls_certificate_set_dh_params( this->cred, params.get_params_t()); -} - -void certificate_credentials::set_rsa_export_params ( const rsa_params & params) -{ - gnutls_certificate_set_rsa_export_params( this->cred, params.get_params_t()); -} - -void certificate_credentials::set_verify_flags ( unsigned int flags) -{ - gnutls_certificate_set_verify_flags( this->cred, flags); -} - -void certificate_credentials::set_verify_limits ( unsigned int max_bits, unsigned int max_depth) -{ - gnutls_certificate_set_verify_limits( this->cred, max_bits, max_depth); -} - -void certificate_credentials::set_x509_trust_file(const char *cafile, gnutls_x509_crt_fmt_t type) -{ - RETWRAP( gnutls_certificate_set_x509_trust_file( this->cred, cafile, type)); -} - -void certificate_credentials::set_x509_trust(const gnutls_datum_t & CA, gnutls_x509_crt_fmt_t type) -{ - RETWRAP( gnutls_certificate_set_x509_trust_mem( this->cred, &CA, type)); -} - - -void certificate_credentials::set_x509_crl_file( const char *crlfile, gnutls_x509_crt_fmt_t type) -{ - RETWRAP( gnutls_certificate_set_x509_crl_file( this->cred, crlfile, type)); -} - -void certificate_credentials::set_x509_crl(const gnutls_datum_t & CRL, gnutls_x509_crt_fmt_t type) -{ - RETWRAP( gnutls_certificate_set_x509_crl_mem( this->cred, &CRL, type)); -} - -void certificate_credentials::set_x509_key_file(const char *certfile, const char *keyfile, gnutls_x509_crt_fmt_t type) -{ - RETWRAP( gnutls_certificate_set_x509_key_file( this->cred, certfile, keyfile, type)); -} - -void certificate_credentials::set_x509_key(const gnutls_datum_t & CERT, const gnutls_datum_t & KEY, gnutls_x509_crt_fmt_t type) -{ - RETWRAP( gnutls_certificate_set_x509_key_mem( this->cred, &CERT, &KEY, type)); -} - -void certificate_credentials::set_simple_pkcs12_file( const char *pkcs12file, - gnutls_x509_crt_fmt_t type, const char *password) -{ - RETWRAP( gnutls_certificate_set_x509_simple_pkcs12_file( this->cred, pkcs12file, type, password)); -} - -void certificate_credentials::set_x509_key ( gnutls_x509_crt_t * cert_list, int cert_list_size, - gnutls_x509_privkey_t key) -{ - RETWRAP( gnutls_certificate_set_x509_key( this->cred, cert_list, cert_list_size, key)); -} - -void certificate_credentials::set_x509_trust ( gnutls_x509_crt_t * ca_list, int ca_list_size) -{ - RETWRAP( gnutls_certificate_set_x509_trust( this->cred, ca_list, ca_list_size)); -} - -void certificate_credentials::set_x509_crl ( gnutls_x509_crl_t * crl_list, int crl_list_size) -{ - RETWRAP( gnutls_certificate_set_x509_crl( this->cred, crl_list, crl_list_size)); -} - -void certificate_server_credentials::set_retrieve_function( gnutls_certificate_server_retrieve_function* func) -{ - gnutls_certificate_server_set_retrieve_function( this->cred, func); -} - -void certificate_client_credentials::set_retrieve_function( gnutls_certificate_client_retrieve_function* func) -{ - gnutls_certificate_client_set_retrieve_function( this->cred, func); -} - -// SRP - -srp_server_credentials::srp_server_credentials() : credentials(GNUTLS_CRD_SRP) -{ - RETWRAP(gnutls_srp_allocate_server_credentials( &this->cred)); -} - -srp_server_credentials::~srp_server_credentials() -{ - gnutls_srp_free_server_credentials( this->cred); -} - -void* srp_server_credentials::ptr() const -{ - return this->cred; -} - -void srp_server_credentials::set_ptr(void* p) -{ - this->cred = static_cast<gnutls_srp_server_credentials_t> (p); -} - -srp_client_credentials::srp_client_credentials() : credentials(GNUTLS_CRD_SRP) -{ - RETWRAP(gnutls_srp_allocate_client_credentials( &this->cred)); -} - -srp_client_credentials::~srp_client_credentials() -{ - gnutls_srp_free_client_credentials( this->cred); -} - -void* srp_client_credentials::ptr() const -{ - return this->cred; -} - -void srp_client_credentials::set_ptr(void* p) -{ - this->cred = static_cast<gnutls_srp_client_credentials_t> (p); -} - -void srp_client_credentials::set_credentials( const char* username, const char* password) -{ - RETWRAP(gnutls_srp_set_client_credentials (this->cred, username, password)); -} - -void srp_server_credentials::set_credentials_file ( - const char *password_file, const char *password_conf_file) -{ - RETWRAP( gnutls_srp_set_server_credentials_file( this->cred, password_file, password_conf_file)); -} - - -void srp_server_credentials::set_credentials_function(gnutls_srp_server_credentials_function * func) -{ - gnutls_srp_set_server_credentials_function( this->cred, func); -} - -void srp_client_credentials::set_credentials_function(gnutls_srp_client_credentials_function * func) -{ - gnutls_srp_set_client_credentials_function( this->cred, func); -} - -credentials::credentials(gnutls_credentials_type_t t) : type(t) -{ -} - -#if !(defined(__APPLE__) || defined(__MACOS__)) -/* FIXME: This #if is due to a compile bug in Mac OS X. Give it some - time and then remove this cruft. See also - includes/gnutls/gnutlsxx.h. */ -credentials::credentials( credentials& c) -{ - this->type = c.type; - this->set_ptr( c.ptr()); -} -#endif - -gnutls_credentials_type_t credentials::get_type() const -{ - return type; -} - -exception::exception( int x) -{ - retcode = x; -} - -int exception::get_code() -{ - return retcode; -} - -const char* exception::what() const throw() -{ - return gnutls_strerror(retcode); -} - - - - -dh_params::dh_params() -{ - RETWRAP(gnutls_dh_params_init( &params)); -} - -dh_params::~dh_params() -{ - gnutls_dh_params_deinit(params); -} - -void dh_params::import_raw( const gnutls_datum_t & prime, - const gnutls_datum_t & generator) -{ - RETWRAP( gnutls_dh_params_import_raw( params, &prime, &generator)); -} - -void dh_params::import_pkcs3( const gnutls_datum_t & pkcs3_params, - gnutls_x509_crt_fmt_t format) -{ - RETWRAP(gnutls_dh_params_import_pkcs3( params, &pkcs3_params, format)); -} - -void dh_params::generate( unsigned int bits) -{ - RETWRAP(gnutls_dh_params_generate2( params, bits)); -} - -void dh_params::export_pkcs3( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size) -{ - RETWRAP( gnutls_dh_params_export_pkcs3( params, format, params_data, params_data_size)); -} - -void dh_params::export_raw( gnutls_datum_t& prime, gnutls_datum_t &generator) -{ - RETWRAP( gnutls_dh_params_export_raw( params, &prime, &generator, NULL)); -} - -gnutls_dh_params_t dh_params::get_params_t() const -{ - return params; -} - -dh_params & dh_params::operator=(const dh_params& src) -{ - dh_params* dst = new dh_params; - int ret; - - ret = gnutls_dh_params_cpy( dst->params, src.params); - - if (ret < 0) { - delete dst; - throw(ret); - } - - return *dst; -} - - -// RSA - -rsa_params::rsa_params() -{ - RETWRAP(gnutls_rsa_params_init( &params)); -} - -rsa_params::~rsa_params() -{ - gnutls_rsa_params_deinit(params); -} - -void rsa_params::import_pkcs1( const gnutls_datum_t & pkcs1_params, - gnutls_x509_crt_fmt_t format) -{ - RETWRAP(gnutls_rsa_params_import_pkcs1( params, &pkcs1_params, format)); -} - -void rsa_params::generate( unsigned int bits) -{ - RETWRAP(gnutls_rsa_params_generate2( params, bits)); -} - -void rsa_params::export_pkcs1( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size) -{ - RETWRAP( gnutls_rsa_params_export_pkcs1( params, format, params_data, params_data_size)); -} - -gnutls_rsa_params_t rsa_params::get_params_t() const -{ - return params; -} - -rsa_params & rsa_params::operator=(const rsa_params& src) -{ - rsa_params* dst = new rsa_params; - int ret; - - ret = gnutls_rsa_params_cpy( dst->params, src.params); - - if (ret < 0) - delete dst; - throw(ret); - - return *dst; -} - -void rsa_params::import_raw( const gnutls_datum_t & m, - const gnutls_datum_t & e, - const gnutls_datum_t & d, - const gnutls_datum_t & p, - const gnutls_datum_t & q, - const gnutls_datum_t & u) -{ - - RETWRAP(gnutls_rsa_params_import_raw ( params, &m, &e, &d, &p, &q, &u)); -} - - -void rsa_params::export_raw( gnutls_datum_t & m, gnutls_datum_t & e, - gnutls_datum_t & d, gnutls_datum_t & p, - gnutls_datum_t & q, gnutls_datum_t & u) -{ - RETWRAP( gnutls_rsa_params_export_raw ( params, &m, &e, &d, &p, &q, &u, NULL)); -} diff --git a/src/daemon/https/tls/io_debug.h b/src/daemon/https/tls/io_debug.h @@ -22,9 +22,9 @@ * */ -/* This debug file was contributed by +/* This debug file was contributed by * Paul Sheer <psheer@icon.co.za>. Some changes were made by nmav. - * Its purpose is to debug non blocking behaviour of gnutls. The included + * Its purpose is to debug non blocking behavior of gnutls. The included * send() and recv() functions return EAGAIN errors in random. * */ diff --git a/src/daemon/https/tls/libgnutlsxx.vers b/src/daemon/https/tls/libgnutlsxx.vers @@ -1,30 +0,0 @@ -# libgnutlsxx.vers -- Versioning script to control what symbols to export. -# Copyright (C) 2005, 2006 Free Software Foundation -# -# Author: Simon Josefsson -# -# This file is part of GNUTLS. -# -# The GNUTLS library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. -# -# The GNUTLS library is distributed in the hope that it will be -#useful, but WITHOUT ANY WARRANTY; without even the implied warranty -#of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -#Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with the GNUTLS library; if not, write to the Free -# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA - -GNUTLS_1_6 -{ - global: - extern "C++" { - gnutls*; - }; - local: *; -}; diff --git a/src/daemon/https/x509/x509_privkey.c b/src/daemon/https/x509/x509_privkey.c @@ -51,7 +51,7 @@ int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params); * gnutls_x509_privkey_init - This function initializes a gnutls_crl structure * @key: The structure to be initialized * - * This function will initialize an private key structure. + * This function will initialize an private key structure. * * Returns 0 on success. * @@ -75,7 +75,7 @@ gnutls_x509_privkey_init (gnutls_x509_privkey_t * key) * gnutls_x509_privkey_deinit - This function deinitializes memory used by a gnutls_x509_privkey_t structure * @key: The structure to be initialized * - * This function will deinitialize a private key structure. + * This function will deinitialize a private key structure. * **/ void @@ -357,8 +357,7 @@ gnutls_x509_privkey_import (gnutls_x509_privkey_t key, key->pk_algorithm = GNUTLS_PK_UNKNOWN; - /* If the Certificate is in PEM format then decode it - */ + /* If the Certificate is in PEM format then decode it */ if (format == GNUTLS_X509_FMT_PEM) { opaque *out; @@ -399,9 +398,7 @@ gnutls_x509_privkey_import (gnutls_x509_privkey_t key, } else { - /* Try decoding with both, and accept the one that - * succeeds. - */ + /* Try decoding with both, and accept the one that succeeds. */ key->pk_algorithm = GNUTLS_PK_RSA; key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key); @@ -419,7 +416,8 @@ gnutls_x509_privkey_import (gnutls_x509_privkey_t key, { gnutls_assert (); result = GNUTLS_E_ASN1_DER_ERROR; - goto cleanup; + key->pk_algorithm = GNUTLS_PK_UNKNOWN; + return result; } if (need_free) @@ -429,11 +427,6 @@ gnutls_x509_privkey_import (gnutls_x509_privkey_t key, */ return 0; - -cleanup:key->pk_algorithm = GNUTLS_PK_UNKNOWN; - if (need_free) - _gnutls_free_datum (&_data); - return result; } #define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \ diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = . AM_CPPFLAGS = \ -I$(top_srcdir)/src/include \ --I$(top_srcdir)/src/https/includes +-I$(top_srcdir)/src/daemon/https/includes # example programs noinst_PROGRAMS = \ diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -73,6 +73,10 @@ #include "plibc.h" #endif +#if HTTPS_SUPPORT +#include "gnutls.h" +#endif + #ifdef __cplusplus extern "C" { @@ -725,6 +729,20 @@ MHD_get_connection_values (struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls); +#if HTTPS_SUPPORT +/* get cipher spec for this connection */ +gnutls_cipher_algorithm_t MHDS_get_session_cipher (struct MHD_Connection * session ); + +gnutls_kx_algorithm_t MHDS_get_session_kx (struct MHD_Connection * session ); +gnutls_mac_algorithm_t MHDS_get_session_mac (struct MHD_Connection * session ); +gnutls_compression_method_t MHDS_get_session_compression (struct MHD_Connection * session ); +gnutls_certificate_type_t MHDS_get_session_cert_type (struct MHD_Connection * session ); + +//TODO impl +size_t MHDS_get_key_size (struct MHD_Daemon * daemon, gnutls_cipher_algorithm_t algorithm); +size_t MHDS_get_mac_key_size (struct MHD_Daemon * daemon, gnutls_mac_algorithm_t algorithm); +#endif + /** * Get a particular header value. If multiple * values match the kind, return any one of them. @@ -836,7 +854,7 @@ MHD_get_response_headers (struct MHD_Response *response, * @param key which header to get * @return NULL if header does not exist */ -const char *MHD_get_response_header (struct MHD_Response *response, +const char * MHD_get_response_header (struct MHD_Response *response, const char *key); diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am @@ -1,6 +1,7 @@ SUBDIRS = . https AM_CPPFLAGS = \ +-I$(top_srcdir)/src/daemon/https/includes \ -I$(top_srcdir)/src/daemon \ -I$(top_srcdir)/src/include diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am @@ -1,11 +1,13 @@ SUBDIRS = . AM_CPPFLAGS = -ggdb \ +-I$(top_srcdir)/src/daemon/https/includes \ -I$(top_srcdir)/src/daemon \ --I$(top_srcdir)/src/include +-I$(top_srcdir)/src/include check_PROGRAMS = \ - daemon_https_test_get + daemon_https_test_get \ + mhds_test_session_info TESTS = $(check_PROGRAMS) @@ -14,3 +16,9 @@ daemon_https_test_get_SOURCES = \ daemon_https_test_get_LDADD = \ $(top_builddir)/src/daemon/libmicrohttpd.la \ @LIBCURL@ + +mhds_test_session_info_SOURCES = \ + mhds_test_session_info.c +mhds_test_session_info_LDADD = \ + $(top_builddir)/src/daemon/libmicrohttpd.la \ + @LIBCURL@ diff --git a/src/testcurl/https/daemon_https_test_get.c b/src/testcurl/https/daemon_https_test_get.c @@ -173,7 +173,7 @@ http_ahc (void *cls, struct MHD_Connection *connection, * @param test_fd: file to attempt transfering */ static int -test_HTTPS_Get (FILE * test_fd) +test_HTTPS_Get (FILE * test_fd, char * cipher_suite, int proto_version) { struct MHD_Daemon *d; CURL *c; @@ -232,9 +232,10 @@ test_HTTPS_Get (FILE * test_fd) curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); curl_easy_setopt (c, CURLOPT_FILE, &cbc); + /* TLS options */ - curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3); - curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, "AES256-SHA"); + curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version); + curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite); // TODO rm : currently skip any peer authentication */ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0); @@ -263,6 +264,7 @@ test_HTTPS_Get (FILE * test_fd) fprintf (stderr, "Error: local file & received file differ. %s\n"); return 8; } + return 0; } @@ -311,12 +313,15 @@ main (int argc, char *const *argv) return 32; } - errorCount += test_HTTPS_Get (test_fd); + errorCount += test_HTTPS_Get (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3); + errorCount += test_HTTPS_Get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1); + if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", errorCount); curl_global_cleanup (); fclose (test_fd); + return errorCount != 0; } diff --git a/src/testcurl/https/mhds_test_session_info.c b/src/testcurl/https/mhds_test_session_info.c @@ -0,0 +1,238 @@ +/* + This file is part of libmicrohttpd + (C) 2007 Christian Grothoff + + libmicrohttpd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + libmicrohttpd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libmicrohttpd; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file mhds_test_session_info.c + * @brief Testcase for libmicrohttpd GET operations + * @author lv-426 + */ + +#include "config.h" +#include "plibc.h" +#include "microhttpd.h" +#include <errno.h> + +#include <curl/curl.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <fcntl.h> +#include <unistd.h> + +#define BUF_SIZE 1024 +#define MAX_URL_LEN 255 + +#define EMPTY_PAGE "<html><head><title>Empty page</title></head><body>Empty page</body></html>" + +/* Test Certificate */ +const char cert_pem[] = + "-----BEGIN CERTIFICATE-----\n" + "MIICpjCCAZCgAwIBAgIESEPtjjALBgkqhkiG9w0BAQUwADAeFw0wODA2MDIxMjU0\n" + "MzhaFw0wOTA2MDIxMjU0NDZaMAAwggEfMAsGCSqGSIb3DQEBAQOCAQ4AMIIBCQKC\n" + "AQC03TyUvK5HmUAirRp067taIEO4bibh5nqolUoUdo/LeblMQV+qnrv/RNAMTx5X\n" + "fNLZ45/kbM9geF8qY0vsPyQvP4jumzK0LOJYuIwmHaUm9vbXnYieILiwCuTgjaud\n" + "3VkZDoQ9fteIo+6we9UTpVqZpxpbLulBMh/VsvX0cPJ1VFC7rT59o9hAUlFf9jX/\n" + "GmKdYI79MtgVx0OPBjmmSD6kicBBfmfgkO7bIGwlRtsIyMznxbHu6VuoX/eVxrTv\n" + "rmCwgEXLWRZ6ru8MQl5YfqeGXXRVwMeXU961KefbuvmEPccgCxm8FZ1C1cnDHFXh\n" + "siSgAzMBjC/b6KVhNQ4KnUdZAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0O\n" + "BBYEFJcUvpjvE5fF/yzUshkWDpdYiQh/MAsGCSqGSIb3DQEBBQOCAQEARP7eKSB2\n" + "RNd6XjEjK0SrxtoTnxS3nw9sfcS7/qD1+XHdObtDFqGNSjGYFB3Gpx8fpQhCXdoN\n" + "8QUs3/5ZVa5yjZMQewWBgz8kNbnbH40F2y81MHITxxCe1Y+qqHWwVaYLsiOTqj2/\n" + "0S3QjEJ9tvklmg7JX09HC4m5QRYfWBeQLD1u8ZjA1Sf1xJriomFVyRLI2VPO2bNe\n" + "JDMXWuP+8kMC7gEvUnJ7A92Y2yrhu3QI3bjPk8uSpHea19Q77tul1UVBJ5g+zpH3\n" + "OsF5p0MyaVf09GTzcLds5nE/osTdXGUyHJapWReVmPm3Zn6gqYlnzD99z+DPIgIV\n" + "RhZvQx74NQnS6g==\n" "-----END CERTIFICATE-----\n"; + +const char key_pem[] = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEowIBAAKCAQEAtN08lLyuR5lAIq0adOu7WiBDuG4m4eZ6qJVKFHaPy3m5TEFf\n" + "qp67/0TQDE8eV3zS2eOf5GzPYHhfKmNL7D8kLz+I7psytCziWLiMJh2lJvb2152I\n" + "niC4sArk4I2rnd1ZGQ6EPX7XiKPusHvVE6VamacaWy7pQTIf1bL19HDydVRQu60+\n" + "faPYQFJRX/Y1/xpinWCO/TLYFcdDjwY5pkg+pInAQX5n4JDu2yBsJUbbCMjM58Wx\n" + "7ulbqF/3lca0765gsIBFy1kWeq7vDEJeWH6nhl10VcDHl1PetSnn27r5hD3HIAsZ\n" + "vBWdQtXJwxxV4bIkoAMzAYwv2+ilYTUOCp1HWQIDAQABAoIBAArOQv3R7gmqDspj\n" + "lDaTFOz0C4e70QfjGMX0sWnakYnDGn6DU19iv3GnX1S072ejtgc9kcJ4e8VUO79R\n" + "EmqpdRR7k8dJr3RTUCyjzf/C+qiCzcmhCFYGN3KRHA6MeEnkvRuBogX4i5EG1k5l\n" + "/5t+YBTZBnqXKWlzQLKoUAiMLPg0eRWh+6q7H4N7kdWWBmTpako7TEqpIwuEnPGx\n" + "u3EPuTR+LN6lF55WBePbCHccUHUQaXuav18NuDkcJmCiMArK9SKb+h0RqLD6oMI/\n" + "dKD6n8cZXeMBkK+C8U/K0sN2hFHACsu30b9XfdnljgP9v+BP8GhnB0nCB6tNBCPo\n" + "32srOwECgYEAxWh3iBT4lWqL6bZavVbnhmvtif4nHv2t2/hOs/CAq8iLAw0oWGZc\n" + "+JEZTUDMvFRlulr0kcaWra+4fN3OmJnjeuFXZq52lfMgXBIKBmoSaZpIh2aDY1Rd\n" + "RbEse7nQl9hTEPmYspiXLGtnAXW7HuWqVfFFP3ya8rUS3t4d07Hig8ECgYEA6ou6\n" + "OHiBRTbtDqLIv8NghARc/AqwNWgEc9PelCPe5bdCOLBEyFjqKiT2MttnSSUc2Zob\n" + "XhYkHC6zN1Mlq30N0e3Q61YK9LxMdU1vsluXxNq2rfK1Scb1oOlOOtlbV3zA3VRF\n" + "hV3t1nOA9tFmUrwZi0CUMWJE/zbPAyhwWotKyZkCgYEAh0kFicPdbABdrCglXVae\n" + "SnfSjVwYkVuGd5Ze0WADvjYsVkYBHTvhgRNnRJMg+/vWz3Sf4Ps4rgUbqK8Vc20b\n" + "AU5G6H6tlCvPRGm0ZxrwTWDHTcuKRVs+pJE8C/qWoklE/AAhjluWVoGwUMbPGuiH\n" + "6Gf1bgHF6oj/Sq7rv/VLZ8ECgYBeq7ml05YyLuJutuwa4yzQ/MXfghzv4aVyb0F3\n" + "QCdXR6o2IYgR6jnSewrZKlA9aPqFJrwHNR6sNXlnSmt5Fcf/RWO/qgJQGLUv3+rG\n" + "7kuLTNDR05azSdiZc7J89ID3Bkb+z2YkV+6JUiPq/Ei1+nDBEXb/m+/HqALU/nyj\n" + "P3gXeQKBgBusb8Rbd+KgxSA0hwY6aoRTPRt8LNvXdsB9vRcKKHUFQvxUWiUSS+L9\n" + "/Qu1sJbrUquKOHqksV5wCnWnAKyJNJlhHuBToqQTgKXjuNmVdYSe631saiI7PHyC\n" + "eRJ6DxULPxABytJrYCRrNqmXi5TCiqR2mtfalEMOPxz8rUU8dYyx\n" + "-----END RSA PRIVATE KEY-----\n"; + +struct MHD_Daemon *d; + +struct CBC +{ + char *buf; + size_t pos; + size_t size; +}; + +static size_t +copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) +{ + struct CBC *cbc = ctx; + + if (cbc->pos + size * nmemb > cbc->size) + return 0; /* overflow */ + memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb); + cbc->pos += size * nmemb; + return size * nmemb; +} + +/* HTTP access handler call back */ +static int +query_session_ahc (void *cls, struct MHD_Connection *connection, + const char *url, const char *method, + const char *upload_data, const char *version, + unsigned int *upload_data_size, void **ptr) +{ + struct MHD_Response *response; + int ret; + + /* assert actual connection cipher is the one negotiated */ + if (MHDS_get_session_cipher (connection) != GNUTLS_CIPHER_AES_256_CBC) + { + fprintf (stderr, "Error: requested cipher mismatch. %s\n", + strerror (errno)); + return -1; + } + + // TODO should these be hard coded into the server ? + if (MHDS_get_session_mac (connection) != GNUTLS_MAC_SHA1) + { + fprintf (stderr, "Error: requested mac algorithm mismatch. %s\n", + strerror (errno)); + return -1; + } + if (MHDS_get_session_compression (connection) != GNUTLS_COMP_NULL) + { + fprintf (stderr, "Error: requested compression mismatch. %s\n", + strerror (errno)); + return -1; + } + if (MHDS_get_session_cert_type (connection) != GNUTLS_CRT_X509) + { + fprintf (stderr, "Error: requested certificate mismatch. %s\n", + strerror (errno)); + return -1; + } + + response = MHD_create_response_from_data (strlen (EMPTY_PAGE), + (void *) EMPTY_PAGE, + MHD_NO, MHD_NO); + ret = MHD_queue_response (connection, MHD_HTTP_OK, response); + MHD_destroy_response (response); + return ret; +} + +static int +test_query_session () +{ + + CURL *c; + struct CBC cbc; + CURLcode errornum; + char url[] = "https://localhost:42433/"; + + if (NULL == (cbc.buf = malloc (sizeof (char) * 255))) + return 16; + cbc.size = 255; + cbc.pos = 0; + + /* setup test */ + d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | + MHD_USE_DEBUG, 42433, + NULL, NULL, &query_session_ahc, NULL, + MHD_OPTION_HTTPS_MEM_KEY, key_pem, + MHD_OPTION_HTTPS_MEM_CERT, cert_pem, MHD_OPTION_END); + + if (d == NULL) + return 2; + + c = curl_easy_init (); + //curl_easy_setopt (c, CURLOPT_VERBOSE, 1); + curl_easy_setopt (c, CURLOPT_URL, url); + curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L); + curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer); + curl_easy_setopt (c, CURLOPT_FILE, &cbc); + /* TLS options */ + curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3); + curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, "AES256-SHA"); + /* currently skip any peer authentication */ + curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0); + + curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); + + // NOTE: use of CONNECTTIMEOUT without also + // setting NOSIGNAL results in really weird + // crashes on my system! + curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); + if (CURLE_OK != (errornum = curl_easy_perform (c))) + { + fprintf (stderr, "curl_easy_perform failed: `%s'\n", + curl_easy_strerror (errornum)); + curl_easy_cleanup (c); + MHD_stop_daemon (d); + return 4; + } + + curl_easy_cleanup (c); + MHD_stop_daemon (d); + + return 0; +} + +int +main (int argc, char *const *argv) +{ + FILE *test_fd; + unsigned int errorCount = 0; + + if (0 != curl_global_init (CURL_GLOBAL_ALL)) + { + fprintf (stderr, "Error (code: %u)\n", errorCount); + return 8; + } + + errorCount += test_query_session (test_fd); + if (errorCount != 0) + fprintf (stderr, "Error (code: %u)\n", errorCount); + + curl_global_cleanup (); + + return errorCount != 0; +}