X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/ec799d60f6cd3f41041b57efe3963c28dda94d4a..refs/heads/master:/signature.c diff --git a/signature.c b/signature.c index c55645fe..f10a90b9 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,25 +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 "netdissect-stdinc.h" #include +#include -#include "interface.h" +#include "netdissect.h" #include "signature.h" +#include "diag-control.h" #ifdef HAVE_LIBCRYPTO #include @@ -38,6 +33,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 +44,10 @@ const struct tok signature_check_values[] = { * Compute a HMAC MD5 sum. * Taken from rfc2104, Appendix. */ +DIAG_OFF_DEPRECATION 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 */ @@ -83,8 +80,8 @@ signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *ke */ /* start out by storing key in pads */ - memset(k_ipad, 0, sizeof k_ipad); - memset(k_opad, 0, sizeof k_opad); + memset(k_ipad, 0, sizeof(k_ipad)); + memset(k_opad, 0, sizeof(k_opad)); memcpy(k_ipad, key, key_len); memcpy(k_opad, key, key_len); @@ -110,50 +107,100 @@ 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 +DIAG_ON_DEPRECATION -#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_TTEST_LEN(pptr, plen)) { + /* No. */ + return (CANT_CHECK_SIGNATURE); + } - if (!sigsecret) { + /* + * Do we have the entire signature to check? + */ + if (!ND_TTEST_LEN(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("%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 - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */