Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sip/transp: add client certificate to all TLS transports #1173

Merged
merged 1 commit into from
Aug 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 64 additions & 23 deletions src/sip/transp.c
Original file line number Diff line number Diff line change
@@ -47,6 +47,12 @@ struct sip_ccert {
};


struct sip_ccert_data {
uint32_t hsup;
struct sip_ccert *ccert;
};


struct sip_transport {
struct le le;
struct sa laddr;
@@ -191,6 +197,31 @@ static const struct sip_transport *transp_find(struct sip *sip,
}


static struct le *transp_apply_all(struct sip *sip, enum sip_transp tp, int af,
list_apply_h ah, void *arg)
{
if (!ah)
return NULL;

for (struct le *le = sip->transpl.head; le; le = le->next) {

const struct sip_transport *transp = le->data;
const struct sa *laddr = &transp->laddr;

if (transp->tp != tp)
continue;

if (af != AF_UNSPEC && sa_af(laddr) != af)
continue;

if (ah(le, arg))
return le;
}

return NULL;
}


static struct sip_conn *conn_find(struct sip *sip, const struct sa *paddr,
bool secure)
{
@@ -1401,6 +1432,27 @@ int sip_transp_add_websock(struct sip *sip, enum sip_transp tp,
}


static bool add_ccert_handler(struct le *le, void *arg)
{
const struct sip_transport *transp = le->data;
struct sip_ccert_data *cc = arg;

if (!cc->ccert->he.list)
hash_append(transp->ht_ccert, cc->hsup, &cc->ccert->he,
cc->ccert);
else {
struct sip_ccert *ccert = mem_zalloc(sizeof(*ccert), NULL);
if (!ccert)
return false;

ccert->file = cc->ccert->file;
hash_append(transp->ht_ccert, cc->hsup, &ccert->he, ccert);
}

return false;
}


/**
* Add a client certificate to the TLS transport object
* Client certificates are saved as hash-table.
@@ -1416,10 +1468,9 @@ int sip_transp_add_ccert(struct sip *sip, const struct uri *uri,
const char *cert)
{
int err = 0;
const struct sip_transport *transp = NULL;
struct sip_ccert *ccert = NULL;
struct sip_ccert_data cc_data;
struct mbuf *sup = NULL;
uint32_t hsup = 0;

if (!sip || !uri || !cert)
return EINVAL;
@@ -1435,30 +1486,20 @@ int sip_transp_add_ccert(struct sip *sip, const struct uri *uri,

mbuf_set_pos(sup, 0);

hsup = hash_joaat(mbuf_buf(sup), mbuf_get_left(sup));
transp = transp_find(sip, SIP_TRANSP_TLS, AF_INET, NULL);
if (transp) {
ccert = mem_zalloc(sizeof(*ccert), NULL);
if (!ccert) {
err = ENOMEM;
goto out;
}

pl_set_str(&ccert->file, cert);
hash_append(transp->ht_ccert, hsup, &ccert->he, ccert);
ccert = mem_zalloc(sizeof(*ccert), NULL);
if (!ccert) {
err = ENOMEM;
goto out;
}
pl_set_str(&ccert->file, cert);

transp = transp_find(sip, SIP_TRANSP_TLS, AF_INET6, NULL);
if (transp) {
ccert = mem_zalloc(sizeof(*ccert), NULL);
if (!ccert) {
err = ENOMEM;
goto out;
}
cc_data.hsup = hash_joaat(mbuf_buf(sup), mbuf_get_left(sup));
cc_data.ccert = ccert;

pl_set_str(&ccert->file, cert);
hash_append(transp->ht_ccert, hsup, &ccert->he, ccert);
}
(void)transp_apply_all(sip, SIP_TRANSP_TLS, AF_INET, add_ccert_handler,
&cc_data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about WSS transport ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to change the behavior as little as possible. Before this change, the sip_transp_add_ccert function did not consider WSS either and when adding the WSS transport with sip_transp_add_websock, the hash table for the certs is not even allocated.

It would probably make sense, but maybe add that support in a different PR.

(void)transp_apply_all(sip, SIP_TRANSP_TLS, AF_INET6,
add_ccert_handler, &cc_data);

out:
mem_deref(sup);