File: oid.go

package info (click to toggle)
golang-github-zmap-zlint 3.6.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,008 kB
  • sloc: sh: 162; makefile: 38
file content (210 lines) | stat: -rw-r--r-- 12,368 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
 * ZLint Copyright 2024 Regents of the University of Michigan
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package util

import (
	"errors"

	"github.com/zmap/zcrypto/encoding/asn1"
	"github.com/zmap/zcrypto/x509"
	"github.com/zmap/zcrypto/x509/pkix"
)

var (
	//extension OIDs
	AdobeTimeStampOID            = asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 9, 1}    // Adobe Time-stamp x509 extension
	AdobeArchiveRevInfoOID       = asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 9, 2}    // Adobe Archive Revocation Info x509 extension
	AiaOID                       = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1}        // Authority Information Access
	AuthkeyOID                   = asn1.ObjectIdentifier{2, 5, 29, 35}                     // Authority Key Identifier
	BasicConstOID                = asn1.ObjectIdentifier{2, 5, 29, 19}                     // Basic Constraints
	CertPolicyOID                = asn1.ObjectIdentifier{2, 5, 29, 32}                     // Certificate Policies
	CrlDistOID                   = asn1.ObjectIdentifier{2, 5, 29, 31}                     // CRL Distribution Points
	CtPoisonOID                  = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3} // CT Poison
	EkuSynOid                    = asn1.ObjectIdentifier{2, 5, 29, 37}                     // Extended Key Usage Syntax
	FreshCRLOID                  = asn1.ObjectIdentifier{2, 5, 29, 46}                     // Freshest CRL
	InhibitAnyPolicyOID          = asn1.ObjectIdentifier{2, 5, 29, 54}                     // Inhibit Any Policy
	IssuerAlternateNameOID       = asn1.ObjectIdentifier{2, 5, 29, 18}                     // Issuer Alt Name
	KeyUsageOID                  = asn1.ObjectIdentifier{2, 5, 29, 15}                     // Key Usage
	LegalEntityIdentifierOID     = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 52266, 1}       // Legal Entity Identifier
	LegalEntityIdentifierRoleOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 52266, 2}       // Legal Entity Identifier Role
	LogoTypeOID                  = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 12}       // Logo Type Ext
	NameConstOID                 = asn1.ObjectIdentifier{2, 5, 29, 30}                     // Name Constraints
	OscpNoCheckOID               = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 5}    // OSCP No Check
	PolicyConstOID               = asn1.ObjectIdentifier{2, 5, 29, 36}                     // Policy Constraints
	PolicyMapOID                 = asn1.ObjectIdentifier{2, 5, 29, 33}                     // Policy Mappings
	PrivKeyUsageOID              = asn1.ObjectIdentifier{2, 5, 29, 16}                     // Private Key Usage Period
	QcStateOid                   = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3}        // QC Statements
	TimestampOID                 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} // Signed Certificate Timestamp List
	SmimeOID                     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 15}      // Smime Capabilities
	SubjectAlternateNameOID      = asn1.ObjectIdentifier{2, 5, 29, 17}                     // Subject Alt Name
	SubjectDirAttrOID            = asn1.ObjectIdentifier{2, 5, 29, 9}                      // Subject Directory Attributes
	SubjectInfoAccessOID         = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11}       // Subject Info Access Syntax
	SubjectKeyIdentityOID        = asn1.ObjectIdentifier{2, 5, 29, 14}                     // Subject Key Identifier
	ReasonCodeOID                = asn1.ObjectIdentifier{2, 5, 29, 21}                     // CRL Reason Code
	// CA/B reserved policies
	BRDomainValidatedOID                        = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}    // CA/B BR Domain-Validated
	BROrganizationValidatedOID                  = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 2}    // CA/B BR Organization-Validated
	BRIndividualValidatedOID                    = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 3}    // CA/B BR Individual-Validated
	BRTorServiceDescriptor                      = asn1.ObjectIdentifier{2, 23, 140, 1, 31}      // CA/B BR Tor Service Descriptor
	CabfExtensionOrganizationIdentifier         = asn1.ObjectIdentifier{2, 23, 140, 3, 1}       // CA/B EV 9.8.2 cabfOrganizationIdentifier
	SMIMEBRMailboxValidatedLegacyOID            = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 1, 1} // CA/B SMIME BR Mailbox Validated, Legacy
	SMIMEBRMailboxValidatedMultipurposeOID      = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 1, 2} // CA/B SMIME BR Mailbox Validated, Multipurpose
	SMIMEBRMailboxValidatedStrictOID            = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 1, 3} // CA/B SMIME BR Mailbox Validated, Strict
	SMIMEBROrganizationValidatedLegacyOID       = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 2, 1} // CA/B SMIME BR Organization Validated, Legacy
	SMIMEBROrganizationValidatedMultipurposeOID = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 2, 2} // CA/B SMIME BR Organization Validated, Multipurpose
	SMIMEBROrganizationValidatedStrictOID       = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 2, 3} // CA/B SMIME BR Organization Validated, Strict
	SMIMEBRSponsorValidatedLegacyOID            = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 3, 1} // CA/B SMIME BR Sponsor Validated, Legacy
	SMIMEBRSponsorValidatedMultipurposeOID      = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 3, 2} // CA/B SMIME BR Sponsor Validated, Multipurpose
	SMIMEBRSponsorValidatedStrictOID            = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 3, 3} // CA/B SMIME BR Sponsor Validated, Strict
	SMIMEBRIndividualValidatedLegacyOID         = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 4, 1} // CA/B SMIME BR Individual Validated, Legacy
	SMIMEBRIndividualValidatedMultipurposeOID   = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 4, 2} // CA/B SMIME BR Individual Validated, Multipurpose
	SMIMEBRIndividualValidatedStrictOID         = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 4, 3} // CA/B SMIME BR Individual Validated, Strict
	//X.500 attribute types
	CommonNameOID             = asn1.ObjectIdentifier{2, 5, 4, 3}
	SurnameOID                = asn1.ObjectIdentifier{2, 5, 4, 4}
	SerialOID                 = asn1.ObjectIdentifier{2, 5, 4, 5}
	CountryNameOID            = asn1.ObjectIdentifier{2, 5, 4, 6}
	LocalityNameOID           = asn1.ObjectIdentifier{2, 5, 4, 7}
	StateOrProvinceNameOID    = asn1.ObjectIdentifier{2, 5, 4, 8}
	StreetAddressOID          = asn1.ObjectIdentifier{2, 5, 4, 9}
	OrganizationNameOID       = asn1.ObjectIdentifier{2, 5, 4, 10}
	OrganizationalUnitNameOID = asn1.ObjectIdentifier{2, 5, 4, 11}
	BusinessOID               = asn1.ObjectIdentifier{2, 5, 4, 15}
	PostalCodeOID             = asn1.ObjectIdentifier{2, 5, 4, 17}
	GivenNameOID              = asn1.ObjectIdentifier{2, 5, 4, 42}
	// SAN otherNames
	OidIdOnSmtpUtf8Mailbox = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 9}
	// Hash algorithms - see https://golang.org/src/crypto/x509/x509.go
	SHA256OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
	SHA384OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
	SHA512OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
	// other OIDs
	OidRSAEncryption           = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
	OidRSASSAPSS               = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
	OidMD2WithRSAEncryption    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
	OidMD5WithRSAEncryption    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
	OidSHA1WithRSAEncryption   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
	OidSHA224WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 14}
	OidSHA256WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
	OidSHA384WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
	OidSHA512WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
	AnyPolicyOID               = asn1.ObjectIdentifier{2, 5, 29, 32, 0}
	UserNoticeOID              = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 2}
	CpsOID                     = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1}
	IdEtsiQcsQcCompliance      = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 1}
	IdEtsiQcsQcLimitValue      = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 2}
	IdEtsiQcsQcRetentionPeriod = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 3}
	IdEtsiQcsQcSSCD            = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 4}
	IdEtsiQcsQcEuPDS           = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 5}
	IdEtsiQcsQcType            = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6}
	IdEtsiQcsQctEsign          = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 1}
	IdEtsiQcsQctEseal          = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 2}
	IdEtsiQcsQctWeb            = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 3}
)

