Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***************************************************************************
- * sslscan - A SSL cipher scanning tool *
- * Copyright 2007-2009 by Ian Ventura-Whiting (Fizz) *
- * fizz@titania.co.uk *
- * *
- * Modified by Jeffrey Walton in 2013 to support TLS 1.1 and TLS 1.2 *
- * noloader@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- * *
- * In addition, as a special exception, the copyright holders give *
- * permission to link the code of portions of this program with the *
- * OpenSSL library under certain conditions as described in each *
- * individual source file, and distribute linked combinations *
- * including the two. *
- * You must obey the GNU General Public License in all respects *
- * for all of the code used other than OpenSSL. If you modify *
- * file(s) with this exception, you may extend this exception to your *
- * version of the file(s), but you are not obligated to do so. If you *
- * do not wish to do so, delete this exception statement from your *
- * version. If you delete this exception statement from all source *
- * files in the program, then also delete it here. *
- ***************************************************************************/
- // Includes...
- #include <string.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <openssl/err.h>
- #include <openssl/ssl.h>
- #include <openssl/pkcs12.h>
- #include <openssl/x509.h>
- #include <openssl/x509v3.h>
- #include <openssl/opensslconf.h>
- // Defines...
- #define false 0
- #define true 1
- #define mode_help 0
- #define mode_version 1
- #define mode_single 2
- #define mode_multiple 3
- #define BUFFERSIZE 1024
- #define ssl_all 0
- #define ssl_v2 1
- #define ssl_v3 2
- #define tls_v1 3
- #define tls_v1_1 4
- #define tls_v1_2 5
- // Colour Console Output...
- #if !defined(__WIN32__)
- const char *RESET = "[0m"; // DEFAULT
- const char *COL_RED = "[31m"; // RED
- const char *COL_BLUE = "[34m"; // BLUE
- const char *COL_GREEN = "[32m"; // GREEN
- #else
- const char *RESET = "";
- const char *COL_RED = "";
- const char *COL_BLUE = "";
- const char *COL_GREEN = "";
- #endif
- const char *program_banner = " _\n"
- " ___ ___| |___ ___ __ _ _ __\n"
- " / __/ __| / __|/ __/ _` | '_ \\\n"
- " \\__ \\__ \\ \\__ \\ (_| (_| | | | |\n"
- " |___/___/_|___/\\___\\__,_|_| |_|\n\n"
- " Version 1.8.2\n"
- " http://www.titania.co.uk\n"
- " Copyright Ian Ventura-Whiting 2009\n"
- " Modified Jeffrey Walton 2013\n";
- const char *program_version = "sslscan version 1.8.2\nhttp://www.titania.co.uk\nCopyright (C) Ian Ventura-Whiting 2009\n";
- const char *xml_version = "1.8.2";
- struct sslCipher
- {
- // Cipher Properties...
- const char *name;
- char *version;
- int bits;
- char description[512];
- const SSL_METHOD *sslMethod;
- struct sslCipher *next;
- };
- struct sslCheckOptions
- {
- // Program Options...
- char host[512];
- int port;
- int noFailed;
- int noSNI;
- int starttls;
- int sslVersion;
- int targets;
- int pout;
- int sslbugs;
- int http;
- // File Handles...
- FILE *xmlOutput;
- // TCP Connection Variables...
- struct hostent *hostStruct;
- struct sockaddr_in serverAddress;
- // SSL Variables...
- SSL_CTX *ctx;
- struct sslCipher *ciphers;
- char *clientCertsFile;
- char *privateKeyFile;
- char *privateKeyPassword;
- };
- /* Per the CHANGELOG, TLS 1.1 and TLS 1.2 are available in 1.0.1 and above */
- #if !(OPENSSL_VERSION_NUMBER >= 0x10001000L)
- # define SSLSCAN_NO_TLS1_1
- # define SSLSCAN_NO_TLS1_2
- #endif
- /* OpenSSL was config'd with 'no-ssl2' */
- #ifdef OPENSSL_NO_SSL2
- # define SSLSCAN_NO_SSL2
- #endif
- static const char* availableProtocols()
- {
- static char buffer[128] = {};
- buffer[0] = '\0';
- strcat(buffer, "Protocols: ");
- #ifndef SSLSCAN_NO_SSL2
- strcat(buffer, "SSLv2 ");
- #endif
- #ifndef SSLSCAN_NO_SSL3
- strcat(buffer, "SSLv3 ");
- #endif
- #ifndef SSLSCAN_NO_TLS1_0
- strcat(buffer, "TLSv1.0 ");
- #endif
- #ifndef SSLSCAN_NO_TLS1_1
- strcat(buffer, "TLSv1.1 ");
- #endif
- #ifndef SSLSCAN_NO_TLS1_2
- strcat(buffer, "TLSv1.2 ");
- #endif
- return buffer;
- }
- // Adds Ciphers to the Cipher List structure
- int populateCipherList(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
- {
- // Variables...
- int returnCode = true;
- struct sslCipher *sslCipherPointer;
- int tempInt;
- int loop;
- STACK_OF(SSL_CIPHER) *cipherList;
- SSL *ssl = NULL;
- // Setup Context Object...
- options->ctx = SSL_CTX_new(sslMethod);
- if (options->ctx != NULL)
- {
- SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL");
- // Create new SSL object
- ssl = SSL_new(options->ctx);
- if (ssl != NULL)
- {
- // Get List of Ciphers
- cipherList = SSL_get_ciphers(ssl);
- // Create Cipher Struct Entries...
- for (loop = 0; loop < sk_SSL_CIPHER_num(cipherList); loop++)
- {
- // Create Structure...
- if (options->ciphers == 0)
- {
- options->ciphers = malloc(sizeof(struct sslCipher));
- sslCipherPointer = options->ciphers;
- }
- else
- {
- sslCipherPointer = options->ciphers;
- while (sslCipherPointer->next != 0)
- sslCipherPointer = sslCipherPointer->next;
- sslCipherPointer->next = malloc(sizeof(struct sslCipher));
- sslCipherPointer = sslCipherPointer->next;
- }
- // Init
- memset(sslCipherPointer, 0, sizeof(struct sslCipher));
- // Add cipher information...
- sslCipherPointer->sslMethod = sslMethod;
- sslCipherPointer->name = SSL_CIPHER_get_name(sk_SSL_CIPHER_value(cipherList, loop));
- sslCipherPointer->version = SSL_CIPHER_get_version(sk_SSL_CIPHER_value(cipherList, loop));
- SSL_CIPHER_description(sk_SSL_CIPHER_value(cipherList, loop), sslCipherPointer->description, sizeof(sslCipherPointer->description) - 1);
- sslCipherPointer->bits = SSL_CIPHER_get_bits(sk_SSL_CIPHER_value(cipherList, loop), &tempInt);
- }
- // Free SSL object
- SSL_free(ssl);
- }
- else
- {
- returnCode = false;
- printf("%sERROR: Could not create SSL object.%s\n", COL_RED, RESET);
- }
- // Free CTX Object
- SSL_CTX_free(options->ctx);
- }
- // Error Creating Context Object
- else
- {
- returnCode = false;
- printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
- }
- return returnCode;
- }
- // File Exists
- int fileExists(char *fileName)
- {
- // Variables...
- struct stat fileStats;
- if (stat(fileName, &fileStats) == 0)
- return true;
- else
- return false;
- }
- // Read a line from the input...
- void readLine(FILE *input, char *lineFromFile, int maxSize)
- {
- // Variables...
- int stripPointer;
- // Read line from file...
- fgets(lineFromFile, maxSize, input);
- // Clear the end-of-line stuff...
- stripPointer = strlen(lineFromFile) -1;
- while ((lineFromFile[stripPointer] == '\r') || (lineFromFile[stripPointer] == '\n') || (lineFromFile[stripPointer] == ' '))
- {
- lineFromFile[stripPointer] = 0;
- stripPointer--;
- }
- }
- // Create a TCP socket
- int tcpConnect(struct sslCheckOptions *options)
- {
- // Variables...
- int socketDescriptor;
- char buffer[BUFFERSIZE];
- struct sockaddr_in localAddress;
- int status;
- // Create Socket
- socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
- if(socketDescriptor < 0)
- {
- printf("%s ERROR: Could not open a socket.%s\n", COL_RED, RESET);
- return 0;
- }
- // Configure Local Port
- localAddress.sin_family = AF_INET;
- localAddress.sin_addr.s_addr = htonl(INADDR_ANY);
- localAddress.sin_port = htons(0);
- status = bind(socketDescriptor, (struct sockaddr *) &localAddress, sizeof(localAddress));
- if(status < 0)
- {
- printf("%s ERROR: Could not bind to port.%s\n", COL_RED, RESET);
- return 0;
- }
- // Connect
- status = connect(socketDescriptor, (struct sockaddr *) &options->serverAddress, sizeof(options->serverAddress));
- if(status < 0)
- {
- printf("%s ERROR: Could not open a connection to host %s on port %d.%s\n", COL_RED, options->host, options->port, RESET);
- return 0;
- }
- // If STARTTLS is required...
- if (options->starttls == true)
- {
- memset(buffer, 0, BUFFERSIZE);
- recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0);
- if (strncmp(buffer, "220", 3) != 0)
- {
- close(socketDescriptor);
- 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);
- return 0;
- }
- send(socketDescriptor, "EHLO titania.co.uk\r\n", 20, 0);
- memset(buffer, 0, BUFFERSIZE);
- recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0);
- if (strncmp(buffer, "250", 3) != 0)
- {
- close(socketDescriptor);
- 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);
- return 0;
- }
- send(socketDescriptor, "STARTTLS\r\n", 10, 0);
- memset(buffer, 0, BUFFERSIZE);
- recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0);
- if (strncmp(buffer, "220", 3) != 0)
- {
- close(socketDescriptor);
- 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);
- return 0;
- }
- }
- // Return
- return socketDescriptor;
- }
- // Private Key Password Callback...
- static int password_callback(char *buf, int size, int rwflag, void *userdata)
- {
- strncpy(buf, (char *)userdata, size);
- buf[strlen(userdata)] = 0;
- return strlen(userdata);
- }
- // Load client certificates/private keys...
- int loadCerts(struct sslCheckOptions *options)
- {
- // Variables...
- int status = 1;
- PKCS12 *pk12 = NULL;
- FILE *pk12File = NULL;
- X509 *cert = NULL;
- EVP_PKEY *pkey = NULL;
- STACK_OF(X509) *ca = NULL;
- // Configure PKey password...
- if (options->privateKeyPassword != 0)
- {
- SSL_CTX_set_default_passwd_cb_userdata(options->ctx, (void *)options->privateKeyPassword);
- SSL_CTX_set_default_passwd_cb(options->ctx, password_callback);
- }
- // Seperate Certs and PKey Files...
- if ((options->clientCertsFile != 0) && (options->privateKeyFile != 0))
- {
- // Load Cert...
- if (!SSL_CTX_use_certificate_file(options->ctx, options->clientCertsFile, SSL_FILETYPE_PEM))
- {
- if (!SSL_CTX_use_certificate_file(options->ctx, options->clientCertsFile, SSL_FILETYPE_ASN1))
- {
- if (!SSL_CTX_use_certificate_chain_file(options->ctx, options->clientCertsFile))
- {
- printf("%s Could not configure certificate(s).%s\n", COL_RED, RESET);
- status = 0;
- }
- }
- }
- // Load PKey...
- if (status != 0)
- {
- if (!SSL_CTX_use_PrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_PEM))
- {
- if (!SSL_CTX_use_PrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_ASN1))
- {
- if (!SSL_CTX_use_RSAPrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_PEM))
- {
- if (!SSL_CTX_use_RSAPrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_ASN1))
- {
- printf("%s Could not configure private key.%s\n", COL_RED, RESET);
- status = 0;
- }
- }
- }
- }
- }
- }
- // PKCS Cert and PKey File...
- else if (options->privateKeyFile != 0)
- {
- pk12File = fopen(options->privateKeyFile, "rb");
- if (pk12File != NULL)
- {
- pk12 = d2i_PKCS12_fp(pk12File, NULL);
- if (!pk12)
- {
- status = 0;
- printf("%s Could not read PKCS#12 file.%s\n", COL_RED, RESET);
- }
- else
- {
- if (!PKCS12_parse(pk12, options->privateKeyPassword, &pkey, &cert, &ca))
- {
- status = 0;
- printf("%s Error parsing PKCS#12. Are you sure that password was correct?%s\n", COL_RED, RESET);
- }
- else
- {
- if (!SSL_CTX_use_certificate(options->ctx, cert))
- {
- status = 0;
- printf("%s Could not configure certificate.%s\n", COL_RED, RESET);
- }
- if (!SSL_CTX_use_PrivateKey(options->ctx, pkey))
- {
- status = 0;
- printf("%s Could not configure private key.%s\n", COL_RED, RESET);
- }
- }
- PKCS12_free(pk12);
- }
- fclose(pk12File);
- }
- else
- {
- printf("%s Could not open PKCS#12 file.%s\n", COL_RED, RESET);
- status = 0;
- }
- }
- // Check Cert/Key...
- if (status != 0)
- {
- if (!SSL_CTX_check_private_key(options->ctx))
- {
- printf("%s Prvate key does not match certificate.%s\n", COL_RED, RESET);
- return false;
- }
- else
- return true;
- }
- else
- return false;
- }
- // Test a cipher...
- int testCipher(struct sslCheckOptions *options, struct sslCipher *sslCipherPointer)
- {
- // Variables...
- int cipherStatus;
- int status = true;
- int socketDescriptor = 0;
- SSL *ssl = NULL;
- BIO *cipherConnectionBio;
- BIO *stdoutBIO = NULL;
- int tempInt;
- char requestBuffer[200];
- char buffer[50];
- int resultSize = 0;
- // Create request buffer...
- memset(requestBuffer, 0, 200);
- snprintf(requestBuffer, 199, "GET / HTTP/1.0\r\nUser-Agent: SSLScan\r\nHost: %s\r\n\r\n", options->host);
- // Connect to host
- socketDescriptor = tcpConnect(options);
- if (socketDescriptor != 0)
- {
- if (SSL_CTX_set_cipher_list(options->ctx, sslCipherPointer->name) != 0)
- {
- // Create SSL object...
- ssl = SSL_new(options->ctx);
- if (ssl != NULL)
- {
- #if (OPENSSL_VERSION_NUMBER >= 0x00908060L /*0.9.8f*/)
- // Added at 0.9.8f, see CHANGELOG
- if(! options->noSNI)
- SSL_set_tlsext_host_name(ssl, options->host);
- #endif
- // Connect socket and BIO
- cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE);
- // Connect SSL and BIO
- SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio);
- // Connect SSL over socket
- cipherStatus = SSL_connect(ssl);
- // Show Cipher Status
- if (!((options->noFailed == true) && (cipherStatus != 1)))
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <cipher status=\"");
- if (cipherStatus == 1)
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "accepted\"");
- if (options->pout == true)
- printf("|| Accepted || ");
- else
- printf(" Accepted ");
- if (options->http == true)
- {
- // Stdout BIO...
- stdoutBIO = BIO_new(BIO_s_file());
- BIO_set_fp(stdoutBIO, stdout, BIO_NOCLOSE);
- // HTTP Get...
- SSL_write(ssl, requestBuffer, sizeof(requestBuffer));
- memset(buffer ,0 , 50);
- resultSize = SSL_read(ssl, buffer, 49);
- if (resultSize > 9)
- {
- int loop = 0;
- for (loop = 9; (loop < 49) && (buffer[loop] != 0) && (buffer[loop] != '\r') && (buffer[loop] != '\n'); loop++)
- { }
- buffer[loop] = 0;
- // Output HTTP code...
- if (options->pout == true)
- printf("%s || ", buffer + 9);
- else
- {
- printf("%s", buffer + 9);
- loop = strlen(buffer + 9);
- while (loop < 17)
- {
- loop++;
- printf(" ");
- }
- }
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " http=\"%s\"", buffer + 9);
- }
- else
- {
- // Output HTTP code...
- if (options->pout == true)
- printf("|| || ");
- else
- printf(" ");
- }
- }
- }
- else if (cipherStatus == 0)
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "rejected\"");
- if (options->http == true)
- {
- if (options->pout == true)
- printf("|| Rejected || N/A || ");
- else
- printf(" Rejected N/A ");
- }
- else
- {
- if (options->pout == true)
- printf("|| Rejected || ");
- else
- printf(" Rejected ");
- }
- }
- else
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "failed\"");
- if (options->http == true)
- {
- if (options->pout == true)
- printf("|| Failed || N/A || ");
- else
- printf(" Failed N/A ");
- }
- else
- {
- if (options->pout == true)
- printf("|| Failed || ");
- else
- printf(" Failed ");
- }
- }
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " sslversion=\"");
- #ifndef SSLSCAN_NO_SSL2
- if (sslCipherPointer->sslMethod == SSLv2_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "SSLv2\" bits=\"");
- if (options->pout == true)
- printf("SSLv2 || ");
- else
- printf("SSLv2 ");
- }
- else
- #endif
- if (sslCipherPointer->sslMethod == SSLv3_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "SSLv3\" bits=\"");
- if (options->pout == true)
- printf("SSLv3 || ");
- else
- printf("SSLv3 ");
- }
- else if (sslCipherPointer->sslMethod == TLSv1_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "TLSv1\" bits=\"");
- if (options->pout == true)
- printf("TLSv1 || ");
- else
- printf("TLSv1 ");
- }
- #ifndef SSLSCAN_NO_TLS1_1
- else if (sslCipherPointer->sslMethod == TLSv1_1_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "TLSv1.1\" bits=\"");
- if (options->pout == true)
- printf("TLSv1.1 || ");
- else
- printf("TLSv1.1 ");
- }
- #endif
- #ifndef SSLSCAN_NO_TLS1_2
- else if (sslCipherPointer->sslMethod == TLSv1_2_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "TLSv1.2\" bits=\"");
- if (options->pout == true)
- printf("TLSv1.2 || ");
- else
- printf("TLSv1.2 ");
- }
- #endif
- else
- {
- printf("ERROR unknown protocol version\n");
- }
- if (sslCipherPointer->bits < 10)
- tempInt = 2;
- else if (sslCipherPointer->bits < 100)
- tempInt = 1;
- else
- tempInt = 0;
- if (options->pout == true)
- printf("%d || ", sslCipherPointer->bits);
- else
- printf("%d bits ", sslCipherPointer->bits);
- while (tempInt != 0)
- {
- tempInt--;
- printf(" ");
- }
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "%d\" cipher=\"%s\" />\n", sslCipherPointer->bits, sslCipherPointer->name);
- if (options->pout == true)
- printf("%s ||\n", sslCipherPointer->name);
- else
- printf("%s\n", sslCipherPointer->name);
- }
- // Disconnect SSL over socket
- if (cipherStatus == 1)
- SSL_shutdown(ssl);
- // Free SSL object
- SSL_free(ssl);
- }
- else
- {
- status = false;
- printf("%s ERROR: Could create SSL object.%s\n", COL_RED, RESET);
- }
- }
- else
- {
- status = false;
- printf("%s ERROR: Could set cipher %s.%s\n", COL_RED, sslCipherPointer->name, RESET);
- }
- // Disconnect from host
- close(socketDescriptor);
- }
- // Could not connect
- else
- status = false;
- return status;
- }
- // Test for prefered ciphers
- int defaultCipher(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
- {
- // Variables...
- int cipherStatus;
- int status = true;
- int socketDescriptor = 0;
- SSL *ssl = NULL;
- BIO *cipherConnectionBio;
- int tempInt;
- int tempInt2;
- // Connect to host
- socketDescriptor = tcpConnect(options);
- if (socketDescriptor != 0)
- {
- // Setup Context Object...
- options->ctx = SSL_CTX_new(sslMethod);
- if (options->ctx != NULL)
- {
- if (SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL") != 0)
- {
- // Load Certs if required...
- if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0))
- status = loadCerts(options);
- if (status == true)
- {
- // Create SSL object...
- ssl = SSL_new(options->ctx);
- if (ssl != NULL)
- {
- // Connect socket and BIO
- cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE);
- // Connect SSL and BIO
- SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio);
- // Connect SSL over socket
- cipherStatus = SSL_connect(ssl);
- if (cipherStatus == 1)
- {
- #ifndef SSLSCAN_NO_SSL2
- if (sslMethod == SSLv2_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <defaultcipher sslversion=\"SSLv2\" bits=\"");
- if (options->pout == true)
- printf("|| SSLv2 || ");
- else
- printf(" SSLv2 ");
- }
- else
- #endif
- if (sslMethod == SSLv3_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <defaultcipher sslversion=\"SSLv3\" bits=\"");
- if (options->pout == true)
- printf("|| SSLv3 || ");
- else
- printf(" SSLv3 ");
- }
- else if (sslMethod == TLSv1_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <defaultcipher sslversion=\"TLSv1\" bits=\"");
- if (options->pout == true)
- printf("|| TLSv1 || ");
- else
- printf(" TLSv1 ");
- }
- #ifndef SSLSCAN_NO_TLS1_1
- else if (sslMethod == TLSv1_1_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <defaultcipher sslversion=\"TLSv1.1\" bits=\"");
- if (options->pout == true)
- printf("|| TLSv1.1 || ");
- else
- printf(" TLSv1.1 ");
- }
- #endif
- #ifndef SSLSCAN_NO_TLS1_2
- else if (sslMethod == TLSv1_2_client_method())
- {
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <defaultcipher sslversion=\"TLSv1.2\" bits=\"");
- if (options->pout == true)
- printf("|| TLSv1.2 || ");
- else
- printf(" TLSv1.2 ");
- }
- #endif
- else
- {
- printf("ERROR: unknown protocol\n");
- }
- if (SSL_get_cipher_bits(ssl, &tempInt2) < 10)
- tempInt = 2;
- else if (SSL_get_cipher_bits(ssl, &tempInt2) < 100)
- tempInt = 1;
- else
- tempInt = 0;
- if (options->pout == true)
- printf("%d bits || ", SSL_get_cipher_bits(ssl, &tempInt2));
- else
- printf("%d bits ", SSL_get_cipher_bits(ssl, &tempInt2));
- while (tempInt != 0)
- {
- tempInt--;
- printf(" ");
- }
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, "%d\" cipher=\"%s\" />\n", SSL_get_cipher_bits(ssl, &tempInt2), SSL_get_cipher_name(ssl));
- if (options->pout == true)
- printf("%s ||\n", SSL_get_cipher_name(ssl));
- else
- printf("%s\n", SSL_get_cipher_name(ssl));
- // Disconnect SSL over socket
- SSL_shutdown(ssl);
- }
- // Free SSL object
- SSL_free(ssl);
- }
- else
- {
- status = false;
- printf("%s ERROR: Could create SSL object.%s\n", COL_RED, RESET);
- }
- }
- }
- else
- {
- status = false;
- printf("%s ERROR: Could set cipher.%s\n", COL_RED, RESET);
- }
- // Free CTX Object
- SSL_CTX_free(options->ctx);
- }
- // Error Creating Context Object
- else
- {
- status = false;
- printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
- }
- // Disconnect from host
- close(socketDescriptor);
- }
- // Could not connect
- else
- status = false;
- return status;
- }
- // Get certificate...
- int getCertificate(struct sslCheckOptions *options)
- {
- // Variables...
- int cipherStatus = 0;
- int status = true;
- int socketDescriptor = 0;
- SSL *ssl = NULL;
- BIO *cipherConnectionBio = NULL;
- BIO *stdoutBIO = NULL;
- BIO *fileBIO = NULL;
- X509 *x509Cert = NULL;
- EVP_PKEY *publicKey = NULL;
- const SSL_METHOD *sslMethod = NULL;
- ASN1_OBJECT *asn1Object = NULL;
- X509_EXTENSION *extension = NULL;
- char buffer[1024];
- long tempLong = 0;
- int tempInt = 0;
- int tempInt2 = 0;
- long verifyError = 0;
- // Connect to host
- socketDescriptor = tcpConnect(options);
- if (socketDescriptor != 0)
- {
- // Setup Context Object...
- sslMethod = SSLv23_method();
- options->ctx = SSL_CTX_new(sslMethod);
- if (options->ctx != NULL)
- {
- if (SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL") != 0)
- {
- // Load Certs if required...
- if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0))
- status = loadCerts(options);
- if (status == true)
- {
- // Create SSL object...
- ssl = SSL_new(options->ctx);
- if (ssl != NULL)
- {
- // Connect socket and BIO
- cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE);
- // Connect SSL and BIO
- SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio);
- // Connect SSL over socket
- cipherStatus = SSL_connect(ssl);
- if (cipherStatus == 1)
- {
- // Setup BIO's
- stdoutBIO = BIO_new(BIO_s_file());
- BIO_set_fp(stdoutBIO, stdout, BIO_NOCLOSE);
- if (options->xmlOutput != 0)
- {
- fileBIO = BIO_new(BIO_s_file());
- BIO_set_fp(fileBIO, options->xmlOutput, BIO_NOCLOSE);
- }
- // Get Certificate...
- printf("\n %sSSL Certificate:%s\n", COL_BLUE, RESET);
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <certificate>\n");
- x509Cert = SSL_get_peer_certificate(ssl);
- if (x509Cert != NULL)
- {
- //SSL_set_verify(ssl, SSL_VERIFY_NONE|SSL_VERIFY_CLIENT_ONCE, NULL);
- // Cert Version
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VERSION))
- {
- tempLong = X509_get_version(x509Cert) + 1;
- printf(" Version: %lu\n", tempLong);
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <version>%lu</version>\n", tempLong);
- }
- // Cert Serial No.
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SERIAL))
- {
- tempLong = ASN1_INTEGER_get(X509_get_serialNumber(x509Cert));
- if (tempLong < 1)
- {
- printf(" Serial Number: -%lu\n", tempLong);
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <serial>-%lu</serial>\n", tempLong);
- }
- else
- {
- printf(" Serial Number: %lu\n", tempLong);
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <serial>%lu</serial>\n", tempLong);
- }
- }
- // Signature Algo...
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SIGNAME))
- {
- printf(" Signature Algorithm: ");
- i2a_ASN1_OBJECT(stdoutBIO, x509Cert->cert_info->signature->algorithm);
- printf("\n");
- if (options->xmlOutput != 0)
- {
- fprintf(options->xmlOutput, " <signature-algorithm>");
- i2a_ASN1_OBJECT(fileBIO, x509Cert->cert_info->signature->algorithm);
- fprintf(options->xmlOutput, "</signature-algorithm>\n");
- }
- }
- // SSL Certificate Issuer...
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_ISSUER))
- {
- X509_NAME_oneline(X509_get_issuer_name(x509Cert), buffer, sizeof(buffer) - 1);
- printf(" Issuer: %s\n", buffer);
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <issuer>%s</issuer>\n", buffer);
- }
- // Validity...
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VALIDITY))
- {
- printf(" Not valid before: ");
- ASN1_TIME_print(stdoutBIO, X509_get_notBefore(x509Cert));
- if (options->xmlOutput != 0)
- {
- fprintf(options->xmlOutput, " <not-valid-before>");
- ASN1_TIME_print(fileBIO, X509_get_notBefore(x509Cert));
- fprintf(options->xmlOutput, "</not-valid-before>\n");
- }
- printf("\n Not valid after: ");
- ASN1_TIME_print(stdoutBIO, X509_get_notAfter(x509Cert));
- printf("\n");
- if (options->xmlOutput != 0)
- {
- fprintf(options->xmlOutput, " <not-valid-after>");
- ASN1_TIME_print(fileBIO, X509_get_notAfter(x509Cert));
- fprintf(options->xmlOutput, "</not-valid-after>\n");
- }
- }
- // SSL Certificate Subject...
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SUBJECT))
- {
- X509_NAME_oneline(X509_get_subject_name(x509Cert), buffer, sizeof(buffer) - 1);
- printf(" Subject: %s\n", buffer);
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <subject>%s</subject>\n", buffer);
- }
- // Public Key Algo...
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_PUBKEY))
- {
- printf(" Public Key Algorithm: ");
- i2a_ASN1_OBJECT(stdoutBIO, x509Cert->cert_info->key->algor->algorithm);
- printf("\n");
- if (options->xmlOutput != 0)
- {
- fprintf(options->xmlOutput, " <pk-algorithm>");
- i2a_ASN1_OBJECT(fileBIO, x509Cert->cert_info->key->algor->algorithm);
- fprintf(options->xmlOutput, "</pk-algorithm>\n");
- }
- // Public Key...
- publicKey = X509_get_pubkey(x509Cert);
- if (publicKey == NULL)
- {
- printf(" Public Key: Could not load\n");
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <pk error=\"true\" />\n");
- }
- else
- {
- switch (publicKey->type)
- {
- case EVP_PKEY_RSA:
- printf(" RSA Public Key: (%d bit)\n", BN_num_bits(publicKey->pkey.rsa->n));
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <pk error=\"false\" type=\"RSA\" bits=\"%d\">\n", BN_num_bits(publicKey->pkey.rsa->n));
- RSA_print(stdoutBIO, publicKey->pkey.rsa, 6);
- if (options->xmlOutput != 0)
- {
- RSA_print(fileBIO, publicKey->pkey.rsa, 4);
- fprintf(options->xmlOutput, " </pk>\n");
- }
- break;
- case EVP_PKEY_DSA:
- printf(" DSA Public Key:\n");
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <pk error=\"false\" type=\"DSA\">\n");
- DSA_print(stdoutBIO, publicKey->pkey.dsa, 6);
- if (options->xmlOutput != 0)
- {
- DSA_print(fileBIO, publicKey->pkey.dsa, 4);
- fprintf(options->xmlOutput, " </pk>\n");
- }
- break;
- case EVP_PKEY_EC:
- printf(" EC Public Key:\n");
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <pk error=\"false\" type=\"EC\">\n");
- EC_KEY_print(stdoutBIO, publicKey->pkey.ec, 6);
- if (options->xmlOutput != 0)
- {
- EC_KEY_print(fileBIO, publicKey->pkey.ec, 4);
- fprintf(options->xmlOutput, " </pk>\n");
- }
- break;
- default:
- printf(" Public Key: Unknown\n");
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <pk error=\"true\" type=\"unknown\" />\n");
- break;
- }
- EVP_PKEY_free(publicKey);
- }
- }
- // X509 v3...
- if (!(X509_FLAG_COMPAT & X509_FLAG_NO_EXTENSIONS))
- {
- if (sk_X509_EXTENSION_num(x509Cert->cert_info->extensions) > 0)
- {
- printf(" X509v3 Extensions:\n");
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <X509v3-Extensions>\n");
- for (tempInt = 0; tempInt < sk_X509_EXTENSION_num(x509Cert->cert_info->extensions); tempInt++)
- {
- // Get Extension...
- extension = sk_X509_EXTENSION_value(x509Cert->cert_info->extensions, tempInt);
- // Print Extension name...
- printf(" ");
- asn1Object = X509_EXTENSION_get_object(extension);
- i2a_ASN1_OBJECT(stdoutBIO, asn1Object);
- tempInt2 = X509_EXTENSION_get_critical(extension);
- BIO_printf(stdoutBIO, ": %s\n", tempInt2 ? "critical" : "");
- if (options->xmlOutput != 0)
- {
- fprintf(options->xmlOutput, " <extension name=\"");
- i2a_ASN1_OBJECT(fileBIO, asn1Object);
- BIO_printf(fileBIO, "\"%s>", tempInt2 ? " level=\"critical\"" : "");
- }
- // Print Extension value...
- if (!X509V3_EXT_print(stdoutBIO, extension, X509_FLAG_COMPAT, 8))
- {
- printf(" ");
- M_ASN1_OCTET_STRING_print(stdoutBIO, extension->value);
- }
- if (options->xmlOutput != 0)
- {
- if (!X509V3_EXT_print(fileBIO, extension, X509_FLAG_COMPAT, 0))
- M_ASN1_OCTET_STRING_print(fileBIO, extension->value);
- fprintf(options->xmlOutput, "</extension>\n");
- }
- printf("\n");
- }
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " </X509v3-Extensions>\n");
- }
- }
- // Verify Certificate...
- printf(" Verify Certificate:\n");
- verifyError = SSL_get_verify_result(ssl);
- if (verifyError == X509_V_OK)
- printf(" Certificate passed verification\n");
- else
- printf(" %s\n", X509_verify_cert_error_string(verifyError));
- // Free X509 Certificate...
- X509_free(x509Cert);
- }
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " </certificate>\n");
- // Free BIO
- BIO_free(stdoutBIO);
- if (options->xmlOutput != 0)
- BIO_free(fileBIO);
- // Disconnect SSL over socket
- SSL_shutdown(ssl);
- }
- // Free SSL object
- SSL_free(ssl);
- }
- else
- {
- status = false;
- printf("%s ERROR: Could create SSL object.%s\n", COL_RED, RESET);
- }
- }
- }
- else
- {
- status = false;
- printf("%s ERROR: Could set cipher.%s\n", COL_RED, RESET);
- }
- // Free CTX Object
- SSL_CTX_free(options->ctx);
- }
- // Error Creating Context Object
- else
- {
- status = false;
- printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
- }
- // Disconnect from host
- close(socketDescriptor);
- }
- // Could not connect
- else
- status = false;
- return status;
- }
- // Test a single host and port for ciphers...
- int testHost(struct sslCheckOptions *options)
- {
- // Variables...
- struct sslCipher *sslCipherPointer;
- int status = true;
- // Resolve Host Name
- options->hostStruct = gethostbyname(options->host);
- if (options->hostStruct == NULL)
- {
- printf("%sERROR: Could not resolve hostname %s.%s\n", COL_RED, options->host, RESET);
- return false;
- }
- // Configure Server Address and Port
- options->serverAddress.sin_family = options->hostStruct->h_addrtype;
- memcpy((char *) &options->serverAddress.sin_addr.s_addr, options->hostStruct->h_addr_list[0], options->hostStruct->h_length);
- options->serverAddress.sin_port = htons(options->port);
- // XML Output...
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " <ssltest host=\"%s\" port=\"%d\">\n", options->host, options->port);
- // Test supported ciphers...
- printf("\n%sTesting SSL server %s on port %d%s\n\n", COL_GREEN, options->host, options->port, RESET);
- printf(" %sSupported Server Cipher(s):%s\n", COL_BLUE, RESET);
- if ((options->http == true) && (options->pout == true))
- printf("|| Status || HTTP Code || Version || Bits || Cipher ||\n");
- else if (options->pout == true)
- printf("|| Status || Version || Bits || Cipher ||\n");
- sslCipherPointer = options->ciphers;
- while ((sslCipherPointer != 0) && (status == true))
- {
- // Setup Context Object...
- options->ctx = SSL_CTX_new(sslCipherPointer->sslMethod);
- if (options->ctx != NULL)
- {
- // SSL implementation bugs/workaround
- if (options->sslbugs)
- SSL_CTX_set_options(options->ctx, SSL_OP_ALL | 0);
- else
- SSL_CTX_set_options(options->ctx, 0);
- // Load Certs if required...
- if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0))
- status = loadCerts(options);
- // Test
- if (status == true)
- status = testCipher(options, sslCipherPointer);
- // Free CTX Object
- SSL_CTX_free(options->ctx);
- }
- // Error Creating Context Object
- else
- {
- status = false;
- printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
- }
- sslCipherPointer = sslCipherPointer->next;
- }
- if (status == true)
- {
- // Test prefered ciphers...
- printf("\n %sPrefered Server Cipher(s):%s\n", COL_BLUE, RESET);
- if (options->pout == true)
- printf("|| Version || Bits || Cipher ||\n");
- switch (options->sslVersion)
- {
- case ssl_all:
- #ifndef SSLSCAN_NO_SSL2
- status = defaultCipher(options, SSLv2_client_method());
- if (status != false)
- #endif
- status = defaultCipher(options, SSLv3_client_method());
- if (status != false)
- status = defaultCipher(options, TLSv1_client_method());
- #ifndef SSLSCAN_NO_TLS1_1
- if (status != false)
- status = defaultCipher(options, TLSv1_1_client_method());
- #endif
- #ifndef SSLSCAN_NO_TLS1_2
- if (status != false)
- status = defaultCipher(options, TLSv1_2_client_method());
- #endif
- break;
- #ifndef SSLSCAN_NO_SSL2
- case ssl_v2:
- status = defaultCipher(options, SSLv2_client_method());
- break;
- #endif
- case ssl_v3:
- status = defaultCipher(options, SSLv3_client_method());
- break;
- case tls_v1:
- status = defaultCipher(options, TLSv1_client_method());
- break;
- #ifndef SSLSCAN_NO_TLS1_1
- case tls_v1_1:
- status = defaultCipher(options, TLSv1_1_client_method());
- break;
- #endif
- #ifndef SSLSCAN_NO_TLS1_2
- case tls_v1_2:
- status = defaultCipher(options, TLSv1_2_client_method());
- break;
- #endif
- }
- }
- if (status == true)
- {
- status = getCertificate(options);
- }
- // XML Output...
- if (options->xmlOutput != 0)
- fprintf(options->xmlOutput, " </ssltest>\n");
- // Return status...
- return status;
- }
- int main(int argc, char *argv[])
- {
- // Variables...
- struct sslCheckOptions options;
- struct sslCipher *sslCipherPointer;
- int status;
- int argLoop;
- int tempInt;
- int maxSize;
- int xmlArg;
- int mode = mode_help;
- FILE *targetsFile;
- char line[1024];
- // Init...
- memset(&options, 0x00, sizeof(struct sslCheckOptions));
- options.port = 443;
- xmlArg = 0;
- strcpy(options.host, "127.0.0.1");
- options.noFailed = false;
- options.starttls = false;
- options.sslVersion = ssl_all;
- options.pout = false;
- unsigned long v1 = OPENSSL_VERSION_NUMBER;
- unsigned long v2 = SSLeay();
- if((v1 & 0xFFFF0000) != (v2 & 0xFFFF0000))
- {
- fprintf(stderr, "SSLscan was compiled with OpenSSL version 0x%lx, but linked against 0x%lx", OPENSSL_VERSION_NUMBER, SSLeay());
- exit (1);
- }
- OpenSSL_add_ssl_algorithms();
- SSL_load_error_strings();
- // Get program parameters
- for (argLoop = 1; argLoop < argc; argLoop++)
- {
- // Help
- if (strcmp("--help", argv[argLoop]) == 0)
- mode = mode_help;
- // targets
- else if ((strncmp("--targets=", argv[argLoop], 10) == 0) && (strlen(argv[argLoop]) > 10))
- {
- mode = mode_multiple;
- options.targets = argLoop;
- }
- // Show only supported
- else if (strcmp("--no-failed", argv[argLoop]) == 0)
- options.noFailed = true;
- // Version
- else if (strcmp("--version", argv[argLoop]) == 0)
- mode = mode_version;
- // XML Output
- else if (strncmp("--xml=", argv[argLoop], 6) == 0)
- xmlArg = argLoop;
- // P Output
- else if (strcmp("-p", argv[argLoop]) == 0)
- options.pout = true;
- // Client Certificates
- else if (strncmp("--certs=", argv[argLoop], 8) == 0)
- options.clientCertsFile = argv[argLoop] +8;
- // Private Key File
- else if (strncmp("--pk=", argv[argLoop], 5) == 0)
- options.privateKeyFile = argv[argLoop] +5;
- // Private Key Password
- else if (strncmp("--pkpass=", argv[argLoop], 9) == 0)
- options.privateKeyPassword = argv[argLoop] +9;
- // StartTLS...
- else if (strcmp("--starttls", argv[argLoop]) == 0)
- {
- options.sslVersion = tls_v1;
- options.starttls = true;
- }
- // SSL v2 only...
- else if (strcmp("--ssl2", argv[argLoop]) == 0)
- options.sslVersion = ssl_v2;
- // SSL v3 only...
- else if (strcmp("--ssl3", argv[argLoop]) == 0)
- options.sslVersion = ssl_v3;
- // TLS v1 only...
- else if (strcmp("--tls1", argv[argLoop]) == 0)
- options.sslVersion = tls_v1;
- else if (strcmp("--tls1_0", argv[argLoop]) == 0)
- options.sslVersion = tls_v1;
- else if (strcmp("--tls1.0", argv[argLoop]) == 0)
- options.sslVersion = tls_v1;
- // TLS v1.1 only...
- else if (strcmp("--tls1_1", argv[argLoop]) == 0)
- options.sslVersion = tls_v1_1;
- else if (strcmp("--tls1.1", argv[argLoop]) == 0)
- options.sslVersion = tls_v1_1;
- // TLS v1.2 only...
- else if (strcmp("--tls1_2", argv[argLoop]) == 0)
- options.sslVersion = tls_v1_2;
- else if (strcmp("--tls1.2", argv[argLoop]) == 0)
- options.sslVersion = tls_v1_2;
- else if (strcmp("--no-sni", argv[argLoop]) == 0)
- options.noSNI = 1;
- // SSL Bugs...
- else if (strcmp("--bugs", argv[argLoop]) == 0)
- options.sslbugs = 1;
- // SSL HTTP Get...
- else if (strcmp("--http", argv[argLoop]) == 0)
- options.http = 1;
- // Host (maybe port too)...
- else if (argLoop + 1 == argc)
- {
- mode = mode_single;
- // Get host...
- tempInt = 0;
- maxSize = strlen(argv[argLoop]);
- while ((argv[argLoop][tempInt] != 0) && (argv[argLoop][tempInt] != ':'))
- tempInt++;
- argv[argLoop][tempInt] = 0;
- strncpy(options.host, argv[argLoop], sizeof(options.host) -1);
- // Get port (if it exists)...
- tempInt++;
- if (tempInt < maxSize)
- options.port = atoi(argv[argLoop] + tempInt);
- }
- // Not too sure what the user is doing...
- else
- mode = mode_help;
- }
- // Open XML file output...
- if ((xmlArg > 0) && (mode != mode_help))
- {
- options.xmlOutput = fopen(argv[xmlArg] + 6, "w");
- if (options.xmlOutput == NULL)
- {
- printf("%sERROR: Could not open XML output file %s.%s\n", COL_RED, argv[xmlArg] + 6, RESET);
- exit(0);
- }
- // Output file header...
- 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);
- }
- switch (mode)
- {
- case mode_version:
- printf("%s%s%s", COL_BLUE, program_version, RESET);
- printf("%s%s (0x%lx) %s\n", COL_BLUE, SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER, RESET);
- printf("%s%s%s\n", COL_BLUE, availableProtocols(), RESET);
- break;
- case mode_help:
- // Program version banner...
- printf("%s%s%s\n", COL_BLUE, program_banner, RESET);
- printf("SSLScan is a fast SSL port scanner. SSLScan connects to SSL\n");
- printf("ports and determines what ciphers are supported, which are\n");
- printf("the servers prefered ciphers, which SSL protocols are\n");
- printf("supported and returns the SSL certificate. Client\n");
- printf("certificates / private key can be configured and output is\n");
- printf("to text / XML.\n\n");
- printf("%sCommand:%s\n", COL_BLUE, RESET);
- printf(" %s%s [Options] [host:port | host]%s\n\n", COL_GREEN, argv[0], RESET);
- printf("%sOptions:%s\n", COL_BLUE, RESET);
- printf(" %s--targets=<file>%s A file containing a list of hosts to\n", COL_GREEN, RESET);
- printf(" check. Hosts can be supplied with\n");
- printf(" ports (i.e. host:port).\n");
- printf(" %s--no-failed%s List only accepted ciphers (default\n", COL_GREEN, RESET);
- printf(" is to listing all ciphers).\n");
- printf(" %s--ssl2%s Only check SSLv2 ciphers.\n", COL_GREEN, RESET);
- printf(" %s--ssl3%s Only check SSLv3 ciphers.\n", COL_GREEN, RESET);
- printf(" %s--tls1%s Only check TLSv1 ciphers.\n", COL_GREEN, RESET);
- printf(" %s--tls1_1%s Only check TLSv1.1 ciphers.\n", COL_GREEN, RESET);
- printf(" %s--tls1_2%s Only check TLSv1.2 ciphers.\n", COL_GREEN, RESET);
- printf(" %s--no-sni%s Disable SNI for TLS1 and above.\n", COL_GREEN, RESET);
- printf(" %s--pk=<file>%s A file containing the private key or\n", COL_GREEN, RESET);
- printf(" a PKCS#12 file containing a private\n");
- printf(" key/certificate pair (as produced by\n");
- printf(" MSIE and Netscape).\n");
- printf(" %s--pkpass=<password>%s The password for the private key or\n", COL_GREEN, RESET);
- printf(" PKCS#12 file.\n");
- printf(" %s--certs=<file>%s A file containing PEM/ASN1 formatted\n", COL_GREEN, RESET);
- printf(" client certificates.\n");
- printf(" %s--starttls%s If a STARTTLS is required to kick an\n", COL_GREEN, RESET);
- printf(" SMTP service into action.\n");
- printf(" %s--http%s Test a HTTP connection.\n", COL_GREEN, RESET);
- printf(" %s--bugs%s Enable SSL implementation bug work-\n", COL_GREEN, RESET);
- printf(" arounds.\n");
- printf(" %s--xml=<file>%s Output results to an XML file.\n", COL_GREEN, RESET);
- printf(" %s--version%s Display the program version.\n", COL_GREEN, RESET);
- printf(" %s--help%s Display the help text you are now\n", COL_GREEN, RESET);
- printf(" reading.\n");
- printf("%sExample:%s\n", COL_BLUE, RESET);
- printf(" %s%s 127.0.0.1%s\n\n", COL_GREEN, argv[0], RESET);
- break;
- // Check a single host/port ciphers...
- case mode_single:
- case mode_multiple:
- printf("%s%s%s", COL_BLUE, program_banner, RESET);
- SSLeay_add_all_algorithms();
- ERR_load_crypto_strings();
- // Build a list of ciphers...
- switch (options.sslVersion)
- {
- case ssl_all:
- #ifndef SSLSCAN_NO_SSL2
- populateCipherList(&options, SSLv2_client_method());
- #endif
- populateCipherList(&options, SSLv3_client_method());
- populateCipherList(&options, TLSv1_client_method());
- #ifndef SSLSCAN_NO_TLS1_1
- populateCipherList(&options, TLSv1_1_client_method());
- #endif
- #ifndef SSLSCAN_NO_TLS1_2
- populateCipherList(&options, TLSv1_2_client_method());
- #endif
- break;
- #ifndef SSLSCAN_NO_SSL2
- case ssl_v2:
- populateCipherList(&options, SSLv2_client_method());
- break;
- #endif
- case ssl_v3:
- populateCipherList(&options, SSLv3_client_method());
- break;
- case tls_v1:
- populateCipherList(&options, TLSv1_client_method());
- #ifndef SSLSCAN_NO_TLS1_1
- case tls_v1_1:
- populateCipherList(&options, TLSv1_1_client_method());
- #endif
- #ifndef SSLSCAN_NO_TLS1_2
- case tls_v1_2:
- populateCipherList(&options, TLSv1_2_client_method());
- break;
- #endif
- }
- // Do the testing...
- if (mode == mode_single)
- status = testHost(&options);
- else
- {
- if (fileExists(argv[options.targets] + 10) == true)
- {
- // Open targets file...
- targetsFile = fopen(argv[options.targets] + 10, "r");
- if (targetsFile == NULL)
- printf("%sERROR: Could not open targets file %s.%s\n", COL_RED, argv[options.targets] + 10, RESET);
- else
- {
- readLine(targetsFile, line, sizeof(line));
- while (feof(targetsFile) == 0)
- {
- if (strlen(line) != 0)
- {
- // Get host...
- tempInt = 0;
- while ((line[tempInt] != 0) && (line[tempInt] != ':'))
- tempInt++;
- line[tempInt] = 0;
- strncpy(options.host, line, sizeof(options.host) -1);
- // Get port (if it exists)...
- tempInt++;
- if (strlen(line + tempInt) > 0)
- options.port = atoi(line + tempInt);
- // Test the host...
- status = testHost(&options);
- }
- readLine(targetsFile, line, sizeof(line));
- }
- }
- }
- else
- printf("%sERROR: Targets file %s does not exist.%s\n", COL_RED, argv[options.targets] + 10, RESET);
- }
- // Free Structures
- while (options.ciphers != 0)
- {
- sslCipherPointer = options.ciphers->next;
- free(options.ciphers);
- options.ciphers = sslCipherPointer;
- }
- break;
- }
- // Close XML file, if required...
- if ((xmlArg > 0) && (mode != mode_help))
- {
- fprintf(options.xmlOutput, "</document>\n");
- fclose(options.xmlOutput);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement