src/lib/tls.c
bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host)
{
   SSL *ssl = tls->openssl;
   X509 *cert;
   X509_NAME *subject;
   bool auth_success = false;
   int extensions;
   int i, j;
   const char *pval, *phost;

   int cnLastPos = -1;
   X509_NAME_ENTRY *neCN;
   ASN1_STRING *asn1CN;

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

   /* Check subjectAltName extensions first */
   if ((extensions = X509_get_ext_count(cert)) > 0) {
      for (i = 0; i < extensions; i++) {
         X509_EXTENSION *ext;
         const char *extname;

         ext = X509_get_ext(cert, i);
         extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));

         if (strcmp(extname, "subjectAltName") == 0) {
#ifdef HAVE_OPENSSLv1
            const X509V3_EXT_METHOD *method;
#else
            X509V3_EXT_METHOD *method;
#endif
            STACK_OF(CONF_VALUE) *val;
            CONF_VALUE *nval;
            void *extstr = NULL;
            const unsigned char *ext_value_data;
            const ASN1_STRING *asn1_ext_val;

            /* Get x509 extension method structure */
            if (!(method = X509V3_EXT_get(ext))) {
               break;
            }

            asn1_ext_val = X509_EXTENSION_get_data(ext);
            ext_value_data = ASN1_STRING_get0_data(asn1_ext_val);

            if (method->it) {
               /* New style ASN1 */

               /* Decode ASN1 item in data */
               extstr = ASN1_item_d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val),
                                      ASN1_ITEM_ptr(method->it));
            } else {
               /* Old style ASN1 */

               /* Decode ASN1 item in data */
               extstr = method->d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val));
            }

            /* Iterate through to find the dNSName field(s) */
            val = method->i2v(method, extstr, NULL);

            /* dNSName shortname is "DNS" */
            Dmsg0(250, "Check DNS name\n");
            for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
               nval = sk_CONF_VALUE_value(val, j);
               if (strcmp(nval->name, "DNS") == 0) {
                  if (strncasecmp(nval->value, "*.", 2) == 0) {
                     Dmsg0(250, "Wildcard Certificate\n");
                     pval = strstr(nval->value, ".");
                     phost = strstr(host, ".");
                     if (pval && phost && (strcasecmp(pval, phost) == 0)) {
                        auth_success = true;
                        goto success;
                     }
                  } else if (strcasecmp(nval->value, host) == 0) {
                     auth_success = true;
                     goto success;
                  }
                  Dmsg2(250, "No DNS name match. Host=%s cert=%s\n", host, nval->value);
               }
            }
         }
      }
   }

   /* Try verifying against the subject name */
   if (!auth_success) {
      Dmsg0(250, "Check subject name name\n");
      if ((subject = X509_get_subject_name(cert)) != NULL) {
         /* Loop through all CNs */
         for (;;) {
            cnLastPos = X509_NAME_get_index_by_NID(subject, NID_commonName, cnLastPos);
            if (cnLastPos == -1) {
               break;
            }
            neCN = X509_NAME_get_entry(subject, cnLastPos);
            asn1CN = X509_NAME_ENTRY_get_data(neCN);
            if (strncasecmp((const char*)asn1CN->data, "*.", 2) == 0) {
               /* wildcard certificate */
               Dmsg0(250, "Wildcard Certificate\n");
               pval = strstr((const char*)asn1CN->data, ".");
               phost = strstr(host, ".");
               if (pval && phost && (strcasecmp(pval, phost) == 0)) {
                  auth_success = true;
                  goto success;
               }
            } else if (strcasecmp((const char*)asn1CN->data, host) == 0) {
               auth_success = true;
               break;
            }
            Dmsg2(250, "No subject name match. Host=%s cert=%s\n", host, (const char*)asn1CN->data);
         }
      }
   }

success:
   X509_free(cert);
   return auth_success;
}
/*
 * Verifies a peer's hostname against the subjectAltName and commonName
 * attributes.
 *  Returns: true on success
 *           false on failure
 */
