示例#1
0
uint8_t *
cga_key2der(EVP_PKEY *k, int *dlen)
{
	uint8_t *p;
	uint8_t *der = NULL;
	X509_PUBKEY *pki = NULL;
	
	if (X509_PUBKEY_set(&pki, k) == 0) {
		ssl_err(__FUNCTION__, "X509_PUBKEY_set() failed");
		goto done;
	}

	if ((*dlen = i2d_X509_PUBKEY(pki, NULL)) < 0) {
		ssl_err(__FUNCTION__, "i2d_PublicKey failed");
		goto done;
	}
	if ((der = malloc(*dlen)) == NULL) {
		APPLOG_NOMEM();
		goto done;
	}

	p = der;
	if (i2d_X509_PUBKEY(pki, &p) < 0) {
		ssl_err(__FUNCTION__, "i2d_PublicKey failed");
		free(der);
		der = NULL;
	}
	DBG(&dbg_asn1, "DER-encoded key is %d bytes", *dlen);

done:
	if (pki) X509_PUBKEY_free(pki);
	return (der);
}
示例#2
0
/** setup SSL context */
static SSL_CTX*
setup_ctx(struct config_file* cfg)
{
	char* s_cert, *c_key, *c_cert;
	SSL_CTX* ctx;

	s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
	c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
	c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
	if(!s_cert || !c_key || !c_cert)
		fatal_exit("out of memory");
        ctx = SSL_CTX_new(SSLv23_client_method());
	if(!ctx)
		ssl_err("could not allocate SSL_CTX pointer");
        if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2))
		ssl_err("could not set SSL_OP_NO_SSLv2");
	if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM) ||
		!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
		|| !SSL_CTX_check_private_key(ctx))
		ssl_err("Error setting up SSL_CTX client key and cert");
	if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
		ssl_err("Error setting up SSL_CTX verify, server cert");
	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

	free(s_cert);
	free(c_key);
	free(c_cert);
	return ctx;
}
示例#3
0
/** setup SSL on the connection */
static SSL*
setup_ssl(SSL_CTX* ctx, int fd)
{
	SSL* ssl;
	X509* x;
	int r;

	ssl = SSL_new(ctx);
	if(!ssl)
		ssl_err("could not SSL_new");
	SSL_set_connect_state(ssl);
	(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
	if(!SSL_set_fd(ssl, fd))
		ssl_err("could not SSL_set_fd");
	while(1) {
		ERR_clear_error();
		if( (r=SSL_do_handshake(ssl)) == 1)
			break;
		r = SSL_get_error(ssl, r);
		if(r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
			ssl_err("SSL handshake failed");
		/* wants to be called again */
	}

	/* check authenticity of server */
	if(SSL_get_verify_result(ssl) != X509_V_OK)
		ssl_err("SSL verification failed");
	x = SSL_get_peer_certificate(ssl);
	if(!x)
		ssl_err("Server presented no peer certificate");
	X509_free(x);
	return ssl;
}
示例#4
0
/** send command and display result */
static int
go_cmd(SSL* ssl, int quiet, int argc, char* argv[])
{
	char pre[10];
	const char* space=" ";
	const char* newline="\n";
	int was_error = 0, first_line = 1;
	int r, i;
	char buf[1024];
	snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
	if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0)
		ssl_err("could not SSL_write");
	for(i=0; i<argc; i++) {
		if(SSL_write(ssl, space, (int)strlen(space)) <= 0)
			ssl_err("could not SSL_write");
		if(SSL_write(ssl, argv[i], (int)strlen(argv[i])) <= 0)
			ssl_err("could not SSL_write");
	}
	if(SSL_write(ssl, newline, (int)strlen(newline)) <= 0)
		ssl_err("could not SSL_write");

	if(argc == 1 && strcmp(argv[0], "load_cache") == 0) {
		send_file(ssl, stdin, buf, sizeof(buf));
	}
	else if(argc == 1 && (strcmp(argv[0], "local_zones") == 0 ||
		strcmp(argv[0], "local_zones_remove") == 0 ||
		strcmp(argv[0], "local_datas") == 0 ||
		strcmp(argv[0], "local_datas_remove") == 0)) {
		send_file(ssl, stdin, buf, sizeof(buf));
		send_eof(ssl);
	}

	while(1) {
		ERR_clear_error();
		if((r = SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) {
			if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
				/* EOF */
				break;
			}
			ssl_err("could not SSL_read");
		}
		buf[r] = 0;
		if(first_line && strncmp(buf, "error", 5) == 0) {
			printf("%s", buf);
			was_error = 1;
		} else if (!quiet)
			printf("%s", buf);

		first_line = 0;
	}
	return was_error;
}
示例#5
0
/** send end-of-file marker to server */
static void
send_eof(SSL* ssl)
{
	char e[] = {0x04, 0x0a};
	if(SSL_write(ssl, e, (int)sizeof(e)) <= 0)
		ssl_err("could not SSL_write end-of-file marker");
}
/** read from ssl or fd, fatalexit on error, 0 EOF, 1 success */
static int
remote_read(SSL* ssl, int fd, char* buf, size_t len)
{
	if(ssl) {
		int r;
		ERR_clear_error();
		if((r = SSL_read(ssl, buf, (int)len-1)) <= 0) {
			if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
				/* EOF */
				return 0;
			}
			ssl_err("could not SSL_read");
		}
		buf[r] = 0;
	} else {
		ssize_t rr = recv(fd, buf, len-1, 0);
		if(rr <= 0) {
			if(rr == 0) {
				/* EOF */
				return 0;
			}
#ifndef USE_WINSOCK
			fatal_exit("could not recv: %s", strerror(errno));
#else
			fatal_exit("could not recv: %s", wsa_strerror(WSAGetLastError()));
#endif
		}
		buf[rr] = 0;
	}
	return 1;
}
示例#7
0
/** read from ssl or fd, fatalexit on error, 0 EOF, 1 success */
static int
remote_read(SSL* ssl, int fd, char* buf, size_t len)
{
	if(ssl) {
		int r;
		ERR_clear_error();
		if((r = SSL_read(ssl, buf, (int)len-1)) <= 0) {
			if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
				/* EOF */
				return 0;
			}
			ssl_err("could not SSL_read");
		}
		buf[r] = 0;
	} else {
		ssize_t rr = read(fd, buf, len-1);
		if(rr <= 0) {
			if(rr == 0) {
				/* EOF */
				return 0;
			}
			fprintf(stderr, "could not read: %s\n",
				strerror(errno));
			exit(1);
		}
		buf[rr] = 0;
	}
	return 1;
}
示例#8
0
/** send stdin to server */
static void
send_file(SSL* ssl, FILE* in, char* buf, size_t sz)
{
	while(fgets(buf, (int)sz, in)) {
		if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0)
			ssl_err("could not SSL_write contents");
	}
}
示例#9
0
void
ldns_err(const char* s, ldns_status err)
{
	if (err == LDNS_STATUS_SSL_ERR) {
		ssl_err(s);
	} else {
		fprintf(stderr, "%s: %s\n", s, ldns_get_errorstr_by_id(err));
		exit(EXIT_FAILURE);
	}
}
示例#10
0
/** setup SSL context */
static SSL_CTX*
setup_ctx(struct nsd_options* cfg)
{
	char* s_cert, *c_key, *c_cert;
	SSL_CTX* ctx;

	if(!options_remote_is_address(cfg))
		return NULL;
	s_cert = cfg->server_cert_file;
	c_key = cfg->control_key_file;
	c_cert = cfg->control_cert_file;

	/* filenames may be relative to zonesdir */
	if (cfg->zonesdir && cfg->zonesdir[0] &&
		(s_cert[0] != '/' || c_key[0] != '/' || c_cert[0] != '/')) {
		if(chdir(cfg->zonesdir))
			error("could not chdir to zonesdir: %s %s",
				cfg->zonesdir, strerror(errno));
	}

        ctx = SSL_CTX_new(SSLv23_client_method());
	if(!ctx)
		ssl_err("could not allocate SSL_CTX pointer");
        if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
		!= SSL_OP_NO_SSLv2)
		ssl_err("could not set SSL_OP_NO_SSLv2");
        if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
		!= SSL_OP_NO_SSLv3)
		ssl_err("could not set SSL_OP_NO_SSLv3");
	if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM))
		ssl_path_err("Error setting up SSL_CTX client cert", c_cert);
	if(!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM))
		ssl_path_err("Error setting up SSL_CTX client key", c_key);
	if(!SSL_CTX_check_private_key(ctx))
		ssl_err("Error setting up SSL_CTX client key");
	if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
		ssl_path_err("Error setting up SSL_CTX verify, server cert",
			s_cert);
	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

	return ctx;
}
示例#11
0
static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len)
{
        sslsockdata *data = conn->sockdata;
        int rc;

        rc = SSL_write (data->ssl, buf, len);
        if (rc <= 0)
                ssl_err (data, rc);

        return rc;
}
示例#12
0
/** send command and display result */
static int
go_cmd(SSL* ssl, int argc, char* argv[])
{
	const char* pre="UBCT";
	const char* space=" ";
	const char* newline="\n";
	int was_error = 0, first_line = 1;
	int r, i;
	char buf[1024];
	if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0)
		ssl_err("could not SSL_write");
	for(i=0; i<argc; i++) {
		if(SSL_write(ssl, space, (int)strlen(space)) <= 0)
			ssl_err("could not SSL_write");
		if(SSL_write(ssl, argv[i], (int)strlen(argv[i])) <= 0)
			ssl_err("could not SSL_write");
	}
	if(SSL_write(ssl, newline, (int)strlen(newline)) <= 0)
		ssl_err("could not SSL_write");

	if(argc == 1 && strcmp(argv[0], "load_cache") == 0) {
		send_file(ssl, stdin, buf, sizeof(buf));
	}

	while(1) {
		ERR_clear_error();
		if((r = SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) {
			if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
				/* EOF */
				break;
			}
			ssl_err("could not SSL_read");
		}
		buf[r] = 0;
		printf("%s", buf);
		if(first_line && strncmp(buf, "error", 5) == 0)
			was_error = 1;
		first_line = 0;
	}
	return was_error;
}
示例#13
0
static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len)
{
        sslsockdata *data = conn->sockdata;
        int rc;

        rc = SSL_read (data->ssl, buf, len);
        if (rc <= 0) {
                data->isopen = 0;
                ssl_err (data, rc);
        }

        return rc;
}
示例#14
0
/** write to ssl or fd, fatalexit on error */
static void
remote_write(SSL* ssl, int fd, const char* buf, size_t len)
{
	if(ssl) {
		if(SSL_write(ssl, buf, (int)len) <= 0)
			ssl_err("could not SSL_write");
	} else {
		if(write(fd, buf, len) < (ssize_t)len) {
			fprintf(stderr, "could not write: %s\n",
				strerror(errno));
			exit(1);
		}
	}
}
示例#15
0
/** exit with ssl error related to a file path */
static void ssl_path_err(const char* s, const char *path)
{
	unsigned long err;
	err = ERR_peek_error();
	if (ERR_GET_LIB(err) == ERR_LIB_SYS &&
		(ERR_GET_FUNC(err) == SYS_F_FOPEN ||
		 ERR_GET_FUNC(err) == SYS_F_FREAD) ) {
		fprintf(stderr, "error: %s\n%s: %s\n",
			s, path, ERR_reason_error_string(err));
		exit(1);
	} else {
		ssl_err(s);
	}
}
示例#16
0
NS_INTERNAL int tls_cl_hello(SSL *ssl) {
  int i = 0;
  struct tls_cl_hello hello;

  /* hello */
  hello.type = HANDSHAKE_CLIENT_HELLO;
  hello.len_hi = 0;
  hello.len = htobe16(sizeof(hello) - 4);
  hello.version = htobe16(0x0303);
  hello.random.time = htobe32(time(NULL));
  if (!kr_get_random(hello.random.opaque, sizeof(hello.random.opaque))) {
    ssl_err(ssl, SSL_ERROR_SYSCALL);
    return 0;
  }
  hello.sess_id_len = 0;
#if ALLOW_NULL_CIPHERS
  /* if we allow them, it's for testing reasons, so NULL comes first */
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_NULL_MD5);
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_AES_128_CBC_SHA256);
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_AES_128_CBC_SHA);
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_RC4_128_SHA);
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_RC4_128_MD5);
  hello.cipher_suite[i++] = htobe16(TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
#else
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_AES_128_CBC_SHA256);
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_AES_128_CBC_SHA);
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_RC4_128_SHA);
  hello.cipher_suite[i++] = htobe16(TLS_RSA_WITH_RC4_128_MD5);
  hello.cipher_suite[i++] = htobe16(TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
#endif
  hello.cipher_suites_len = htobe16(i * 2);
  hello.num_compressors = 1;
  hello.compressor[0] = COMPRESSOR_NULL;
  hello.ext_len = htobe16(sizeof(hello.ext_reneg));

  hello.ext_reneg.type = htobe16(EXT_RENEG_INFO);
  hello.ext_reneg.len = htobe16(1);
  hello.ext_reneg.ri_len = 0;

  if (!tls_send(ssl, TLS_HANDSHAKE, &hello, sizeof(hello))) return 0;
  SHA256_Update(&ssl->nxt->handshakes_hash, ((uint8_t *) &hello),
                sizeof(hello));

  /* store the random we generated */
  memcpy(&ssl->nxt->cl_rnd, &hello.random, sizeof(ssl->nxt->cl_rnd));

  return 1;
}
示例#17
0
/** write to ssl or fd, fatalexit on error */
static void
remote_write(SSL* ssl, int fd, const char* buf, size_t len)
{
	if(ssl) {
		if(SSL_write(ssl, buf, (int)len) <= 0)
			ssl_err("could not SSL_write");
	} else {
		if(send(fd, buf, len, 0) < (ssize_t)len) {
#ifndef USE_WINSOCK
			fatal_exit("could not send: %s", strerror(errno));
#else
			fatal_exit("could not send: %s", wsa_strerror(WSAGetLastError()));
#endif
		}
	}
}
示例#18
0
/**
 * Loads a certificate from a file and sets its key into the CGA context.
 *
 * cga: the CGA context
 * f: the file name
 *
 * returns 0 on success, -1 on failure
 */
