github.com/zmap/zlint@v1.1.0/lints/lint_ext_cert_policy_explicit_text_includes_control.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  An explicitText field includes the textual statement directly in
    19  the certificate.  The explicitText field is a string with a
    20  maximum size of 200 characters.  Conforming CAs SHOULD use the
    21  UTF8String encoding for explicitText, but MAY use IA5String.
    22  Conforming CAs MUST NOT encode explicitText as VisibleString or
    23  BMPString.  The explicitText string SHOULD NOT include any control
    24  characters (e.g., U+0000 to U+001F and U+007F to U+009F).  When
    25  the UTF8String encoding is used, all character sequences SHOULD be
    26  normalized according to Unicode normalization form C (NFC) [NFC].
    27  *********************************************************************/
    28  
    29  import (
    30  	"github.com/zmap/zcrypto/x509"
    31  	"github.com/zmap/zlint/util"
    32  )
    33  
    34  type controlChar struct{}
    35  
    36  func (l *controlChar) Initialize() error {
    37  	return nil
    38  }
    39  
    40  func (l *controlChar) CheckApplies(c *x509.Certificate) bool {
    41  	for _, text := range c.ExplicitTexts {
    42  		if text != nil {
    43  			return true
    44  		}
    45  	}
    46  	return false
    47  }
    48  
    49  func (l *controlChar) Execute(c *x509.Certificate) *LintResult {
    50  	for _, firstLvl := range c.ExplicitTexts {
    51  		for _, text := range firstLvl {
    52  			if text.Tag == 12 {
    53  				for i := 0; i < len(text.Bytes); i++ {
    54  					if text.Bytes[i]&0x80 == 0 {
    55  						if text.Bytes[i] < 0x20 || text.Bytes[i] == 0x7f {
    56  							return &LintResult{Status: Warn}
    57  						}
    58  					} else if text.Bytes[i]&0x20 == 0 {
    59  						if text.Bytes[i] == 0xc2 && text.Bytes[i+1] >= 0x80 && text.Bytes[i+1] <= 0x9f {
    60  							return &LintResult{Status: Warn}
    61  						}
    62  						i += 1
    63  					} else if text.Bytes[i]&0x10 == 0 {
    64  						i += 2
    65  					} else if text.Bytes[i]&0x08 == 0 {
    66  						i += 3
    67  					} else if text.Bytes[i]&0x04 == 0 {
    68  						i += 4
    69  					} else if text.Bytes[i]&0x02 == 0 {
    70  						i += 5
    71  					}
    72  				}
    73  			}
    74  		}
    75  	}
    76  
    77  	return &LintResult{Status: Pass}
    78  }
    79  
    80  func init() {
    81  	RegisterLint(&Lint{
    82  		Name:          "w_ext_cert_policy_explicit_text_includes_control",
    83  		Description:   "Explicit text should not include any control characters",
    84  		Citation:      "RFC 6818: 3",
    85  		Source:        RFC5280,
    86  		EffectiveDate: util.RFC6818Date,
    87  		Lint:          &controlChar{},
    88  	})
    89  }