Verifies a peer's hostname against the subjectAltName and commonName
attributes.
Returns: true on success
false on failure
Verifies a peer ' s hostname against the subjectAltName and commonName attributes . Returns : true on success false on failure
bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host)
{
   SSL *ssl = tls->openssl;
   X509 *cert;
   X509_NAME *subject;
   bool auth_success = false;
   int extensions;
   int i, j;
   const char *pval, *phost;
   int cnLastPos = -1;
   X509_NAME_ENTRY *neCN;
   ASN1_STRING *asn1CN;
   if (!(cert = SSL_get_peer_certificate(ssl))) {
      Qmsg1(jcr, M_ERROR, 0,
            _("Peer %s failed to present a TLS certificate\n"), host);
      Dmsg1(250, _("Peer %s failed to present a TLS certificate\n"), host);
      return false;
   }
   if ((extensions = X509_get_ext_count(cert)) > 0) {
      for (i = 0; i < extensions; i++) {
         X509_EXTENSION *ext;
         const char *extname;
         ext = X509_get_ext(cert, i);
         extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
         if (strcmp(extname, "subjectAltName") == 0) {
#ifdef HAVE_OPENSSLv1
            const X509V3_EXT_METHOD *method;
#else
            X509V3_EXT_METHOD *method;
#endif
            STACK_OF(CONF_VALUE) *val;
            CONF_VALUE *nval;
            void *extstr = NULL;
            const unsigned char *ext_value_data;
            const ASN1_STRING *asn1_ext_val;
            if (!(method = X509V3_EXT_get(ext))) {
               break;
            }
            asn1_ext_val = X509_EXTENSION_get_data(ext);
            ext_value_data = ASN1_STRING_get0_data(asn1_ext_val);
            if (method->it) {
               extstr = ASN1_item_d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val),
                                      ASN1_ITEM_ptr(method->it));
            } else {
               extstr = method->d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val));
            }
            val = method->i2v(method, extstr, NULL);
            Dmsg0(250, "Check DNS name\n");
            for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
               nval = sk_CONF_VALUE_value(val, j);
               if (strcmp(nval->name, "DNS") == 0) {
                  if (strncasecmp(nval->value, "*.", 2) == 0) {
                     Dmsg0(250, "Wildcard Certificate\n");
                     pval = strstr(nval->value, ".");
                     phost = strstr(host, ".");
                     if (pval && phost && (strcasecmp(pval, phost) == 0)) {
                        auth_success = true;
                        goto success;
                     }
                  } else if (strcasecmp(nval->value, host) == 0) {
                     auth_success = true;
                     goto success;
                  }
                  Dmsg2(250, "No DNS name match. Host=%s cert=%s\n", host, nval->value);
               }
            }
         }
      }
   }
   if (!auth_success) {
      Dmsg0(250, "Check subject name name\n");
      if ((subject = X509_get_subject_name(cert)) != NULL) {
         for (;;) {
            cnLastPos = X509_NAME_get_index_by_NID(subject, NID_commonName, cnLastPos);
            if (cnLastPos == -1) {
               break;
            }
            neCN = X509_NAME_get_entry(subject, cnLastPos);
            asn1CN = X509_NAME_ENTRY_get_data(neCN);
            if (strncasecmp((const char*)asn1CN->data, "*.", 2) == 0) {
               Dmsg0(250, "Wildcard Certificate\n");
               pval = strstr((const char*)asn1CN->data, ".");
               phost = strstr(host, ".");
               if (pval && phost && (strcasecmp(pval, phost) == 0)) {
                  auth_success = true;
                  goto success;
               }
            } else if (strcasecmp((const char*)asn1CN->data, host) == 0) {
               auth_success = true;
               break;
            }
            Dmsg2(250, "No subject name match. Host=%s cert=%s\n", host, (const char*)asn1CN->data);
         }
      }
   }
