Advertisement
Guest User

Modified SSLscan

a guest
Dec 28th, 2014
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 69.37 KB | None | 0 0
  1. /***************************************************************************
  2.  *   sslscan - A SSL cipher scanning tool                                  *
  3.  *   Copyright 2007-2009 by Ian Ventura-Whiting (Fizz)                     *
  4.  *   fizz@titania.co.uk                                                    *
  5.  *                                                                         *
  6.  *   Modified by Jeffrey Walton in 2013 to support TLS 1.1 and TLS 1.2     *
  7.  *   noloader@gmail.com                                                    *
  8.  *                                                                         *
  9.  *   This program is free software; you can redistribute it and/or modify  *
  10.  *   it under the terms of the GNU General Public License as published by  *
  11.  *   the Free Software Foundation; either version 3 of the License, or     *
  12.  *   (at your option) any later version.                                   *
  13.  *                                                                         *
  14.  *   This program is distributed in the hope that it will be useful,       *
  15.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  16.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  17.  *   GNU General Public License for more details.                          *
  18.  *                                                                         *
  19.  *   You should have received a copy of the GNU General Public License     *
  20.  *   along with this program. If not, see <http://www.gnu.org/licenses/>.  *
  21.  *                                                                         *
  22.  *   In addition, as a special exception, the copyright holders give       *
  23.  *   permission to link the code of portions of this program with the      *
  24.  *   OpenSSL library under certain conditions as described in each         *
  25.  *   individual source file, and distribute linked combinations            *
  26.  *   including the two.                                                    *
  27.  *   You must obey the GNU General Public License in all respects          *
  28.  *   for all of the code used other than OpenSSL.  If you modify           *
  29.  *   file(s) with this exception, you may extend this exception to your    *
  30.  *   version of the file(s), but you are not obligated to do so.  If you   *
  31.  *   do not wish to do so, delete this exception statement from your       *
  32.  *   version.  If you delete this exception statement from all source      *
  33.  *   files in the program, then also delete it here.                       *
  34.  ***************************************************************************/
  35.  
  36. // Includes...
  37. #include <string.h>
  38. #include <netdb.h>
  39. #include <unistd.h>
  40. #include <sys/stat.h>
  41. #include <sys/socket.h>
  42. #include <openssl/err.h>
  43. #include <openssl/ssl.h>
  44. #include <openssl/pkcs12.h>
  45. #include <openssl/x509.h>
  46. #include <openssl/x509v3.h>
  47. #include <openssl/opensslconf.h>
  48.  
  49. // Defines...
  50. #define false 0
  51. #define true 1
  52.  
  53. #define mode_help 0
  54. #define mode_version 1
  55. #define mode_single 2
  56. #define mode_multiple 3
  57.  
  58. #define BUFFERSIZE 1024
  59.  
  60. #define ssl_all 0
  61. #define ssl_v2 1
  62. #define ssl_v3 2
  63. #define tls_v1 3
  64. #define tls_v1_1 4
  65. #define tls_v1_2 5
  66.  
  67. // Colour Console Output...
  68. #if !defined(__WIN32__)
  69. const char *RESET = "";         // DEFAULT
  70. const char *COL_RED = "";      // RED
  71. const char *COL_BLUE = "";     // BLUE
  72. const char *COL_GREEN = "";    // GREEN
  73. #else
  74. const char *RESET = "";
  75. const char *COL_RED = "";
  76. const char *COL_BLUE = "";
  77. const char *COL_GREEN = "";
  78. #endif
  79.  
  80.  
  81. const char *program_banner = "                   _\n"
  82. "           ___ ___| |___  ___ __ _ _ __\n"
  83. "          / __/ __| / __|/ __/ _` | '_ \\\n"
  84. "          \\__ \\__ \\ \\__ \\ (_| (_| | | | |\n"
  85. "          |___/___/_|___/\\___\\__,_|_| |_|\n\n"
  86. "                  Version 1.8.2\n"
  87. "             http://www.titania.co.uk\n"
  88. "        Copyright Ian Ventura-Whiting 2009\n"
  89. "           Modified Jeffrey Walton 2013\n";
  90. const char *program_version = "sslscan version 1.8.2\nhttp://www.titania.co.uk\nCopyright (C) Ian Ventura-Whiting 2009\n";
  91. const char *xml_version = "1.8.2";
  92.  
  93. struct sslCipher
  94. {
  95.     // Cipher Properties...
  96.     const char *name;
  97.     char *version;
  98.     int bits;
  99.     char description[512];
  100.     const SSL_METHOD *sslMethod;
  101.     struct sslCipher *next;
  102. };
  103.  
  104. struct sslCheckOptions
  105. {
  106.     // Program Options...
  107.     char host[512];
  108.     int port;
  109.     int noFailed;
  110.     int noSNI;
  111.     int starttls;
  112.     int sslVersion;
  113.     int targets;
  114.     int pout;
  115.     int sslbugs;
  116.     int http;
  117.    
  118.     // File Handles...
  119.     FILE *xmlOutput;
  120.    
  121.     // TCP Connection Variables...
  122.     struct hostent *hostStruct;
  123.     struct sockaddr_in serverAddress;
  124.    
  125.     // SSL Variables...
  126.     SSL_CTX *ctx;
  127.     struct sslCipher *ciphers;
  128.     char *clientCertsFile;
  129.     char *privateKeyFile;
  130.     char *privateKeyPassword;
  131. };
  132.  
  133. /* Per the CHANGELOG, TLS 1.1 and TLS 1.2 are available in 1.0.1 and above */
  134. #if !(OPENSSL_VERSION_NUMBER >= 0x10001000L)
  135. # define SSLSCAN_NO_TLS1_1
  136. # define SSLSCAN_NO_TLS1_2
  137. #endif
  138.  
  139. /* OpenSSL was config'd with 'no-ssl2' */
  140. #ifdef OPENSSL_NO_SSL2
  141. # define SSLSCAN_NO_SSL2
  142. #endif
  143.  
  144. static const char* availableProtocols()
  145. {
  146.     static char buffer[128] = {};
  147.     buffer[0] = '\0';
  148.    
  149.     strcat(buffer, "Protocols: ");
  150.    
  151. #ifndef SSLSCAN_NO_SSL2
  152.     strcat(buffer, "SSLv2 ");
  153. #endif
  154.    
  155. #ifndef SSLSCAN_NO_SSL3
  156.     strcat(buffer, "SSLv3 ");
  157. #endif
  158.    
  159. #ifndef SSLSCAN_NO_TLS1_0
  160.     strcat(buffer, "TLSv1.0 ");
  161. #endif
  162.    
  163. #ifndef SSLSCAN_NO_TLS1_1
  164.     strcat(buffer, "TLSv1.1 ");
  165. #endif
  166.    
  167. #ifndef SSLSCAN_NO_TLS1_2
  168.     strcat(buffer, "TLSv1.2 ");
  169. #endif
  170.    
  171.     return buffer;
  172. }
  173.  
  174. // Adds Ciphers to the Cipher List structure
  175. int populateCipherList(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
  176. {
  177.     // Variables...
  178.     int returnCode = true;
  179.     struct sslCipher *sslCipherPointer;
  180.     int tempInt;
  181.     int loop;
  182.     STACK_OF(SSL_CIPHER) *cipherList;
  183.     SSL *ssl = NULL;
  184.    
  185.     // Setup Context Object...
  186.     options->ctx = SSL_CTX_new(sslMethod);
  187.     if (options->ctx != NULL)
  188.     {
  189.         SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL");
  190.        
  191.         // Create new SSL object
  192.         ssl = SSL_new(options->ctx);
  193.         if (ssl != NULL)
  194.         {
  195.             // Get List of Ciphers
  196.             cipherList = SSL_get_ciphers(ssl);
  197.            
  198.             // Create Cipher Struct Entries...
  199.             for (loop = 0; loop < sk_SSL_CIPHER_num(cipherList); loop++)
  200.             {
  201.                 // Create Structure...
  202.                 if (options->ciphers == 0)
  203.                 {
  204.                     options->ciphers = malloc(sizeof(struct sslCipher));
  205.                     sslCipherPointer = options->ciphers;
  206.                 }
  207.                 else
  208.                 {
  209.                     sslCipherPointer = options->ciphers;
  210.                     while (sslCipherPointer->next != 0)
  211.                         sslCipherPointer = sslCipherPointer->next;
  212.                     sslCipherPointer->next = malloc(sizeof(struct sslCipher));
  213.                     sslCipherPointer = sslCipherPointer->next;
  214.                 }
  215.                
  216.                 // Init
  217.                 memset(sslCipherPointer, 0, sizeof(struct sslCipher));
  218.                
  219.                 // Add cipher information...
  220.                 sslCipherPointer->sslMethod = sslMethod;
  221.                 sslCipherPointer->name = SSL_CIPHER_get_name(sk_SSL_CIPHER_value(cipherList, loop));
  222.                 sslCipherPointer->version = SSL_CIPHER_get_version(sk_SSL_CIPHER_value(cipherList, loop));
  223.                 SSL_CIPHER_description(sk_SSL_CIPHER_value(cipherList, loop), sslCipherPointer->description, sizeof(sslCipherPointer->description) - 1);
  224.                 sslCipherPointer->bits = SSL_CIPHER_get_bits(sk_SSL_CIPHER_value(cipherList, loop), &tempInt);
  225.             }
  226.            
  227.             // Free SSL object
  228.             SSL_free(ssl);
  229.         }
  230.         else
  231.         {
  232.             returnCode = false;
  233.             printf("%sERROR: Could not create SSL object.%s\n", COL_RED, RESET);
  234.         }
  235.        
  236.         // Free CTX Object
  237.         SSL_CTX_free(options->ctx);
  238.     }
  239.    
  240.     // Error Creating Context Object
  241.     else
  242.     {
  243.         returnCode = false;
  244.         printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
  245.     }
  246.    
  247.     return returnCode;
  248. }
  249.  
  250.  
  251. // File Exists
  252. int fileExists(char *fileName)
  253. {
  254.     // Variables...
  255.     struct stat fileStats;
  256.    
  257.     if (stat(fileName, &fileStats) == 0)
  258.         return true;
  259.     else
  260.         return false;
  261. }
  262.  
  263.  
  264. // Read a line from the input...
  265. void readLine(FILE *input, char *lineFromFile, int maxSize)
  266. {
  267.     // Variables...
  268.     int stripPointer;
  269.    
  270.     // Read line from file...
  271.     fgets(lineFromFile, maxSize, input);
  272.    
  273.     // Clear the end-of-line stuff...
  274.     stripPointer = strlen(lineFromFile) -1;
  275.     while ((lineFromFile[stripPointer] == '\r') || (lineFromFile[stripPointer] == '\n') || (lineFromFile[stripPointer] == ' '))
  276.     {
  277.         lineFromFile[stripPointer] = 0;
  278.         stripPointer--;
  279.     }
  280. }
  281.  
  282.  
  283. // Create a TCP socket
  284. int tcpConnect(struct sslCheckOptions *options)
  285. {
  286.     // Variables...
  287.     int socketDescriptor;
  288.     char buffer[BUFFERSIZE];
  289.     struct sockaddr_in localAddress;
  290.     int status;
  291.    
  292.     // Create Socket
  293.     socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
  294.     if(socketDescriptor < 0)
  295.     {
  296.         printf("%s    ERROR: Could not open a socket.%s\n", COL_RED, RESET);
  297.         return 0;
  298.     }
  299.    
  300.     // Configure Local Port
  301.     localAddress.sin_family = AF_INET;
  302.     localAddress.sin_addr.s_addr = htonl(INADDR_ANY);
  303.     localAddress.sin_port = htons(0);
  304.     status = bind(socketDescriptor, (struct sockaddr *) &localAddress, sizeof(localAddress));
  305.     if(status < 0)
  306.     {
  307.         printf("%s    ERROR: Could not bind to port.%s\n", COL_RED, RESET);
  308.         return 0;
  309.     }
  310.    
  311.     // Connect
  312.     status = connect(socketDescriptor, (struct sockaddr *) &options->serverAddress, sizeof(options->serverAddress));
  313.     if(status < 0)
  314.     {
  315.         printf("%s    ERROR: Could not open a connection to host %s on port %d.%s\n", COL_RED, options->host, options->port, RESET);
  316.         return 0;
  317.     }
  318.    
  319.     // If STARTTLS is required...
  320.     if (options->starttls == true)
  321.     {
  322.         memset(buffer, 0, BUFFERSIZE);
  323.         recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0);
  324.         if (strncmp(buffer, "220", 3) != 0)
  325.         {
  326.             close(socketDescriptor);
  327.             printf("%s    ERROR: The host %s on port %d did not appear to be an SMTP service.%s\n", COL_RED, options->host, options->port, RESET);
  328.             return 0;
  329.         }
  330.         send(socketDescriptor, "EHLO titania.co.uk\r\n", 20, 0);
  331.         memset(buffer, 0, BUFFERSIZE);
  332.         recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0);
  333.         if (strncmp(buffer, "250", 3) != 0)
  334.         {
  335.             close(socketDescriptor);
  336.             printf("%s    ERROR: The SMTP service on %s port %d did not respond with status 250 to our HELO.%s\n", COL_RED, options->host, options->port, RESET);
  337.             return 0;
  338.         }
  339.         send(socketDescriptor, "STARTTLS\r\n", 10, 0);
  340.         memset(buffer, 0, BUFFERSIZE);
  341.         recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0);
  342.         if (strncmp(buffer, "220", 3) != 0)
  343.         {
  344.             close(socketDescriptor);
  345.             printf("%s    ERROR: The SMTP service on %s port %d did not appear to support STARTTLS.%s\n", COL_RED, options->host, options->port, RESET);
  346.             return 0;
  347.         }
  348.     }
  349.    
  350.     // Return
  351.     return socketDescriptor;
  352. }
  353.  
  354.  
  355. // Private Key Password Callback...
  356. static int password_callback(char *buf, int size, int rwflag, void *userdata)
  357. {
  358.     strncpy(buf, (char *)userdata, size);
  359.     buf[strlen(userdata)] = 0;
  360.     return strlen(userdata);
  361. }
  362.  
  363.  
  364. // Load client certificates/private keys...
  365. int loadCerts(struct sslCheckOptions *options)
  366. {
  367.     // Variables...
  368.     int status = 1;
  369.     PKCS12 *pk12 = NULL;
  370.     FILE *pk12File = NULL;
  371.     X509 *cert = NULL;
  372.     EVP_PKEY *pkey = NULL;
  373.     STACK_OF(X509) *ca = NULL;
  374.    
  375.     // Configure PKey password...
  376.     if (options->privateKeyPassword != 0)
  377.     {
  378.         SSL_CTX_set_default_passwd_cb_userdata(options->ctx, (void *)options->privateKeyPassword);
  379.         SSL_CTX_set_default_passwd_cb(options->ctx, password_callback);
  380.     }
  381.    
  382.     // Seperate Certs and PKey Files...
  383.     if ((options->clientCertsFile != 0) && (options->privateKeyFile != 0))
  384.     {
  385.         // Load Cert...
  386.         if (!SSL_CTX_use_certificate_file(options->ctx, options->clientCertsFile, SSL_FILETYPE_PEM))
  387.         {
  388.             if (!SSL_CTX_use_certificate_file(options->ctx, options->clientCertsFile, SSL_FILETYPE_ASN1))
  389.             {
  390.                 if (!SSL_CTX_use_certificate_chain_file(options->ctx, options->clientCertsFile))
  391.                 {
  392.                     printf("%s    Could not configure certificate(s).%s\n", COL_RED, RESET);
  393.                     status = 0;
  394.                 }
  395.             }
  396.         }
  397.        
  398.         // Load PKey...
  399.         if (status != 0)
  400.         {
  401.             if (!SSL_CTX_use_PrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_PEM))
  402.             {
  403.                 if (!SSL_CTX_use_PrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_ASN1))
  404.                 {
  405.                     if (!SSL_CTX_use_RSAPrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_PEM))
  406.                     {
  407.                         if (!SSL_CTX_use_RSAPrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_ASN1))
  408.                         {
  409.                             printf("%s    Could not configure private key.%s\n", COL_RED, RESET);
  410.                             status = 0;
  411.                         }
  412.                     }
  413.                 }
  414.             }
  415.         }
  416.     }
  417.    
  418.     // PKCS Cert and PKey File...
  419.     else if (options->privateKeyFile != 0)
  420.     {
  421.         pk12File = fopen(options->privateKeyFile, "rb");
  422.         if (pk12File != NULL)
  423.         {
  424.             pk12 = d2i_PKCS12_fp(pk12File, NULL);
  425.             if (!pk12)
  426.             {
  427.                 status = 0;
  428.                 printf("%s    Could not read PKCS#12 file.%s\n", COL_RED, RESET);
  429.             }
  430.             else
  431.             {
  432.                 if (!PKCS12_parse(pk12, options->privateKeyPassword, &pkey, &cert, &ca))
  433.                 {
  434.                     status = 0;
  435.                     printf("%s    Error parsing PKCS#12. Are you sure that password was correct?%s\n", COL_RED, RESET);
  436.                 }
  437.                 else
  438.                 {
  439.                     if (!SSL_CTX_use_certificate(options->ctx, cert))
  440.                     {
  441.                         status = 0;
  442.                         printf("%s    Could not configure certificate.%s\n", COL_RED, RESET);
  443.                     }
  444.                     if (!SSL_CTX_use_PrivateKey(options->ctx, pkey))
  445.                     {
  446.                         status = 0;
  447.                         printf("%s    Could not configure private key.%s\n", COL_RED, RESET);
  448.                     }
  449.                 }
  450.                 PKCS12_free(pk12);
  451.             }
  452.             fclose(pk12File);
  453.         }
  454.         else
  455.         {
  456.             printf("%s    Could not open PKCS#12 file.%s\n", COL_RED, RESET);
  457.             status = 0;
  458.         }
  459.     }
  460.    
  461.     // Check Cert/Key...
  462.     if (status != 0)
  463.     {
  464.         if (!SSL_CTX_check_private_key(options->ctx))
  465.         {
  466.             printf("%s    Prvate key does not match certificate.%s\n", COL_RED, RESET);
  467.             return false;
  468.         }
  469.         else
  470.             return true;
  471.     }
  472.     else
  473.         return false;
  474. }
  475.  
  476.  
  477. // Test a cipher...
  478. int testCipher(struct sslCheckOptions *options, struct sslCipher *sslCipherPointer)
  479. {
  480.     // Variables...
  481.     int cipherStatus;
  482.     int status = true;
  483.     int socketDescriptor = 0;
  484.     SSL *ssl = NULL;
  485.     BIO *cipherConnectionBio;
  486.     BIO *stdoutBIO = NULL;
  487.     int tempInt;
  488.     char requestBuffer[200];
  489.     char buffer[50];
  490.     int resultSize = 0;
  491.    
  492.     // Create request buffer...
  493.     memset(requestBuffer, 0, 200);
  494.     snprintf(requestBuffer, 199, "GET / HTTP/1.0\r\nUser-Agent: SSLScan\r\nHost: %s\r\n\r\n", options->host);
  495.    
  496.     // Connect to host
  497.     socketDescriptor = tcpConnect(options);
  498.     if (socketDescriptor != 0)
  499.     {
  500.         if (SSL_CTX_set_cipher_list(options->ctx, sslCipherPointer->name) != 0)
  501.         {            
  502.             // Create SSL object...
  503.             ssl = SSL_new(options->ctx);
  504.             if (ssl != NULL)
  505.             {
  506.                
  507. #if (OPENSSL_VERSION_NUMBER >= 0x00908060L /*0.9.8f*/)
  508.                 // Added at 0.9.8f, see CHANGELOG
  509.                 if(! options->noSNI)
  510.                     SSL_set_tlsext_host_name(ssl, options->host);
  511. #endif
  512.                
  513.                 // Connect socket and BIO
  514.                 cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE);
  515.                
  516.                 // Connect SSL and BIO
  517.                 SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio);
  518.                
  519.                 // Connect SSL over socket
  520.                 cipherStatus = SSL_connect(ssl);
  521.                
  522.                 // Show Cipher Status
  523.                 if (!((options->noFailed == true) && (cipherStatus != 1)))
  524.                 {
  525.                     if (options->xmlOutput != 0)
  526.                         fprintf(options->xmlOutput, "  <cipher status=\"");
  527.                     if (cipherStatus == 1)
  528.                     {
  529.                         if (options->xmlOutput != 0)
  530.                             fprintf(options->xmlOutput, "accepted\"");
  531.                         if (options->pout == true)
  532.                             printf("|| Accepted || ");
  533.                         else
  534.                             printf("    Accepted  ");
  535.                         if (options->http == true)
  536.                         {
  537.                            
  538.                             // Stdout BIO...
  539.                             stdoutBIO = BIO_new(BIO_s_file());
  540.                             BIO_set_fp(stdoutBIO, stdout, BIO_NOCLOSE);
  541.                            
  542.                             // HTTP Get...
  543.                             SSL_write(ssl, requestBuffer, sizeof(requestBuffer));
  544.                             memset(buffer ,0 , 50);
  545.                             resultSize = SSL_read(ssl, buffer, 49);
  546.                             if (resultSize > 9)
  547.                             {
  548.                                 int loop = 0;
  549.                                 for (loop = 9; (loop < 49) && (buffer[loop] != 0) && (buffer[loop] != '\r') && (buffer[loop] != '\n'); loop++)
  550.                                 { }
  551.                                 buffer[loop] = 0;
  552.                                
  553.                                 // Output HTTP code...
  554.                                 if (options->pout == true)
  555.                                     printf("%s || ", buffer + 9);
  556.                                 else
  557.                                 {
  558.                                     printf("%s", buffer + 9);
  559.                                     loop = strlen(buffer + 9);
  560.                                     while (loop < 17)
  561.                                     {
  562.                                         loop++;
  563.                                         printf(" ");
  564.                                     }
  565.                                 }
  566.                                 if (options->xmlOutput != 0)
  567.                                     fprintf(options->xmlOutput, " http=\"%s\"", buffer + 9);
  568.                             }
  569.                             else
  570.                             {
  571.                                 // Output HTTP code...
  572.                                 if (options->pout == true)
  573.                                     printf("|| || ");
  574.                                 else
  575.                                     printf("                 ");
  576.                             }
  577.                         }
  578.                     }
  579.                     else if (cipherStatus == 0)
  580.                     {
  581.                         if (options->xmlOutput != 0)
  582.                             fprintf(options->xmlOutput, "rejected\"");
  583.                         if (options->http == true)
  584.                         {
  585.                             if (options->pout == true)
  586.                                 printf("|| Rejected || N/A || ");
  587.                             else
  588.                                 printf("    Rejected  N/A              ");
  589.                         }
  590.                         else
  591.                         {
  592.                             if (options->pout == true)
  593.                                 printf("|| Rejected || ");
  594.                             else
  595.                                 printf("    Rejected  ");
  596.                         }
  597.                     }
  598.                     else
  599.                     {
  600.                         if (options->xmlOutput != 0)
  601.                             fprintf(options->xmlOutput, "failed\"");
  602.                         if (options->http == true)
  603.                         {
  604.                             if (options->pout == true)
  605.                                 printf("|| Failed || N/A || ");
  606.                             else
  607.                                 printf("    Failed    N/A              ");
  608.                         }
  609.                         else
  610.                         {
  611.                             if (options->pout == true)
  612.                                 printf("|| Failed || ");
  613.                             else
  614.                                 printf("    Failed    ");
  615.                         }
  616.                     }
  617.                     if (options->xmlOutput != 0)
  618.                         fprintf(options->xmlOutput, " sslversion=\"");
  619. #ifndef SSLSCAN_NO_SSL2
  620.                     if (sslCipherPointer->sslMethod == SSLv2_client_method())
  621.                     {
  622.                         if (options->xmlOutput != 0)
  623.                             fprintf(options->xmlOutput, "SSLv2\" bits=\"");
  624.                         if (options->pout == true)
  625.                             printf("SSLv2 || ");
  626.                         else
  627.                             printf("SSLv2  ");
  628.                     }
  629.                     else
  630. #endif
  631.                         if (sslCipherPointer->sslMethod == SSLv3_client_method())
  632.                         {
  633.                             if (options->xmlOutput != 0)
  634.                                 fprintf(options->xmlOutput, "SSLv3\" bits=\"");
  635.                             if (options->pout == true)
  636.                                 printf("SSLv3 || ");
  637.                             else
  638.                                 printf("SSLv3  ");
  639.                         }
  640.                         else if (sslCipherPointer->sslMethod == TLSv1_client_method())
  641.                         {
  642.                             if (options->xmlOutput != 0)
  643.                                 fprintf(options->xmlOutput, "TLSv1\" bits=\"");
  644.                             if (options->pout == true)
  645.                                 printf("TLSv1 || ");
  646.                             else
  647.                                 printf("TLSv1  ");
  648.                         }
  649. #ifndef SSLSCAN_NO_TLS1_1
  650.                         else if (sslCipherPointer->sslMethod == TLSv1_1_client_method())
  651.                         {
  652.                             if (options->xmlOutput != 0)
  653.                                 fprintf(options->xmlOutput, "TLSv1.1\" bits=\"");
  654.                             if (options->pout == true)
  655.                                 printf("TLSv1.1 || ");
  656.                             else
  657.                                 printf("TLSv1.1  ");
  658.                         }
  659. #endif
  660.                    
  661. #ifndef SSLSCAN_NO_TLS1_2
  662.                         else if (sslCipherPointer->sslMethod == TLSv1_2_client_method())
  663.                         {
  664.                             if (options->xmlOutput != 0)
  665.                                 fprintf(options->xmlOutput, "TLSv1.2\" bits=\"");
  666.                             if (options->pout == true)
  667.                                 printf("TLSv1.2 || ");
  668.                             else
  669.                                 printf("TLSv1.2  ");
  670.                         }
  671. #endif
  672.                         else
  673.                         {
  674.                             printf("ERROR unknown protocol version\n");
  675.                            
  676.                         }
  677.                     if (sslCipherPointer->bits < 10)
  678.                         tempInt = 2;
  679.                     else if (sslCipherPointer->bits < 100)
  680.                         tempInt = 1;
  681.                     else
  682.                         tempInt = 0;
  683.                     if (options->pout == true)
  684.                         printf("%d || ", sslCipherPointer->bits);
  685.                     else
  686.                         printf("%d bits  ", sslCipherPointer->bits);
  687.                     while (tempInt != 0)
  688.                     {
  689.                         tempInt--;
  690.                         printf(" ");
  691.                     }
  692.                     if (options->xmlOutput != 0)
  693.                         fprintf(options->xmlOutput, "%d\" cipher=\"%s\" />\n", sslCipherPointer->bits, sslCipherPointer->name);
  694.                     if (options->pout == true)
  695.                         printf("%s ||\n", sslCipherPointer->name);
  696.                     else
  697.                         printf("%s\n", sslCipherPointer->name);
  698.                 }
  699.                
  700.                 // Disconnect SSL over socket
  701.                 if (cipherStatus == 1)
  702.                     SSL_shutdown(ssl);
  703.                
  704.                 // Free SSL object
  705.                 SSL_free(ssl);
  706.             }
  707.             else
  708.             {
  709.                 status = false;
  710.                 printf("%s    ERROR: Could create SSL object.%s\n", COL_RED, RESET);
  711.             }
  712.         }
  713.         else
  714.         {
  715.             status = false;
  716.             printf("%s    ERROR: Could set cipher %s.%s\n", COL_RED, sslCipherPointer->name, RESET);
  717.         }
  718.        
  719.         // Disconnect from host
  720.         close(socketDescriptor);
  721.     }
  722.    
  723.     // Could not connect
  724.     else
  725.         status = false;
  726.    
  727.     return status;
  728. }
  729.  
  730.  
  731. // Test for prefered ciphers
  732. int defaultCipher(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
  733. {
  734.     // Variables...
  735.     int cipherStatus;
  736.     int status = true;
  737.     int socketDescriptor = 0;
  738.     SSL *ssl = NULL;
  739.     BIO *cipherConnectionBio;
  740.     int tempInt;
  741.     int tempInt2;
  742.    
  743.     // Connect to host
  744.     socketDescriptor = tcpConnect(options);
  745.     if (socketDescriptor != 0)
  746.     {
  747.        
  748.         // Setup Context Object...
  749.         options->ctx = SSL_CTX_new(sslMethod);
  750.         if (options->ctx != NULL)
  751.         {
  752.             if (SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL") != 0)
  753.             {
  754.                
  755.                 // Load Certs if required...
  756.                 if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0))
  757.                     status = loadCerts(options);
  758.                
  759.                 if (status == true)
  760.                 {
  761.                     // Create SSL object...
  762.                     ssl = SSL_new(options->ctx);
  763.                     if (ssl != NULL)
  764.                     {
  765.                         // Connect socket and BIO
  766.                         cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE);
  767.                        
  768.                         // Connect SSL and BIO
  769.                         SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio);
  770.                        
  771.                         // Connect SSL over socket
  772.                         cipherStatus = SSL_connect(ssl);
  773.                         if (cipherStatus == 1)
  774.                         {
  775. #ifndef SSLSCAN_NO_SSL2
  776.                             if (sslMethod == SSLv2_client_method())
  777.                             {
  778.                                 if (options->xmlOutput != 0)
  779.                                     fprintf(options->xmlOutput, "  <defaultcipher sslversion=\"SSLv2\" bits=\"");
  780.                                 if (options->pout == true)
  781.                                     printf("|| SSLv2 || ");
  782.                                 else
  783.                                     printf("    SSLv2  ");
  784.                             }
  785.                             else
  786. #endif
  787.                                 if (sslMethod == SSLv3_client_method())
  788.                                 {
  789.                                     if (options->xmlOutput != 0)
  790.                                         fprintf(options->xmlOutput, "  <defaultcipher sslversion=\"SSLv3\" bits=\"");
  791.                                     if (options->pout == true)
  792.                                         printf("|| SSLv3 || ");
  793.                                     else
  794.                                         printf("    SSLv3  ");
  795.                                 }
  796.                            
  797.                                 else if (sslMethod == TLSv1_client_method())
  798.                                 {
  799.                                     if (options->xmlOutput != 0)
  800.                                         fprintf(options->xmlOutput, "  <defaultcipher sslversion=\"TLSv1\" bits=\"");
  801.                                     if (options->pout == true)
  802.                                         printf("|| TLSv1 || ");
  803.                                     else
  804.                                         printf("    TLSv1  ");
  805.                                 }
  806. #ifndef SSLSCAN_NO_TLS1_1
  807.                                 else if (sslMethod == TLSv1_1_client_method())
  808.                                 {
  809.                                     if (options->xmlOutput != 0)
  810.                                         fprintf(options->xmlOutput, "  <defaultcipher sslversion=\"TLSv1.1\" bits=\"");
  811.                                     if (options->pout == true)
  812.                                         printf("|| TLSv1.1 || ");
  813.                                     else
  814.                                         printf("    TLSv1.1  ");
  815.                                 }
  816. #endif
  817.                            
  818. #ifndef SSLSCAN_NO_TLS1_2
  819.                                 else if (sslMethod == TLSv1_2_client_method())
  820.                                 {
  821.                                     if (options->xmlOutput != 0)
  822.                                         fprintf(options->xmlOutput, "  <defaultcipher sslversion=\"TLSv1.2\" bits=\"");
  823.                                     if (options->pout == true)
  824.                                         printf("|| TLSv1.2 || ");
  825.                                     else
  826.                                         printf("    TLSv1.2  ");
  827.                                 }
  828. #endif
  829.                            
  830.                                 else
  831.                                 {
  832.                                     printf("ERROR: unknown protocol\n");
  833.                                 }
  834.                             if (SSL_get_cipher_bits(ssl, &tempInt2) < 10)
  835.                                 tempInt = 2;
  836.                             else if (SSL_get_cipher_bits(ssl, &tempInt2) < 100)
  837.                                 tempInt = 1;
  838.                             else
  839.                                 tempInt = 0;
  840.                             if (options->pout == true)
  841.                                 printf("%d bits || ", SSL_get_cipher_bits(ssl, &tempInt2));
  842.                             else
  843.                                 printf("%d bits  ", SSL_get_cipher_bits(ssl, &tempInt2));
  844.                             while (tempInt != 0)
  845.                             {
  846.                                 tempInt--;
  847.                                 printf(" ");
  848.                             }
  849.                             if (options->xmlOutput != 0)
  850.                                 fprintf(options->xmlOutput, "%d\" cipher=\"%s\" />\n", SSL_get_cipher_bits(ssl, &tempInt2), SSL_get_cipher_name(ssl));
  851.                             if (options->pout == true)
  852.                                 printf("%s ||\n", SSL_get_cipher_name(ssl));
  853.                             else
  854.                                 printf("%s\n", SSL_get_cipher_name(ssl));
  855.                            
  856.                             // Disconnect SSL over socket
  857.                             SSL_shutdown(ssl);
  858.                         }
  859.                        
  860.                         // Free SSL object
  861.                         SSL_free(ssl);
  862.                     }
  863.                     else
  864.                     {
  865.                         status = false;
  866.                         printf("%s    ERROR: Could create SSL object.%s\n", COL_RED, RESET);
  867.                     }
  868.                 }
  869.             }
  870.             else
  871.             {
  872.                 status = false;
  873.                 printf("%s    ERROR: Could set cipher.%s\n", COL_RED, RESET);
  874.             }
  875.            
  876.             // Free CTX Object
  877.             SSL_CTX_free(options->ctx);
  878.         }
  879.        
  880.         // Error Creating Context Object
  881.         else
  882.         {
  883.             status = false;
  884.             printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
  885.         }
  886.        
  887.         // Disconnect from host
  888.         close(socketDescriptor);
  889.     }
  890.    
  891.     // Could not connect
  892.     else
  893.         status = false;
  894.    
  895.     return status;
  896. }
  897.  
  898.  
  899. // Get certificate...
  900. int getCertificate(struct sslCheckOptions *options)
  901. {
  902.     // Variables...
  903.     int cipherStatus = 0;
  904.     int status = true;
  905.     int socketDescriptor = 0;
  906.     SSL *ssl = NULL;
  907.     BIO *cipherConnectionBio = NULL;
  908.     BIO *stdoutBIO = NULL;
  909.     BIO *fileBIO = NULL;
  910.     X509 *x509Cert = NULL;
  911.     EVP_PKEY *publicKey = NULL;
  912.     const SSL_METHOD *sslMethod = NULL;
  913.     ASN1_OBJECT *asn1Object = NULL;
  914.     X509_EXTENSION *extension = NULL;
  915.     char buffer[1024];
  916.     long tempLong = 0;
  917.     int tempInt = 0;
  918.     int tempInt2 = 0;
  919.     long verifyError = 0;
  920.    
  921.     // Connect to host
  922.     socketDescriptor = tcpConnect(options);
  923.     if (socketDescriptor != 0)
  924.     {
  925.        
  926.         // Setup Context Object...
  927.         sslMethod = SSLv23_method();
  928.         options->ctx = SSL_CTX_new(sslMethod);
  929.         if (options->ctx != NULL)
  930.         {
  931.            
  932.             if (SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL") != 0)
  933.             {
  934.                
  935.                 // Load Certs if required...
  936.                 if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0))
  937.                     status = loadCerts(options);
  938.                
  939.                 if (status == true)
  940.                 {
  941.                     // Create SSL object...
  942.                     ssl = SSL_new(options->ctx);
  943.                     if (ssl != NULL)
  944.                     {
  945.                        
  946.                         // Connect socket and BIO
  947.                         cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE);
  948.                        
  949.                         // Connect SSL and BIO
  950.                         SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio);
  951.                        
  952.                         // Connect SSL over socket
  953.                         cipherStatus = SSL_connect(ssl);
  954.                         if (cipherStatus == 1)
  955.                         {
  956.                            
  957.                             // Setup BIO's
  958.                             stdoutBIO = BIO_new(BIO_s_file());
  959.                             BIO_set_fp(stdoutBIO, stdout, BIO_NOCLOSE);
  960.                             if (options->xmlOutput != 0)
  961.                             {
  962.                                 fileBIO = BIO_new(BIO_s_file());
  963.                                 BIO_set_fp(fileBIO, options->xmlOutput, BIO_NOCLOSE);
  964.                             }
  965.                            
  966.                             // Get Certificate...
  967.                             printf("\n  %sSSL Certificate:%s\n", COL_BLUE, RESET);
  968.                             if (options->xmlOutput != 0)
  969.                                 fprintf(options->xmlOutput, "  <certificate>\n");
  970.                             x509Cert = SSL_get_peer_certificate(ssl);
  971.                             if (x509Cert != NULL)
  972.                             {
  973.                                
  974.                                 //SSL_set_verify(ssl, SSL_VERIFY_NONE|SSL_VERIFY_CLIENT_ONCE, NULL);
  975.                                
  976.                                 // Cert Version
  977.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VERSION))
  978.                                 {
  979.                                     tempLong = X509_get_version(x509Cert) + 1;
  980.                                     printf("    Version: %lu\n", tempLong);
  981.                                     if (options->xmlOutput != 0)
  982.                                         fprintf(options->xmlOutput, "   <version>%lu</version>\n", tempLong);
  983.                                 }
  984.                                
  985.                                 // Cert Serial No.
  986.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SERIAL))
  987.                                 {
  988.                                     tempLong = ASN1_INTEGER_get(X509_get_serialNumber(x509Cert));
  989.                                     if (tempLong < 1)
  990.                                     {
  991.                                         printf("    Serial Number: -%lu\n", tempLong);
  992.                                         if (options->xmlOutput != 0)
  993.                                             fprintf(options->xmlOutput, "   <serial>-%lu</serial>\n", tempLong);
  994.                                     }
  995.                                     else
  996.                                     {
  997.                                         printf("    Serial Number: %lu\n", tempLong);
  998.                                         if (options->xmlOutput != 0)
  999.                                             fprintf(options->xmlOutput, "   <serial>%lu</serial>\n", tempLong);
  1000.                                     }
  1001.                                 }
  1002.                                
  1003.                                 // Signature Algo...
  1004.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SIGNAME))
  1005.                                 {
  1006.                                     printf("    Signature Algorithm: ");
  1007.                                     i2a_ASN1_OBJECT(stdoutBIO, x509Cert->cert_info->signature->algorithm);
  1008.                                     printf("\n");
  1009.                                     if (options->xmlOutput != 0)
  1010.                                     {
  1011.                                         fprintf(options->xmlOutput, "   <signature-algorithm>");
  1012.                                         i2a_ASN1_OBJECT(fileBIO, x509Cert->cert_info->signature->algorithm);
  1013.                                         fprintf(options->xmlOutput, "</signature-algorithm>\n");
  1014.                                     }
  1015.                                 }
  1016.                                
  1017.                                 // SSL Certificate Issuer...
  1018.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_ISSUER))
  1019.                                 {
  1020.                                     X509_NAME_oneline(X509_get_issuer_name(x509Cert), buffer, sizeof(buffer) - 1);
  1021.                                     printf("    Issuer: %s\n", buffer);
  1022.                                     if (options->xmlOutput != 0)
  1023.                                         fprintf(options->xmlOutput, "   <issuer>%s</issuer>\n", buffer);
  1024.                                 }
  1025.                                
  1026.                                 // Validity...
  1027.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VALIDITY))
  1028.                                 {
  1029.                                     printf("    Not valid before: ");
  1030.                                     ASN1_TIME_print(stdoutBIO, X509_get_notBefore(x509Cert));
  1031.                                     if (options->xmlOutput != 0)
  1032.                                     {
  1033.                                         fprintf(options->xmlOutput, "   <not-valid-before>");
  1034.                                         ASN1_TIME_print(fileBIO, X509_get_notBefore(x509Cert));
  1035.                                         fprintf(options->xmlOutput, "</not-valid-before>\n");
  1036.                                     }
  1037.                                     printf("\n    Not valid after: ");
  1038.                                     ASN1_TIME_print(stdoutBIO, X509_get_notAfter(x509Cert));
  1039.                                     printf("\n");
  1040.                                     if (options->xmlOutput != 0)
  1041.                                     {
  1042.                                         fprintf(options->xmlOutput, "   <not-valid-after>");
  1043.                                         ASN1_TIME_print(fileBIO, X509_get_notAfter(x509Cert));
  1044.                                         fprintf(options->xmlOutput, "</not-valid-after>\n");
  1045.                                     }
  1046.                                 }
  1047.                                
  1048.                                 // SSL Certificate Subject...
  1049.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SUBJECT))
  1050.                                 {
  1051.                                     X509_NAME_oneline(X509_get_subject_name(x509Cert), buffer, sizeof(buffer) - 1);
  1052.                                     printf("    Subject: %s\n", buffer);
  1053.                                     if (options->xmlOutput != 0)
  1054.                                         fprintf(options->xmlOutput, "   <subject>%s</subject>\n", buffer);
  1055.                                 }
  1056.                                
  1057.                                 // Public Key Algo...
  1058.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_PUBKEY))
  1059.                                 {
  1060.                                     printf("    Public Key Algorithm: ");
  1061.                                     i2a_ASN1_OBJECT(stdoutBIO, x509Cert->cert_info->key->algor->algorithm);
  1062.                                     printf("\n");
  1063.                                     if (options->xmlOutput != 0)
  1064.                                     {
  1065.                                         fprintf(options->xmlOutput, "   <pk-algorithm>");
  1066.                                         i2a_ASN1_OBJECT(fileBIO, x509Cert->cert_info->key->algor->algorithm);
  1067.                                         fprintf(options->xmlOutput, "</pk-algorithm>\n");
  1068.                                     }
  1069.                                    
  1070.                                     // Public Key...
  1071.                                     publicKey = X509_get_pubkey(x509Cert);
  1072.                                     if (publicKey == NULL)
  1073.                                     {
  1074.                                         printf("    Public Key: Could not load\n");
  1075.                                         if (options->xmlOutput != 0)
  1076.                                             fprintf(options->xmlOutput, "   <pk error=\"true\" />\n");
  1077.                                     }
  1078.                                     else
  1079.                                     {
  1080.                                         switch (publicKey->type)
  1081.                                         {
  1082.                                             case EVP_PKEY_RSA:
  1083.                                                 printf("    RSA Public Key: (%d bit)\n", BN_num_bits(publicKey->pkey.rsa->n));
  1084.                                                 if (options->xmlOutput != 0)
  1085.                                                     fprintf(options->xmlOutput, "   <pk error=\"false\" type=\"RSA\" bits=\"%d\">\n", BN_num_bits(publicKey->pkey.rsa->n));
  1086.                                                 RSA_print(stdoutBIO, publicKey->pkey.rsa, 6);
  1087.                                                 if (options->xmlOutput != 0)
  1088.                                                 {
  1089.                                                     RSA_print(fileBIO, publicKey->pkey.rsa, 4);
  1090.                                                     fprintf(options->xmlOutput, "   </pk>\n");
  1091.                                                 }
  1092.                                                 break;
  1093.                                             case EVP_PKEY_DSA:
  1094.                                                 printf("    DSA Public Key:\n");
  1095.                                                 if (options->xmlOutput != 0)
  1096.                                                     fprintf(options->xmlOutput, "   <pk error=\"false\" type=\"DSA\">\n");
  1097.                                                 DSA_print(stdoutBIO, publicKey->pkey.dsa, 6);
  1098.                                                 if (options->xmlOutput != 0)
  1099.                                                 {
  1100.                                                     DSA_print(fileBIO, publicKey->pkey.dsa, 4);
  1101.                                                     fprintf(options->xmlOutput, "   </pk>\n");
  1102.                                                 }
  1103.                                                 break;
  1104.                                             case EVP_PKEY_EC:
  1105.                                                 printf("    EC Public Key:\n");
  1106.                                                 if (options->xmlOutput != 0)
  1107.                                                     fprintf(options->xmlOutput, "   <pk error=\"false\" type=\"EC\">\n");
  1108.                                                 EC_KEY_print(stdoutBIO, publicKey->pkey.ec, 6);
  1109.                                                 if (options->xmlOutput != 0)
  1110.                                                 {
  1111.                                                     EC_KEY_print(fileBIO, publicKey->pkey.ec, 4);
  1112.                                                     fprintf(options->xmlOutput, "   </pk>\n");
  1113.                                                 }
  1114.                                                 break;
  1115.                                             default:
  1116.                                                 printf("    Public Key: Unknown\n");
  1117.                                                 if (options->xmlOutput != 0)
  1118.                                                     fprintf(options->xmlOutput, "   <pk error=\"true\" type=\"unknown\" />\n");
  1119.                                                 break;
  1120.                                         }
  1121.                                        
  1122.                                         EVP_PKEY_free(publicKey);
  1123.                                     }
  1124.                                 }
  1125.                                
  1126.                                 // X509 v3...
  1127.                                 if (!(X509_FLAG_COMPAT & X509_FLAG_NO_EXTENSIONS))
  1128.                                 {
  1129.                                     if (sk_X509_EXTENSION_num(x509Cert->cert_info->extensions) > 0)
  1130.                                     {
  1131.                                         printf("    X509v3 Extensions:\n");
  1132.                                         if (options->xmlOutput != 0)
  1133.                                             fprintf(options->xmlOutput, "   <X509v3-Extensions>\n");
  1134.                                         for (tempInt = 0; tempInt < sk_X509_EXTENSION_num(x509Cert->cert_info->extensions); tempInt++)
  1135.                                         {
  1136.                                             // Get Extension...
  1137.                                             extension = sk_X509_EXTENSION_value(x509Cert->cert_info->extensions, tempInt);
  1138.                                            
  1139.                                             // Print Extension name...
  1140.                                             printf("      ");
  1141.                                             asn1Object = X509_EXTENSION_get_object(extension);
  1142.                                             i2a_ASN1_OBJECT(stdoutBIO, asn1Object);
  1143.                                             tempInt2 = X509_EXTENSION_get_critical(extension);
  1144.                                             BIO_printf(stdoutBIO, ": %s\n", tempInt2 ? "critical" : "");
  1145.                                             if (options->xmlOutput != 0)
  1146.                                             {
  1147.                                                 fprintf(options->xmlOutput, "    <extension name=\"");
  1148.                                                 i2a_ASN1_OBJECT(fileBIO, asn1Object);
  1149.                                                 BIO_printf(fileBIO, "\"%s>", tempInt2 ? " level=\"critical\"" : "");
  1150.                                             }
  1151.                                            
  1152.                                             // Print Extension value...
  1153.                                             if (!X509V3_EXT_print(stdoutBIO, extension, X509_FLAG_COMPAT, 8))
  1154.                                             {
  1155.                                                 printf("        ");
  1156.                                                 M_ASN1_OCTET_STRING_print(stdoutBIO, extension->value);
  1157.                                             }
  1158.                                             if (options->xmlOutput != 0)
  1159.                                             {
  1160.                                                 if (!X509V3_EXT_print(fileBIO, extension, X509_FLAG_COMPAT, 0))
  1161.                                                     M_ASN1_OCTET_STRING_print(fileBIO, extension->value);
  1162.                                                 fprintf(options->xmlOutput, "</extension>\n");
  1163.                                             }
  1164.                                             printf("\n");
  1165.                                         }
  1166.                                         if (options->xmlOutput != 0)
  1167.                                             fprintf(options->xmlOutput, "   </X509v3-Extensions>\n");
  1168.                                     }
  1169.                                 }
  1170.                                
  1171.                                 // Verify Certificate...
  1172.                                 printf("  Verify Certificate:\n");
  1173.                                 verifyError = SSL_get_verify_result(ssl);
  1174.                                 if (verifyError == X509_V_OK)
  1175.                                     printf("    Certificate passed verification\n");
  1176.                                 else
  1177.                                     printf("    %s\n", X509_verify_cert_error_string(verifyError));
  1178.                                
  1179.                                 // Free X509 Certificate...
  1180.                                 X509_free(x509Cert);
  1181.                             }
  1182.                            
  1183.                             if (options->xmlOutput != 0)
  1184.                                 fprintf(options->xmlOutput, "  </certificate>\n");
  1185.                            
  1186.                             // Free BIO
  1187.                             BIO_free(stdoutBIO);
  1188.                             if (options->xmlOutput != 0)
  1189.                                 BIO_free(fileBIO);
  1190.                            
  1191.                             // Disconnect SSL over socket
  1192.                             SSL_shutdown(ssl);
  1193.                         }
  1194.                        
  1195.                         // Free SSL object
  1196.                         SSL_free(ssl);
  1197.                     }
  1198.                     else
  1199.                     {
  1200.                         status = false;
  1201.                         printf("%s    ERROR: Could create SSL object.%s\n", COL_RED, RESET);
  1202.                     }
  1203.                 }
  1204.             }
  1205.             else
  1206.             {
  1207.                 status = false;
  1208.                 printf("%s    ERROR: Could set cipher.%s\n", COL_RED, RESET);
  1209.             }
  1210.            
  1211.             // Free CTX Object
  1212.             SSL_CTX_free(options->ctx);
  1213.         }
  1214.        
  1215.         // Error Creating Context Object
  1216.         else
  1217.         {
  1218.             status = false;
  1219.             printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
  1220.         }
  1221.        
  1222.         // Disconnect from host
  1223.         close(socketDescriptor);
  1224.     }
  1225.    
  1226.     // Could not connect
  1227.     else
  1228.         status = false;
  1229.    
  1230.     return status;
  1231. }
  1232.  
  1233.  
  1234. // Test a single host and port for ciphers...
  1235. int testHost(struct sslCheckOptions *options)
  1236. {
  1237.     // Variables...
  1238.     struct sslCipher *sslCipherPointer;
  1239.     int status = true;
  1240.    
  1241.     // Resolve Host Name
  1242.     options->hostStruct = gethostbyname(options->host);
  1243.     if (options->hostStruct == NULL)
  1244.     {
  1245.         printf("%sERROR: Could not resolve hostname %s.%s\n", COL_RED, options->host, RESET);
  1246.         return false;
  1247.     }
  1248.    
  1249.     // Configure Server Address and Port
  1250.     options->serverAddress.sin_family = options->hostStruct->h_addrtype;
  1251.     memcpy((char *) &options->serverAddress.sin_addr.s_addr, options->hostStruct->h_addr_list[0], options->hostStruct->h_length);
  1252.     options->serverAddress.sin_port = htons(options->port);
  1253.    
  1254.     // XML Output...
  1255.     if (options->xmlOutput != 0)
  1256.         fprintf(options->xmlOutput, " <ssltest host=\"%s\" port=\"%d\">\n", options->host, options->port);
  1257.    
  1258.     // Test supported ciphers...
  1259.     printf("\n%sTesting SSL server %s on port %d%s\n\n", COL_GREEN, options->host, options->port, RESET);
  1260.     printf("  %sSupported Server Cipher(s):%s\n", COL_BLUE, RESET);
  1261.     if ((options->http == true) && (options->pout == true))
  1262.         printf("|| Status || HTTP Code || Version || Bits || Cipher ||\n");
  1263.     else if (options->pout == true)
  1264.         printf("|| Status || Version || Bits || Cipher ||\n");
  1265.     sslCipherPointer = options->ciphers;
  1266.     while ((sslCipherPointer != 0) && (status == true))
  1267.     {
  1268.        
  1269.         // Setup Context Object...
  1270.         options->ctx = SSL_CTX_new(sslCipherPointer->sslMethod);
  1271.         if (options->ctx != NULL)
  1272.         {
  1273.            
  1274.             // SSL implementation bugs/workaround
  1275.             if (options->sslbugs)
  1276.                 SSL_CTX_set_options(options->ctx, SSL_OP_ALL | 0);
  1277.             else
  1278.                 SSL_CTX_set_options(options->ctx, 0);
  1279.            
  1280.             // Load Certs if required...
  1281.             if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0))
  1282.                 status = loadCerts(options);
  1283.            
  1284.             // Test
  1285.             if (status == true)
  1286.                 status = testCipher(options, sslCipherPointer);
  1287.            
  1288.             // Free CTX Object
  1289.             SSL_CTX_free(options->ctx);
  1290.         }
  1291.        
  1292.         // Error Creating Context Object
  1293.         else
  1294.         {
  1295.             status = false;
  1296.             printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
  1297.         }
  1298.        
  1299.         sslCipherPointer = sslCipherPointer->next;
  1300.     }
  1301.    
  1302.     if (status == true)
  1303.     {
  1304.         // Test prefered ciphers...
  1305.         printf("\n  %sPrefered Server Cipher(s):%s\n", COL_BLUE, RESET);
  1306.         if (options->pout == true)
  1307.             printf("|| Version || Bits || Cipher ||\n");
  1308.         switch (options->sslVersion)
  1309.         {
  1310.             case ssl_all:
  1311. #ifndef SSLSCAN_NO_SSL2
  1312.                 status = defaultCipher(options, SSLv2_client_method());
  1313.                 if (status != false)
  1314. #endif
  1315.                     status = defaultCipher(options, SSLv3_client_method());
  1316.                 if (status != false)
  1317.                     status = defaultCipher(options, TLSv1_client_method());
  1318.                
  1319. #ifndef SSLSCAN_NO_TLS1_1
  1320.                 if (status != false)
  1321.                     status = defaultCipher(options, TLSv1_1_client_method());
  1322. #endif
  1323.                
  1324. #ifndef SSLSCAN_NO_TLS1_2
  1325.                 if (status != false)
  1326.                     status = defaultCipher(options, TLSv1_2_client_method());
  1327. #endif
  1328.                
  1329.                 break;
  1330. #ifndef SSLSCAN_NO_SSL2
  1331.             case ssl_v2:
  1332.                 status = defaultCipher(options, SSLv2_client_method());
  1333.                 break;
  1334. #endif
  1335.             case ssl_v3:
  1336.                 status = defaultCipher(options, SSLv3_client_method());
  1337.                 break;
  1338.             case tls_v1:
  1339.                 status = defaultCipher(options, TLSv1_client_method());
  1340.                 break;
  1341.                
  1342. #ifndef SSLSCAN_NO_TLS1_1
  1343.             case tls_v1_1:
  1344.                 status = defaultCipher(options, TLSv1_1_client_method());
  1345.                 break;
  1346. #endif
  1347.                
  1348. #ifndef SSLSCAN_NO_TLS1_2
  1349.             case tls_v1_2:
  1350.                 status = defaultCipher(options, TLSv1_2_client_method());
  1351.                 break;
  1352. #endif
  1353.         }
  1354.     }
  1355.    
  1356.     if (status == true)
  1357.     {
  1358.         status = getCertificate(options);
  1359.     }
  1360.    
  1361.     // XML Output...
  1362.     if (options->xmlOutput != 0)
  1363.         fprintf(options->xmlOutput, " </ssltest>\n");
  1364.    
  1365.     // Return status...
  1366.     return status;
  1367. }
  1368.  
  1369.  
  1370. int main(int argc, char *argv[])
  1371. {
  1372.     // Variables...
  1373.     struct sslCheckOptions options;
  1374.     struct sslCipher *sslCipherPointer;
  1375.     int status;
  1376.     int argLoop;
  1377.     int tempInt;
  1378.     int maxSize;
  1379.     int xmlArg;
  1380.     int mode = mode_help;
  1381.     FILE *targetsFile;
  1382.     char line[1024];
  1383.    
  1384.     // Init...
  1385.     memset(&options, 0x00, sizeof(struct sslCheckOptions));
  1386.     options.port = 443;
  1387.     xmlArg = 0;
  1388.     strcpy(options.host, "127.0.0.1");
  1389.     options.noFailed = false;
  1390.     options.starttls = false;
  1391.     options.sslVersion = ssl_all;
  1392.     options.pout = false;
  1393.    
  1394.     unsigned long v1 = OPENSSL_VERSION_NUMBER;
  1395.     unsigned long v2 = SSLeay();
  1396.    
  1397.     if((v1 & 0xFFFF0000) != (v2 & 0xFFFF0000))
  1398.     {
  1399.         fprintf(stderr, "SSLscan was compiled with OpenSSL version 0x%lx, but linked against 0x%lx", OPENSSL_VERSION_NUMBER, SSLeay());
  1400.         exit (1);
  1401.     }
  1402.    
  1403.     OpenSSL_add_ssl_algorithms();
  1404.     SSL_load_error_strings();
  1405.    
  1406.     // Get program parameters
  1407.     for (argLoop = 1; argLoop < argc; argLoop++)
  1408.     {
  1409.         // Help
  1410.         if (strcmp("--help", argv[argLoop]) == 0)
  1411.             mode = mode_help;
  1412.        
  1413.         // targets
  1414.         else if ((strncmp("--targets=", argv[argLoop], 10) == 0) && (strlen(argv[argLoop]) > 10))
  1415.         {
  1416.             mode = mode_multiple;
  1417.             options.targets = argLoop;
  1418.         }
  1419.        
  1420.         // Show only supported
  1421.         else if (strcmp("--no-failed", argv[argLoop]) == 0)
  1422.             options.noFailed = true;
  1423.        
  1424.         // Version
  1425.         else if (strcmp("--version", argv[argLoop]) == 0)
  1426.             mode = mode_version;
  1427.        
  1428.         // XML Output
  1429.         else if (strncmp("--xml=", argv[argLoop], 6) == 0)
  1430.             xmlArg = argLoop;
  1431.        
  1432.         // P Output
  1433.         else if (strcmp("-p", argv[argLoop]) == 0)
  1434.             options.pout = true;
  1435.        
  1436.         // Client Certificates
  1437.         else if (strncmp("--certs=", argv[argLoop], 8) == 0)
  1438.             options.clientCertsFile = argv[argLoop] +8;
  1439.        
  1440.         // Private Key File
  1441.         else if (strncmp("--pk=", argv[argLoop], 5) == 0)
  1442.             options.privateKeyFile = argv[argLoop] +5;
  1443.        
  1444.         // Private Key Password
  1445.         else if (strncmp("--pkpass=", argv[argLoop], 9) == 0)
  1446.             options.privateKeyPassword = argv[argLoop] +9;
  1447.        
  1448.         // StartTLS...
  1449.         else if (strcmp("--starttls", argv[argLoop]) == 0)
  1450.         {
  1451.             options.sslVersion = tls_v1;
  1452.             options.starttls = true;
  1453.         }
  1454.        
  1455.         // SSL v2 only...
  1456.         else if (strcmp("--ssl2", argv[argLoop]) == 0)
  1457.             options.sslVersion = ssl_v2;
  1458.        
  1459.         // SSL v3 only...
  1460.         else if (strcmp("--ssl3", argv[argLoop]) == 0)
  1461.             options.sslVersion = ssl_v3;
  1462.        
  1463.         // TLS v1 only...
  1464.         else if (strcmp("--tls1", argv[argLoop]) == 0)
  1465.             options.sslVersion = tls_v1;
  1466.        
  1467.         else if (strcmp("--tls1_0", argv[argLoop]) == 0)
  1468.             options.sslVersion = tls_v1;
  1469.        
  1470.         else if (strcmp("--tls1.0", argv[argLoop]) == 0)
  1471.             options.sslVersion = tls_v1;
  1472.        
  1473.         // TLS v1.1 only...
  1474.         else if (strcmp("--tls1_1", argv[argLoop]) == 0)
  1475.             options.sslVersion = tls_v1_1;
  1476.        
  1477.         else if (strcmp("--tls1.1", argv[argLoop]) == 0)
  1478.             options.sslVersion = tls_v1_1;
  1479.        
  1480.         // TLS v1.2 only...
  1481.         else if (strcmp("--tls1_2", argv[argLoop]) == 0)
  1482.             options.sslVersion = tls_v1_2;
  1483.        
  1484.         else if (strcmp("--tls1.2", argv[argLoop]) == 0)
  1485.             options.sslVersion = tls_v1_2;
  1486.        
  1487.         else if (strcmp("--no-sni", argv[argLoop]) == 0)
  1488.             options.noSNI = 1;
  1489.        
  1490.         // SSL Bugs...
  1491.         else if (strcmp("--bugs", argv[argLoop]) == 0)
  1492.             options.sslbugs = 1;
  1493.        
  1494.         // SSL HTTP Get...
  1495.         else if (strcmp("--http", argv[argLoop]) == 0)
  1496.             options.http = 1;
  1497.        
  1498.         // Host (maybe port too)...
  1499.         else if (argLoop + 1 == argc)
  1500.         {
  1501.             mode = mode_single;
  1502.            
  1503.             // Get host...
  1504.             tempInt = 0;
  1505.             maxSize = strlen(argv[argLoop]);
  1506.             while ((argv[argLoop][tempInt] != 0) && (argv[argLoop][tempInt] != ':'))
  1507.                 tempInt++;
  1508.             argv[argLoop][tempInt] = 0;
  1509.             strncpy(options.host, argv[argLoop], sizeof(options.host) -1);
  1510.            
  1511.             // Get port (if it exists)...
  1512.             tempInt++;
  1513.             if (tempInt < maxSize)
  1514.                 options.port = atoi(argv[argLoop] + tempInt);
  1515.         }
  1516.        
  1517.         // Not too sure what the user is doing...
  1518.         else
  1519.             mode = mode_help;
  1520.     }
  1521.    
  1522.     // Open XML file output...
  1523.     if ((xmlArg > 0) && (mode != mode_help))
  1524.     {
  1525.         options.xmlOutput = fopen(argv[xmlArg] + 6, "w");
  1526.         if (options.xmlOutput == NULL)
  1527.         {
  1528.             printf("%sERROR: Could not open XML output file %s.%s\n", COL_RED, argv[xmlArg] + 6, RESET);
  1529.             exit(0);
  1530.         }
  1531.        
  1532.         // Output file header...
  1533.         fprintf(options.xmlOutput, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document title=\"SSLScan Results\" version=\"%s\" web=\"http://www.titania.co.uk\">\n", xml_version);
  1534.     }
  1535.    
  1536.     switch (mode)
  1537.     {
  1538.         case mode_version:
  1539.             printf("%s%s%s", COL_BLUE, program_version, RESET);
  1540.             printf("%s%s (0x%lx) %s\n", COL_BLUE, SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER, RESET);
  1541.             printf("%s%s%s\n", COL_BLUE, availableProtocols(), RESET);
  1542.            
  1543.             break;
  1544.            
  1545.         case mode_help:
  1546.             // Program version banner...
  1547.             printf("%s%s%s\n", COL_BLUE, program_banner, RESET);
  1548.             printf("SSLScan is a fast SSL port scanner. SSLScan connects to SSL\n");
  1549.             printf("ports and determines what  ciphers are supported, which are\n");
  1550.             printf("the servers  prefered  ciphers,  which  SSL  protocols  are\n");
  1551.             printf("supported  and   returns  the   SSL   certificate.   Client\n");
  1552.             printf("certificates /  private key can be configured and output is\n");
  1553.             printf("to text / XML.\n\n");
  1554.             printf("%sCommand:%s\n", COL_BLUE, RESET);
  1555.             printf("  %s%s [Options] [host:port | host]%s\n\n", COL_GREEN, argv[0], RESET);
  1556.             printf("%sOptions:%s\n", COL_BLUE, RESET);
  1557.             printf("  %s--targets=<file>%s     A file containing a list of hosts to\n", COL_GREEN, RESET);
  1558.             printf("                       check.  Hosts can  be supplied  with\n");
  1559.             printf("                       ports (i.e. host:port).\n");
  1560.             printf("  %s--no-failed%s          List only accepted ciphers  (default\n", COL_GREEN, RESET);
  1561.             printf("                       is to listing all ciphers).\n");
  1562.             printf("  %s--ssl2%s               Only check SSLv2 ciphers.\n", COL_GREEN, RESET);
  1563.             printf("  %s--ssl3%s               Only check SSLv3 ciphers.\n", COL_GREEN, RESET);
  1564.             printf("  %s--tls1%s               Only check TLSv1 ciphers.\n", COL_GREEN, RESET);
  1565.             printf("  %s--tls1_1%s             Only check TLSv1.1 ciphers.\n", COL_GREEN, RESET);
  1566.             printf("  %s--tls1_2%s             Only check TLSv1.2 ciphers.\n", COL_GREEN, RESET);
  1567.             printf("  %s--no-sni%s             Disable SNI for TLS1 and above.\n", COL_GREEN, RESET);
  1568.             printf("  %s--pk=<file>%s          A file containing the private key or\n", COL_GREEN, RESET);
  1569.             printf("                       a PKCS#12  file containing a private\n");
  1570.             printf("                       key/certificate pair (as produced by\n");
  1571.             printf("                       MSIE and Netscape).\n");
  1572.             printf("  %s--pkpass=<password>%s  The password for the private  key or\n", COL_GREEN, RESET);
  1573.             printf("                       PKCS#12 file.\n");
  1574.             printf("  %s--certs=<file>%s       A file containing PEM/ASN1 formatted\n", COL_GREEN, RESET);
  1575.             printf("                       client certificates.\n");
  1576.             printf("  %s--starttls%s           If a STARTTLS is required to kick an\n", COL_GREEN, RESET);
  1577.             printf("                       SMTP service into action.\n");
  1578.             printf("  %s--http%s               Test a HTTP connection.\n", COL_GREEN, RESET);
  1579.             printf("  %s--bugs%s               Enable SSL implementation  bug work-\n", COL_GREEN, RESET);
  1580.             printf("                       arounds.\n");
  1581.             printf("  %s--xml=<file>%s         Output results to an XML file.\n", COL_GREEN, RESET);
  1582.             printf("  %s--version%s            Display the program version.\n", COL_GREEN, RESET);
  1583.             printf("  %s--help%s               Display the  help text  you are  now\n", COL_GREEN, RESET);
  1584.             printf("                       reading.\n");
  1585.             printf("%sExample:%s\n", COL_BLUE, RESET);
  1586.             printf("  %s%s 127.0.0.1%s\n\n", COL_GREEN, argv[0], RESET);
  1587.             break;
  1588.            
  1589.             // Check a single host/port ciphers...
  1590.         case mode_single:
  1591.         case mode_multiple:
  1592.             printf("%s%s%s", COL_BLUE, program_banner, RESET);
  1593.            
  1594.             SSLeay_add_all_algorithms();
  1595.             ERR_load_crypto_strings();
  1596.            
  1597.             // Build a list of ciphers...
  1598.             switch (options.sslVersion)
  1599.         {
  1600.             case ssl_all:
  1601. #ifndef SSLSCAN_NO_SSL2
  1602.                 populateCipherList(&options, SSLv2_client_method());
  1603. #endif
  1604.                 populateCipherList(&options, SSLv3_client_method());
  1605.                 populateCipherList(&options, TLSv1_client_method());
  1606.                
  1607. #ifndef SSLSCAN_NO_TLS1_1
  1608.                 populateCipherList(&options, TLSv1_1_client_method());
  1609. #endif
  1610.                
  1611. #ifndef SSLSCAN_NO_TLS1_2
  1612.                 populateCipherList(&options, TLSv1_2_client_method());
  1613. #endif
  1614.                
  1615.                 break;
  1616. #ifndef SSLSCAN_NO_SSL2
  1617.             case ssl_v2:
  1618.                 populateCipherList(&options, SSLv2_client_method());
  1619.                 break;
  1620. #endif
  1621.             case ssl_v3:
  1622.                 populateCipherList(&options, SSLv3_client_method());
  1623.                 break;
  1624.             case tls_v1:
  1625.                 populateCipherList(&options, TLSv1_client_method());
  1626.                
  1627. #ifndef SSLSCAN_NO_TLS1_1
  1628.             case tls_v1_1:
  1629.                 populateCipherList(&options, TLSv1_1_client_method());
  1630. #endif
  1631.                
  1632. #ifndef SSLSCAN_NO_TLS1_2
  1633.             case tls_v1_2:
  1634.                 populateCipherList(&options, TLSv1_2_client_method());
  1635.                 break;
  1636. #endif
  1637.         }
  1638.            
  1639.             // Do the testing...
  1640.             if (mode == mode_single)
  1641.                 status = testHost(&options);
  1642.             else
  1643.             {
  1644.                 if (fileExists(argv[options.targets] + 10) == true)
  1645.                 {
  1646.                     // Open targets file...
  1647.                     targetsFile = fopen(argv[options.targets] + 10, "r");
  1648.                     if (targetsFile == NULL)
  1649.                         printf("%sERROR: Could not open targets file %s.%s\n", COL_RED, argv[options.targets] + 10, RESET);
  1650.                     else
  1651.                     {
  1652.                         readLine(targetsFile, line, sizeof(line));
  1653.                         while (feof(targetsFile) == 0)
  1654.                         {
  1655.                             if (strlen(line) != 0)
  1656.                             {
  1657.                                 // Get host...
  1658.                                 tempInt = 0;
  1659.                                 while ((line[tempInt] != 0) && (line[tempInt] != ':'))
  1660.                                     tempInt++;
  1661.                                 line[tempInt] = 0;
  1662.                                 strncpy(options.host, line, sizeof(options.host) -1);
  1663.                                
  1664.                                 // Get port (if it exists)...
  1665.                                 tempInt++;
  1666.                                 if (strlen(line + tempInt) > 0)
  1667.                                     options.port = atoi(line + tempInt);
  1668.                                
  1669.                                 // Test the host...
  1670.                                 status = testHost(&options);
  1671.                             }
  1672.                             readLine(targetsFile, line, sizeof(line));
  1673.                         }
  1674.                     }
  1675.                 }
  1676.                 else
  1677.                     printf("%sERROR: Targets file %s does not exist.%s\n", COL_RED, argv[options.targets] + 10, RESET);
  1678.             }
  1679.            
  1680.             // Free Structures
  1681.             while (options.ciphers != 0)
  1682.             {
  1683.                 sslCipherPointer = options.ciphers->next;
  1684.                 free(options.ciphers);
  1685.                 options.ciphers = sslCipherPointer;
  1686.             }
  1687.             break;
  1688.     }
  1689.    
  1690.     // Close XML file, if required...
  1691.     if ((xmlArg > 0) && (mode != mode_help))
  1692.     {
  1693.         fprintf(options.xmlOutput, "</document>\n");
  1694.         fclose(options.xmlOutput);
  1695.     }
  1696.    
  1697.     return 0;
  1698. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement