Browse code

CL_DB_CVDNOTMP is now the only way to load .cvd/.cld files; prepare for .info signing

Tomasz Kojm authored on 2010/01/20 23:02:13
Showing 10 changed files
... ...
@@ -114,7 +114,7 @@ int main(int argc, char **argv)
114 114
 	int ret, tcpsock = 0, localsock = 0, i, min_port, max_port;
115 115
 	unsigned int sigs = 0;
116 116
 	int lsockets[2], nlsockets = 0;
117
-	unsigned int dboptions = CL_DB_CVDNOTMP;
117
+	unsigned int dboptions = 0;
118 118
 #ifdef C_LINUX
119 119
 	struct stat sb;
120 120
 #endif
... ...
@@ -314,7 +314,7 @@ int scanmanager(const struct optstruct *opts)
314 314
 {
315 315
 	mode_t fmode;
316 316
 	int ret = 0, fmodeint, i;
317
-	unsigned int options = 0, dboptions = CL_DB_CVDNOTMP;
317
+	unsigned int options = 0, dboptions = 0;
318 318
 	struct cl_engine *engine;
319 319
 	struct stat sb;
320 320
 	char *file, cwd[1024], *pua_cats = NULL;
... ...
@@ -867,9 +867,6 @@ N * * * *	/usr/local/bin/freshclam --quiet
867 867
 	Initialize the phishing detection module and load .wdb and .pdb files.
868 868
 	\item \textbf{CL\_DB\_PUA}\\
869 869
 	Load signatures for Potentially Unwanted Applications.
870
-	\item \textbf{CL\_DB\_CVDNOTMP}\\
871
-	Load CVD files directly without unpacking them into a temporary
872
-	directory.
873 870
     \end{itemize}
874 871
     \verb+cl_load()+ returns \verb+CL_SUCCESS+ on success and another code on
875 872
     failure.
... ...
@@ -73,7 +73,7 @@ typedef enum {
73 73
 #define CL_DB_PHISHING	    0x2
74 74
 #define CL_DB_PHISHING_URLS 0x8
75 75
 #define CL_DB_PUA	    0x10
76
-#define CL_DB_CVDNOTMP	    0x20
76
+#define CL_DB_CVDNOTMP	    0x20    /* obsolete */
77 77
 #define CL_DB_OFFICIAL	    0x40    /* internal */
78 78
 #define CL_DB_PUA_MODE	    0x80
79 79
 #define CL_DB_PUA_INCLUDE   0x100
... ...
@@ -84,7 +84,7 @@ typedef enum {
84 84
 #define CL_DB_BYTECODE      0x2000
85 85
 
86 86
 /* recommended db settings */
87
-#define CL_DB_STDOPT	    (CL_DB_PHISHING | CL_DB_PHISHING_URLS | CL_DB_CVDNOTMP | CL_DB_BYTECODE)
87
+#define CL_DB_STDOPT	    (CL_DB_PHISHING | CL_DB_PHISHING_URLS | CL_DB_BYTECODE)
88 88
 
89 89
 /* scan options */
90 90
 #define CL_SCAN_RAW			0x0
... ...
@@ -575,35 +575,7 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
575 575
 	engine->dbversion[1] = cvd.stime;
576 576
     }
577 577
 
578
-    if(options & CL_DB_CVDNOTMP) {
579
-
580
-	return cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL);
581
-
582
-    } else {
583
-
584
-	if(!(dir = cli_gentemp(engine->tmpdir)))
585
-	    return CL_EMEM;
586
-
587
-	if(mkdir(dir, 0700)) {
588
-	    cli_errmsg("cli_cvdload(): Can't create temporary directory %s\n", dir);
589
-	    free(dir);
590
-	    return CL_ETMPDIR;
591
-	}
592
-
593
-	if(cli_untgz(cfd, dir)) {
594
-	    cli_errmsg("cli_cvdload(): Can't unpack CVD file.\n");
595
-	    free(dir);
596
-	    return CL_ECVD;
597
-	}
598
-
599
-	/* load extracted directory */
600
-	ret = cl_load(dir, engine, signo, options | CL_DB_OFFICIAL);
601
-
602
-	cli_rmdirs(dir);
603
-	free(dir);
604
-
605
-	return ret;
606
-    }
578
+    return cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL);
607 579
 }
608 580
 
609 581
 int cli_cvdunpack(const char *file, const char *dir)
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- *  Copyright (C) 2007-2009 Sourcefire, Inc.
2
+ *  Copyright (C) 2007-2010 Sourcefire, Inc.
3 3
  *
4 4
  *  Authors: Tomasz Kojm
5 5
  *
... ...
@@ -32,6 +32,7 @@
32 32
 #include "dsig.h"
33 33
 #include "str.h"
34 34
 #include "bignum.h"
35
+#include "sha256.h"
35 36
 
36 37
 #define CLI_NSTR "118640995551645342603070001658453189751527774412027743746599405743243142607464144767361060640655844749760788890022283424922762488917565551002467771109669598189410434699034532232228621591089508178591428456220796841621637175567590476666928698770143328137383952820383197532047771780196576957695822641224262693037"
37 38
 
... ...
@@ -145,3 +146,72 @@ int cli_versig(const char *md5, const char *dsig)
145 145
     cli_dbgmsg("cli_versig: Digital signature is correct.\n");
146 146
     return CL_SUCCESS;
147 147
 }
148
+
149
+#define HASH_LEN    32
150
+#define SALT_LEN    32
151
+#define PAD_LEN	    (2048 / 8)
152
+#define BLK_LEN	    (PAD_LEN - HASH_LEN - 1)
153
+int cli_versig2(const unsigned char *sha256, const char *dsig_str, const char *n_str, const char *e_str)
154
+{
155
+	unsigned char *decoded, digest1[HASH_LEN], digest2[HASH_LEN], digest3[HASH_LEN], *salt;
156
+	unsigned char mask[BLK_LEN], data[BLK_LEN], final[8 + 2 * HASH_LEN], c[4];
157
+	unsigned int i, rounds;
158
+	SHA256_CTX ctx;
159
+	mp_int n, e;
160
+
161
+    mp_init(&e);
162
+    mp_read_radix(&e, e_str, 10);
163
+    mp_init(&n);
164
+    mp_read_radix(&n, n_str, 10);
165
+
166
+    decoded = cli_decodesig(dsig_str, PAD_LEN, e, n);
167
+    mp_clear(&n);
168
+    mp_clear(&e);
169
+    if(!decoded)
170
+	return CL_EVERIFY;
171
+
172
+    if(decoded[PAD_LEN - 1] != 0xbc) {
173
+	free(decoded);
174
+	return CL_EVERIFY;
175
+    }
176
+
177
+    memcpy(mask, decoded, BLK_LEN);
178
+    memcpy(digest2, &decoded[BLK_LEN], HASH_LEN);
179
+    free(decoded);
180
+
181
+    c[0] = c[1] = 0;
182
+    rounds = (BLK_LEN + HASH_LEN - 1) / HASH_LEN;
183
+    for(i = 0; i < rounds; i++) {
184
+	c[2] = (unsigned char) (i / 256);
185
+	c[3] = (unsigned char) i;
186
+	sha256_init(&ctx);
187
+	sha256_update(&ctx, digest2, HASH_LEN);
188
+	sha256_update(&ctx, c, 4);
189
+	sha256_final(&ctx, digest3);
190
+	if(i + 1 == rounds)
191
+            memcpy(&data[i * 32], digest3, BLK_LEN - i * HASH_LEN);
192
+	else
193
+	    memcpy(&data[i * 32], digest3, HASH_LEN);
194
+    }
195
+
196
+    for(i = 0; i < BLK_LEN; i++)
197
+	data[i] ^= mask[i];
198
+    data[0] &= (0xff >> 1);
199
+
200
+    if(!(salt = memchr(data, 0x01, BLK_LEN)))
201
+	return CL_EVERIFY;
202
+    salt++;
203
+
204
+    if(data + BLK_LEN - salt != SALT_LEN)
205
+	return CL_EVERIFY;
206
+
207
+    memset(final, 0, 8);
208
+    memcpy(&final[8], sha256, HASH_LEN);
209
+    memcpy(&final[8 + HASH_LEN], salt, SALT_LEN);
210
+
211
+    sha256_init(&ctx);
212
+    sha256_update(&ctx, final, sizeof(final));
213
+    sha256_final(&ctx, digest1);
214
+
215
+    return memcmp(digest1, digest2, HASH_LEN) ? CL_EVERIFY : CL_SUCCESS;
216
+}
... ...
@@ -25,9 +25,7 @@
25 25
 #include "clamav-config.h"
26 26
 #endif
27 27
 
28
-#include "bignum.h"
29
-
30 28
 int cli_versig(const char *md5, const char *dsig);
31
-unsigned char *cli_decodesig(const char *sig, unsigned int plen, mp_int e, mp_int n);
29
+int cli_versig2(const unsigned char *sha256, const char *dsig_str, const char *n_str, const char *e_str);
32 30
 
33 31
 #endif
... ...
@@ -133,6 +133,7 @@ CLAMAV_PRIVATE {
133 133
     mp_read_radix;
134 134
     mp_clear;
135 135
     cli_versig;
136
+    cli_versig2;
136 137
     cli_filecopy;
137 138
     cli_ftw;
138 139
     cli_unlink;
... ...
@@ -2086,7 +2086,7 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo
2086 2086
 	ret = cli_cvdload(fs, engine, signo, !strcmp(dbname, "daily.cvd"), options, 0);
2087 2087
 
2088 2088
     } else if(cli_strbcasestr(dbname, ".cld")) {
2089
-	ret = cli_cvdload(fs, engine, signo, !strcmp(dbname, "daily.cld"), options | CL_DB_CVDNOTMP, 1);
2089
+	ret = cli_cvdload(fs, engine, signo, !strcmp(dbname, "daily.cld"), options, 1);
2090 2090
 
2091 2091
     } else if(cli_strbcasestr(dbname, ".hdb")) {
2092 2092
 	ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options, dbio, dbname);
