return (processed);
}
+/*
+ * Clear checksum and lifetime prior to signature verification.
+ */
+static void
+isis_clear_checksum_lifetime(void *header)
+{
+ struct isis_lsp_header *header_lsp = (struct isis_lsp_header *) header;
+
+ header_lsp->checksum[0] = 0;
+ header_lsp->checksum[1] = 0;
+ header_lsp->remaining_lifetime[0] = 0;
+ header_lsp->remaining_lifetime[1] = 0;
+}
+
/*
* isis_print
* Decode IS-IS packets. Return 0 on error.
u_short packet_len,pdu_len, key_id;
u_int i,vendor_id;
int sigcheck;
-#ifdef HAVE_LIBCRYPTO
- uint8_t *packet_copy;
-#endif
packet_len=length;
optr = p; /* initialize the _o_riginal pointer to the packet start -
ND_PRINT((ndo, ", (invalid subTLV) "));
#ifdef HAVE_LIBCRYPTO
- /*
- * Make a copy of the packet, so we don't overwrite the
- * original.
- */
- ND_TCHECK2(*optr, packet_len);
- packet_copy = malloc(packet_len);
- if (packet_copy == NULL)
- sigcheck = CANT_ALLOCATE_COPY;
- else {
- struct isis_lsp_header *header_lsp_copy;
- u_int8_t *tptr_copy;
-
- memcpy(packet_copy, optr, packet_len);
-
- /*
- * Clear checksum and lifetime in the copy prior to
- * signature verification.
- */
- header_lsp_copy = (struct isis_lsp_header *)(packet_copy + ISIS_COMMON_HEADER_SIZE);
- header_lsp_copy->checksum[0] = 0;
- header_lsp_copy->checksum[1] = 0;
- header_lsp_copy->remaining_lifetime[0] = 0;
- header_lsp_copy->remaining_lifetime[1] = 0;
-
- tptr_copy = packet_copy + (tptr - optr);
- sigcheck = signature_verify(ndo, packet_copy, length,
- tptr_copy + 1);
- free(packet_copy);
- }
+ sigcheck = signature_verify(ndo, optr, length, tptr + 1,
+ isis_clear_checksum_lifetime,
+ header_lsp);
#else
sigcheck = CANT_CHECK_SIGNATURE;
#endif
return 0;
}
+/*
+ * Clear checksum prior to signature verification.
+ */
+static void
+rsvp_clear_checksum(void *header)
+{
+ struct rsvp_common_header *rsvp_com_header = (struct rsvp_common_header *) header;
+
+ rsvp_com_header->checksum[0] = 0;
+ rsvp_com_header->checksum[1] = 0;
+}
+
static int
rsvp_obj_print(netdissect_options *ndo,
const u_char *pptr
_U_
#endif
, const u_char *tptr,
- const char *ident, u_int tlen)
+ const char *ident, u_int tlen,
+ const struct rsvp_common_header *rsvp_com_header
+#ifndef HAVE_LIBCRYPTO
+_U_
+#endif
+)
{
const struct rsvp_object_header *rsvp_obj_header;
const u_char *obj_tptr;
EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest + 12)));
#ifdef HAVE_LIBCRYPTO
- sigcheck = signature_verify(ndo, pptr, plen, (unsigned char *)obj_ptr.\
- rsvp_obj_integrity->digest);
+ sigcheck = signature_verify(ndo, pptr, plen,
+ obj_ptr.rsvp_obj_integrity->digest,
+ rsvp_clear_checksum,
+ rsvp_com_header);
#else
sigcheck = CANT_CHECK_SIGNATURE;
#endif
rsvp_print(netdissect_options *ndo,
register const u_char *pptr, register u_int len)
{
- struct rsvp_common_header *rsvp_com_header;
+ const struct rsvp_common_header *rsvp_com_header;
const u_char *tptr,*subtptr;
u_short plen, tlen, subtlen;
tptr=pptr;
- rsvp_com_header = (struct rsvp_common_header *)pptr;
+ rsvp_com_header = (const struct rsvp_common_header *)pptr;
ND_TCHECK(*rsvp_com_header);
/*
rsvp_com_header->ttl,
EXTRACT_16BITS(rsvp_com_header->checksum)));
- /*
- * Clear checksum prior to signature verification.
- */
- rsvp_com_header->checksum[0] = 0;
- rsvp_com_header->checksum[1] = 0;
-
if (tlen < sizeof(const struct rsvp_common_header)) {
ND_PRINT((ndo, "ERROR: common header too short %u < %lu", tlen,
(unsigned long)sizeof(const struct rsvp_common_header)));
case RSVP_MSGTYPE_AGGREGATE:
while(tlen > 0) {
subtptr=tptr;
- rsvp_com_header = (struct rsvp_common_header *)subtptr;
+ rsvp_com_header = (const struct rsvp_common_header *)subtptr;
ND_TCHECK(*rsvp_com_header);
/*
rsvp_com_header->ttl,
EXTRACT_16BITS(rsvp_com_header->checksum)));
- /*
- * Clear checksum prior to signature verification.
- */
- rsvp_com_header->checksum[0] = 0;
- rsvp_com_header->checksum[1] = 0;
-
if (subtlen < sizeof(const struct rsvp_common_header)) {
ND_PRINT((ndo, "ERROR: common header too short %u < %lu", subtlen,
(unsigned long)sizeof(const struct rsvp_common_header)));
subtptr+=sizeof(const struct rsvp_common_header);
subtlen-=sizeof(const struct rsvp_common_header);
- if (rsvp_obj_print(ndo, pptr, plen, subtptr, "\n\t ", subtlen) == -1)
+ if (rsvp_obj_print(ndo, pptr, plen, subtptr, "\n\t ", subtlen, rsvp_com_header) == -1)
return;
tptr+=subtlen+sizeof(const struct rsvp_common_header);
case RSVP_MSGTYPE_HELLO:
case RSVP_MSGTYPE_ACK:
case RSVP_MSGTYPE_SREFRESH:
- if (rsvp_obj_print(ndo, pptr, plen, tptr, "\n\t ", tlen) == -1)
+ if (rsvp_obj_print(ndo, pptr, plen, tptr, "\n\t ", tlen, rsvp_com_header) == -1)
return;
break;
#include <netdissect-stdinc.h>
#include <string.h>
+#include <stdlib.h>
#include "netdissect.h"
#include "signature.h"
* Currently only MD5 is supported.
*/
int
-signature_verify(netdissect_options *ndo,
- const u_char *pptr, u_int plen, u_char *sig_ptr)
+signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen,
+ const u_char *sig_ptr, void (*clear_rtn)(void *),
+ const void *clear_arg)
{
- uint8_t rcvsig[16];
+ uint8_t *packet_copy, *sig_copy;
uint8_t sig[16];
unsigned int i;
+ if (!ndo->ndo_sigsecret) {
+ return (CANT_CHECK_SIGNATURE);
+ }
+
/*
- * Save the signature before clearing it.
+ * Do we have all the packet data to be checked?
*/
- memcpy(rcvsig, sig_ptr, sizeof(rcvsig));
- memset(sig_ptr, 0, sizeof(rcvsig));
+ if (!ND_TTEST2(pptr, plen)) {
+ /* No. */
+ return (CANT_CHECK_SIGNATURE);
+ }
- if (!ndo->ndo_sigsecret) {
+ /*
+ * Do we have the entire signature to check?
+ */
+ if (!ND_TTEST2(sig_ptr, sizeof(sig))) {
+ /* No. */
+ return (CANT_CHECK_SIGNATURE);
+ }
+ if ((sig_ptr + sizeof(sig) - pptr) > plen) {
+ /* No. */
return (CANT_CHECK_SIGNATURE);
}
- signature_compute_hmac_md5(pptr, plen, (unsigned char *)ndo->ndo_sigsecret,
+ /*
+ * Make a copy of the packet, so we don't overwrite the original.
+ */
+ packet_copy = malloc(plen);
+ if (packet_copy == NULL) {
+ return (CANT_ALLOCATE_COPY);
+ }
+
+ memcpy(packet_copy, pptr, plen);
+
+ /*
+ * Clear the signature in the copy.
+ */
+ sig_copy = packet_copy + (sig_ptr - pptr);
+ memset(sig_copy, 0, sizeof(sig));
+
+ /*
+ * Clear anything else that needs to be cleared in the copy.
+ * Our caller is assumed to have vetted the clear_arg pointer.
+ */
+ (*clear_rtn)((void *)(packet_copy + ((const u_int8_t *)clear_arg - pptr)));
+
+ /*
+ * Compute the signature.
+ */
+ signature_compute_hmac_md5(packet_copy, plen,
+ (unsigned char *)ndo->ndo_sigsecret,
strlen(ndo->ndo_sigsecret), sig);
- if (memcmp(rcvsig, sig, sizeof(sig)) == 0) {
- return (SIGNATURE_VALID);
+ /*
+ * Free the copy.
+ */
+ free(packet_copy);
+ /*
+ * Does the computed signature match the signature in the packet?
+ */
+ if (memcmp(sig_ptr, sig, sizeof(sig)) == 0) {
+ /* Yes. */
+ return (SIGNATURE_VALID);
} else {
-
+ /* No - print the computed signature. */
for (i = 0; i < sizeof(sig); ++i) {
ND_PRINT((ndo, "%02x", sig[i]));
}
#define CANT_CHECK_SIGNATURE 3
extern const struct tok signature_check_values[];
-extern int signature_verify(netdissect_options *, const u_char *, u_int, u_char *);
+extern int signature_verify(netdissect_options *, const u_char *, u_int,
+ const u_char *, void (*)(void *), const void *);