Exemple #1
0
static int
cert_verify_callback (gnutls_session_t session)
{
  int rc;
  unsigned int status = 0;
  int ssh = ENABLED_OPT(TOFU);
  const char* txt_service;

  if (!x509_cafile && !pgp_keyring)
    return 0;
    
  rc = cert_verify(session, hostname);
  if (rc == 0)
    {
      printf ("*** Verifying server certificate failed...\n");
      if (!insecure && !ssh)
        return -1;
    }
  else if (ENABLED_OPT(OCSP))
    { /* off-line verification succeeded. Try OCSP */
      rc = cert_verify_ocsp(session);
      if (rc == 0)
        {
          printf ("*** Verifying (with OCSP) server certificate failed...\n");
          if (!insecure && !ssh)
            return -1;
        }
      else if (rc == -1)
        printf("*** OCSP response ignored\n");
    }

  if (ssh) /* try ssh auth */
    {
      unsigned int list_size;
      const gnutls_datum_t * cert;
      
      cert = gnutls_certificate_get_peers(session, &list_size);
      if (cert == NULL)
        {
          fprintf(stderr, "Cannot obtain peer's certificate!\n");
          return -1;
        }

      txt_service = port_to_service(service);
      
      rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, txt_service, 
                                       GNUTLS_CRT_X509, cert, 0);
      if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
        {
          print_cert_info_compact(session);
          fprintf(stderr, "Host %s (%s) has never been contacted before.\n", hostname, txt_service);
          if (status == 0)
            fprintf(stderr, "Its certificate is valid for %s.\n", hostname);

          rc = read_yesno("Are you sure you want to trust it? (y/N): ");
          if (rc == 0)
            return -1;
        }
      else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
        {
          print_cert_info_compact(session);
          fprintf(stderr, "Warning: host %s is known and it is associated with a different key.\n", hostname);
          fprintf(stderr, "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n");
          if (status == 0)
            fprintf(stderr, "Its certificate is valid for %s.\n", hostname);

          rc = read_yesno("Do you trust the received key? (y/N): ");
          if (rc == 0)
            return -1;
        }
      else if (rc < 0)
        {
          fprintf(stderr, "gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(rc));
          return -1;
        }
      
      if (rc != 0)
        {
          rc = gnutls_store_pubkey(NULL, NULL, hostname, txt_service, 
                                   GNUTLS_CRT_X509, cert, 0, 0);
          if (rc < 0)
            fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc));
        }
    }

  return 0;
}
Exemple #2
0
void doit(void)
{
	gnutls_datum_t der_cert, der_cert2;
	int ret;
	gnutls_datum_t hash;

	/* the sha1 hash of the server's pubkey */
	hash.data = (void *) SHA1_HASH;
	hash.size = sizeof(SHA1_HASH) - 1;

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(2);

	ret =
	    gnutls_pem_base64_decode_alloc("CERTIFICATE", &server_cert,
					   &der_cert);
	if (ret < 0) {
		fail("base64 decoding\n");
		goto fail;
	}

	ret =
	    gnutls_pem_base64_decode_alloc("CERTIFICATE", &client_cert,
					   &der_cert2);
	if (ret < 0) {
		fail("base64 decoding\n");
		goto fail;
	}

	remove(TMP_FILE);

	/* verify whether the stored hash verification succeeeds */
	ret = gnutls_store_commitment(TMP_FILE, NULL, "localhost", "https",
				      GNUTLS_DIG_SHA1, &hash, 0, 0);
	if (ret != 0) {
		fail("commitment storage: %s\n", gnutls_strerror(ret));
		goto fail;
	}

	if (debug)
		success("Commitment storage: passed\n");

	ret =
	    gnutls_verify_stored_pubkey(TMP_FILE, NULL, "localhost",
					"https", GNUTLS_CRT_X509,
					&der_cert, 0);
	remove(TMP_FILE);

	if (ret != 0) {
		fail("commitment verification: %s\n",
		     gnutls_strerror(ret));
		goto fail;
	}

	if (debug)
		success("Commitment verification: passed\n");

	/* verify whether the stored pubkey verification succeeeds */
	ret = gnutls_store_pubkey(TMP_FILE, NULL, "localhost", "https",
				  GNUTLS_CRT_X509, &der_cert, 0, 0);
	if (ret != 0) {
		fail("storage: %s\n", gnutls_strerror(ret));
		goto fail;
	}

	if (debug)
		success("Public key storage: passed\n");

	ret =
	    gnutls_verify_stored_pubkey(TMP_FILE, NULL, "localhost",
					"https", GNUTLS_CRT_X509,
					&der_cert, 0);
	if (ret != 0) {
		fail("pubkey verification: %s\n", gnutls_strerror(ret));
		goto fail;
	}

	ret =
	    gnutls_verify_stored_pubkey(TMP_FILE, NULL, "localhost",
					"https", GNUTLS_CRT_X509,
					&der_cert2, 0);
	remove(TMP_FILE);
	if (ret == 0) {
		fail("verification succeed when shouldn't!\n");
		goto fail;
	}
	if (ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH) {
		fail("Wrong error code returned: %s!\n",
		     gnutls_strerror(ret));
		goto fail;
	}

	if (debug)
		success("Public key verification: passed\n");


	gnutls_global_deinit();
	gnutls_free(der_cert.data);
	gnutls_free(der_cert2.data);

	return;
      fail:
	remove(TMP_FILE);
	exit(1);
}
Exemple #3
0
static int
cert_verify_callback (gnutls_session_t session)
{
  int rc;
  unsigned int status = 0;
  int ssh = ENABLED_OPT(TOFU);
#ifdef HAVE_DANE
  int dane = ENABLED_OPT(DANE);
#endif
  int ca_verify = ENABLED_OPT(CA_VERIFICATION);
  const char* txt_service;

  print_cert_info (session, verbose, print_cert);

  if (ca_verify)
    {
      rc = cert_verify(session, hostname);
      if (rc == 0)
        {
          printf ("*** Verifying server certificate failed...\n");
          if (!insecure && !ssh)
            return -1;
        }
      else if (ENABLED_OPT(OCSP) && gnutls_ocsp_status_request_is_checked(session, 0) == 0)
        { /* off-line verification succeeded. Try OCSP */
          rc = cert_verify_ocsp(session);
          if (rc == 0)
            {
              printf ("*** Verifying (with OCSP) server certificate failed...\n");
              if (!insecure && !ssh)
                return -1;
            }
          else if (rc == -1)
            printf("*** OCSP response ignored\n");
        }
    }

  if (ssh) /* try ssh auth */
    {
      unsigned int list_size;
      const gnutls_datum_t * cert;
      
      cert = gnutls_certificate_get_peers(session, &list_size);
      if (cert == NULL)
        {
          fprintf(stderr, "Cannot obtain peer's certificate!\n");
          return -1;
        }

      txt_service = port_to_service(service);
      
      rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, txt_service, 
                                       GNUTLS_CRT_X509, cert, 0);
      if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
        {
          print_cert_info_compact(session);
          fprintf(stderr, "Host %s (%s) has never been contacted before.\n", hostname, txt_service);
          if (status == 0)
            fprintf(stderr, "Its certificate is valid for %s.\n", hostname);

          rc = read_yesno("Are you sure you want to trust it? (y/N): ");
          if (rc == 0)
            return -1;
        }
      else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
        {
          print_cert_info_compact(session);
          fprintf(stderr, "Warning: host %s is known and it is associated with a different key.\n", hostname);
          fprintf(stderr, "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n");
          if (status == 0)
            fprintf(stderr, "Its certificate is valid for %s.\n", hostname);

          rc = read_yesno("Do you trust the received key? (y/N): ");
          if (rc == 0)
            return -1;
        }
      else if (rc < 0)
        {
          fprintf(stderr, "gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(rc));
          return -1;
        }
      
      if (rc != 0)
        {
          rc = gnutls_store_pubkey(NULL, NULL, hostname, txt_service, 
                                   GNUTLS_CRT_X509, cert, 0, 0);
          if (rc < 0)
            fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc));
        }
    }

#ifdef HAVE_DANE
  if (dane) /* try DANE auth */
    {
      unsigned int sflags = ENABLED_OPT(LOCAL_DNS)?0:DANE_F_IGNORE_LOCAL_RESOLVER;
      rc = dane_verify_session_crt( NULL, session, hostname, udp?"udp":"tcp", atoi(service), 
                                    sflags, 0, &status);
      if (rc < 0)
        {
          fprintf(stderr, "*** DANE verification error: %s\n", dane_strerror(rc));
          if (!insecure)
            return -1;
        }
      else
        {
          gnutls_datum_t out;

          rc = dane_verification_status_print( status, &out, 0);
          if (rc < 0)
            {
              fprintf(stderr, "*** DANE error: %s\n", dane_strerror(rc));
              if (!insecure)
                return -1;
            }
          
          fprintf(stderr, "- %s\n", out.data);
          gnutls_free(out.data);
        }

    }
#endif

  return 0;
}