Пример #1
0
/*
   allocates a new ssl object

   SYNOPSIS
     my_ssl_init
       mysql     connection object

   RETURN VALUES
     NULL on error
     SSL  new SSL object
*/
SSL *my_ssl_init(MYSQL *mysql)
{
  int verify;
  SSL *ssl= NULL;

  DBUG_ENTER("my_ssl_init");

  DBUG_ASSERT(mysql->net.vio->ssl == NULL);

  if (!my_ssl_initialized)
    my_ssl_start(mysql); 

  if (!(ssl= SSL_new(SSL_context)))
    goto error;

  if (!SSL_set_app_data(ssl, mysql))
    goto error;
  if (my_ssl_set_certs(ssl))
    goto error;

  verify= (!mysql->options.ssl_ca && !mysql->options.ssl_capath) ?
           SSL_VERIFY_NONE : SSL_VERIFY_PEER;
  SSL_set_verify(ssl, verify, my_verify_callback);
  SSL_set_verify_depth(ssl, 1);

  DBUG_RETURN(ssl);
error:
  if (ssl)
    SSL_free(ssl);
  DBUG_RETURN(NULL);
} 
Пример #2
0
int dtls_flow_start(struct dtls_flow *flow, const struct sa *peer, bool active)
{
	int r, err = 0;

	if (!flow || !peer)
		return EINVAL;

	flow->peer = *peer;

	if (active) {
		r = SSL_connect(flow->ssl);
		if (r < 0) {
			int ssl_err = SSL_get_error(flow->ssl, r);

			ERR_clear_error();

			if (ssl_err != SSL_ERROR_WANT_READ) {
				warning("dtls: SSL_connect() failed"
					" (err=%d)\n", ssl_err);
			}
		}

		check_timer(flow);
	}
	else {
		SSL_set_accept_state(flow->ssl);

		SSL_set_verify_depth(flow->ssl, 0);
		SSL_set_verify(flow->ssl,
			       SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
			       verify_callback);
	}

	return err;
}
Пример #3
0
void SecuredServerSession::verifyPeer(const std::string &caFile)
{
    if (!caFile.empty()) {
        auto certs = SSL_load_client_CA_file(caFile.c_str());
        if (!certs)
            throw std::runtime_error(ERR_error_string(ERR_get_error(), nullptr));
        SSL_set_client_CA_list(m_SSL, certs);
    }
    SSL_set_verify(m_SSL, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, &verify_callback);
    SSL_set_verify_depth(m_SSL, 10);
    m_renegotiate = true;
}
Пример #4
0
CWBool CWSecurityInitSessionClient(CWSocket sock, CWNetworkLev4Address *addrPtr, CWSafeList packetReceiveList, CWSecurityContext ctx, CWSecuritySession *sessionPtr, int *PMTUPtr) {
	BIO *sbio = NULL;
	CWNetworkLev4Address peer;
	int peerlen = sizeof(peer);
	int i;

	if(ctx == NULL || sessionPtr == NULL || PMTUPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);
	
	if((*sessionPtr = SSL_new(ctx)) == NULL) {
		CWSecurityRaiseError(CW_ERROR_CREATING);
	}
	
	#ifdef CW_DEBUGGING
		CWDebugLog("My Certificate");
		PEM_write_X509(stdout, SSL_get_certificate(*sessionPtr));
	#endif
	
    if((sbio = BIO_new_memory(sock, addrPtr, packetReceiveList)) == NULL) {
		SSL_free(*sessionPtr);
		CWSecurityRaiseError(CW_ERROR_CREATING);
	}

	if (getsockname(sock, (struct sockaddr*)&peer, (void *)&peerlen) < 0) {
		SSL_free(*sessionPtr);
		CWSecurityRaiseSystemError(CW_ERROR_GENERAL);
	}
	
	i = BIO_ctrl_set_connected(sbio, 1, &peer);
	
	//BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); // TO-DO (pass MTU?)
	BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_MTU, 10000, NULL); // TO-DO if we don't set a big MTU, thw DTLS implementation will
														 // not be able to use a big certificate 
	

	// Let the verify_callback catch the verify_depth error so that we get
	// an appropriate error in the logfile.
	SSL_set_verify_depth((*sessionPtr), CW_DTLS_CERT_VERIFY_DEPTH + 1);

    SSL_set_read_ahead( (*sessionPtr), 1); // required by DTLS implementation to avoid data loss
	
    SSL_set_bio((*sessionPtr), sbio, sbio);
	SSL_set_connect_state((*sessionPtr));
	
	CWDebugLog("Before HS");
	CWSecurityManageSSLError(
			SSL_do_handshake(*sessionPtr), *sessionPtr, SSL_free(*sessionPtr););
