<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;

]>
<!-- Module User's Guide -->

<chapter>

	<title>&adminguide;</title>

	<section>
	<title>Overview</title>
	<para>
		This module provides various cryptography tools for use
		in &kamailio; configuration file. For compatibility with
		existing crypto libraries its internal operation mode can
		be configured as well. This allows the module to be used
		e.g. with existing Java applications or PostgreSQL DB
		functions.
	</para>
	<para>
		It relies on OpenSSL libraries for cryptographic operations
		(libssl, libcrypto).
	</para>
	</section>

	<section>
	<title>Dependencies</title>
	<section>
		<title>&kamailio; Modules</title>
		<para>
		The following modules must be loaded before this module:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>none</emphasis>.
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>
	<section>
		<title>External Libraries or Applications</title>
		<para>
		The following libraries or applications must be installed before running
		&kamailio; with this module loaded:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>libcrypto</emphasis> - part of OpenSSL project
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>
	</section>

	<section>
	<title>Parameters</title>
	<section id="crypto.p.salt">
		<title><varname>salt</varname> (str)</title>
		<para>
			A keyword to generate salt for encryption. It must be
			at least 8 chars long. If set to empty, no salt is used
			for encryption.
		</para>
		<para>
			The salt is a binary array that is appended to the encryption
			password for better protection against dictionary attacks. Same
			salt and password need to be used when encrypting and decrypting.
		</para>
		<para>
		<emphasis>
			Default value is "..." (see code).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>salt</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("crypto", "salt", "l0Bh2M8a")
...
</programlisting>
		</example>
	</section>
	<section id="crypto.p.register_callid">
		<title><varname>register_callid</varname> (int)</title>
		<para>
			Set it to 1 in order to register a callback to core for generation
			of callid values for requests generated by &kamailio; tm module.
		</para>
		<para>
			This callid generator uses libssl random and hashing functions
			for generating RFC 4122 version 4 UUID with high quality entropy.
			It is useful when wanting to have new callids that cannot be
			predicted from previous values.
		</para>
		<para>
		<emphasis>
			Default value is 0.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>register_callid</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("crypto", "register_callid", 1)
...
</programlisting>
		</example>
	</section>
	<section id="crypto.p.register_evcb">
		<title><varname>register_evcb</varname> (int)</title>
		<para>
			Set it to 1 in order to register the event route callbacks, in
			case AES encryption/decryption of SIP traffic is wanted. The
			event_route[crypto:netio] or corresponding KEMI callback are
			executed.
		</para>
		<para>
		<emphasis>
			Default value is 0.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>register_evcb</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("crypto", "register_evcb", 1)
...
</programlisting>
		</example>
	</section>
	<section id="crypto.p.kevcb_netio">
		<title><varname>kevcb_netio</varname> (str)</title>
		<para>
			Name of the KEMI callback function for netio events. It receives a
			string parameter with event route name.
		</para>
		<para>
		<emphasis>
			Default value is not set.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>kevcb_netio</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("crypto", "kevcb_netio", "ksr_crypto_netio")
...
function ksr_crypto_netio(evname)
  ...
end
...
</programlisting>
		</example>
	</section>
	<section id="crypto.p.netio_key">
		<title><varname>netio_key</varname> (str)</title>
		<para>
			The shared secret used to encrypt/decrypt network traffic.
		</para>
		<para>
		<emphasis>
			Default value is not set.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>netio_key</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("crypto", "netio_key", "strong-password-here")
...
</programlisting>
		</example>
	</section>
	<section id="crypto.p.key_derivation">
		<title><varname>key_derivation</varname> (str)</title>
		<para>
			Specify if the module should use an internal derivation function
			to generate the initialization vector for encryption operations.
			This is the default mode. If set to 0 the initialization vector
			will be generated randomly or read from the configuration file.
		</para>
		<para>
			The source of the initialization vector is configured with the
			<emphasis>init_vector</emphasis> parameter.
		</para>
		<para>
		<emphasis>
			Default value is 1 - generate the initialization vector internally
		</emphasis>
		</para>
		<example>
		<title>Set <varname>key_derivation</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("crypto", "key_derivation", 0)
...
</programlisting>
		</example>
	</section>
	<section id="crypto.p.init_vector">
		<title><varname>init_vector</varname> (str)</title>
		<para>
			The initialization vector used for the cryptographic operations.
			This needs to be a Base64 encoded value with 16 bytes lengths.
		</para>
		<para>
			If this parameter is not set and the <emphasis>key_derivation
			</emphasis> parameter is also set to 0, the module will create
			a random initialization vector for decryption operations. For
			encryption operations the initialization vector will be read
			from the first 16 bytes of the cipher text.
		</para>
		<para>
		<emphasis>
			Default value is not set.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>init_vector</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("crypto", "init_vector", "MTIzNDU2Nzg5MTIzNDU2Nw==")
...
</programlisting>
		</example>
	</section>

	</section>

	<section>
	<title>Functions</title>
	<section id="async.f.crypto_aes_encrypt">
	    <title>
		<function moreinfo="none">crypto_aes_encrypt(text, key, res)</function>
	    </title>
	    <para>
		Encrypts the text with the key using AES encryption algorithm. The
		result is encoded in base64 format and stored in res. The parameter
		res must be a read-write variables. The parameters text and key can
		be static strings or strings with variables (dynamic strings).
		</para>
		<para>
		This function can be used from ANY_ROUTE.
		</para>
		<example>
		<title><function>crypto_aes_encrypt</function> usage</title>
		<programlisting format="linespecific">
