Skip to content

Commit

Permalink
stir_shaken: add ability to skip Date header checks when verifying
Browse files Browse the repository at this point in the history
Add a new "require_date_hdr" modparam that controls whether the Date
header is mandatory when verifying.
  • Loading branch information
rvlad-patrascu committed Aug 12, 2021
1 parent 35f55f1 commit 736ad5c
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 30 deletions.
41 changes: 37 additions & 4 deletions modules/stir_shaken/doc/stir_shaken_admin.xml
Expand Up @@ -66,13 +66,18 @@ modparam("stir_shaken", "auth_date_freshness", 300)
<section id="param_verify_date_freshness" xreflabel="verify_date_freshness">
<title><varname>verify_date_freshness</varname> (integer)</title>
<para>
The maximum number of seconds that the value in the Date header field
can be older than the current time. Also, if the <emphasis>iat</emphasis>
value in the PASSporT is different than the Date value, but remains within
this interval, it will be used in the verification process (for the
The maximum number of seconds that the value in the Date header field can be
older than the current time. Also, if the <emphasis>iat</emphasis> value in
the PASSporT is different than the Date value, but remains within the
permitted interval, it will be used in the verification process (for the
reconstructed PASSporT) instead of the Date value.
</para>
<para>
If the <xref linkend="param_require_date_hdr"/> parameter is set to not
required and the Date header is missing, the <emphasis>iat</emphasis> value
will be used for this check instead.
</para>
<para>
This parameter is only relevant for the
<xref linkend="func_stir_shaken_verify"/> function.
</para>
Expand Down Expand Up @@ -172,6 +177,34 @@ modparam("stir_shaken", "crl_dir", "/stir_certs/crls")
...
modparam("stir_shaken", "e164_strict_mode", 1)
...
</programlisting>
</example>
</section>

<section id="param_require_date_hdr" xreflabel="require_date_hdr">
<title><varname>require_date_hdr</varname> (integer)</title>
<para>
Specifies whether the Date header is mandatory when doing verification
with the <xref linkend="func_stir_shaken_verify"/> function.
</para>
<para>
A value of <emphasis>1</emphasis> means required and <emphasis>0</emphasis>
not required.
</para>
<para>
If the parameter is set to not required but the header is present in the
message, the Date value will be used as normally to check the freshness (as
configured in the <xref linkend="param_verify_date_freshness"/>
parameter). If the Date header is indeed missing, the value of the
<emphasis>iat</emphasis> claim in the PASSporT will be used instead.
</para>
<para>The default value is <emphasis>1</emphasis> (required).</para>
<example>
<title>Set <varname>require_date_hdr</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("stir_shaken", "require_date_hdr", 0)
...
</programlisting>
</example>
</section>
Expand Down
78 changes: 52 additions & 26 deletions modules/stir_shaken/stir_shaken.c
Expand Up @@ -105,6 +105,8 @@ static char *crl_dir;

static int e164_strict_mode;

static int require_date_hdr = 1;

static int tn_authlist_nid;

static int parsed_ctx_idx =-1;
Expand All @@ -119,6 +121,7 @@ static param_export_t params[] = {
{"crl_list", STR_PARAM, &crl_list},
{"crl_dir", STR_PARAM, &crl_dir},
{"e164_strict_mode", INT_PARAM, &e164_strict_mode},
{"require_date_hdr", INT_PARAM, &require_date_hdr},
{0, 0, 0}
};

Expand Down Expand Up @@ -1756,32 +1759,46 @@ static int w_stir_verify(struct sip_msg *msg, str *cert_buf,
}

date_hf = get_header_by_static_name(msg, "Date");
if (!date_hf) {
LM_NOTICE("No Date header found\n");
SET_VERIFY_ERR_VARS(BADREQ_CODE, BADREQ_NODATE_REASON);
rc = -2;
goto error;
}

if (get_date_ts(date_hf, &date_ts) < 0) {
LM_ERR("Failed to get UNIX time from Date header\n");
SET_VERIFY_ERR_VARS(IERROR_CODE, IERROR_REASON);
rc = -1;
goto error;
}

if ((now = time(0)) == -1) {
LM_ERR("Failed to get current time\n");
SET_VERIFY_ERR_VARS(IERROR_CODE, IERROR_REASON);
rc = -1;
goto error;
}
if (now - date_ts > verify_date_freshness) {
LM_NOTICE("Date header value is older than local policy (%lds > %ds)\n",
now - date_ts, verify_date_freshness);
SET_VERIFY_ERR_VARS(STALE_DATE_CODE, STALE_DATE_REASON);
rc = -6;
goto error;

iat_ts = (time_t)parsed->iat->valuedouble;

if (require_date_hdr || date_hf) {
if (!date_hf) {
LM_NOTICE("No Date header found\n");
SET_VERIFY_ERR_VARS(BADREQ_CODE, BADREQ_NODATE_REASON);
rc = -2;
goto error;
}

if (get_date_ts(date_hf, &date_ts) < 0) {
LM_ERR("Failed to get UNIX time from Date header\n");
SET_VERIFY_ERR_VARS(IERROR_CODE, IERROR_REASON);
rc = -1;
goto error;
}

if (now - date_ts > verify_date_freshness) {
LM_NOTICE("Date header value is older than local policy (%lds > %ds)\n",
now - date_ts, verify_date_freshness);
SET_VERIFY_ERR_VARS(STALE_DATE_CODE, STALE_DATE_REASON);
rc = -6;
goto error;
}
} else {
if (now - iat_ts > verify_date_freshness) {
LM_NOTICE("'iat' value is older than local policy (%lds > %ds)\n",
now - iat_ts, verify_date_freshness);
SET_VERIFY_ERR_VARS(STALE_DATE_CODE, STALE_DATE_REASON);
rc = -6;
goto error;
}
}

/* if the identities in the PASSporT and SIP message are different
Expand Down Expand Up @@ -1815,11 +1832,20 @@ static int w_stir_verify(struct sip_msg *msg, str *cert_buf,
goto error;
}

if (!check_cert_validity(&date_ts, cert)) {
LM_INFO("The Date header does not fall within the certificate validity\n");
SET_VERIFY_ERR_VARS(STALE_DATE_CODE, STALE_DATE_REASON);
rc = -7;
goto error;
if (require_date_hdr || date_hf) {
if (!check_cert_validity(&date_ts, cert)) {
LM_INFO("The Date header does not fall within the certificate validity\n");
SET_VERIFY_ERR_VARS(STALE_DATE_CODE, STALE_DATE_REASON);
rc = -7;
goto error;
}
} else {
if (!check_cert_validity(&iat_ts, cert)) {
LM_INFO("The 'iat' value does not fall within the certificate validity\n");
SET_VERIFY_ERR_VARS(STALE_DATE_CODE, STALE_DATE_REASON);
rc = -7;
goto error;
}
}

if ((rc = validate_certificate(cert, certchain)) < 0) {
Expand All @@ -1834,8 +1860,8 @@ static int w_stir_verify(struct sip_msg *msg, str *cert_buf,
}
}

iat_ts = (time_t)parsed->iat->valuedouble;
if (iat_ts != date_ts && (now - iat_ts > verify_date_freshness))
if (date_hf && iat_ts != date_ts &&
(now - iat_ts > verify_date_freshness))
iat_ts = date_ts;

if ((rc = verify_signature(cert, parsed, iat_ts, orig_tn_p, dest_tn_p)) <= 0) {
Expand Down

0 comments on commit 736ad5c

Please sign in to comment.