const (
	// Tags
	DNSNameTag = 2
)

// IsExtInCert is equivalent to GetExtFromCert() != nil.
func IsExtInCert(cert *x509.Certificate, oid asn1.ObjectIdentifier) bool {
	if cert != nil && GetExtFromCert(cert, oid) != nil {
		return true
	}
	return false
}

// GetExtFromCert returns the extension with the matching OID, if present. If
// the extension if not present, it returns nil.
func GetExtFromCert(cert *x509.Certificate, oid asn1.ObjectIdentifier) *pkix.Extension {
	// Since this function is called by many Lint CheckApplies functions we use
	// the x509.Certificate.ExtensionsMap field added by zcrypto to check for
	// the extension in O(1) instead of looping through the
	// `x509.Certificate.Extensions` in O(n).
	if ext, found := cert.ExtensionsMap[oid.String()]; found {
		return &ext
	}
	return nil
}

// Helper function that checks if an []asn1.ObjectIdentifier slice contains an asn1.ObjectIdentifier
func SliceContainsOID(list []asn1.ObjectIdentifier, oid asn1.ObjectIdentifier) bool {
	for _, v := range list {
		if oid.Equal(v) {
			return true
		}
	}
	return false
}

// Helper function that checks for a name type in a pkix.Name
func TypeInName(name *pkix.Name, oid asn1.ObjectIdentifier) bool {
	for _, v := range name.Names {
		if oid.Equal(v.Type) {
			return true
		}
	}
	return false
}