int
cga_load_cert(cga_ctx_t *cga, const char *f)
{
	X509 *x;
	FILE *fp;
	EVP_PKEY *k;
	int r;

	if ((fp = fopen(f, "r")) == NULL) {
		DBG(&dbg_ssl, "fopen failed: %s", strerror(errno));
		return (-1);
	}

	x = PEM_read_X509(fp, NULL, NULL, NULL);
	if (x == NULL) {
		ssl_err(__FUNCTION__, "PEM_read_x509 failed");
		goto fail;
	}

	k = X509_PUBKEY_get(x->cert_info->key);

	if (cga->key && cga->free_key) {
		free(cga->key);
		cga->key = NULL;
	}
	if ((cga->key = cga_key2der(k, &cga->klen)) == NULL) {
		goto fail;
	}
	cga->free_key = 1;
	cga->key_set = 1;

	r = 0;
	goto done;

fail:
	r = -1;
	if (cga->key) free(cga->key);
	cga->key = NULL;
	cga->klen = 0;

done:
	fclose(fp);
	X509_free(x);

	return (r);
}
示例#19
0
文件: ssl.c 项目: darnir/neomutt
/**
 * ssl_socket_write - Write data to an SSL socket - Implements Connection::conn_write()
 */
static int ssl_socket_write(struct Connection *conn, const char *buf, size_t count)
{
  struct SslSockData *data = conn->sockdata;
  int rc;

  rc = SSL_write(data->ssl, buf, count);
  if ((rc <= 0) || (errno == EINTR))
  {
    if (errno == EINTR)
    {
      rc = -1;
    }
    ssl_err(data, rc);
  }

  return rc;
}
示例#20
0
int
cga_load_key(cga_ctx_t *cga, const char *f)
{
	FILE *fp;
	EVP_PKEY *k = NULL;
	int r = 0;
	int first = 1;
	struct stat sb[1];

	if (stat(f, sb)  < 0) {
		DBG(&dbg_ssl, "Could not stat file: %s\n", strerror(errno));
		return (-1);
	}
	if ((fp = fopen(f, "r")) == NULL) {
		DBG(&dbg_ssl, "Could not open file: %s\n", strerror(errno));
		return (-1);
	}

	if (cga->key && cga->free_key) {
		free(cga->key);
	}
	cga->key = NULL;
	cga->klen = 0;

	while (ftell(fp) < sb->st_size) {
		if ((k = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) {
			ssl_err(__FUNCTION__, "PEM_read_PrivateKey");
			r = -1;
			break;
		}

		if (cga_add_key(cga, k, first, CGA_MULTIKEY_EXT) < 0) {
			EVP_PKEY_free(k);
			r = -1;
			break;
		}
		first = 0;

		EVP_PKEY_free(k);
	}

	fclose(fp);
	return (r);
}
示例#21
0
/** setup SSL context */
static SSL_CTX*
setup_ctx(struct config_file* cfg)
{
	char* s_cert=NULL, *c_key=NULL, *c_cert=NULL;
	SSL_CTX* ctx;

	if(cfg->remote_control_use_cert) {
		s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
		c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
		c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
		if(!s_cert || !c_key || !c_cert)
			fatal_exit("out of memory");
	}
	ctx = SSL_CTX_new(SSLv23_client_method());
	if(!ctx)
		ssl_err("could not allocate SSL_CTX pointer");
	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
		!= SSL_OP_NO_SSLv2)
		ssl_err("could not set SSL_OP_NO_SSLv2");
	if(cfg->remote_control_use_cert) {
		if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
			!= SSL_OP_NO_SSLv3)
			ssl_err("could not set SSL_OP_NO_SSLv3");
		if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
		    !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
		    || !SSL_CTX_check_private_key(ctx))
			ssl_err("Error setting up SSL_CTX client key and cert");
		if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
			ssl_err("Error setting up SSL_CTX verify, server cert");
		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

		free(s_cert);
		free(c_key);
		free(c_cert);
	} else {
		/* Use ciphers that don't require authentication  */
#if defined(SSL_OP_NO_TLSv1_3)
		/* in openssl 1.1.1, negotiation code for tls 1.3 does
		 * not allow the unauthenticated aNULL and eNULL ciphers */
		SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3);
