bool network_client::connect(const char* ip, int port) { if (connected_) { last_error_ = boost::system::errc::make_error_code(boost::system::errc::already_connected); return false; } if (io_service_ == nullptr) { io_service_ = io_service_pt(new asio_io_service_t()); } if (strand_ == nullptr) { strand_ = strand_pt(new asio_strand_t(*io_service_)); } boost::container::vector<unsigned char> cert_buff, key_buff; if (!make_certificate(cert_buff, key_buff)) { // @todo: make custom errors last_error_ = boost::system::errc::make_error_code(boost::system::errc::not_supported); return false; } asio_ssl_context_t ssl_context(*io_service_, asio_ssl_context_t::tlsv1); ssl_context.set_verify_mode(asio_ssl_context_t::verify_none); ssl_context.use_certificate(boost::asio::const_buffer(cert_buff.data(), cert_buff.size()), asio_ssl_context_t::asn1); ssl_context.use_private_key(boost::asio::const_buffer(key_buff.data(), key_buff.size()), asio_ssl_context_t::asn1); ssl_socket_ = ssl_socket_pt(new asio_ssl_socket_t(*io_service_, ssl_context)); auto endpoint = boost::asio::ip::tcp::endpoint( boost::asio::ip::address::from_string(ip), port); ssl_socket_->next_layer().async_connect(endpoint, strand_->wrap(boost::bind(&network_client::handle_connect, this, boost::asio::placeholders::error))); t_ = boost::thread(boost::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), io_service_)); return true; }
int /* O - 1 on success, 0 on error */ cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */ { OSStatus error = 0; /* Error code */ SecTrustRef peerTrust; /* Peer certificates */ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.", con->number); con->http->encryption = HTTP_ENCRYPTION_ALWAYS; con->http->tls_credentials = copy_cdsa_certificate(con); if (!con->http->tls_credentials) { /* * No keychain (yet), make a self-signed certificate... */ if (make_certificate(con)) con->http->tls_credentials = copy_cdsa_certificate(con); } if (!con->http->tls_credentials) { cupsdLogMessage(CUPSD_LOG_ERROR, "Could not find signing key in keychain \"%s\"", ServerCertificate); error = errSSLBadConfiguration; } if (!error) con->http->tls = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType); if (!error) error = SSLSetIOFuncs(con->http->tls, _httpReadCDSA, _httpWriteCDSA); if (!error) error = SSLSetConnection(con->http->tls, HTTP(con)); if (!error) error = SSLSetCertificate(con->http->tls, con->http->tls_credentials); if (!error) { /* * Perform SSL/TLS handshake */ while ((error = SSLHandshake(con->http->tls)) == errSSLWouldBlock) usleep(1000); } if (error) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s - %s (%d)", con->http->hostname, cssmErrorString(error), (int)error); con->http->error = error; con->http->status = HTTP_ERROR; if (con->http->tls) { CFRelease(con->http->tls); con->http->tls = NULL; } if (con->http->tls_credentials) { CFRelease(con->http->tls_credentials); con->http->tls_credentials = NULL; } return (0); } cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.", con->http->hostname); if (!SSLCopyPeerTrust(con->http->tls, &peerTrust) && peerTrust) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates.", (int)SecTrustGetCertificateCount(peerTrust)); CFRelease(peerTrust); } else cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates."); return (1); }
int /* O - 1 on success, 0 on error */ cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */ { int status; /* Error code */ gnutls_certificate_server_credentials *credentials; /* TLS credentials */ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.", con->http.fd); /* * Verify that we have a certificate... */ if (access(ServerKey, 0) || access(ServerCertificate, 0)) { /* * Nope, make a self-signed certificate... */ if (!make_certificate(con)) return (0); } /* * Create the SSL object and perform the SSL handshake... */ credentials = (gnutls_certificate_server_credentials *) malloc(sizeof(gnutls_certificate_server_credentials)); if (credentials == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s - %s", con->http.hostname, strerror(errno)); return (0); } gnutls_certificate_allocate_credentials(credentials); gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate, ServerKey, GNUTLS_X509_FMT_PEM); gnutls_init(&con->http.tls, GNUTLS_SERVER); gnutls_set_default_priority(con->http.tls); gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials); gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con)); gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS); gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS); while ((status = gnutls_handshake(con->http.tls)) != GNUTLS_E_SUCCESS) { if (gnutls_error_is_fatal(status)) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s - %s", con->http.hostname, gnutls_strerror(status)); gnutls_deinit(con->http.tls); gnutls_certificate_free_credentials(*credentials); con->http.tls = NULL; free(credentials); return (0); } } cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.", con->http.hostname); con->http.tls_credentials = credentials; return (1); }