Navigation


Changeset 31:26685c67d387 in freeDiameter for freeDiameter/cnxctx.c


Ignore:
Timestamp:
Oct 28, 2009, 6:51:45 PM (15 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Completed the test and fixed a couple issues

File:
1 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/cnxctx.c

    r30 r31  
    404404}
    405405
     406/* Set the hostname to check during handshake */
     407void fd_cnx_sethostname(struct cnxctx * conn, char * hn)
     408{
     409        CHECK_PARAMS_DO( conn, return );
     410        conn->cc_tls_para.cn = hn;
     411}
     412
    406413/* Return the TLS state of a connection */
    407414int fd_cnx_getTLS(struct cnxctx * conn)
     
    769776}
    770777
     778/* Verify remote credentials after successful handshake (return 0 if OK, EINVAL otherwise) */
     779int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn)
     780{
     781        int ret, i;
     782        const gnutls_datum_t *cert_list;
     783        unsigned int cert_list_size;
     784        gnutls_x509_crt_t cert;
     785        time_t now;
     786       
     787        /* First, use built-in verification */
     788        CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (session, &ret), return EINVAL );
     789        if (ret) {
     790                if (TRACE_BOOL(INFO)) {
     791                        fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     792                        if (ret & GNUTLS_CERT_INVALID)
     793                                fd_log_debug(" - The certificate is not trusted (unknown CA?)\n");
     794                        if (ret & GNUTLS_CERT_REVOKED)
     795                                fd_log_debug(" - The certificate has been revoked.\n");
     796                        if (ret & GNUTLS_CERT_SIGNER_NOT_FOUND)
     797                                fd_log_debug(" - The certificate hasn't got a known issuer.\n");
     798                        if (ret & GNUTLS_CERT_SIGNER_NOT_CA)
     799                                fd_log_debug(" - The certificate signer is not a CA, or uses version 1, or 3 without basic constraints.\n");
     800                        if (ret & GNUTLS_CERT_INSECURE_ALGORITHM)
     801                                fd_log_debug(" - The certificate signature uses a weak algorithm.\n");
     802                }
     803                return EINVAL;
     804        }
     805       
     806        /* Code from http://www.gnu.org/software/gnutls/manual/gnutls.html#Verifying-peer_0027s-certificate */
     807        if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
     808                return EINVAL;
     809       
     810        cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
     811        if (cert_list == NULL)
     812                return EINVAL;
     813       
     814        now = time(NULL);
     815
     816        /* Check validity of all the certificates */
     817        for (i = 0; i < cert_list_size; i++)
     818        {
     819                time_t deadline;
     820               
     821                CHECK_GNUTLS_DO( gnutls_x509_crt_init (&cert), return EINVAL);
     822                CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL);
     823               
     824                deadline = gnutls_x509_crt_get_expiration_time(cert);
     825                if ((deadline != (time_t)-1) && (deadline < now)) {
     826                        if (TRACE_BOOL(INFO)) {
     827                                fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     828                                fd_log_debug(" - The certificate %d in the chain is expired\n", i);
     829                        }
     830                        return EINVAL;
     831                }
     832               
     833                deadline = gnutls_x509_crt_get_activation_time(cert);
     834                if ((deadline != (time_t)-1) && (deadline > now)) {
     835                        if (TRACE_BOOL(INFO)) {
     836                                fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     837                                fd_log_debug(" - The certificate %d in the chain is not yet activated\n", i);
     838                        }
     839                        return EINVAL;
     840                }
     841               
     842                if ((i == 0) && (conn->cc_tls_para.cn)) {
     843                        if (!gnutls_x509_crt_check_hostname (cert, conn->cc_tls_para.cn)) {
     844                                if (TRACE_BOOL(INFO)) {
     845                                        fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
     846                                        fd_log_debug(" - The certificate hostname does not match '%s'\n", conn->cc_tls_para.cn);
     847                                }
     848                                return EINVAL;
     849                        }
     850                }
     851               
     852                gnutls_x509_crt_deinit (cert);
     853        }
     854
     855        return 0;
     856}
     857
    771858/* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */
    772859int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds)
     
    813900
    814901                /* Now verify the remote credentials are valid -- only simple test here */
    815                 CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (conn->cc_tls_para.session, &ret), return EINVAL );
    816                 if (ret) {
    817                         if (TRACE_BOOL(INFO)) {
    818                                 fd_log_debug("TLS: Remote certificate invalid on socket %d (%s) :\n", conn->cc_socket, conn->cc_id);
    819                                 if (ret & GNUTLS_CERT_INVALID)
    820                                         fd_log_debug(" - The certificate is not trusted (unknown CA?)\n");
    821                                 if (ret & GNUTLS_CERT_REVOKED)
    822                                         fd_log_debug(" - The certificate has been revoked.\n");
    823                                 if (ret & GNUTLS_CERT_SIGNER_NOT_FOUND)
    824                                         fd_log_debug(" - The certificate hasn't got a known issuer.\n");
    825                                 if (ret & GNUTLS_CERT_SIGNER_NOT_CA)
    826                                         fd_log_debug(" - The certificate signer is not a CA, or uses version 1, or 3 without basic constraints.\n");
    827                                 if (ret & GNUTLS_CERT_INSECURE_ALGORITHM)
    828                                         fd_log_debug(" - The certificate signature uses a weak algorithm.\n");
    829                         }
    830                         return EINVAL;
    831                 }
     902                CHECK_FCT( fd_tls_verify_credentials(conn->cc_tls_para.session, conn) );
    832903        }
    833904
Note: See TracChangeset for help on using the changeset viewer.