1 /* Copyright (C) 2007-2020 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Implements the to_md5 transformation keyword
24  */
25 
26 #include "suricata-common.h"
27 
28 #include "detect.h"
29 #include "detect-engine.h"
30 #include "detect-engine-prefilter.h"
31 #include "detect-parse.h"
32 #include "detect-transform-md5.h"
33 
34 #include "util-unittest.h"
35 #include "util-print.h"
36 
37 static int DetectTransformToMd5Setup (DetectEngineCtx *, Signature *, const char *);
38 #ifdef HAVE_NSS
39 #ifdef UNITTESTS
40 static void DetectTransformToMd5RegisterTests(void);
41 #endif
42 static void TransformToMd5(InspectionBuffer *buffer, void *options);
43 #endif
44 
DetectTransformMd5Register(void)45 void DetectTransformMd5Register(void)
46 {
47     sigmatch_table[DETECT_TRANSFORM_MD5].name = "to_md5";
48     sigmatch_table[DETECT_TRANSFORM_MD5].desc =
49         "convert to md5 hash of the buffer";
50     sigmatch_table[DETECT_TRANSFORM_MD5].url =
51         "/rules/transforms.html#to-md5";
52     sigmatch_table[DETECT_TRANSFORM_MD5].Setup =
53         DetectTransformToMd5Setup;
54 #ifdef HAVE_NSS
55     sigmatch_table[DETECT_TRANSFORM_MD5].Transform =
56         TransformToMd5;
57 #ifdef UNITTESTS
58     sigmatch_table[DETECT_TRANSFORM_MD5].RegisterTests =
59         DetectTransformToMd5RegisterTests;
60 #endif
61 #endif
62     sigmatch_table[DETECT_TRANSFORM_MD5].flags |= SIGMATCH_NOOPT;
63 }
64 
65 #ifndef HAVE_NSS
DetectTransformToMd5Setup(DetectEngineCtx * de_ctx,Signature * s,const char * nullstr)66 static int DetectTransformToMd5Setup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr)
67 {
68     SCLogError(SC_ERR_NO_MD5_SUPPORT, "no MD5 calculation support built in, "
69             "needed for to_md5 keyword");
70     return -1;
71 }
72 #else
73 /**
74  *  \internal
75  *  \brief Apply the nocase keyword to the last pattern match, either content or uricontent
76  *  \param det_ctx detection engine ctx
77  *  \param s signature
78  *  \param nullstr should be null
79  *  \retval 0 ok
80  *  \retval -1 failure
81  */
DetectTransformToMd5Setup(DetectEngineCtx * de_ctx,Signature * s,const char * nullstr)82 static int DetectTransformToMd5Setup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr)
83 {
84     SCEnter();
85     int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_MD5, NULL);
86     SCReturnInt(r);
87 }
88 
TransformToMd5(InspectionBuffer * buffer,void * options)89 static void TransformToMd5(InspectionBuffer *buffer, void *options)
90 {
91     const uint8_t *input = buffer->inspect;
92     const uint32_t input_len = buffer->inspect_len;
93     uint8_t output[MD5_LENGTH];
94 
95     //PrintRawDataFp(stdout, input, input_len);
96 
97     HASHContext *ctx = HASH_Create(HASH_AlgMD5);
98     if (ctx) {
99         HASH_Begin(ctx);
100         HASH_Update(ctx, input, input_len);
101         unsigned int len = 0;
102         HASH_End(ctx, output, &len, sizeof(output));
103         HASH_Destroy(ctx);
104 
105         InspectionBufferCopy(buffer, output, sizeof(output));
106     }
107 }
108 
109 #ifdef UNITTESTS
DetectTransformToMd5Test01(void)110 static int DetectTransformToMd5Test01(void)
111 {
112     const uint8_t *input = (const uint8_t *)" A B C D ";
113     uint32_t input_len = strlen((char *)input);
114 
115     InspectionBuffer buffer;
116     InspectionBufferInit(&buffer, 8);
117     InspectionBufferSetup(NULL, -1, &buffer, input, input_len);
118     PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
119     TransformToMd5(&buffer, NULL);
120     PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
121     InspectionBufferFree(&buffer);
122     PASS;
123 }
124 
DetectTransformToMd5RegisterTests(void)125 static void DetectTransformToMd5RegisterTests(void)
126 {
127     UtRegisterTest("DetectTransformToMd5Test01",
128             DetectTransformToMd5Test01);
129 }
130 #endif
131 #endif
132