github.com/zmap/zlint@v1.1.0/zlint.go (about) 1 /* 2 * ZLint Copyright 2018 Regents of the University of Michigan 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 * implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 // Used to check parsed info from certificate for compliance 16 17 package zlint 18 19 import ( 20 "encoding/json" 21 "io" 22 "regexp" 23 "time" 24 25 "github.com/zmap/zcrypto/x509" 26 "github.com/zmap/zlint/lints" 27 ) 28 29 const Version int64 = 3 30 31 // ResultSet contains the output of running all lints against a single certificate. 32 type ResultSet struct { 33 Version int64 `json:"version"` 34 Timestamp int64 `json:"timestamp"` 35 Results map[string]*lints.LintResult `json:"lints"` 36 NoticesPresent bool `json:"notices_present"` 37 WarningsPresent bool `json:"warnings_present"` 38 ErrorsPresent bool `json:"errors_present"` 39 FatalsPresent bool `json:"fatals_present"` 40 } 41 42 func (z *ResultSet) execute(cert *x509.Certificate, filter *regexp.Regexp) { 43 z.Results = make(map[string]*lints.LintResult, len(lints.Lints)) 44 for name, l := range lints.Lints { 45 if filter != nil && !filter.MatchString(name) { 46 continue 47 } 48 res := l.Execute(cert) 49 z.Results[name] = res 50 z.updateErrorStatePresent(res) 51 } 52 } 53 54 func (z *ResultSet) updateErrorStatePresent(result *lints.LintResult) { 55 switch result.Status { 56 case lints.Notice: 57 z.NoticesPresent = true 58 case lints.Warn: 59 z.WarningsPresent = true 60 case lints.Error: 61 z.ErrorsPresent = true 62 case lints.Fatal: 63 z.FatalsPresent = true 64 } 65 } 66 67 // EncodeLintDescriptionsToJSON outputs a description of each lint as JSON 68 // object, one object per line. 69 func EncodeLintDescriptionsToJSON(w io.Writer) { 70 enc := json.NewEncoder(w) 71 enc.SetEscapeHTML(false) 72 for _, lint := range lints.Lints { 73 enc.Encode(lint) 74 } 75 } 76 77 // LintCertificate runs all registered lints on c, producing a ZLint. 78 func LintCertificate(c *x509.Certificate) *ResultSet { 79 // Instead of panicing on nil certificate, just returns nil and let the client 80 // panic when accessing ZLint, if they're into panicing. 81 if c == nil { 82 return nil 83 } 84 85 // Run all tests 86 return LintCertificateFiltered(c, nil) 87 } 88 89 // LintCertificateFiltered runs all lints with names matching the provided 90 // regexp on c, producing a ResultSet. 91 func LintCertificateFiltered(c *x509.Certificate, filter *regexp.Regexp) *ResultSet { 92 if c == nil { 93 return nil 94 } 95 96 // Run tests with provided filter 97 res := new(ResultSet) 98 res.execute(c, filter) 99 res.Version = Version 100 res.Timestamp = time.Now().Unix() 101 return res 102 }