Пример #5
0
static int openssl_ssl_set(lua_State*L)
{
  SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl");
  int i;
  int top = lua_gettop(L);
  int ret = 1;
  for (i = 2; i <= top; i += 2)
  {
    const char* what = luaL_checklstring(L, i, NULL);
    if (strcmp(what, "fd") == 0)
    {
      ret = SSL_set_fd(s, luaL_checkint(L, i + 1));
    }
    else if (strcmp(what, "rfd") == 0)
    {
      ret = SSL_set_wfd(s, luaL_checkint(L, i + 1));
    }
    else if (strcmp(what, "wfd") == 0)
    {
      ret = SSL_set_wfd(s, luaL_checkint(L, i + 1));
    }
    else if (strcmp(what, "client_CA") == 0)
    {
      X509* x = CHECK_OBJECT(i + 1, X509, "openssl.x509");
      ret = SSL_add_client_CA(s, x);
    }
    else if (strcmp(what, "read_ahead") == 0)
    {
      int yes = auxiliar_checkboolean(L, i + 1);
      SSL_set_read_ahead(s, yes);
    }
    else if (strcmp(what, "cipher_list") == 0)
    {
      const char* list = lua_tostring(L, i + 1);
      ret = SSL_set_cipher_list(s, list);
    }
    else if (strcmp(what, "verify_depth") == 0)
    {
      int depth = luaL_checkint(L, i + 1);
      SSL_set_verify_depth(s, depth);
    }

    else if (strcmp(what, "purpose") == 0)
    {
      //FIX
      int purpose = luaL_checkint(L, i + 1);
      ret = SSL_set_purpose(s, purpose);
    }
    else if (strcmp(what, "trust") == 0)
    {
      //FIX
      int trust = luaL_checkint(L, i + 1);
      ret = SSL_set_trust(s, trust);
    }
    else if (strcmp(what, "verify_result") == 0)
    {
      int result = luaL_checkint(L, i + 1);
      SSL_set_verify_result(s, result);
    }
    else if (strcmp(what, "hostname") == 0)
    {
      const char* hostname = luaL_checkstring(L, i + 1);
      SSL_set_tlsext_host_name(s, hostname);
    }

#if OPENSSL_VERSION_NUMBER > 0x10000000L
    else if (strcmp(what, "state") == 0)
    {
      int l = luaL_checkint(L, 2);
      SSL_set_state(s, l);
    }
#endif
    else
      luaL_argerror(L, i, "don't understand");

    if (ret != 1)
      return openssl_pushresult(L, ret);
  }
  return 0;
}
Пример #6
0
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;
}
Пример #7
0
/* Switch a socket to SSL communication
 *
 * Creates a SSL data structure for the connection;
 * Sets up callbacks and initiates a SSL handshake with the peer;
 * Reports error conditions and performs cleanup upon failure.
 *
 * flags: ssl flags, i.e connect or listen
 * verify: peer certificate verification flags
 * loglevel: is the level to output information about the connection
 * and certificates.
 * host: contains the dns name or ip address of the peer. Used for
 * verification.
 * cb: optional callback, this function will be called after the
 * handshake completes.
 *
 * Return value: 0 on success, !=0 on failure.
 */
