コード例 #1
0
ファイル: cli.c プロジェクト: philippe-goetz/gnutls
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;
}
コード例 #2
0
ファイル: cli.c プロジェクト: nobled/gnutls
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;
}