5
5
"crypto/dsa"
6
6
"crypto/ecdsa"
7
7
"crypto/rsa"
8
+ "crypto/sha1"
8
9
"crypto/sha256"
9
- "crypto/x509"
10
10
"database/sql"
11
11
"database/sql/driver"
12
12
"encoding/json"
@@ -20,11 +20,14 @@ import (
20
20
"net"
21
21
"os"
22
22
"os/signal"
23
+ "path/filepath"
23
24
"regexp"
24
25
"strconv"
25
26
"strings"
26
27
"time"
27
28
29
+ "github.com/gallypette/certificate-transparency-go/x509"
30
+
28
31
"github.com/gomodule/redigo/redis"
29
32
_ "github.com/lib/pq"
30
33
)
@@ -41,9 +44,11 @@ type (
41
44
postgresPort string
42
45
postgresDB string
43
46
certPath string
47
+ format string
48
+ recursive bool
44
49
}
45
50
46
- BigNumber big.Int
51
+ bigNumber big.Int
47
52
48
53
certMapElm struct {
49
54
CertHash string
@@ -73,10 +78,12 @@ type (
73
78
)
74
79
75
80
var (
76
- db * sql.DB
77
- confdir = flag .String ("c" , "conf.sample" , "configuration directory" )
78
- connectRedis = true
79
- cr redis.Conn
81
+ db * sql.DB
82
+ confdir = flag .String ("c" , "conf.sample" , "configuration directory" )
83
+ recursive = flag .Bool ("r" , false , "should it open the directory recursively" )
84
+ format = flag .String ("f" , "json" , "certificate file format [json, crt, der]" )
85
+ pull = flag .Bool ("p" , true , "pull from redis?" )
86
+ cr redis.Conn
80
87
)
81
88
82
89
func main () {
@@ -119,25 +126,9 @@ func main() {
119
126
* confdir = strings .TrimSuffix (* confdir , "\\ " )
120
127
}
121
128
122
- // Parse Redis Config
123
- tmp := readConfFile (* confdir , "redis" )
124
- ss := strings .Split (string (tmp ), "/" )
125
- if len (ss ) <= 1 {
126
- log .Fatal ("Missing Database in Redis config: should be host:port/database_name" )
127
- }
128
- c .redisDB , _ = strconv .Atoi (ss [1 ])
129
- var ret bool
130
- ret , ss [0 ] = isNet (ss [0 ])
131
- if ! ret {
132
- sss := strings .Split (string (ss [0 ]), ":" )
133
- c .redisHost = sss [0 ]
134
- c .redisPort = sss [1 ]
135
- }
136
- c .redisQueue = string (readConfFile (* confdir , "redis_queue" ))
137
-
138
129
// Parse DB Config
139
- tmp = readConfFile (* confdir , "postgres" )
140
- ss = strings .Split (string (tmp ), "/" )
130
+ tmp : = readConfFile (* confdir , "postgres" )
131
+ ss : = strings .Split (string (tmp ), "/" )
141
132
if len (ss ) <= 1 {
142
133
log .Fatal ("Missing Database in Postgres config: should be user:pwd@host:port/database_name" )
143
134
}
@@ -161,27 +152,40 @@ func main() {
161
152
162
153
// Parse Certificate Folder
163
154
c .certPath = string (readConfFile (* confdir , "certfolder" ))
155
+ c .recursive = * recursive
156
+ c .format = * format
164
157
165
158
// DB
166
159
initDB (c .postgresUser , c .postgresPWD , c .postgresHost , c .postgresPort , c .postgresDB )
167
160
defer db .Close ()
168
161
169
162
var jsonPath string
170
163
171
- // Redis
172
- if connectRedis {
164
+ if * pull { // Redis
165
+ // Parse Redis Config
166
+ tmp := readConfFile (* confdir , "redis" )
167
+ ss := strings .Split (string (tmp ), "/" )
168
+ if len (ss ) <= 1 {
169
+ log .Fatal ("Missing Database in Redis config: should be host:port/database_name" )
170
+ }
171
+ c .redisDB , _ = strconv .Atoi (ss [1 ])
172
+ var ret bool
173
+ ret , ss [0 ] = isNet (ss [0 ])
174
+ if ! ret {
175
+ sss := strings .Split (string (ss [0 ]), ":" )
176
+ c .redisHost = sss [0 ]
177
+ c .redisPort = sss [1 ]
178
+ }
179
+ c .redisQueue = string (readConfFile (* confdir , "redis_queue" ))
173
180
initRedis (c .redisHost , c .redisPort , c .redisDB )
174
181
defer cr .Close ()
175
182
// pop redis queue
176
183
for {
177
184
err := errors .New ("" )
178
185
jsonPath , err = redis .String (cr .Do ("LPOP" , "analyzer:ja3-jl:" + c .redisQueue ))
179
186
if err != nil {
180
- time .Sleep (30 * time .Second )
181
- } else {
182
- processFile (c .certPath , jsonPath )
187
+ time .Sleep (2 * time .Second )
183
188
}
184
-
185
189
// Exit Signal Handle
186
190
select {
187
191
case <- s :
@@ -191,31 +195,123 @@ func main() {
191
195
continue
192
196
}
193
197
}
194
-
195
- } else {
196
- var path []string
197
- path = append (path , "./sessions" )
198
- path = append (path , "" )
199
- files , err := ioutil .ReadDir (path [0 ])
200
- if err != nil {
201
- log .Fatal (err )
198
+ } else { // Files
199
+ if c .recursive {
200
+ err := filepath .Walk (c .certPath ,
201
+ func (path string , info os.FileInfo , err error ) error {
202
+ if err != nil {
203
+ return err
204
+ }
205
+ if ! info .IsDir () {
206
+ processFile (c .certPath , path , c .format )
207
+ }
208
+ return nil
209
+ })
210
+ if err != nil {
211
+ log .Println (err )
212
+ }
213
+ } else {
214
+ var path []string
215
+ path = append (path , "./sessions" )
216
+ path = append (path , "" )
217
+ files , err := ioutil .ReadDir (path [0 ])
218
+ if err != nil {
219
+ log .Fatal (err )
220
+ }
221
+ for _ , f := range files {
222
+ path [1 ] = f .Name ()
223
+ jsonPath = strings .Join (path , "/" )
224
+ processFile (c .certPath , jsonPath , c .format )
225
+
226
+ // Exit Signal Handle
227
+ select {
228
+ case <- s :
229
+ fmt .Println ("Exiting..." )
230
+ os .Exit (0 )
231
+ }
232
+ }
202
233
}
203
- for _ , f := range files {
204
- path [1 ] = f .Name ()
205
- jsonPath = strings .Join (path , "/" )
206
- processFile (c .certPath , jsonPath )
207
234
208
- // Exit Signal Handle
209
- select {
210
- case <- s :
211
- fmt .Println ("Exiting..." )
212
- os .Exit (0 )
235
+ }
236
+ }
237
+
238
+ func processFile (fp string , p string , f string ) {
239
+ switch f {
240
+ case "json" :
241
+ processJSON (fp , p )
242
+ break
243
+ case "der" :
244
+ processDER (fp , p )
245
+ break
246
+ case "crt" :
247
+ processCRT (fp , p )
248
+ break
249
+ }
250
+ }
251
+
252
+ func processDER (fp string , p string ) bool {
253
+ // read corresponding der file
254
+ dat , err := ioutil .ReadFile (p )
255
+ if err != nil {
256
+ log .Fatal (err )
257
+ }
258
+ cert , err := x509 .ParseCertificate (dat )
259
+ if err != nil {
260
+ // Not stopping on Non Fatal Errors
261
+ switch err := err .(type ) {
262
+ case x509.NonFatalErrors :
263
+ // Stopping on Unknown PK Algo
264
+ if cert .PublicKeyAlgorithm == 0 {
265
+ fmt .Println ("Unknown Public Key Algorithm, skipping key (most likely GOST R 14)" )
266
+ break
213
267
}
268
+ goto I
269
+ default :
270
+ fmt .Println ("failed to parse certificate: " + err .Error ())
214
271
}
215
272
}
273
+
274
+ I:
275
+ // Cert elem
276
+ h := sha1 .New ()
277
+ h .Write (cert .Raw )
278
+ c := certMapElm {Certificate : cert , CertHash : fmt .Sprintf ("%x" , h .Sum (nil ))}
279
+ // Insert Certificate
280
+ err = insertLeafCertificate (fp , c )
281
+ if err != nil {
282
+ log .Fatal (fmt .Sprintf ("Insert Certificate into DB failed: %q" , err ))
283
+ }
284
+
285
+ return true
286
+ }
287
+
288
+ func insertLeafCertificate (fp string , c certMapElm ) error {
289
+ q := `INSERT INTO "certificate" (hash, "is_CA", "is_SS", issuer, subject, cert_chain, is_valid_chain, file_path) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT DO NOTHING`
290
+ _ , err := db .Exec (q , c .CertHash , c .Certificate .IsCA , false , c .Certificate .Issuer .String (), c .Certificate .Subject .String (), nil , false , getFullPath (fp , c .CertHash ))
291
+ if err != nil {
292
+ return err
293
+ }
294
+ key , err := insertPublicKey (* c .Certificate )
295
+ if err != nil {
296
+ return err
297
+ }
298
+ //fmt.Println(c.CertHash)
299
+ //fmt.Println(key)
300
+ q = `INSERT INTO "many_certificate_has_many_public_key" ("hash_certificate", "hash_public_key") VALUES ($1, $2) ON CONFLICT DO NOTHING `
301
+ _ , err = db .Exec (q , c .CertHash , key )
302
+ if err != nil {
303
+ fmt .Println (c .CertHash )
304
+ return err
305
+ }
306
+ return nil
307
+ }
308
+
309
+ func processCRT (fp string , p string ) bool {
310
+
311
+ return true
216
312
}
217
313
218
- func processFile (fp string , p string ) bool {
314
+ func processJSON (fp string , p string ) bool {
219
315
// read corresponding json file
220
316
dat , err := ioutil .ReadFile (p )
221
317
if err != nil {
@@ -303,19 +399,24 @@ func insertPublicKey(c x509.Certificate) (string, error) {
303
399
switch pub := pub .(type ) {
304
400
case * rsa.PublicKey :
305
401
q := `INSERT INTO "public_key" (hash, type, modulus, exponent, modulus_size) VALUES ($1, $2, $3, $4, $5) ON CONFLICT DO NOTHING`
306
- _ , err := db .Exec (q , hash , "RSA" , (* BigNumber )(pub .N ), pub .E , pub .Size ())
402
+ _ , err := db .Exec (q , hash , "RSA" , (* bigNumber )(pub .N ), pub .E , pub .Size ())
307
403
if err != nil {
308
404
return hash , err
309
405
}
406
+ // else {
407
+ // Adds the moduli into Redis for analysis
408
+ // cr.Send("HMSET", hash, "moduli", (*BigNumber)(pub.N))
409
+ //cr.Send("LPUSH", "albums", "1")
410
+ // }
310
411
case * dsa.PublicKey :
311
412
q := `INSERT INTO "public_key" (hash, type, "G", "P", "Q", "Y") VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT DO NOTHING`
312
- _ , err := db .Exec (q , hash , "DSA" , (* BigNumber )(pub .Parameters .G ), (* BigNumber )(pub .Parameters .P ), (* BigNumber )(pub .Parameters .Q ), (* BigNumber )(pub .Y ))
413
+ _ , err := db .Exec (q , hash , "DSA" , (* bigNumber )(pub .Parameters .G ), (* bigNumber )(pub .Parameters .P ), (* bigNumber )(pub .Parameters .Q ), (* bigNumber )(pub .Y ))
313
414
if err != nil {
314
415
return hash , err
315
416
}
316
417
case * ecdsa.PublicKey :
317
418
q := `INSERT INTO "public_key" (hash, type, "Y", "X", "P", "N", "B", "bitsize", "Gx", "Gy", "curve_name") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) ON CONFLICT DO NOTHING`
318
- _ , err := db .Exec (q , hash , "ECDSA" , (* BigNumber )(pub .Y ), (* BigNumber )(pub .X ), (* BigNumber )(pub .Curve .Params ().P ), (* BigNumber )(pub .Curve .Params ().N ), (* BigNumber )(pub .Curve .Params ().B ), pub .Curve .Params ().BitSize , (* BigNumber )(pub .Curve .Params ().Gx ), (* BigNumber )(pub .Curve .Params ().Gy ), pub .Params ().Name )
419
+ _ , err := db .Exec (q , hash , "ECDSA" , (* bigNumber )(pub .Y ), (* bigNumber )(pub .X ), (* bigNumber )(pub .Curve .Params ().P ), (* bigNumber )(pub .Curve .Params ().N ), (* bigNumber )(pub .Curve .Params ().B ), pub .Curve .Params ().BitSize , (* bigNumber )(pub .Curve .Params ().Gx ), (* bigNumber )(pub .Curve .Params ().Gy ), pub .Params ().Name )
319
420
if err != nil {
320
421
return hash , err
321
422
}
@@ -325,7 +426,7 @@ func insertPublicKey(c x509.Certificate) (string, error) {
325
426
return hash , nil
326
427
}
327
428
328
- func (bn * BigNumber ) Value () (driver.Value , error ) {
429
+ func (bn * bigNumber ) Value () (driver.Value , error ) {
329
430
return driver .Value ((* big .Int )(bn ).Text (10 )), nil
330
431
}
331
432
0 commit comments