Ejemplo n.º 1
0
int tlsops_desc(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *res)
{
	static char buf[128];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		LM_INFO("TLS connection not found in select_desc\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	buf[0] = '\0';
	SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, 128);
	res->rs.s = buf;
	res->rs.len = strlen(buf);
	res->flags = PV_VAL_STR;

	tcpconn_put(c);

	return 0;
err:
	if (c) tcpconn_put(c);
	return pv_get_null(msg, param, res);
}
Ejemplo n.º 2
0
int tlsops_cipher(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *res)
{
	str cipher;
	static char buf[1024];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		LM_INFO("TLS connection not found in select_cipher\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	cipher.s = (char*)SSL_CIPHER_get_name(SSL_get_current_cipher(ssl));
	cipher.len = cipher.s ? strlen(cipher.s) : 0;
	if (cipher.len >= 1024) {
		LM_ERR("cipher name too long\n");
		goto err;
	}
	memcpy(buf, cipher.s, cipher.len);
	res->rs.s = buf;
	res->rs.len = cipher.len;
	res->flags = PV_VAL_STR;
	tcpconn_put(c);

	return 0;
err:
	if (c) tcpconn_put(c);
	return pv_get_null(msg, param, res);
}
Ejemplo n.º 3
0
static int get_desc(str* res, sip_msg_t* msg)
{
	static char buf[128];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		INFO("TLS connection not found in select_desc\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	buf[0] = '\0';
	SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, 128);
	res->s = buf;
	res->len = strlen(buf);
	tcpconn_put(c);
	return 0;

 err:
	if (c) tcpconn_put(c);
	return -1;	
}
Ejemplo n.º 4
0
static int get_version(str* res, sip_msg_t* msg)
{
	str version;
	static char buf[1024];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		INFO("TLS connection not found in select_version\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	version.s = (char*)SSL_get_version(ssl);
	version.len = version.s ? strlen(version.s) : 0;
	if (version.len >= 1024) {
		ERR("Version string too long\n");
		goto err;
	}
	memcpy(buf, version.s, version.len);
	res->s = buf;
	res->len = version.len;
	tcpconn_put(c);
        return 0;

 err:
	if (c) tcpconn_put(c);
	return -1;
}
Ejemplo n.º 5
0
static int get_bits(str* res, int* i, sip_msg_t* msg) 
{
	str bits;
	int b;
	static char buf[1024];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		INFO("TLS connection not found in select_bits\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	b = SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), 0);
	bits.s = int2str(b, &bits.len);
	if (bits.len >= 1024) {
		ERR("Bits string too long\n");
		goto err;
	}
	memcpy(buf, bits.s, bits.len);
	res->s = buf;
	res->len = bits.len;
	if (i) *i = b;
	tcpconn_put(c);
	return 0;

 err:
	if (c) tcpconn_put(c);
	return -1;
}
Ejemplo n.º 6
0
static int get_cipher(str* res, sip_msg_t* msg) 
{
	str cipher;
	static char buf[1024];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		INFO("TLS connection not found in select_cipher\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	cipher.s = (char*)SSL_CIPHER_get_name(SSL_get_current_cipher(ssl));
	cipher.len = cipher.s ? strlen(cipher.s) : 0;
	if (cipher.len >= 1024) {
		ERR("Cipher name too long\n");
		goto err;
	}
	memcpy(buf, cipher.s, cipher.len);
	res->s = buf;
	res->len = cipher.len;
	tcpconn_put(c);
	return 0;

 err:
	if (c) tcpconn_put(c);
	return -1;
}
Ejemplo n.º 7
0
static int get_cert(X509** cert, struct tcp_connection** c, struct sip_msg* msg, int my)
{
	SSL* ssl;

	*cert = 0;
	*c = get_cur_connection(msg);
	if (!(*c)) {
		INFO("TLS connection not found\n");
		return -1;
	}
	ssl = get_ssl(*c);
	if (!ssl) goto err;
	*cert = my ? SSL_get_certificate(ssl) : SSL_get_peer_certificate(ssl);
	if (!*cert) {
		if (my) {
			ERR("Unable to retrieve my TLS certificate from SSL structure\n");
		} else {
			ERR("Unable to retrieve peer TLS certificate from SSL structure\n");
		}
		goto err;
	}
	
	return 0;
	
 err:
	tcpconn_put(*c);
	return -1;
}
Ejemplo n.º 8
0
static int get_tlsext_sn(str* res, sip_msg_t* msg)
{
	static char buf[1024];
	struct tcp_connection* c;
	str server_name;	
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		INFO("TLS connection not found in select_desc\n");
		goto error;
	}
	ssl = get_ssl(c);
	if (!ssl) goto error;

	buf[0] = '\0';

	server_name.s = (char*)SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
	if (server_name.s) {
		server_name.len = strlen(server_name.s);
		DBG("received server_name (TLS extension): '%.*s'\n", 
			STR_FMT(&server_name));
	} else {
		DBG("SSL_get_servername returned NULL\n");
		goto error;
	}
	
	/* copy server_name into the buffer. If the buffer is too small copy only
	 * the last bytes as these are the more important ones and prefix with
	 * '+' */
	if (server_name.len > sizeof(buf)) {
		ERR("server_name to big for buffer\n");
		buf[0] = '+';
		memcpy(buf + 1, server_name.s + 1 + server_name.len - sizeof(buf), 
			   sizeof(buf) - 1);
		res->len = sizeof(buf);
	} else {
		memcpy(buf, server_name.s, server_name.len);
		res->len = server_name.len;
	}
	res->s = buf;
	
	tcpconn_put(c);
	return 0;
	
error:
	if (c) tcpconn_put(c);
	return -1;
}
Ejemplo n.º 9
0
/*
 * Check whether peer certificate exists and verify the result
 * of certificate verification
 */
int tlsops_check_cert(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *res)
{
	static str succ = str_init("1");
	static str fail = str_init("0");

	int err;
	struct tcp_connection* c;
	SSL* ssl;
	X509* cert = 0;

	switch (param->pvn.u.isname.name.n) {
	case CERT_VERIFIED:   err = X509_V_OK;                              break;
	case CERT_REVOKED:    err = X509_V_ERR_CERT_REVOKED;                break;
	case CERT_EXPIRED:    err = X509_V_ERR_CERT_HAS_EXPIRED;            break;
	case CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break;
	default:
		LM_CRIT("unexpected parameter value \"%d\"\n",
				param->pvn.u.isname.name.n);
		return pv_get_null(msg, param, res);
	}   

	c = get_cur_connection(msg);
	if (!c) return -1;

	ssl = get_ssl(c);
	if (!ssl) goto err;

	if ((cert = SSL_get_peer_certificate(ssl)) && SSL_get_verify_result(ssl) == err) {
		res->rs.s = succ.s;
		res->rs.len = succ.len;
		res->ri   = 1;
	} else {
		res->rs.s = fail.s;
		res->rs.len = fail.len;
		res->ri   = 0;
	}
	res->flags = PV_VAL_STR | PV_VAL_INT;

	if (cert) X509_free(cert);
	tcpconn_put(c);

	return 0;
err:
	if (cert) X509_free(cert);
	if (c) tcpconn_put(c);
	return pv_get_null(msg, param, res);
}
Ejemplo n.º 10
0
/*
 * Check whether peer certificate exists and verify the result
 * of certificate verification
 */
static int check_cert(str* res, int* ires, int local, int err, sip_msg_t* msg)
{
	static str succ = STR_STATIC_INIT("1");
	static str fail = STR_STATIC_INIT("0");

	struct tcp_connection* c;
	SSL* ssl;
	X509* cert = 0;

	c = get_cur_connection(msg);
	if (!c) return -1;

	ssl = get_ssl(c);
	if (!ssl) goto error;

	if (local) {
		DBG("Verification of local certificates not supported\n");
		goto error;
	} else {
		if ((cert = SSL_get_peer_certificate(ssl)) && SSL_get_verify_result(ssl) == err) {
			*res = succ;
			if (ires) *ires = 1;
		} else {
			*res = fail;
			if (ires) *ires = 0;
		}
	}

	if (cert) X509_free(cert);
	tcpconn_put(c);
	return 0;

 error:
	if (cert) X509_free(cert);
	if (c) tcpconn_put(c);
	return -1;
}
Ejemplo n.º 11
0
static inline int get_cert(X509** cert, struct tcp_connection** c,
												struct sip_msg* msg, int my)
{
	SSL* ssl;

	*cert = 0;
	*c = get_cur_connection(msg);
	if (!(*c)) {
		LM_INFO("TLS connection not found\n");
		return -1;
	}
	ssl = get_ssl(*c);
	if (!ssl) goto err;
	*cert = my ? SSL_get_certificate(ssl) : SSL_get_peer_certificate(ssl);
	if (!*cert) {
		LM_ERR("failed to get certificate from SSL structure\n");
		goto err;
	}

	return 0;
err:
	tcpconn_put(*c);
	return -1;
}
Ejemplo n.º 12
0
int tlsops_version(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *res)
{
	str version;
	static char buf[1024];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		LM_INFO("TLS connection not found in select_version\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	version.s = (char*)SSL_get_version(ssl);
	version.len = version.s ? strlen(version.s) : 0;
	if (version.len >= 1024) {
		LM_ERR("version string too long\n");
		goto err;
	}
	memcpy(buf, version.s, version.len);

	res->rs.s = buf;
	res->rs.len = version.len;
	res->flags = PV_VAL_STR;

	tcpconn_put(c);

	return 0;
err:
	if (c) tcpconn_put(c);
	return pv_get_null(msg, param, res);
}
Ejemplo n.º 13
0
int tlsops_bits(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *res)
{
	str bits;
	int b;
	static char buf[1024];

	struct tcp_connection* c;
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		LM_INFO("TLS connection not found in select_bits\n");
		goto err;
	}
	ssl = get_ssl(c);
	if (!ssl) goto err;

	b = SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), 0);
	bits.s = int2str(b, &bits.len);
	if (bits.len >= 1024) {
		LM_ERR("bits string too long\n");
		goto err;
	}
	memcpy(buf, bits.s, bits.len);
	res->rs.s = buf;
	res->rs.len = bits.len;
	res->ri = b;
	res->flags = PV_VAL_STR | PV_VAL_INT;
	tcpconn_put(c);

	return 0;
err:
	if (c) tcpconn_put(c);
	return pv_get_null(msg, param, res);
}