#endif
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
		SSL_CTX_set_security_level(ctx, 0);
#endif
		if(!SSL_CTX_set_cipher_list(ctx, "aNULL:eNULL"))
			ssl_err("Error setting NULL cipher!");
	}
	return ctx;
}
示例#22
0
/** setup SSL context */
static SSL_CTX*
setup_ctx(struct config_file* cfg)
{
	char* s_cert=NULL, *c_key=NULL, *c_cert=NULL;
	SSL_CTX* ctx;

	if(cfg->remote_control_use_cert) {
		s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
		c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
		c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
		if(!s_cert || !c_key || !c_cert)
			fatal_exit("out of memory");
	}
        ctx = SSL_CTX_new(SSLv23_client_method());
	if(!ctx)
		ssl_err("could not allocate SSL_CTX pointer");
        if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
		!= SSL_OP_NO_SSLv2)
		ssl_err("could not set SSL_OP_NO_SSLv2");
        if(cfg->remote_control_use_cert) {
		if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
			!= SSL_OP_NO_SSLv3)
			ssl_err("could not set SSL_OP_NO_SSLv3");
		if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
		    !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
		    || !SSL_CTX_check_private_key(ctx))
			ssl_err("Error setting up SSL_CTX client key and cert");
		if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
			ssl_err("Error setting up SSL_CTX verify, server cert");
		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

		free(s_cert);
		free(c_key);
		free(c_cert);
	} else {
		/* Use ciphers that don't require authentication  */
		if(!SSL_CTX_set_cipher_list(ctx, "aNULL"))
			ssl_err("Error setting NULL cipher!");
	}
	return ctx;
}