...
crypto_aes_encrypt("$rb", "my-secret-key", "$var(encrypted)");
...
</programlisting>
	    </example>
	</section>

	<section id="async.f.crypto_aes_decrypt">
	    <title>
		<function moreinfo="none">crypto_aes_decrypt(text, key, res)</function>
	    </title>
	    <para>
		Decrypts the text with the key using AES encryption algorithm. The
		text has to be encoded in base64 format. The parameter
		res must be a read-write variables. The parameters text and key can
		be static strings or strings with variables (dynamic strings).
		</para>
		<para>
		This function can be used from ANY_ROUTE.
		</para>
		<example>
		<title><function>crypto_aes_decrypt</function> usage</title>
		<programlisting format="linespecific">
...
crypto_aes_decrypt("$var(encrypted)", "my-secret-key", "$var(text)");
...
</programlisting>
	    </example>
	</section>

	<section id="async.f.crypto_hmac_sha256">
		<title>
			<function moreinfo="none">crypto_hmac_sha256(text, key, res)</function>
		</title>
		<para>
			Calculates HMAC (keyed-hash message authentication code) with SHA256
			as a cryptographic hash function. The result is encoded in base64 url
			encoded format and stored in res. The parameter res must be a read-write
			variable. The parameters text and key can be static strings or strings
			with variables (dynamic strings).
		</para>
		<para>
		This function can be used from ANY_ROUTE.
		</para>
		<example>
			<title><function>crypto_hmac_sha256</function> usage</title>
			<programlisting format="linespecific">
...
crypto_hmac_sha256("$var(text)", "my-secret-key", "$var(hmac)");
...
</programlisting>
		</example>
	</section>
	
	<section id="async.f.crypto_netio_in">
	    <title>
		<function moreinfo="none">crypto_netio_in)</function>
	    </title>
	    <para>
		Return 1 (true) if it is an incoming net message, or -1 (false) otherwise.
		</para>
		<para>
		This function can be used from EVENT_ROUTE.
		</para>
		<example>
		<title><function>crypto_netio_in</function> usage</title>
		<programlisting format="linespecific">
...
event_route[crypto:netio] {
  if(crypto_netio_in()) {
    crypto_netio_decrypt();
  }
...
</programlisting>
	    </example>
	</section>

	<section id="async.f.crypto_netio_out">
	    <title>
		<function moreinfo="none">crypto_netio_out()</function>
	    </title>
	    <para>
		Return 1 (true) if it is an outgoing net message, or -1 (false) otherwise.
		</para>
		<para>
		This function can be used from EVENT_ROUTE.
		</para>
		<example>
		<title><function>crypto_netio_out</function> usage</title>
		<programlisting format="linespecific">
...
event_route[crypto:netio] {
  if(crypto_netio_out()) {
    crypto_netio_encrypt();
  }
...
</programlisting>
	    </example>
	</section>

	<section id="async.f.crypto_netio_encrypt">
	    <title>
		<function moreinfo="none">crypto_netio_encrypt()</function>
	    </title>
	    <para>
		Mark the network message for encryption.
		</para>
		<para>
		This function can be used from EVENT_ROUTE.
		</para>
		<example>
		<title><function>crypto_netio_encrypt</function> usage</title>
		<programlisting format="linespecific">
...
event_route[crypto:netio] {
  if(crypto_netio_out()) {
    crypto_netio_encrypt();
  }
...
</programlisting>
	    </example>
	</section>

	<section id="async.f.crypto_netio_decrypt">
	    <title>
		<function moreinfo="none">crypto_netio_decrypt()</function>
	    </title>
	    <para>
		Mark the network message for decryption.
		</para>
		<para>
		This function can be used from EVENT_ROUTE.
		</para>
		<example>
		<title><function>crypto_netio_decrypt</function> usage</title>
		<programlisting format="linespecific">
...
event_route[crypto:netio] {
  if(crypto_netio_in()) {
    crypto_netio_decrypt();
  }
...
</programlisting>
	    </example>
	</section>
	</section>

	<section>
	<title>Event Routes</title>
	<section id="async.ev.crypto_netio">
	    <title>
		<function moreinfo="none">event_route[crypto:netio]</function>
	    </title>
	    <para>
		</para>
		<example>
		<title><function>event_route[crypto:netio]</function> usage</title>
		<programlisting format="linespecific">
...
# ----- crypto params -----
modparam("crypto", "register_evcb", 1)
modparam("crypto", "netio_key", "strong-password-here")
...
event_route[crypto:netio] {
	if(crypto_netio_in()) {
		if(src_port==5060) {
			crypto_netio_decrypt();
		}
	} else {
		if($sndto(port)==5060) {
			crypto_netio_encrypt();
		}
	}
}

# Main SIP request routing logic
request_route {
	sl_send_reply("200", "ok");
	if(src_port==5060) {
		$du = "sip:127.0.0.1:9";
		forward();
	} else {
		$du = "sip:127.0.0.1:5060";
		forward();
	}
	exit;
}
...
</programlisting>
	    </example>
	</section>
	</section>
</chapter>
