diff options
author | Bill Fenner <fenner@FreeBSD.org> | 2002-06-21 00:43:23 +0000 |
---|---|---|
committer | Bill Fenner <fenner@FreeBSD.org> | 2002-06-21 00:43:23 +0000 |
commit | a90e161be323456b08b7fe13acb201536809510f (patch) | |
tree | bfb72dba6e8e623feaf334f1b808f93f5e292c68 /contrib/tcpdump/print-esp.c | |
parent | 39eaefddae4491b77468e6ff0cd5f9a6b9acbf3d (diff) | |
download | src-a90e161be323456b08b7fe13acb201536809510f.tar.gz src-a90e161be323456b08b7fe13acb201536809510f.zip |
Import tcpdump 3.7.1, from
Notes
Notes:
svn path=/vendor/tcpdump/dist/; revision=98524
Diffstat (limited to 'contrib/tcpdump/print-esp.c')
-rw-r--r-- | contrib/tcpdump/print-esp.c | 229 |
1 files changed, 167 insertions, 62 deletions
diff --git a/contrib/tcpdump/print-esp.c b/contrib/tcpdump/print-esp.c index 7ebad59559b3..1bdf76a8697d 100644 --- a/contrib/tcpdump/print-esp.c +++ b/contrib/tcpdump/print-esp.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.17 2000/12/12 09:58:41 itojun Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.20 2002/01/21 11:39:59 mcr Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -39,13 +39,13 @@ static const char rcsid[] = #include <netinet/in.h> #ifdef HAVE_LIBCRYPTO -#include <des.h> -#include <blowfish.h> +#include <openssl/des.h> +#include <openssl/blowfish.h> #ifdef HAVE_RC5_H -#include <rc5.h> +#include <openssl/rc5.h> #endif #ifdef HAVE_CAST_H -#include <cast.h> +#include <openssl/cast.h> #endif #endif @@ -57,28 +57,153 @@ static const char rcsid[] = #include "ip6.h" #endif +#define AVOID_CHURN 1 #include "interface.h" #include "addrtoname.h" +static struct esp_algorithm *espsecret_xform=NULL; /* cache of decoded alg. */ +static char *espsecret_key=NULL; + + +enum cipher { NONE, + DESCBC, + BLOWFISH, + RC5, + CAST128, + DES3CBC}; + + + +struct esp_algorithm { + char *name; + enum cipher algo; + int ivlen; + int authlen; + int replaysize; +}; + +struct esp_algorithm esp_xforms[]={ + {"none", NONE, 0, 0, 0}, + {"des-cbc", DESCBC, 8, 0, 0}, + {"des-cbc-hmac96", DESCBC, 8, 12, 4}, + {"blowfish-cbc", BLOWFISH,8, 0, 0}, + {"blowfish-cbc-hmac96", BLOWFISH,8, 12, 4}, + {"rc5-cbc", RC5, 8, 0, 0}, + {"rc5-cbc-hmac96", RC5, 8, 12, 4}, + {"cast128-cbc", CAST128, 8, 0, 0}, + {"cast128-cbc-hmac96", CAST128, 8, 12, 4}, + {"3des-cbc-hmac96", DES3CBC, 8, 12, 4}, +}; + +static int hexdigit(char hex) +{ + if(hex >= '0' && hex <= '9') { + return (hex - '0'); + } else if(hex >= 'A' && hex <= 'F') { + return (hex - 'A' + 10); + } else if(hex >= 'a' && hex <= 'f') { + return (hex - 'a' + 10); + } else { + printf("invalid hex digit %c in espsecret\n", hex); + return 0; + } +} + +static int hex2byte(char *hexstring) +{ + int byte; + + byte = (hexdigit(hexstring[0]) << 4) + + hexdigit(hexstring[1]); + return byte; +} + + +void esp_print_decodesecret() +{ + char *colon; + int len, i; + struct esp_algorithm *xf; + + if(espsecret == NULL) { + /* set to NONE transform */ + espsecret_xform = esp_xforms; + return; + } + + if(espsecret_key != NULL) { + return; + } + + colon = strchr(espsecret, ':'); + if(colon == NULL) { + printf("failed to decode espsecret: %s\n", + espsecret); + /* set to NONE transform */ + espsecret_xform = esp_xforms; + } + + len = colon - espsecret; + xf = esp_xforms; + while(xf->name && strncasecmp(espsecret, xf->name, len)!=0) { + xf++; + } + if(xf->name == NULL) { + printf("failed to find cipher algo %s\n", + espsecret); + espsecret_xform = esp_xforms; + return; + } + espsecret_xform = xf; + + colon++; + if(colon[0]=='0' && colon[1]=='x') { + /* decode some hex! */ + colon+=2; + len = strlen(colon) / 2; + espsecret_key = (char *)malloc(len); + if(espsecret_key == NULL) { + fprintf(stderr, "%s: ran out of memory (%d) to allocate secret key\n", + program_name, len); + exit(2); + } + i = 0; + while(colon[0] != '\0' && colon[1]!='\0') { + espsecret_key[i]=hex2byte(colon); + colon+=2; + i++; + } + } else { + espsecret_key = colon; + } +} + int -esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) +esp_print(register const u_char *bp, register const u_char *bp2, + int *nhdr, int *padlen) { register const struct esp *esp; register const u_char *ep; u_int32_t spi; - enum { NONE, DESCBC, BLOWFISH, RC5, CAST128, DES3CBC } algo = NONE; struct ip *ip = NULL; #ifdef INET6 struct ip6_hdr *ip6 = NULL; #endif int advance; int len; - char *secret = NULL; + char *secret; int ivlen = 0; u_char *ivoff; - + u_char *p; + esp = (struct esp *)bp; spi = (u_int32_t)ntohl(esp->esp_spi); + secret = NULL; + +#if 0 + /* keep secret out of a register */ + p = (u_char *)&secret; +#endif /* 'ep' points to the end of available data. */ ep = snapend; @@ -95,40 +220,11 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) if (!espsecret) goto fail; - if (strncmp(espsecret, "des-cbc:", 8) == 0 - && strlen(espsecret + 8) == 8) { - algo = DESCBC; - ivlen = 8; - secret = espsecret + 8; - } else if (strncmp(espsecret, "blowfish-cbc:", 13) == 0) { - algo = BLOWFISH; - ivlen = 8; - secret = espsecret + 13; - } else if (strncmp(espsecret, "rc5-cbc:", 8) == 0) { - algo = RC5; - ivlen = 8; - secret = espsecret + 8; - } else if (strncmp(espsecret, "cast128-cbc:", 12) == 0) { - algo = CAST128; - ivlen = 8; - secret = espsecret + 12; - } else if (strncmp(espsecret, "3des-cbc:", 9) == 0 - && strlen(espsecret + 9) == 24) { - algo = DES3CBC; - ivlen = 8; - secret = espsecret + 9; - } else if (strncmp(espsecret, "none:", 5) == 0) { - algo = NONE; - ivlen = 0; - secret = espsecret + 5; - } else if (strlen(espsecret) == 8) { - algo = DESCBC; - ivlen = 8; - secret = espsecret; - } else { - algo = NONE; - ivlen = 0; - secret = espsecret; + if(!espsecret_xform) { + esp_print_decodesecret(); + } + if(espsecret_xform->algo == NONE) { + goto fail; } ip = (struct ip *)bp2; @@ -145,6 +241,9 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) break; #endif /*INET6*/ case 4: + /* nexthdr & padding are in the last fragment */ + if (ntohs(ip->ip_off) & IP_MF) + goto fail; #ifdef INET6 ip6 = NULL; #endif @@ -158,18 +257,16 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) if (ep - bp2 < len) goto fail; - if (Rflag) - ivoff = (u_char *)(esp + 1) + sizeof(u_int32_t); - else - ivoff = (u_char *)(esp + 1); + ivoff = (u_char *)(esp + 1) + espsecret_xform->replaysize; + ivlen = espsecret_xform->ivlen; + secret = espsecret_key; - switch (algo) { + switch (espsecret_xform->algo) { case DESCBC: #ifdef HAVE_LIBCRYPTO { u_char iv[8]; des_key_schedule schedule; - u_char *p; switch (ivlen) { case 4: @@ -206,7 +303,6 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) #ifdef HAVE_LIBCRYPTO { BF_KEY schedule; - u_char *p; BF_set_key(&schedule, strlen(secret), secret); @@ -224,7 +320,6 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) #if defined(HAVE_LIBCRYPTO) && defined(HAVE_RC5_H) { RC5_32_KEY schedule; - u_char *p; RC5_32_set_key(&schedule, strlen(secret), secret, RC5_16_ROUNDS); @@ -243,7 +338,6 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) #if defined(HAVE_LIBCRYPTO) && defined(HAVE_CAST_H) && !defined(HAVE_BUGGY_CAST128) { CAST_KEY schedule; - u_char *p; CAST_set_key(&schedule, strlen(secret), secret); @@ -261,16 +355,26 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) #if defined(HAVE_LIBCRYPTO) { des_key_schedule s1, s2, s3; - u_char *p; - des_check_key = 0; - des_set_key((void *)secret, s1); - des_set_key((void *)(secret + 8), s2); - des_set_key((void *)(secret + 16), s3); + des_check_key = 1; + des_set_odd_parity((void *)secret); + des_set_odd_parity((void *)secret+8); + des_set_odd_parity((void *)secret+16); + if(des_set_key((void *)secret, s1) != 0) { + printf("failed to schedule key 1\n"); + } + if(des_set_key((void *)(secret + 8), s2)!=0) { + printf("failed to schedule key 2\n"); + } + if(des_set_key((void *)(secret + 16), s3)!=0) { + printf("failed to schedule key 3\n"); + } p = ivoff + ivlen; des_ede3_cbc_encrypt((void *)p, (void *)p, - (long)(ep - p), s1, s2, s3, (void *)ivoff, DES_DECRYPT); + (long)(ep - p), + s1, s2, s3, + (void *)ivoff, DES_DECRYPT); advance = ivoff - (u_char *)esp + ivlen; break; } @@ -280,17 +384,18 @@ esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr) case NONE: default: - if (Rflag) - advance = sizeof(struct esp) + sizeof(u_int32_t); - else - advance = sizeof(struct esp); + advance = sizeof(struct esp) + espsecret_xform->replaysize; break; } + ep = ep - espsecret_xform->authlen; /* sanity check for pad length */ if (ep - bp < *(ep - 2)) goto fail; + if (padlen) + *padlen = *(ep - 2) + 2; + if (nhdr) *nhdr = *(ep - 1); |