[Nagiosplug-devel] Anybody interested in a plugin that checks SSL certificate validity or has it already been done?

Naoki naoki at valuecommerce.com
Fri Jan 21 01:48:42 CET 2005


The "check_http -S" plugin call will check for cert expiry but that's
not good enough for me. I've created a plugin that will check for self
signed, bad intermediate CAs etc. If there is some interest I'll clean
it up ( move to getopt and add '--help' mainly ) and submit it properly.


$ ./check_ssl_cert www.verisign.com 443 vcCA/verisign_ca 
OK: ok 
$ ./check_ssl_cert myfakebox.com 443 vcCA/verisign_ca 
Verifcation Error: unable to get local issuer certificate 
$ ./check_ssl_cert localhost 443 vcCA/verisign_ca 
Verifcation Error: self signed certificate 
$ ./check_ssl_cert localhost 4433 vcCA/verisign_ca 
connect: Connection refused 
$ ./check_ssl_cert www.bogusdomain 443 vcCA/verisign_ca 
ERROR: No valid host


//Naoki's Code to Verifiy an SSL certificate using optional intermediate
CAs. 
//2005/01/21 - v0.1 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 

#include <openssl/bio.h> 
#include <openssl/err.h> 
#include <openssl/rand.h> 
#include <openssl/ssl.h> 
#include <openssl/x509v3.h> 

#define CHK_NULL(x) if ((x)==NULL) exit (1) 
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); } 
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit
(2); } 

int main ( int argc, char *argv[] ) { 

//    Counters 
   int    i,j,port,err; 
   int   debug_mode = 0; 
   int   return_code = 0; 
   long   l; 
   char*     cert_name; 
   char*   cert_issuer; 
   char    *trusted_ca_file=NULL; 
   char    *trusted_ca_path=NULL; 
//   TCP Structures 
   int    sd; 
   struct    hostent *host; 
   struct    sockaddr_in addr; 

//   SSL Structures 
   SSL_METHOD *method; 
   SSL_CTX *ctx; 
   SSL*   ssl; 
   X509*    server_cert; 

//   Setup SSL 
   OpenSSL_add_all_algorithms();    
   SSL_load_error_strings();      
   method = SSLv23_client_method(); 
   ctx = SSL_CTX_new(method); 
   CHK_SSL(err); 

//   The first argument is our host, the second our port. The third is
the path to trusted CA. The fourth is optional debug. 
   host = gethostbyname(argv[1]); 
   if (host == NULL) { printf ("ERROR: No valid host\n"); exit (2); } 
   port = atoi (argv[2]); 
   trusted_ca_file = (argv[3]); 

   if (argv[4] != NULL) {    
      if ( strncmp(argv[4],"debug",5) == 0 ) {debug_mode = 1; ;printf
("set to %d, %s\n", debug_mode, argv[4]); } 
   } 

//   Create a socket 
   sd = socket(PF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket"); 
   memset(&addr, 0, sizeof(addr)); 
   addr.sin_family = AF_INET; 
   addr.sin_port = htons(port); 
   addr.sin_addr.s_addr = *(long*)(host->h_addr); 
   err = connect(sd, (struct sockaddr*)&addr, sizeof(addr)); CHK_ERR
(err, "connect"); 
if (debug_mode) printf("TCP Connection opened.. Starting SSL negotiation
\n"); 

        //SSL_CTX_set_verify_depth(ctx, 10); 
   //SSL_CTX_set_verify(ctx,verify,verify_callback); 
        SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file
(trusted_ca_file)); 
        if (SSL_CTX_load_verify_locations(ctx, trusted_ca_file,
trusted_ca_path)) {   l = SSL_CTX_set_default_verify_paths(ctx); } 
if (debug_mode)   printf("Set Trusted CA location: %d\n",l); 

   ssl = SSL_new(ctx);  CHK_NULL(ssl);  

   SSL_set_fd(ssl, sd); 
   err = SSL_connect(ssl); CHK_SSL(err); 

if (debug_mode) printf("SSL Connection Established.. Checking server
CERT\n");    

   SSL_get_peer_cert_chain(ssl); 

   server_cert = SSL_get_peer_certificate (ssl);        
   CHK_NULL(server_cert); 

     cert_name = X509_NAME_oneline (X509_get_subject_name
(server_cert),0,0); 
     CHK_NULL(cert_name); 

     cert_issuer = X509_NAME_oneline (X509_get_issuer_name
(server_cert),0,0); 
     CHK_NULL(cert_issuer); 

        l = SSL_get_verify_result( ssl ); 

if (debug_mode) { 
   printf ("Cert issuer: %s\n", cert_issuer); 
     printf ("Cert subject: %s\n", cert_name); 
   printf("Verifcation Code: %d\n",l); 
} 

   if (l != X509_V_OK ) { 
      printf("Verifcation Error: %s\n",X509_verify_cert_error_string
(l)); 
      return_code = 1;    
   } else { 
      printf ("OK: %s\n", X509_verify_cert_error_string(l) ); 
      return_code = 0; 
   } 
    

//   If all good, cleanup and leave 
   OPENSSL_free (cert_name); 
   OPENSSL_free (cert_issuer); 
     X509_free (server_cert); 
     close (sd); 
     SSL_free (ssl); 
    SSL_CTX_free (ctx); 

   return return_code; 
}

Mark "Naoki" Rogers 
----------------------------------------
Vice President - Systems and Engineering
ValueCommerce





More information about the Devel mailing list