Navigation


source: freeDiameter/freeDiameter/cnxctx.c @ 20:277ec00d793e

Last change on this file since 20:277ec00d793e was 20:277ec00d793e, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 12 years ago

Backup before typhoon... Progress on server side

File size: 6.0 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2009, WIDE Project and NICT                                                              *
6* All rights reserved.                                                                                   *
7*                                                                                                        *
8* Redistribution and use of this software in source and binary forms, with or without modification, are  *
9* permitted provided that the following conditions are met:                                              *
10*                                                                                                        *
11* * Redistributions of source code must retain the above                                                 *
12*   copyright notice, this list of conditions and the                                                    *
13*   following disclaimer.                                                                                *
14*                                                                                                        *
15* * Redistributions in binary form must reproduce the above                                              *
16*   copyright notice, this list of conditions and the                                                    *
17*   following disclaimer in the documentation and/or other                                               *
18*   materials provided with the distribution.                                                            *
19*                                                                                                        *
20* * Neither the name of the WIDE Project or NICT nor the                                                 *
21*   names of its contributors may be used to endorse or                                                  *
22*   promote products derived from this software without                                                  *
23*   specific prior written permission of WIDE Project and                                                *
24*   NICT.                                                                                                *
25*                                                                                                        *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT     *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                             *
34*********************************************************************************************************/
35
36#include "fD.h"
37
38/* Initialize a connection context */
39struct cnxctx * fd_cnx_init(int sock, int proto)
40{
41        struct cnxctx * conn = NULL;
42       
43        TRACE_ENTRY("%d %d", sock, proto);
44        CHECK_PARAMS_DO( (proto == IPPROTO_TCP) || (proto == IPPROTO_SCTP), return NULL);
45       
46        CHECK_MALLOC_DO( conn = malloc(sizeof(struct cnxctx)), return NULL );
47        memset(conn, 0, sizeof(struct cnxctx));
48       
49        conn->cc_socket = sock;
50        conn->cc_proto  = proto;
51       
52        fd_list_init(&conn->cc_ep_remote, conn);
53        fd_list_init(&conn->cc_ep_local, conn);
54       
55        if (proto == IPPROTO_SCTP) {
56#ifndef DISABLE_SCTP
57                CHECK_FCT_DO( fd_sctp_get_str_info( sock, &conn->cc_sctp_para.str_in, &conn->cc_sctp_para.str_out ),
58                                { free(conn); return NULL; } );
59                conn->cc_sctp_para.pairs = (conn->cc_sctp_para.str_out < conn->cc_sctp_para.str_in) ? conn->cc_sctp_para.str_out : conn->cc_sctp_para.str_in;
60#else /* DISABLE_SCTP */
61                ASSERT(0);
62#endif /* DISABLE_SCTP */
63        }
64       
65        return conn;
66}
67
68/* TLS handshake the connection */
69int fd_cnx_handshake(struct cnxctx * conn, int mode)
70{
71        TRACE_ENTRY( "%p %d", conn, mode);
72        CHECK_PARAMS( conn && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) );
73       
74        /* Save the mode */
75        conn->cc_tls_para.mode = mode;
76       
77        /* Create the master session context */
78        CHECK_GNUTLS_DO( gnutls_init (&conn->cc_tls_para.session, mode), return ENOMEM );
79       
80        /* Set the algorithm suite */
81        CHECK_GNUTLS_DO( gnutls_priority_set( conn->cc_tls_para.session, fd_g_config->cnf_sec_data.prio_cache ), return EINVAL );
82       
83        /* Set the credentials of this side of the connection */
84        CHECK_GNUTLS_DO( gnutls_credentials_set (conn->cc_tls_para.session, GNUTLS_CRD_CERTIFICATE, fd_g_config->cnf_sec_data.credentials), return EINVAL );
85       
86        /* Request the remote credentials as well */
87        if (mode == GNUTLS_SERVER) {
88                gnutls_certificate_server_set_request (conn->cc_tls_para.session, GNUTLS_CERT_REQUIRE);
89        }
90
91        /* Set the socket info in the session */
92        gnutls_transport_set_ptr (conn->cc_tls_para.session, (gnutls_transport_ptr_t) conn->cc_socket);
93
94        /* Special case: multi-stream TLS is not natively managed in GNU TLS, we use a wrapper library */
95        if ((conn->cc_proto == IPPROTO_SCTP) && (conn->cc_sctp_para.pairs > 0)) {
96#ifndef DISABLE_SCTP
97                TODO("Initialize the SCTP TLS wrapper");
98                TODO("Set the lowat, push and pull functions");
99#else /* DISABLE_SCTP */
100                ASSERT(0);
101#endif /* DISABLE_SCTP */
102        }
103       
104        /* Handshake master session */
105        {
106                int ret;
107                CHECK_GNUTLS_DO( ret = gnutls_handshake(conn->cc_tls_para.session),
108                        {
109                                if (TRACE_BOOL(INFO)) {
110                                        fd_log_debug("TLS Handshake failed on socket %d : %s\n", conn->cc_socket, gnutls_strerror(ret));
111                                }
112                                return EINVAL;
113                        } );
114               
115                /* Now verify the remote credentials are valid -- only simple test here */
116                CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (conn->cc_tls_para.session, &ret), return EINVAL );
117                if (ret) {
118                        if (TRACE_BOOL(INFO)) {
119                                fd_log_debug("TLS: Remote certificate invalid on socket %d :\n", conn->cc_socket);
120                                if (ret & GNUTLS_CERT_INVALID)
121                                        fd_log_debug(" - The certificate is not trusted (unknown CA?)\n");
122                                if (ret & GNUTLS_CERT_REVOKED)
123                                        fd_log_debug(" - The certificate has been revoked.\n");
124                                if (ret & GNUTLS_CERT_SIGNER_NOT_FOUND)
125                                        fd_log_debug(" - The certificate hasn't got a known issuer.\n");
126                                if (ret & GNUTLS_CERT_SIGNER_NOT_CA)
127                                        fd_log_debug(" - The certificate signer is not a CA, or uses version 1, or 3 without basic constraints.\n");
128                                if (ret & GNUTLS_CERT_INSECURE_ALGORITHM)
129                                        fd_log_debug(" - The certificate signature uses a weak algorithm.\n");
130                        }
131                        return EINVAL;
132                }
133        }
134       
135        /* Other sessions in case of multi-stream SCTP are resumed from the master */
136        if ((conn->cc_proto == IPPROTO_SCTP) && (conn->cc_sctp_para.pairs > 0)) {
137#ifndef DISABLE_SCTP
138                TODO("Init and resume all additional sessions from the master one.");
139#endif /* DISABLE_SCTP */
140        }
141       
142        return 0;
143}
Note: See TracBrowser for help on using the repository browser.