44 "crypto/sha256"
55 "crypto/tls"
66 "crypto/x509"
7- "encoding/pem"
87 "encoding/json"
8+ "encoding/pem"
99 "flag"
1010 "fmt"
1111 "net"
@@ -56,6 +56,13 @@ const (
5656 ERROR = iota
5757)
5858
59+ type fingerprint []byte
60+
61+ func (fp fingerprint ) Hex () string {
62+ return fmt .Sprintf ("%X" , fp )
63+ //return "a"
64+ }
65+
5966// return domain status for printing
6067func (status domainStatus ) String () string {
6168 switch status {
@@ -78,10 +85,11 @@ func (status domainStatus) String() string {
7885// structure to store a domain and its edges
7986type DomainNode struct {
8087 Domain string
81- Depth uint `json:"-"`
82- Fingerprint [] byte
88+ Depth uint
89+ Fingerprint fingerprint
8390 Neighbors []string
8491 Status domainStatus
92+ Root bool
8593}
8694
8795// constructor for DomainNode, converts domain to directDomain
@@ -97,7 +105,7 @@ func (d *DomainNode) String() string {
97105 if list {
98106 return fmt .Sprintf ("%s" , d .Domain )
99107 }
100- return fmt .Sprintf ("%s\t %d\t %s\t %X \t %v" , d .Domain , d .Depth , d .Status , d .Fingerprint , d .Neighbors )
108+ return fmt .Sprintf ("%s\t %d\t %s\t %s \t %v" , d .Domain , d .Depth , d .Status , d .Fingerprint . Hex () , d .Neighbors )
101109}
102110
103111func main () {
@@ -200,7 +208,52 @@ func directDomain(domain string) string {
200208
201209// prnts the graph as a json object
202210func printJSONGraph () {
203- j , err := json .Marshal (domainGraph )
211+ // TODO remove the need for all these temp vars
212+ //domains := make(map[string]map[string]string)
213+ certs := make (map [string ]bool )
214+ nodes := make ([]map [string ]string , 0 , 2 * len (domainGraph ))
215+ links := make ([]map [string ]string , 0 , 2 * len (domainGraph ))
216+
217+ for domain := range domainGraph {
218+ fp := domainGraph [domain ].Fingerprint .Hex ()
219+
220+ // add domain node
221+ dnode := make (map [string ]string )
222+ dnode ["type" ] = "domain"
223+ dnode ["id" ] = domain
224+ dnode ["status" ] = domainGraph [domain ].Status .String ()
225+ dnode ["root" ] = strconv .FormatBool (domainGraph [domain ].Root );
226+ nodes = append (nodes , dnode )
227+
228+ // add domain -> cert
229+ if fp != "" {
230+ links = append (links , map [string ]string {"source" : domain , "target" : fp , "type" : "uses" })
231+ }
232+
233+ // check cert
234+ if ! certs [fp ] && fp != "" {
235+ certs [fp ] = true
236+
237+ // add cert node
238+ cnode := make (map [string ]string )
239+ cnode ["type" ] = "certificate"
240+ cnode ["id" ] = fp
241+ nodes = append (nodes , cnode )
242+
243+ // add cert -> domains
244+ for _ , neighbor := range domainGraph [domain ].Neighbors {
245+ links = append (links , map [string ]string {"source" : fp , "target" : directDomain (neighbor ), "type" : "sans" })
246+ }
247+
248+ }
249+ }
250+
251+ jsonGraph := make (map [string ][]map [string ]string )
252+ jsonGraph ["nodes" ] = nodes
253+ jsonGraph ["links" ] = links
254+
255+ //j, err := json.Marshal(jsonGraph)
256+ j , err := json .MarshalIndent (jsonGraph , "" , "\t " )
204257 if err != nil {
205258 fmt .Println (err )
206259 return
@@ -235,7 +288,9 @@ func BFS(roots []string) {
235288
236289 for _ , root := range roots {
237290 wg .Add (1 )
238- domainChan <- NewDomainNode (root , 0 )
291+ n := NewDomainNode (root , 0 )
292+ n .Root = true
293+ domainChan <- n
239294 }
240295 go func () {
241296 for {
0 commit comments