github.com/zmap/zlint@v1.1.0/lints/lint_generalized_time_includes_fraction_seconds.go (about) 1 package lints 2 3 /* 4 * ZLint Copyright 2018 Regents of the University of Michigan 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 * use this file except in compliance with the License. You may obtain a copy 8 * of the License at http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 * implied. See the License for the specific language governing 14 * permissions and limitations under the License. 15 */ 16 17 /******************************************************************** 18 4.1.2.5.2. GeneralizedTime 19 The generalized time type, GeneralizedTime, is a standard ASN.1 type 20 for variable precision representation of time. Optionally, the 21 GeneralizedTime field can include a representation of the time 22 differential between local and Greenwich Mean Time. 23 24 For the purposes of this profile, GeneralizedTime values MUST be 25 expressed in Greenwich Mean Time (Zulu) and MUST include seconds 26 (i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds 27 is zero. GeneralizedTime values MUST NOT include fractional seconds. 28 ********************************************************************/ 29 30 import ( 31 "encoding/asn1" 32 33 "github.com/zmap/zcrypto/x509" 34 "github.com/zmap/zlint/util" 35 ) 36 37 type generalizedTimeFraction struct { 38 } 39 40 func (l *generalizedTimeFraction) Initialize() error { 41 return nil 42 } 43 44 func (l *generalizedTimeFraction) CheckApplies(c *x509.Certificate) bool { 45 firstDate, secondDate := util.GetTimes(c) 46 beforeTag, afterTag := util.FindTimeType(firstDate, secondDate) 47 date1Gen := beforeTag == 24 48 date2Gen := afterTag == 24 49 return date1Gen || date2Gen 50 } 51 52 func (l *generalizedTimeFraction) Execute(c *x509.Certificate) *LintResult { 53 r := Pass 54 date1, date2 := util.GetTimes(c) 55 beforeTag, afterTag := util.FindTimeType(date1, date2) 56 date1Gen := beforeTag == 24 57 date2Gen := afterTag == 24 58 if date1Gen { 59 // UTC Tests on notBefore 60 checkFraction(&r, date1) 61 if r == Error { 62 return &LintResult{Status: r} 63 } 64 } 65 if date2Gen { 66 checkFraction(&r, date2) 67 } 68 return &LintResult{Status: r} 69 } 70 71 func checkFraction(r *LintStatus, t asn1.RawValue) { 72 if t.Bytes[len(t.Bytes)-1] == 'Z' { 73 if len(t.Bytes) > 15 { 74 *r = Error 75 } 76 } else if t.Bytes[len(t.Bytes)-5] == '-' || t.Bytes[len(t.Bytes)-1] == '+' { 77 if len(t.Bytes) > 19 { 78 *r = Error 79 } 80 } else { 81 if len(t.Bytes) > 14 { 82 *r = Error 83 } 84 } 85 } 86 87 func init() { 88 RegisterLint(&Lint{ 89 Name: "e_generalized_time_includes_fraction_seconds", 90 Description: "Generalized time values MUST NOT include fractional seconds", 91 Citation: "RFC 5280: 4.1.2.5.2", 92 Source: RFC5280, 93 EffectiveDate: util.RFC2459Date, 94 Lint: &generalizedTimeFraction{}, 95 }) 96 }