tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

print-esp.c
Go to the documentation of this file.
1 /* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */
2 
3 /*
4  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
5  * The Regents of the University of California. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  */
23 
24 /* \summary: IPSEC Encapsulating Security Payload (ESP) printer */
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 
30 #include "netdissect-stdinc.h"
31 
32 #include <string.h>
33 #include <stdlib.h>
34 
35 /* Any code in this file that depends on HAVE_LIBCRYPTO depends on
36  * HAVE_OPENSSL_EVP_H too. Undefining the former when the latter isn't defined
37  * is the simplest way of handling the dependency.
38  */
39 #ifdef HAVE_LIBCRYPTO
40 #ifdef HAVE_OPENSSL_EVP_H
41 #include <openssl/evp.h>
42 #else
43 #undef HAVE_LIBCRYPTO
44 #endif
45 #endif
46 
47 #include "netdissect.h"
48 #include "extract.h"
49 
50 #ifdef HAVE_LIBCRYPTO
51 #include "strtoaddr.h"
52 #include "ascii_strcasecmp.h"
53 #endif
54 
55 #include "ip.h"
56 #include "ip6.h"
57 
58 /*
59  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
60  * All rights reserved.
61  *
62  * Redistribution and use in source and binary forms, with or without
63  * modification, are permitted provided that the following conditions
64  * are met:
65  * 1. Redistributions of source code must retain the above copyright
66  * notice, this list of conditions and the following disclaimer.
67  * 2. Redistributions in binary form must reproduce the above copyright
68  * notice, this list of conditions and the following disclaimer in the
69  * documentation and/or other materials provided with the distribution.
70  * 3. Neither the name of the project nor the names of its contributors
71  * may be used to endorse or promote products derived from this software
72  * without specific prior written permission.
73  *
74  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
75  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
76  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
77  * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
78  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
79  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
80  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
81  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
82  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
83  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
84  * SUCH DAMAGE.
85  */
86 
87 /*
88  * RFC1827/2406 Encapsulated Security Payload.
89  */
90 
91 struct newesp {
92  nd_uint32_t esp_spi; /* ESP */
93  nd_uint32_t esp_seq; /* Sequence number */
94  /*variable size*/ /* (IV and) Payload data */
95  /*variable size*/ /* padding */
96  /*8bit*/ /* pad size */
97  /*8bit*/ /* next header */
98  /*8bit*/ /* next header */
99  /*variable size, 32bit bound*/ /* Authentication data */
100 };
101 
102 #ifdef HAVE_LIBCRYPTO
103 union inaddr_u {
104  nd_ipv4 in4;
105  nd_ipv6 in6;
106 };
107 struct sa_list {
108  struct sa_list *next;
109  u_int daddr_version;
110  union inaddr_u daddr;
111  uint32_t spi; /* if == 0, then IKEv2 */
112  int initiator;
113  u_char spii[8]; /* for IKEv2 */
114  u_char spir[8];
115  const EVP_CIPHER *evp;
116  u_int ivlen;
117  int authlen;
118  u_char authsecret[256];
119  int authsecret_len;
120  u_char secret[256]; /* is that big enough for all secrets? */
121  int secretlen;
122 };
123 
124 #ifndef HAVE_EVP_CIPHER_CTX_NEW
125 /*
126  * Allocate an EVP_CIPHER_CTX.
127  * Used if we have an older version of OpenSSL that doesn't provide
128  * routines to allocate and free them.
129  */
130 static EVP_CIPHER_CTX *
131 EVP_CIPHER_CTX_new(void)
132 {
133  EVP_CIPHER_CTX *ctx;
134 
135  ctx = malloc(sizeof(*ctx));
136  if (ctx == NULL)
137  return (NULL);
138  memset(ctx, 0, sizeof(*ctx));
139  return (ctx);
140 }
141 
142 static void
143 EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
144 {
145  EVP_CIPHER_CTX_cleanup(ctx);
146  free(ctx);
147 }
148 #endif
149 
150 #ifdef HAVE_EVP_DECRYPTINIT_EX
151 /*
152  * Initialize the cipher by calling EVP_DecryptInit_ex(), because
153  * calling EVP_DecryptInit() will reset the cipher context, clearing
154  * the cipher, so calling it twice, with the second call having a
155  * null cipher, will clear the already-set cipher. EVP_DecryptInit_ex(),
156  * however, won't reset the cipher context, so you can use it to specify
157  * the IV in a second call after a first call to EVP_DecryptInit_ex()
158  * to set the cipher and the key.
159  *
160  * XXX - is there some reason why we need to make two calls?
161  */
162 static int
163 set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
164  const unsigned char *key,
165  const unsigned char *iv)
166 {
167  return EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv);
168 }
169 #else
170 /*
171  * Initialize the cipher by calling EVP_DecryptInit(), because we don't
172  * have EVP_DecryptInit_ex(); we rely on it not trashing the context.
173  */
174 static int
175 set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
176  const unsigned char *key,
177  const unsigned char *iv)
178 {
179  return EVP_DecryptInit(ctx, cipher, key, iv);
180 }
181 #endif
182 
183 static u_char *
184 do_decrypt(netdissect_options *ndo, const char *caller, struct sa_list *sa,
185  const u_char *iv, const u_char *ct, unsigned int ctlen)
186 {
187  EVP_CIPHER_CTX *ctx;
188  unsigned int block_size;
189  unsigned int ptlen;
190  u_char *pt;
191  int len;
192 
193  ctx = EVP_CIPHER_CTX_new();
194  if (ctx == NULL) {
195  /*
196  * Failed to initialize the cipher context.
197  * From a look at the OpenSSL code, this appears to
198  * mean "couldn't allocate memory for the cipher context";
199  * note that we're not passing any parameters, so there's
200  * not much else it can mean.
201  */
202  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
203  "%s: can't allocate memory for cipher context", caller);
204  return NULL;
205  }
206 
207  if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL) < 0) {
208  EVP_CIPHER_CTX_free(ctx);
209  (*ndo->ndo_warning)(ndo, "%s: espkey init failed", caller);
210  return NULL;
211  }
212  if (set_cipher_parameters(ctx, NULL, NULL, iv) < 0) {
213  EVP_CIPHER_CTX_free(ctx);
214  (*ndo->ndo_warning)(ndo, "%s: IV init failed", caller);
215  return NULL;
216  }
217 
218  /*
219  * At least as I read RFC 5996 section 3.14 and RFC 4303 section 2.4,
220  * if the cipher has a block size of which the ciphertext's size must
221  * be a multiple, the payload must be padded to make that happen, so
222  * the ciphertext length must be a multiple of the block size. Fail
223  * if that's not the case.
224  */
225  block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
226  if ((ctlen % block_size) != 0) {
227  EVP_CIPHER_CTX_free(ctx);
228  (*ndo->ndo_warning)(ndo,
229  "%s: ciphertext size %u is not a multiple of the cipher block size %u",
230  caller, ctlen, block_size);
231  return NULL;
232  }
233 
234  /*
235  * Attempt to allocate a buffer for the decrypted data, because
236  * we can't decrypt on top of the input buffer.
237  */
238  ptlen = ctlen;
239  pt = (u_char *)malloc(ptlen);
240  if (pt == NULL) {
241  EVP_CIPHER_CTX_free(ctx);
242  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
243  "%s: can't allocate memory for decryption buffer", caller);
244  return NULL;
245  }
246 
247  /*
248  * The size of the ciphertext handed to us is a multiple of the
249  * cipher block size, so we don't need to worry about padding.
250  */
251  if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) {
252  free(pt);
253  EVP_CIPHER_CTX_free(ctx);
254  (*ndo->ndo_warning)(ndo,
255  "%s: EVP_CIPHER_CTX_set_padding failed", caller);
256  return NULL;
257  }
258  if (!EVP_DecryptUpdate(ctx, pt, &len, ct, ctlen)) {
259  free(pt);
260  EVP_CIPHER_CTX_free(ctx);
261  (*ndo->ndo_warning)(ndo, "%s: EVP_DecryptUpdate failed",
262  caller);
263  return NULL;
264  }
265  EVP_CIPHER_CTX_free(ctx);
266  return pt;
267 }
268 
269 /*
270  * This will allocate a new buffer containing the decrypted data.
271  * It returns 1 on success and 0 on failure.
272  *
273  * It will push the new buffer and the values of ndo->ndo_packetp and
274  * ndo->ndo_snapend onto the buffer stack, and change ndo->ndo_packetp
275  * and ndo->ndo_snapend to refer to the new buffer.
276  *
277  * Our caller must pop the buffer off the stack when it's finished
278  * dissecting anything in it and before it does any dissection of
279  * anything in the old buffer. That will free the new buffer.
280  */
283  int initiator,
284  const u_char spii[8],
285  const u_char spir[8],
286  const u_char *buf, const u_char *end)
287 {
288  struct sa_list *sa;
289  const u_char *iv;
290  const u_char *ct;
291  unsigned int ctlen;
292  u_char *pt;
293 
294  /* initiator arg is any non-zero value */
295  if(initiator) initiator=1;
296 
297  /* see if we can find the SA, and if so, decode it */
298  for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
299  if (sa->spi == 0
300  && initiator == sa->initiator
301  && memcmp(spii, sa->spii, 8) == 0
302  && memcmp(spir, sa->spir, 8) == 0)
303  break;
304  }
305 
306  if(sa == NULL) return 0;
307  if(sa->evp == NULL) return 0;
308 
309  /*
310  * remove authenticator, and see if we still have something to
311  * work with
312  */
313  end = end - sa->authlen;
314  iv = buf;
315  ct = iv + sa->ivlen;
316  ctlen = end-ct;
317 
318  if(end <= ct) return 0;
319 
320  pt = do_decrypt(ndo, "esp_decrypt_buffer_by_ikev2_print", sa, iv,
321  ct, ctlen);
322  if (pt == NULL)
323  return 0;
324 
325  /*
326  * Switch to the output buffer for dissection, and save it
327  * on the buffer stack so it can be freed; our caller must
328  * pop it when done.
329  */
330  if (!nd_push_buffer(ndo, pt, pt, pt + ctlen)) {
331  free(pt);
332  return 0;
333  }
334 
335  return 1;
336 }
338 
339 static void esp_print_addsa(netdissect_options *ndo,
340  struct sa_list *sa, int sa_def)
341 {
342  /* copy the "sa" */
343 
344  struct sa_list *nsa;
345 
346  /* malloc() return used in a 'struct sa_list': do not free() */
347  nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
348  if (nsa == NULL)
349  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
350  "%s: malloc", __func__);
351 
352  *nsa = *sa;
353 
354  if (sa_def)
355  ndo->ndo_sa_default = nsa;
356 
357  nsa->next = ndo->ndo_sa_list_head;
358  ndo->ndo_sa_list_head = nsa;
359 }
360 
361 
362 static u_int hexdigit(netdissect_options *ndo, char hex)
363 {
364  if (hex >= '0' && hex <= '9')
365  return (hex - '0');
366  else if (hex >= 'A' && hex <= 'F')
367  return (hex - 'A' + 10);
368  else if (hex >= 'a' && hex <= 'f')
369  return (hex - 'a' + 10);
370  else {
371  (*ndo->ndo_error)(ndo, S_ERR_ND_ESP_SECRET,
372  "invalid hex digit %c in espsecret\n", hex);
373  }
374 }
375 
376 static u_int hex2byte(netdissect_options *ndo, char *hexstring)
377 {
378  u_int byte;
379 
380  byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
381  return byte;
382 }
383 
384 /*
385  * returns size of binary, 0 on failure.
386  */
387 static
388 int espprint_decode_hex(netdissect_options *ndo,
389  u_char *binbuf, unsigned int binbuf_len,
390  char *hex)
391 {
392  unsigned int len;
393  int i;
394 
395  len = strlen(hex) / 2;
396 
397  if (len > binbuf_len) {
398  (*ndo->ndo_warning)(ndo, "secret is too big: %u\n", len);
399  return 0;
400  }
401 
402  i = 0;
403  while (hex[0] != '\0' && hex[1]!='\0') {
404  binbuf[i] = hex2byte(ndo, hex);
405  hex += 2;
406  i++;
407  }
408 
409  return i;
410 }
411 
412 /*
413  * decode the form: SPINUM@IP <tab> ALGONAME:0xsecret
414  */
415 
417 static int
418 espprint_decode_encalgo(netdissect_options *ndo,
419  char *decode, struct sa_list *sa)
420 {
421  size_t i;
422  const EVP_CIPHER *evp;
423  int authlen = 0;
424  char *colon, *p;
425 
426  colon = strchr(decode, ':');
427  if (colon == NULL) {
428  (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
429  return 0;
430  }
431  *colon = '\0';
432 
433  if (strlen(decode) > strlen("-hmac96") &&
434  !strcmp(decode + strlen(decode) - strlen("-hmac96"),
435  "-hmac96")) {
436  p = strstr(decode, "-hmac96");
437  *p = '\0';
438  authlen = 12;
439  }
440  if (strlen(decode) > strlen("-cbc") &&
441  !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
442  p = strstr(decode, "-cbc");
443  *p = '\0';
444  }
445  evp = EVP_get_cipherbyname(decode);
446 
447  if (!evp) {
448  (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
449  sa->evp = NULL;
450  sa->authlen = 0;
451  sa->ivlen = 0;
452  return 0;
453  }
454 
455  sa->evp = evp;
456  sa->authlen = authlen;
457  /* This returns an int, but it should never be negative */
458  sa->ivlen = EVP_CIPHER_iv_length(evp);
459 
460  colon++;
461  if (colon[0] == '0' && colon[1] == 'x') {
462  /* decode some hex! */
463 
464  colon += 2;
465  sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon);
466  if(sa->secretlen == 0) return 0;
467  } else {
468  i = strlen(colon);
469 
470  if (i < sizeof(sa->secret)) {
471  memcpy(sa->secret, colon, i);
472  sa->secretlen = i;
473  } else {
474  memcpy(sa->secret, colon, sizeof(sa->secret));
475  sa->secretlen = sizeof(sa->secret);
476  }
477  }
478 
479  return 1;
480 }
482 
483 /*
484  * for the moment, ignore the auth algorithm, just hard code the authenticator
485  * length. Need to research how openssl looks up HMAC stuff.
486  */
487 static int
488 espprint_decode_authalgo(netdissect_options *ndo,
489  char *decode, struct sa_list *sa)
490 {
491  char *colon;
492 
493  colon = strchr(decode, ':');
494  if (colon == NULL) {
495  (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
496  return 0;
497  }
498  *colon = '\0';
499 
500  if(ascii_strcasecmp(decode,"sha1") == 0 ||
501  ascii_strcasecmp(decode,"md5") == 0) {
502  sa->authlen = 12;
503  }
504  return 1;
505 }
506 
507 static void esp_print_decode_ikeline(netdissect_options *ndo, char *line,
508  const char *file, int lineno)
509 {
510  /* it's an IKEv2 secret, store it instead */
511  struct sa_list sa1;
512 
513  char *init;
514  char *icookie, *rcookie;
515  int ilen, rlen;
516  char *authkey;
517  char *enckey;
518 
519  init = strsep(&line, " \t");
520  icookie = strsep(&line, " \t");
521  rcookie = strsep(&line, " \t");
522  authkey = strsep(&line, " \t");
523  enckey = strsep(&line, " \t");
524 
525  /* if any fields are missing */
526  if(!init || !icookie || !rcookie || !authkey || !enckey) {
527  (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u",
528  file, lineno);
529 
530  return;
531  }
532 
533  ilen = strlen(icookie);
534  rlen = strlen(rcookie);
535 
536  if((init[0]!='I' && init[0]!='R')
537  || icookie[0]!='0' || icookie[1]!='x'
538  || rcookie[0]!='0' || rcookie[1]!='x'
539  || ilen!=18
540  || rlen!=18) {
541  (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.",
542  file, lineno);
543 
544  (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)",
545  init, icookie, ilen, rcookie, rlen);
546 
547  return;
548  }
549 
550  sa1.spi = 0;
551  sa1.initiator = (init[0] == 'I');
552  if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8)
553  return;
554 
555  if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8)
556  return;
557 
558  if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return;
559 
560  if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return;
561 
562  esp_print_addsa(ndo, &sa1, FALSE);
563 }
564 
565 /*
566  *
567  * special form: file /name
568  * causes us to go read from this file instead.
569  *
570  */
571 static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
572  const char *file, int lineno)
573 {
574  struct sa_list sa1;
575  int sa_def;
576 
577  char *spikey;
578  char *decode;
579 
580  spikey = strsep(&line, " \t");
581  sa_def = 0;
582  memset(&sa1, 0, sizeof(struct sa_list));
583 
584  /* if there is only one token, then it is an algo:key token */
585  if (line == NULL) {
586  decode = spikey;
587  spikey = NULL;
588  /* sa1.daddr.version = 0; */
589  /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
590  /* sa1.spi = 0; */
591  sa_def = 1;
592  } else
593  decode = line;
594 
595  if (spikey && ascii_strcasecmp(spikey, "file") == 0) {
596  /* open file and read it */
597  FILE *secretfile;
598  char fileline[1024];
599  int subfile_lineno=0;
600  char *nl;
601  char *filename = line;
602 
603  secretfile = fopen(filename, FOPEN_READ_TXT);
604  if (secretfile == NULL) {
605  (*ndo->ndo_error)(ndo, S_ERR_ND_OPEN_FILE,
606  "%s: can't open %s: %s\n",
607  __func__, filename, strerror(errno));
608  }
609 
610  while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
611  subfile_lineno++;
612  /* remove newline from the line */
613  nl = strchr(fileline, '\n');
614  if (nl)
615  *nl = '\0';
616  if (fileline[0] == '#') continue;
617  if (fileline[0] == '\0') continue;
618 
619  esp_print_decode_onesecret(ndo, fileline, filename, subfile_lineno);
620  }
621  fclose(secretfile);
622 
623  return;
624  }
625 
626  if (spikey && ascii_strcasecmp(spikey, "ikev2") == 0) {
627  esp_print_decode_ikeline(ndo, line, file, lineno);
628  return;
629  }
630 
631  if (spikey) {
632 
633  char *spistr, *foo;
634  uint32_t spino;
635 
636  spistr = strsep(&spikey, "@");
637  if (spistr == NULL) {
638  (*ndo->ndo_warning)(ndo, "print_esp: failed to find the @ token");
639  return;
640  }
641 
642  spino = strtoul(spistr, &foo, 0);
643  if (spistr == foo || !spikey) {
644  (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
645  return;
646  }
647 
648  sa1.spi = spino;
649 
650  if (strtoaddr6(spikey, &sa1.daddr.in6) == 1) {
651  sa1.daddr_version = 6;
652  } else if (strtoaddr(spikey, &sa1.daddr.in4) == 1) {
653  sa1.daddr_version = 4;
654  } else {
655  (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
656  return;
657  }
658  }
659 
660  if (decode) {
661  /* skip any blank spaces */
662  while (*decode == ' ' || *decode == '\t' || *decode == '\r' || *decode == '\n')
663  decode++;
664 
665  if(!espprint_decode_encalgo(ndo, decode, &sa1)) {
666  return;
667  }
668  }
669 
670  esp_print_addsa(ndo, &sa1, sa_def);
671 }
672 
674 static void esp_init(netdissect_options *ndo _U_)
675 {
676  /*
677  * 0.9.6 doesn't appear to define OPENSSL_API_COMPAT, so
678  * we check whether it's undefined or it's less than the
679  * value for 1.1.0.
680  */
681 #if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < 0x10100000L
682  OpenSSL_add_all_algorithms();
683 #endif
684  EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
685 }
687 
689 {
690  char *line;
691  char *p;
692  static int initialized = 0;
693 
694  if (!initialized) {
695  esp_init(ndo);
696  initialized = 1;
697  }
698 
699  p = ndo->ndo_espsecret;
700 
701  while (p && p[0] != '\0') {
702  /* pick out the first line or first thing until a comma */
703  if ((line = strsep(&p, "\n,")) == NULL) {
704  line = p;
705  p = NULL;
706  }
707 
708  esp_print_decode_onesecret(ndo, line, "cmdline", 0);
709  }
710 
711  ndo->ndo_espsecret = NULL;
712 }
713 
714 #endif
715 
716 #ifdef HAVE_LIBCRYPTO
717 #define USED_IF_LIBCRYPTO
718 #else
719 #define USED_IF_LIBCRYPTO _U_
720 #endif
721 
722 #ifdef HAVE_LIBCRYPTO
724 #endif
725 void
727  const u_char *bp, u_int length,
728  const u_char *bp2 USED_IF_LIBCRYPTO,
729  u_int ver USED_IF_LIBCRYPTO,
730  int fragmented USED_IF_LIBCRYPTO,
731  u_int ttl_hl USED_IF_LIBCRYPTO)
732 {
733  const struct newesp *esp;
734  const u_char *ep;
735 #ifdef HAVE_LIBCRYPTO
736  const struct ip *ip;
737  struct sa_list *sa = NULL;
738  const struct ip6_hdr *ip6 = NULL;
739  const u_char *iv;
740  u_int ivlen;
741  u_int payloadlen;
742  const u_char *ct;
743  u_char *pt;
744  u_int padlen;
745  u_int nh;
746 #endif
747 
748  ndo->ndo_protocol = "esp";
749  esp = (const struct newesp *)bp;
750 
751  /* 'ep' points to the end of available data. */
752  ep = ndo->ndo_snapend;
753 
754  if ((const u_char *)(esp + 1) >= ep) {
755  nd_print_trunc(ndo);
756  return;
757  }
758  ND_PRINT("ESP(spi=0x%08x", GET_BE_U_4(esp->esp_spi));
759  ND_PRINT(",seq=0x%x)", GET_BE_U_4(esp->esp_seq));
760  ND_PRINT(", length %u", length);
761 
762 #ifdef HAVE_LIBCRYPTO
763  /* initiailize SAs */
764  if (ndo->ndo_sa_list_head == NULL) {
765  if (!ndo->ndo_espsecret)
766  return;
767 
769  }
770 
771  if (ndo->ndo_sa_list_head == NULL)
772  return;
773 
774  ip = (const struct ip *)bp2;
775  switch (ver) {
776  case 6:
777  ip6 = (const struct ip6_hdr *)bp2;
778  /* we do not attempt to decrypt jumbograms */
779  if (!GET_BE_U_2(ip6->ip6_plen))
780  return;
781  /* XXX - check whether it's fragmented? */
782  /* if we can't get nexthdr, we do not need to decrypt it */
783 
784  /* see if we can find the SA, and if so, decode it */
785  for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
786  if (sa->spi == GET_BE_U_4(esp->esp_spi) &&
787  sa->daddr_version == 6 &&
788  UNALIGNED_MEMCMP(&sa->daddr.in6, &ip6->ip6_dst,
789  sizeof(nd_ipv6)) == 0) {
790  break;
791  }
792  }
793  break;
794  case 4:
795  /* nexthdr & padding are in the last fragment */
796  if (fragmented)
797  return;
798 
799  /* see if we can find the SA, and if so, decode it */
800  for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
801  if (sa->spi == GET_BE_U_4(esp->esp_spi) &&
802  sa->daddr_version == 4 &&
803  UNALIGNED_MEMCMP(&sa->daddr.in4, &ip->ip_dst,
804  sizeof(nd_ipv4)) == 0) {
805  break;
806  }
807  }
808  break;
809  default:
810  return;
811  }
812 
813  /* if we didn't find the specific one, then look for
814  * an unspecified one.
815  */
816  if (sa == NULL)
817  sa = ndo->ndo_sa_default;
818 
819  /* if not found fail */
820  if (sa == NULL)
821  return;
822 
823  /* pointer to the IV, if there is one */
824  iv = (const u_char *)(esp + 1) + 0;
825  /* length of the IV, if there is one; 0, if there isn't */
826  ivlen = sa->ivlen;
827 
828  /*
829  * Get a pointer to the ciphertext.
830  *
831  * p points to the beginning of the payload, i.e. to the
832  * initialization vector, so if we skip past the initialization
833  * vector, it points to the beginning of the ciphertext.
834  */
835  ct = iv + ivlen;
836 
837  /*
838  * Make sure the authentication data/integrity check value length
839  * isn't bigger than the total amount of data available after
840  * the ESP header and initialization vector is removed and,
841  * if not, slice the authentication data/ICV off.
842  */
843  if (ep - ct < sa->authlen) {
844  nd_print_trunc(ndo);
845  return;
846  }
847  ep = ep - sa->authlen;
848 
849  /*
850  * Calculate the length of the ciphertext. ep points to
851  * the beginning of the authentication data/integrity check
852  * value, i.e. right past the end of the ciphertext;
853  */
854  payloadlen = ep - ct;
855 
856  if (sa->evp == NULL)
857  return;
858 
859  /*
860  * If the next header value is past the end of the available
861  * data, we won't be able to fetch it once we've decrypted
862  * the ciphertext, so there's no point in decrypting the data.
863  *
864  * Report it as truncation.
865  */
866  if (!ND_TTEST_1(ep - 1)) {
867  nd_print_trunc(ndo);
868  return;
869  }
870 
871  pt = do_decrypt(ndo, "esp_print", sa, iv, ct, payloadlen);
872  if (pt == NULL)
873  return;
874 
875  /*
876  * Switch to the output buffer for dissection, and
877  * save it on the buffer stack so it can be freed.
878  */
879  ep = pt + payloadlen;
880  if (!nd_push_buffer(ndo, pt, pt, ep)) {
881  free(pt);
882  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
883  "%s: can't push buffer on buffer stack", __func__);
884  }
885 
886  /*
887  * Sanity check for pad length; if it, plus 2 for the pad
888  * length and next header fields, is bigger than the ciphertext
889  * length (which is also the plaintext length), it's too big.
890  *
891  * XXX - the check can fail if the packet is corrupt *or* if
892  * it was not decrypted with the correct key, so that the
893  * "plaintext" is not what was being sent.
894  */
895  padlen = GET_U_1(ep - 2);
896  if (padlen + 2 > payloadlen) {
897  nd_print_trunc(ndo);
898  return;
899  }
900 
901  /* Get the next header */
902  nh = GET_U_1(ep - 1);
903 
904  ND_PRINT(": ");
905 
906  /*
907  * Don't put padding + padding length(1 byte) + next header(1 byte)
908  * in the buffer because they are not part of the plaintext to decode.
909  */
910  nd_push_snapend(ndo, ep - (padlen + 2));
911 
912  /* Now dissect the plaintext. */
913  ip_demux_print(ndo, pt, payloadlen - (padlen + 2), ver, fragmented,
914  ttl_hl, nh, bp2);
915 
916  /* Pop the buffer, freeing it. */
917  nd_pop_packet_info(ndo);
918  /* Pop the nd_push_snapend */
919  nd_pop_packet_info(ndo);
920 #endif
921 }
922 #ifdef HAVE_LIBCRYPTO
924 #endif
static const char hex[16]
Definition: addrtoname.c:397
int ascii_strcasecmp(const char *s1, const char *s2)
#define GET_BE_U_4(p)
Definition: extract.h:877
#define GET_BE_U_2(p)
Definition: extract.h:875
#define GET_U_1(p)
Definition: extract.h:872
#define ND_TTEST_1(p)
Definition: extract.h:551
static char line[BUFSIZ+1]
Definition: getservent.c:45
char * strsep(char **, const char *)
Definition: strsep.c:56
#define USES_APPLE_DEPRECATED_API
#define FOPEN_READ_TXT
#define FALSE
#define USES_APPLE_RST
int nd_push_snapend(netdissect_options *ndo, const u_char *new_snapend)
Definition: netdissect.c:176
int nd_push_buffer(netdissect_options *ndo, u_char *new_buffer, const u_char *new_packetp, const u_char *new_snapend)
Definition: netdissect.c:151
void nd_pop_packet_info(netdissect_options *ndo)
Definition: netdissect.c:218
void ip_demux_print(netdissect_options *, const u_char *, u_int, u_int, int, u_int, uint8_t, const u_char *)
#define UNALIGNED_MEMCMP(p, q, l)
Definition: netdissect.h:444
void esp_decodesecret_print(netdissect_options *)
int esp_decrypt_buffer_by_ikev2_print(netdissect_options *, int, const u_char spii[8], const u_char spir[8], const u_char *, const u_char *)
void nd_print_trunc(netdissect_options *)
Definition: util-print.c:409
unsigned char nd_ipv4[4]
Definition: netdissect.h:92
#define ND_PRINT(...)
Definition: netdissect.h:385
unsigned char nd_uint32_t[4]
Definition: netdissect.h:49
unsigned char nd_ipv6[16]
Definition: netdissect.h:97
char * strerror(int)
nd_uint8_t byte
Definition: print-decnet.c:40
#define USED_IF_LIBCRYPTO
Definition: print-esp.c:719
void esp_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2, u_int ver, int fragmented, u_int ttl_hl)
Definition: print-esp.c:726
cookie_t initiator
Definition: print-isakmp.c:644
@ S_ERR_ND_OPEN_FILE
@ S_ERR_ND_ESP_SECRET
@ S_ERR_ND_MEM_ALLOC
int strtoaddr6(const char *src, void *dst)
Definition: strtoaddr.c:153
int strtoaddr(const char *src, void *dst)
Definition: strtoaddr.c:58
Definition: ip6.h:76
nd_ipv6 ip6_dst
Definition: ip6.h:87
Definition: ip.h:52
nd_ipv4 ip_dst
Definition: ip.h:66
const u_char * ndo_snapend
Definition: netdissect.h:239
int(*) void NORETURN_FUNCPTR(* ndo_error)(netdissect_options *, status_exit_codes_t status, const char *fmt,...) PRINTFLIKE_FUNCPTR(3
Definition: netdissect.h:256
const char * ndo_protocol
Definition: netdissect.h:218
int(*) void NORETURN_FUNCPTR(*) void(* ndo_warning)(netdissect_options *, const char *fmt,...) PRINTFLIKE_FUNCPTR(2
Definition: netdissect.h:261
struct sa_list * ndo_sa_list_head
Definition: netdissect.h:227
struct sa_list * ndo_sa_default
Definition: netdissect.h:228
nd_uint32_t esp_seq
Definition: print-esp.c:93
nd_uint32_t esp_spi
Definition: print-esp.c:92
nd_ipv6 in6
Definition: print-isakmp.c:641
nd_ipv4 in4
Definition: print-isakmp.c:640
#define _U_
Definition: varattrs.h:56