summaryrefslogtreecommitdiff
path: root/signature.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-12-27 17:59:56 -0800
committerGuy Harris <guy@alum.mit.edu>2015-12-27 17:59:56 -0800
commit59caec8a010375386ba91fb8a581f882912f2733 (patch)
treec6535d631353432b3b686a88b647bea52ff875a6 /signature.c
parent20f164f5e4825a605d97906b9ac6bf4222b9eef4 (diff)
downloadtcpdump-59caec8a010375386ba91fb8a581f882912f2733.tar.gz
Have signature_verify() do the copying and clearing.
Just pass it a pointer to a routine to do the clearing and a pointer to the data that needs to be cleared; signature_verify() will relocate all pointers to stuff that needs to be cleared to point into the copy, clear the signature itself, and call the routine to clear anything else.
Diffstat (limited to 'signature.c')
-rw-r--r--signature.c72
1 files changed, 61 insertions, 11 deletions
diff --git a/signature.c b/signature.c
index b989baff..77ec493b 100644
--- a/signature.c
+++ b/signature.c
@@ -22,6 +22,7 @@
#include <netdissect-stdinc.h>
#include <string.h>
+#include <stdlib.h>
#include "netdissect.h"
#include "signature.h"
@@ -116,31 +117,80 @@ USES_APPLE_RST
* 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]));
}