X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/f5fe14663d9ed32b7a995ed0924c04e705f74237..refs/heads/master:/signature.c diff --git a/signature.c b/signature.c index 18449fc2..f10a90b9 100644 --- a/signature.c +++ b/signature.c @@ -12,19 +12,19 @@ * * Functions for signature and digest verification. * - * Original code by Hannes Gredler (hannes@juniper.net) + * Original code by Hannes Gredler (hannes@gredler.at) */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#include -#include +#include "netdissect-stdinc.h" #include +#include #include "netdissect.h" #include "signature.h" +#include "diag-control.h" #ifdef HAVE_LIBCRYPTO #include @@ -33,6 +33,7 @@ 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 } }; @@ -43,7 +44,7 @@ const struct tok signature_check_values[] = { * Compute a HMAC MD5 sum. * Taken from rfc2104, Appendix. */ -USES_APPLE_DEPRECATED_API +DIAG_OFF_DEPRECATION static void signature_compute_hmac_md5(const uint8_t *text, int text_len, unsigned char *key, unsigned int key_len, uint8_t *digest) @@ -79,8 +80,8 @@ signature_compute_hmac_md5(const uint8_t *text, int text_len, unsigned char *key */ /* 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); @@ -106,52 +107,100 @@ signature_compute_hmac_md5(const uint8_t *text, int text_len, unsigned char *key MD5_Update(&context, digest, 16); /* then results of 1st hash */ MD5_Final(digest, &context); /* finish up 2nd pass */ } -USES_APPLE_RST -#endif +DIAG_ON_DEPRECATION -#ifdef HAVE_LIBCRYPTO /* * Verify a cryptographic signature of the packet. * 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_TTEST_LEN(pptr, plen)) { + /* No. */ + return (CANT_CHECK_SIGNATURE); + } - if (!ndo->ndo_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); + } + + /* + * 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 uint8_t *)clear_arg - pptr))); - signature_compute_hmac_md5(pptr, plen, (unsigned char *)ndo->ndo_sigsecret, + /* + * 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])); + 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: - */