"Fossies" - the Fresh Open Source Software Archive

Member "tcpdump-4.99.1/./print-esp.c" (7 Jun 2021, 23683 Bytes) of package /linux/misc/tcpdump-4.99.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code 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  */
  281 USES_APPLE_DEPRECATED_API
  282 int esp_decrypt_buffer_by_ikev2_print(netdissect_options *ndo,
  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 }
  337 USES_APPLE_RST
  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 
  416 USES_APPLE_DEPRECATED_API
  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 }
  481 USES_APPLE_RST
  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 
  673 USES_APPLE_DEPRECATED_API
  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 }
  686 USES_APPLE_RST
  687 
  688 void esp_decodesecret_print(netdissect_options *ndo)
  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
  723 USES_APPLE_DEPRECATED_API
  724 #endif
  725 void
  726 esp_print(netdissect_options *ndo,
  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 
  768         esp_decodesecret_print(ndo);
  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
  923 USES_APPLE_RST
  924 #endif