⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslsniffer.c

📁 ssl sniffer源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    break;	case TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST:	    printf("Certificate request\n");	    ProcessCertificateRequest(cur_handshake_packet, ssl_conn);	    break;	case TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE:	    printf("Server hello done\n");	    break;	case TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY:	    printf("Certificate verify\n");	    break;	case TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE:	    printf("Client key exchange\n");	    ProcessTLSClientKeyExchange(cur_handshake_packet, ssl_conn);	    break;	case TLS_HANDSHAKE_TYPE_FINISHED:	    printf("Finished Handshake!\n");	    break;	default:	    printf("Can't recognise Handshake request type %d!\n",cur_handshake_packet[0]);	}		/* 	   pull out the content length of the handshake packet and add it to	   both the bytes processed and also the currentpacket pointer 	*/	handshake_packet_len = ThreeBytesToInt(&(cur_handshake_packet[1]));	bytes_processed += handshake_packet_len + TLS_HANDSHAKE_HEADER_SIZE;	cur_handshake_packet += handshake_packet_len + TLS_HANDSHAKE_HEADER_SIZE;	/* just for formatting reasons */ 	if(bytes_processed < total_bytes_to_process)	{	    printf("\n");	}    }}/*  Given the handshake packet containing the Client Hello message, this  processes it to obtain the protocol version, session ID and the list of   cipher suite that the client can use.*/static void ProcessTLSClientHello(char *buffer){    char *ptr; /* points at cipher suite */    short cipher_suite_len;    int i;        printf("From Client Hello -- ");    ptr = ProcessTLSHello(buffer);    memcpy(&cipher_suite_len, ptr, 2);    cipher_suite_len = ntohs(cipher_suite_len);    printf("Cipher suite length is %d bytes ... number of cipher suites %d\n",	   cipher_suite_len,cipher_suite_len / 2);        ptr += 2; /* advance over the length field of cipher suite */        printf("List of cipher suites are -- \n");    for(i = 0; i < cipher_suite_len; i += 2)            ProcessTLSCipherSuite(ptr[i], ptr[i + 1]);    }/*  Given the handshake packet containing either the ClientHello or ServerHello  message, it extracts the protocol version, the session ID which is   printed byte by byte in hex and returns the a pointer to the length field   of the cipher suite.*/static char *ProcessTLSHello(char *buffer){    char *temp, *ptr = buffer + TLS_HANDSHAKE_HEADER_SIZE;    int i;    unsigned int byte;        /* print out protocol version */    printf("Protocol Version %d.%d\n",(int)ptr[0],(int)ptr[1]);        ptr += SESSION_ID_OFFSET; /* skip over random and protocol version field */        /*        sesssion ID in a hello record is only max 32 bytes => need 1       byte session ID    */    printf("Length of session ID -- %d bytes\n",(int) (*ptr));        /*        nothing big enough to hold a number of 32 bytes so just iterate       over the chars and print them    */    printf("Session ID --\n  0x");        for(i = 0, temp = ptr + 1; i < *ptr; i++, temp++)    {	byte = 0;	memcpy(&byte, temp, 1);	printf("%2.2x",byte);    }    printf("\n");      /* skip over the number of bytes in the session ID field */    ptr += ((*ptr) + 1); /* now pointing at cipher suite */        return ptr;}/*  Given the handshake packet containing the Server Hello message, this  processes it to obtain the protocol version, session ID and the  cipher suite that is to be used.*/static voidProcessServerHello(char *buffer, ssl_connection *ssl_conn){    char *ptr;    printf("From Server Hello -- ");    ptr = ProcessTLSHello(buffer); /* points at cipher suite */    printf("Cipher Suite is -- \n");    ProcessTLSCipherSuite(ptr[0], ptr[1]);        DetermineTLSKeyExchangeAlgorithm(ptr[1], ssl_conn);}/*  Examines the bytes given and prints out the cipher suite that is  being used.*/static voidProcessTLSCipherSuite(char byte1,char byte2){    char *name;        if(byte1 == (char)0xff)    {	printf("  Hex Code:");	utl_PrintCharAsHex(byte1);	utl_PrintCharAsHex(byte2);	printf("\n  Type: Unknown Cipher Suite\n");	return;    }        /* done because 0x will only be prefixed to a non zero result. */    printf("  Hex Code:");    utl_PrintCharAsHex(byte1);    utl_PrintCharAsHex(byte2);    printf("\n  Type: ");        switch(byte2)    {    case 0x00: 	name = "No encryption"; 	break;    case 0x01: 	name = "RSA with hash function MD5"; 	break;    case 0x02: 	name = "RSA with SHA"; 	break;    case 0x03: 	name = "RSA EXPORT with 40 bit RC4 and hash function MD5";	break;    case 0x04: 	name = "RSA with 128 bit RC4 and hash function MD5";	break;    case 0x05: 	name = "RSA with 128 bit RC4 and hash function SHA";	break;    case 0x06: 	name = "RSA EXPORT with 40 bit RC2 in CBC mode and hash function MD5"; 	break;    case 0x07: 	name = "RSA with IDEA in CBC mode and hash function SHA";	break;    case 0x08:	name = "RSA EXPORT with 40 bit DES in CBC mode and hash function SHA"; 	break;    case 0x09:	name = "RSA with DES in CBC mode and hash function SHA";	break;    case 0x0A:	name = "RSA with 3DES EDE in CBC mode and hash function SHA";	break;    case 0x0B:	name = "DH DSS EXPORT with 40 bit DES in CBC mode and hash function SHA";	break;    case 0x0C:	name = "DH DSS with DES in CBC mode and hash function SHA";	break;    case 0x0D:	name = "DH DSS with 3DES EDE in CBC mode and hash function SHA";	break;    case 0x0E: 	name = "DH RSA EXPORT with 40 bit DES in CBC mode and hash function SHA";	break;    case 0x0F:	name = "DH RSA with DES in CBC mode and hash function SHA";	break;    case 0x10:	name = "DH RSA with 3DES EDE in CBC mode and hash function SHA";	break;    case 0x11: 	name = "DHE DSS EXPORT with 40 bit DES in CBC mode and hash function SHA";	break;    case 0x12:	name = "DHE DSS with DES in CBC mode and hash function SHA";	break;    case 0x13:	name = "DHE DSS with 3DES EDE in CBC mode and hash function SHA";	break;    case 0x14:	name = "RSA EXPORT with 40 bit DES in CBC mode and hash function SHA";	break;    case 0x15:	name = "DHE RSA with DES in CBC mode and hash function SHA";	break;    case 0x16:	name = "DHE RSA with 3DES EDE in CBC mode and hash function SHA";	break;    case 0x17:	name = "Anonymous DH EXPORT with 40 bit RC4 and hash function MD5";	break;    case 0x18:	name = "Anonymous DH with 128 bit RC4 and hash function MD5";	break;    case 0x19:	name = "Anonymous DH EXPORT with 40 bit DES in CBC mode and hash function SHA"; 	break;    case 0x1A:	name = "Anonymous DH with DES in CBC mode and hash function SHA";	break;    case 0x1B:	name = "Anonymous DH with 3DES EDE in CBC mode and hash function SHA"; 	break;	/* Elliptic Curve Cipher Suites */    case 0x34:	name = "Elliptic Curve DHE DSS and hash function SHA";	break;    case 0x36:	name = "Elliptic Curve DHE DSS with 128 bit RC4 and hash function SHA";	break;    case 0x37:	name = "Elliptic Curve DHE DSS with DES CBC and hash function SHA";	break;    case 0x38:	name = "Elliptic Curve DHE DSS with 3DES EDE CBC and hash function SHA";	break;    case 0x39:	name = "Elliptic Curve DHE DSS Export with 40 bit DES CBC and hash function SHA";	break;    case 0x40:	name = "Elliptic Curve DHE DSS Export with 40 bit RC4 and hash function SHA";	break;    case 0x60:	name = "RSA Export with 56 bit RC4 and hash function MD5";	break;    case 0x61:	name = "RSA Export with 56 bit RC2 CBC and hash function MD5";	break;    case 0x62:	name = "RSA Export with DES CBC and hash function SHA";	break;    case 0x63:	name = "DHE DSS Export with DES CBC and hash function SHA";      break;    case 0x64:	name = "RSA Export with 56 bit RC4 and hash function SHA";	break;    case 0x65:	name = "DHE DSS Export with 56 bit RC4 and hash function SHA";	break;    case 0x66:	name = "DHE DSS with 128 bit RC4 and hash function SHA";	break;    default: 	printf("Unknown Cipher Suite\n"); 	return;    }    printf("%s\n",name);    }/*  Determines if the algorithm is using DH or RSA and returns the value  through keyxchange_alg field of the ssl_conn struct.*/static voidDetermineTLSKeyExchangeAlgorithm(char byte1, ssl_connection *ssl_conn){  switch(byte1)    {    case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06:     case 0x07: case 0x08: case 0x09: case 0x0A: case 0x14:    case 0x60: case 0x61: case 0x62: case 0x64:       ssl_conn->keyxchange_alg = RSA; break;    case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10:    case 0x11: case 0x12: case 0x13:    case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1A:    case 0x1B:    case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:    case 0x40:    case 0x63: case 0x65: case 0x66:      ssl_conn->keyxchange_alg = DH; break;     default:      printf("Error: no such key exchange algorithm\n");    }}/*  processes the certificates that the server might send to the client.  uses code from the openssl library.  This should not be used for a SSLV2 certificate data because it  seems like V2 does not support cert chains.*/static voidProcessCertificateChain(char *buffer, ssl_connection *ssl_conn){    X509 *cert = NULL;    unsigned long nc, llen, l;    unsigned char *p,*d,*q;       /* from openssl, including naming conventions */    /* these pointers are different depending on what version of ssl */    if(ssl_conn->ssl_version == VERSION_TLS ||        ssl_conn->ssl_version == VERSION_SSL3)    {	d = p = (unsigned char *) (buffer + TLS_HANDSHAKE_HEADER_SIZE);    }    else    {	printf("    ERR Incorrect SSL version in record header for certificate.\n");        return;    }    n2l3(p, llen);        for (nc = 0; nc < llen; )    {	n2l3(p, l);	if ((l + nc + 3) > llen)	{	    printf("    ERR Certificate length mismatch\n"); 	    return;	}		q = p;		cert = d2i_X509(NULL, &q, l); /* grab the current cert */		if (cert == NULL)	{	    printf("    ERR Bad Certificate\n"); 	    return;	}	if (q != (p + l))	{	    printf("    ERR in Certificate Decode\n"); 	    return;	}		ProcessCertificate(cert);		cert = NULL;	nc += l + 3;	p = q;    }}/*  takes the X509 certificate and parses out the information into a  UTL_CERT_INFO struct. Taken from Dan Boneh's utl_cert.c*/static voidProcessCertificate(X509 *x){    UTL_CERT_INFO buf;    BIO *mem = NULL;    EVP_PKEY *key;        if ((mem=BIO_new(BIO_s_mem())) == NULL)    {	printf("ERR Unable to create new BIO\n");	return;    }        /* Extract and process validity periods */    ASN1_UTCTIME_print(mem, X509_get_notAfter(x));    BIO_gets(mem, buf.notAfter, sizeof(buf.notAfter));    ASN1_UTCTIME_print(mem, X509_get_notBefore(x));    BIO_gets(mem, buf.notBefore, sizeof(buf.notBefore));        /* Extract and process subject name */    buf.subj = X509_get_subject_name(x);    X509_NAME_oneline(buf.subj,		      buf.subj_DistName, sizeof(buf.subj_DistName) );        /* Extract and process issuer name */    buf.issuer = X509_get_issuer_name(x);    X509_NAME_oneline(buf.issuer,		      buf.issuer_DistName, sizeof(buf.issuer_DistName) );        /* get the key size */    key = X509_get_pubkey(x);        PrintCertificateInfo(&buf,key);        BIO_free(mem);    EVP_PKEY_free(key);    }/*  takes the info from utl_cert_info and prints out the info.   also prints out the key size and type of key exchange mechanism.  key handling taken from Dan Boneh's utl_cert.c*/static voidPrintCertificateInfo(UTL_CERT_INFO *buf, EVP_PKEY *key){    printf("  CERTIFICATE INFORMATION :- \n");    printf("  Validity -- Not After  %s\n",buf->notAfter);    printf("              Not Before %s\n",buf->notBefore);    printf("  Subject Distinguished Name -- \n    %s\n",buf->subj_DistName);    printf("  Issuer Distinguished Name  -- \n    %s\n",buf->issuer_DistName);        if (key == NULL) return;        switch (key->type)     {    case EVP_PKEY_RSA:	buf->keysize = RSA_size(key->pkey.rsa)*8;	printf("  RSA Public key size %d bits\n\n",buf->keysize);	break;          case EVP_PKEY_DSA:	buf->keysize = DSA_size(key->pkey.dsa)*8;	printf("  DSS Public key size %d bits\n\n",buf->keysize);	break;    default:	printf("  Unknown key type\n\n");    }}/*  prints out the types of certificates requested. At present just  dumps out the distinguished names of the CA as a string.*/static void ProcessCertificateRequest(char *buffer, ssl_connection *ssl_conn){    char *data = buffer + TLS_HANDSHAKE_HEADER_SIZE;    char *temp;    unsigned int cert_type_len = 0;    int i;      unsigned int len = ThreeBytesToInt(buffer + 1);    printf("Types of certificates requested --\n");    memcpy(&cert_type_len, data, 1);        for(i = 0, data++; i < cert_type_len; i++, data++)    {        switch(*data)	{	case 1:	    printf("\tRSA certificate\n"); 	    break;	  	case 2:	    printf("\tDSS certificate\n"); 	    break;	case 3:	    printf("\tRSA certificate with fixed DH parameters\n"); 	    break;	case 4:	    printf("\tDSS certificate with fixed DH parameters\n"); 	    break;	default:	    printf("\tUnknown certificate requested\n"); 	    break;	}    }      /* print out the distinguished names of the CA */    len -= cert_type_len;    temp = (char *) utl_GetMem(len + 1);    memcpy(temp, data, len);    temp[len] = '\0';    printf("Distinguished Names of CA's -- %s", temp);        free(temp);  }/*  processes the server key exchange to obtain the parameters.   depending on whether the algorithm is RSA or DSS, different  params will be printed out.*/static void ProcessTLSServerKeyExchange(char *buffer, ssl_connection *ssl_conn){    char *data = buffer + TLS_HANDSHAKE_HEADER_SIZE;    switch(ssl_conn->keyxchange_alg)    {    case RSA:	data = ExtractParams(data, "RSA Modulus");	ExtractParams(data, "RSA Exponent");	break;    case DH:	data = ExtractParams(data, "DH Prime Modulus p");	data = ExtractParams(data, "DH Generator g");	data = ExtractParams(data, "DH public value (g^X mod p)");	break;    }}/*  prints out the data in hex of the parameters. assumes that the length  of the data is given by the first 2 bytes.*/static char *ExtractParams(char *params, char *type){    unsigned short param_len = TwoBytesToInt(params);    char *start = params;    int i;      unsigned int byte;        printf("Length of %s -- %d\n", type, param_len);    printf("%s --\n  0x",type);    /* skip over two byte length field */    for(i = 0, params += 2; i < param_len; i++, params++)    {	byte = 0; memcpy(&byte, params, 1);	printf("%2.2x", byte);		    }    printf("\n");     return (start + 2 + param_len);}/*  Using the keyxchange_alg field of the ssl_conn passed in, will  process and print out the appropriate information. For RSA, prints  out the RSA encrypted premaster secret and for DH, prints out the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -