@@ -236,6 +236,9 @@ type OctoRPKI struct {
236236
237237 Resources * schemas.ResourcesJSON
238238 ResourcesMu sync.RWMutex
239+
240+ DoCT bool
241+ CTPath string
239242}
240243
241244func (s * OctoRPKI ) getRRDPFetch () map [string ]string {
@@ -1025,7 +1028,7 @@ func (s *OctoRPKI) signROAList(roaList *prefixfile.ROAList, span opentracing.Spa
10251028 roaList .Metadata .SignatureDate = signdate
10261029}
10271030
1028- func (s * OctoRPKI ) mainValidation (pSpan opentracing.Span ) {
1031+ func (s * OctoRPKI ) mainValidation (pSpan opentracing.Span ) [][] * pki. PKIFile {
10291032 t1 := time .Now ()
10301033 ia := make ([][]SIA , len (s .Tals ))
10311034 for i := 0 ; i < len (ia ); i ++ {
@@ -1036,6 +1039,8 @@ func (s *OctoRPKI) mainValidation(pSpan opentracing.Span) {
10361039 span := s .tracer .StartSpan ("validation" , opentracing .ChildOf (pSpan .Context ()))
10371040 defer span .Finish ()
10381041
1042+ ctData := make ([][]* pki.PKIFile , 0 )
1043+
10391044 pkiManagers := make ([]* pki.SimpleManager , len (s .Tals ))
10401045 for i , tal := range s .Tals {
10411046 tSpan := s .tracer .StartSpan ("explore" , opentracing .ChildOf (span .Context ()))
@@ -1113,6 +1118,10 @@ func (s *OctoRPKI) mainValidation(pSpan opentracing.Span) {
11131118 sm .Close ()
11141119 tSpan .LogKV ("count-valid" , count , "count-total" , countExplore )
11151120 tSpan .Finish ()
1121+
1122+ if s .DoCT {
1123+ ctData = append (ctData , s .ct (pkiManagers , i )... )
1124+ }
11161125 }
11171126
11181127 s .setInfoAuthorities (ia )
@@ -1122,6 +1131,46 @@ func (s *OctoRPKI) mainValidation(pSpan opentracing.Span) {
11221131 s .stats .ValidationDuration = t2 .Sub (t1 )
11231132 MetricOperationTime .With (prometheus.Labels {"type" : "validation" }).Observe (float64 (s .stats .ValidationDuration .Seconds ()))
11241133 MetricLastValidation .Set (float64 (s .LastComputed .Unix ()))
1134+
1135+ return ctData
1136+ }
1137+
1138+ func (s * OctoRPKI ) ct (pkiManagers []* pki.SimpleManager , i int ) [][]* pki.PKIFile {
1139+ skiToAki := make (map [string ]string )
1140+ skiToPath := make (map [string ]* pki.PKIFile )
1141+ for _ , obj := range pkiManagers [i ].Validator .ValidObjects {
1142+ res := obj .Resource .(* librpki.RPKICertificate )
1143+ ski := hex .EncodeToString (res .Certificate .SubjectKeyId )
1144+ aki := hex .EncodeToString (res .Certificate .AuthorityKeyId )
1145+ skiToAki [ski ] = aki
1146+ skiToPath [ski ] = obj .File
1147+ }
1148+
1149+ pathCT := make ([][]* pki.PKIFile , 0 )
1150+ for ski , aki := range skiToAki {
1151+ skiDone := make (map [string ]bool )
1152+ skiDone [ski ] = true
1153+
1154+ curAki := aki
1155+ curPath := skiToPath [ski ]
1156+ curPathCT := make ([]* pki.PKIFile , 1 )
1157+ curPathCT [0 ] = curPath
1158+
1159+ var ok bool
1160+ for curAki != "" && ! ok {
1161+ ok = skiDone [curAki ]
1162+ skiDone [curAki ] = true
1163+
1164+ curPath = skiToPath [curAki ]
1165+ if curAki != "" {
1166+ curPathCT = append (curPathCT , curPath )
1167+ }
1168+ curAki = skiToAki [curAki ]
1169+ }
1170+ pathCT = append (pathCT , curPathCT )
1171+ }
1172+
1173+ return pathCT
11251174}
11261175
11271176func (s * OctoRPKI ) setInfoAuthorities (ia [][]SIA ) {
@@ -1405,6 +1454,10 @@ func main() {
14051454 log .Fatalf ("Mode %v is not specified. Choose either server or oneoff" , * Mode )
14061455 }
14071456
1457+ if * CertTransparencyThreads < 1 {
1458+ * CertTransparencyThreads = 1
1459+ }
1460+
14081461 s .validationLoop ()
14091462}
14101463
@@ -1425,6 +1478,8 @@ func NewOctoRPKI(tals []*pki.PKIFile, talNames []string) *OctoRPKI {
14251478 stats : newOctoRPKIStats (),
14261479 InfoAuthorities : make ([][]SIA , 0 ),
14271480 tracer : opentracing .GlobalTracer (),
1481+ DoCT : * CertTransparency ,
1482+ CTPath : * CertTransparencyAddr ,
14281483 }
14291484}
14301485
@@ -1498,7 +1553,7 @@ func (s *OctoRPKI) validationLoop() {
14981553
14991554 s .mainRsync (span )
15001555
1501- s .mainValidation (span )
1556+ ctData := s .mainValidation (span )
15021557
15031558 // Reduce
15041559 changed := s .MainReduce ()
@@ -1524,6 +1579,20 @@ func (s *OctoRPKI) validationLoop() {
15241579 break
15251580 }
15261581
1582+ // Certificate Transparency
1583+ if s .DoCT && (s .Stable .Load () || ! * WaitStable ) {
1584+ t1 := time .Now ().UTC ()
1585+
1586+ s .SendCertificateTransparency (span , ctData , * CertTransparencyThreads , * CertTransparencyTimeout )
1587+
1588+ t2 := time .Now ().UTC ()
1589+ MetricOperationTime .With (
1590+ prometheus.Labels {
1591+ "type" : "ct" ,
1592+ }).
1593+ Observe (float64 (t2 .Sub (t1 ).Seconds ()))
1594+ }
1595+
15271596 if s .Stable .Load () {
15281597 MetricLastStableValidation .Set (float64 (s .LastComputed .Unix ()))
15291598 MetricState .Set (float64 (1 ))
0 commit comments