bool VSslServer::setKeyCrtStuff(VError& error, SSL* con, EVP_PKEY* key, X509* crt) { LOG_ASSERT(key != NULL); LOG_ASSERT(crt != NULL); // LOG_DEBUG("con=%p key=%p crt=%p", con, key, crt); // gilgil temp 2014.03.14 int res = SSL_use_certificate(con, crt); if (res <= 0) { error = VSslError(QString("SSL_use_certificate return %1").arg(res), VSslError::IN_SSL_CTX_USE_CERTIFICATE); return false; } res = SSL_use_PrivateKey(con, key); if (res <= 0) { error = VSslError(QString("SSL_use_PrivateKey return %1").arg(res), VSslError::SSL_CTX_USER_PRIVATEKEY); return false; } res = SSL_check_private_key(con); if (!res) { error = VSslError(QString("SSL_check_private_key return %1").arg(res), VSslError::SSL_CTX_CHECK_PRIVATEKEY); return false; } return true; }
bool Engine::set_p12_certificate_privatekey(const Data & data, const std::string & password) { if( data.empty() ) // BIO undefined behaviour when writing 0 return false; BIO *mem = BIO_new(BIO_s_mem()); BIO_write(mem, data.getData(), data.getSize()); PKCS12 * pkcs12 = d2i_PKCS12_bio(mem, NULL); BIO_free(mem); mem = 0; X509 * cax = 0; EVP_PKEY * pkey = 0; // int succ = PKCS12_parse(pkcs12, password.c_str(), &pkey, &cax, NULL); // int err = ERR_get_error(); // const char * err_str = ERR_error_string(err, 0); int cert_res = SSL_use_certificate(ssl, cax); if (cax) X509_free(cax); cax = 0; int key_res = SSL_use_PrivateKey(ssl, pkey); if( pkey ) EVP_PKEY_free(pkey); pkey = 0; int check_res = SSL_check_private_key(ssl); return cert_res == 1 && key_res == 1 && check_res == 1; }
bool Engine::set_pem_certificate_privatekey(const Data & data, const std::string & password) { if( data.empty() ) // BIO undefined behaviour when writing 0 return false; BIO *mem = BIO_new(BIO_s_mem()); BIO_write(mem, data.getData(), data.getSize()); X509 * cax = PEM_read_bio_X509(mem, NULL, 0, const_cast<char *>(password.c_str())); // Stupid C guys BIO_free(mem); mem = 0; mem = BIO_new(BIO_s_mem()); BIO_write(mem, data.getData(), data.getSize()); EVP_PKEY * pkey = PEM_read_bio_PrivateKey(mem, NULL, 0, const_cast<char *>(password.c_str())); // Stupid C guys BIO_free(mem); mem = 0; int cert_res = SSL_use_certificate(ssl, cax); if (cax) X509_free(cax); cax = 0; int key_res = SSL_use_PrivateKey(ssl, pkey); if( pkey ) EVP_PKEY_free(pkey); pkey = 0; int check_res = SSL_check_private_key(ssl); return cert_res == 1 && key_res == 1 && check_res == 1; }
// XXX Clean up this function, we MUST handle all errors possible int krypt_set_rsa(krypt_t *kconn) { if (kconn->security_level == KRYPT_RSA) { jlog(L_NOTICE, "the security level is already set to RSA"); return 0; } SSL_set_cipher_list(kconn->ssl, "AES256-SHA"); // Load the trusted certificate store into our SSL_CTX SSL_CTX_set_cert_store(kconn->ctx, kconn->passport->trusted_authority); // Force the peer cert verifying + fail if no cert is sent by the peer SSL_set_verify(kconn->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); // Set the certificate and key SSL_use_certificate(kconn->ssl, kconn->passport->certificate); SSL_use_PrivateKey(kconn->ssl, kconn->passport->keyring); if (kconn->conn_type == KRYPT_SERVER) { jlog(L_NOTICE, "set verify"); // Change the session id to avoid resuming ADH session SSL_set_session_id_context(kconn->ssl, (void*)&s_server_auth_session_id_context, sizeof(s_server_auth_session_id_context)); } kconn->security_level = KRYPT_RSA; return 0; }
static int openssl_iostream_use_certificate(struct ssl_iostream *ssl_io, const char *cert) { BIO *in; X509 *x; int ret = 0; in = BIO_new_mem_buf(t_strdup_noconst(cert), strlen(cert)); if (in == NULL) { i_error("BIO_new_mem_buf() failed: %s", openssl_iostream_error()); return -1; } x = PEM_read_bio_X509(in, NULL, NULL, NULL); if (x != NULL) { ret = SSL_use_certificate(ssl_io->ssl, x); if (ERR_peek_error() != 0) ret = 0; X509_free(x); } BIO_free(in); if (ret == 0) { i_error("%s: Can't load ssl_cert: %s", ssl_io->source, ssl_iostream_get_use_certificate_error(cert)); return -1; } return 0; }
void SSLConnect::setToken( const QSslCertificate &cert, Qt::HANDLE key ) { if( !d->ssl ) return d->setError( tr("SSL context is missing") ); if( cert.isNull() ) return d->setError( tr("Certificate is empty") ); if( !SSL_use_certificate( d->ssl, X509_dup( (X509*)cert.handle() ) ) || !SSL_use_PrivateKey( d->ssl, (EVP_PKEY*)key ) ) d->setError(); }
static void regress_bufferevent_openssl(void *arg) { struct basic_test_data *data = arg; struct bufferevent *bev1, *bev2; SSL *ssl1, *ssl2; X509 *cert = getcert(); EVP_PKEY *key = getkey(); const int start_open = strstr((char*)data->setup_data, "open")!=NULL; const int filter = strstr((char*)data->setup_data, "filter")!=NULL; int flags = BEV_OPT_DEFER_CALLBACKS; struct bufferevent *bev_ll[2] = { NULL, NULL }; evutil_socket_t *fd_pair = NULL; tt_assert(cert); tt_assert(key); init_ssl(); if (strstr((char*)data->setup_data, "renegotiate")) { if (SSLeay() >= 0x10001000 && SSLeay() < 0x1000104f) { /* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2 * can't renegotiate with themselves. Disable. */ disable_tls_11_and_12 = 1; } renegotiate_at = 600; } ssl1 = SSL_new(get_ssl_ctx()); ssl2 = SSL_new(get_ssl_ctx()); SSL_use_certificate(ssl2, cert); SSL_use_PrivateKey(ssl2, key); if (! start_open) flags |= BEV_OPT_CLOSE_ON_FREE; if (!filter) { tt_assert(strstr((char*)data->setup_data, "socketpair")); fd_pair = data->pair; } else { bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0], BEV_OPT_CLOSE_ON_FREE); bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1], BEV_OPT_CLOSE_ON_FREE); } open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2, fd_pair, bev_ll); if (!filter) { tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]); } else {
int SSL_use_certificate_file (SSL * ssl, const char *file, int type) { int j; BIO *in; int ret = 0; X509 *x = NULL; in = BIO_new (BIO_s_file_internal ()); if (in == NULL) { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename (in, file) <= 0) { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; x = d2i_X509_bio (in, NULL); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; x = PEM_read_bio_X509 (in, NULL, ssl->ctx->default_passwd_callback, ssl->ctx->default_passwd_callback_userdata); } else { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } if (x == NULL) { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, j); goto end; } ret = SSL_use_certificate (ssl, x); end: if (x != NULL) X509_free (x); if (in != NULL) BIO_free (in); return (ret); }
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) { X509 *x; int ret; x = d2i_X509(NULL, &d, (long)len); if (x == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } ret = SSL_use_certificate(ssl, x); X509_free(x); return ret; }
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) { X509 *x; int ret; x = d2i_X509(NULL, &d, (long)len); if (x == NULL) { SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); return (0); } ret = SSL_use_certificate(ssl, x); X509_free(x); return (ret); }
static void regress_bufferevent_openssl(void *arg) { struct basic_test_data *data = arg; struct bufferevent *bev1, *bev2; SSL *ssl1, *ssl2; X509 *cert = getcert(); EVP_PKEY *key = getkey(); const int start_open = strstr((char*)data->setup_data, "open")!=NULL; const int filter = strstr((char*)data->setup_data, "filter")!=NULL; int flags = BEV_OPT_DEFER_CALLBACKS; struct bufferevent *bev_ll[2] = { NULL, NULL }; int *fd_pair = NULL; tt_assert(cert); tt_assert(key); init_ssl(); ssl1 = SSL_new(get_ssl_ctx()); ssl2 = SSL_new(get_ssl_ctx()); SSL_use_certificate(ssl2, cert); SSL_use_PrivateKey(ssl2, key); if (! start_open) flags |= BEV_OPT_CLOSE_ON_FREE; if (strstr((char*)data->setup_data, "renegotiate")) renegotiate_at = 600; if (!filter) { tt_assert(strstr((char*)data->setup_data, "socketpair")); fd_pair = data->pair; } else { bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0], BEV_OPT_CLOSE_ON_FREE); bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1], BEV_OPT_CLOSE_ON_FREE); } open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2, fd_pair, bev_ll); if (!filter) { tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]); } else {
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { if (der_len > LONG_MAX) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return 0; } const uint8_t *p = der; X509 *x509 = d2i_X509(NULL, &p, (long)der_len); if (x509 == NULL || p != der + der_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); X509_free(x509); return 0; } int ret = SSL_use_certificate(ssl, x509); X509_free(x509); return ret; }
static int openssl_ssl_use(lua_State*L) { SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); X509* x = CHECK_OBJECT(2, X509, "openssl.x509"); EVP_PKEY* pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); int ret; luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key"); ret = SSL_use_PrivateKey(s, pkey); if (ret == 1) { ret = SSL_use_certificate(s, x); if (ret == 1) { ret = SSL_check_private_key(s); } } return openssl_pushresult(L, ret); }
int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { int reason_code; BIO *in; int ret = 0; X509 *x = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { reason_code = ERR_R_ASN1_LIB; x = d2i_X509_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { reason_code = ERR_R_PEM_LIB; x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, ssl->ctx->default_passwd_callback_userdata); } else { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } if (x == NULL) { OPENSSL_PUT_ERROR(SSL, reason_code); goto end; } ret = SSL_use_certificate(ssl, x); end: X509_free(x); BIO_free(in); return ret; }
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) { long options = 0; BIO* bio; RSA* rsa; X509* x509; /** * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE)) return FALSE; if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); return FALSE; } } else { WLog_ERR(TAG, "no private key defined"); return FALSE; } rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "invalid private key"); return FALSE; } if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); RSA_free(rsa); return FALSE; } if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); return FALSE; } } else { WLog_ERR(TAG, "no certificate defined"); return FALSE; } x509 = PEM_read_bio_X509(bio, NULL, NULL, 0); BIO_free(bio); if (!x509) { WLog_ERR(TAG, "invalid certificate"); return FALSE; } if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); X509_free(x509); return FALSE; } #ifndef OPENSSL_NO_TLSEXT /** * The Microsoft iOS clients eventually send a null or even double null * terminated hostname in the SNI TLS extension! * If the length indicator does not equal the hostname strlen OpenSSL * will abort (see openssl:ssl/t1_lib.c). * Here is a tcpdump segment of Microsoft Remote Desktop Client Version * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted * SNI hostname TLV blob when connection to server "abcd": * 00 name_type 0x00 (host_name) * 00 06 length_in_bytes 0x0006 * 61 62 63 64 00 00 host_name "abcd\0\0" * * Currently the only (runtime) workaround is setting an openssl tls * extension debug callback that sets the SSL context's servername_done * to 1 which effectively disables the parsing of that extension type. */ SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; }
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) { long options = 0; BIO* bio; RSA* rsa; X509* x509; /** * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE)) return FALSE; if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); return FALSE; } } else { WLog_ERR(TAG, "no private key defined"); return FALSE; } rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "invalid private key"); return FALSE; } if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); RSA_free(rsa); return FALSE; } if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); return FALSE; } } else { WLog_ERR(TAG, "no certificate defined"); return FALSE; } x509 = PEM_read_bio_X509(bio, NULL, NULL, 0); BIO_free(bio); if (!x509) { WLog_ERR(TAG, "invalid certificate"); return FALSE; } if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); X509_free(x509); return FALSE; } #if defined(MICROSOFT_IOS_SNI_BUG) && !defined(OPENSSL_NO_TLSEXT) SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; }
static int ngx_http_multiple_ssl_set_der_certificate(ngx_ssl_conn_t *ssl_conn, ngx_str_t *cert, ngx_str_t *key) { BIO *bio = NULL; X509 *x509 = NULL; u_long n; bio = BIO_new_file((char *) cert->data, "r"); if (bio == NULL) { return NGX_ERROR; } x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL); if (x509 == NULL) { BIO_free(bio); return NGX_ERROR; } SSL_certs_clear(ssl_conn); if (SSL_use_certificate(ssl_conn, x509) == 0) { X509_free(x509); BIO_free(bio); return NGX_ERROR; } #if 0 if (SSL_set_ex_data(ssl_conn, ngx_ssl_certificate_index, x509) == 0) { X509_free(x509); BIO_free(bio); return NGX_ERROR; } #endif X509_free(x509); x509 = NULL; /* read rest of the chain */ for ( ;; ) { x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); if (x509 == NULL) { n = ERR_peek_last_error(); if (ERR_GET_LIB(n) == ERR_LIB_PEM && ERR_GET_REASON(n) == PEM_R_NO_START_LINE) { ERR_clear_error(); break; } BIO_free(bio); return NGX_ERROR; } if (SSL_add0_chain_cert(ssl_conn, x509) == 0) { X509_free(x509); BIO_free(bio); return NGX_ERROR; } } BIO_free(bio); bio = NULL; if (SSL_use_PrivateKey_file(ssl_conn, (char *) key->data, SSL_FILETYPE_PEM) != 1) { return NGX_ERROR; } return NGX_OK; }
tcp_stream_t * tcp_stream_create_ssl_from_fd(int fd, const char *hostname, const tcp_ssl_info_t *tsi, char *errbuf, size_t errlen) { char errmsg[120]; tcp_stream_t *ts = calloc(1, sizeof(tcp_stream_t)); ts->ts_fd = fd; if((ts->ts_ssl = SSL_new(ssl_ctx)) == NULL) goto bad_ssl; if(SSL_set_fd(ts->ts_ssl, fd) == 0) goto bad_ssl; if(tsi->key != NULL) { BIO *cbio = BIO_new_mem_buf((char *)tsi->key, -1); EVP_PKEY *key = PEM_read_bio_PrivateKey(cbio, NULL, NULL, NULL); BIO_free(cbio); if(key == NULL) { snprintf(errbuf, errlen, "Unable to load private key"); goto bad; } SSL_use_PrivateKey(ts->ts_ssl, key); EVP_PKEY_free(key); } if(tsi->cert != NULL) { BIO *cbio = BIO_new_mem_buf((char *)tsi->cert, -1); X509 *cert = PEM_read_bio_X509(cbio, NULL, 0, NULL); BIO_free(cbio); if(cert == NULL) { snprintf(errbuf, errlen, "Unable to load certificate"); goto bad; } SSL_use_certificate(ts->ts_ssl, cert); X509_free(cert); } if(SSL_connect(ts->ts_ssl) <= 0) { goto bad_ssl; } SSL_set_mode(ts->ts_ssl, SSL_MODE_AUTO_RETRY); X509 *peer = SSL_get_peer_certificate(ts->ts_ssl); if(peer == NULL) { goto bad_ssl; } int err = SSL_get_verify_result(ts->ts_ssl); if(err != X509_V_OK) { snprintf(errbuf, errlen, "Certificate error: %s", X509_verify_cert_error_string(err)); X509_free(peer); goto bad; } if(verify_hostname(hostname, peer, errbuf, errlen)) { X509_free(peer); goto bad; } X509_free(peer); ts->ts_fd = fd; htsbuf_queue_init(&ts->ts_spill, INT32_MAX); htsbuf_queue_init(&ts->ts_sendq, INT32_MAX); ts->ts_write = ssl_write; ts->ts_read = ssl_read; return ts; bad_ssl: ERR_error_string(ERR_get_error(), errmsg); snprintf(errbuf, errlen, "SSL: %s", errmsg); bad: tcp_close(ts); return NULL; }
static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key, const char *passwd) { #ifdef PKCS12_FUNCS FILE *f; PKCS12 *p12; EVP_PKEY *pkey; X509 *cert; int res = 0; f = fopen(private_key, "r"); if (f == NULL) return -1; p12 = d2i_PKCS12_fp(f, NULL); if (p12 == NULL) { wpa_printf(MSG_DEBUG, "TLS: Failed to read PKCS12 file '%s'", private_key); fclose(f); return -1; } fclose(f); pkey = NULL; cert = NULL; if (!PKCS12_parse(p12, passwd, &pkey, &cert, NULL)) { wpa_printf(MSG_DEBUG, "TLS: Failed to parse PKCS12 file '%s': " "%s", private_key, ERR_error_string(ERR_get_error(), NULL)); return -1; } wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 file '%s'", private_key); if (cert) { wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12"); if (ssl) { if (SSL_use_certificate(ssl, cert) != 1) res = -1; } else { if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1) res = -1; } X509_free(cert); } if (pkey) { wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12"); if (ssl) { if (SSL_use_PrivateKey(ssl, pkey) != 1) res = -1; } else { if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) res = -1; } EVP_PKEY_free(pkey); } PKCS12_free(p12); return res; #else /* PKCS12_FUNCS */ wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read " "p12/pfx files"); return -1; #endif /* PKCS12_FUNCS */ }
/* read the data and then respond */ static int client_certificate(SSL *s) { unsigned char *buf; unsigned char *p,*d; int i; unsigned int n; int cert_ch_len; unsigned char *cert_ch; buf=(unsigned char *)s->init_buf->data; /* We have a cert associated with the SSL, so attach it to * the session if it does not have one */ if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A) { i=ssl2_read(s,(char *)&(buf[s->init_num]), SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num); if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num)) return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i)); s->init_num += i; if (s->msg_callback) s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* REQUEST-CERTIFICATE */ /* type=buf[0]; */ /* type eq x509 */ if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_AUTHENTICATION_TYPE); return(-1); } if ((s->cert == NULL) || (s->cert->key->x509 == NULL) || (s->cert->key->privatekey == NULL)) { s->state=SSL2_ST_X509_GET_CLIENT_CERTIFICATE; } else s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C; } cert_ch = buf + 2; cert_ch_len = s->init_num - 2; if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE) { X509 *x509=NULL; EVP_PKEY *pkey=NULL; /* If we get an error we need to * ssl->rwstate=SSL_X509_LOOKUP; * return(error); * We should then be retried when things are ok and we * can get a cert or not */ i=0; if (s->ctx->client_cert_cb != NULL) { i=s->ctx->client_cert_cb(s,&(x509),&(pkey)); } if (i < 0) { s->rwstate=SSL_X509_LOOKUP; return(-1); } s->rwstate=SSL_NOTHING; if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C; if ( !SSL_use_certificate(s,x509) || !SSL_use_PrivateKey(s,pkey)) { i=0; } X509_free(x509); EVP_PKEY_free(pkey); } else if (i == 1) { if (x509 != NULL) X509_free(x509); if (pkey != NULL) EVP_PKEY_free(pkey); SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); i=0; } if (i == 0) { /* We have no client certificate to respond with * so send the correct error message back */ s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B; p=buf; *(p++)=SSL2_MT_ERROR; s2n(SSL2_PE_NO_CERTIFICATE,p); s->init_off=0; s->init_num=3; /* Write is done at the end */ } } if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B) { return(ssl2_do_write(s)); } if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C) { EVP_MD_CTX ctx; /* ok, now we calculate the checksum * do it first so we can reuse buf :-) */ p=buf; EVP_MD_CTX_init(&ctx); EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL); EVP_SignUpdate(&ctx,s->s2->key_material, s->s2->key_material_length); EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len); n=i2d_X509(s->session->sess_cert->peer_key->x509,&p); EVP_SignUpdate(&ctx,buf,(unsigned int)n); p=buf; d=p+6; *(p++)=SSL2_MT_CLIENT_CERTIFICATE; *(p++)=SSL2_CT_X509_CERTIFICATE; n=i2d_X509(s->cert->key->x509,&d); s2n(n,p); if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey)) { /* this is not good. If things have failed it * means there so something wrong with the key. * We will continue with a 0 length signature */ } EVP_MD_CTX_cleanup(&ctx); s2n(n,p); d+=n; s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D; s->init_num=d-buf; s->init_off=0; } /* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */ return(ssl2_do_write(s)); }
void bud_client_sni_cb(bud_http_request_t* req, bud_error_t err) { bud_client_t* client; bud_config_t* config; bud_client_error_t cerr; int r; STACK_OF(X509)* chain; SSL_CTX* ctx; X509* x509; EVP_PKEY* pkey; client = req->data; config = client->config; client->sni_req = NULL; client->async_hello = kBudProgressDone; if (!bud_is_ok(err)) { WARNING(&client->frontend, "SNI cb failed: \"%s\"", bud_error_to_str(err)); goto fatal; } if (req->code == 404) { /* Not found */ DBG(&client->frontend, "SNI name not found: \"%.*s\"", client->hello.servername_len, client->hello.servername); goto done; } /* Parse incoming JSON */ err = bud_sni_from_json(config, req->response, &client->sni_ctx); if (!bud_is_ok(err)) { WARNING(&client->frontend, "SNI from json failed: \"%s\"", bud_error_to_str(err)); goto fatal; } /* Success */ DBG(&client->frontend, "SNI name found: \"%.*s\"", client->hello.servername_len, client->hello.servername); if (!SSL_set_ex_data(client->ssl, kBudSSLSNIIndex, &client->sni_ctx)) { err = bud_error(kBudErrClientSetExData); goto fatal; } /* NOTE: reference count is not increased by this API methods */ ctx = client->sni_ctx.ctx; x509 = SSL_CTX_get0_certificate(ctx); pkey = SSL_CTX_get0_privatekey(ctx); r = SSL_CTX_get0_chain_certs(ctx, &chain); if (r == 1) r = SSL_use_certificate(client->ssl, x509); if (r == 1) r = SSL_use_PrivateKey(client->ssl, pkey); if (r == 1 && chain != NULL) r = SSL_set1_chain(client->ssl, chain); if (r != 1) { err = bud_error(kBudErrClientSetSNICert); goto fatal; } /* Update context, may be needed for early ticket key generation */ SSL_set_SSL_CTX(client->ssl, ctx); /* Do not loose the cert callback! */ SSL_set_cert_cb(client->ssl, bud_client_ssl_cert_cb, client); client->ssl->options = client->sni_ctx.ctx->options; done: /* Request stapling info if needed */ if (config->stapling.enabled && client->hello.ocsp_request != 0) { err = bud_client_ocsp_stapling(client); if (!bud_is_ok(err)) goto fatal; } json_value_free(req->response); if (client->async_hello == kBudProgressDone) { cerr = bud_client_cycle(client); if (!bud_is_ok(cerr.err)) bud_client_close(client, cerr); } return; fatal: bud_client_close(client, bud_client_error(err, &client->frontend)); }
static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) { const char *servername; connection *con = (connection *) SSL_get_app_data(ssl); UNUSED(al); buffer_copy_string(con->uri.scheme, "https"); if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { #if 0 /* this "error" just means the client didn't support it */ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", "failed to get TLS server name"); #endif return SSL_TLSEXT_ERR_NOACK; } buffer_copy_string(con->tlsext_server_name, servername); buffer_to_lower(con->tlsext_server_name); /* Sometimes this is still set, confusing COMP_HTTP_HOST */ buffer_reset(con->uri.authority); config_cond_cache_reset(srv, con); config_setup_connection(srv, con); con->conditional_is_valid[COMP_SERVER_SOCKET] = 1; con->conditional_is_valid[COMP_HTTP_SCHEME] = 1; con->conditional_is_valid[COMP_HTTP_HOST] = 1; config_patch_connection(srv, con); if (NULL == con->conf.ssl_pemfile_x509 || NULL == con->conf.ssl_pemfile_pkey) { /* x509/pkey available <=> pemfile was set <=> pemfile got patched: so this should never happen, unless you nest $SERVER["socket"] */ log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", "no certificate/private key for TLS server name", con->tlsext_server_name); return SSL_TLSEXT_ERR_ALERT_FATAL; } /* first set certificate! setting private key checks whether certificate matches it */ if (!SSL_use_certificate(ssl, con->conf.ssl_pemfile_x509)) { log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:", "failed to set certificate for TLS server name", con->tlsext_server_name, ERR_error_string(ERR_get_error(), NULL)); return SSL_TLSEXT_ERR_ALERT_FATAL; } if (!SSL_use_PrivateKey(ssl, con->conf.ssl_pemfile_pkey)) { log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:", "failed to set private key for TLS server name", con->tlsext_server_name, ERR_error_string(ERR_get_error(), NULL)); return SSL_TLSEXT_ERR_ALERT_FATAL; } if (con->conf.ssl_verifyclient) { if (NULL == con->conf.ssl_ca_file_cert_names) { log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:", "can't verify client without ssl.ca-file for TLS server name", con->tlsext_server_name, ERR_error_string(ERR_get_error(), NULL)); return SSL_TLSEXT_ERR_ALERT_FATAL; } SSL_set_client_CA_list(ssl, SSL_dup_CA_list(con->conf.ssl_ca_file_cert_names)); /* forcing verification here is really not that useful - a client could just connect without SNI */ SSL_set_verify( ssl, SSL_VERIFY_PEER | (con->conf.ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0), NULL ); SSL_set_verify_depth(ssl, con->conf.ssl_verifyclient_depth); } else { SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); } return SSL_TLSEXT_ERR_OK; }
MONO_API int mono_btls_ssl_use_certificate (MonoBtlsSsl *ptr, X509 *x509) { return SSL_use_certificate (ptr->ssl, x509); }
/* * Read a file that contains our certificate in "PEM" format, possibly * followed by a sequence of CA certificates that should be sent to the peer * in the Certificate message. */ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) { BIO *in; int ret = 0; X509 *x = NULL; pem_password_cb *passwd_callback; void *passwd_callback_userdata; ERR_clear_error(); /* clear error stack for * SSL_CTX_use_certificate() */ if (ctx != NULL) { passwd_callback = ctx->default_passwd_callback; passwd_callback_userdata = ctx->default_passwd_callback_userdata; } else { passwd_callback = ssl->default_passwd_callback; passwd_callback_userdata = ssl->default_passwd_callback_userdata; } in = BIO_new(BIO_s_file()); if (in == NULL) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); goto end; } x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, passwd_callback_userdata); if (x == NULL) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); goto end; } if (ctx) ret = SSL_CTX_use_certificate(ctx, x); else ret = SSL_use_certificate(ssl, x); if (ERR_peek_error() != 0) ret = 0; /* Key/certificate mismatch doesn't imply * ret==0 ... */ if (ret) { /* * If we could set up our certificate, now proceed to the CA * certificates. */ X509 *ca; int r; unsigned long err; if (ctx) r = SSL_CTX_clear_chain_certs(ctx); else r = SSL_clear_chain_certs(ssl); if (r == 0) { ret = 0; goto end; } while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback, passwd_callback_userdata)) != NULL) { if (ctx) r = SSL_CTX_add0_chain_cert(ctx, ca); else r = SSL_add0_chain_cert(ssl, ca); /* * Note that we must not free ca if it was successfully added to * the chain (while we must free the main certificate, since its * reference count is increased by SSL_CTX_use_certificate). */ if (!r) { X509_free(ca); ret = 0; goto end; } } /* When the while loop ends, it's usually just EOF. */ err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) ERR_clear_error(); else ret = 0; /* some real error */ } end: X509_free(x); BIO_free(in); return (ret); }