int ssl_handshake(int sock, int flags, int verify, int loglevel, char *host,
                  IntFunc cb)
{
  int i, err, ret;
  ssl_appdata *data;
  struct threaddata *td = threaddata();

  debug0("TLS: attempting SSL negotiation...");
  if (!ssl_ctx && ssl_init()) {
    debug0("TLS: Failed. OpenSSL not initialized properly.");
    return -1;
  }
  /* find the socket in the list */
  i = findsock(sock);
  if (i == -1) {
    debug0("TLS: socket not in socklist");
    return -2;
  }
  if (td->socklist[i].ssl) {
    debug0("TLS: handshake not required - SSL session already established");
    return 0;
  }
  td->socklist[i].ssl = SSL_new(ssl_ctx);
  if (!td->socklist[i].ssl ||
      !SSL_set_fd(td->socklist[i].ssl, td->socklist[i].sock)) {
    debug1("TLS: cannot initiate SSL session - %s",
           ERR_error_string(ERR_get_error(), 0));
    return -3;
  }

  /* Prepare a ssl appdata struct for the verify callback */
  data = nmalloc(sizeof(ssl_appdata));
  egg_bzero(data, sizeof(ssl_appdata));
  data->flags = flags & (TLS_LISTEN | TLS_CONNECT);
  data->verify = flags & ~(TLS_LISTEN | TLS_CONNECT);
  data->loglevel = loglevel;
  data->cb = cb;
  strncpyz(data->host, host ? host : "", sizeof(data->host));
  SSL_set_app_data(td->socklist[i].ssl, data);
  SSL_set_info_callback(td->socklist[i].ssl, (void *) ssl_info);
  /* We set this +1 to be able to report extra long chains properly.
   * Otherwise, OpenSSL will break the verification reporting about
   * missing certificates instead. The rest of the fix is in
   * ssl_verify()
   */
  SSL_set_verify_depth(td->socklist[i].ssl, tls_maxdepth + 1);

  SSL_set_mode(td->socklist[i].ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
               SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  if (data->flags & TLS_CONNECT) {
    SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);
    ret = SSL_connect(td->socklist[i].ssl);
    if (!ret)
      debug0("TLS: connect handshake failed.");
  } else {
    if (data->flags & TLS_VERIFYPEER)
      SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER |
                     SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify);
    else
      SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);
    ret = SSL_accept(td->socklist[i].ssl);
    if (!ret)
      debug0("TLS: accept handshake failed");
  }

  err = SSL_get_error(td->socklist[i].ssl, ret);
  /* Normal condition for async I/O, similar to EAGAIN */
  if (ret > 0 || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
    debug0("TLS: handshake in progress");
    return 0;
  }
  if (ERR_peek_error())
    debug0("TLS: handshake failed due to the following errors: ");
  while ((err = ERR_get_error()))
    debug1("TLS: %s", ERR_error_string(err, NULL));

  /* Attempt failed, cleanup and abort */
  SSL_shutdown(td->socklist[i].ssl);
  SSL_free(td->socklist[i].ssl);
  td->socklist[i].ssl = NULL;
  nfree(data);
  return -4;
}
SSL* SDMMD_lockssl_handshake(SDMMD_lockdown_conn *lockdown_conn, CFTypeRef hostCert, CFTypeRef deviceCert, CFTypeRef hostPrivKey, uint32_t num) {
	SSL *ssl = NULL;
	SSL_CTX *sslCTX = NULL;
	sdmmd_return_t result = 0x0;
	BIO_METHOD *bioMethod = BIO_s_socket();
	BIO *bioSocket = BIO_new(bioMethod);
	if (bioSocket) {
		BIO_set_fd(bioSocket, lockdown_conn->connection, 0);
		X509 *cert = SDMMD__decode_certificate(hostCert);
		if (cert == 0) {
			printf("_create_ssl_context: Could not certificate.\n");
		}
		RSA *rsa = NULL;
		BIO *dataBIO = SDMMD__create_bio_from_data(hostPrivKey);
		if (dataBIO == 0) {
			printf("_create_ssl_context: Could not decode host private key.\n");
			if (cert) {
				X509_free(cert);
				result = 0x0;
			}
		} else {
			PEM_read_bio_RSAPrivateKey(dataBIO, &rsa, 0x0, 0x0);
			BIO_free(dataBIO);
			if (rsa) {
				if (hostCert) {
					sslCTX = SSL_CTX_new(SSLv3_method());
					if (sslCTX) {
						result = SSL_CTX_use_certificate(sslCTX, cert);
						if (result == 0)
							printf("_create_ssl_context: Could not set certificate.\n");
						result = SSL_CTX_use_RSAPrivateKey(sslCTX, rsa);
						if (result == 0)
							printf("_create_ssl_context: Could not set private key.\n");
					} else {
						printf("_create_ssl_context: Could not create SSLv3 context.\n");
					}
				}
				RSA_free(rsa);
				if (cert)
					X509_free(cert);
				if (sslCTX) {
					ssl = SSL_new(sslCTX);
					if (ssl) {
						if (num) {
							SSL_set_connect_state(ssl);
						} else {
							SSL_set_accept_state(ssl);
						}
						SSL_set_verify(ssl, 0x3, SDMMD__ssl_verify_callback);
						SSL_set_verify_depth(ssl, 0x0);
						SSL_set_bio(ssl, bioSocket, bioSocket);
						SSL_set_ex_data(ssl, SDMMobileDevice->peer_certificate_data_index, (void*)deviceCert);
						result = SSL_do_handshake(ssl);
						if (result == 1) {
							SSL_CTX_free(sslCTX);
						} else {
							uint32_t err = SSL_get_error(ssl, result);
							if (err) {
								char *reason = SDMMD_ssl_strerror(ssl, err);
								printf("lockssl_handshake: SSL handshake fatal lower level error %d: %s.\n", err, reason);
							} else {
								char *reason = SDMMD_ssl_strerror(ssl, 0x0);
								printf("lockssl_handshake: SSL handshake controlled failure %d: %s.\n", err, reason);
							}
							SSL_free(ssl);
						}
					} else {
						printf("_create_ssl: Could not create SSL thing.\n");
					}
				}
			} else {
				printf("_create_ssl_context: Could not decode private key.\n");
				if (cert) {
					X509_free(cert);
					result = 0x0;
				}
			}
		}
	} else {
		printf("lockssl_handshake: Could not create SSL bio.\n");
	}
	return ssl;
}