Initial checkin of sslstrength/ssltelnet source.

This commit is contained in:
mcgreer%netscape.com 2000-04-03 20:31:05 +00:00
parent dbe48be092
commit 84d9905156
5 changed files with 1240 additions and 0 deletions

View File

@ -0,0 +1,72 @@
#! gmake
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include $(CORE_DEPTH)/security/cmd/platlibs.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################

View File

@ -0,0 +1,50 @@
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
CORE_DEPTH = ../../..
MODULE = security
EXPORTS =
CSRCS = sslstrength.c \
$(NULL)
PROGRAM = sslstrength
REQUIRES = security dbm seccmd
DEFINES = -DNSPR20
PACKAGE_FILES = sslstrength
ARCHIVE_NAME = sslstrength

View File

@ -0,0 +1,296 @@
#!/usr/bin/perl
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
use CGI qw(:standard);
# Replace this will the full path to the sslstrength executable.
$sslstrength = "./sslstrength";
# Replace this with the name of this CGI.
$sslcgi = "sslstr.cgi";
$query = new CGI;
print header;
print "<HTML><HEAD>
<SCRIPT language='javascript'>
function doexport(form) {
form.ssl2ciphers.options[0].selected=0;
form.ssl2ciphers.options[1].selected=0;
form.ssl2ciphers.options[2].selected=0;
form.ssl2ciphers.options[3].selected=0;
form.ssl2ciphers.options[4].selected=1;
form.ssl2ciphers.options[5].selected=1;
form.ssl3ciphers.options[0].selected=1;
form.ssl3ciphers.options[1].selected=1;
form.ssl3ciphers.options[2].selected=0;
form.ssl3ciphers.options[3].selected=1;
form.ssl3ciphers.options[4].selected=1;
form.ssl3ciphers.options[5].selected=1;
form.ssl3ciphers.options[6].selected=0;
form.ssl3ciphers.options[7].selected=0;
}
function dodomestic(form) {
form.ssl2ciphers.options[0].selected=1;
form.ssl2ciphers.options[1].selected=1;
form.ssl2ciphers.options[2].selected=1;
form.ssl2ciphers.options[3].selected=1;
form.ssl2ciphers.options[4].selected=1;
form.ssl2ciphers.options[5].selected=1;
form.ssl3ciphers.options[0].selected=1;
form.ssl3ciphers.options[1].selected=1;
form.ssl3ciphers.options[2].selected=1;
form.ssl3ciphers.options[3].selected=1;
form.ssl3ciphers.options[4].selected=1;
form.ssl3ciphers.options[5].selected=1;
form.ssl3ciphers.options[6].selected=1;
form.ssl3ciphers.options[7].selected=1;
}
function doclearssl2(form) {
form.ssl2ciphers.options[0].selected=0;
form.ssl2ciphers.options[1].selected=0;
form.ssl2ciphers.options[2].selected=0;
form.ssl2ciphers.options[3].selected=0;
form.ssl2ciphers.options[4].selected=0;
form.ssl2ciphers.options[5].selected=0;
}
function doclearssl3(form) {
form.ssl3ciphers.options[0].selected=0;
form.ssl3ciphers.options[1].selected=0;
form.ssl3ciphers.options[2].selected=0;
form.ssl3ciphers.options[3].selected=0;
form.ssl3ciphers.options[4].selected=0;
form.ssl3ciphers.options[5].selected=0;
form.ssl3ciphers.options[6].selected=0;
form.ssl3ciphers.options[7].selected=0;
}
function dohost(form,hostname) {
form.host.value=hostname;
}
</SCRIPT>
<TITLE>\n";
print "SSLStrength\n";
print "</TITLE></HEAD>\n";
print "<h1>SSLStrength</h1>\n";
if ($query->param('dotest')) {
print "Output from sslstrength: \n";
print "<pre>\n";
$cs = "";
@ssl2ciphers = $query->param('ssl2ciphers');
for $cipher (@ssl2ciphers) {
if ($cipher eq "SSL_EN_RC2_128_WITH_MD5") { $cs .= "a"; }
if ($cipher eq "SSL_EN_RC2_128_CBC_WITH_MD5") { $cs .= "b"; }
if ($cipher eq "SSL_EN_DES_192_EDE3_CBC_WITH_MD5") { $cs .= "c"; }
if ($cipher eq "SSL_EN_DES_64_CBC_WITH_MD5") { $cs .= "d"; }
if ($cipher eq "SSL_EN_RC4_128_EXPORT40_WITH_MD5") { $cs .= "e"; }
if ($cipher eq "SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5") { $cs .= "f"; }
}
@ssl3ciphers = $query->param('ssl3ciphers');
for $cipher (@ssl3ciphers) {
if ($cipher eq "SSL_RSA_WITH_RC4_128_MD5") { $cs .= "i"; }
if ($cipher eq "SSL_RSA_WITH_3DES_EDE_CBC_SHA") { $cs .= "j"; }
if ($cipher eq "SSL_RSA_WITH_DES_CBC_SHA") { $cs .= "k"; }
if ($cipher eq "SSL_RSA_EXPORT_WITH_RC4_40_MD5") { $cs .= "l"; }
if ($cipher eq "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5") { $cs .= "m"; }
if ($cipher eq "SSL_RSA_WITH_NULL_MD5") { $cs .= "o"; }
if ($cipher eq "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA") { $cs .= "p"; }
if ($cipher eq "SSL_RSA_FIPS_WITH_DES_CBC_SHA") { $cs .= "q"; }
}
$hs = $query->param('host');
if ($hs eq "") {
print "</pre>You must specify a host to connect to.<br><br>\n";
exit(0);
}
$ps = $query->param('policy');
$cmdstring = "$sslstrength $hs policy=$ps ciphers=$cs";
print "running sslstrength:\n";
print "$cmdstring\n";
$r = open(SSLS, "$cmdstring |");
if ($r == 0) {
print "<pre>There was a problem starting $cmdstring<br><br>\n";
exit(0);
}
while (<SSLS>) {
print "$_";
}
close(SSLS);
print "</pre>\n";
}
else {
print "<FORM method=post action=$sslcgi>\n";
print "<hr>
<h2>Host Name</h2>
<TABLE BORDER=0 CELLPADDING=20>
<TR>
<TD>
Type hostname here:<br>
<input type=text name=host size=30>&nbsp;<br><br>
<TD>
<b>Or click these buttons to test some well-known servers</b><br>
<TABLE BORDER=0>
<TR>
<TD>
Export servers:
<TD>
<input type=button value='F-Tech' onclick=dohost(this.form,'strongbox.ftech.net')>
</TR>
<TR>
<TD>
Domestic servers:
<TD>
<input type=button value='Wells Fargo' onclick=dohost(this.form,'banking.wellsfargo.com')>
</TR>
<TR>
<TD>
Step-Up Servers
<TD>
<input type=button value='Barclaycard' onclick=dohost(this.form,'enigma.barclaycard.co.uk')>
<input type=button value='BBVnet' onclick=dohost(this.form,'www.bbvnet.com')>&nbsp;
<input type=button value='BHIF' onclick=dohost(this.form,'empresas.bhif.cl')>&nbsp;
</TR>
</TABLE>
</TR>
</TABLE>
<br>
<hr>
<br>
<h2>Encryption policy</h2>
<input type=radio name=policy VALUE=export onclick=doexport(this.form)>&nbsp;
Export<br>
<input type=radio name=policy VALUE=domestic CHECKED onclick=dodomestic(this.form)>&nbsp;
Domestic<br>
<br>
<hr>
<br>
<h2>Cipher Selection</h2>
(use ctrl to multi-select)<br>
<table>
<tr>
<td>SSL 2 Ciphers
<td>
<SELECT NAME=ssl2ciphers SIZE=6 MULTIPLE align=bottom>
<OPTION SELECTED>SSL_EN_RC4_128_WITH_MD5
<OPTION SELECTED>SSL_EN_RC2_128_CBC_WITH_MD5
<OPTION SELECTED>SSL_EN_DES_192_EDE3_CBC_WITH_MD5
<OPTION SELECTED>SSL_EN_DES_64_CBC_WITH_MD5
<OPTION SELECTED>SSL_EN_RC4_128_EXPORT40_WITH_MD5
<OPTION SELECTED>SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5
</SELECT>
<input type=button Value='Clear all' onclick = 'doclearssl2(this.form)'>
</tr>
<tr>
<td>SSL3 Ciphers
<td>
<SELECT NAME=ssl3ciphers SIZE=8 MULTIPLE>
<OPTION SELECTED>SSL_RSA_WITH_RC4_128_MD5
<OPTION SELECTED>SSL_RSA_WITH_3DES_EDE_CBC_SHA
<OPTION SELECTED>SSL_RSA_WITH_DES_CBC_SHA
<OPTION SELECTED>SSL_RSA_EXPORT_WITH_RC4_40_MD5
<OPTION SELECTED>SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
<OPTION SELECTED>SSL_RSA_WITH_NULL_MD5
<OPTION SELECTED>SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
<OPTION SELECTED>SSL_RSA_FIPS_WITH_DES_CBC_SHA
</SELECT>
<input type=button value='Clear all' onclick = 'doclearssl3(this.form)'>
<TD>
<input type=submit name=dotest value='Run SSLStrength'>
</tr>
</table>
<input type=hidden name=dotest>
<br>
<br>
</form>
\n";
}
exit(0);
__END__
id CipherName Domestic Export
a SSL_EN_RC4_128_WITH_MD5 (ssl2) Yes No
b SSL_EN_RC2_128_CBC_WITH_MD5 (ssl2) Yes No
c SSL_EN_DES_192_EDE3_CBC_WITH_MD5 (ssl2) Yes No
d SSL_EN_DES_64_CBC_WITH_MD5 (ssl2) Yes No
e SSL_EN_RC4_128_EXPORT40_WITH_MD5 (ssl2) Yes Yes
f SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 (ssl2) Yes Yes
i SSL_RSA_WITH_RC4_128_MD5 (ssl3) Yes Step-up only
j SSL_RSA_WITH_3DES_EDE_CBC_SHA (ssl3) Yes Step-up only
k SSL_RSA_WITH_DES_CBC_SHA (ssl3) Yes No
l SSL_RSA_EXPORT_WITH_RC4_40_MD5 (ssl3) Yes Yes
m SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (ssl3) Yes Yes
o SSL_RSA_WITH_NULL_MD5 (ssl3) Yes Yes

View File

@ -0,0 +1,641 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifdef SSLTELNET
#include <termios.h>
#endif
/* Portable layer header files */
#include "prinit.h"
#include "prprf.h"
#include "prsystem.h"
#include "prmem.h"
#include "plstr.h"
#include "prnetdb.h"
#include "prinrval.h"
#include "secutil.h"
/* Security library files */
#include "cert.h"
#include "cdbhdl.h"
#include "ssl.h"
#include "sslproto.h"
/* define this if you want telnet capability! */
/* #define SSLTELNET 1 */
PRInt32 debug;
#ifdef DEBUG_stevep
#define dbmsg(x) if (verbose) PR_fprintf(PR_STDOUT,x);
#else
#define dbmsg(x) ;
#endif
/* Set SSL Policy to Domestic (strong=1) or Export (strong=0) */
#define ALLOW(x) SSL_SetPolicy(x,SSL_ALLOWED); SSL_EnableCipher(x,1);
#define DISALLOW(x) SSL_SetPolicy(x,SSL_NOT_ALLOWED); SSL_EnableCipher(x,0);
#define MAYBEALLOW(x) SSL_SetPolicy(x,SSL_RESTRICTED); SSL_EnableCipher(x,1);
struct CipherPolicy {
char number;
long id;
char *name;
PRInt32 pref;
PRInt32 domestic;
PRInt32 export;
};
struct CipherPolicy ciphers[] = {
{ 'a',SSL_EN_RC4_128_WITH_MD5, "SSL_EN_RC4_128_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'b',SSL_EN_RC2_128_CBC_WITH_MD5, "SSL_EN_RC2_128_CBC_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'c',SSL_EN_DES_192_EDE3_CBC_WITH_MD5, "SSL_EN_DES_192_EDE3_CBC_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'd',SSL_EN_DES_64_CBC_WITH_MD5, "SSL_EN_DES_64_CBC_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'e',SSL_EN_RC4_128_EXPORT40_WITH_MD5, "SSL_EN_RC4_128_EXPORT40_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_ALLOWED },
{ 'f',SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_ALLOWED },
#ifdef FORTEZZA
{ 'g',SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA",1,SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'h',SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, "SSL_FORTEZZA_DMS_WITH_RC4_128_SHA",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
#endif
{ 'i',SSL_RSA_WITH_RC4_128_MD5, "SSL_RSA_WITH_RC4_128_MD5 (ssl3)",1, SSL_ALLOWED,SSL_RESTRICTED },
{ 'j',SSL_RSA_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_WITH_3DES_EDE_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_RESTRICTED },
{ 'k',SSL_RSA_WITH_DES_CBC_SHA, "SSL_RSA_WITH_DES_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'l',SSL_RSA_EXPORT_WITH_RC4_40_MD5, "SSL_RSA_EXPORT_WITH_RC4_40_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED },
{ 'm',SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED },
#ifdef FORTEZZA
{ 'n',SSL_FORTEZZA_DMS_WITH_NULL_SHA, "SSL_FORTEZZA_DMS_WITH_NULL_SHA",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
#endif
{ 'o',SSL_RSA_WITH_NULL_MD5, "SSL_RSA_WITH_NULL_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED },
{ 'p',SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'q',SSL_RSA_FIPS_WITH_DES_CBC_SHA, "SSL_RSA_FIPS_WITH_DES_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }
};
void PrintErrString(char *progName,char *msg) {
PRErrorCode e = PORT_GetError();
char *s=NULL;
if ((e >= PR_NSPR_ERROR_BASE) && (e < PR_MAX_ERROR)) {
if (e == PR_DIRECTORY_LOOKUP_ERROR)
s = PL_strdup("Hostname Lookup Failed");
else if (e == PR_NETWORK_UNREACHABLE_ERROR)
s = PL_strdup("Network Unreachable");
else if (e == PR_CONNECT_TIMEOUT_ERROR)
s = PL_strdup("Connection Timed Out");
else s = PR_smprintf("%d",e);
if (!s) return;
}
else {
s = PL_strdup(SECU_ErrorString(e));
}
PR_fprintf(PR_STDOUT,"%s: ",progName);
if (s) {
if (strlen(s) > 0)
PR_fprintf(PR_STDOUT, "%s\n", s);
else
PR_fprintf(PR_STDOUT, "\n");
PR_Free(s);
}
}
void PrintCiphers(int onlyenabled) {
int ciphercount,i;
if (onlyenabled) {
PR_fprintf(PR_STDOUT,"Your Cipher preference:\n");
}
ciphercount = sizeof(ciphers)/sizeof(struct CipherPolicy);
PR_fprintf(PR_STDOUT,
" %s %-45s %-12s %-12s\n","id","CipherName","Domestic","Export");
for (i=0;i<ciphercount;i++) {
if ( (onlyenabled ==0) || ((onlyenabled==1)&&(ciphers[i].pref))) {
PR_fprintf(PR_STDOUT,
" %c %-45s %-12s %-12s\n",ciphers[i].number,ciphers[i].name,
(ciphers[i].domestic==SSL_ALLOWED)?"Yes":
( (ciphers[i].domestic==SSL_NOT_ALLOWED)?"No":"Step-up only"),
(ciphers[i].export==SSL_ALLOWED)?"Yes":
( (ciphers[i].export==SSL_NOT_ALLOWED)?"No":"Step-up only"));
}
}
}
void SetPolicy(char *c,int policy) { /* policy==1 : domestic, policy==0, export */
int i,j,cpolicy;
/* first, enable all relevant ciphers according to policy */
for (j=0;j<(sizeof(ciphers)/sizeof(struct CipherPolicy));j++) {
SSL_SetPolicy(ciphers[j].id,policy?ciphers[j].domestic:ciphers[j].export);
SSL_EnableCipher(ciphers[j].id,0);
ciphers[j].pref =0;
}
for (i=0;i<PL_strlen(c);i++) {
for (j=0;j<(sizeof(ciphers)/sizeof(struct CipherPolicy));j++) {
if (ciphers[j].number == c[i]) {
cpolicy = policy?ciphers[j].domestic:ciphers[j].export;
if (cpolicy == SSL_NOT_ALLOWED) {
PR_fprintf(PR_STDOUT, "You're trying to enable a cipher (%c:%s) outside of your policy. ignored\n",
c[i],ciphers[j].name);
}
else {
ciphers[j].pref=1;
SSL_EnableCipher(ciphers[j].id,1);
}
}
}
}
}
int MyAuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checksig, PRBool isserver) {
return SECSuccess;
}
void Usage() {
#ifdef SSLTELNET
PR_fprintf(PR_STDOUT,"SSLTelnet ");
#else
PR_fprintf(PR_STDOUT,"SSLStrength (No telnet functionality) ");
#endif
PR_fprintf(PR_STDOUT,"Version 1.5\n");
PR_fprintf(PR_STDOUT,"Usage:\n sslstrength hostname[:port] [ciphers=xyz] [certdir=x] [debug] [verbose] "
#ifdef SSLTELNET
"[telnet]|[servertype]|[querystring=<string>] "
#endif
"[policy=export|domestic]\n sslstrength ciphers\n");
}
PRInt32 debug = 0;
PRInt32 verbose = 0;
PRInt32 main(PRInt32 argc,char **argv, char **envp)
{
/* defaults for command line arguments */
char *hostnamearg=NULL;
char *portnumarg=NULL;
char *sslversionarg=NULL;
char *keylenarg=NULL;
char *certdir=NULL;
char *hostname;
char *nickname=NULL;
char *progname=NULL;
/* struct sockaddr_in addr; */
PRNetAddr addr;
int ss_on;
char *ss_cipher;
int ss_keysize;
int ss_secretsize;
char *ss_issuer;
char *ss_subject;
int policy=1;
char *set_ssl_policy=NULL;
int print_ciphers=0;
char buf[10];
char netdbbuf[PR_NETDB_BUF_SIZE];
PRHostEnt hp;
PRStatus r;
PRNetAddr na;
SECStatus rv;
int portnum=443; /* default https: port */
PRFileDesc *s,*fd;
CERTCertDBHandle *handle;
CERTCertificate *c;
PRInt32 i;
#ifdef SSLTELNET
struct termios tmp_tc;
char cb;
int prev_lflag,prev_oflag,prev_iflag;
int t_fin,t_fout;
int servertype=0, telnet=0;
char *querystring=NULL;
#endif
debug = 0;
progname = (char *)PL_strrchr(argv[0], '/');
progname = progname ? progname+1 : argv[0];
/* Read in command line args */
if (argc == 1) {
Usage();
return(0);
}
if (! PL_strcmp("ciphers",argv[1])) {
PrintCiphers(0);
exit(0);
}
hostname = argv[1];
if (!PL_strcmp(hostname , "usage") || !PL_strcmp(hostname, "-help") ) {
Usage();
exit(0);
}
if ((portnumarg = PL_strchr(hostname,':'))) {
*portnumarg = 0;
portnumarg = &portnumarg[1];
}
if (portnumarg) {
if (PL_strlen(portnumarg) == 0) {
PR_fprintf(PR_STDOUT,"malformed port number supplied\n");
return(1);
}
portnum = atoi(portnumarg);
}
for (i = 2 ; i < argc; i++)
{
if (!PL_strncmp(argv[i] , "sslversion=",11) )
sslversionarg=&(argv[i][11]);
else if (!PL_strncmp(argv[i], "certdir=",8) )
certdir = &(argv[i][8]);
else if (!PL_strncmp(argv[i], "ciphers=",8) )
{
set_ssl_policy=&(argv[i][8]);
}
else if (!PL_strncmp(argv[i], "policy=",7) ) {
if (!PL_strcmp(&(argv[i][7]),"domestic")) policy=1;
else if (!PL_strcmp(&(argv[i][7]),"export")) policy=0;
else {
PR_fprintf(PR_STDOUT,"sslstrength: invalid argument. policy must be one of (domestic,export)\n");
}
}
else if (!PL_strcmp(argv[i] , "debug") )
debug = 1;
#ifdef SSLTELNET
else if (!PL_strcmp(argv[i] , "telnet") )
telnet = 1;
else if (!PL_strcmp(argv[i] , "servertype") )
servertype = 1;
else if (!PL_strncmp(argv[i] , "querystring=",11) )
querystring = &argv[i][12];
#endif
else if (!PL_strcmp(argv[i] , "verbose") )
verbose = 1;
}
#ifdef SSLTELNET
if (telnet && (servertype || querystring)) {
PR_fprintf(PR_STDOUT,"You can't use telnet and (server or querystring) options at the same time\n");
exit(1);
}
#endif
PR_fprintf(PR_STDOUT,"Using %s policy\n",policy?"domestic":"export");
/* use current directory for certificate database if not set */
if (! certdir) {
certdir = PR_smprintf(".");
}
SECU_ConfigDirectory(certdir);
/* allow you to set env var SSLDIR to set the cert directory */
if (! certdir) certdir = SECU_DefaultSSLDir();
if (certdir) SECU_ConfigDirectory(certdir);
/* PR_Init(progname, 1, 1, 0); */
SECU_PKCS11Init(PR_FALSE /*readOnly==PR_FALSE*/);
/* Lookup host */
r = PR_GetHostByName(hostname,netdbbuf,PR_NETDB_BUF_SIZE,&hp);
if (r) {
PrintErrString(progname,"Host Name lookup failed");
return(1);
}
/* should the third field really be 0? */
PR_EnumerateHostEnt(0,&hp,0,&na);
PR_InitializeNetAddr(PR_IpAddrNull,portnum,&na);
PR_fprintf(PR_STDOUT,"Connecting to %s:%d\n",hostname, portnum);
/* Create socket */
fd = PR_NewTCPSocket();
if (fd == NULL) {
PrintErrString(progname, "error creating socket");
return -1;
}
s = SSL_ImportFD(NULL,fd);
if (s == NULL) {
PrintErrString(progname, "error creating socket");
return -1;
}
/* Initialize all the libsec goodies */
SEC_Init();
dbmsg("10: About to enable security\n");
rv = SSL_Enable(s, SSL_SECURITY, 1);
if (rv < 0) {
PrintErrString(progname, "error enabling socket");
return -1;
}
if (set_ssl_policy) {
SetPolicy(set_ssl_policy,policy);
}
else {
PR_fprintf(PR_STDOUT,"Using all ciphersuites usually found in client\n");
if (policy) {
SetPolicy("abcdefghijklmnopqrst",policy);
}
else {
SetPolicy("efghijlmo",policy);
}
}
PrintCiphers(1);
rv = SSL_Enable(s, SSL_HANDSHAKE_AS_CLIENT, 1);
if (rv < 0) {
PrintErrString(progname, "error enabling client handshake");
return -1;
}
handle = (CERTCertDBHandle *)PORT_ZAlloc(sizeof(CERTCertDBHandle));
if (!handle) {
PrintErrString(progname, "could not allocate database handle");
return -1;
}
dbmsg("20: About to open certificate database\n");
/* Open up the certificate database */
rv = CERT_OpenCertDBFilename(handle, "cert7.db", PR_TRUE);
if ( rv ) {
PrintErrString(progname, "unable to open cert database");
rv = CERT_OpenVolatileCertDB(handle);
}
CERT_SetDefaultCertDB(handle);
dbmsg("30: About to set AuthCertificateHook\n");
SSL_AuthCertificateHook(s, MyAuthCertificateHook, (void *)handle);
/* SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle); */
/* SSL_GetClientAuthDataHook(s, GetClientAuthDataHook, (void *)nickname);*/
dbmsg("40: About to SSLConnect\n");
/* Try to connect to the server */
/* now SSL_Connect takes new arguments. */
r = PR_Connect(s, &na, PR_TicksPerSecond()*5);
if (r < 0) {
PrintErrString(progname, "unable to connect");
return -1;
}
rv = SSL_ForceHandshake(s);
if (rv) {
PrintErrString(progname,"SSL Handshake failed. ");
exit(1);
}
rv = SSL_SecurityStatus(s, &ss_on, &ss_cipher,
&ss_keysize, &ss_secretsize,
&ss_issuer, &ss_subject);
dbmsg("60: done with security status, about to print\n");
c = SSL_PeerCertificate(s);
if (!c) PR_fprintf(PR_STDOUT,"Couldn't retrieve peers Certificate\n");
PR_fprintf(PR_STDOUT,"SSL Connection Status\n",rv);
PR_fprintf(PR_STDOUT," Cipher: %s\n",ss_cipher);
PR_fprintf(PR_STDOUT," Key Size: %d\n",ss_keysize);
PR_fprintf(PR_STDOUT," Secret Key Size: %d\n",ss_secretsize);
PR_fprintf(PR_STDOUT," Issuer: %s\n",ss_issuer);
PR_fprintf(PR_STDOUT," Subject: %s\n",ss_subject);
PR_fprintf(PR_STDOUT," Valid: from %s to %s\n",
c==NULL?"???":DER_UTCDayToAscii(&c->validity.notBefore),
c==NULL?"???":DER_UTCDayToAscii(&c->validity.notAfter));
#ifdef SSLTELNET
if (servertype || querystring) {
char buffer[1024];
char ch;
char qs[] = "HEAD / HTTP/1.0";
if (!querystring) querystring = qs;
PR_fprintf(PR_STDOUT,"\nServer query mode\n>>Sending:\n%s\n",querystring);
PR_fprintf(PR_STDOUT,"\n*** Server said:\n");
ch = querystring[PL_strlen(querystring)-1];
if (ch == '"' || ch == '\'') {
PR_fprintf(PR_STDOUT,"Warning: I'm not smart enough to cope with quotes mid-string like that\n");
}
rv = PR_Write(s,querystring,PL_strlen(querystring));
if ((rv < 1) ) {
PR_fprintf(PR_STDOUT,"Oh dear - couldn't send servertype query\n");
goto closedown;
}
rv = PR_Write(s,"\r\n\r\n",4);
rv = PR_Read(s,buffer,1024);
if ((rv < 1) ) {
PR_fprintf(PR_STDOUT,"Oh dear - couldn't read server repsonse\n");
goto closedown;
}
PR_Write(PR_STDOUT,buffer,rv);
}
if (telnet) {
PR_fprintf(PR_STDOUT,"---------------------------\n"
"telnet mode. CTRL-C to exit\n"
"---------------------------\n");
/* fudge terminal attributes */
t_fin = PR_FileDesc2NativeHandle(PR_STDIN);
t_fout = PR_FileDesc2NativeHandle(PR_STDOUT);
tcgetattr(t_fin,&tmp_tc);
prev_lflag = tmp_tc.c_lflag;
prev_oflag = tmp_tc.c_oflag;
prev_iflag = tmp_tc.c_iflag;
tmp_tc.c_lflag &= ~ECHO;
/* tmp_tc.c_oflag &= ~ONLCR; */
tmp_tc.c_lflag &= ~ICANON;
tmp_tc.c_iflag &= ~ICRNL;
tmp_tc.c_cflag |= CS8;
tmp_tc.c_cc[VMIN] = 1;
tmp_tc.c_cc[VTIME] = 0;
tcsetattr(t_fin, TCSANOW, &tmp_tc);
/* ioctl(tin, FIONBIO, (char *)&onoff);
ioctl(tout, FIONBIO, (char *)&onoff);*/
{
PRPollDesc pds[2];
char buffer[1024];
int amt,amtwritten;
char *x;
/* STDIN */
pds[0].fd = PR_STDIN;
pds[0].in_flags = PR_POLL_READ;
pds[1].fd = s;
pds[1].in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
while (1) {
int nfds;
nfds = PR_Poll(pds,2,PR_SecondsToInterval(2));
if (nfds == 0) continue;
/** read input from keyboard*/
/* note: this is very inefficient if reading from a file */
if (pds[0].out_flags & PR_POLL_READ) {
amt = PR_Read(PR_STDIN,&buffer,1);
/* PR_fprintf(PR_STDOUT,"fd[0]:%d=%d\r\n",amt,buffer[0]); */
if (amt == 0) {
PR_fprintf(PR_STDOUT,"\n");
goto loser;
}
if (buffer[0] == '\r') {
buffer[0] = '\r';
buffer[1] = '\n';
amt = 2;
}
rv = PR_Write(PR_STDOUT,buffer,amt);
rv = PR_Write(s,buffer,amt);
if (rv == -1) {
PR_fprintf(PR_STDOUT,"Error writing to socket: %d\n",PR_GetError());
}
}
/***/
/***/
if (pds[1].out_flags & PR_POLL_EXCEPT) {
PR_fprintf(PR_STDOUT,"\r\nServer closed connection\r\n");
goto loser;
}
if (pds[1].out_flags & PR_POLL_READ) {
amt = PR_Read(s,&buffer,1024);
if (amt == 0) {
PR_fprintf(PR_STDOUT,"\r\nServer closed connection\r\n");
goto loser;
}
rv = PR_Write(PR_STDOUT,buffer,amt);
}
/***/
}
}
loser:
/* set terminal back to normal */
tcgetattr(t_fin,&tmp_tc);
tmp_tc.c_lflag = prev_lflag;
tmp_tc.c_oflag = prev_oflag;
tmp_tc.c_iflag = prev_iflag;
tcsetattr(t_fin, TCSANOW, &tmp_tc);
/* ioctl(tin, FIONBIO, (char *)&onoff);
ioctl(tout, FIONBIO, (char *)&onoff); */
}
#endif
/* SSLTELNET */
closedown:
PR_Close(s);
return(0);
} /* main */
/*EOF*/

View File

@ -0,0 +1,181 @@
#!/usr/bin/perl
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL"), in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your
# version of this file only under the terms of the GPL and not to
# allow others to use your version of this file under the MPL,
# indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient
# may use your version of this file under either the MPL or the
# GPL.
#
@profiles = (
# "host:port" "policy" "ciphers" "exp-cipher" "expkeysize"
[ "cfu:443", "export", "efijlmo", "RC4-40", "40" ],
[ "hbombsgi:448", "export", "efijlmo", "RC4-40", "40" ],
[ "hbombsgi:448", "domestic", "abcdefijklmo", "RC4", "128" ],
[ "gandalf:5666", "domestic", "abcdefijklmo", "RC4", "128" ],
[ "gandalf:5666", "export", "efijlmo", "RC4", "128" ],
[ "gandalf:5666", "domestic", "j", "3DES-EDE-CBC", "168" ],
[ "gandalf:5666", "domestic", "k", "DES-CBC", "56" ],
[ "gandalf:5666", "export", "l", "RC4-40", "40" ],
[ "gandalf:5666", "export", "efijlmo", "RC4", "128" ],
[ "hbombcfu:443", "export", "efijlmo", "RC4", "128" ],
);
$file = &filename;
open(HTML, ">$file.htm") || die"Cannot open html output file\n";
$mutversion = "";
$platform = $ARGV[0];
print HTML
"<HTML><HEAD>
<TITLE>ssl/sslstrength: Version: $mutversion Platform: $platform Run date mm/dd/yy</TITLE></HEAD><BODY>\n";
print HTML
"<TABLE BORDER=1><TR>
<TD><B>Test Case Number</B></TD>
<TD><B>Program</B></TD>
<TD><B>Description of Test Case</B></TD>
<TD><B>Start date/time<B></TD>
<TD><B>End date/time<B></TD>
<TD><B>PASS/FAIL</B></TD>
</TR>\n";
$countpass =0;
$countfail =0;
$testnum =0;
for $profile (@profiles) {
$testnum ++;
($host, $policy, $ciphers, $expcipher, $expkeysize) = @$profile;
$cmd = "./sslstrength $host policy=$policy ciphers=$ciphers";
$starttime = &datestring." ".&timestring;
print STDERR "$cmd\n";
open(PIPE, "$cmd|") || die "Cannot start sslstrength\n";
$cipher = "";
$keysize = "";
while (<PIPE>) {
chop;
if (/^ Cipher: *(.*)/) {
$cipher = $1;
}
if (/^ Secret Key Size: (.*)/) {
$keysize = $1;
}
}
close(PIPE);
$endtime = &datestring." ".&timestring;
if (( $? != 0) || ($cipher ne $expcipher) || ($keysize ne $expkeysize)) {
$countfail ++;
$passed =0;
}
else {
$countpass ++;
$passed =1;
}
print HTML
"<TR>
<TD><B>$testnum</B></TD>
<TD></TD>
<TD>$cmd</TD>
<TD>$starttime</TD>
<TD>$endtime</TD>
<TD><B>".($passed ? "PASS" : "<FONT COLOR=red>FAIL: return code =
c=$cipher, ec=$expcipher, s=$keysize, es=$expkeysize.</FONT>")."
</B></TD>
</TR>\n";
}
print HTML "</table>\n";
close(HTML);
open (SUM, ">$file.sum") ||die "couldn't open summary file for writing\n";
print SUM <<EOM;
[Status]
mut=SSL
mutversion=1.0
platform=$platform
pass=$countpass
fail=$countfail
knownFail=0
malformed=0
EOM
close(SUM);
sub timestring
{
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
my $string;
$string = sprintf "%2d:%02d:%02d",$hour, $min, $sec;
return $string;
}
sub datestring
{
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
my $string;
$string = sprintf "%d/%d/%2d",$mon+1, $mday+1, $year;
return $string;
}
sub filename
{
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
my $string;
$string = sprintf "%04d%02d%02d",$year+1900, $mon+1, $mday;
return $string;
}