Example #1
0
bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
{
   TLS_CONNECTION *tls;
   JCR *jcr = bsock->jcr();

   tls = new_tls_connection(ctx, bsock->m_fd);
   if (!tls) {
      Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
      return false;
   }

   bsock->tls = tls;

   /* Initiate TLS Negotiation */
   if (!tls_bsock_accept(bsock)) {
      Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
      goto err;
   }

   if (verify_list) {
      if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
         Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
                                         " Peer certificate did not match a required commonName\n"),
                                         bsock->host());
         goto err;
      }
   }
   Dmsg0(50, "TLS server negotiation established.\n");
   return true;

err:
   free_tls_connection(tls);
   bsock->tls = NULL;
   return false;
}
Example #2
0
/*
 * Verifies a list of common names against the certificate
 * commonName attribute.
 *  Returns: true on success
 *           false on failure
 */
bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list)
{
   SSL *ssl = tls->openssl;
   X509 *cert;
   X509_NAME *subject;
   bool auth_success = false;
   char data[256];

   /* Check if peer provided a certificate */
   if (!(cert = SSL_get_peer_certificate(ssl))) {
      Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
      return false;
   }

   if ((subject = X509_get_subject_name(cert)) != NULL) {
      if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
         char *cn;
         /* NULL terminate data */
         data[255] = 0;

         /* Try all the CNs in the list */
         foreach_alist(cn, verify_list) {
            if (bstrcasecmp(data, cn)) {
               auth_success = true;
            }
         }
      }
   }
Example #3
0
/*
 * Establish a TLS connection -- client side
 * Returns: true  on success
 *          false on failure
 */
bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list)
{
   TLS_CONNECTION *tls;
   JCR *jcr = bsock->jcr();

   tls  = new_tls_connection(ctx, bsock->m_fd);
   if (!tls) {
      Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
      return false;
   }

   bsock->tls = tls;

   /* Initiate TLS Negotiation */
   if (!tls_bsock_connect(bsock)) {
      goto err;
   }

   /* If there's an Allowed CN verify list, use that to validate the remote
    * certificate's CN. Otherwise, we use standard host/CN matching. */
   if (verify_list) {
      if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
         Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
                                         " Peer certificate did not match a required commonName\n"),
                                         bsock->host());
         goto err;
      }
   } else if (!tls_postconnect_verify_host(jcr, tls, bsock->host())) {
      /* If host is 127.0.0.1, try localhost */
      if (strcmp(bsock->host(), "127.0.0.1") != 0 ||
             !tls_postconnect_verify_host(jcr, tls, "localhost")) {
         Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host name \"%s\" did not match presented certificate\n"),
               bsock->host());
         goto err;
      }
   }
   Dmsg0(50, "TLS client negotiation established.\n");
   return true;

err:
   free_tls_connection(tls);
   bsock->tls = NULL;
   return false;
}