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 }