Navigation


Changeset 807:09f8f0c4f4a4 in freeDiameter


Ignore:
Timestamp:
Aug 24, 2012, 7:15:48 AM (12 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Several changes to support GnuTLS 3.x in a more efficient way

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • libfdcore/cnxctx.c

    r803 r807  
    587587       
    588588        TRACE_DEBUG(FULL, "Error flag set for socket %d (%s, %s)", conn->cc_socket, conn->cc_id, conn->cc_remid);
    589        
     589
    590590        /* Mark the error */
    591591        fd_cnx_addstate(conn, CC_STATUS_ERROR);
     
    597597                fd_cnx_addstate(conn, CC_STATUS_SIGNALED);
    598598        }
     599       
    599600        return;
    600601fatal:
     
    843844                                case GNUTLS_E_REHANDSHAKE:
    844845                                        if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING)) {
    845                                                 #ifdef GNUTLS_VERSION_310
    846                                                 GNUTLS_TRACE( gnutls_handshake_set_timeout( session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT));
    847                                                 #endif /* GNUTLS_VERSION_310 */
    848846                                                CHECK_GNUTLS_DO( ret = gnutls_handshake(session),
    849847                                                        {
     
    891889                                case GNUTLS_E_REHANDSHAKE:
    892890                                        if (!fd_cnx_teststate(conn, CC_STATUS_CLOSING)) {
    893                                                 #ifdef GNUTLS_VERSION_310
    894                                                 GNUTLS_TRACE( gnutls_handshake_set_timeout( session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT));
    895                                                 #endif /* GNUTLS_VERSION_310 */
    896 
    897891                                                CHECK_GNUTLS_DO( ret = gnutls_handshake(session),
    898892                                                        {
     
    10311025                gnutls_certificate_server_set_request (*session, GNUTLS_CERT_REQUIRE);
    10321026        }
    1033        
     1027               
    10341028        return 0;
    10351029}
     1030
     1031#ifndef GNUTLS_VERSION_300
    10361032
    10371033/* Verify remote credentials after successful handshake (return 0 if OK, EINVAL otherwise) */
     
    12541250}
    12551251
     1252#else /* GNUTLS_VERSION_300 */
     1253
     1254/* Verify remote credentials DURING handshake (return gnutls status) */
     1255int fd_tls_verify_credentials_2(gnutls_session_t session)
     1256{
     1257        /* inspired from gnutls 3.x guidelines */
     1258        unsigned int status;
     1259        const gnutls_datum_t *cert_list = NULL;
     1260        unsigned int cert_list_size;
     1261        gnutls_x509_crt_t cert;
     1262        struct cnxctx * conn;
     1263        int hostname_verified = 0;
     1264
     1265        TRACE_ENTRY("%p", session);
     1266       
     1267        /* get the associated connection */
     1268        conn = gnutls_session_get_ptr (session);
     1269       
     1270        /* Trace the session information -- http://www.gnu.org/software/gnutls/manual/gnutls.html#Obtaining-session-information */
     1271        if (TRACE_BOOL(FULL)) {
     1272                const char *tmp;
     1273                gnutls_credentials_type_t cred;
     1274                gnutls_kx_algorithm_t kx;
     1275                int dhe, ecdh;
     1276
     1277                dhe = ecdh = 0;
     1278
     1279                fd_log_debug("TLS Session information for connection '%s':\n", conn->cc_id);
     1280               
     1281                /* print the key exchange's algorithm name
     1282                */
     1283                GNUTLS_TRACE( kx = gnutls_kx_get (session) );
     1284                GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) );
     1285                fd_log_debug("\t- Key Exchange: %s\n", tmp);
     1286
     1287                /* Check the authentication type used and switch
     1288                * to the appropriate.
     1289                */
     1290                GNUTLS_TRACE( cred = gnutls_auth_get_type (session) );
     1291                switch (cred)
     1292                {
     1293                        case GNUTLS_CRD_IA:
     1294                                fd_log_debug("\t - TLS/IA session\n");
     1295                                break;
     1296
     1297
     1298                        #ifdef ENABLE_SRP
     1299                        case GNUTLS_CRD_SRP:
     1300                                fd_log_debug("\t - SRP session with username %s\n",
     1301                                        gnutls_srp_server_get_username (session));
     1302                                break;
     1303                        #endif
     1304
     1305                        case GNUTLS_CRD_PSK:
     1306                                /* This returns NULL in server side.
     1307                                */
     1308                                if (gnutls_psk_client_get_hint (session) != NULL)
     1309                                        fd_log_debug("\t - PSK authentication. PSK hint '%s'\n",
     1310                                                gnutls_psk_client_get_hint (session));
     1311                                /* This returns NULL in client side.
     1312                                */
     1313                                if (gnutls_psk_server_get_username (session) != NULL)
     1314                                        fd_log_debug("\t - PSK authentication. Connected as '%s'\n",
     1315                                                gnutls_psk_server_get_username (session));
     1316
     1317                                if (kx == GNUTLS_KX_ECDHE_PSK)
     1318                                        ecdh = 1;
     1319                                else if (kx == GNUTLS_KX_DHE_PSK)
     1320                                        dhe = 1;
     1321                                break;
     1322
     1323                        case GNUTLS_CRD_ANON:      /* anonymous authentication */
     1324                                fd_log_debug("\t - Anonymous DH using prime of %d bits\n",
     1325                                        gnutls_dh_get_prime_bits (session));
     1326                                if (kx == GNUTLS_KX_ANON_ECDH)
     1327                                        ecdh = 1;
     1328                                else if (kx == GNUTLS_KX_ANON_DH)
     1329                                        dhe = 1;
     1330                                break;
     1331
     1332                        case GNUTLS_CRD_CERTIFICATE:       /* certificate authentication */
     1333
     1334                                /* Check if we have been using ephemeral Diffie-Hellman.
     1335                                */
     1336                                if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
     1337                                        dhe = 1;
     1338                                else if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA)
     1339                                        ecdh = 1;
     1340                               
     1341                                /* Now print some info on the remote certificate */
     1342                                if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509) {
     1343                                        gnutls_datum_t cinfo;
     1344
     1345                                        cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
     1346
     1347                                        fd_log_debug("\t Peer provided %d certificates.\n", cert_list_size);
     1348
     1349                                        if (cert_list_size > 0)
     1350                                        {
     1351                                                int ret;
     1352
     1353                                                /* we only print information about the first certificate.
     1354                                                */
     1355                                                gnutls_x509_crt_init (&cert);
     1356
     1357                                                gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER);
     1358
     1359                                                fd_log_debug("\t Certificate info:\n");
     1360
     1361                                                /* This is the preferred way of printing short information about
     1362                                                 a certificate. */
     1363
     1364                                                ret = gnutls_x509_crt_print (cert, GNUTLS_CRT_PRINT_ONELINE, &cinfo);
     1365                                                if (ret == 0)
     1366                                                {
     1367                                                  fd_log_debug("\t\t%s\n", cinfo.data);
     1368                                                  gnutls_free (cinfo.data);
     1369                                                }
     1370                                               
     1371                                                if (conn->cc_tls_para.cn) {
     1372                                                        if (!gnutls_x509_crt_check_hostname (cert, conn->cc_tls_para.cn)) {
     1373                                                                fd_log_debug("\tTLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     1374                                                                fd_log_debug("\t - The certificate hostname does not match '%s'\n", conn->cc_tls_para.cn);
     1375                                                                gnutls_x509_crt_deinit (cert);
     1376                                                                return GNUTLS_E_CERTIFICATE_ERROR;
     1377                                                        }
     1378                                                       
     1379                                                }
     1380
     1381                                                hostname_verified = 1;
     1382
     1383                                                gnutls_x509_crt_deinit (cert);
     1384
     1385                                        }
     1386                                }
     1387                                break;
     1388
     1389                }                           /* switch */
     1390
     1391                if (ecdh != 0)
     1392                        fd_log_debug("\t - Ephemeral ECDH using curve %s\n",
     1393                                gnutls_ecc_curve_get_name (gnutls_ecc_curve_get (session)));
     1394                else if (dhe != 0)
     1395                        fd_log_debug("\t - Ephemeral DH using prime of %d bits\n",
     1396                                gnutls_dh_get_prime_bits (session));
     1397
     1398                /* print the protocol's name (ie TLS 1.0)
     1399                */
     1400                tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
     1401                fd_log_debug("\t - Protocol: %s\n", tmp);
     1402
     1403                /* print the certificate type of the peer.
     1404                * ie X.509
     1405                */
     1406                tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session));
     1407                fd_log_debug("\t - Certificate Type: %s\n", tmp);
     1408
     1409                /* print the compression algorithm (if any)
     1410                */
     1411                tmp = gnutls_compression_get_name (gnutls_compression_get (session));
     1412                fd_log_debug("\t - Compression: %s\n", tmp);
     1413
     1414                /* print the name of the cipher used.
     1415                * ie 3DES.
     1416                */
     1417                tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
     1418                fd_log_debug("\t - Cipher: %s\n", tmp);
     1419
     1420                /* Print the MAC algorithms name.
     1421                * ie SHA1
     1422                */
     1423                tmp = gnutls_mac_get_name (gnutls_mac_get (session));
     1424                fd_log_debug("\t - MAC: %s\n", tmp);
     1425       
     1426        }
     1427
     1428        /* This verification function uses the trusted CAs in the credentials
     1429        * structure. So you must have installed one or more CA certificates.
     1430        */
     1431        CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (session, &status), return GNUTLS_E_CERTIFICATE_ERROR );
     1432        if (TRACE_BOOL(INFO) && (status & GNUTLS_CERT_INVALID)) {
     1433                fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     1434                if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
     1435                        fd_log_debug(" - The certificate hasn't got a known issuer.\n");
     1436
     1437                if (status & GNUTLS_CERT_REVOKED)
     1438                        fd_log_debug(" - The certificate has been revoked.\n");
     1439
     1440                if (status & GNUTLS_CERT_EXPIRED)
     1441                        fd_log_debug(" - The certificate has expired.\n");
     1442
     1443                if (status & GNUTLS_CERT_NOT_ACTIVATED)
     1444                        fd_log_debug(" - The certificate is not yet activated.\n");
     1445        }       
     1446        if (status & GNUTLS_CERT_INVALID)
     1447        {
     1448                return GNUTLS_E_CERTIFICATE_ERROR;
     1449        }
     1450       
     1451        /* Up to here the process is the same for X.509 certificates and
     1452        * OpenPGP keys. From now on X.509 certificates are assumed. This can
     1453        * be easily extended to work with openpgp keys as well.
     1454        */
     1455        if ((!hostname_verified) && (conn->cc_tls_para.cn)) {
     1456                if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) {
     1457                        TRACE_DEBUG(INFO, "TLS: Remote credentials are not x509, rejected on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     1458                        return GNUTLS_E_CERTIFICATE_ERROR;
     1459                }
     1460
     1461                CHECK_GNUTLS_DO( gnutls_x509_crt_init (&cert), return GNUTLS_E_CERTIFICATE_ERROR );
     1462
     1463                cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
     1464                CHECK_PARAMS_DO( cert_list, return GNUTLS_E_CERTIFICATE_ERROR );
     1465
     1466                CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER), return GNUTLS_E_CERTIFICATE_ERROR );
     1467
     1468                if (!gnutls_x509_crt_check_hostname (cert, conn->cc_tls_para.cn)) {
     1469                        if (TRACE_BOOL(INFO)) {
     1470                                fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     1471                                fd_log_debug(" - The certificate hostname does not match '%s'\n", conn->cc_tls_para.cn);
     1472                        }
     1473                        gnutls_x509_crt_deinit (cert);
     1474                        return GNUTLS_E_CERTIFICATE_ERROR;
     1475                }
     1476
     1477                gnutls_x509_crt_deinit (cert);
     1478        }
     1479
     1480        /* notify gnutls to continue handshake normally */
     1481        return 0;
     1482}
     1483
     1484#endif /* GNUTLS_VERSION_300 */
     1485
    12561486/* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */
    12571487int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds)
     
    12891519                GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) );
    12901520        }
    1291 
     1521       
     1522        /* additional initialization for gnutls 3.x */
     1523        #ifdef GNUTLS_VERSION_300
     1524                /* the verify function has already been set in the global initialization in config.c */
     1525       
     1526        /* fd_tls_verify_credentials_2 uses the connection */
     1527        gnutls_session_set_ptr (conn->cc_tls_para.session, (void *) conn);
     1528       
     1529        if ((conn->cc_tls_para.cn != NULL) && (mode == GNUTLS_CLIENT)) {
     1530                /* this might allow virtual hosting on the remote peer */
     1531                CHECK_GNUTLS_DO( gnutls_server_name_set (conn->cc_tls_para.session, GNUTLS_NAME_DNS, conn->cc_tls_para.cn, strlen(conn->cc_tls_para.cn)), /* ignore failure */);
     1532        }
     1533       
     1534        #endif /* GNUTLS_VERSION_300 */
     1535
     1536        #ifdef GNUTLS_VERSION_310
     1537        GNUTLS_TRACE( gnutls_handshake_set_timeout( conn->cc_tls_para.session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT));
     1538        #endif /* GNUTLS_VERSION_310 */
     1539       
    12921540        /* Mark the connection as protected from here, so that the gnutls credentials will be freed */
    12931541        fd_cnx_addstate(conn, CC_STATUS_TLS);
     
    12961544        {
    12971545                int ret;
    1298                 #ifdef GNUTLS_VERSION_310
    1299                 GNUTLS_TRACE( gnutls_handshake_set_timeout( conn->cc_tls_para.session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT));
    1300                 #endif /* GNUTLS_VERSION_310 */
    1301 
    1302                 /* When gnutls 2.10.1 is around, we should use gnutls_certificate_set_verify_function and fd_tls_verify_credentials, so that handshake fails directly. */
    1303                
     1546       
    13041547                CHECK_GNUTLS_DO( ret = gnutls_handshake(conn->cc_tls_para.session),
    13051548                        {
     
    13111554                        } );
    13121555
     1556                #ifndef GNUTLS_VERSION_300
    13131557                /* Now verify the remote credentials are valid -- only simple tests here */
    13141558                CHECK_FCT_DO( fd_tls_verify_credentials(conn->cc_tls_para.session, conn, 1),
     
    13181562                                return EINVAL;
    13191563                        });
     1564                #endif /* GNUTLS_VERSION_300 */
    13201565        }
    13211566
     
    13251570                /* Start reading the messages from the master session. That way, if the remote peer closed, we are not stuck inside handshake */
    13261571                CHECK_FCT(fd_sctps_startthreads(conn, 0));
    1327                
     1572
    13281573                /* Resume all additional sessions from the master one. */
    13291574                CHECK_FCT(fd_sctps_handshake_others(conn, priority, alt_creds));
  • libfdcore/cnxctx.h

    r740 r807  
    9898int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session);
    9999int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority, void * alt_creds);
     100#ifndef GNUTLS_VERSION_300
    100101int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, int verbose);
     102#endif /* GNUTLS_VERSION_300 */
    101103
    102104/* TCP */
     
    143145#endif /* DISABLE_SCTP */
    144146
    145 
    146147#endif /* _CNXCTX_H */
    147148
  • libfdcore/config.c

    r805 r807  
    538538        /* gnutls_certificate_set_verify_limits -- so far the default values are fine... */
    539539       
     540        #ifdef GNUTLS_VERSION_300
     541        /* Use certificate verification during the handshake */
     542        gnutls_certificate_set_verify_function (fd_g_config->cnf_sec_data.credentials, fd_tls_verify_credentials_2);
     543        #endif /* GNUTLS_VERSION_300 */
     544       
    540545        /* DH */
    541546        if (fd_g_config->cnf_sec_data.dh_file) {
  • libfdcore/fdcore-internal.h

    r805 r807  
    352352int             fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len, uint32_t flags);
    353353void            fd_cnx_destroy(struct cnxctx * conn);
     354#ifdef GNUTLS_VERSION_300
     355int             fd_tls_verify_credentials_2(gnutls_session_t session);
     356#endif /* GNUTLS_VERSION_300 */
    354357
    355358/* Flags for the fd_cnx_send function : */
  • libfdcore/sctps.c

    r803 r807  
    105105                       
    106106                        case FDEVP_CNX_ERROR:
    107                                 fd_cnx_markerror(conn);
    108107                                goto out;
    109108                               
     
    121120        /* Signal termination of the connection to all decipher threads */
    122121        for (strid = 0; strid < conn->cc_sctp_para.pairs; strid++) {
    123                 if (conn->cc_sctps_data.array[strid].raw_recv)
     122                if (conn->cc_sctps_data.array[strid].raw_recv) {
    124123                        CHECK_FCT_DO(fd_event_send(conn->cc_sctps_data.array[strid].raw_recv, FDEVP_CNX_ERROR, 0, NULL), goto fatal );
    125         }
     124                }
     125        }
     126        fd_cnx_markerror(conn);
    126127        TRACE_DEBUG(FULL, "Thread terminated");
    127128        return NULL;
     
    171172        CHECK_PARAMS_DO( tr && data, { errno = EINVAL; return -1; } );
    172173       
    173         CHECK_FCT_DO( fd_sctp_sendstr(ctx->parent, ctx->strid, (uint8_t *)data, len), /* errno is already set */ return -1 );
     174        CHECK_FCT_DO( fd_sctp_sendstr(ctx->parent, ctx->strid, (uint8_t *)data, len), return -1 );
    174175       
    175176        return len;
     
    184185       
    185186        TRACE_ENTRY("%p %p %zd", tr, buf, len);
    186         CHECK_PARAMS_DO( tr && buf, { errno = EINVAL; return -1; } );
     187        CHECK_PARAMS_DO( tr && buf, { errno = EINVAL; goto error; } );
    187188       
    188189        /* If we don't have data available now, pull new message from the fifo -- this is blocking (until the queue is destroyed) */
    189190        if (!ctx->partial.buf) {
    190191                int ev;
    191                 CHECK_FCT_DO( errno = fd_event_get(ctx->raw_recv, &ev, &ctx->partial.bufsz, (void *)&ctx->partial.buf), return -1 );
    192                 if (ev == FDEVP_CNX_ERROR)
    193                         return 0; /* connection closed */
     192                CHECK_FCT_DO( errno = fd_event_get(ctx->raw_recv, &ev, &ctx->partial.bufsz, (void *)&ctx->partial.buf), goto error );
     193                if (ev == FDEVP_CNX_ERROR) {
     194                        /* Documentations says to return 0 on connection closed, but it does hang within gnutls_handshake */
     195                        return -1;
     196                }
    194197        }
    195198               
     
    216219        /* We are done */
    217220        return pulled;
     221       
     222error:
     223        gnutls_transport_set_errno (ctx->session, errno);
     224        return -1;
    218225}
    219226
     
    463470       
    464471        TRACE_DEBUG(FULL, "Starting TLS resumed handshake on stream %hu", ctx->strid);
    465 #ifdef GNUTLS_VERSION_310
    466         GNUTLS_TRACE( gnutls_handshake_set_timeout( ctx->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT));
    467 #endif /* GNUTLS_VERSION_310 */
     472
    468473        CHECK_GNUTLS_DO( gnutls_handshake( ctx->session ), return NULL);
    469474                       
    470475        GNUTLS_TRACE( resumed = gnutls_session_is_resumed(ctx->session) );
     476        #ifndef GNUTLS_VERSION_300
    471477        if (!resumed) {
    472478                /* Check the credentials here also */
    473479                CHECK_FCT_DO( fd_tls_verify_credentials(ctx->session, ctx->parent, 0), return NULL );
    474480        }
     481        #endif /* GNUTLS_VERSION_300 */
    475482        if (TRACE_BOOL(FULL)) {
    476483                if (resumed) {
    477484                        fd_log_debug("Session was resumed successfully on stream %hu (conn: '%s')\n", ctx->strid, fd_cnx_getid(ctx->parent));
    478485                } else {
    479                         fd_log_debug("Session was NOT resumed on stream %hu  (full handshake + verif) (conn: '%s')\n", ctx->strid, fd_cnx_getid(ctx->parent));
     486                        fd_log_debug("Session was NOT resumed on stream %hu  (full handshake) (conn: '%s')\n", ctx->strid, fd_cnx_getid(ctx->parent));
    480487                }
    481488        }
     
    555562                CHECK_FCT( fd_tls_prepare(&conn->cc_sctps_data.array[i].session, conn->cc_tls_para.mode, priority, alt_creds) );
    556563               
     564                /* additional initialization for gnutls 3.x */
     565                #ifdef GNUTLS_VERSION_300
     566                        /* the verify function has already been set in the global initialization in config.c */
     567
     568                /* fd_tls_verify_credentials_2 uses the connection */
     569                gnutls_session_set_ptr (conn->cc_sctps_data.array[i].session, (void *) conn);
     570
     571                if ((conn->cc_tls_para.cn != NULL) && (conn->cc_tls_para.mode == GNUTLS_CLIENT)) {
     572                        /* this might allow virtual hosting on the remote peer */
     573                        CHECK_GNUTLS_DO( gnutls_server_name_set (conn->cc_sctps_data.array[i].session, GNUTLS_NAME_DNS, conn->cc_tls_para.cn, strlen(conn->cc_tls_para.cn)), /* ignore failure */);
     574                }
     575
     576                #endif /* GNUTLS_VERSION_300 */
     577
     578                #ifdef GNUTLS_VERSION_310
     579                GNUTLS_TRACE( gnutls_handshake_set_timeout( conn->cc_sctps_data.array[i].session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT));
     580                #endif /* GNUTLS_VERSION_310 */
     581
    557582                /* For the client, copy data from master session; for the server, set session resuming pointers */
    558583                if (conn->cc_tls_para.mode == GNUTLS_CLIENT) {
  • tests/testcnx.c

    r795 r807  
    614614        CHECK( 1, ret );
    615615       
     616        #ifdef GNUTLS_VERSION_300
     617        {
     618                /* We import these CA in the trust list */
     619                gnutls_x509_crt_t * calist;
     620                unsigned int cacount = 0;
     621               
     622                CHECK_GNUTLS_DO( ret = gnutls_x509_crt_list_import2(&calist, &cacount, &ca, GNUTLS_X509_FMT_PEM,
     623                                                        GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED), );
     624                CHECK( 1, cacount );
     625
     626                CHECK_GNUTLS_DO( ret = gnutls_x509_trust_list_add_cas (fd_g_config->cnf_sec_data.trustlist, calist, cacount, 0), );
     627                CHECK( 1, ret );
     628        }
     629               
     630        /* Use certificate verification during the handshake */
     631        gnutls_certificate_set_verify_function (fd_g_config->cnf_sec_data.credentials, fd_tls_verify_credentials_2);
     632       
     633        #endif /* GNUTLS_VERSION_300 */
     634                                                       
     635       
    616636        /* Set the server credentials (in config) */
    617637        CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_key_mem( fd_g_config->cnf_sec_data.credentials,
     
    12011221       
    12021222        /* Basic operation tested successfully, now test we detect error conditions */
    1203        
     1223
    12041224        /* Untrusted certificate, TCP */
    12051225        {
     
    12381258                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    12391259                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1260                fd_cnx_destroy(server_side);
     1261               
    12401262                CHECK( 0, pthread_join(thr, NULL) );
    12411263               
    12421264                /* Now close the connection */
    12431265                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
    1244                 fd_cnx_destroy(server_side);
    12451266                CHECK( 0, pthread_join(thr, NULL) );
    12461267               
     
    12671288                /* Set the CA */
    12681289                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &notrust_ca, GNUTLS_X509_FMT_PEM), );
    1269                 /* TODO: fix me.
    1270                  We should not get stuck when the server fails the handshake but the client succeeds.
    1271                  However, at the moment we do get stuck.
    1272                  FFS, is this a test problem or a problem in the code?
    1273                  
    1274                  CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &ca, GNUTLS_X509_FMT_PEM), );
    1275                  */
     1290                CHECK_GNUTLS_DO( ret = gnutls_certificate_set_x509_trust_mem( hf.creds, &ca, GNUTLS_X509_FMT_PEM), );
    12761291                CHECK( 1, ret );
    12771292                /* Set the key */
     
    12941309                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    12951310                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1311                fd_cnx_destroy(server_side);
    12961312                CHECK( 0, pthread_join(thr, NULL) );
    12971313               
    12981314                /* Now close the connection */
    12991315                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
    1300                 fd_cnx_destroy(server_side);
    13011316                CHECK( 0, pthread_join(thr, NULL) );
    13021317               
     
    13431358                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    13441359                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1360                fd_cnx_destroy(server_side);
    13451361                CHECK( 0, pthread_join(thr, NULL) );
    13461362               
    13471363                /* Now close the connection */
    13481364                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
    1349                 fd_cnx_destroy(server_side);
    13501365                CHECK( 0, pthread_join(thr, NULL) );
    13511366               
     
    14211436                CHECK( 0, pthread_create(&thr, NULL, handshake_thr, &hf) );
    14221437                CHECK( EINVAL, fd_cnx_handshake(server_side, GNUTLS_SERVER, NULL, NULL) );
     1438                fd_cnx_destroy(server_side);
    14231439                CHECK( 0, pthread_join(thr, NULL) );
    14241440               
    14251441                /* Now close the connection */
    14261442                CHECK( 0, pthread_create(&thr, NULL, destroy_thr, client_side) );
    1427                 fd_cnx_destroy(server_side);
    14281443                CHECK( 0, pthread_join(thr, NULL) );
    14291444               
Note: See TracChangeset for help on using the changeset viewer.