xref: /freebsd/contrib/tcpdump/print-esp.c (revision ee67461e56828dd1f8de165947ba83f6d9148a87)
1b0453382SBill Fenner /*	$NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $	*/
2b0453382SBill Fenner 
3b0453382SBill Fenner /*
4b0453382SBill Fenner  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
5b0453382SBill Fenner  *	The Regents of the University of California.  All rights reserved.
6b0453382SBill Fenner  *
7b0453382SBill Fenner  * Redistribution and use in source and binary forms, with or without
8b0453382SBill Fenner  * modification, are permitted provided that: (1) source code distributions
9b0453382SBill Fenner  * retain the above copyright notice and this paragraph in its entirety, (2)
10b0453382SBill Fenner  * distributions including binary code include the above copyright notice and
11b0453382SBill Fenner  * this paragraph in its entirety in the documentation or other materials
12b0453382SBill Fenner  * provided with the distribution, and (3) all advertising materials mentioning
13b0453382SBill Fenner  * features or use of this software display the following acknowledgement:
14b0453382SBill Fenner  * ``This product includes software developed by the University of California,
15b0453382SBill Fenner  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16b0453382SBill Fenner  * the University nor the names of its contributors may be used to endorse
17b0453382SBill Fenner  * or promote products derived from this software without specific prior
18b0453382SBill Fenner  * written permission.
19b0453382SBill Fenner  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20b0453382SBill Fenner  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21b0453382SBill Fenner  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22b0453382SBill Fenner  */
23b0453382SBill Fenner 
243340d773SGleb Smirnoff /* \summary: IPSEC Encapsulating Security Payload (ESP) printer */
253340d773SGleb Smirnoff 
26b0453382SBill Fenner #ifdef HAVE_CONFIG_H
27*ee67461eSJoseph Mingrone #include <config.h>
28b0453382SBill Fenner #endif
29b0453382SBill Fenner 
30*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
315b0fe478SBruce M Simpson 
323c602fabSXin LI #include <string.h>
339afd0c29SBill Fenner #include <stdlib.h>
34b0453382SBill Fenner 
353c602fabSXin LI /* Any code in this file that depends on HAVE_LIBCRYPTO depends on
363c602fabSXin LI  * HAVE_OPENSSL_EVP_H too. Undefining the former when the latter isn't defined
373c602fabSXin LI  * is the simplest way of handling the dependency.
383c602fabSXin LI  */
39685295f4SBill Fenner #ifdef HAVE_LIBCRYPTO
405b0fe478SBruce M Simpson #ifdef HAVE_OPENSSL_EVP_H
415b0fe478SBruce M Simpson #include <openssl/evp.h>
423c602fabSXin LI #else
433c602fabSXin LI #undef HAVE_LIBCRYPTO
44b0453382SBill Fenner #endif
45b0453382SBill Fenner #endif
46b0453382SBill Fenner 
473340d773SGleb Smirnoff #include "netdissect.h"
485b0fe478SBruce M Simpson #include "extract.h"
49b0453382SBill Fenner 
50*ee67461eSJoseph Mingrone #include "diag-control.h"
51*ee67461eSJoseph Mingrone 
52*ee67461eSJoseph Mingrone #ifdef HAVE_LIBCRYPTO
53*ee67461eSJoseph Mingrone #include "strtoaddr.h"
543340d773SGleb Smirnoff #include "ascii_strcasecmp.h"
55*ee67461eSJoseph Mingrone #endif
563340d773SGleb Smirnoff 
573340d773SGleb Smirnoff #include "ip.h"
583340d773SGleb Smirnoff #include "ip6.h"
593340d773SGleb Smirnoff 
603c602fabSXin LI /*
613c602fabSXin LI  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
623c602fabSXin LI  * All rights reserved.
633c602fabSXin LI  *
643c602fabSXin LI  * Redistribution and use in source and binary forms, with or without
653c602fabSXin LI  * modification, are permitted provided that the following conditions
663c602fabSXin LI  * are met:
673c602fabSXin LI  * 1. Redistributions of source code must retain the above copyright
683c602fabSXin LI  *    notice, this list of conditions and the following disclaimer.
693c602fabSXin LI  * 2. Redistributions in binary form must reproduce the above copyright
703c602fabSXin LI  *    notice, this list of conditions and the following disclaimer in the
713c602fabSXin LI  *    documentation and/or other materials provided with the distribution.
723c602fabSXin LI  * 3. Neither the name of the project nor the names of its contributors
733c602fabSXin LI  *    may be used to endorse or promote products derived from this software
743c602fabSXin LI  *    without specific prior written permission.
753c602fabSXin LI  *
763c602fabSXin LI  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
773c602fabSXin LI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
783c602fabSXin LI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
793c602fabSXin LI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
803c602fabSXin LI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
813c602fabSXin LI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
823c602fabSXin LI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
833c602fabSXin LI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
843c602fabSXin LI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
853c602fabSXin LI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
863c602fabSXin LI  * SUCH DAMAGE.
873c602fabSXin LI  */
883c602fabSXin LI 
893c602fabSXin LI /*
903c602fabSXin LI  * RFC1827/2406 Encapsulated Security Payload.
913c602fabSXin LI  */
923c602fabSXin LI 
933c602fabSXin LI struct newesp {
94*ee67461eSJoseph Mingrone 	nd_uint32_t	esp_spi;	/* ESP */
95*ee67461eSJoseph Mingrone 	nd_uint32_t	esp_seq;	/* Sequence number */
963c602fabSXin LI 	/*variable size*/		/* (IV and) Payload data */
973c602fabSXin LI 	/*variable size*/		/* padding */
983c602fabSXin LI 	/*8bit*/			/* pad size */
993c602fabSXin LI 	/*8bit*/			/* next header */
1003c602fabSXin LI 	/*8bit*/			/* next header */
1013c602fabSXin LI 	/*variable size, 32bit bound*/	/* Authentication data */
1025b0fe478SBruce M Simpson };
103a90e161bSBill Fenner 
1045b0fe478SBruce M Simpson #ifdef HAVE_LIBCRYPTO
1053c602fabSXin LI union inaddr_u {
106*ee67461eSJoseph Mingrone 	nd_ipv4 in4;
107*ee67461eSJoseph Mingrone 	nd_ipv6 in6;
1083c602fabSXin LI };
1095b0fe478SBruce M Simpson struct sa_list {
1105b0fe478SBruce M Simpson 	struct sa_list	*next;
1113c602fabSXin LI 	u_int		daddr_version;
1123c602fabSXin LI 	union inaddr_u	daddr;
1133c602fabSXin LI 	uint32_t	spi;          /* if == 0, then IKEv2 */
11427df3f5dSRui Paulo 	int             initiator;
11527df3f5dSRui Paulo 	u_char          spii[8];      /* for IKEv2 */
11627df3f5dSRui Paulo 	u_char          spir[8];
1175b0fe478SBruce M Simpson 	const EVP_CIPHER *evp;
118*ee67461eSJoseph Mingrone 	u_int		ivlen;
119a90e161bSBill Fenner 	int		authlen;
12027df3f5dSRui Paulo 	u_char          authsecret[256];
12127df3f5dSRui Paulo 	int             authsecret_len;
122f4d0c64aSSam Leffler 	u_char		secret[256];  /* is that big enough for all secrets? */
1235b0fe478SBruce M Simpson 	int		secretlen;
124a90e161bSBill Fenner };
125a90e161bSBill Fenner 
1263340d773SGleb Smirnoff #ifndef HAVE_EVP_CIPHER_CTX_NEW
1273340d773SGleb Smirnoff /*
1283340d773SGleb Smirnoff  * Allocate an EVP_CIPHER_CTX.
1293340d773SGleb Smirnoff  * Used if we have an older version of OpenSSL that doesn't provide
1303340d773SGleb Smirnoff  * routines to allocate and free them.
1313340d773SGleb Smirnoff  */
1323340d773SGleb Smirnoff static EVP_CIPHER_CTX *
1333340d773SGleb Smirnoff EVP_CIPHER_CTX_new(void)
1343340d773SGleb Smirnoff {
1353340d773SGleb Smirnoff 	EVP_CIPHER_CTX *ctx;
1363340d773SGleb Smirnoff 
1373340d773SGleb Smirnoff 	ctx = malloc(sizeof(*ctx));
1383340d773SGleb Smirnoff 	if (ctx == NULL)
1393340d773SGleb Smirnoff 		return (NULL);
1403340d773SGleb Smirnoff 	memset(ctx, 0, sizeof(*ctx));
1413340d773SGleb Smirnoff 	return (ctx);
1423340d773SGleb Smirnoff }
1433340d773SGleb Smirnoff 
1443340d773SGleb Smirnoff static void
1453340d773SGleb Smirnoff EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
1463340d773SGleb Smirnoff {
1473340d773SGleb Smirnoff 	EVP_CIPHER_CTX_cleanup(ctx);
1483340d773SGleb Smirnoff 	free(ctx);
1493340d773SGleb Smirnoff }
1503340d773SGleb Smirnoff #endif
1513340d773SGleb Smirnoff 
152*ee67461eSJoseph Mingrone #ifdef HAVE_EVP_DECRYPTINIT_EX
1530bff6a5aSEd Maste /*
154*ee67461eSJoseph Mingrone  * Initialize the cipher by calling EVP_DecryptInit_ex(), because
155*ee67461eSJoseph Mingrone  * calling EVP_DecryptInit() will reset the cipher context, clearing
1560bff6a5aSEd Maste  * the cipher, so calling it twice, with the second call having a
157*ee67461eSJoseph Mingrone  * null cipher, will clear the already-set cipher.  EVP_DecryptInit_ex(),
1580bff6a5aSEd Maste  * however, won't reset the cipher context, so you can use it to specify
159*ee67461eSJoseph Mingrone  * the IV in a second call after a first call to EVP_DecryptInit_ex()
1600bff6a5aSEd Maste  * to set the cipher and the key.
1610bff6a5aSEd Maste  *
1620bff6a5aSEd Maste  * XXX - is there some reason why we need to make two calls?
1630bff6a5aSEd Maste  */
1640bff6a5aSEd Maste static int
1650bff6a5aSEd Maste set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
1660bff6a5aSEd Maste 		      const unsigned char *key,
167*ee67461eSJoseph Mingrone 		      const unsigned char *iv)
1680bff6a5aSEd Maste {
169*ee67461eSJoseph Mingrone 	return EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv);
1700bff6a5aSEd Maste }
1710bff6a5aSEd Maste #else
1720bff6a5aSEd Maste /*
173*ee67461eSJoseph Mingrone  * Initialize the cipher by calling EVP_DecryptInit(), because we don't
174*ee67461eSJoseph Mingrone  * have EVP_DecryptInit_ex(); we rely on it not trashing the context.
1750bff6a5aSEd Maste  */
1760bff6a5aSEd Maste static int
1770bff6a5aSEd Maste set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
1780bff6a5aSEd Maste 		      const unsigned char *key,
179*ee67461eSJoseph Mingrone 		      const unsigned char *iv)
1800bff6a5aSEd Maste {
181*ee67461eSJoseph Mingrone 	return EVP_DecryptInit(ctx, cipher, key, iv);
1820bff6a5aSEd Maste }
1830bff6a5aSEd Maste #endif
1840bff6a5aSEd Maste 
185*ee67461eSJoseph Mingrone static u_char *
186*ee67461eSJoseph Mingrone do_decrypt(netdissect_options *ndo, const char *caller, struct sa_list *sa,
187*ee67461eSJoseph Mingrone     const u_char *iv, const u_char *ct, unsigned int ctlen)
188*ee67461eSJoseph Mingrone {
189*ee67461eSJoseph Mingrone 	EVP_CIPHER_CTX *ctx;
190*ee67461eSJoseph Mingrone 	unsigned int block_size;
191*ee67461eSJoseph Mingrone 	unsigned int ptlen;
192*ee67461eSJoseph Mingrone 	u_char *pt;
193*ee67461eSJoseph Mingrone 	int len;
194*ee67461eSJoseph Mingrone 
195*ee67461eSJoseph Mingrone 	ctx = EVP_CIPHER_CTX_new();
196*ee67461eSJoseph Mingrone 	if (ctx == NULL) {
19727df3f5dSRui Paulo 		/*
198*ee67461eSJoseph Mingrone 		 * Failed to initialize the cipher context.
199*ee67461eSJoseph Mingrone 		 * From a look at the OpenSSL code, this appears to
200*ee67461eSJoseph Mingrone 		 * mean "couldn't allocate memory for the cipher context";
201*ee67461eSJoseph Mingrone 		 * note that we're not passing any parameters, so there's
202*ee67461eSJoseph Mingrone 		 * not much else it can mean.
20327df3f5dSRui Paulo 		 */
204*ee67461eSJoseph Mingrone 		(*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
205*ee67461eSJoseph Mingrone 		    "%s: can't allocate memory for cipher context", caller);
206*ee67461eSJoseph Mingrone 		return NULL;
207*ee67461eSJoseph Mingrone 	}
208*ee67461eSJoseph Mingrone 
209*ee67461eSJoseph Mingrone 	if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL) < 0) {
210*ee67461eSJoseph Mingrone 		EVP_CIPHER_CTX_free(ctx);
211*ee67461eSJoseph Mingrone 		(*ndo->ndo_warning)(ndo, "%s: espkey init failed", caller);
212*ee67461eSJoseph Mingrone 		return NULL;
213*ee67461eSJoseph Mingrone 	}
214*ee67461eSJoseph Mingrone 	if (set_cipher_parameters(ctx, NULL, NULL, iv) < 0) {
215*ee67461eSJoseph Mingrone 		EVP_CIPHER_CTX_free(ctx);
216*ee67461eSJoseph Mingrone 		(*ndo->ndo_warning)(ndo, "%s: IV init failed", caller);
217*ee67461eSJoseph Mingrone 		return NULL;
218*ee67461eSJoseph Mingrone 	}
219*ee67461eSJoseph Mingrone 
220*ee67461eSJoseph Mingrone 	/*
221*ee67461eSJoseph Mingrone 	 * At least as I read RFC 5996 section 3.14 and RFC 4303 section 2.4,
222*ee67461eSJoseph Mingrone 	 * if the cipher has a block size of which the ciphertext's size must
223*ee67461eSJoseph Mingrone 	 * be a multiple, the payload must be padded to make that happen, so
224*ee67461eSJoseph Mingrone 	 * the ciphertext length must be a multiple of the block size.  Fail
225*ee67461eSJoseph Mingrone 	 * if that's not the case.
226*ee67461eSJoseph Mingrone 	 */
227*ee67461eSJoseph Mingrone 	block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
228*ee67461eSJoseph Mingrone 	if ((ctlen % block_size) != 0) {
229*ee67461eSJoseph Mingrone 		EVP_CIPHER_CTX_free(ctx);
230*ee67461eSJoseph Mingrone 		(*ndo->ndo_warning)(ndo,
231*ee67461eSJoseph Mingrone 		    "%s: ciphertext size %u is not a multiple of the cipher block size %u",
232*ee67461eSJoseph Mingrone 		    caller, ctlen, block_size);
233*ee67461eSJoseph Mingrone 		return NULL;
234*ee67461eSJoseph Mingrone 	}
235*ee67461eSJoseph Mingrone 
236*ee67461eSJoseph Mingrone 	/*
237*ee67461eSJoseph Mingrone 	 * Attempt to allocate a buffer for the decrypted data, because
238*ee67461eSJoseph Mingrone 	 * we can't decrypt on top of the input buffer.
239*ee67461eSJoseph Mingrone 	 */
240*ee67461eSJoseph Mingrone 	ptlen = ctlen;
241*ee67461eSJoseph Mingrone 	pt = (u_char *)calloc(1, ptlen);
242*ee67461eSJoseph Mingrone 	if (pt == NULL) {
243*ee67461eSJoseph Mingrone 		EVP_CIPHER_CTX_free(ctx);
244*ee67461eSJoseph Mingrone 		(*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
245*ee67461eSJoseph Mingrone 		    "%s: can't allocate memory for decryption buffer", caller);
246*ee67461eSJoseph Mingrone 		return NULL;
247*ee67461eSJoseph Mingrone 	}
248*ee67461eSJoseph Mingrone 
249*ee67461eSJoseph Mingrone 	/*
250*ee67461eSJoseph Mingrone 	 * The size of the ciphertext handed to us is a multiple of the
251*ee67461eSJoseph Mingrone 	 * cipher block size, so we don't need to worry about padding.
252*ee67461eSJoseph Mingrone 	 */
253*ee67461eSJoseph Mingrone 	if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) {
254*ee67461eSJoseph Mingrone 		free(pt);
255*ee67461eSJoseph Mingrone 		EVP_CIPHER_CTX_free(ctx);
256*ee67461eSJoseph Mingrone 		(*ndo->ndo_warning)(ndo,
257*ee67461eSJoseph Mingrone 		    "%s: EVP_CIPHER_CTX_set_padding failed", caller);
258*ee67461eSJoseph Mingrone 		return NULL;
259*ee67461eSJoseph Mingrone 	}
260*ee67461eSJoseph Mingrone 	if (!EVP_DecryptUpdate(ctx, pt, &len, ct, ctlen)) {
261*ee67461eSJoseph Mingrone 		free(pt);
262*ee67461eSJoseph Mingrone 		EVP_CIPHER_CTX_free(ctx);
263*ee67461eSJoseph Mingrone 		(*ndo->ndo_warning)(ndo, "%s: EVP_DecryptUpdate failed",
264*ee67461eSJoseph Mingrone 		    caller);
265*ee67461eSJoseph Mingrone 		return NULL;
266*ee67461eSJoseph Mingrone 	}
267*ee67461eSJoseph Mingrone 	EVP_CIPHER_CTX_free(ctx);
268*ee67461eSJoseph Mingrone 	return pt;
269*ee67461eSJoseph Mingrone }
270*ee67461eSJoseph Mingrone 
271*ee67461eSJoseph Mingrone /*
272*ee67461eSJoseph Mingrone  * This will allocate a new buffer containing the decrypted data.
273*ee67461eSJoseph Mingrone  * It returns 1 on success and 0 on failure.
274*ee67461eSJoseph Mingrone  *
275*ee67461eSJoseph Mingrone  * It will push the new buffer and the values of ndo->ndo_packetp and
276*ee67461eSJoseph Mingrone  * ndo->ndo_snapend onto the buffer stack, and change ndo->ndo_packetp
277*ee67461eSJoseph Mingrone  * and ndo->ndo_snapend to refer to the new buffer.
278*ee67461eSJoseph Mingrone  *
279*ee67461eSJoseph Mingrone  * Our caller must pop the buffer off the stack when it's finished
280*ee67461eSJoseph Mingrone  * dissecting anything in it and before it does any dissection of
281*ee67461eSJoseph Mingrone  * anything in the old buffer.  That will free the new buffer.
282*ee67461eSJoseph Mingrone  */
283*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION
284*ee67461eSJoseph Mingrone int esp_decrypt_buffer_by_ikev2_print(netdissect_options *ndo,
28527df3f5dSRui Paulo 				      int initiator,
286*ee67461eSJoseph Mingrone 				      const u_char spii[8],
287*ee67461eSJoseph Mingrone 				      const u_char spir[8],
2883340d773SGleb Smirnoff 				      const u_char *buf, const u_char *end)
28927df3f5dSRui Paulo {
29027df3f5dSRui Paulo 	struct sa_list *sa;
2913340d773SGleb Smirnoff 	const u_char *iv;
292*ee67461eSJoseph Mingrone 	const u_char *ct;
293*ee67461eSJoseph Mingrone 	unsigned int ctlen;
294*ee67461eSJoseph Mingrone 	u_char *pt;
29527df3f5dSRui Paulo 
29627df3f5dSRui Paulo 	/* initiator arg is any non-zero value */
29727df3f5dSRui Paulo 	if(initiator) initiator=1;
29827df3f5dSRui Paulo 
29927df3f5dSRui Paulo 	/* see if we can find the SA, and if so, decode it */
30027df3f5dSRui Paulo 	for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
30127df3f5dSRui Paulo 		if (sa->spi == 0
30227df3f5dSRui Paulo 		    && initiator == sa->initiator
30327df3f5dSRui Paulo 		    && memcmp(spii, sa->spii, 8) == 0
30427df3f5dSRui Paulo 		    && memcmp(spir, sa->spir, 8) == 0)
30527df3f5dSRui Paulo 			break;
30627df3f5dSRui Paulo 	}
30727df3f5dSRui Paulo 
30827df3f5dSRui Paulo 	if(sa == NULL) return 0;
30927df3f5dSRui Paulo 	if(sa->evp == NULL) return 0;
31027df3f5dSRui Paulo 
31127df3f5dSRui Paulo 	/*
31227df3f5dSRui Paulo 	 * remove authenticator, and see if we still have something to
31327df3f5dSRui Paulo 	 * work with
31427df3f5dSRui Paulo 	 */
31527df3f5dSRui Paulo 	end = end - sa->authlen;
31627df3f5dSRui Paulo 	iv  = buf;
317*ee67461eSJoseph Mingrone 	ct = iv + sa->ivlen;
318*ee67461eSJoseph Mingrone 	ctlen = end-ct;
31927df3f5dSRui Paulo 
320*ee67461eSJoseph Mingrone 	if(end <= ct) return 0;
32127df3f5dSRui Paulo 
322*ee67461eSJoseph Mingrone 	pt = do_decrypt(ndo, __func__, sa, iv,
323*ee67461eSJoseph Mingrone 	    ct, ctlen);
324*ee67461eSJoseph Mingrone 	if (pt == NULL)
3253340d773SGleb Smirnoff 		return 0;
32639e421e8SCy Schubert 
32739e421e8SCy Schubert 	/*
328*ee67461eSJoseph Mingrone 	 * Switch to the output buffer for dissection, and save it
329*ee67461eSJoseph Mingrone 	 * on the buffer stack so it can be freed; our caller must
330*ee67461eSJoseph Mingrone 	 * pop it when done.
33139e421e8SCy Schubert 	 */
332*ee67461eSJoseph Mingrone 	if (!nd_push_buffer(ndo, pt, pt, ctlen)) {
333*ee67461eSJoseph Mingrone 		free(pt);
334*ee67461eSJoseph Mingrone 		(*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
335*ee67461eSJoseph Mingrone 			"%s: can't push buffer on buffer stack", __func__);
3360bff6a5aSEd Maste 	}
33727df3f5dSRui Paulo 
33827df3f5dSRui Paulo 	return 1;
33927df3f5dSRui Paulo }
340*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION
34127df3f5dSRui Paulo 
3421de50e9fSSam Leffler static void esp_print_addsa(netdissect_options *ndo,
343*ee67461eSJoseph Mingrone 			    const struct sa_list *sa, int sa_def)
3445b0fe478SBruce M Simpson {
3455b0fe478SBruce M Simpson 	/* copy the "sa" */
3465b0fe478SBruce M Simpson 
3475b0fe478SBruce M Simpson 	struct sa_list *nsa;
3485b0fe478SBruce M Simpson 
349*ee67461eSJoseph Mingrone 	/* malloc() return used in a 'struct sa_list': do not free() */
3505b0fe478SBruce M Simpson 	nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
3515b0fe478SBruce M Simpson 	if (nsa == NULL)
352*ee67461eSJoseph Mingrone 		(*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
353*ee67461eSJoseph Mingrone 				  "%s: malloc", __func__);
3545b0fe478SBruce M Simpson 
3555b0fe478SBruce M Simpson 	*nsa = *sa;
3565b0fe478SBruce M Simpson 
3575b0fe478SBruce M Simpson 	if (sa_def)
3581de50e9fSSam Leffler 		ndo->ndo_sa_default = nsa;
3595b0fe478SBruce M Simpson 
3601de50e9fSSam Leffler 	nsa->next = ndo->ndo_sa_list_head;
3611de50e9fSSam Leffler 	ndo->ndo_sa_list_head = nsa;
3625b0fe478SBruce M Simpson }
3635b0fe478SBruce M Simpson 
364a90e161bSBill Fenner 
365f4d0c64aSSam Leffler static u_int hexdigit(netdissect_options *ndo, char hex)
366a90e161bSBill Fenner {
3675b0fe478SBruce M Simpson 	if (hex >= '0' && hex <= '9')
368a90e161bSBill Fenner 		return (hex - '0');
3695b0fe478SBruce M Simpson 	else if (hex >= 'A' && hex <= 'F')
370a90e161bSBill Fenner 		return (hex - 'A' + 10);
3715b0fe478SBruce M Simpson 	else if (hex >= 'a' && hex <= 'f')
372a90e161bSBill Fenner 		return (hex - 'a' + 10);
3735b0fe478SBruce M Simpson 	else {
374*ee67461eSJoseph Mingrone 		(*ndo->ndo_error)(ndo, S_ERR_ND_ESP_SECRET,
375*ee67461eSJoseph Mingrone 				  "invalid hex digit %c in espsecret\n", hex);
376a90e161bSBill Fenner 	}
377a90e161bSBill Fenner }
378a90e161bSBill Fenner 
379f4d0c64aSSam Leffler static u_int hex2byte(netdissect_options *ndo, char *hexstring)
380a90e161bSBill Fenner {
381f4d0c64aSSam Leffler 	u_int byte;
382a90e161bSBill Fenner 
3831de50e9fSSam Leffler 	byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
384a90e161bSBill Fenner 	return byte;
385a90e161bSBill Fenner }
386a90e161bSBill Fenner 
3875b0fe478SBruce M Simpson /*
38827df3f5dSRui Paulo  * returns size of binary, 0 on failure.
38927df3f5dSRui Paulo  */
390*ee67461eSJoseph Mingrone static int
391*ee67461eSJoseph Mingrone espprint_decode_hex(netdissect_options *ndo,
392*ee67461eSJoseph Mingrone 		    u_char *binbuf, unsigned int binbuf_len, char *hex)
39327df3f5dSRui Paulo {
39427df3f5dSRui Paulo 	unsigned int len;
39527df3f5dSRui Paulo 	int i;
39627df3f5dSRui Paulo 
39727df3f5dSRui Paulo 	len = strlen(hex) / 2;
39827df3f5dSRui Paulo 
39927df3f5dSRui Paulo 	if (len > binbuf_len) {
400*ee67461eSJoseph Mingrone 		(*ndo->ndo_warning)(ndo, "secret is too big: %u\n", len);
40127df3f5dSRui Paulo 		return 0;
40227df3f5dSRui Paulo 	}
40327df3f5dSRui Paulo 
40427df3f5dSRui Paulo 	i = 0;
40527df3f5dSRui Paulo 	while (hex[0] != '\0' && hex[1]!='\0') {
40627df3f5dSRui Paulo 		binbuf[i] = hex2byte(ndo, hex);
40727df3f5dSRui Paulo 		hex += 2;
40827df3f5dSRui Paulo 		i++;
40927df3f5dSRui Paulo 	}
41027df3f5dSRui Paulo 
41127df3f5dSRui Paulo 	return i;
41227df3f5dSRui Paulo }
41327df3f5dSRui Paulo 
41427df3f5dSRui Paulo /*
4155b0fe478SBruce M Simpson  * decode the form:    SPINUM@IP <tab> ALGONAME:0xsecret
41627df3f5dSRui Paulo  */
41727df3f5dSRui Paulo 
418*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION
41927df3f5dSRui Paulo static int
42027df3f5dSRui Paulo espprint_decode_encalgo(netdissect_options *ndo,
42127df3f5dSRui Paulo 			char *decode, struct sa_list *sa)
42227df3f5dSRui Paulo {
42327df3f5dSRui Paulo 	size_t i;
42427df3f5dSRui Paulo 	const EVP_CIPHER *evp;
42527df3f5dSRui Paulo 	int authlen = 0;
42627df3f5dSRui Paulo 	char *colon, *p;
42727df3f5dSRui Paulo 
42827df3f5dSRui Paulo 	colon = strchr(decode, ':');
42927df3f5dSRui Paulo 	if (colon == NULL) {
43027df3f5dSRui Paulo 		(*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
43127df3f5dSRui Paulo 		return 0;
43227df3f5dSRui Paulo 	}
43327df3f5dSRui Paulo 	*colon = '\0';
43427df3f5dSRui Paulo 
43527df3f5dSRui Paulo 	if (strlen(decode) > strlen("-hmac96") &&
43627df3f5dSRui Paulo 	    !strcmp(decode + strlen(decode) - strlen("-hmac96"),
43727df3f5dSRui Paulo 		    "-hmac96")) {
43827df3f5dSRui Paulo 		p = strstr(decode, "-hmac96");
43927df3f5dSRui Paulo 		*p = '\0';
44027df3f5dSRui Paulo 		authlen = 12;
44127df3f5dSRui Paulo 	}
44227df3f5dSRui Paulo 	if (strlen(decode) > strlen("-cbc") &&
44327df3f5dSRui Paulo 	    !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
44427df3f5dSRui Paulo 		p = strstr(decode, "-cbc");
44527df3f5dSRui Paulo 		*p = '\0';
44627df3f5dSRui Paulo 	}
44727df3f5dSRui Paulo 	evp = EVP_get_cipherbyname(decode);
44827df3f5dSRui Paulo 
44927df3f5dSRui Paulo 	if (!evp) {
45027df3f5dSRui Paulo 		(*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
45127df3f5dSRui Paulo 		sa->evp = NULL;
45227df3f5dSRui Paulo 		sa->authlen = 0;
45327df3f5dSRui Paulo 		sa->ivlen = 0;
45427df3f5dSRui Paulo 		return 0;
45527df3f5dSRui Paulo 	}
45627df3f5dSRui Paulo 
45727df3f5dSRui Paulo 	sa->evp = evp;
45827df3f5dSRui Paulo 	sa->authlen = authlen;
459*ee67461eSJoseph Mingrone 	/* This returns an int, but it should never be negative */
46027df3f5dSRui Paulo 	sa->ivlen = EVP_CIPHER_iv_length(evp);
46127df3f5dSRui Paulo 
46227df3f5dSRui Paulo 	colon++;
46327df3f5dSRui Paulo 	if (colon[0] == '0' && colon[1] == 'x') {
46427df3f5dSRui Paulo 		/* decode some hex! */
46527df3f5dSRui Paulo 
46627df3f5dSRui Paulo 		colon += 2;
46727df3f5dSRui Paulo 		sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon);
46827df3f5dSRui Paulo 		if(sa->secretlen == 0) return 0;
46927df3f5dSRui Paulo 	} else {
47027df3f5dSRui Paulo 		i = strlen(colon);
47127df3f5dSRui Paulo 
47227df3f5dSRui Paulo 		if (i < sizeof(sa->secret)) {
47327df3f5dSRui Paulo 			memcpy(sa->secret, colon, i);
47427df3f5dSRui Paulo 			sa->secretlen = i;
47527df3f5dSRui Paulo 		} else {
47627df3f5dSRui Paulo 			memcpy(sa->secret, colon, sizeof(sa->secret));
47727df3f5dSRui Paulo 			sa->secretlen = sizeof(sa->secret);
47827df3f5dSRui Paulo 		}
47927df3f5dSRui Paulo 	}
48027df3f5dSRui Paulo 
48127df3f5dSRui Paulo 	return 1;
48227df3f5dSRui Paulo }
483*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION
48427df3f5dSRui Paulo 
48527df3f5dSRui Paulo /*
48639e421e8SCy Schubert  * for the moment, ignore the auth algorithm, just hard code the authenticator
48727df3f5dSRui Paulo  * length. Need to research how openssl looks up HMAC stuff.
48827df3f5dSRui Paulo  */
48927df3f5dSRui Paulo static int
49027df3f5dSRui Paulo espprint_decode_authalgo(netdissect_options *ndo,
49127df3f5dSRui Paulo 			 char *decode, struct sa_list *sa)
49227df3f5dSRui Paulo {
49327df3f5dSRui Paulo 	char *colon;
49427df3f5dSRui Paulo 
49527df3f5dSRui Paulo 	colon = strchr(decode, ':');
49627df3f5dSRui Paulo 	if (colon == NULL) {
49727df3f5dSRui Paulo 		(*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
49827df3f5dSRui Paulo 		return 0;
49927df3f5dSRui Paulo 	}
50027df3f5dSRui Paulo 	*colon = '\0';
50127df3f5dSRui Paulo 
502*ee67461eSJoseph Mingrone 	if(ascii_strcasecmp(decode,"sha1") == 0 ||
503*ee67461eSJoseph Mingrone 	   ascii_strcasecmp(decode,"md5") == 0) {
50427df3f5dSRui Paulo 		sa->authlen = 12;
50527df3f5dSRui Paulo 	}
50627df3f5dSRui Paulo 	return 1;
50727df3f5dSRui Paulo }
50827df3f5dSRui Paulo 
50927df3f5dSRui Paulo static void esp_print_decode_ikeline(netdissect_options *ndo, char *line,
51027df3f5dSRui Paulo 				     const char *file, int lineno)
51127df3f5dSRui Paulo {
51227df3f5dSRui Paulo 	/* it's an IKEv2 secret, store it instead */
51327df3f5dSRui Paulo 	struct sa_list sa1;
51427df3f5dSRui Paulo 
51527df3f5dSRui Paulo 	char *init;
51627df3f5dSRui Paulo 	char *icookie, *rcookie;
51727df3f5dSRui Paulo 	int   ilen, rlen;
51827df3f5dSRui Paulo 	char *authkey;
51927df3f5dSRui Paulo 	char *enckey;
52027df3f5dSRui Paulo 
52127df3f5dSRui Paulo 	init = strsep(&line, " \t");
52227df3f5dSRui Paulo 	icookie = strsep(&line, " \t");
52327df3f5dSRui Paulo 	rcookie = strsep(&line, " \t");
52427df3f5dSRui Paulo 	authkey = strsep(&line, " \t");
52527df3f5dSRui Paulo 	enckey  = strsep(&line, " \t");
52627df3f5dSRui Paulo 
52727df3f5dSRui Paulo 	/* if any fields are missing */
52827df3f5dSRui Paulo 	if(!init || !icookie || !rcookie || !authkey || !enckey) {
52927df3f5dSRui Paulo 		(*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u",
53027df3f5dSRui Paulo 				    file, lineno);
53127df3f5dSRui Paulo 
53227df3f5dSRui Paulo 		return;
53327df3f5dSRui Paulo 	}
53427df3f5dSRui Paulo 
53527df3f5dSRui Paulo 	ilen = strlen(icookie);
53627df3f5dSRui Paulo 	rlen = strlen(rcookie);
53727df3f5dSRui Paulo 
53827df3f5dSRui Paulo 	if((init[0]!='I' && init[0]!='R')
53927df3f5dSRui Paulo 	   || icookie[0]!='0' || icookie[1]!='x'
54027df3f5dSRui Paulo 	   || rcookie[0]!='0' || rcookie[1]!='x'
54127df3f5dSRui Paulo 	   || ilen!=18
54227df3f5dSRui Paulo 	   || rlen!=18) {
54327df3f5dSRui Paulo 		(*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.",
54427df3f5dSRui Paulo 				    file, lineno);
54527df3f5dSRui Paulo 
54627df3f5dSRui Paulo 		(*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)",
54727df3f5dSRui Paulo 				    init, icookie, ilen, rcookie, rlen);
54827df3f5dSRui Paulo 
54927df3f5dSRui Paulo 		return;
55027df3f5dSRui Paulo 	}
55127df3f5dSRui Paulo 
55227df3f5dSRui Paulo 	sa1.spi = 0;
55327df3f5dSRui Paulo 	sa1.initiator = (init[0] == 'I');
55427df3f5dSRui Paulo 	if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8)
55527df3f5dSRui Paulo 		return;
55627df3f5dSRui Paulo 
55727df3f5dSRui Paulo 	if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8)
55827df3f5dSRui Paulo 		return;
55927df3f5dSRui Paulo 
56027df3f5dSRui Paulo 	if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return;
56127df3f5dSRui Paulo 
56227df3f5dSRui Paulo 	if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return;
56327df3f5dSRui Paulo 
56427df3f5dSRui Paulo 	esp_print_addsa(ndo, &sa1, FALSE);
56527df3f5dSRui Paulo }
56627df3f5dSRui Paulo 
56727df3f5dSRui Paulo /*
5685b0fe478SBruce M Simpson  *
5695b0fe478SBruce M Simpson  * special form: file /name
5705b0fe478SBruce M Simpson  * causes us to go read from this file instead.
5715b0fe478SBruce M Simpson  *
5725b0fe478SBruce M Simpson  */
57327df3f5dSRui Paulo static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
57427df3f5dSRui Paulo 				       const char *file, int lineno)
575a90e161bSBill Fenner {
5765b0fe478SBruce M Simpson 	struct sa_list sa1;
5775b0fe478SBruce M Simpson 	int sa_def;
578a90e161bSBill Fenner 
5795b0fe478SBruce M Simpson 	char *spikey;
5805b0fe478SBruce M Simpson 	char *decode;
5815b0fe478SBruce M Simpson 
5825b0fe478SBruce M Simpson 	spikey = strsep(&line, " \t");
5835b0fe478SBruce M Simpson 	sa_def = 0;
5845b0fe478SBruce M Simpson 	memset(&sa1, 0, sizeof(struct sa_list));
5855b0fe478SBruce M Simpson 
5865b0fe478SBruce M Simpson 	/* if there is only one token, then it is an algo:key token */
5875b0fe478SBruce M Simpson 	if (line == NULL) {
5885b0fe478SBruce M Simpson 		decode = spikey;
5895b0fe478SBruce M Simpson 		spikey = NULL;
5903c602fabSXin LI 		/* sa1.daddr.version = 0; */
5915b0fe478SBruce M Simpson 		/* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
5925b0fe478SBruce M Simpson 		/* sa1.spi = 0; */
5935b0fe478SBruce M Simpson 		sa_def    = 1;
5945b0fe478SBruce M Simpson 	} else
5955b0fe478SBruce M Simpson 		decode = line;
5965b0fe478SBruce M Simpson 
5973340d773SGleb Smirnoff 	if (spikey && ascii_strcasecmp(spikey, "file") == 0) {
5985b0fe478SBruce M Simpson 		/* open file and read it */
5995b0fe478SBruce M Simpson 		FILE *secretfile;
6005b0fe478SBruce M Simpson 		char  fileline[1024];
6013340d773SGleb Smirnoff 		int   subfile_lineno=0;
6025b0fe478SBruce M Simpson 		char  *nl;
60327df3f5dSRui Paulo 		char *filename = line;
6045b0fe478SBruce M Simpson 
60527df3f5dSRui Paulo 		secretfile = fopen(filename, FOPEN_READ_TXT);
6065b0fe478SBruce M Simpson 		if (secretfile == NULL) {
607*ee67461eSJoseph Mingrone 			(*ndo->ndo_error)(ndo, S_ERR_ND_OPEN_FILE,
608*ee67461eSJoseph Mingrone 					  "%s: can't open %s: %s\n",
609*ee67461eSJoseph Mingrone 					  __func__, filename, strerror(errno));
6105b0fe478SBruce M Simpson 		}
6115b0fe478SBruce M Simpson 
6125b0fe478SBruce M Simpson 		while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
6133340d773SGleb Smirnoff 			subfile_lineno++;
6145b0fe478SBruce M Simpson 			/* remove newline from the line */
6155b0fe478SBruce M Simpson 			nl = strchr(fileline, '\n');
6165b0fe478SBruce M Simpson 			if (nl)
6175b0fe478SBruce M Simpson 				*nl = '\0';
6185b0fe478SBruce M Simpson 			if (fileline[0] == '#') continue;
6195b0fe478SBruce M Simpson 			if (fileline[0] == '\0') continue;
6205b0fe478SBruce M Simpson 
6213340d773SGleb Smirnoff 			esp_print_decode_onesecret(ndo, fileline, filename, subfile_lineno);
6225b0fe478SBruce M Simpson 		}
6235b0fe478SBruce M Simpson 		fclose(secretfile);
6245b0fe478SBruce M Simpson 
625a90e161bSBill Fenner 		return;
626a90e161bSBill Fenner 	}
627a90e161bSBill Fenner 
6283340d773SGleb Smirnoff 	if (spikey && ascii_strcasecmp(spikey, "ikev2") == 0) {
62927df3f5dSRui Paulo 		esp_print_decode_ikeline(ndo, line, file, lineno);
63027df3f5dSRui Paulo 		return;
63127df3f5dSRui Paulo 	}
63227df3f5dSRui Paulo 
6335b0fe478SBruce M Simpson 	if (spikey) {
63427df3f5dSRui Paulo 
6355b0fe478SBruce M Simpson 		char *spistr, *foo;
6363c602fabSXin LI 		uint32_t spino;
6375b0fe478SBruce M Simpson 
6385b0fe478SBruce M Simpson 		spistr = strsep(&spikey, "@");
63939e421e8SCy Schubert 		if (spistr == NULL) {
64039e421e8SCy Schubert 			(*ndo->ndo_warning)(ndo, "print_esp: failed to find the @ token");
64139e421e8SCy Schubert 			return;
64239e421e8SCy Schubert 		}
6435b0fe478SBruce M Simpson 
6445b0fe478SBruce M Simpson 		spino = strtoul(spistr, &foo, 0);
6455b0fe478SBruce M Simpson 		if (spistr == foo || !spikey) {
6461de50e9fSSam Leffler 			(*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
647a90e161bSBill Fenner 			return;
648a90e161bSBill Fenner 		}
649a90e161bSBill Fenner 
6505b0fe478SBruce M Simpson 		sa1.spi = spino;
6515b0fe478SBruce M Simpson 
6523340d773SGleb Smirnoff 		if (strtoaddr6(spikey, &sa1.daddr.in6) == 1) {
6533c602fabSXin LI 			sa1.daddr_version = 6;
6543340d773SGleb Smirnoff 		} else if (strtoaddr(spikey, &sa1.daddr.in4) == 1) {
6553c602fabSXin LI 			sa1.daddr_version = 4;
6565b0fe478SBruce M Simpson 		} else {
6571de50e9fSSam Leffler 			(*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
6585b0fe478SBruce M Simpson 			return;
6595b0fe478SBruce M Simpson 		}
6605b0fe478SBruce M Simpson 	}
6615b0fe478SBruce M Simpson 
6625b0fe478SBruce M Simpson 	if (decode) {
6635b0fe478SBruce M Simpson 		/* skip any blank spaces */
664*ee67461eSJoseph Mingrone 		while (*decode == ' ' || *decode == '\t' || *decode == '\r' || *decode == '\n')
6655b0fe478SBruce M Simpson 			decode++;
6665b0fe478SBruce M Simpson 
66727df3f5dSRui Paulo 		if(!espprint_decode_encalgo(ndo, decode, &sa1)) {
668a90e161bSBill Fenner 			return;
669a90e161bSBill Fenner 		}
670a90e161bSBill Fenner 	}
671a90e161bSBill Fenner 
6721de50e9fSSam Leffler 	esp_print_addsa(ndo, &sa1, sa_def);
6735b0fe478SBruce M Simpson }
6745b0fe478SBruce M Simpson 
675*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION
6761de50e9fSSam Leffler static void esp_init(netdissect_options *ndo _U_)
6775b0fe478SBruce M Simpson {
6783340d773SGleb Smirnoff 	/*
6793340d773SGleb Smirnoff 	 * 0.9.6 doesn't appear to define OPENSSL_API_COMPAT, so
6803340d773SGleb Smirnoff 	 * we check whether it's undefined or it's less than the
6813340d773SGleb Smirnoff 	 * value for 1.1.0.
6823340d773SGleb Smirnoff 	 */
6833340d773SGleb Smirnoff #if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < 0x10100000L
6845b0fe478SBruce M Simpson 	OpenSSL_add_all_algorithms();
6853340d773SGleb Smirnoff #endif
6865b0fe478SBruce M Simpson 	EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
6875b0fe478SBruce M Simpson }
688*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION
68927df3f5dSRui Paulo 
690*ee67461eSJoseph Mingrone void esp_decodesecret_print(netdissect_options *ndo)
69127df3f5dSRui Paulo {
69227df3f5dSRui Paulo 	char *line;
69327df3f5dSRui Paulo 	char *p;
69427df3f5dSRui Paulo 	static int initialized = 0;
69527df3f5dSRui Paulo 
69627df3f5dSRui Paulo 	if (!initialized) {
69727df3f5dSRui Paulo 		esp_init(ndo);
69827df3f5dSRui Paulo 		initialized = 1;
69927df3f5dSRui Paulo 	}
70027df3f5dSRui Paulo 
70127df3f5dSRui Paulo 	p = ndo->ndo_espsecret;
70227df3f5dSRui Paulo 
70327df3f5dSRui Paulo 	while (p && p[0] != '\0') {
70427df3f5dSRui Paulo 		/* pick out the first line or first thing until a comma */
70527df3f5dSRui Paulo 		if ((line = strsep(&p, "\n,")) == NULL) {
70627df3f5dSRui Paulo 			line = p;
70727df3f5dSRui Paulo 			p = NULL;
70827df3f5dSRui Paulo 		}
70927df3f5dSRui Paulo 
71027df3f5dSRui Paulo 		esp_print_decode_onesecret(ndo, line, "cmdline", 0);
71127df3f5dSRui Paulo 	}
71227df3f5dSRui Paulo 
71327df3f5dSRui Paulo 	ndo->ndo_espsecret = NULL;
71427df3f5dSRui Paulo }
71527df3f5dSRui Paulo 
7165b0fe478SBruce M Simpson #endif
7175b0fe478SBruce M Simpson 
7183c602fabSXin LI #ifdef HAVE_LIBCRYPTO
719*ee67461eSJoseph Mingrone #define USED_IF_LIBCRYPTO
720*ee67461eSJoseph Mingrone #else
721*ee67461eSJoseph Mingrone #define USED_IF_LIBCRYPTO _U_
7223c602fabSXin LI #endif
723*ee67461eSJoseph Mingrone 
724*ee67461eSJoseph Mingrone #ifdef HAVE_LIBCRYPTO
725*ee67461eSJoseph Mingrone DIAG_OFF_DEPRECATION
726*ee67461eSJoseph Mingrone #endif
727*ee67461eSJoseph Mingrone void
7281de50e9fSSam Leffler esp_print(netdissect_options *ndo,
729*ee67461eSJoseph Mingrone 	  const u_char *bp, u_int length,
730*ee67461eSJoseph Mingrone 	  const u_char *bp2 USED_IF_LIBCRYPTO,
731*ee67461eSJoseph Mingrone 	  u_int ver USED_IF_LIBCRYPTO,
732*ee67461eSJoseph Mingrone 	  int fragmented USED_IF_LIBCRYPTO,
733*ee67461eSJoseph Mingrone 	  u_int ttl_hl USED_IF_LIBCRYPTO)
7345b0fe478SBruce M Simpson {
735*ee67461eSJoseph Mingrone 	const struct newesp *esp;
736*ee67461eSJoseph Mingrone 	const u_char *ep;
7375b0fe478SBruce M Simpson #ifdef HAVE_LIBCRYPTO
7383340d773SGleb Smirnoff 	const struct ip *ip;
7395b0fe478SBruce M Simpson 	struct sa_list *sa = NULL;
7403340d773SGleb Smirnoff 	const struct ip6_hdr *ip6 = NULL;
741*ee67461eSJoseph Mingrone 	const u_char *iv;
742*ee67461eSJoseph Mingrone 	u_int ivlen;
743*ee67461eSJoseph Mingrone 	u_int payloadlen;
744*ee67461eSJoseph Mingrone 	const u_char *ct;
745*ee67461eSJoseph Mingrone 	u_char *pt;
746*ee67461eSJoseph Mingrone 	u_int padlen;
747*ee67461eSJoseph Mingrone 	u_int nh;
7485b0fe478SBruce M Simpson #endif
749b0453382SBill Fenner 
750*ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "esp";
7513340d773SGleb Smirnoff 	esp = (const struct newesp *)bp;
7525b0fe478SBruce M Simpson 
753685295f4SBill Fenner 	/* 'ep' points to the end of available data. */
7541de50e9fSSam Leffler 	ep = ndo->ndo_snapend;
755b0453382SBill Fenner 
7563340d773SGleb Smirnoff 	if ((const u_char *)(esp + 1) >= ep) {
757*ee67461eSJoseph Mingrone 		nd_print_trunc(ndo);
758*ee67461eSJoseph Mingrone 		return;
759b0453382SBill Fenner 	}
760*ee67461eSJoseph Mingrone 	ND_PRINT("ESP(spi=0x%08x", GET_BE_U_4(esp->esp_spi));
761*ee67461eSJoseph Mingrone 	ND_PRINT(",seq=0x%x)", GET_BE_U_4(esp->esp_seq));
762*ee67461eSJoseph Mingrone 	ND_PRINT(", length %u", length);
763b0453382SBill Fenner 
764*ee67461eSJoseph Mingrone #ifdef HAVE_LIBCRYPTO
765*ee67461eSJoseph Mingrone 	/* initialize SAs */
7661de50e9fSSam Leffler 	if (ndo->ndo_sa_list_head == NULL) {
7671de50e9fSSam Leffler 		if (!ndo->ndo_espsecret)
768*ee67461eSJoseph Mingrone 			return;
769b0453382SBill Fenner 
770*ee67461eSJoseph Mingrone 		esp_decodesecret_print(ndo);
771a90e161bSBill Fenner 	}
7725b0fe478SBruce M Simpson 
7731de50e9fSSam Leffler 	if (ndo->ndo_sa_list_head == NULL)
774*ee67461eSJoseph Mingrone 		return;
775b0453382SBill Fenner 
7763340d773SGleb Smirnoff 	ip = (const struct ip *)bp2;
777*ee67461eSJoseph Mingrone 	switch (ver) {
778b0453382SBill Fenner 	case 6:
7793340d773SGleb Smirnoff 		ip6 = (const struct ip6_hdr *)bp2;
780b0453382SBill Fenner 		/* we do not attempt to decrypt jumbograms */
781*ee67461eSJoseph Mingrone 		if (!GET_BE_U_2(ip6->ip6_plen))
782*ee67461eSJoseph Mingrone 			return;
783*ee67461eSJoseph Mingrone 		/* XXX - check whether it's fragmented? */
784b0453382SBill Fenner 		/* if we can't get nexthdr, we do not need to decrypt it */
7855b0fe478SBruce M Simpson 
7865b0fe478SBruce M Simpson 		/* see if we can find the SA, and if so, decode it */
7871de50e9fSSam Leffler 		for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
788*ee67461eSJoseph Mingrone 			if (sa->spi == GET_BE_U_4(esp->esp_spi) &&
7893c602fabSXin LI 			    sa->daddr_version == 6 &&
7903c602fabSXin LI 			    UNALIGNED_MEMCMP(&sa->daddr.in6, &ip6->ip6_dst,
791*ee67461eSJoseph Mingrone 				   sizeof(nd_ipv6)) == 0) {
7925b0fe478SBruce M Simpson 				break;
7935b0fe478SBruce M Simpson 			}
7945b0fe478SBruce M Simpson 		}
795b0453382SBill Fenner 		break;
796b0453382SBill Fenner 	case 4:
797a90e161bSBill Fenner 		/* nexthdr & padding are in the last fragment */
798*ee67461eSJoseph Mingrone 		if (fragmented)
799*ee67461eSJoseph Mingrone 			return;
8005b0fe478SBruce M Simpson 
8015b0fe478SBruce M Simpson 		/* see if we can find the SA, and if so, decode it */
8021de50e9fSSam Leffler 		for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
803*ee67461eSJoseph Mingrone 			if (sa->spi == GET_BE_U_4(esp->esp_spi) &&
8043c602fabSXin LI 			    sa->daddr_version == 4 &&
8053c602fabSXin LI 			    UNALIGNED_MEMCMP(&sa->daddr.in4, &ip->ip_dst,
806*ee67461eSJoseph Mingrone 				   sizeof(nd_ipv4)) == 0) {
8075b0fe478SBruce M Simpson 				break;
8085b0fe478SBruce M Simpson 			}
8095b0fe478SBruce M Simpson 		}
810b0453382SBill Fenner 		break;
811b0453382SBill Fenner 	default:
812*ee67461eSJoseph Mingrone 		return;
813b0453382SBill Fenner 	}
814b0453382SBill Fenner 
8155b0fe478SBruce M Simpson 	/* if we didn't find the specific one, then look for
8165b0fe478SBruce M Simpson 	 * an unspecified one.
8175b0fe478SBruce M Simpson 	 */
8185b0fe478SBruce M Simpson 	if (sa == NULL)
8191de50e9fSSam Leffler 		sa = ndo->ndo_sa_default;
8205b0fe478SBruce M Simpson 
8215b0fe478SBruce M Simpson 	/* if not found fail */
8225b0fe478SBruce M Simpson 	if (sa == NULL)
823*ee67461eSJoseph Mingrone 		return;
824b0453382SBill Fenner 
8250bff6a5aSEd Maste 	/* pointer to the IV, if there is one */
826*ee67461eSJoseph Mingrone 	iv = (const u_char *)(esp + 1) + 0;
8270bff6a5aSEd Maste 	/* length of the IV, if there is one; 0, if there isn't */
8285b0fe478SBruce M Simpson 	ivlen = sa->ivlen;
829*ee67461eSJoseph Mingrone 
830*ee67461eSJoseph Mingrone 	/*
831*ee67461eSJoseph Mingrone 	 * Get a pointer to the ciphertext.
832*ee67461eSJoseph Mingrone 	 *
833*ee67461eSJoseph Mingrone 	 * p points to the beginning of the payload, i.e. to the
834*ee67461eSJoseph Mingrone 	 * initialization vector, so if we skip past the initialization
835*ee67461eSJoseph Mingrone 	 * vector, it points to the beginning of the ciphertext.
836*ee67461eSJoseph Mingrone 	 */
837*ee67461eSJoseph Mingrone 	ct = iv + ivlen;
838*ee67461eSJoseph Mingrone 
839*ee67461eSJoseph Mingrone 	/*
840*ee67461eSJoseph Mingrone 	 * Make sure the authentication data/integrity check value length
841*ee67461eSJoseph Mingrone 	 * isn't bigger than the total amount of data available after
842*ee67461eSJoseph Mingrone 	 * the ESP header and initialization vector is removed and,
843*ee67461eSJoseph Mingrone 	 * if not, slice the authentication data/ICV off.
844*ee67461eSJoseph Mingrone 	 */
845*ee67461eSJoseph Mingrone 	if (ep - ct < sa->authlen) {
846*ee67461eSJoseph Mingrone 		nd_print_trunc(ndo);
847*ee67461eSJoseph Mingrone 		return;
848*ee67461eSJoseph Mingrone 	}
8491de50e9fSSam Leffler 	ep = ep - sa->authlen;
850b0453382SBill Fenner 
851*ee67461eSJoseph Mingrone 	/*
852*ee67461eSJoseph Mingrone 	 * Calculate the length of the ciphertext.  ep points to
853*ee67461eSJoseph Mingrone 	 * the beginning of the authentication data/integrity check
854*ee67461eSJoseph Mingrone 	 * value, i.e. right past the end of the ciphertext;
855*ee67461eSJoseph Mingrone 	 */
856*ee67461eSJoseph Mingrone 	payloadlen = ep - ct;
8575b0fe478SBruce M Simpson 
858*ee67461eSJoseph Mingrone 	if (sa->evp == NULL)
859*ee67461eSJoseph Mingrone 		return;
8600bff6a5aSEd Maste 
8610bff6a5aSEd Maste 	/*
862*ee67461eSJoseph Mingrone 	 * If the next header value is past the end of the available
863*ee67461eSJoseph Mingrone 	 * data, we won't be able to fetch it once we've decrypted
864*ee67461eSJoseph Mingrone 	 * the ciphertext, so there's no point in decrypting the data.
865*ee67461eSJoseph Mingrone 	 *
866*ee67461eSJoseph Mingrone 	 * Report it as truncation.
8670bff6a5aSEd Maste 	 */
868*ee67461eSJoseph Mingrone 	if (!ND_TTEST_1(ep - 1)) {
869*ee67461eSJoseph Mingrone 		nd_print_trunc(ndo);
870*ee67461eSJoseph Mingrone 		return;
8710bff6a5aSEd Maste 	}
8720bff6a5aSEd Maste 
873*ee67461eSJoseph Mingrone 	pt = do_decrypt(ndo, __func__, sa, iv, ct, payloadlen);
874*ee67461eSJoseph Mingrone 	if (pt == NULL)
875*ee67461eSJoseph Mingrone 		return;
876*ee67461eSJoseph Mingrone 
8770bff6a5aSEd Maste 	/*
878*ee67461eSJoseph Mingrone 	 * Switch to the output buffer for dissection, and
879*ee67461eSJoseph Mingrone 	 * save it on the buffer stack so it can be freed.
8800bff6a5aSEd Maste 	 */
881*ee67461eSJoseph Mingrone 	if (!nd_push_buffer(ndo, pt, pt, payloadlen)) {
882*ee67461eSJoseph Mingrone 		free(pt);
883*ee67461eSJoseph Mingrone 		(*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
884*ee67461eSJoseph Mingrone 			"%s: can't push buffer on buffer stack", __func__);
885*ee67461eSJoseph Mingrone 	}
886b0453382SBill Fenner 
887*ee67461eSJoseph Mingrone 	/*
888*ee67461eSJoseph Mingrone 	 * Sanity check for pad length; if it, plus 2 for the pad
889*ee67461eSJoseph Mingrone 	 * length and next header fields, is bigger than the ciphertext
890*ee67461eSJoseph Mingrone 	 * length (which is also the plaintext length), it's too big.
891*ee67461eSJoseph Mingrone 	 *
892*ee67461eSJoseph Mingrone 	 * XXX - the check can fail if the packet is corrupt *or* if
893*ee67461eSJoseph Mingrone 	 * it was not decrypted with the correct key, so that the
894*ee67461eSJoseph Mingrone 	 * "plaintext" is not what was being sent.
895*ee67461eSJoseph Mingrone 	 */
896*ee67461eSJoseph Mingrone 	padlen = GET_U_1(pt + payloadlen - 2);
897*ee67461eSJoseph Mingrone 	if (padlen + 2 > payloadlen) {
898*ee67461eSJoseph Mingrone 		nd_print_trunc(ndo);
899*ee67461eSJoseph Mingrone 		return;
900*ee67461eSJoseph Mingrone 	}
901b0453382SBill Fenner 
902*ee67461eSJoseph Mingrone 	/* Get the next header */
903*ee67461eSJoseph Mingrone 	nh = GET_U_1(pt + payloadlen - 1);
904a90e161bSBill Fenner 
905*ee67461eSJoseph Mingrone 	ND_PRINT(": ");
906b0453382SBill Fenner 
907*ee67461eSJoseph Mingrone 	/*
908*ee67461eSJoseph Mingrone 	 * Don't put padding + padding length(1 byte) + next header(1 byte)
909*ee67461eSJoseph Mingrone 	 * in the buffer because they are not part of the plaintext to decode.
910*ee67461eSJoseph Mingrone 	 */
911*ee67461eSJoseph Mingrone 	if (!nd_push_snaplen(ndo, pt, payloadlen - (padlen + 2))) {
912*ee67461eSJoseph Mingrone 		(*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
913*ee67461eSJoseph Mingrone 			"%s: can't push snaplen on buffer stack", __func__);
914*ee67461eSJoseph Mingrone 	}
915*ee67461eSJoseph Mingrone 
916*ee67461eSJoseph Mingrone 	/* Now dissect the plaintext. */
917*ee67461eSJoseph Mingrone 	ip_demux_print(ndo, pt, payloadlen - (padlen + 2), ver, fragmented,
918*ee67461eSJoseph Mingrone 		       ttl_hl, nh, bp2);
919*ee67461eSJoseph Mingrone 
920*ee67461eSJoseph Mingrone 	/* Pop the buffer, freeing it. */
921*ee67461eSJoseph Mingrone 	nd_pop_packet_info(ndo);
922*ee67461eSJoseph Mingrone 	/* Pop the nd_push_snaplen */
923*ee67461eSJoseph Mingrone 	nd_pop_packet_info(ndo);
9245b0fe478SBruce M Simpson #endif
925b0453382SBill Fenner }
9263c602fabSXin LI #ifdef HAVE_LIBCRYPTO
927*ee67461eSJoseph Mingrone DIAG_ON_DEPRECATION
9283c602fabSXin LI #endif
929