ssltap.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,340 行 · 第 1/3 页

C
1,340
字号
    serverstream.isEncrypted = 1;    }    break;  case 3:    PR_fprintf(PR_STDOUT," [ssl2]  Client Finished V2 {...}\n");    isV2Session = 1;    break;  case 4:  /* V2 Server Hello */    isV2Session = 1;    PR_fprintf(PR_STDOUT," [ssl2]  ServerHelloV2 {\n");    PR_fprintf(PR_STDOUT,"           sid hit = {0x%02x}\n",	       (PRUintn)shv2->sidhit);    PR_fprintf(PR_STDOUT,"           version = {0x%02x, 0x%02x}\n",	       (PRUint32)shv2->version[0],(PRUint32)shv2->version[1]);    PR_fprintf(PR_STDOUT,"           cipher-specs-length = %d (0x%02x)\n",	       (PRUint32)(GET_SHORT((shv2->cslength))),	       (PRUint32)(GET_SHORT((shv2->cslength))));    PR_fprintf(PR_STDOUT,"           sid-length = %d (0x%02x)\n",	       (PRUint32)(GET_SHORT((shv2->cidlength))),	       (PRUint32)(GET_SHORT((shv2->cidlength))));    pos = (unsigned char *)shv2;    pos += 2;   /* skip length header */    pos += 11;  /* position pointer to Certificate data area */    q = GET_SHORT(&shv2->certlength);    if (q >alloclen) {      goto eosh;    }    pos += q; 			/* skip certificate */    PR_fprintf(PR_STDOUT,"           cipher-suites = { ");    len = GET_SHORT((shv2->cslength));    for (p = 0; p < len; p += 3) {      const char *cs_str=NULL;      PRUint32 cs_int=0;      cs_int = GET_24((pos+p));      cs_str = V2CipherString(cs_int);      PR_fprintf(PR_STDOUT,"\n              ");      PR_fprintf(PR_STDOUT,"(0x%06x) %s", cs_int, cs_str);    }    pos += len;    PR_fprintf(PR_STDOUT,"   }\n");	/* End of cipher suites */    len = (PRUint32)GET_SHORT((shv2->cidlength));    if (len) {      PR_fprintf(PR_STDOUT,"           connection-id = { ");      for (p = 0; p < len; p += 2) {	PR_fprintf(PR_STDOUT,"0x%04x ", (PRUint32)(GET_SHORT((pos + p))));      }      PR_fprintf(PR_STDOUT,"   }\n");	/* End of connection id */    }eosh:    PR_fprintf(PR_STDOUT,"\n              }\n"); /* end of ServerHelloV2 */    if (shv2->sidhit) {      clientstream.isEncrypted = 1;      serverstream.isEncrypted = 1;    }    break;  case 5:    PR_fprintf(PR_STDOUT," [ssl2]  Server Verify V2 {...}\n");    isV2Session = 1;    break;  case 6:    PR_fprintf(PR_STDOUT," [ssl2]  Server Finished V2 {...}\n");    isV2Session = 1;    break;  case 7:    PR_fprintf(PR_STDOUT," [ssl2]  Request Certificate V2 {...}\n");    isV2Session = 1;    break;  case 8:    PR_fprintf(PR_STDOUT," [ssl2]  Client Certificate V2 {...}\n");    isV2Session = 1;    break;  default:    PR_fprintf(PR_STDOUT," [ssl2]  UnknownType 0x%02x {...}\n",	  (PRUint32)chv2->type);    break;  }}void print_ssl3_handshake(unsigned char *tbuf,                           unsigned int   alloclen,                          SSLRecord *    sr){  struct sslhandshake sslh;   unsigned char *     hsdata;    int                 offset=0;  PR_fprintf(PR_STDOUT,"   handshake {\n");  while (offset < alloclen) {    sslh.type = tbuf[offset];     sslh.length = GET_24(tbuf+offset+1);    hsdata= &tbuf[offset+4];    if (sslhexparse) print_hex(4,tbuf+offset);    PR_fprintf(PR_STDOUT,"      type = %d (",sslh.type);    switch(sslh.type) {    case 0:  PR_fprintf(PR_STDOUT,"hello_request)\n");   break;    case 1:  PR_fprintf(PR_STDOUT,"client_hello)\n");    break;    case 2:  PR_fprintf(PR_STDOUT,"server_hello)\n");    break;    case 11: PR_fprintf(PR_STDOUT,"certificate)\n");     break;    case 12: PR_fprintf(PR_STDOUT,"server_key_exchange)\n");  break;    case 13: PR_fprintf(PR_STDOUT,"certificate_request)\n");  break;    case 14: PR_fprintf(PR_STDOUT,"server_hello_done)\n");    break;    case 15: PR_fprintf(PR_STDOUT,"certificate_verify)\n");   break;    case 16: PR_fprintf(PR_STDOUT,"client_key_exchange)\n");  break;    case 20: PR_fprintf(PR_STDOUT,"finished)\n");         break;    default: PR_fprintf(PR_STDOUT,"unknown)\n");    }    PR_fprintf(PR_STDOUT,"      length = %d (0x%06x)\n",sslh.length,sslh.length);    switch (sslh.type) {    case 1: /* client hello */      switch (sr->ver_maj)  {      case 2:  /* ssl version 2 */	PR_fprintf(PR_STDOUT,"         ClientHelloV2 {...}\n");	break;      case 3:  /* ssl version 3 */	{	  int sidlength,pos,csuitelength,w;	  PR_fprintf(PR_STDOUT,"         ClientHelloV3 {\n");	  PR_fprintf(PR_STDOUT,"            client_version = {%d, %d}\n",		     (PRUint8)hsdata[0],(PRUint8)hsdata[1]);	  PR_fprintf(PR_STDOUT,"            random = {...}\n");	  if (sslhexparse) print_hex(32,&hsdata[2]);	  PR_fprintf(PR_STDOUT,"            session ID = {\n");	  sidlength = (int)hsdata[2+32];	  PR_fprintf(PR_STDOUT,"                length = %d\n",sidlength);	  PR_fprintf(PR_STDOUT,"                contents = {..}\n");	  if (sslhexparse) print_hex(sidlength,&hsdata[2+32+1]);	  PR_fprintf(PR_STDOUT,"            }\n");	  pos = 2+32+1+sidlength;	  csuitelength = GET_SHORT((hsdata+pos));	  PR_fprintf(PR_STDOUT,"            cipher_suites[%d] = { \n",		     csuitelength/2);	  if (csuitelength%1) {	    PR_fprintf(PR_STDOUT,	       "*error in protocol - csuitelength shouldn't be odd*\n");	  }	  for (w=0; w<csuitelength; w+=2) {	    const char *cs_str=NULL;	    PRUint32 cs_int=0;	    cs_int = GET_SHORT((hsdata+pos+2+w));	    cs_str = V2CipherString(cs_int);	    PR_fprintf(PR_STDOUT,	      "                (0x%04x) %s\n", cs_int, cs_str);	  }	  /*		  for (w=0;w<csuitelength;w+=2) {	    PR_fprintf(PR_STDOUT,"0x%04x ",GET_SHORT((hsdata+pos+2+w)));	  } */	  PR_fprintf(PR_STDOUT,"\n               }\n");	  PR_fprintf(PR_STDOUT,"         }\n");	} /* end of ssl version 3 */	break;      default:	PR_fprintf(PR_STDOUT,"           ClientHelloUndefinedVersion{}\n");      } /* end of switch sr->ver_maj */      break;    case 2: /* server hello */      {	int sidlength, pos;	const char *cs_str=NULL;	PRUint32 cs_int=0;	PR_fprintf(PR_STDOUT,"         ServerHello {\n");	PR_fprintf(PR_STDOUT,"            server_version = {%d, %d}\n",		   (PRUint8)hsdata[0],(PRUint8)hsdata[1]);	PR_fprintf(PR_STDOUT,"            random = {...}\n");	if (sslhexparse) print_hex(32,&hsdata[2]);	PR_fprintf(PR_STDOUT,"            session ID = {\n");	sidlength = (int)hsdata[2+32];	PR_fprintf(PR_STDOUT,"                length = %d\n",sidlength);	PR_fprintf(PR_STDOUT,"                contents = {..}\n");	if (sslhexparse) print_hex(sidlength,&hsdata[2+32+1]);	PR_fprintf(PR_STDOUT,"            }\n");	pos = 2+32+1+sidlength;	cs_int = GET_SHORT((hsdata+pos));	cs_str = V2CipherString(cs_int);	PR_fprintf(PR_STDOUT,"            cipher_suite = (0x%04x) %s\n",		   cs_int, cs_str);	PR_fprintf(PR_STDOUT,"         }\n");      }      break;    case 11: /* certificate */      {	PRFileDesc *cfd;	int         pos;	int         certslength;	int         certlength;	int         certbytesread	= 0;	static int  certFileNumber;	char        certFileName[20];	PR_fprintf(PR_STDOUT,"         CertificateChain {\n");	certslength = GET_24(hsdata);	PR_fprintf(PR_STDOUT,"            chainlength = %d (0x%04x)\n",		certslength,certslength);	pos = 3;	while (certbytesread < certslength) {	  certlength = GET_24((hsdata+pos));	  pos += 3;	  PR_fprintf(PR_STDOUT,"            Certificate {\n");	  PR_fprintf(PR_STDOUT,"               size = %d (0x%04x)\n",		certlength,certlength);	  PR_snprintf(certFileName, sizeof certFileName, "cert.%03d",	              ++certFileNumber);	  cfd = PR_Open(certFileName, PR_WRONLY|PR_CREATE_FILE, 0664);	  if (!cfd) {	    PR_fprintf(PR_STDOUT,	               "               data = { couldn't save file '%s' }\n",		       certFileName);	  } else {	    PR_Write(cfd, (hsdata+pos), certlength);	    PR_fprintf(PR_STDOUT,	               "               data = { saved in file '%s' }\n",		       certFileName);	    PR_Close(cfd);	  }	  PR_fprintf(PR_STDOUT,"            }\n");	  pos           += certlength;	  certbytesread += certlength+3;	}	PR_fprintf(PR_STDOUT,"         }\n");      }      break;    case 13: /* certificate request */      if (sslhexparse) { 	PR_fprintf(PR_STDOUT,"         CertificateRequest {\n");        print_hex(sslh.length, hsdata);	PR_fprintf(PR_STDOUT,"         }\n");      }      break;    case 16: /* client key exchange */      {	PR_fprintf(PR_STDOUT,"         ClientKeyExchange {\n");	PR_fprintf(PR_STDOUT,"            message = {...}\n");	PR_fprintf(PR_STDOUT,"         }\n");      }      break;    }  /* end of switch sslh.type */    offset += sslh.length + 4; /* +4 because of length (3 bytes) and type (1 byte) */  } /* while */  PR_fprintf(PR_STDOUT,"   }\n");}void print_ssl(DataBufferList *s, int length, unsigned char *buffer){  /* --------------------------------------------------------  */  /* first, create a new buffer object for this piece of data. */  DataBuffer *db;  int i,l;  if (s->size == 0 && length > 0 && buffer[0] >= 32 && buffer[0] < 128) {    /* Not an SSL record, treat entire buffer as plaintext */    PR_Write(PR_STDOUT,buffer,length);    return;  }  check_integrity(s);  i = 0;  l = length;  db = PR_NEW(struct _DataBuffer);  db->buffer = (unsigned char*)PR_Malloc(length);  db->length = length;  db->offset = 0;  memcpy(db->buffer, buffer, length);  db->next = NULL;  /* now, add it to the stream */  if (s->last != NULL) s->last->next = db;  s->last = db;  s->size += length;  if (s->first == NULL) s->first = db;  check_integrity(s);  /*------------------------------------------------------- */  /* now we look at the stream to see if we have enough data to     decode  */  while (s->size > 0 ) {    unsigned char *tbuf = NULL;    SSLRecord sr;    unsigned alloclen;    unsigned recordsize;    check_integrity(s);    if ( s->first == NULL) {      PR_fprintf(PR_STDOUT,"ERROR: s->first is null\n");      exit(9);    }    /* in the case of an SSL 2 client-hello (which is all ssltap supports) */    /* will have the high-bit set, whereas an SSL 3 client-hello will not  */    /* SSL2 can also send records that begin with the high bit clear.     * This code will incorrectly handle them. XXX     */    if (isV2Session || s->first->buffer[s->first->offset] & 0x80) {      /* it's an SSL 2 packet */      unsigned char lenbuf[3];      /* first, we check if there's enough data for it to be an SSL2-type       * record.  What a pain.*/      if (s->size < sizeof lenbuf) {	partial_packet(length, s->size, sizeof lenbuf);	return;      }      /* read the first two bytes off the stream. */      read_stream_bytes(lenbuf, s, sizeof(lenbuf));      alloclen = ((unsigned int)(lenbuf[0] & 0x7f) << 8) + lenbuf[1] +                  ((lenbuf[0] & 0x80) ? 2 : 3);      PR_fprintf(PR_STDOUT, "alloclen = %u bytes\n", alloclen);      /* put 'em back on the head of the stream. */      db = PR_NEW(struct _DataBuffer);      db->length = sizeof lenbuf;      db->buffer = (unsigned char*) PR_Malloc(db->length);      db->offset = 0;      memcpy(db->buffer, lenbuf, sizeof lenbuf);      db->next = s->first;      s->first = db;      if (s->last == NULL) 	s->last = db;      s->size += db->length;      /* if there wasn't enough, go back for more. */      if (s->size < alloclen) {	check_integrity(s);	partial_packet(length, s->size, alloclen);	return;      }      partial_packet(length, s->size, alloclen);      /* read in the whole record. */      tbuf = PR_Malloc(alloclen);      read_stream_bytes(tbuf, s, alloclen);      print_sslv2(s, tbuf, alloclen);      PR_FREEIF(tbuf);      check_integrity(s);      continue;    }    /***********************************************************/    /* It's SSL v3 */    /***********************************************************/    check_integrity(s);    if (s->size < sizeof(SSLRecord)) {      partial_packet(length, s->size, sizeof(SSLRecord));      return;    }    read_stream_bytes((unsigned char *)&sr, s, sizeof sr);    /* we have read the stream bytes. Look at the length of       the ssl record. If we don't have enough data to satisfy this       request, then put the bytes we just took back at the head       of the queue */    recordsize = GET_SHORT(sr.length);    if (recordsize > s->size) {      db = PR_NEW(struct _DataBuffer);      db->length = sizeof sr;      db->buffer = (unsigned char*) PR_Malloc(db->length);      db->offset = 0;      memcpy(db->buffer, &sr, sizeof sr);      db->next = s->first;      /* now, add it back on to the head of the stream */      s->first = db;      if (s->last == NULL)         s->last = db;      s->size += db->length;      check_integrity(s);      partial_packet(length, s->size, recordsize);      return;    }    partial_packet(length, s->size, recordsize);    PR_fprintf(PR_STDOUT,"SSLRecord { [%s]\n", get_time_string() );    if (sslhexparse) {      print_hex(5,(unsigned char*)&sr);    }    check_integrity(s);    PR_fprintf(PR_STDOUT,"   type    = %d (",sr.type);    switch(sr.type) {    case 20 :      PR_fprintf(PR_STDOUT,"change_cipher_spec)\n");      break;    case 21 :      PR_fprintf(PR_STDOUT,"alert)\n");      break;    case 22 :      PR_fprintf(PR_STDOUT,"handshake)\n");

⌨️ 快捷键说明

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