示例#1
0
int tls_connection_private_key(void *_ssl_ctx, struct tls_connection *conn,
			       const char *private_key,
			       const char *private_key_passwd)
{
	SSL_CTX *ssl_ctx = _ssl_ctx;
	char *passwd;

	if (private_key == NULL)
		return 0;
	if (conn == NULL)
		return -1;

	if (private_key_passwd) {
		passwd = strdup(private_key_passwd);
		if (passwd == NULL)
			return -1;
	} else
		passwd = NULL;

	SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
	SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
	if (SSL_use_PrivateKey_file(conn->ssl, private_key,
				    SSL_FILETYPE_ASN1) != 1 &&
	    SSL_use_PrivateKey_file(conn->ssl, private_key,
				    SSL_FILETYPE_PEM) != 1 &&
	    tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd)) {
		wpa_printf(MSG_INFO, "SSL: Failed to load private key: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		free(passwd);
		ERR_clear_error();
		return -1;
	}
	ERR_clear_error();
	free(passwd);
	SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
	
	if (!SSL_check_private_key(conn->ssl)) {
		wpa_printf(MSG_INFO, "SSL: Private key failed "
			   "verification: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		return -1;
	}

	return 0;
}
示例#2
0
/// loads one private key
int Certificate::loadPrivateKeyFromFile( void )
{
	const int certificateFileCheckResult = validateCertificateFilename(m_privkeyfn);
	if(certificateFileCheckResult < 0) return certificateFileCheckResult;

	m_ssl = SSL_new( SSL_CTX_new( SSLv23_method() ) );
	SSL_use_PrivateKey_file( m_ssl, m_privkeyfn.c_str(), m_type);
	return( 0 );
}
示例#3
0
static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
{
    int rv = 1;
    if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
        return -2;
    if (cctx->ctx)
        rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
    if (cctx->ssl)
        rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
    return rv > 0;
}
示例#4
0
文件: conn.c 项目: pwhelan/kannel
static int conn_init_client_ssl(Connection *ret, Octstr *certkeyfile)
{
    ret->ssl = SSL_new(global_ssl_context);

    /*
     * The current thread's error queue must be empty before
     * the TLS/SSL I/O operation is attempted, or SSL_get_error()
     * will not work reliably.
     */
    ERR_clear_error();

    if (certkeyfile != NULL) {
        SSL_use_certificate_file(ret->ssl, octstr_get_cstr(certkeyfile),
                                 SSL_FILETYPE_PEM);
        SSL_use_PrivateKey_file(ret->ssl, octstr_get_cstr(certkeyfile),
                                SSL_FILETYPE_PEM);
        if (SSL_check_private_key(ret->ssl) != 1) {
            error(0, "conn_open_ssl: private key isn't consistent with the "
                     "certificate from file %s (or failed reading the file)",
                  octstr_get_cstr(certkeyfile));
            return -1;
        }
    }

    /* SSL_set_fd can fail, so check it */
    if (SSL_set_fd(ret->ssl, ret->fd) == 0) {
        /* SSL_set_fd failed, log error */
        error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
        return -1;
    }

    /*
     * make sure the socket is non-blocking while we do SSL_connect
     */
    if (socket_set_blocking(ret->fd, 0) < 0) {
        return -1;
    }
    BIO_set_nbio(SSL_get_rbio(ret->ssl), 1);
    BIO_set_nbio(SSL_get_wbio(ret->ssl), 1);

    SSL_set_connect_state(ret->ssl);
    
    return 0;
}
示例#5
0
文件: ssl.c 项目: umegaya/pfm
DSCRPTR
nbr_ssl_accept(DSCRPTR fd, void *addr, int *alen, SKCONF *cfg)
{
	int r, ret;
	sslfd_t *sfd = nbr_array_alloc(g_ssl.socks), *afd = (sslfd_t *)fd;
	if (!sfd) {
		SSL_ERROUT(ERROR,EXPIRE,"sfd alloc fail");
		goto bad;
	}
	if ((sfd->fd = nbr_osdep_tcp_accept(afd->fd, addr, alen, cfg)) == INVALID_FD) {
		SSL_ERROUT(ERROR,ACCEPT,"ssl accept fail");
		goto bad;
	}
	if (!(sfd->ssl = SSL_new(g_ssl.server))) {
		SSL_ERROUT(ERROR,EXPIRE,"ssl new fail");
		goto bad;
	}
#if defined(_DEBUG)
	sfd->ssl->info_callback = (void (*)())ssl_info_callback;
#endif
	if (!g_ssl.pubkey || SSL_use_certificate_file(sfd->ssl, g_ssl.pubkey, SSL_FILETYPE_PEM) < 0) {
		SSL_ERROUT(ERROR,EXPIRE,"ssl SSL_use_certificate_file fail");
		goto bad;
	}
	if (!g_ssl.privkey || SSL_use_PrivateKey_file(sfd->ssl, g_ssl.privkey, SSL_FILETYPE_PEM) < 0) {
		SSL_ERROUT(ERROR,EXPIRE,"ssl SSL_use_PrivateKey_file fail");
		goto bad;
	}
	SSL_set_fd(sfd->ssl, sfd->fd);
	if ((r = SSL_accept(sfd->ssl)) <= 0) {
		ret = SSL_get_error(sfd->ssl, ret);
		if (ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE) {
			return 0;	/* connection pending */
		}
		ERR_print_errors_fp(stderr);
		SSL_ERROUT(ERROR,ACCEPT,"ssl_accept fail (%d/%d)", r, ret);
		goto bad;
	}
	return (DSCRPTR)sfd;
bad:
	ssl_free_fd(sfd);
	return INVALID_FD;
}
示例#6
0
文件: ssls.c 项目: nsauzede/netsan2
int main( int argc, char *argv[])
{
	int port = 10001;
	int n;
	int s;

	if (argc > 1)
	{
		sscanf( argv[1], "%d", &port);
	}

	SSL_library_init();
	SSL_load_error_strings();

	s = socket( PF_INET, SOCK_STREAM, 0);
	if (s != -1)
	{
		int cs;
		char buf[1024];
		struct sockaddr_in sa;
		int on;

		on = 1;
		setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof( on));
		memset( &sa, 0, sizeof( sa));
		sa.sin_family = AF_INET;
		sa.sin_port = htons( port);
		sa.sin_addr.s_addr = INADDR_ANY;
		bind( s, (struct sockaddr *)&sa, sizeof( sa));
		listen( s, 1);
		while (1)
		{
			printf( "accepting on port %d..\n", port);
			cs = accept( s, NULL, NULL);
			if (cs != -1)
			{
				SSL *ssl = 0;
				SSL_CTX *ssl_ctx = 0;

				ssl_ctx = SSL_CTX_new( SSLv23_server_method());
				if (ssl_ctx)
				{
					ssl = SSL_new( ssl_ctx);
					if (ssl)
					{
						n = SSL_use_PrivateKey_file( ssl, key_file, 1);
						if (n != 1)
							printf( "failed to SSL use key (%d, %d)\n", n, SSL_get_error( ssl, n));
						n = SSL_use_certificate_file( ssl, certificate_file, 1);
						if (n != 1)
							printf( "failed to SSL use cert (%d, %d)\n", n, SSL_get_error( ssl, n));
						if (SSL_set_fd( ssl, cs))
						{
							printf( "SSL accepting..\n");
							n = SSL_accept( ssl);
							if (n == 1)
							{
								printf( "ssl initiated\n");
								if ((n = SSL_read( ssl, buf, sizeof( buf))) > 0)
								{
									if (n > (sizeof( buf) - 1))
										n = sizeof( buf) - 1;
									buf[n] = 0;
									printf( "SSL_read %d bytes [%s]\n", n, buf);
								}
								else
									printf( "failed to SSL read\n");
							}
							else
							{
#ifdef WIN32
								unsigned long err = ERR_get_error();
								printf( "failed to SSL accept (%d, %d) (%ld, %s)\n", n, SSL_get_error( ssl, n), err, ERR_error_string( err, NULL));
#else
								printf( "failed to SSL accept (%d)\n", n);
#endif
							}
						}
						else
							printf( "failed to SSL set fd\n");
						SSL_shutdown( ssl);
					}
					else
						printf( "couldn't create server ssl\n");
					SSL_CTX_free( ssl_ctx);
				}
				else
					printf( "couldn't create server ctx\n");
				close( cs);
			}
			else
				perror( "accept");
		}
	}
	else
		perror( "socket");

	return 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;
}
示例#8
0
/** Create a new server TLS session
 *
 * Configures a new server TLS session, configuring options, setting callbacks etc...
 *
 * @param ctx		to alloc session data in. Should usually be NULL unless the lifetime of the
 *			session is tied to another talloc'd object.
 * @param conf		values for this TLS session.
 * @param request	The current #REQUEST.
 * @param client_cert	Whether to require a client_cert.
 * @return
 *	- A new session on success.
 *	- NULL on error.
 */
tls_session_t *tls_session_init_server(TALLOC_CTX *ctx, fr_tls_conf_t *conf, REQUEST *request, bool client_cert)
{
	tls_session_t	*session = NULL;
	SSL		*new_tls = NULL;
	int		verify_mode = 0;
	VALUE_PAIR	*vp;
	SSL_CTX		*ssl_ctx;

	rad_assert(request != NULL);
	rad_assert(conf->ctx_count > 0);

	RDEBUG2("Initiating new TLS session");

	ssl_ctx = conf->ctx[(conf->ctx_count == 1) ? 0 : conf->ctx_next++ % conf->ctx_count];	/* mutex not needed */
	rad_assert(ssl_ctx);

	new_tls = SSL_new(ssl_ctx);
	if (new_tls == NULL) {
		tls_log_error(request, "Error creating new TLS session");
		return NULL;
	}

	session = talloc_zero(ctx, tls_session_t);
	if (session == NULL) {
		RERROR("Error allocating memory for TLS session");
		SSL_free(new_tls);

		return NULL;
	}
	session_init(session);
	session->ctx = ssl_ctx;
	session->ssl = new_tls;

	talloc_set_destructor(session, _tls_session_free);

	/*
	 *	Initialize callbacks
	 */
	session->record_init = record_init;
	session->record_close = record_close;
	session->record_from_buff = record_from_buff;
	session->record_to_buff = record_to_buff;

	/*
	 *	Create & hook the BIOs to handle the dirty side of the
	 *	SSL.  This is *very important* as we want to handle
	 *	the transmission part.  Now the only IO interface
	 *	that SSL is aware of, is our defined BIO buffers.
	 *
	 *	This means that all SSL IO is done to/from memory,
	 *	and we can update those BIOs from the packets we've
	 *	received.
	 */
	session->into_ssl = BIO_new(BIO_s_mem());
	session->from_ssl = BIO_new(BIO_s_mem());
	SSL_set_bio(session->ssl, session->into_ssl, session->from_ssl);

	/*
	 *	Add the message callback to identify what type of
	 *	message/handshake is passed
	 */
	SSL_set_msg_callback(new_tls, tls_session_msg_cb);
	SSL_set_msg_callback_arg(new_tls, session);
	SSL_set_info_callback(new_tls, tls_session_info_cb);

	/*
	 *	This sets the context sessions can be resumed in.
	 *	This is to prevent sessions being created by one application
	 *	and used by another.  In our case it prevents sessions being
	 *	reused between modules, or TLS server components such as
	 *	RADSEC.
	 *
	 *	A context must always be set when doing session resumption
	 *	otherwise session resumption will fail.
	 *
	 *	As the context ID must be <= 32, we digest the context
	 *	data with sha256.
	 */
	rad_assert(conf->session_id_name);
	{
		char		*context_id;
		EVP_MD_CTX	*md_ctx;
		uint8_t		digest[SHA256_DIGEST_LENGTH];

		static_assert(sizeof(digest) <= SSL_MAX_SSL_SESSION_ID_LENGTH,
			      "SSL_MAX_SSL_SESSION_ID_LENGTH must be >= SHA256_DIGEST_LENGTH");

		if (tmpl_aexpand(session, &context_id, request, conf->session_id_name, NULL, NULL) < 0) {
			RPEDEBUG("Failed expanding session ID");
			talloc_free(session);
		}

		MEM(md_ctx = EVP_MD_CTX_create());
		EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
		EVP_DigestUpdate(md_ctx, context_id, talloc_array_length(context_id) - 1);
		EVP_DigestFinal_ex(md_ctx, digest, NULL);
		EVP_MD_CTX_destroy(md_ctx);
		talloc_free(context_id);

		if (!fr_cond_assert(SSL_set_session_id_context(session->ssl, digest, sizeof(digest)) == 1)) {
			talloc_free(session);
			return NULL;
		}
	}

	/*
	 *	Add the session certificate to the session.
	 */
	vp = fr_pair_find_by_da(request->control, attr_tls_session_cert_file, TAG_ANY);
	if (vp) {
		RDEBUG2("Loading TLS session certificate \"%s\"", vp->vp_strvalue);

		if (SSL_use_certificate_file(session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
			tls_log_error(request, "Failed loading TLS session certificate \"%s\"",
				      vp->vp_strvalue);
			talloc_free(session);
			return NULL;
		}

		if (SSL_use_PrivateKey_file(session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
			tls_log_error(request, "Failed loading TLS session certificate \"%s\"",
				      vp->vp_strvalue);
			talloc_free(session);
			return NULL;
		}

		if (SSL_check_private_key(session->ssl) != 1) {
			tls_log_error(request, "Failed validating TLS session certificate \"%s\"",
				      vp->vp_strvalue);
			talloc_free(session);
			return NULL;
		}
	/*
	 *	Better to perform explicit checks, than rely
	 *	on OpenSSL's opaque error messages.
	 */
	} else {
		if (!conf->chains || !conf->chains[0]->private_key_file) {
			ERROR("TLS Server requires a private key file");
			talloc_free(session);
			return NULL;
		}

		if (!conf->chains || !conf->chains[0]->certificate_file) {
			ERROR("TLS Server requires a certificate file");
			talloc_free(session);
			return NULL;
		}
	}

	/*
	 *	In Server mode we only accept.
	 *
	 *	This sets up the SSL session to work correctly with
	 *	tls_session_handhsake.
	 */
	SSL_set_accept_state(session->ssl);

	/*
	 *	Verify the peer certificate, if asked.
	 */
	if (client_cert) {
		RDEBUG2("Setting verify mode to require certificate from client");
		verify_mode = SSL_VERIFY_PEER;
		verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
		verify_mode |= SSL_VERIFY_CLIENT_ONCE;
	}
	SSL_set_verify(session->ssl, verify_mode, tls_validate_cert_cb);

	SSL_set_ex_data(session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
	SSL_set_ex_data(session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)session);

	/*
	 *	We use default fragment size, unless the Framed-MTU
	 *	tells us it's too big.  Note that we do NOT account
	 *	for the EAP-TLS headers if conf->fragment_size is
	 *	large, because that config item looks to be confusing.
	 *
	 *	i.e. it should REALLY be called MTU, and the code here
	 *	should figure out what that means for TLS fragment size.
	 *	asking the administrator to know the internal details
	 *	of EAP-TLS in order to calculate fragment sizes is
	 *	just too much.
	 */
	session->mtu = conf->fragment_size;
	vp = fr_pair_find_by_da(request->packet->vps, attr_framed_mtu, TAG_ANY);
	if (vp && (vp->vp_uint32 > 100) && (vp->vp_uint32 < session->mtu)) {
		RDEBUG2("Setting fragment_len to %u from &Framed-MTU", vp->vp_uint32);
		session->mtu = vp->vp_uint32;
	}

	if (conf->session_cache_server) session->allow_session_resumption = true; /* otherwise it's false */

	return session;
}