Example #1
0
File: tls_g.c Project: 1ack/Impala
/* Certs are not automatically varified during the handshake */
static int
tlsg_cert_verify( tlsg_session *ssl )
{
	unsigned int status = 0;
	int err;
	time_t now = time(0);
	time_t peertime;

	err = gnutls_certificate_verify_peers2( ssl->session, &status );
	if ( err < 0 ) {
		Debug( LDAP_DEBUG_ANY,"TLS: gnutls_certificate_verify_peers2 failed %d\n",
			err,0,0 );
		return -1;
	}
	if ( status ) {
		Debug( LDAP_DEBUG_TRACE,"TLS: peer cert untrusted or revoked (0x%x)\n",
			status, 0,0 );
		return -1;
	}
	peertime = gnutls_certificate_expiration_time_peers( ssl->session );
	if ( peertime == (time_t) -1 ) {
		Debug( LDAP_DEBUG_ANY, "TLS: gnutls_certificate_expiration_time_peers failed\n",
			0, 0, 0 );
		return -1;
	}
	if ( peertime < now ) {
		Debug( LDAP_DEBUG_ANY, "TLS: peer certificate is expired\n",
			0, 0, 0 );
		return -1;
	}
	peertime = gnutls_certificate_activation_time_peers( ssl->session );
	if ( peertime == (time_t) -1 ) {
		Debug( LDAP_DEBUG_ANY, "TLS: gnutls_certificate_activation_time_peers failed\n",
			0, 0, 0 );
		return -1;
	}
	if ( peertime > now ) {
		Debug( LDAP_DEBUG_ANY, "TLS: peer certificate not yet active\n",
			0, 0, 0 );
		return -1;
	}
	return 0;
}
Example #2
0
static gboolean
ssl_verify_certificate (LmSSL *ssl, const gchar *server)
{
    LmSSLBase *base;
    unsigned int        status;
    int rc;

    base = LM_SSL_BASE (ssl);

    /* This verification function uses the trusted CAs in the credentials
     * structure. So you must have installed one or more CA certificates.
     */
    rc = gnutls_certificate_verify_peers2 (ssl->gnutls_session, &status);

    if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
        if (base->func (ssl,
                        LM_SSL_STATUS_NO_CERT_FOUND,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (rc != 0) {
        if (base->func (ssl,
                        LM_SSL_STATUS_GENERIC_ERROR,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
        if (base->func (ssl,
                        LM_SSL_STATUS_NO_CERT_FOUND,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (status & GNUTLS_CERT_INVALID
        || status & GNUTLS_CERT_REVOKED) {
        if (base->func (ssl, LM_SSL_STATUS_UNTRUSTED_CERT,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (gnutls_certificate_expiration_time_peers (ssl->gnutls_session) < time (0)) {
        if (base->func (ssl, LM_SSL_STATUS_CERT_EXPIRED,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (gnutls_certificate_activation_time_peers (ssl->gnutls_session) > time (0)) {
        if (base->func (ssl, LM_SSL_STATUS_CERT_NOT_ACTIVATED,
                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    if (gnutls_certificate_type_get (ssl->gnutls_session) == GNUTLS_CRT_X509) {
        const gnutls_datum_t* cert_list;
        guint cert_list_size;
        gnutls_digest_algorithm_t digest = GNUTLS_DIG_SHA256;
        guchar digest_bin[LM_FINGERPRINT_LENGTH];
        size_t digest_size;
        gnutls_x509_crt_t cert;

        cert_list = gnutls_certificate_get_peers (ssl->gnutls_session, &cert_list_size);
        if (cert_list == NULL) {
            if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }

        gnutls_x509_crt_init (&cert);

        if (gnutls_x509_crt_import (cert, &cert_list[0],
                                    GNUTLS_X509_FMT_DER) != 0) {
            if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }

        if (!gnutls_x509_crt_check_hostname (cert, server)) {
            if (base->func (ssl, LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }

        gnutls_x509_crt_deinit (cert);

        digest_size = gnutls_hash_get_len(digest);
        g_assert(digest_size < sizeof(digest_bin));

        if (gnutls_fingerprint (digest,
                                &cert_list[0],
                                digest_bin,
                                &digest_size) >= 0) {
            _lm_ssl_base_set_fingerprint(base, digest_bin, digest_size);
            if (_lm_ssl_base_check_fingerprint(base) != 0 &&
                base->func (ssl,
                            LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH,
                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
                return FALSE;
            }
        }
        else if (base->func (ssl, LM_SSL_STATUS_GENERIC_ERROR,
                             base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
            return FALSE;
        }
    }

    return TRUE;
}
time_t session::get_peers_certificate_activation_time () const
{
    return gnutls_certificate_activation_time_peers (s);
}
Example #4
0
static gboolean
ssl_verify_certificate (LmSSL *ssl, const gchar *server)
{
	int           status;

	/* This verification function uses the trusted CAs in the credentials
	 * structure. So you must have installed one or more CA certificates.
	 */
	status = gnutls_certificate_verify_peers (ssl->gnutls_session);

	if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) {
		if (ssl->func (ssl,
			       LM_SSL_STATUS_NO_CERT_FOUND,
			       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
			return FALSE;
		}
	}
	
	if (status & GNUTLS_CERT_INVALID
	    || status & GNUTLS_CERT_REVOKED) {
		if (ssl->func (ssl, LM_SSL_STATUS_UNTRUSTED_CERT,
			       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
			return FALSE;
		}
	}
	
	if (gnutls_certificate_expiration_time_peers (ssl->gnutls_session) < time (0)) {
		if (ssl->func (ssl, LM_SSL_STATUS_CERT_EXPIRED,
			       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
			return FALSE;
		}
	}
	
	if (gnutls_certificate_activation_time_peers (ssl->gnutls_session) > time (0)) {
		if (ssl->func (ssl, LM_SSL_STATUS_CERT_NOT_ACTIVATED,
			       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
			return FALSE;
		}
	}
	
	if (gnutls_certificate_type_get (ssl->gnutls_session) == GNUTLS_CRT_X509) {
		const gnutls_datum* cert_list;
		guint cert_list_size;
		size_t digest_size;
		gnutls_x509_crt cert;
		
		cert_list = gnutls_certificate_get_peers (ssl->gnutls_session, &cert_list_size);
		if (cert_list == NULL) {
			if (ssl->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND,
				       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
				return FALSE;
			}
		}

		gnutls_x509_crt_init (&cert);

		if (!gnutls_x509_crt_import (cert, &cert_list[0],
					     GNUTLS_X509_FMT_DER)) {
			if (ssl->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, 
				       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
				return FALSE;
			}
		}
		
		if (!gnutls_x509_crt_check_hostname (cert, server)) {
			if (ssl->func (ssl, LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH,
				       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
				return FALSE;
			}
		}

		gnutls_x509_crt_deinit (cert);

		if (gnutls_fingerprint (GNUTLS_DIG_MD5, &cert_list[0],
					     ssl->fingerprint,
					     &digest_size) >= 0) {
			if (ssl->expected_fingerprint &&
			    memcmp (ssl->expected_fingerprint, ssl->fingerprint,
				    digest_size) &&
			    ssl->func (ssl,
				       LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH,
				       ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
				return FALSE;
			}
		} 
		else if (ssl->func (ssl, LM_SSL_STATUS_GENERIC_ERROR,
				    ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) {
			return FALSE; 
		} 
	}

	return TRUE;
}