... ...
@@ -773,102 +773,6 @@ static int cdiff_execute(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf,
773 773
     return 0;
774 774
 }
775 775
 
776
-static void pss_mgf(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int outlen)
777
-{
778
-	SHA256_CTX ctx;
779
-	unsigned int i, laps;
780
-	unsigned char cnt[4], digest[PSS_DIGEST_LENGTH];
781
-
782
-
783
-    laps = (outlen + PSS_DIGEST_LENGTH - 1) / PSS_DIGEST_LENGTH;
784
-
785
-    for(i = 0; i < laps; i++) {
786
-	cnt[0] = (unsigned char) 0;
787
-	cnt[1] = (unsigned char) 0;
788
-	cnt[2] = (unsigned char) (i / 256);
789
-	cnt[3] = (unsigned char) i;
790
-
791
-	sha256_init(&ctx);
792
-	sha256_update(&ctx, in, inlen);
793
-	sha256_update(&ctx, cnt, sizeof(cnt));
794
-	sha256_final(&ctx, digest);
795
-
796
-	if(i != laps - 1)
797
-	    memcpy(&out[i * PSS_DIGEST_LENGTH], digest, PSS_DIGEST_LENGTH);
798
-	else
799
-	    memcpy(&out[i * PSS_DIGEST_LENGTH], digest, outlen - i * PSS_DIGEST_LENGTH);
800
-    }
801
-}
802
-
803
-static int pss_versig(const unsigned char *sha256, const char *dsig)
804
-{
805
-	mp_int n, e;
806
-	SHA256_CTX ctx;
807
-	unsigned char *pt, digest1[PSS_DIGEST_LENGTH], digest2[PSS_DIGEST_LENGTH], *salt;
808
-	unsigned int plen = PSS_NBITS / 8, hlen, slen, i;
809
-	unsigned char dblock[PSS_NBITS / 8 - PSS_DIGEST_LENGTH - 1];
810
-	unsigned char mblock[PSS_NBITS / 8 - PSS_DIGEST_LENGTH - 1];
811
-	unsigned char fblock[8 + 2 * PSS_DIGEST_LENGTH];
812
-
813
-
814
-    hlen = slen = PSS_DIGEST_LENGTH;
815
-    mp_init(&n);
816
-    mp_read_radix(&n, PSS_NSTR, 10);
817
-    mp_init(&e);
818
-    mp_read_radix(&e, PSS_ESTR, 10);
819
-    if(!(pt = cli_decodesig(dsig, plen, e, n))) {
820
-	mp_clear(&n);
821
-	mp_clear(&e);
822
-	return -1;
823
-    }
824
-    mp_clear(&n);
825
-    mp_clear(&e);
826
-
827
-    if(pt[plen - 1] != 0xbc) {
828
-	/* cli_dbgmsg("cli_versigpss: Incorrect signature syntax (0xbc)\n"); */
829
-	free(pt);
830
-	return -1;
831
-    }
832
-
833
-    memcpy(mblock, pt, plen - hlen - 1);
834
-    memcpy(digest2, &pt[plen - hlen - 1], hlen);
835
-    free(pt);
836
-
837
-    pss_mgf(digest2, hlen, dblock, plen - hlen - 1);
838
-
839
-    for(i = 0; i < plen - hlen - 1; i++)
840
-	dblock[i] ^= mblock[i];
841
-
842
-    dblock[0] &= (0xff >> 1);
843
-
844
-    salt = memchr(dblock, 0x01, sizeof(dblock));
845
-    if(!salt) {
846
-	/* cli_dbgmsg("cli_versigpss: Can't find salt\n"); */
847
-	return -1;
848
-    }
849
-    salt++;
850
-
851
-    if((unsigned int) (dblock + sizeof(dblock) - salt) != slen) {
852
-	/* cli_dbgmsg("cli_versigpss: Bad salt size\n"); */
853
-	return -1;
854
-    }
855
-
856
-    memset(fblock, 0, 8);
857
-    memcpy(&fblock[8], sha256, hlen);
858
-    memcpy(&fblock[8 + hlen], salt, slen);
859
-
860
-    sha256_init(&ctx);
861
-    sha256_update(&ctx, fblock, sizeof(fblock));
862
-    sha256_final(&ctx, digest1);
863
-
864
-    if(memcmp(digest1, digest2, hlen)) {
865
-	/* cli_dbgmsg("cli_versigpss: Signature doesn't match.\n"); */
866
-	return -1;
867
-    }
868
-
869
-    return 0;
870
-}
871
-
872 776
 int cdiff_apply(int fd, unsigned short mode)
873 777
 {
874 778
 	struct cdiff_ctx ctx;
... ...
@@ -977,7 +881,7 @@ int cdiff_apply(int fd, unsigned short mode)
977 977
 	}
978 978
 	sha256_final(&sha256ctx, digest);
979 979
 
980
-	if(pss_versig(digest, dsig)) {
980
+	if(cli_versig2(digest, dsig, PSS_NSTR, PSS_ESTR) != CL_SUCCESS) {
981 981
 	    logg("!cdiff_apply: Incorrect digital signature\n");
982 982
 	    close(desc);
983 983
 	    free(line);