X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/d8d89857912e74201068ba55438dfbfdf57b40bc..6c8ef0eb86a39c277d1a43802dd8ea01b51cfb2a:/signature.c diff --git a/signature.c b/signature.c index c55645fe..204e3456 100644 --- a/signature.c +++ b/signature.c @@ -1,4 +1,4 @@ -/* +/* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph @@ -11,24 +11,20 @@ * FOR A PARTICULAR PURPOSE. * * Functions for signature and digest verification. - * - * Original code by Hannes Gredler (hannes@juniper.net) + * + * Original code by Hannes Gredler (hannes@gredler.at) */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/signature.c,v 1.2 2008-09-22 20:22:10 guy Exp $ (LBL)"; -#endif - #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include +#include -#include "interface.h" +#include "netdissect.h" #include "signature.h" #ifdef HAVE_LIBCRYPTO @@ -38,6 +34,7 @@ static const char rcsid[] _U_ = const struct tok signature_check_values[] = { { SIGNATURE_VALID, "valid"}, { SIGNATURE_INVALID, "invalid"}, + { CANT_ALLOCATE_COPY, "can't allocate memory"}, { CANT_CHECK_SIGNATURE, "unchecked"}, { 0, NULL } }; @@ -48,9 +45,10 @@ const struct tok signature_check_values[] = { * Compute a HMAC MD5 sum. * Taken from rfc2104, Appendix. */ +USES_APPLE_DEPRECATED_API static void -signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *key, - unsigned int key_len, u_int8_t *digest) +signature_compute_hmac_md5(const uint8_t *text, int text_len, unsigned char *key, + unsigned int key_len, uint8_t *digest) { MD5_CTX context; unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ @@ -110,45 +108,102 @@ signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *ke MD5_Update(&context, digest, 16); /* then results of 1st hash */ MD5_Final(digest, &context); /* finish up 2nd pass */ } -#endif +USES_APPLE_RST -#ifdef HAVE_LIBCRYPTO /* * Verify a cryptographic signature of the packet. * Currently only MD5 is supported. */ int -signature_verify (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) { - u_int8_t rcvsig[16]; - u_int8_t sig[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 (!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 *)sigsecret, - strlen(sigsecret), sig); + /* + * 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); + } - if (memcmp(rcvsig, sig, sizeof(sig)) == 0) { - return (SIGNATURE_VALID); + memcpy(packet_copy, pptr, plen); - } else { + /* + * 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 uint8_t *)clear_arg - pptr))); + /* + * Compute the signature. + */ + signature_compute_hmac_md5(packet_copy, plen, + (unsigned char *)ndo->ndo_sigsecret, + strlen(ndo->ndo_sigsecret), sig); + + /* + * 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) { - (void)printf("%02x", sig[i]); + ND_PRINT((ndo, "%02x", sig[i])); } return (SIGNATURE_INVALID); } } +#else +int +signature_verify(netdissect_options *ndo _U_, const u_char *pptr _U_, + u_int plen _U_, const u_char *sig_ptr _U_, + void (*clear_rtn)(void *) _U_, const void *clear_arg _U_) +{ + return (CANT_CHECK_SIGNATURE); +} #endif /*