]> The Tcpdump Group git mirrors - tcpdump/blobdiff - signature.c
Avoid -E and -M options inconsistencies with no libcrypto
[tcpdump] / signature.c
index 55b69b866e687ad94d56b561d7351469456a9988..f10a90b94ee90cef0fd70671828396f8e248eb39 100644 (file)
  *
  * 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 <config.h>
 
-#include <tcpdump-stdinc.h>
+#include "netdissect-stdinc.h"
 
 #include <string.h>
+#include <stdlib.h>
 
-#include "interface.h"
+#include "netdissect.h"
 #include "signature.h"
+#include "diag-control.h"
 
 #ifdef HAVE_LIBCRYPTO
 #include <openssl/md5.h>
@@ -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,10 +44,10 @@ 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 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 */
@@ -84,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);
 
@@ -111,51 +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 */
 }
-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 (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:
- */