ssltap.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,340 行 · 第 1/3 页
C
1,340 行
/* * 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. *//* * ssltap.c * * Version 1.0 : Frederick Roeber : 11 June 1997 * Version 2.0 : Steve Parkinson : 13 November 1997 * Version 3.0 : Nelson Bolyard : 22 July 1998 * Version 3.1 : Nelson Bolyard : 24 May 1999 * * changes in version 2.0: * Uses NSPR20 * Shows structure of SSL negotiation, if enabled. * * This "proxies" a socket connection (like a socks tunnel), but displays the * data is it flies by. * * In the code, the 'client' socket is the one on the client side of the * proxy, and the server socket is on the server side. * */#include "nspr.h"#include "plstr.h"#include "secutil.h"#include <memory.h> /* for memcpy, etc. */#include <string.h>#include <time.h>#include "plgetopt.h"#define VERSIONSTRING "$Revision: 1.1 $ ($Date: 2000/03/31 20:12:54 $) $Author: relyea%netscape.com $"struct _DataBufferList;struct _DataBuffer;typedef struct _DataBufferList { struct _DataBuffer *first,*last; int size; int isEncrypted;} DataBufferList;typedef struct _DataBuffer { unsigned char *buffer; int length; int offset; /* offset of first good byte */ struct _DataBuffer *next;} DataBuffer;DataBufferList clientstream = {NULL, NULL, 0, 0}, serverstream = {NULL, NULL, 0, 0};struct sslhandshake { PRUint8 type; PRUint32 length;};typedef struct _SSLRecord { PRUint8 type; PRUint8 ver_maj,ver_min; PRUint8 length[2];} SSLRecord;typedef struct _ClientHelloV2 { PRUint8 length[2]; PRUint8 type; PRUint8 version[2]; PRUint8 cslength[2]; PRUint8 sidlength[2]; PRUint8 rndlength[2]; PRUint8 csuites[1];} ClientHelloV2;typedef struct _ServerHelloV2 { PRUint8 length[2]; PRUint8 type; PRUint8 sidhit; PRUint8 certtype; PRUint8 version[2]; PRUint8 certlength[2]; PRUint8 cslength[2]; PRUint8 cidlength[2];} ServerHelloV2;typedef struct _ClientMasterKeyV2 { PRUint8 length[2]; PRUint8 type; PRUint8 cipherkind[3]; PRUint8 clearkey[2]; PRUint8 secretkey[2];} ClientMasterKeyV2;#define TAPBUFSIZ 16384#define DEFPORT 1924#include <ctype.h>int hexparse=0;int sslparse=0;int sslhexparse=0;int looparound=0;int fancy=0;int isV2Session=0;#define GET_SHORT(x) ((PRUint16)(((PRUint16)((PRUint8*)x)[0]) << 8) + ((PRUint16)((PRUint8*)x)[1]))#define GET_24(x) ((PRUint32) ( \ (((PRUint32)((PRUint8*)x)[0]) << 16) \ + \ (((PRUint32)((PRUint8*)x)[1]) << 8) \ + \ (((PRUint32)((PRUint8*)x)[2]) << 0) \ ) )void print_hex(int amt, unsigned char *buf);void read_stream_bytes(unsigned char *d, DataBufferList *db, int length);void myhalt(int dblsize,int collectedsize) { while(1) ;}const char *get_error_text(int error) { switch (error) { case PR_IO_TIMEOUT_ERROR: return "Timeout"; break; case PR_CONNECT_REFUSED_ERROR: return "Connection refused"; break; case PR_NETWORK_UNREACHABLE_ERROR: return "Network unreachable"; break; case PR_BAD_ADDRESS_ERROR: return "Bad address"; break; case PR_CONNECT_RESET_ERROR: return "Connection reset"; break; case PR_PIPE_ERROR: return "Pipe error"; break; } return "";}void check_integrity(DataBufferList *dbl) { DataBuffer *db; int i; db = dbl->first; i =0; while (db) { i+= db->length - db->offset; db = db->next; } if (i != dbl->size) { myhalt(dbl->size,i); }}/* Free's the DataBuffer at the head of the list and returns the pointer * to the new head of the list. */DataBuffer * free_head(DataBufferList *dbl){ DataBuffer *db = dbl->first; PR_ASSERT(db->offset >= db->length); if (db->offset >= db->length) { dbl->first = db->next; if (dbl->first == NULL) { dbl->last = NULL; } PR_Free(db->buffer); PR_Free(db); db = dbl->first; } return db;}void read_stream_bytes(unsigned char *d, DataBufferList *dbl, int length) { int copied = 0; DataBuffer *db = dbl->first; if (!db) { PR_fprintf(PR_STDERR,"assert failed - dbl->first is null\n"); exit(8); } while (length) { int toCopy; /* find the number of bytes to copy from the head buffer */ /* if there's too many in this buffer, then only copy 'length' */ toCopy = PR_MIN(db->length - db->offset, length); memcpy(d + copied, db->buffer + db->offset, toCopy); copied += toCopy; db->offset += toCopy; length -= toCopy; dbl->size -= toCopy; /* if we emptied the head buffer */ if (db->offset >= db->length) { db = free_head(dbl); } } check_integrity(dbl);}voidflush_stream(DataBufferList *dbl){ DataBuffer *db = dbl->first; check_integrity(dbl); while (db) { db->offset = db->length; db = free_head(dbl); } dbl->size = 0; check_integrity(dbl);}const char * V2CipherString(int cs_int) { char *cs_str; cs_str = NULL; switch (cs_int) { case 0x010080: cs_str = "SSL2/RSA/RC4-128/MD5"; break; case 0x020080: cs_str = "SSL2/RSA/RC4-40/MD5"; break; case 0x030080: cs_str = "SSL2/RSA/RC2CBC128/MD5"; break; case 0x040080: cs_str = "SSL2/RSA/RC2CBC40/MD5"; break; case 0x050080: cs_str = "SSL2/RSA/IDEA128CBC/MD5"; break; case 0x060040: cs_str = "SSL2/RSA/DES56-CBC/MD5"; break; case 0x0700C0: cs_str = "SSL2/RSA/3DES192EDE-CBC/MD5"; break; case 0x000001: cs_str = "SSL3/RSA/NULL/MD5"; break; case 0x000002: cs_str = "SSL3/RSA/NULL/SHA"; break; case 0x000003: cs_str = "SSL3/RSA/RC4-40/MD5"; break; case 0x000004: cs_str = "SSL3/RSA/RC4-128/MD5"; break; case 0x000005: cs_str = "SSL3/RSA/RC4-128/SHA"; break; case 0x000006: cs_str = "SSL3/RSA/RC2CBC40/MD5"; break; case 0x000007: cs_str = "SSL3/RSA/IDEA128CBC/SHA"; break; case 0x000008: cs_str = "SSL3/RSA/DES40-CBC/SHA"; break; case 0x000009: cs_str = "SSL3/RSA/DES56-CBC/SHA"; break; case 0x00000A: cs_str = "SSL3/RSA/3DES192EDE-CBC/SHA"; break; case 0x00000B: cs_str = "SSL3/DH-DSS/DES40-CBC/SHA"; break; case 0x00000C: cs_str = "SSL3/DH_DSS/DES56-CBC/SHA"; break; case 0x00000D: cs_str = "SSL3/DH-DSS/DES192EDE3CBC/SHA"; break; case 0x00000E: cs_str = "SSL3/DH-RSA/DES40-CBC/SHA"; break; case 0x00000F: cs_str = "SSL3/DH_RSA/DES56-CBC/SHA"; break; case 0x000010: cs_str = "SSL3/DH-RSA/3DES192EDE-CBC/SHA"; break; case 0x000011: cs_str = "SSL3/DHE-DSS/DES40-CBC/SHA"; break; case 0x000012: cs_str = "SSL3/DHE_DSS/DES56-CBC/SHA"; break; case 0x000013: cs_str = "SSL3/DHE-DSS/DES192EDE3CBC/SHA"; break; case 0x000014: cs_str = "SSL3/DHE-RSA/DES40-CBC/SHA"; break; case 0x000015: cs_str = "SSL3/DHE_RSA/DES56-CBC/SHA"; break; case 0x000016: cs_str = "SSL3/DHE-RSA/3DES192EDE-CBC/SHA"; break; case 0x000017: cs_str = "SSL3/DH-anon/RC4-40/MD5"; break; case 0x000018: cs_str = "SSL3/DH-anon/RC4-128/MD5"; break; case 0x000019: cs_str = "SSL3/DH-anon/DES40-CBC/SHA"; break; case 0x00001A: cs_str = "SSL3/DH-anon/DES56-CBC/SHA"; break; case 0x00001B: cs_str = "SSL3/DH-anon/3DES192EDE-CBC/SHA"; break; case 0x00001C: cs_str = "SSL3/FORTEZZA-DMS/NULL/SHA"; break; case 0x00001D: cs_str = "SSL3/FORTEZZA-DMS/FORTEZZA-CBC/SHA"; break; case 0x00001E: cs_str = "SSL3/FORTEZZA-DMS/RC4-128/SHA"; break; case 0x000062: cs_str = "TLS/RSA_EXPORT1024/DES56_CBC/SHA"; break; case 0x000064: cs_str = "TLS/RSA_EXPORT1024/RC4-56/SHA"; break; case 0x000063: cs_str = "TLS/DHE-DSS_EXPORT1024/DES56-CBC/SHA"; break; case 0x000065: cs_str = "TLS/DHE-DSS_EXPORT1024/RC4-56/SHA"; break; case 0x000066: cs_str = "TLS/DHE-DSS/RC4-128/SHA"; break; case 0x00ffe1: cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA"; break; case 0x00ffe0: cs_str = "SSL3/RSA-FIPS/3DES192EDE-CBC/SHA"; break; default: cs_str = "????/????????/?????????/???"; break; } return cs_str;}void partial_packet(int thispacket, int size, int needed){ PR_fprintf(PR_STDOUT,"(%u bytes", thispacket); if (thispacket < needed) { PR_fprintf(PR_STDOUT,", making %u", size); } PR_fprintf(PR_STDOUT," of %u", needed); if (size > needed) { PR_fprintf(PR_STDOUT,", with %u left over", size - needed); } PR_fprintf(PR_STDOUT,")\n");}char * get_time_string(void){ struct tm *tm; char *cp; char *eol; time_t tt; time(&tt);#if 0 tm = localtime(&tt); cp = asctime(tm);#else cp = ctime(&tt);#endif eol = strchr(cp, '\n'); if (eol) *eol = 0; return cp;}void print_sslv2(DataBufferList *s, unsigned char *tbuf, unsigned int alloclen){ ClientHelloV2 *chv2; ServerHelloV2 *shv2; unsigned char *pos; unsigned int p; unsigned int q; PRUint32 len; chv2 = (ClientHelloV2 *)tbuf; shv2 = (ServerHelloV2 *)tbuf; if (s->isEncrypted) { PR_fprintf(PR_STDOUT," [ssl2] Encrypted {...}\n"); return; } PR_fprintf(PR_STDOUT," [%s]", get_time_string() ); switch(chv2->type) { case 1: PR_fprintf(PR_STDOUT," [ssl2] ClientHelloV2 {\n"); PR_fprintf(PR_STDOUT," version = {0x%02x, 0x%02x}\n", (PRUint32)chv2->version[0],(PRUint32)chv2->version[1]); PR_fprintf(PR_STDOUT," cipher-specs-length = %d (0x%02x)\n", (PRUint32)(GET_SHORT((chv2->cslength))), (PRUint32)(GET_SHORT((chv2->cslength)))); PR_fprintf(PR_STDOUT," sid-length = %d (0x%02x)\n", (PRUint32)(GET_SHORT((chv2->sidlength))), (PRUint32)(GET_SHORT((chv2->sidlength)))); PR_fprintf(PR_STDOUT," challenge-length = %d (0x%02x)\n", (PRUint32)(GET_SHORT((chv2->rndlength))), (PRUint32)(GET_SHORT((chv2->rndlength)))); PR_fprintf(PR_STDOUT," cipher-suites = { \n"); for (p=0;p<GET_SHORT((chv2->cslength));p+=3) { const char *cs_str=NULL; PRUint32 cs_int=0; cs_int = GET_24((&chv2->csuites[p])); cs_str = V2CipherString(cs_int); PR_fprintf(PR_STDOUT," (0x%06x) %s\n", cs_int, cs_str); } q = p; PR_fprintf(PR_STDOUT," }\n"); if (chv2->sidlength) { PR_fprintf(PR_STDOUT," session-id = { "); for (p=0;p<GET_SHORT((chv2->sidlength));p+=2) { PR_fprintf(PR_STDOUT,"0x%04x ",(PRUint32)(GET_SHORT((&chv2->csuites[p+q])))); } } q += p; PR_fprintf(PR_STDOUT,"}\n"); if (chv2->rndlength) { PR_fprintf(PR_STDOUT," challenge = { "); for (p=0;p<GET_SHORT((chv2->rndlength));p+=2) { PR_fprintf(PR_STDOUT,"0x%04x ",(PRUint32)(GET_SHORT((&chv2->csuites[p+q])))); } PR_fprintf(PR_STDOUT,"}\n"); } PR_fprintf(PR_STDOUT,"}\n"); break; /* end of V2 CLientHello Parsing */ case 2: /* Client Master Key */ { const char *cs_str=NULL; PRUint32 cs_int=0; ClientMasterKeyV2 *cmkv2; cmkv2 = (ClientMasterKeyV2 *)chv2; isV2Session = 1; PR_fprintf(PR_STDOUT," [ssl2] ClientMasterKeyV2 { \n"); cs_int = GET_24(&cmkv2->cipherkind[0]); cs_str = V2CipherString(cs_int); PR_fprintf(PR_STDOUT," cipher-spec-chosen = (0x%06x) %s\n", cs_int, cs_str); PR_fprintf(PR_STDOUT," clear-portion = %d bits\n", 8*(PRUint32)(GET_SHORT((cmkv2->clearkey)))); PR_fprintf(PR_STDOUT," }\n"); clientstream.isEncrypted = 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?