Navigation


Changeset 1181:22de21feec64 in freeDiameter


Ignore:
Timestamp:
Jun 5, 2013, 8:22:26 PM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Preparing for DTLS support

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • doc/freediameter.conf.sample

    r1180 r1181  
    3636# freeDiameter 1.2.0 introduces the support of DTLS over SCTP (RFC6083) instead of TLS over SCTP (RFC3436),
    3737# as specified in RFC6733. If you need compatibility with older implementation that use TLS over SCTP, you
    38 # can open an additional SCTP server port using this method:
     38# can open an additional SCTP server port using TLS/SCTP by specifying the following parameter.
     39# Note that no TCP server is started on the following port.
    3940# Default: 0 (disabled). Use 3869 for compatibility with freeDiameter < 1.2.0.
    4041#SctpSec3436 = 0;
  • libfdcore/cnxctx.c

    r1180 r1181  
    9696}
    9797
     98#define CC_ID_HDR "{----} "
     99
    98100/* Create and bind a server socket to the given endpoint and port */
    99101struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep)
     
    139141                if (rc)
    140142                        snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc));
    141                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "TCP srv [%s]:%hu (%d)", addrbuf, port, cnx->cc_socket);
     143                snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "TCP srv [%s]:%hu (%d)", addrbuf, port, cnx->cc_socket);
    142144        }
    143145
     
    179181
    180182        /* Generate the name for the connection object */
    181         snprintf(cnx->cc_id, sizeof(cnx->cc_id), "SCTP srv :%hu (%d)", port, cnx->cc_socket);
     183        snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "SCTP srv :%hu (%d)", port, cnx->cc_socket);
    182184
    183185        cnx->cc_proto = IPPROTO_SCTP;
     
    249251               
    250252                /* Numeric values for debug... */
    251                 snprintf(cli->cc_id, sizeof(cli->cc_id), "%s from [%s]:%s (%d<-%d)",
     253                snprintf(cli->cc_id, sizeof(cli->cc_id), CC_ID_HDR "%s from [%s]:%s (%d<-%d)",
    252254                                IPPROTO_NAME(cli->cc_proto), addrbuf, portbuf, serv->cc_socket, cli->cc_socket);
    253255               
     
    313315                int  rc;
    314316               
    315                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "TCP,#%d->%s", cnx->cc_socket, sa_buf);
     317                snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "TCP,#%d->%s", cnx->cc_socket, sa_buf);
    316318               
    317319                /* ...Name for log messages */
     
    376378                int  rc;
    377379               
    378                 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "SCTP,#%d->%s", cnx->cc_socket, sa_buf);
     380                snprintf(cnx->cc_id, sizeof(cnx->cc_id), CC_ID_HDR "SCTP,#%d->%s", cnx->cc_socket, sa_buf);
    379381               
    380382                /* ...Name for log messages */
     
    433435        return st & flag;
    434436}
     437void fd_cnx_update_id(struct cnxctx * conn) {
     438        if (conn->cc_state & CC_STATUS_CLOSING)
     439                conn->cc_id[1] = 'C';
     440        else
     441                conn->cc_id[1] = '-';
     442       
     443        if (conn->cc_state & CC_STATUS_ERROR)
     444                conn->cc_id[2] = 'E';
     445        else
     446                conn->cc_id[2] = '-';
     447       
     448        if (conn->cc_state & CC_STATUS_SIGNALED)
     449                conn->cc_id[3] = 'S';
     450        else
     451                conn->cc_id[3] = '-';
     452       
     453        if (conn->cc_state & CC_STATUS_TLS)
     454                conn->cc_id[4] = 'T';
     455        else
     456                conn->cc_id[4] = '-';
     457}
    435458void fd_cnx_addstate(struct cnxctx * conn, uint32_t orstate)
    436459{
    437460        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
    438461        conn->cc_state |= orstate;
     462        fd_cnx_update_id(conn);
    439463        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
    440464}
     
    443467        CHECK_POSIX_DO( pthread_mutex_lock(&state_lock), { ASSERT(0); } );
    444468        conn->cc_state = abstate;
     469        fd_cnx_update_id(conn);
    445470        CHECK_POSIX_DO( pthread_mutex_unlock(&state_lock), { ASSERT(0); } );
    446471}
     
    659684}
    660685
    661 #ifndef DISABLE_SCTP
     686#ifndef DISABLE_SCTP /* WE use this function only in SCTP code */
    662687static uint8_t * fd_cnx_realloc_msg_buffer(uint8_t * buffer, size_t expected_len, struct fd_msg_pmdl ** pmdl)
    663688{
     
    853878
    854879
    855 /* Returns 0 on error, received data size otherwise (always >= 0) */
     880/* Returns 0 on error, received data size otherwise (always >= 0). This is not used for DTLS-protected associations. */
    856881static ssize_t fd_tls_recv_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
    857882{
    858883        ssize_t ret;
    859884again: 
    860         CHECK_GNUTLS_DO( ret = gnutls_record_recv(session, data, sz),
     885        CHECK_GNUTLS_DO( ret = gnutls_record_recv(session, data, sz), 
    861886                {
    862887                        switch (ret) {
     
    885910                               
    886911                                default:
    887                                         TRACE_DEBUG(INFO, "This GNU TLS error is not handled, assume unrecoverable error");
     912                                        if (gnutls_error_is_fatal (ret) == 0) {
     913                                                LOG_N("Ignoring non-fatal GNU TLS error: %s", gnutls_strerror (ret));
     914                                                goto again;
     915                                        }
     916                                        LOG_E("Fatal GNUTLS error: %s", gnutls_strerror (ret));
    888917                        }
    889918                } );
     
    898927}
    899928
    900 /* Wrapper around gnutls_record_send to handle some error codes */
     929/* Wrapper around gnutls_record_send to handle some error codes. This is also used for DTLS-protected associations */
    901930static ssize_t fd_tls_send_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
    902931{
     
    925954
    926955                                default:
    927                                         TRACE_DEBUG(INFO, "This TLS error is not handled, assume unrecoverable error");
     956                                        if (gnutls_error_is_fatal (ret) == 0) {
     957                                                LOG_N("Ignoring non-fatal GNU TLS error: %s", gnutls_strerror (ret));
     958                                                goto again;
     959                                        }
     960                                        LOG_E("Fatal GNUTLS error: %s", gnutls_strerror (ret));
    928961                        }
    929962                } );
     
    937970
    938971/* The function that receives TLS data and re-builds a Diameter message -- it exits only on error or cancelation */
     972/*         For the case of DTLS, since we are not using SCTP_UNORDERED, the messages over a single stream are ordered.
     973           Furthermore, as long as messages are shorter than the MTU [2^14 = 16384 bytes], they are delivered in a single
     974           record, as far as I understand.
     975           For larger messages, however, it is possible that pieces of messages coming from different streams can get interleaved.
     976           As a result, we do not use the following function for DTLS reception, because we use the sequence number to rebuild the
     977           messages. */
    939978int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session)
    940979{
    941         /* No guarantee that GnuTLS preserves the message boundaries, so we re-build it as in TCP */
     980        /* No guarantee that GnuTLS preserves the message boundaries, so we re-build it as in TCP. */
    942981        do {
    943982                uint8_t header[4];
     
    10251064
    10261065/* Prepare a gnutls session object for handshake */
    1027 int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority, void * alt_creds)
    1028 {
     1066int fd_tls_prepare(gnutls_session_t * session, int mode, int dtls, char * priority, void * alt_creds)
     1067{
     1068        if (dtls) {
     1069                LOG_E("DTLS sessions not yet supported");
     1070                return ENOTSUP;
     1071        }
     1072
    10291073        /* Create the session context */
    10301074        CHECK_GNUTLS_DO( gnutls_init (session, mode), return ENOMEM );
     
    10661110       
    10671111        /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */
    1068         if (verbose && TRACE_BOOL(FULL)) {
     1112        #ifdef DEBUG
     1113        if (verbose) {
    10691114                const char *tmp;
    10701115                gnutls_kx_algorithm_t kx;
    10711116                gnutls_credentials_type_t cred;
    10721117               
    1073                 fd_log_debug("TLS Session information for connection '%s':", conn->cc_id);
     1118                LOG_A("TLS Session information for connection '%s':", conn->cc_id);
    10741119
    10751120                /* print the key exchange's algorithm name */
    10761121                GNUTLS_TRACE( kx = gnutls_kx_get (session) );
    10771122                GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) );
    1078                 fd_log_debug("\t - Key Exchange: %s", tmp);
     1123                LOG_A("\t - Key Exchange: %s", tmp);
    10791124
    10801125                /* Check the authentication type used and switch
     
    10841129                {
    10851130                        case GNUTLS_CRD_IA:
    1086                                 fd_log_debug("\t - TLS/IA session");
     1131                                LOG_A("\t - TLS/IA session");
    10871132                                break;
    10881133
     
    10901135                                /* This returns NULL in server side. */
    10911136                                if (gnutls_psk_client_get_hint (session) != NULL)
    1092                                         fd_log_debug("\t - PSK authentication. PSK hint '%s'",
     1137                                        LOG_A("\t - PSK authentication. PSK hint '%s'",
    10931138                                                gnutls_psk_client_get_hint (session));
    10941139                                /* This returns NULL in client side. */
    10951140                                if (gnutls_psk_server_get_username (session) != NULL)
    1096                                         fd_log_debug("\t - PSK authentication. Connected as '%s'",
     1141                                        LOG_A("\t - PSK authentication. Connected as '%s'",
    10971142                                                gnutls_psk_server_get_username (session));
    10981143                                break;
    10991144
    11001145                        case GNUTLS_CRD_ANON:   /* anonymous authentication */
    1101                                 fd_log_debug("\t - Anonymous DH using prime of %d bits",
     1146                                LOG_A("\t - Anonymous DH using prime of %d bits",
    11021147                                        gnutls_dh_get_prime_bits (session));
    11031148                                break;
     
    11061151                                /* Check if we have been using ephemeral Diffie-Hellman. */
    11071152                                if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
    1108                                         fd_log_debug("\t - Ephemeral DH using prime of %d bits",
     1153                                        LOG_A("\t - Ephemeral DH using prime of %d bits",
    11091154                                                gnutls_dh_get_prime_bits (session));
    11101155                                }
     
    11121157#ifdef ENABLE_SRP                               
    11131158                        case GNUTLS_CRD_SRP:
    1114                                 fd_log_debug("\t - SRP session with username %s",
     1159                                LOG_A("\t - SRP session with username %s",
    11151160                                        gnutls_srp_server_get_username (session));
    11161161                                break;
     
    11251170                /* print the protocol's name (ie TLS 1.0) */
    11261171                tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
    1127                 fd_log_debug("\t - Protocol: %s", tmp);
     1172                LOG_A("\t - Protocol: %s", tmp);
    11281173
    11291174                /* print the certificate type of the peer. ie X.509 */
    11301175                tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session));
    1131                 fd_log_debug("\t - Certificate Type: %s", tmp);
     1176                LOG_A("\t - Certificate Type: %s", tmp);
    11321177
    11331178                /* print the compression algorithm (if any) */
    11341179                tmp = gnutls_compression_get_name (gnutls_compression_get (session));
    1135                 fd_log_debug("\t - Compression: %s", tmp);
     1180                LOG_A("\t - Compression: %s", tmp);
    11361181
    11371182                /* print the name of the cipher used. ie 3DES. */
    11381183                tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
    1139                 fd_log_debug("\t - Cipher: %s", tmp);
     1184                LOG_A("\t - Cipher: %s", tmp);
    11401185
    11411186                /* Print the MAC algorithms name. ie SHA1 */
    11421187                tmp = gnutls_mac_get_name (gnutls_mac_get (session));
    1143                 fd_log_debug("\t - MAC: %s", tmp);
    1144         }
     1188                LOG_A("\t - MAC: %s", tmp);
     1189        }
     1190        #endif /* DEBUG */
    11451191       
    11461192        /* First, use built-in verification */
     
    11731219        now = time(NULL);
    11741220       
    1175         if (verbose && TRACE_BOOL(FULL)) {
     1221        #ifdef DEBUG
    11761222                char serial[40];
    11771223                char dn[128];
     
    11801226                time_t expiration_time, activation_time;
    11811227               
    1182                 fd_log_debug("TLS Certificate information for connection '%s' (%d certs provided):", conn->cc_id, cert_list_size);
     1228                LOG_D("TLS Certificate information for connection '%s' (%d certs provided):", conn->cc_id, cert_list_size);
    11831229                for (i = 0; i < cert_list_size; i++)
    11841230                {
     
    11871233                        CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL);
    11881234               
    1189                         fd_log_debug(" Certificate %d info:", i);
     1235                        LOG_A(" Certificate %d info:", i);
    11901236
    11911237                        GNUTLS_TRACE( expiration_time = gnutls_x509_crt_get_expiration_time (cert) );
    11921238                        GNUTLS_TRACE( activation_time = gnutls_x509_crt_get_activation_time (cert) );
    11931239
    1194                         fd_log_debug("\t - Certificate is valid since: %s", ctime (&activation_time));
    1195                         fd_log_debug("\t - Certificate expires: %s", ctime (&expiration_time));
     1240                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate is valid since: %.24s", ctime (&activation_time));
     1241                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate expires: %.24s", ctime (&expiration_time));
    11961242
    11971243                        /* Print the serial number of the certificate. */
     
    12061252                                        snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02hhx", serial[j]);
    12071253                                }
    1208                                 fd_log_debug("%s", buf);
     1254                                LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "%s", buf);
    12091255                        }
    12101256
    12111257                        /* Extract some of the public key algorithm's parameters */
    12121258                        GNUTLS_TRACE( algo = gnutls_x509_crt_get_pk_algorithm (cert, &bits) );
    1213                         fd_log_debug("\t - Certificate public key: %s",
     1259                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate public key: %s",
    12141260                              gnutls_pk_algorithm_get_name (algo));
    12151261
    12161262                        /* Print the version of the X.509 certificate. */
    1217                         fd_log_debug("\t - Certificate version: #%d",
     1263                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Certificate version: #%d",
    12181264                              gnutls_x509_crt_get_version (cert));
    12191265
    12201266                        size = sizeof (dn);
    12211267                        GNUTLS_TRACE( gnutls_x509_crt_get_dn (cert, dn, &size) );
    1222                         fd_log_debug("\t - DN: %s", dn);
     1268                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - DN: %s", dn);
    12231269
    12241270                        size = sizeof (dn);
    12251271                        GNUTLS_TRACE( gnutls_x509_crt_get_issuer_dn (cert, dn, &size) );
    1226                         fd_log_debug("\t - Issuer's DN: %s", dn);
     1272                        LOG( i ? FD_LOG_ANNOYING : FD_LOG_DEBUG, "\t - Issuer's DN: %s", dn);
    12271273
    12281274                        GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) );
    12291275                }
    1230         }
     1276        #endif /* DEBUG */
    12311277
    12321278        /* Check validity of all the certificates */
     
    12911337       
    12921338        /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */
    1293         if (TRACE_BOOL(FULL)) {
     1339#ifdef DEBUG
    12941340                const char *tmp;
    12951341                gnutls_credentials_type_t cred;
     
    12991345                dhe = ecdh = 0;
    13001346
    1301                 fd_log_debug("TLS Session information for connection '%s':", conn->cc_id);
     1347                LOG_A("TLS Session information for connection '%s':", conn->cc_id);
    13021348               
    13031349                /* print the key exchange's algorithm name
     
    13051351                GNUTLS_TRACE( kx = gnutls_kx_get (session) );
    13061352                GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) );
    1307                 fd_log_debug("\t- Key Exchange: %s", tmp);
     1353                LOG_A("\t- Key Exchange: %s", tmp);
    13081354
    13091355                /* Check the authentication type used and switch
     
    13141360                {
    13151361                        case GNUTLS_CRD_IA:
    1316                                 fd_log_debug("\t - TLS/IA session");
     1362                                LOG_A("\t - TLS/IA session");
    13171363                                break;
    13181364
     
    13201366                        #ifdef ENABLE_SRP
    13211367                        case GNUTLS_CRD_SRP:
    1322                                 fd_log_debug("\t - SRP session with username %s",
     1368                                LOG_A("\t - SRP session with username %s",
    13231369                                        gnutls_srp_server_get_username (session));
    13241370                                break;
     
    13291375                                */
    13301376                                if (gnutls_psk_client_get_hint (session) != NULL)
    1331                                         fd_log_debug("\t - PSK authentication. PSK hint '%s'",
     1377                                        LOG_A("\t - PSK authentication. PSK hint '%s'",
    13321378                                                gnutls_psk_client_get_hint (session));
    13331379                                /* This returns NULL in client side.
    13341380                                */
    13351381                                if (gnutls_psk_server_get_username (session) != NULL)
    1336                                         fd_log_debug("\t - PSK authentication. Connected as '%s'",
     1382                                        LOG_A("\t - PSK authentication. Connected as '%s'",
    13371383                                                gnutls_psk_server_get_username (session));
    13381384
     
    13441390
    13451391                        case GNUTLS_CRD_ANON:      /* anonymous authentication */
    1346                                 fd_log_debug("\t - Anonymous DH using prime of %d bits",
     1392                                LOG_A("\t - Anonymous DH using prime of %d bits",
    13471393                                        gnutls_dh_get_prime_bits (session));
    13481394                                if (kx == GNUTLS_KX_ANON_ECDH)
     
    13671413                                        cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
    13681414
    1369                                         fd_log_debug("\t Peer provided %d certificates.", cert_list_size);
     1415                                        LOG_A("\t Peer provided %d certificates.", cert_list_size);
    13701416
    13711417                                        if (cert_list_size > 0)
     
    13791425                                                gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER);
    13801426
    1381                                                 fd_log_debug("\t Certificate info:");
     1427                                                                                                LOG_A("\t Certificate info:");
    13821428
    13831429                                                /* This is the preferred way of printing short information about
     
    13871433                                                if (ret == 0)
    13881434                                                {
    1389                                                   fd_log_debug("\t\t%s", cinfo.data);
     1435                                                  LOG_A("\t\t%s", cinfo.data);
    13901436                                                  gnutls_free (cinfo.data);
    13911437                                                }
     
    14101456
    14111457                        default:
    1412                                 fd_log_debug("\t - unknown session type (%d)", cred);
     1458                                LOG_A("\t - unknown session type (%d)", cred);
    14131459
    14141460                }                           /* switch */
    14151461
    14161462                if (ecdh != 0)
    1417                         fd_log_debug("\t - Ephemeral ECDH using curve %s",
     1463                        LOG_A("\t - Ephemeral ECDH using curve %s",
    14181464                                gnutls_ecc_curve_get_name (gnutls_ecc_curve_get (session)));
    14191465                else if (dhe != 0)
    1420                         fd_log_debug("\t - Ephemeral DH using prime of %d bits",
     1466                        LOG_A("\t - Ephemeral DH using prime of %d bits",
    14211467                                gnutls_dh_get_prime_bits (session));
    14221468
     
    14241470                */
    14251471                tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
    1426                 fd_log_debug("\t - Protocol: %s", tmp);
     1472                LOG_A("\t - Protocol: %s", tmp);
    14271473
    14281474                /* print the certificate type of the peer.
     
    14301476                */
    14311477                tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session));
    1432                 fd_log_debug("\t - Certificate Type: %s", tmp);
     1478                LOG_A("\t - Certificate Type: %s", tmp);
    14331479
    14341480                /* print the compression algorithm (if any)
    14351481                */
    14361482                tmp = gnutls_compression_get_name (gnutls_compression_get (session));
    1437                 fd_log_debug("\t - Compression: %s", tmp);
     1483                LOG_A("\t - Compression: %s", tmp);
    14381484
    14391485                /* print the name of the cipher used.
     
    14411487                */
    14421488                tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
    1443                 fd_log_debug("\t - Cipher: %s", tmp);
     1489                LOG_A("\t - Cipher: %s", tmp);
    14441490
    14451491                /* Print the MAC algorithms name.
     
    14471493                */
    14481494                tmp = gnutls_mac_get_name (gnutls_mac_get (session));
    1449                 fd_log_debug("\t - MAC: %s", tmp);
    1450        
    1451         }
     1495                LOG_A("\t - MAC: %s", tmp);
     1496       
     1497#endif /* DEBUG */             
    14521498
    14531499        /* This verification function uses the trusted CAs in the credentials
     
    15091555#endif /* GNUTLS_VERSION_300 */
    15101556
     1557static int fd_cnx_may_dtls(struct cnxctx * conn) {
     1558#ifndef DISABLE_SCTP
     1559        if ((conn->cc_proto == IPPROTO_SCTP) && (conn->cc_tls_para.algo == ALGO_HANDSHAKE_DEFAULT))
     1560                return 1;
     1561#endif /* DISABLE_SCTP */
     1562        return 0;
     1563}
     1564
     1565static int fd_cnx_uses_dtls(struct cnxctx * conn) {
     1566        return fd_cnx_may_dtls(conn) && (fd_cnx_teststate(conn, CC_STATUS_TLS));
     1567}
     1568
    15111569/* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */
    1512 int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds)
    1513 {
    1514         TRACE_ENTRY( "%p %d %p %p", conn, mode, priority, alt_creds);
     1570int fd_cnx_handshake(struct cnxctx * conn, int mode, int algo, char * priority, void * alt_creds)
     1571{
     1572        int dtls = 0;
     1573       
     1574        TRACE_ENTRY( "%p %d %d %p %p", conn, mode, algo, priority, alt_creds);
    15151575        CHECK_PARAMS( conn && (!fd_cnx_teststate(conn, CC_STATUS_TLS)) && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) && (!conn->cc_loop) );
    15161576
    15171577        /* Save the mode */
    15181578        conn->cc_tls_para.mode = mode;
     1579        conn->cc_tls_para.algo = algo;
    15191580       
    15201581        /* Cancel receiving thread if any -- it should already be terminated anyway, we just release the resources */
     
    15241585        conn->cc_loop = 1;
    15251586       
     1587        dtls = fd_cnx_may_dtls(conn);
     1588       
    15261589        /* Prepare the master session credentials and priority */
    1527         CHECK_FCT( fd_tls_prepare(&conn->cc_tls_para.session, mode, priority, alt_creds) );
     1590        CHECK_FCT( fd_tls_prepare(&conn->cc_tls_para.session, mode, dtls, priority, alt_creds) );
    15281591
    15291592        /* Special case: multi-stream TLS is not natively managed in GNU TLS, we use a wrapper library */
    1530         if (conn->cc_sctp_para.pairs > 1) {
     1593        if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) {
    15311594#ifdef DISABLE_SCTP
    15321595                ASSERT(0);
     
    15411604
    15421605                /* Set the push and pull callbacks */
    1543                 GNUTLS_TRACE( gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv) );
    1544                 GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) );
     1606                if (!dtls) {
     1607                        GNUTLS_TRACE( gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv) );
     1608                        GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) );
     1609                } else {
     1610                        TODO("DTLS push/pull functions");
     1611                        return ENOTSUP;
     1612                }
    15451613        }
    15461614       
     
    15891657                #endif /* GNUTLS_VERSION_300 */
    15901658        }
    1591 
     1659       
    15921660        /* Multi-stream TLS: handshake other streams as well */
    1593         if (conn->cc_sctp_para.pairs > 1) {
     1661        if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) {
    15941662#ifndef DISABLE_SCTP
    15951663                /* Start reading the messages from the master session. That way, if the remote peer closed, we are not stuck inside handshake */
     
    16041672        } else {
    16051673                /* Start decrypting the data */
    1606                 CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_tls_single, conn ) );
     1674                if (!dtls) {
     1675                        CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_tls_single, conn ) );
     1676                } else {
     1677                        TODO("Signal the dtls_push function that multiple streams can be used from this point.");
     1678                        TODO("Create DTLS rcvthr (must reassembly based on seq numbers & stream id ?)");
     1679                        return ENOTSUP;
     1680                }
    16071681        }
    16081682       
     
    17371811#ifndef DISABLE_SCTP
    17381812                case IPPROTO_SCTP: {
    1739                         if (flags & FD_CNX_ORDERED) {
    1740                                 /* We send over stream #0 */
    1741                                 CHECK_FCT( send_simple(conn, buf, len) );
    1742                         } else {
    1743                                 /* Default case : no flag specified */
    1744                        
    1745                                 int another_str = 0; /* do we send over stream #0 ? */
    1746                                
    1747                                 if ((conn->cc_sctp_para.str_out > 1) && ((!fd_cnx_teststate(conn, CC_STATUS_TLS)) || (conn->cc_sctp_para.pairs > 1)))  {
    1748                                         /* Update the id of the stream we will send this message over */
    1749                                         conn->cc_sctp_para.next += 1;
    1750                                         conn->cc_sctp_para.next %= (fd_cnx_teststate(conn, CC_STATUS_TLS) ? conn->cc_sctp_para.pairs : conn->cc_sctp_para.str_out);
    1751                                         another_str = (conn->cc_sctp_para.next ? 1 : 0);
    1752                                 }
    1753 
    1754                                 if ( ! another_str ) {
     1813                        int dtls = fd_cnx_uses_dtls(conn);
     1814
     1815                        if (!dtls) {
     1816                                if (flags & FD_CNX_ORDERED) {
     1817                                        /* We send over stream #0 */
    17551818                                        CHECK_FCT( send_simple(conn, buf, len) );
    17561819                                } else {
    1757                                         if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) {
    1758                                                 CHECK_FCT_DO( fd_sctp_sendstr(conn, conn->cc_sctp_para.next, buf, len), { fd_cnx_markerror(conn); return ENOTCONN; } );
     1820                                        /* Default case : no flag specified */
     1821                       
     1822                                        int another_str = 0; /* do we send over stream #0 ? */
     1823
     1824                                        if ((conn->cc_sctp_para.str_out > 1) && ((!fd_cnx_teststate(conn, CC_STATUS_TLS)) || (conn->cc_sctp_para.pairs > 1)))  {
     1825                                                /* Update the id of the stream we will send this message over */
     1826                                                conn->cc_sctp_para.next += 1;
     1827                                                conn->cc_sctp_para.next %= (fd_cnx_teststate(conn, CC_STATUS_TLS) ? conn->cc_sctp_para.pairs : conn->cc_sctp_para.str_out);
     1828                                                another_str = (conn->cc_sctp_para.next ? 1 : 0);
     1829                                        }
     1830
     1831                                        if ( ! another_str ) {
     1832                                                CHECK_FCT( send_simple(conn, buf, len) );
    17591833                                        } else {
    1760                                                 /* push the record to the appropriate session */
    1761                                                 ssize_t ret;
    1762                                                 size_t sent = 0;
    1763                                                 ASSERT(conn->cc_sctp3436_data.array != NULL);
    1764                                                 do {
    1765                                                         CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctp3436_data.array[conn->cc_sctp_para.next].session, buf + sent, len - sent), );
    1766                                                         if (ret <= 0)
    1767                                                                 return ENOTCONN;
    1768 
    1769                                                         sent += ret;
    1770                                                 } while ( sent < len );
     1834                                                if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) {
     1835                                                        CHECK_FCT_DO( fd_sctp_sendstr(conn, conn->cc_sctp_para.next, buf, len), { fd_cnx_markerror(conn); return ENOTCONN; } );
     1836                                                } else {
     1837                                                        /* push the record to the appropriate session */
     1838                                                        ssize_t ret;
     1839                                                        size_t sent = 0;
     1840                                                        ASSERT(conn->cc_sctp3436_data.array != NULL);
     1841                                                        do {
     1842                                                                CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctp3436_data.array[conn->cc_sctp_para.next].session, buf + sent, len - sent), );
     1843                                                                if (ret <= 0)
     1844                                                                        return ENOTCONN;
     1845
     1846                                                                sent += ret;
     1847                                                        } while ( sent < len );
     1848                                                }
    17711849                                        }
    17721850                                }
     1851                        } else {
     1852                                /* DTLS */
     1853                                /* We signal the push function directly to tell if using stream 0 or round-robin */
     1854                                TODO("DTLS send");
     1855                                return ENOTSUP;
    17731856                        }
    17741857                }
     
    18021885        if (fd_cnx_teststate(conn, CC_STATUS_TLS)) {
    18031886#ifndef DISABLE_SCTP
    1804                 if (conn->cc_sctp_para.pairs > 1) {
     1887                int dtls = fd_cnx_uses_dtls(conn);
     1888                if ((!dtls) && (conn->cc_sctp_para.pairs > 1)) {
    18051889                        if (! fd_cnx_teststate(conn, CC_STATUS_ERROR )) {
    18061890                                /* Bye on master session */
  • libfdcore/cnxctx.h

    r1180 r1181  
    4141/* The connection context structure */
    4242struct cnxctx {
    43         char            cc_id[60];      /* The name of this connection */
     43        char            cc_id[60];      /* The name of this connection. the first 5 chars are reserved for flags display (cc_state). */
    4444        char            cc_remid[60];   /* Id of remote peer */
    4545       
     
    6565                DiamId_t                         cn;            /* If not NULL, remote certif will be checked to match this Common Name */
    6666                int                              mode;          /* GNUTLS_CLIENT / GNUTLS_SERVER */
     67                int                              algo;          /* ALGO_HANDSHAKE_DEFAULT / ALGO_HANDSHAKE_3436 */
    6768                gnutls_session_t                 session;       /* Session object (stream #0 in case of SCTP) */
    6869        }               cc_tls_para;
     
    9798/* TLS */
    9899int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session);
    99 int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority, void * alt_creds);
     100int fd_tls_prepare(gnutls_session_t * session, int mode, int dtls, char * priority, void * alt_creds);
    100101#ifndef GNUTLS_VERSION_300
    101102int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, int verbose);
  • libfdcore/config.c

    r1155 r1181  
    9494        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local port ............. : %hu\n", fd_g_config->cnf_port), return NULL);
    9595        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local secure port ...... : %hu\n", fd_g_config->cnf_port_tls), return NULL);
     96        if (fd_g_config->cnf_port_3436) {
     97                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Local SCTP TLS port .... : %hu\n", fd_g_config->cnf_port_3436), return NULL);
     98        }
    9699        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Number of SCTP streams . : %hu\n", fd_g_config->cnf_sctp_str), return NULL);
    97100        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  Number of server threads : %hu\n", fd_g_config->cnf_dispthr), return NULL);
  • libfdcore/fdcore-internal.h

    r1102 r1181  
    342342int             fd_cnx_start_clear(struct cnxctx * conn, int loop);
    343343void            fd_cnx_sethostname(struct cnxctx * conn, DiamId_t hn);
    344 int             fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds);
     344#define ALGO_HANDSHAKE_DEFAULT  0 /* TLS for TCP, DTLS for SCTP */
     345#define ALGO_HANDSHAKE_3436     1 /* For TLS for SCTP also */
     346int             fd_cnx_handshake(struct cnxctx * conn, int mode, int algo, char * priority, void * alt_creds);
    345347char *          fd_cnx_getid(struct cnxctx * conn);
    346348int             fd_cnx_getproto(struct cnxctx * conn);
  • libfdcore/p_ce.c

    r1155 r1181  
    786786                } else {
    787787                        fd_psm_change_state(peer, STATE_OPEN_HANDSHAKE);
    788                         CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_CLIENT, peer->p_hdr.info.config.pic_priority, NULL),
     788                        CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_CLIENT, ALGO_HANDSHAKE_3436, peer->p_hdr.info.config.pic_priority, NULL),
    789789                                {
    790790                                        /* Handshake failed ...  */
     
    955955        if (isi & PI_SEC_TLS_OLD) {
    956956                fd_psm_change_state(peer, STATE_OPEN_HANDSHAKE);
    957                 CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_SERVER, peer->p_hdr.info.config.pic_priority, NULL),
     957                CHECK_FCT_DO( fd_cnx_handshake(peer->p_cnxctx, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, peer->p_hdr.info.config.pic_priority, NULL),
    958958                        {
    959959                                /* Handshake failed ...  */
  • libfdcore/p_cnx.c

    r1155 r1181  
    282282        /* Handshake if needed (secure port) */
    283283        if (nc->dotls) {
    284                 CHECK_FCT_DO( fd_cnx_handshake(cnx, GNUTLS_CLIENT, peer->p_hdr.info.config.pic_priority, NULL),
     284                CHECK_FCT_DO( fd_cnx_handshake(cnx, GNUTLS_CLIENT,
     285                                                (peer->p_hdr.info.config.pic_flags.sctpsec == PI_SCTPSEC_3436) ? ALGO_HANDSHAKE_3436 : ALGO_HANDSHAKE_DEFAULT,
     286                                                peer->p_hdr.info.config.pic_priority, NULL),
    285287                        {
    286288                                /* Handshake failed ...  */
  • libfdcore/p_psm.c

    r1120 r1181  
    785785                        case STATE_WAITCNXACK_ELEC:
    786786                        case STATE_WAITCNXACK:
    787                                 LOG_D("%s: Connection established", peer->p_hdr.info.pi_diamid);
     787                                LOG_D("%s: Connection established, %s", peer->p_hdr.info.pi_diamid, fd_cnx_getid(cnx));
    788788                                fd_p_ce_handle_newcnx(peer, cnx);
    789789                                break;
  • libfdcore/peers.c

    r1113 r1181  
    430430                }
    431431                if (details > 1) {
    432                         CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " [from:%s] flags:%s%s%s%s%s%s%s lft:%ds",
     432                        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " [from:%s] flags:%s%s%s%s%s%s%s%s lft:%ds",
    433433                                peer->p_dbgorig ?: "unset",
    434434                                peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_DEFAULT ? "-" :
     
    439439                                peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE ? "N" :"-",
    440440                                peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD ? "O" :"-",
     441                                peer->p_hdr.info.config.pic_flags.sctpsec & PI_SCTPSEC_3436 ? "3" :"-",
    441442                                peer->p_hdr.info.config.pic_flags.exp ? "E" : "-",
    442443                                peer->p_hdr.info.config.pic_flags.persist ? "P" : "-",
  • libfdcore/sctp3436.c

    r1180 r1181  
    566566        for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
    567567                /* Set credentials and priority */
    568                 CHECK_FCT( fd_tls_prepare(&conn->cc_sctp3436_data.array[i].session, conn->cc_tls_para.mode, priority, alt_creds) );
     568                CHECK_FCT( fd_tls_prepare(&conn->cc_sctp3436_data.array[i].session, conn->cc_tls_para.mode, 0, priority, alt_creds) );
    569569               
    570570                /* additional initialization for gnutls 3.x */
  • libfdcore/server.c

    r1136 r1181  
    5454        struct cnxctx * conn;           /* server connection context (listening socket) */
    5555        int             proto;          /* IPPROTO_TCP or IPPROTO_SCTP */
    56         int             secur;          /* TLS is started immediatly after connection ? */
     56        int             secur;          /* TLS is started immediatly after connection ? 0: no; 1: yes (TLS/TCP or DTLS/SCTP); 2: yes (TLS/TCP or TLS/SCTP) */
    5757       
    5858        pthread_t       thr;            /* The thread listening for new connections */
     
    105105               
    106106                if (details) {
    107                         CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s, %s", s, fd_cnx_getid(s->conn),
     107                        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s(%d), %s", s, fd_cnx_getid(s->conn),
    108108                                        IPPROTO_NAME( s->proto ),
    109                                         s->secur ? "Secur" : "NotSecur",
     109                                        s->secur ? "Secur" : "NotSecur", s->secur,
    110110                                        (st == NOT_CREATED) ? "Thread not created" :
    111111                                        ((st == RUNNING) ? "Thread running" :
     
    147147        TRACE_ENTRY("%p", c);
    148148       
     149        memset(&rcv_data, 0, sizeof(rcv_data));
     150       
    149151        CHECK_PARAMS_DO(c && c->conn && c->chain.head, goto fatal_error );
     152       
    150153       
    151154        s = c->chain.head->o;
     
    156159        /* Handshake if we are a secure server port, or start clear otherwise */
    157160        if (s->secur) {
    158                 int ret = fd_cnx_handshake(c->conn, GNUTLS_SERVER, NULL, NULL);
     161                int ret = fd_cnx_handshake(c->conn, GNUTLS_SERVER, (s->secur == 1) ? ALGO_HANDSHAKE_DEFAULT : ALGO_HANDSHAKE_3436, NULL, NULL);
    159162                if (ret != 0) {
    160163                        char buf[1024];
     
    360363                        CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 1) );
    361364                        CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_tls, empty_conf_ep ? NULL : &fd_g_config->cnf_endpoints) );
     365                        fd_list_insert_before( &FD_SERVERS, &s->chain );
     366                        CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
     367                }
     368               
     369                /* Create the other server on 3436 secure port */
     370                if (fd_g_config->cnf_port_3436) {
     371                        CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 2) );
     372                        CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_3436, empty_conf_ep ? NULL : &fd_g_config->cnf_endpoints) );
    362373                        fd_list_insert_before( &FD_SERVERS, &s->chain );
    363374                        CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
  • tests/testcnx.c

    r1127 r1181  
    549549        struct cnxctx * cnx;
    550550        gnutls_certificate_credentials_t        creds;
     551        int algo;
    551552        int ret;
    552553};
     
    557558        struct handshake_flags * hf = arg;
    558559        fd_log_threadname ( "testcnx:handshake" );
    559         hf->ret = fd_cnx_handshake(hf->cnx, GNUTLS_CLIENT, NULL, hf->creds);
     560        hf->ret = fd_cnx_handshake(hf->cnx, GNUTLS_CLIENT, hf->algo, NULL, hf->creds);
    560561        return NULL;
    561562}
     
    864865                /* At this point in legacy Diameter we start the handshake */
    865866                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    866                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     867                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT /* No impact on TCP */, NULL, NULL) );
    867868                CHECK( 0, pthread_join(thr, NULL) );
    868869                CHECK( 0, hf.ret );
     
    905906               
    906907                memset(&hf, 0, sizeof(hf));
     908                hf.algo = ALGO_HANDSHAKE_3436; /* this is mandatory for old TLS mechanism */
    907909               
    908910                /* Initialize remote certificate */
     
    949951                /* At this point in legacy Diameter we start the handshake */
    950952                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    951                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     953                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, NULL, NULL) );
    952954                CHECK( 0, pthread_join(thr, NULL) );
    953955                CHECK( 0, hf.ret );
     
    10151017                /* Start the handshake directly */
    10161018                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1017                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1019                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    10181020                CHECK( 0, pthread_join(thr, NULL) );
    10191021                CHECK( 0, hf.ret );
     
    10461048       
    10471049#ifndef DISABLE_SCTP
    1048         /* SCTP Client / server emulating new Diameter behavior (handshake at connection directly) */
     1050       
     1051       
     1052        /* SCTP Client / server emulating new Diameter behavior (DTLS handshake at connection directly) */
     1053        TODO("Enabled after DTLS implementation");
     1054        if (0)
    10491055        {
    10501056                struct connect_flags cf;
     
    10801086                /* Start the handshake directly */
    10811087                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1082                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1088                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    10831089                CHECK( 0, pthread_join(thr, NULL) );
    10841090                CHECK( 0, hf.ret );
     
    11101116                gnutls_certificate_free_credentials(hf.creds);
    11111117        }
    1112 #endif /* DISABLE_SCTP */
    1113        
    1114         /* Test with different number of streams between server and client */
    1115 #ifndef DISABLE_SCTP
     1118       
     1119        /* SCTP Client / server emulating old intermediary Diameter behavior (TLS handshake at connection directly) */
    11161120        {
    11171121                struct connect_flags cf;
     
    11221126               
    11231127                memset(&hf, 0, sizeof(hf));
     1128                hf.algo = ALGO_HANDSHAKE_3436; /* this is mandatory for old TLS mechanism */
    11241129               
    11251130                /* Initialize remote certificate */
     
    11331138                CHECK( GNUTLS_E_SUCCESS, ret );
    11341139               
    1135                 /* Start the client thread with more streams than the server */
    1136                 fd_g_config->cnf_sctp_str = 2 * NB_STREAMS;
     1140                /* Start the client thread */
    11371141                CHECK( 0, pthread_create(&thr, NULL, connect_thr, &cf) );
    11381142
     
    11481152                /* Start the handshake directly */
    11491153                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1150                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1154                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, NULL, NULL) );
     1155                CHECK( 0, pthread_join(thr, NULL) );
     1156                CHECK( 0, hf.ret );
     1157               
     1158                /* Send a few TLS protected messages, and replies */
     1159                for (i = 0; i < 2 * NB_STREAMS; i++) {
     1160                        CHECK( 0, fd_cnx_send(server_side, cer_buf, cer_sz, 0));
     1161                        CHECK( 0, fd_cnx_receive(client_side, NULL, &rcv_buf, &rcv_sz));
     1162                        CHECK( cer_sz, rcv_sz );
     1163                        CHECK( 0, memcmp( rcv_buf, cer_buf, cer_sz ) );
     1164                        free(rcv_buf);
     1165
     1166                        CHECK( 0, fd_cnx_send(client_side, cer_buf, cer_sz, 0));
     1167                        CHECK( 0, fd_cnx_receive(server_side, NULL, &rcv_buf, &rcv_sz));
     1168                        CHECK( cer_sz, rcv_sz );
     1169                        CHECK( 0, memcmp( rcv_buf, cer_buf, cer_sz ) );
     1170                        free(rcv_buf);
     1171                }
     1172               
     1173               
     1174                /* Now close the connection */
     1175                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
     1176                fd_cnx_destroy(server_side);
     1177                CHECK( 0, pthread_join(thr, NULL) );
     1178               
     1179                /* Free the credentials */
     1180                gnutls_certificate_free_keys(hf.creds);
     1181                gnutls_certificate_free_cas(hf.creds);
     1182                gnutls_certificate_free_credentials(hf.creds);
     1183        }
     1184#endif /* DISABLE_SCTP */
     1185       
     1186        /* Test with different number of streams between server and client */
     1187#ifndef DISABLE_SCTP
     1188        /* DTLS / SCTP style */
     1189        TODO("Enabled after DTLS implementation");
     1190        if (0)
     1191        {
     1192                struct connect_flags cf;
     1193                struct handshake_flags hf;
     1194               
     1195                memset(&cf, 0, sizeof(cf));
     1196                cf.proto = IPPROTO_SCTP;
     1197               
     1198                memset(&hf, 0, sizeof(hf));
     1199               
     1200                /* Initialize remote certificate */
     1201                CHECK_GNUTLS_DO( ret = gnutls_certificate_allocate_credentials (&hf.creds), );
     1202                CHECK( GNUTLS_E_SUCCESS, ret );
     1203                /* Set the CA */
     1204                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &ca, GNUTLS_X509_FMT_PEM), );
     1205                CHECK( 1, ret );
     1206                /* Set the key */
     1207                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_key_mem( hf.creds, &client_cert, &client_priv, GNUTLS_X509_FMT_PEM), );
     1208                CHECK( GNUTLS_E_SUCCESS, ret );
     1209               
     1210                /* Start the client thread with more streams than the server */
     1211                fd_g_config->cnf_sctp_str = 2 * NB_STREAMS;
     1212                CHECK( 0, pthread_create(&thr, NULL, connect_thr, &cf) );
     1213
     1214                /* Accept the connection of the client */
     1215                server_side = fd_cnx_serv_accept(listener_sctp);
     1216                CHECK( 1, server_side ? 1 : 0 );
     1217               
     1218                /* Retrieve the client connection object */
     1219                CHECK( 0, pthread_join( thr, (void *)&client_side ) );
     1220                CHECK( 1, client_side ? 1 : 0 );
     1221                hf.cnx = client_side;
     1222               
     1223                /* Start the handshake directly */
     1224                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
     1225                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    11511226                CHECK( 0, pthread_join(thr, NULL) );
    11521227                CHECK( 0, hf.ret );
     
    11871262                /* Start the handshake directly */
    11881263                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1189                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1264                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    11901265                CHECK( 0, pthread_join(thr, NULL) );
    11911266                CHECK( 0, hf.ret );
     
    12171292                gnutls_certificate_free_credentials(hf.creds);
    12181293        }
     1294       
     1295        /* TLS / SCTP style */
     1296        {
     1297                struct connect_flags cf;
     1298                struct handshake_flags hf;
     1299               
     1300                memset(&cf, 0, sizeof(cf));
     1301                cf.proto = IPPROTO_SCTP;
     1302               
     1303                memset(&hf, 0, sizeof(hf));
     1304                hf.algo = ALGO_HANDSHAKE_3436;
     1305               
     1306                /* Initialize remote certificate */
     1307                CHECK_GNUTLS_DO( ret = gnutls_certificate_allocate_credentials (&hf.creds), );
     1308                CHECK( GNUTLS_E_SUCCESS, ret );
     1309                /* Set the CA */
     1310                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &ca, GNUTLS_X509_FMT_PEM), );
     1311                CHECK( 1, ret );
     1312                /* Set the key */
     1313                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_key_mem( hf.creds, &client_cert, &client_priv, GNUTLS_X509_FMT_PEM), );
     1314                CHECK( GNUTLS_E_SUCCESS, ret );
     1315               
     1316                /* Start the client thread with more streams than the server */
     1317                fd_g_config->cnf_sctp_str = 2 * NB_STREAMS;
     1318                CHECK( 0, pthread_create(&thr, NULL, connect_thr, &cf) );
     1319
     1320                /* Accept the connection of the client */
     1321                server_side = fd_cnx_serv_accept(listener_sctp);
     1322                CHECK( 1, server_side ? 1 : 0 );
     1323               
     1324                /* Retrieve the client connection object */
     1325                CHECK( 0, pthread_join( thr, (void *)&client_side ) );
     1326                CHECK( 1, client_side ? 1 : 0 );
     1327                hf.cnx = client_side;
     1328               
     1329                /* Start the handshake directly */
     1330                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
     1331                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, NULL, NULL) );
     1332                CHECK( 0, pthread_join(thr, NULL) );
     1333                CHECK( 0, hf.ret );
     1334               
     1335                /* Send a few TLS protected message, and replies */
     1336                for (i = 0; i < 4 * NB_STREAMS; i++) {
     1337                        CHECK( 0, fd_cnx_send(server_side, cer_buf, cer_sz, 0));
     1338                        CHECK( 0, fd_cnx_receive(client_side, NULL, &rcv_buf, &rcv_sz));
     1339                        CHECK( cer_sz, rcv_sz );
     1340                        CHECK( 0, memcmp( rcv_buf, cer_buf, cer_sz ) );
     1341                        free(rcv_buf);
     1342
     1343                        CHECK( 0, fd_cnx_send(client_side, cer_buf, cer_sz, 0));
     1344                        CHECK( 0, fd_cnx_receive(server_side, NULL, &rcv_buf, &rcv_sz));
     1345                        CHECK( cer_sz, rcv_sz );
     1346                        CHECK( 0, memcmp( rcv_buf, cer_buf, cer_sz ) );
     1347                        free(rcv_buf);
     1348                }
     1349               
     1350                /* Now close the connection */
     1351                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
     1352                fd_cnx_destroy(server_side);
     1353                CHECK( 0, pthread_join(thr, NULL) );
     1354               
     1355                /* Do the same test but with more streams on the server this time */
     1356                fd_g_config->cnf_sctp_str = NB_STREAMS / 2;
     1357                CHECK( 0, pthread_create(&thr, NULL, connect_thr, &cf) );
     1358
     1359                /* Accept the connection of the client */
     1360                server_side = fd_cnx_serv_accept(listener_sctp);
     1361                CHECK( 1, server_side ? 1 : 0 );
     1362               
     1363                /* Retrieve the client connection object */
     1364                CHECK( 0, pthread_join( thr, (void *)&client_side ) );
     1365                CHECK( 1, client_side ? 1 : 0 );
     1366                hf.cnx = client_side;
     1367               
     1368                /* Start the handshake directly */
     1369                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
     1370                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, NULL, NULL) );
     1371                CHECK( 0, pthread_join(thr, NULL) );
     1372                CHECK( 0, hf.ret );
     1373               
     1374                /* Send a few TLS protected message, and replies */
     1375                for (i = 0; i < 2 * NB_STREAMS; i++) {
     1376                        CHECK( 0, fd_cnx_send(server_side, cer_buf, cer_sz, 0));
     1377                        CHECK( 0, fd_cnx_receive(client_side, NULL, &rcv_buf, &rcv_sz));
     1378                        CHECK( cer_sz, rcv_sz );
     1379                        CHECK( 0, memcmp( rcv_buf, cer_buf, cer_sz ) );
     1380                        free(rcv_buf);
     1381
     1382                        CHECK( 0, fd_cnx_send(client_side, cer_buf, cer_sz, 0));
     1383                        CHECK( 0, fd_cnx_receive(server_side, NULL, &rcv_buf, &rcv_sz));
     1384                        CHECK( cer_sz, rcv_sz );
     1385                        CHECK( 0, memcmp( rcv_buf, cer_buf, cer_sz ) );
     1386                        free(rcv_buf);
     1387                }
     1388               
     1389                /* Now close the connection */
     1390                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
     1391                fd_cnx_destroy(server_side);
     1392                CHECK( 0, pthread_join(thr, NULL) );
     1393               
     1394               
     1395                /* Free the credentials */
     1396                gnutls_certificate_free_keys(hf.creds);
     1397                gnutls_certificate_free_cas(hf.creds);
     1398                gnutls_certificate_free_credentials(hf.creds);
     1399        }
     1400       
    12191401#endif /* DISABLE_SCTP */
    12201402       
     
    12571439                /* Start the handshake directly */
    12581440                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1259                 CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1441                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    12601442                fd_cnx_destroy(server_side);
    12611443               
     
    12741456        /* Same in SCTP */
    12751457#ifndef DISABLE_SCTP
     1458        /* DTLS */
     1459        TODO("Enabled after DTLS implementation");
     1460        if (0)
    12761461        {
    12771462                struct connect_flags cf;
     
    13081493                /* Start the handshake directly */
    13091494                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1310                 CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1495                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
     1496                fd_cnx_destroy(server_side);
     1497                CHECK( 0, pthread_join(thr, NULL) );
     1498               
     1499                /* Now close the connection */
     1500                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
     1501                CHECK( 0, pthread_join(thr, NULL) );
     1502               
     1503                /* Free the credentials */
     1504                gnutls_certificate_free_keys(hf.creds);
     1505                gnutls_certificate_free_cas(hf.creds);
     1506                gnutls_certificate_free_credentials(hf.creds);
     1507        }
     1508       
     1509        /* TLS */
     1510        {
     1511                struct connect_flags cf;
     1512                struct handshake_flags hf;
     1513               
     1514                memset(&cf, 0, sizeof(cf));
     1515                cf.proto = IPPROTO_SCTP;
     1516               
     1517                memset(&hf, 0, sizeof(hf));
     1518                hf.algo = ALGO_HANDSHAKE_3436;
     1519               
     1520                /* Initialize remote certificate */
     1521                CHECK_GNUTLS_DO( ret = gnutls_certificate_allocate_credentials (&hf.creds), );
     1522                CHECK( GNUTLS_E_SUCCESS, ret );
     1523                /* Set the CA */
     1524                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &notrust_ca, GNUTLS_X509_FMT_PEM), );
     1525                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &ca, GNUTLS_X509_FMT_PEM), );
     1526                CHECK( 1, ret );
     1527                /* Set the key */
     1528                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_key_mem( hf.creds, &notrust_cert, &notrust_priv, GNUTLS_X509_FMT_PEM), );
     1529                CHECK( GNUTLS_E_SUCCESS, ret );
     1530               
     1531                /* Start the client thread */
     1532                CHECK( 0, pthread_create(&thr, NULL, connect_thr, &cf) );
     1533
     1534                /* Accept the connection of the client */
     1535                server_side = fd_cnx_serv_accept(listener_sctp);
     1536                CHECK( 1, server_side ? 1 : 0 );
     1537               
     1538                /* Retrieve the client connection object */
     1539                CHECK( 0, pthread_join( thr, (void *)&client_side ) );
     1540                CHECK( 1, client_side ? 1 : 0 );
     1541                hf.cnx = client_side;
     1542               
     1543                /* Start the handshake directly */
     1544                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
     1545                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, NULL, NULL) );
    13111546                fd_cnx_destroy(server_side);
    13121547                CHECK( 0, pthread_join(thr, NULL) );
     
    13571592                /* Start the handshake directly */
    13581593                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1359                 CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1594                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    13601595                fd_cnx_destroy(server_side);
    13611596                CHECK( 0, pthread_join(thr, NULL) );
     
    14091644                /* Start the handshake, check it is successful */
    14101645                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1411                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1646                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    14121647                CHECK( 0, pthread_join(thr, NULL) );
    14131648                CHECK( 0, hf.ret );
     
    14351670                /* Start the handshake, check it is successful */
    14361671                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1437                 CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1672                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    14381673                fd_cnx_destroy(server_side);
    14391674                CHECK( 0, pthread_join(thr, NULL) );
     
    14891724                /* Start the handshake */
    14901725                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1491                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1726                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    14921727                CHECK( 0, pthread_join(thr, NULL) );
    14931728                CHECK( 0, hf.ret );
     
    15431778#ifndef DISABLE_SCTP
    15441779        /* And re-test with a SCTP connection */
     1780        TODO("Enabled after DTLS implementation");
     1781        if (0)
    15451782        {
    15461783                struct connect_flags cf;
     
    15821819                /* Start the handshake */
    15831820                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    1584                 CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1821                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_DEFAULT, NULL, NULL) );
    15851822                CHECK( 0, pthread_join(thr, NULL) );
    15861823                CHECK( 0, hf.ret );
     
    16331870                gnutls_certificate_free_credentials(hf.creds);
    16341871        }
     1872       
     1873        /* TLS */
     1874        {
     1875                struct connect_flags cf;
     1876                struct handshake_flags hf;
     1877                char * str;
     1878                const gnutls_datum_t *cert_list;
     1879                unsigned int cert_list_size;
     1880                struct fifo * myfifo = NULL;
     1881                struct timespec now;
     1882                int ev_code;
     1883               
     1884                memset(&cf, 0, sizeof(cf));
     1885                cf.proto = IPPROTO_SCTP;
     1886               
     1887                memset(&hf, 0, sizeof(hf));
     1888                hf.algo = ALGO_HANDSHAKE_3436;
     1889               
     1890                /* Initialize remote certificate */
     1891                CHECK_GNUTLS_DO( ret = gnutls_certificate_allocate_credentials (&hf.creds), );
     1892                CHECK( GNUTLS_E_SUCCESS, ret );
     1893                /* Set the CA */
     1894                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &ca, GNUTLS_X509_FMT_PEM), );
     1895                CHECK( 1, ret );
     1896                /* Set the key */
     1897                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_key_mem( hf.creds, &client_cert, &client_priv, GNUTLS_X509_FMT_PEM), );
     1898                CHECK( GNUTLS_E_SUCCESS, ret );
     1899               
     1900                /* Start the client thread */
     1901                CHECK( 0, pthread_create(&thr, NULL, connect_thr, &cf) );
     1902
     1903                /* Accept the connection of the client */
     1904                server_side = fd_cnx_serv_accept(listener_sctp);
     1905                CHECK( 1, server_side ? 1 : 0 );
     1906               
     1907                /* Retrieve the client connection object */
     1908                CHECK( 0, pthread_join( thr, (void *)&client_side ) );
     1909                CHECK( 1, client_side ? 1 : 0 );
     1910                hf.cnx = client_side;
     1911               
     1912                /* Start the handshake */
     1913                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
     1914                CHECK( 0, fd_cnx_handshake(server_side, GNUTLS_SERVER, ALGO_HANDSHAKE_3436, NULL, NULL) );
     1915                CHECK( 0, pthread_join(thr, NULL) );
     1916                CHECK( 0, hf.ret );
     1917               
     1918                /* Test some simple functions */
     1919               
     1920                /* fd_cnx_getid */
     1921                str = fd_cnx_getid(server_side);
     1922                CHECK( 1, str ? 1 : 0 );
     1923                CHECK( 1, (str[0] != '\0') ? 1 : 0 );
     1924               
     1925                /* fd_cnx_getproto */
     1926                i = fd_cnx_getproto(server_side);
     1927                CHECK( IPPROTO_SCTP, i);
     1928               
     1929                /* fd_cnx_getTLS */
     1930                i = fd_cnx_getTLS(server_side);
     1931                CHECK( 1, i ? 1 : 0 );
     1932               
     1933                /* fd_cnx_getcred */
     1934                CHECK( 0, fd_cnx_getcred(server_side, &cert_list, &cert_list_size) );
     1935                CHECK( 1, (cert_list_size > 0) ? 1 : 0 );
     1936                /* We could also verify that the cert_list really contains the client_cert and ca certificates */
     1937               
     1938                /* fd_cnx_getremoteid */
     1939                str = fd_cnx_getremoteid(server_side);
     1940                CHECK( 1, str ? 1 : 0 );
     1941                CHECK( 1, (str[0] != '\0') ? 1 : 0 );
     1942               
     1943                /* fd_cnx_recv_setaltfifo */
     1944                CHECK( 0, fd_cnx_send(client_side, cer_buf, cer_sz, 0));
     1945                CHECK( 0, fd_fifo_new(&myfifo, 0) );
     1946                CHECK( 0, fd_cnx_recv_setaltfifo(server_side, myfifo) );
     1947                CHECK( 0, clock_gettime(CLOCK_REALTIME, &now) );
     1948                do {
     1949                        CHECK( 0, fd_event_timedget(myfifo, &now, ETIMEDOUT, &ev_code, NULL, (void *)&rcv_buf) );
     1950                        free(rcv_buf);
     1951                } while (ev_code != FDEVP_CNX_MSG_RECV);
     1952               
     1953                /* Now close the connection */
     1954                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
     1955                fd_cnx_destroy(server_side);
     1956                CHECK( 0, pthread_join(thr, NULL) );
     1957               
     1958                fd_event_destroy(&myfifo, free);
     1959               
     1960                /* Free the credentials */
     1961                gnutls_certificate_free_keys(hf.creds);
     1962                gnutls_certificate_free_cas(hf.creds);
     1963                gnutls_certificate_free_credentials(hf.creds);
     1964        }
    16351965#endif /* DISABLE_SCTP */
    16361966       
Note: See TracChangeset for help on using the changeset viewer.