Changeset 31:26685c67d387 in freeDiameter for freeDiameter/cnxctx.c
- Timestamp:
- Oct 28, 2009, 6:51:45 PM (15 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/cnxctx.c
r30 r31 404 404 } 405 405 406 /* Set the hostname to check during handshake */ 407 void fd_cnx_sethostname(struct cnxctx * conn, char * hn) 408 { 409 CHECK_PARAMS_DO( conn, return ); 410 conn->cc_tls_para.cn = hn; 411 } 412 406 413 /* Return the TLS state of a connection */ 407 414 int fd_cnx_getTLS(struct cnxctx * conn) … … 769 776 } 770 777 778 /* Verify remote credentials after successful handshake (return 0 if OK, EINVAL otherwise) */ 779 int 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 771 858 /* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */ 772 859 int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds) … … 813 900 814 901 /* 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) ); 832 903 } 833 904
Note: See TracChangeset
for help on using the changeset viewer.