github.com/zmap/zlint@v1.1.0/util/oid.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  package util
    16  
    17  import (
    18  	"encoding/asn1"
    19  	"errors"
    20  
    21  	"github.com/zmap/zcrypto/x509"
    22  	"github.com/zmap/zcrypto/x509/pkix"
    23  )
    24  
    25  var (
    26  	//extension OIDs
    27  	AiaOID                  = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1}        // Authority Information Access
    28  	AuthkeyOID              = asn1.ObjectIdentifier{2, 5, 29, 35}                     // Authority Key Identifier
    29  	BasicConstOID           = asn1.ObjectIdentifier{2, 5, 29, 19}                     // Basic Constraints
    30  	CertPolicyOID           = asn1.ObjectIdentifier{2, 5, 29, 32}                     // Certificate Policies
    31  	CrlDistOID              = asn1.ObjectIdentifier{2, 5, 29, 31}                     // CRL Distribution Points
    32  	CtPoisonOID             = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3} // CT Poison
    33  	EkuSynOid               = asn1.ObjectIdentifier{2, 5, 29, 37}                     // Extended Key Usage Syntax
    34  	FreshCRLOID             = asn1.ObjectIdentifier{2, 5, 29, 46}                     // Freshest CRL
    35  	InhibitAnyPolicyOID     = asn1.ObjectIdentifier{2, 5, 29, 54}                     // Inhibit Any Policy
    36  	IssuerAlternateNameOID  = asn1.ObjectIdentifier{2, 5, 29, 18}                     // Issuer Alt Name
    37  	KeyUsageOID             = asn1.ObjectIdentifier{2, 5, 29, 15}                     // Key Usage
    38  	LogoTypeOID             = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 12}       // Logo Type Ext
    39  	NameConstOID            = asn1.ObjectIdentifier{2, 5, 29, 30}                     // Name Constraints
    40  	OscpNoCheckOID          = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 5}    // OSCP No Check
    41  	PolicyConstOID          = asn1.ObjectIdentifier{2, 5, 29, 36}                     // Policy Constraints
    42  	PolicyMapOID            = asn1.ObjectIdentifier{2, 5, 29, 33}                     // Policy Mappings
    43  	PrivKeyUsageOID         = asn1.ObjectIdentifier{2, 5, 29, 16}                     // Private Key Usage Period
    44  	QcStateOid              = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3}        // QC Statements
    45  	TimestampOID            = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} // Signed Certificate Timestamp List
    46  	SmimeOID                = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 15}      // Smime Capabilities
    47  	SubjectAlternateNameOID = asn1.ObjectIdentifier{2, 5, 29, 17}                     // Subject Alt Name
    48  	SubjectDirAttrOID       = asn1.ObjectIdentifier{2, 5, 29, 9}                      // Subject Directory Attributes
    49  	SubjectInfoAccessOID    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11}       // Subject Info Access Syntax
    50  	SubjectKeyIdentityOID   = asn1.ObjectIdentifier{2, 5, 29, 14}                     // Subject Key Identifier
    51  	// CA/B reserved policies
    52  	BRDomainValidatedOID       = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1} // CA/B BR Domain-Validated
    53  	BROrganizationValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 2} // CA/B BR Organization-Validated
    54  	BRIndividualValidatedOID   = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 3} // CA/B BR Individual-Validated
    55  	BRTorServiceDescriptor     = asn1.ObjectIdentifier{2, 23, 140, 1, 31}   // CA/B BR Tor Service Descriptor
    56  	//X.500 attribute types
    57  	CommonNameOID             = asn1.ObjectIdentifier{2, 5, 4, 3}
    58  	SurnameOID                = asn1.ObjectIdentifier{2, 5, 4, 4}
    59  	SerialOID                 = asn1.ObjectIdentifier{2, 5, 4, 5}
    60  	CountryNameOID            = asn1.ObjectIdentifier{2, 5, 4, 6}
    61  	LocalityNameOID           = asn1.ObjectIdentifier{2, 5, 4, 7}
    62  	StateOrProvinceNameOID    = asn1.ObjectIdentifier{2, 5, 4, 8}
    63  	StreetAddressOID          = asn1.ObjectIdentifier{2, 5, 4, 9}
    64  	OrganizationNameOID       = asn1.ObjectIdentifier{2, 5, 4, 10}
    65  	OrganizationalUnitNameOID = asn1.ObjectIdentifier{2, 5, 4, 11}
    66  	BusinessOID               = asn1.ObjectIdentifier{2, 5, 4, 15}
    67  	PostalCodeOID             = asn1.ObjectIdentifier{2, 5, 4, 17}
    68  	GivenNameOID              = asn1.ObjectIdentifier{2, 5, 4, 42}
    69  	// Hash algorithms - see https://golang.org/src/crypto/x509/x509.go
    70  	SHA256OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
    71  	SHA384OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
    72  	SHA512OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
    73  	// other OIDs
    74  	OidRSAEncryption           = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
    75  	OidRSASSAPSS               = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
    76  	OidMD2WithRSAEncryption    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
    77  	OidMD5WithRSAEncryption    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
    78  	OidSHA1WithRSAEncryption   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
    79  	OidSHA224WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 14}
    80  	OidSHA256WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
    81  	OidSHA384WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
    82  	OidSHA512WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
    83  	AnyPolicyOID               = asn1.ObjectIdentifier{2, 5, 29, 32, 0}
    84  	UserNoticeOID              = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 2}
    85  	CpsOID                     = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1}
    86  	IdEtsiQcsQcCompliance      = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 1}
    87  	IdEtsiQcsQcLimitValue      = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 2}
    88  	IdEtsiQcsQcRetentionPeriod = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 3}
    89  	IdEtsiQcsQcSSCD            = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 4}
    90  	IdEtsiQcsQcEuPDS           = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 5}
    91  	IdEtsiQcsQcType            = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6}
    92  	IdEtsiQcsQctEsign          = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 1}
    93  	IdEtsiQcsQctEseal          = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 2}
    94  	IdEtsiQcsQctWeb            = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 3}
    95  )
    96  
    97  const (
    98  	// Tags
    99  	DNSNameTag = 2
   100  )
   101  
   102  // IsExtInCert is equivalent to GetExtFromCert() != nil.
   103  func IsExtInCert(cert *x509.Certificate, oid asn1.ObjectIdentifier) bool {
   104  	if cert != nil && GetExtFromCert(cert, oid) != nil {
   105  		return true
   106  	}
   107  	return false
   108  }
   109  
   110  // GetExtFromCert returns the extension with the matching OID, if present. If
   111  // the extension if not present, it returns nil.
   112  func GetExtFromCert(cert *x509.Certificate, oid asn1.ObjectIdentifier) *pkix.Extension {
   113  	// Since this function is called by many Lint CheckApplies functions we use
   114  	// the x509.Certificate.ExtensionsMap field added by zcrypto to check for
   115  	// the extension in O(1) instead of looping through the
   116  	// `x509.Certificate.Extensions` in O(n).
   117  	if ext, found := cert.ExtensionsMap[oid.String()]; found {
   118  		return &ext
   119  	}
   120  	return nil
   121  }
   122  
   123  // Helper function that checks if an []asn1.ObjectIdentifier slice contains an asn1.ObjectIdentifier
   124  func SliceContainsOID(list []asn1.ObjectIdentifier, oid asn1.ObjectIdentifier) bool {
   125  	for _, v := range list {
   126  		if oid.Equal(v) {
   127  			return true
   128  		}
   129  	}
   130  	return false
   131  }
   132  
   133  // Helper function that checks for a name type in a pkix.Name
   134  func TypeInName(name *pkix.Name, oid asn1.ObjectIdentifier) bool {
   135  	for _, v := range name.Names {
   136  		if oid.Equal(v.Type) {
   137  			return true
   138  		}
   139  	}
   140  	return false
   141  }
   142  
   143  //helper function to parse policyMapping extensions, returns slices of CertPolicyIds separated by domain
   144  func GetMappedPolicies(polMap *pkix.Extension) (out [][2]asn1.ObjectIdentifier, err error) {
   145  	if polMap == nil {
   146  		return nil, errors.New("policyMap: null pointer")
   147  	}
   148  	var outSeq, inSeq asn1.RawValue
   149  
   150  	empty, err := asn1.Unmarshal(polMap.Value, &outSeq) //strip outer sequence tag/length should be nothing extra
   151  	if err != nil || len(empty) != 0 || outSeq.Class != 0 || outSeq.Tag != 16 || outSeq.IsCompound == false {
   152  		return nil, errors.New("policyMap: Could not unmarshal outer sequence.")
   153  	}
   154  
   155  	for done := false; !done; { //loop through SEQUENCE OF
   156  		outSeq.Bytes, err = asn1.Unmarshal(outSeq.Bytes, &inSeq) //extract next inner SEQUENCE (OID pair)
   157  		if err != nil || inSeq.Class != 0 || inSeq.Tag != 16 || inSeq.IsCompound == false {
   158  			err = errors.New("policyMap: Could not unmarshal inner sequence.")
   159  			return
   160  		}
   161  		if len(outSeq.Bytes) == 0 { //nothing remaining to parse, stop looping after
   162  			done = true
   163  		}
   164  
   165  		var oidIssue, oidSubject asn1.ObjectIdentifier
   166  		var restIn asn1.RawContent
   167  		restIn, err = asn1.Unmarshal(inSeq.Bytes, &oidIssue) //extract first inner CertPolicyId (issuer domain)
   168  		if err != nil || len(restIn) == 0 {
   169  			err = errors.New("policyMap: Could not unmarshal inner sequence.")
   170  			return
   171  		}
   172  
   173  		empty, err = asn1.Unmarshal(restIn, &oidSubject) //extract second inner CertPolicyId (subject domain)
   174  		if err != nil || len(empty) != 0 {
   175  			err = errors.New("policyMap: Could not unmarshal inner sequence.")
   176  			return
   177  		}
   178  
   179  		//append found OIDs
   180  		out = append(out, [2]asn1.ObjectIdentifier{oidIssue, oidSubject})
   181  	}
   182  
   183  	return
   184  }