tlsops.c

Go to the documentation of this file.
00001 /*$Id: tlsops.c 5276 2008-11-27 15:31:51Z anomarme $
00002  *
00003  * Copyright (C) 2006 nic.at
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  *
00023  * History:
00024  * -------
00025  *  2006-01-26  initial version
00026  *  
00027  * tls module, it implements the following commands:
00028  * is_peer_verified(): returns 1 if the message is received via TLS
00029  *     and the peer was verified during TLS connection handshake,
00030  *     otherwise it returns -1
00031  *  
00032  */
00033 
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <openssl/ssl.h>
00038 
00039 #include "tlsops.h"
00040 #include "tls_select.h"
00041 #include "../../tcp_conn.h"    /* struct tcp_connection */
00042 #include "../../tcp_server.h"  /* tcpconn_get() */
00043 #include "../../sr_module.h"
00044 #include "../../pvar.h"
00045 
00046 MODULE_VERSION
00047 
00048 int tcp_con_lifetime=DEFAULT_TCP_CONNECTION_LIFETIME;
00049 
00050 /* definition of exported functions */
00051 static int is_peer_verified(struct sip_msg*, char*, char*);
00052 
00053 /*
00054  * Module parameter variables
00055  */
00056 
00057 /*
00058  * Exported functions
00059  */
00060 static cmd_export_t cmds[]={
00061    {"is_peer_verified", (cmd_function)is_peer_verified,   0, 0, 0, 
00062          REQUEST_ROUTE},
00063    {0,0,0,0,0,0}
00064 };
00065 
00066 /*
00067  * Exported parameters
00068  */
00069 static param_export_t params[] = {
00070    {0,0,0}
00071 }; 
00072 
00073 /*
00074  *  pseudo variables
00075  */
00076 static pv_export_t mod_items[] = {
00077    /* TLS session parameters */
00078    {{"tls_version", sizeof("tls_version")-1},
00079       PVT_OTHER, tlsops_version, 0,
00080       0, 0, 0, 0 },
00081    {{"tls_description", sizeof("tls_description")-1},
00082       PVT_OTHER, tlsops_desc, 0,
00083       0, 0, 0, 0 },
00084    {{"tls_cipher_info", sizeof("tls_cipher_info")-1},
00085       PVT_OTHER, tlsops_cipher, 0,
00086       0, 0, 0, 0 },
00087    {{"tls_cipher_bits", sizeof("tls_cipher_bits")-1},
00088       PVT_OTHER,  tlsops_bits, 0,
00089       0, 0, 0, 0 },
00090    /* general certificate parameters for peer and local */
00091    {{"tls_peer_version", sizeof("tls_peer_version")-1},
00092       PVT_OTHER, tlsops_cert_version, 0,
00093       0, 0, pv_init_iname, CERT_PEER  },
00094    {{"tls_my_version", sizeof("tls_my_version")-1},
00095       PVT_OTHER, tlsops_cert_version, 0,
00096       0, 0, pv_init_iname, CERT_LOCAL },
00097    {{"tls_peer_serial", sizeof("tls_peer_serial")-1},
00098       PVT_OTHER, tlsops_sn, 0,
00099       0, 0, pv_init_iname, CERT_PEER  },
00100    {{"tls_my_serial", sizeof("tls_my_serial")-1},
00101       PVT_OTHER, tlsops_sn,0,
00102       0, 0, pv_init_iname, CERT_LOCAL },
00103    /* certificate parameters for peer and local, for subject and issuer*/  
00104    {{"tls_peer_subject", sizeof("tls_peer_subject")-1},
00105       PVT_OTHER, tlsops_comp, 0,
00106       0, 0, pv_init_iname, CERT_PEER  | CERT_SUBJECT },
00107    {{"tls_peer_issuer", sizeof("tls_peer_issuer")-1},
00108       PVT_OTHER, tlsops_comp, 0,
00109       0, 0, pv_init_iname, CERT_PEER  | CERT_ISSUER  },
00110    {{"tls_my_subject", sizeof("tls_my_subject")-1},
00111       PVT_OTHER, tlsops_comp, 0,
00112       0, 0, pv_init_iname, CERT_LOCAL | CERT_SUBJECT },
00113    {{"tls_my_issuer", sizeof("tls_my_issuer")-1},
00114       PVT_OTHER, tlsops_comp, 0,
00115       0, 0, pv_init_iname, CERT_LOCAL | CERT_ISSUER  },
00116    {{"tls_peer_subject_cn", sizeof("tls_peer_subject_cn")-1},
00117       PVT_OTHER, tlsops_comp, 0,
00118       0, 0, pv_init_iname, CERT_PEER  | CERT_SUBJECT | COMP_CN },
00119    {{"tls_peer_issuer_cn", sizeof("tls_peer_issuer_cn")-1},
00120       PVT_OTHER, tlsops_comp, 0,
00121       0, 0, pv_init_iname, CERT_PEER  | CERT_ISSUER  | COMP_CN },
00122    {{"tls_my_subject_cn", sizeof("tls_my_subject_cn")-1},
00123       PVT_OTHER, tlsops_comp, 0,
00124       0, 0, pv_init_iname, CERT_LOCAL | CERT_SUBJECT | COMP_CN },
00125    {{"tls_my_issuer_cn", sizeof("tls_my_issuer_cn")-1},
00126       PVT_OTHER, tlsops_comp, 0,
00127       0, 0, pv_init_iname, CERT_LOCAL | CERT_ISSUER  | COMP_CN },
00128    {{"tls_peer_subject_locality", sizeof("tls_peer_subject_locality")-1},
00129       PVT_OTHER, tlsops_comp, 0,
00130       0, 0, pv_init_iname, CERT_PEER  | CERT_SUBJECT | COMP_L },
00131    {{"tls_peer_issuer_locality", sizeof("tls_peer_issuer_locality")-1},
00132       PVT_OTHER, tlsops_comp, 0,
00133       0, 0, pv_init_iname, CERT_PEER  | CERT_ISSUER  | COMP_L },
00134    {{"tls_my_subject_locality", sizeof("tls_my_subject_locality")-1},
00135       PVT_OTHER, tlsops_comp, 0,
00136       0, 0, pv_init_iname, CERT_LOCAL | CERT_SUBJECT | COMP_L },
00137    {{"tls_my_issuer_locality", sizeof("tls_my_issuer_locality")-1},
00138       PVT_OTHER, tlsops_comp, 0,
00139       0, 0, pv_init_iname, CERT_LOCAL | CERT_ISSUER  | COMP_L },
00140    {{"tls_peer_subject_country", sizeof("tls_peer_subject_country")-1},
00141       PVT_OTHER, tlsops_comp, 0,
00142       0, 0, pv_init_iname, CERT_PEER  | CERT_SUBJECT | COMP_C },
00143    {{"tls_peer_issuer_country", sizeof("tls_peer_issuer_country")-1},
00144       PVT_OTHER, tlsops_comp, 0,
00145       0, 0, pv_init_iname, CERT_PEER  | CERT_ISSUER  | COMP_C },
00146    {{"tls_my_subject_country", sizeof("tls_my_subject_country")-1},
00147       PVT_OTHER, tlsops_comp, 0,
00148       0, 0, pv_init_iname, CERT_LOCAL | CERT_SUBJECT | COMP_C },
00149    {{"tls_my_issuer_country", sizeof("tls_my_issuer_country")-1},
00150       PVT_OTHER, tlsops_comp, 0,
00151       0, 0, pv_init_iname, CERT_LOCAL | CERT_ISSUER  | COMP_C },
00152    {{"tls_peer_subject_state", sizeof("tls_peer_subject_state")-1},
00153       PVT_OTHER, tlsops_comp, 0,
00154       0, 0, pv_init_iname, CERT_PEER  | CERT_SUBJECT | COMP_ST },
00155    {{"tls_peer_issuer_state", sizeof("tls_peer_issuer_state")-1},
00156       PVT_OTHER, tlsops_comp, 0,
00157       0, 0, pv_init_iname, CERT_PEER  | CERT_ISSUER  | COMP_ST },
00158    {{"tls_my_subject_state", sizeof("tls_my_subject_state")-1},
00159       PVT_OTHER, tlsops_comp, 0,
00160       0, 0, pv_init_iname, CERT_LOCAL | CERT_SUBJECT | COMP_ST },
00161    {{"tls_my_issuer_state", sizeof("tls_my_issuer_state")-1},
00162       PVT_OTHER, tlsops_comp, 0,
00163       0, 0, pv_init_iname, CERT_LOCAL | CERT_ISSUER  | COMP_ST },
00164    {{"tls_peer_subject_organization", sizeof("tls_peer_subject_organization")-1},
00165       PVT_OTHER, tlsops_comp, 0,
00166       0, 0, pv_init_iname, CERT_PEER  | CERT_SUBJECT | COMP_O },
00167    {{"tls_peer_issuer_organization", sizeof("tls_peer_issuer_organization")-1},
00168       PVT_OTHER, tlsops_comp, 0,
00169       0, 0, pv_init_iname, CERT_PEER  | CERT_ISSUER  | COMP_O },
00170    {{"tls_my_subject_organization", sizeof("tls_my_subject_organization")-1},
00171       PVT_OTHER, tlsops_comp, 0,
00172       0, 0, pv_init_iname, CERT_LOCAL | CERT_SUBJECT | COMP_O },
00173    {{"tls_my_issuer_organization", sizeof("tls_my_issuer_organization")-1},
00174       PVT_OTHER, tlsops_comp, 0,
00175       0, 0, pv_init_iname, CERT_LOCAL | CERT_ISSUER  | COMP_O },
00176    {{"tls_peer_subject_unit", sizeof("tls_peer_subject_unit")-1},
00177       PVT_OTHER, tlsops_comp, 0,
00178       0, 0, pv_init_iname, CERT_PEER  | CERT_SUBJECT | COMP_OU },
00179    {{"tls_peer_issuer_unit", sizeof("tls_peer_issuer_unit")-1},
00180       PVT_OTHER, tlsops_comp, 0,
00181       0, 0, pv_init_iname, CERT_PEER  | CERT_ISSUER  | COMP_OU },
00182    {{"tls_my_subject_unit", sizeof("tls_my_subject_unit")-1},
00183       PVT_OTHER, tlsops_comp, 0,
00184       0, 0, pv_init_iname, CERT_LOCAL | CERT_SUBJECT | COMP_OU },
00185    {{"tls_my_issuer_unit", sizeof("tls_my_issuer_unit")-1},
00186       PVT_OTHER, tlsops_comp, 0,
00187       0, 0, pv_init_iname, CERT_LOCAL | CERT_ISSUER  | COMP_OU },
00188    /* subject alternative name parameters for peer and local */   
00189    {{"tls_peer_san_email", sizeof("tls_peer_san_email")-1},
00190       PVT_OTHER, tlsops_alt, 0,
00191       0, 0, pv_init_iname, CERT_PEER  | COMP_E },
00192    {{"tls_my_san_email", sizeof("tls_my_san_email")-1},
00193       PVT_OTHER, tlsops_alt, 0,
00194       0, 0, pv_init_iname, CERT_LOCAL | COMP_E },
00195    {{"tls_peer_san_hostname", sizeof("tls_peer_san_hostname")-1},
00196       PVT_OTHER, tlsops_alt, 0,
00197       0, 0, pv_init_iname, CERT_PEER  | COMP_HOST },
00198    {{"tls_my_san_hostname", sizeof("tls_my_san_hostname")-1},
00199       PVT_OTHER, tlsops_alt, 0,
00200       0, 0, pv_init_iname, CERT_LOCAL | COMP_HOST },
00201    {{"tls_peer_san_uri", sizeof("tls_peer_san_uri")-1},
00202       PVT_OTHER, tlsops_alt, 0,
00203       0, 0, pv_init_iname, CERT_PEER  | COMP_URI },
00204    {{"tls_my_san_uri", sizeof("tls_my_san_uri")-1},
00205       PVT_OTHER, tlsops_alt, 0,
00206       0, 0, pv_init_iname, CERT_LOCAL | COMP_URI },
00207    {{"tls_peer_san_ip", sizeof("tls_peer_san_ip")-1},
00208       PVT_OTHER, tlsops_alt, 0,
00209       0, 0, pv_init_iname, CERT_PEER  | COMP_IP },
00210    {{"tls_my_san_ip", sizeof("tls_my_san_ip")-1},
00211       PVT_OTHER, tlsops_alt, 0,
00212       0, 0, pv_init_iname, CERT_LOCAL | COMP_IP },
00213    /* peer certificate validation parameters */    
00214    {{"tls_peer_verified", sizeof("tls_peer_verified")-1},
00215       PVT_OTHER, tlsops_check_cert, 0,
00216       0, 0, pv_init_iname, CERT_VERIFIED },
00217    {{"tls_peer_revoked", sizeof("tls_peer_revoked")-1},
00218       PVT_OTHER, tlsops_check_cert, 0,
00219       0, 0, pv_init_iname, CERT_REVOKED },
00220    {{"tls_peer_expired", sizeof("tls_peer_expired")-1},
00221       PVT_OTHER, tlsops_check_cert, 0,
00222       0, 0, pv_init_iname, CERT_EXPIRED },
00223    {{"tls_peer_selfsigned", sizeof("tls_peer_selfsigned")-1},
00224       PVT_OTHER, tlsops_check_cert, 0,
00225       0, 0, pv_init_iname, CERT_SELFSIGNED },
00226    {{"tls_peer_notBefore", sizeof("tls_peer_notBefore")-1},
00227       PVT_OTHER, tlsops_validity, 0,
00228       0, 0, pv_init_iname, CERT_NOTBEFORE },
00229    {{"tls_peer_notAfter", sizeof("tls_peer_notAfter")-1},
00230       PVT_OTHER, tlsops_validity, 0,
00231       0, 0, pv_init_iname, CERT_NOTAFTER },
00232    /* peer certificate validation parameters */    
00233    {{"tls_peer_server_name", sizeof("tls_peer_server_name")-1},
00234       PVT_OTHER, tlsops_tlsext, 0,
00235       0, 0, pv_init_iname, TLSEXT_SNI },
00236 
00237    { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
00238 
00239 }; 
00240 
00241 /*
00242  * Module interface
00243  */
00244 struct module_exports exports = {
00245    "tlsops", 
00246    DEFAULT_DLFLAGS, /* dlopen flags */
00247    cmds,        /* Exported functions */
00248    params,      /* Exported parameters */
00249    0,           /* exported statistics */
00250    0,           /* exported MI functions */
00251    mod_items,   /* exported pseudo-variables */
00252    0,           /* extra processes */
00253    0,           /* module initialization function */
00254    0,           /* response function */
00255    0,           /* destroy function */
00256    0            /* child initialization function */
00257 };
00258 
00259 
00260 static int is_peer_verified(struct sip_msg* msg, char* foo, char* foo2)
00261 {
00262    struct tcp_connection *c;
00263    SSL *ssl;
00264    long ssl_verify;
00265    X509 *x509_cert;
00266 
00267    LM_DBG("started...\n");
00268    if (msg->rcv.proto != PROTO_TLS) {
00269       LM_ERR("proto != TLS --> peer can't be verified, return -1\n");
00270       return -1;
00271    }
00272 
00273    LM_DBG("trying to find TCP connection of received message...\n");
00274    /* what if we have multiple connections to the same remote socket? e.g. we can have 
00275         connection 1: localIP1:localPort1 <--> remoteIP:remotePort
00276         connection 2: localIP2:localPort2 <--> remoteIP:remotePort
00277       but I think the is very unrealistic */
00278    c=tcpconn_get(0, &(msg->rcv.src_ip), msg->rcv.src_port, tcp_con_lifetime, 0);
00279    if (!c) {
00280       LM_ERR("no corresponding TLS/TCP connection found."
00281             " This should not happen... return -1\n");
00282       return -1;
00283    }
00284    LM_DBG("corresponding TLS/TCP connection found. s=%d, fd=%d, id=%d\n",
00285          c->s, c->fd, c->id);
00286 
00287    if (!c->extra_data) {
00288       LM_ERR("no extra_data specified in TLS/TCP connection found."
00289             " This should not happen... return -1\n");
00290       tcpconn_put(c);
00291       return -1;
00292    }
00293 
00294    ssl = (SSL *) c->extra_data;     
00295 
00296    ssl_verify = SSL_get_verify_result(ssl);
00297    if ( ssl_verify != X509_V_OK ) {
00298       LM_WARN("verification of presented certificate failed... return -1\n");
00299       tcpconn_put(c);
00300       return -1;
00301    }
00302    
00303    /* now, we have only valid peer certificates or peers without certificates.
00304     * Thus we have to check for the existence of a peer certificate
00305     */
00306    x509_cert = SSL_get_peer_certificate(ssl);
00307    if ( x509_cert == NULL ) {
00308       LM_WARN("tlsops:is_peer_verified: WARNING: peer did not presented "
00309          "a certificate. Thus it could not be verified... return -1\n");
00310       tcpconn_put(c);
00311       return -1;
00312    }
00313    
00314    X509_free(x509_cert);
00315    
00316    tcpconn_put(c);
00317    
00318    LM_DBG("tlsops:is_peer_verified: peer is successfuly verified"
00319       "...done\n");
00320    return 1;
00321 }

Generated on Thu May 24 20:00:33 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6