github.com/zmap/zlint@v1.1.0/lints/lint_qcstatem_qcpds_valid.go (about) 1 /* 2 * ZLint Copyright 2017 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 package lints 16 17 import ( 18 "encoding/asn1" 19 "fmt" 20 "github.com/zmap/zcrypto/x509" 21 "github.com/zmap/zlint/util" 22 "strings" 23 ) 24 25 type qcStatemQcPdsValid struct{} 26 27 func (this *qcStatemQcPdsValid) getStatementOid() *asn1.ObjectIdentifier { 28 return &util.IdEtsiQcsQcEuPDS 29 } 30 31 func (l *qcStatemQcPdsValid) Initialize() error { 32 return nil 33 } 34 35 func (l *qcStatemQcPdsValid) CheckApplies(c *x509.Certificate) bool { 36 if !util.IsExtInCert(c, util.QcStateOid) { 37 return false 38 } 39 if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { 40 return true 41 } 42 return false 43 } 44 45 func isInList(s string, list []string) bool { 46 for _, i := range list { 47 if strings.Compare(i, s) == 0 { 48 return true 49 } 50 } 51 return false 52 } 53 54 func (l *qcStatemQcPdsValid) Execute(c *x509.Certificate) *LintResult { 55 errString := "" 56 ext := util.GetExtFromCert(c, util.QcStateOid) 57 s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) 58 errString += s.GetErrorInfo() 59 if len(errString) == 0 { 60 codeList := make([]string, 0) 61 foundEn := false 62 pds := s.(util.EtsiQcPds) 63 if len(pds.PdsLocations) == 0 { 64 util.AppendToStringSemicolonDelim(&errString, "PDS list is empty") 65 } 66 for i, loc := range pds.PdsLocations { 67 if len(loc.Language) != 2 { 68 util.AppendToStringSemicolonDelim(&errString, fmt.Sprintf("PDS location %d has a language code with an invalid length", i)) 69 } 70 if strings.Compare(strings.ToLower(loc.Language), "en") == 0 { 71 foundEn = true 72 } 73 if isInList(strings.ToLower(loc.Language), codeList) { 74 util.AppendToStringSemicolonDelim(&errString, "country code '"+loc.Language+"' appears multiple times") 75 } 76 codeList = append(codeList, loc.Language) 77 78 } 79 if !foundEn { 80 util.AppendToStringSemicolonDelim(&errString, "no english PDS present") 81 } 82 } 83 if len(errString) == 0 { 84 return &LintResult{Status: Pass} 85 } else { 86 return &LintResult{Status: Error, Details: errString} 87 } 88 } 89 90 func init() { 91 RegisterLint(&Lint{ 92 Name: "e_qcstatem_qcpds_valid", 93 Description: "Checks that a QC Statement of the type id-etsi-qcs-QcPDS has the correct form", 94 Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.3.4", 95 Source: EtsiEsi, 96 EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, 97 Lint: &qcStatemQcPdsValid{}, 98 }) 99 }