success:
   X509_free(cert);
   return auth_success;
}
bool tls_postconnect_verify_host ( JCR * jcr , TLS_CONNECTION * tls , const char * host ) { SSL * ssl = tls -> openssl ; X509 * cert ; X509_NAME * subject ; bool auth_success = false ; int extensions ; int i , j ; const char * pval , * phost ; int cnLastPos = -1 ; X509_NAME_ENTRY * neCN ; ASN1_STRING * asn1CN ; if ( ! ( cert = SSL_get_peer_certificate ( ssl ) ) ) { Qmsg1 ( jcr , M_ERROR , 0 , _ ( " \n " ) , host ) ; Dmsg1 ( 250 , _ ( " \n " ) , host ) ; return false ; } if ( ( extensions = X509_get_ext_count ( cert ) ) > 0 ) { for ( i = 0 ; i < extensions ; i ++ ) { X509_EXTENSION * ext ; const char * extname ; ext = X509_get_ext ( cert , i ) ; extname = OBJ_nid2sn ( OBJ_obj2nid ( X509_EXTENSION_get_object ( ext ) ) ) ; if ( strcmp ( extname , " " ) == 0 ) { #ifdef HAVE_OPENSSLv1 const X509V3_EXT_METHOD * method ; #else X509V3_EXT_METHOD * method ; #endif STACK_OF ( CONF_VALUE ) * val ; CONF_VALUE * nval ; void * extstr = NULL ; const unsigned char * ext_value_data ; const ASN1_STRING * asn1_ext_val ; if ( ! ( method = X509V3_EXT_get ( ext ) ) ) { break ; } asn1_ext_val = X509_EXTENSION_get_data ( ext ) ; ext_value_data = ASN1_STRING_get0_data ( asn1_ext_val ) ; if ( method -> it ) { extstr = ASN1_item_d2i ( NULL , & ext_value_data , ASN1_STRING_length ( asn1_ext_val ) , ASN1_ITEM_ptr ( method -> it ) ) ; } else { extstr = method -> d2i ( NULL , & ext_value_data , ASN1_STRING_length ( asn1_ext_val ) ) ; } val = method -> i2v ( method , extstr , NULL ) ; Dmsg0 ( 250 , " \n " ) ; for ( j = 0 ; j < sk_CONF_VALUE_num ( val ) ; j ++ ) { nval = sk_CONF_VALUE_value ( val , j ) ; if ( strcmp ( nval -> name , " " ) == 0 ) { if ( strncasecmp ( nval -> value , " " , 2 ) == 0 ) { Dmsg0 ( 250 , " \n " ) ; pval = strstr ( nval -> value , " " ) ; phost = strstr ( host , " " ) ; if ( pval && phost && ( strcasecmp ( pval , phost ) == 0 ) ) { auth_success = true ; goto success ; } } else if ( strcasecmp ( nval -> value , host ) == 0 ) { auth_success = true ; goto success ; } Dmsg2 ( 250 , " \n " , host , nval -> value ) ; } } } } } if ( ! auth_success ) { Dmsg0 ( 250 , " \n " ) ; if ( ( subject = X509_get_subject_name ( cert ) ) != NULL ) { for ( ; ; ) { cnLastPos = X509_NAME_get_index_by_NID ( subject , NID_commonName , cnLastPos ) ; if ( cnLastPos == -1 ) { break ; } neCN = X509_NAME_get_entry ( subject , cnLastPos ) ; asn1CN = X509_NAME_ENTRY_get_data ( neCN ) ; if ( strncasecmp ( ( const char * ) asn1CN -> data , " " , 2 ) == 0 ) { Dmsg0 ( 250 , " \n " ) ; pval = strstr ( ( const char * ) asn1CN -> data , " " ) ; phost = strstr ( host , " " ) ; if ( pval && phost && ( strcasecmp ( pval , phost ) == 0 ) ) { auth_success = true ; goto success ; } } else if ( strcasecmp ( ( const char * ) asn1CN -> data , host ) == 0 ) { auth_success = true ; break ; } Dmsg2 ( 250 , " \n " , host , ( const char * ) asn1CN -> data ) ; } } } success : X509_free ( cert ) ; return auth_success ; }
Verifies a peer's hostname against the subjectAltName and commonName
 attributes.
Verifies a peer ' s hostname against the subjectAltName and commonName attributes .
/* Check if peer provided a certificate */ /* Check subjectAltName extensions first */ /* Get x509 extension method structure */ /* New style ASN1 */ /* Decode ASN1 item in data */ /* Old style ASN1 */ /* Decode ASN1 item in data */ /* Iterate through to find the dNSName field(s) */ /* dNSName shortname is "DNS" */ /* Try verifying against the subject name */ /* Loop through all CNs */ /* wildcard certificate */