func GetTypesInName(name *pkix.Name) []asn1.ObjectIdentifier {
	types := make([]asn1.ObjectIdentifier, 0)
	for _, name := range name.Names {
		types = append(types, name.Type)
	}
	return types
}

// helper function to parse policyMapping extensions, returns slices of CertPolicyIds separated by domain
func GetMappedPolicies(polMap *pkix.Extension) ([][2]asn1.ObjectIdentifier, error) {
	if polMap == nil {
		return nil, errors.New("policyMap: null pointer")
	}
	var outSeq, inSeq asn1.RawValue

	empty, err := asn1.Unmarshal(polMap.Value, &outSeq) //strip outer sequence tag/length should be nothing extra
	if err != nil || len(empty) != 0 || outSeq.Class != 0 || outSeq.Tag != 16 || !outSeq.IsCompound {
		return nil, errors.New("policyMap: Could not unmarshal outer sequence.")
	}

	var out [][2]asn1.ObjectIdentifier
	for done := false; !done; { //loop through SEQUENCE OF
		outSeq.Bytes, err = asn1.Unmarshal(outSeq.Bytes, &inSeq) //extract next inner SEQUENCE (OID pair)
		if err != nil || inSeq.Class != 0 || inSeq.Tag != 16 || !inSeq.IsCompound {
			return nil, errors.New("policyMap: Could not unmarshal inner sequence.")
		}
		if len(outSeq.Bytes) == 0 { //nothing remaining to parse, stop looping after
			done = true
		}

		var oidIssue, oidSubject asn1.ObjectIdentifier
		var restIn asn1.RawContent
		restIn, err = asn1.Unmarshal(inSeq.Bytes, &oidIssue) //extract first inner CertPolicyId (issuer domain)
		if err != nil || len(restIn) == 0 {
			return nil, errors.New("policyMap: Could not unmarshal inner sequence.")
		}

		empty, err = asn1.Unmarshal(restIn, &oidSubject) //extract second inner CertPolicyId (subject domain)
		if err != nil || len(empty) != 0 {
			return nil, errors.New("policyMap: Could not unmarshal inner sequence.")
		}

		//append found OIDs
		out = append(out, [2]asn1.ObjectIdentifier{oidIssue, oidSubject})
	}

	return out, nil
}