extensions.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package x509
  5. import (
  6. "encoding/hex"
  7. "encoding/json"
  8. "net"
  9. "strconv"
  10. "strings"
  11. "github.com/zmap/zcrypto/encoding/asn1"
  12. "github.com/zmap/zcrypto/x509/ct"
  13. "github.com/zmap/zcrypto/x509/pkix"
  14. )
  15. var (
  16. oidExtKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 15}
  17. oidExtBasicConstraints = asn1.ObjectIdentifier{2, 5, 29, 19}
  18. oidExtSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17}
  19. oidExtIssuerAltName = asn1.ObjectIdentifier{2, 5, 29, 18}
  20. oidExtNameConstraints = asn1.ObjectIdentifier{2, 5, 29, 30}
  21. oidCRLDistributionPoints = asn1.ObjectIdentifier{2, 5, 29, 31}
  22. oidExtAuthKeyId = asn1.ObjectIdentifier{2, 5, 29, 35}
  23. oidExtSubjectKeyId = asn1.ObjectIdentifier{2, 5, 29, 14}
  24. oidExtExtendedKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 37}
  25. oidExtCertificatePolicy = asn1.ObjectIdentifier{2, 5, 29, 32}
  26. oidExtensionCRLNumber = asn1.ObjectIdentifier{2, 5, 29, 20}
  27. oidExtensionReasonCode = asn1.ObjectIdentifier{2, 5, 29, 21}
  28. oidExtAuthorityInfoAccess = oidExtensionAuthorityInfoAccess
  29. oidExtensionCTPrecertificatePoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3}
  30. oidExtSignedCertificateTimestampList = oidExtensionSignedCertificateTimestampList
  31. oidExtCABFOrganizationID = asn1.ObjectIdentifier{2, 23, 140, 3, 1}
  32. oidExtQCStatements = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3}
  33. )
  34. type CertificateExtensions struct {
  35. KeyUsage KeyUsage `json:"key_usage,omitempty"`
  36. BasicConstraints *BasicConstraints `json:"basic_constraints,omitempty"`
  37. SubjectAltName *GeneralNames `json:"subject_alt_name,omitempty"`
  38. IssuerAltName *GeneralNames `json:"issuer_alt_name,omitempty"`
  39. NameConstraints *NameConstraints `json:"name_constraints,omitempty"`
  40. CRLDistributionPoints CRLDistributionPoints `json:"crl_distribution_points,omitempty"`
  41. AuthKeyID SubjAuthKeyId `json:"authority_key_id,omitempty"`
  42. SubjectKeyID SubjAuthKeyId `json:"subject_key_id,omitempty"`
  43. ExtendedKeyUsage *ExtendedKeyUsageExtension `json:"extended_key_usage,omitempty"`
  44. CertificatePolicies *CertificatePoliciesData `json:"certificate_policies,omitempty"`
  45. AuthorityInfoAccess *AuthorityInfoAccess `json:"authority_info_access,omitempty"`
  46. IsPrecert IsPrecert `json:"ct_poison,omitempty"`
  47. SignedCertificateTimestampList []*ct.SignedCertificateTimestamp `json:"signed_certificate_timestamps,omitempty"`
  48. TorServiceDescriptors []*TorServiceDescriptorHash `json:"tor_service_descriptors,omitempty"`
  49. CABFOrganizationIdentifier *CABFOrganizationIdentifier `json:"cabf_organization_id,omitempty"`
  50. QCStatements *QCStatements `json:"qc_statements,omitempty"`
  51. }
  52. type UnknownCertificateExtensions []pkix.Extension
  53. type IsPrecert bool
  54. type BasicConstraints struct {
  55. IsCA bool `json:"is_ca"`
  56. MaxPathLen *int `json:"max_path_len,omitempty"`
  57. }
  58. type NoticeReference struct {
  59. Organization string `json:"organization,omitempty"`
  60. NoticeNumbers NoticeNumber `json:"notice_numbers,omitempty"`
  61. }
  62. type UserNoticeData struct {
  63. ExplicitText string `json:"explicit_text,omitempty"`
  64. NoticeReference []NoticeReference `json:"notice_reference,omitempty"`
  65. }
  66. type CertificatePoliciesJSON struct {
  67. PolicyIdentifier string `json:"id,omitempty"`
  68. CPSUri []string `json:"cps,omitempty"`
  69. UserNotice []UserNoticeData `json:"user_notice,omitempty"`
  70. }
  71. type CertificatePolicies []CertificatePoliciesJSON
  72. type CertificatePoliciesData struct {
  73. PolicyIdentifiers []asn1.ObjectIdentifier
  74. QualifierId [][]asn1.ObjectIdentifier
  75. CPSUri [][]string
  76. ExplicitTexts [][]string
  77. NoticeRefOrganization [][]string
  78. NoticeRefNumbers [][]NoticeNumber
  79. }
  80. func (cp *CertificatePoliciesData) MarshalJSON() ([]byte, error) {
  81. policies := CertificatePolicies{}
  82. for idx, oid := range cp.PolicyIdentifiers {
  83. cpsJSON := CertificatePoliciesJSON{}
  84. cpsJSON.PolicyIdentifier = oid.String()
  85. for _, uri := range cp.CPSUri[idx] {
  86. cpsJSON.CPSUri = append(cpsJSON.CPSUri, uri)
  87. }
  88. for idx2, explicit_text := range cp.ExplicitTexts[idx] {
  89. uNoticeData := UserNoticeData{}
  90. uNoticeData.ExplicitText = explicit_text
  91. noticeRef := NoticeReference{}
  92. if len(cp.NoticeRefOrganization[idx]) > 0 {
  93. organization := cp.NoticeRefOrganization[idx][idx2]
  94. noticeRef.Organization = organization
  95. noticeRef.NoticeNumbers = cp.NoticeRefNumbers[idx][idx2]
  96. uNoticeData.NoticeReference = append(uNoticeData.NoticeReference, noticeRef)
  97. }
  98. cpsJSON.UserNotice = append(cpsJSON.UserNotice, uNoticeData)
  99. }
  100. policies = append(policies, cpsJSON)
  101. }
  102. return json.Marshal(policies)
  103. }
  104. // GeneralNames corresponds an X.509 GeneralName defined in
  105. // Section 4.2.1.6 of RFC 5280.
  106. //
  107. // GeneralName ::= CHOICE {
  108. // otherName [0] AnotherName,
  109. // rfc822Name [1] IA5String,
  110. // dNSName [2] IA5String,
  111. // x400Address [3] ORAddress,
  112. // directoryName [4] Name,
  113. // ediPartyName [5] EDIPartyName,
  114. // uniformResourceIdentifier [6] IA5String,
  115. // iPAddress [7] OCTET STRING,
  116. // registeredID [8] OBJECT IDENTIFIER }
  117. type GeneralNames struct {
  118. DirectoryNames []pkix.Name
  119. DNSNames []string
  120. EDIPartyNames []pkix.EDIPartyName
  121. EmailAddresses []string
  122. IPAddresses []net.IP
  123. OtherNames []pkix.OtherName
  124. RegisteredIDs []asn1.ObjectIdentifier
  125. URIs []string
  126. }
  127. type jsonGeneralNames struct {
  128. DirectoryNames []pkix.Name `json:"directory_names,omitempty"`
  129. DNSNames []string `json:"dns_names,omitempty"`
  130. EDIPartyNames []pkix.EDIPartyName `json:"edi_party_names,omitempty"`
  131. EmailAddresses []string `json:"email_addresses,omitempty"`
  132. IPAddresses []net.IP `json:"ip_addresses,omitempty"`
  133. OtherNames []pkix.OtherName `json:"other_names,omitempty"`
  134. RegisteredIDs []string `json:"registered_ids,omitempty"`
  135. URIs []string `json:"uniform_resource_identifiers,omitempty"`
  136. }
  137. func (gn *GeneralNames) MarshalJSON() ([]byte, error) {
  138. jsan := jsonGeneralNames{
  139. DirectoryNames: gn.DirectoryNames,
  140. DNSNames: gn.DNSNames,
  141. EDIPartyNames: gn.EDIPartyNames,
  142. EmailAddresses: gn.EmailAddresses,
  143. IPAddresses: gn.IPAddresses,
  144. OtherNames: gn.OtherNames,
  145. RegisteredIDs: make([]string, 0, len(gn.RegisteredIDs)),
  146. URIs: gn.URIs,
  147. }
  148. for _, id := range gn.RegisteredIDs {
  149. jsan.RegisteredIDs = append(jsan.RegisteredIDs, id.String())
  150. }
  151. return json.Marshal(jsan)
  152. }
  153. func (gn *GeneralNames) UnmarshalJSON(b []byte) error {
  154. var jsan jsonGeneralNames
  155. err := json.Unmarshal(b, &jsan)
  156. if err != nil {
  157. return err
  158. }
  159. gn.DirectoryNames = jsan.DirectoryNames
  160. gn.DNSNames = jsan.DNSNames
  161. gn.EDIPartyNames = jsan.EDIPartyNames
  162. gn.EmailAddresses = jsan.EmailAddresses
  163. gn.IPAddresses = jsan.IPAddresses
  164. gn.OtherNames = jsan.OtherNames
  165. gn.RegisteredIDs = make([]asn1.ObjectIdentifier, len(jsan.RegisteredIDs))
  166. gn.URIs = jsan.URIs
  167. for i, rID := range jsan.RegisteredIDs {
  168. arcs := strings.Split(rID, ".")
  169. oid := make(asn1.ObjectIdentifier, len(arcs))
  170. for j, s := range arcs {
  171. tmp, err := strconv.ParseInt(s, 10, 32)
  172. if err != nil {
  173. return err
  174. }
  175. oid[j] = int(tmp)
  176. }
  177. gn.RegisteredIDs[i] = oid
  178. }
  179. return nil
  180. }
  181. // TODO: Handle excluded names
  182. type NameConstraints struct {
  183. Critical bool `json:"critical"`
  184. PermittedDNSNames []GeneralSubtreeString
  185. PermittedEmailAddresses []GeneralSubtreeString
  186. PermittedURIs []GeneralSubtreeString
  187. PermittedIPAddresses []GeneralSubtreeIP
  188. PermittedDirectoryNames []GeneralSubtreeName
  189. PermittedEdiPartyNames []GeneralSubtreeEdi
  190. PermittedRegisteredIDs []GeneralSubtreeOid
  191. ExcludedEmailAddresses []GeneralSubtreeString
  192. ExcludedDNSNames []GeneralSubtreeString
  193. ExcludedURIs []GeneralSubtreeString
  194. ExcludedIPAddresses []GeneralSubtreeIP
  195. ExcludedDirectoryNames []GeneralSubtreeName
  196. ExcludedEdiPartyNames []GeneralSubtreeEdi
  197. ExcludedRegisteredIDs []GeneralSubtreeOid
  198. }
  199. type NameConstraintsJSON struct {
  200. Critical bool `json:"critical"`
  201. PermittedDNSNames []string `json:"permitted_names,omitempty"`
  202. PermittedEmailAddresses []string `json:"permitted_email_addresses,omitempty"`
  203. PermittedURIs []string `json:"permitted_uris,omitempty"`
  204. PermittedIPAddresses []GeneralSubtreeIP `json:"permitted_ip_addresses,omitempty"`
  205. PermittedDirectoryNames []pkix.Name `json:"permitted_directory_names,omitempty"`
  206. PermittedEdiPartyNames []pkix.EDIPartyName `json:"permitted_edi_party_names,omitempty"`
  207. PermittedRegisteredIDs []string `json:"permitted_registred_id,omitempty"`
  208. ExcludedDNSNames []string `json:"excluded_names,omitempty"`
  209. ExcludedEmailAddresses []string `json:"excluded_email_addresses,omitempty"`
  210. ExcludedURIs []string `json:"excluded_uris,omitempty"`
  211. ExcludedIPAddresses []GeneralSubtreeIP `json:"excluded_ip_addresses,omitempty"`
  212. ExcludedDirectoryNames []pkix.Name `json:"excluded_directory_names,omitempty"`
  213. ExcludedEdiPartyNames []pkix.EDIPartyName `json:"excluded_edi_party_names,omitempty"`
  214. ExcludedRegisteredIDs []string `json:"excluded_registred_id,omitempty"`
  215. }
  216. func (nc *NameConstraints) UnmarshalJSON(b []byte) error {
  217. var ncJson NameConstraintsJSON
  218. err := json.Unmarshal(b, &ncJson)
  219. if err != nil {
  220. return err
  221. }
  222. for _, dns := range ncJson.PermittedDNSNames {
  223. nc.PermittedDNSNames = append(nc.PermittedDNSNames, GeneralSubtreeString{Data: dns})
  224. }
  225. for _, email := range ncJson.PermittedEmailAddresses {
  226. nc.PermittedEmailAddresses = append(nc.PermittedEmailAddresses, GeneralSubtreeString{Data: email})
  227. }
  228. for _, uri := range ncJson.PermittedURIs {
  229. nc.PermittedURIs = append(nc.PermittedURIs, GeneralSubtreeString{Data: uri})
  230. }
  231. for _, constraint := range ncJson.PermittedIPAddresses {
  232. nc.PermittedIPAddresses = append(nc.PermittedIPAddresses, constraint)
  233. }
  234. for _, directory := range ncJson.PermittedDirectoryNames {
  235. nc.PermittedDirectoryNames = append(nc.PermittedDirectoryNames, GeneralSubtreeName{Data: directory})
  236. }
  237. for _, edi := range ncJson.PermittedEdiPartyNames {
  238. nc.PermittedEdiPartyNames = append(nc.PermittedEdiPartyNames, GeneralSubtreeEdi{Data: edi})
  239. }
  240. for _, id := range ncJson.PermittedRegisteredIDs {
  241. arcs := strings.Split(id, ".")
  242. oid := make(asn1.ObjectIdentifier, len(arcs))
  243. for j, s := range arcs {
  244. tmp, err := strconv.ParseInt(s, 10, 32)
  245. if err != nil {
  246. return err
  247. }
  248. oid[j] = int(tmp)
  249. }
  250. nc.PermittedRegisteredIDs = append(nc.PermittedRegisteredIDs, GeneralSubtreeOid{Data: oid})
  251. }
  252. for _, dns := range ncJson.ExcludedDNSNames {
  253. nc.ExcludedDNSNames = append(nc.ExcludedDNSNames, GeneralSubtreeString{Data: dns})
  254. }
  255. for _, email := range ncJson.ExcludedEmailAddresses {
  256. nc.ExcludedEmailAddresses = append(nc.ExcludedEmailAddresses, GeneralSubtreeString{Data: email})
  257. }
  258. for _, uri := range ncJson.ExcludedURIs {
  259. nc.ExcludedURIs = append(nc.ExcludedURIs, GeneralSubtreeString{Data: uri})
  260. }
  261. for _, constraint := range ncJson.ExcludedIPAddresses {
  262. nc.ExcludedIPAddresses = append(nc.ExcludedIPAddresses, constraint)
  263. }
  264. for _, directory := range ncJson.ExcludedDirectoryNames {
  265. nc.ExcludedDirectoryNames = append(nc.ExcludedDirectoryNames, GeneralSubtreeName{Data: directory})
  266. }
  267. for _, edi := range ncJson.ExcludedEdiPartyNames {
  268. nc.ExcludedEdiPartyNames = append(nc.ExcludedEdiPartyNames, GeneralSubtreeEdi{Data: edi})
  269. }
  270. for _, id := range ncJson.ExcludedRegisteredIDs {
  271. arcs := strings.Split(id, ".")
  272. oid := make(asn1.ObjectIdentifier, len(arcs))
  273. for j, s := range arcs {
  274. tmp, err := strconv.ParseInt(s, 10, 32)
  275. if err != nil {
  276. return err
  277. }
  278. oid[j] = int(tmp)
  279. }
  280. nc.ExcludedRegisteredIDs = append(nc.ExcludedRegisteredIDs, GeneralSubtreeOid{Data: oid})
  281. }
  282. return nil
  283. }
  284. func (nc NameConstraints) MarshalJSON() ([]byte, error) {
  285. var out NameConstraintsJSON
  286. for _, dns := range nc.PermittedDNSNames {
  287. out.PermittedDNSNames = append(out.PermittedDNSNames, dns.Data)
  288. }
  289. for _, email := range nc.PermittedEmailAddresses {
  290. out.PermittedEmailAddresses = append(out.PermittedEmailAddresses, email.Data)
  291. }
  292. for _, uri := range nc.PermittedURIs {
  293. out.PermittedURIs = append(out.PermittedURIs, uri.Data)
  294. }
  295. out.PermittedIPAddresses = nc.PermittedIPAddresses
  296. for _, directory := range nc.PermittedDirectoryNames {
  297. out.PermittedDirectoryNames = append(out.PermittedDirectoryNames, directory.Data)
  298. }
  299. for _, edi := range nc.PermittedEdiPartyNames {
  300. out.PermittedEdiPartyNames = append(out.PermittedEdiPartyNames, edi.Data)
  301. }
  302. for _, id := range nc.PermittedRegisteredIDs {
  303. out.PermittedRegisteredIDs = append(out.PermittedRegisteredIDs, id.Data.String())
  304. }
  305. for _, dns := range nc.ExcludedDNSNames {
  306. out.ExcludedDNSNames = append(out.ExcludedDNSNames, dns.Data)
  307. }
  308. for _, email := range nc.ExcludedEmailAddresses {
  309. out.ExcludedEmailAddresses = append(out.ExcludedEmailAddresses, email.Data)
  310. }
  311. for _, uri := range nc.ExcludedURIs {
  312. out.ExcludedURIs = append(out.ExcludedURIs, uri.Data)
  313. }
  314. for _, ip := range nc.ExcludedIPAddresses {
  315. out.ExcludedIPAddresses = append(out.ExcludedIPAddresses, ip)
  316. }
  317. for _, directory := range nc.ExcludedDirectoryNames {
  318. out.ExcludedDirectoryNames = append(out.ExcludedDirectoryNames, directory.Data)
  319. }
  320. for _, edi := range nc.ExcludedEdiPartyNames {
  321. out.ExcludedEdiPartyNames = append(out.ExcludedEdiPartyNames, edi.Data)
  322. }
  323. for _, id := range nc.ExcludedRegisteredIDs {
  324. out.ExcludedRegisteredIDs = append(out.ExcludedRegisteredIDs, id.Data.String())
  325. }
  326. return json.Marshal(out)
  327. }
  328. type CRLDistributionPoints []string
  329. type SubjAuthKeyId []byte
  330. func (kid SubjAuthKeyId) MarshalJSON() ([]byte, error) {
  331. enc := hex.EncodeToString(kid)
  332. return json.Marshal(enc)
  333. }
  334. type ExtendedKeyUsage []ExtKeyUsage
  335. type ExtendedKeyUsageExtension struct {
  336. Known ExtendedKeyUsage
  337. Unknown []asn1.ObjectIdentifier
  338. }
  339. // MarshalJSON implements the json.Marshal interface. The output is a struct of
  340. // bools, with an additional `Value` field containing the actual OIDs.
  341. func (e *ExtendedKeyUsageExtension) MarshalJSON() ([]byte, error) {
  342. aux := new(auxExtendedKeyUsage)
  343. for _, e := range e.Known {
  344. aux.populateFromExtKeyUsage(e)
  345. }
  346. for _, oid := range e.Unknown {
  347. aux.Unknown = append(aux.Unknown, oid.String())
  348. }
  349. return json.Marshal(aux)
  350. }
  351. func (e *ExtendedKeyUsageExtension) UnmarshalJSON(b []byte) error {
  352. aux := new(auxExtendedKeyUsage)
  353. if err := json.Unmarshal(b, aux); err != nil {
  354. return err
  355. }
  356. // TODO: Generate the reverse functions.
  357. return nil
  358. }
  359. //go:generate go run extended_key_usage_gen.go
  360. // The string functions for CertValidationLevel are auto-generated via
  361. // `go generate <full_path_to_x509_package>` or running `go generate` in the package directory
  362. //
  363. //go:generate stringer -type=CertValidationLevel -output=generated_certvalidationlevel_string.go
  364. type CertValidationLevel int
  365. const (
  366. UnknownValidationLevel CertValidationLevel = 0
  367. DV CertValidationLevel = 1
  368. OV CertValidationLevel = 2
  369. EV CertValidationLevel = 3
  370. )
  371. func (c *CertValidationLevel) MarshalJSON() ([]byte, error) {
  372. if *c == UnknownValidationLevel || *c < 0 || *c > EV {
  373. return json.Marshal("unknown")
  374. }
  375. return json.Marshal(c.String())
  376. }
  377. // TODO: All of validation-level maps should be auto-generated from
  378. // https://github.com/zmap/constants.
  379. // ExtendedValidationOIDs contains the UNION of Chromium
  380. // (https://chromium.googlesource.com/chromium/src/net/+/master/cert/ev_root_ca_metadata.cc)
  381. // and Firefox
  382. // (http://hg.mozilla.org/mozilla-central/file/tip/security/certverifier/ExtendedValidation.cpp)
  383. // EV OID lists
  384. var ExtendedValidationOIDs = map[string]interface{}{
  385. // CA/Browser Forum EV OID standard
  386. // https://cabforum.org/object-registry/
  387. "2.23.140.1.1": nil,
  388. // CA/Browser Forum EV Code Signing
  389. "2.23.140.1.3": nil,
  390. // CA/Browser Forum .onion EV Certs
  391. "2.23.140.1.31": nil,
  392. // AC Camerfirma S.A. Chambers of Commerce Root - 2008
  393. // https://www.camerfirma.com
  394. // AC Camerfirma uses the last two arcs to track how the private key
  395. // is managed - the effective verification policy is the same.
  396. "1.3.6.1.4.1.17326.10.14.2.1.2": nil,
  397. "1.3.6.1.4.1.17326.10.14.2.2.2": nil,
  398. // AC Camerfirma S.A. Global Chambersign Root - 2008
  399. // https://server2.camerfirma.com:8082
  400. // AC Camerfirma uses the last two arcs to track how the private key
  401. // is managed - the effective verification policy is the same.
  402. "1.3.6.1.4.1.17326.10.8.12.1.2": nil,
  403. "1.3.6.1.4.1.17326.10.8.12.2.2": nil,
  404. // Actalis Authentication Root CA
  405. // https://ssltest-a.actalis.it:8443
  406. "1.3.159.1.17.1": nil,
  407. // AffirmTrust Commercial
  408. // https://commercial.affirmtrust.com/
  409. "1.3.6.1.4.1.34697.2.1": nil,
  410. // AffirmTrust Networking
  411. // https://networking.affirmtrust.com:4431
  412. "1.3.6.1.4.1.34697.2.2": nil,
  413. // AffirmTrust Premium
  414. // https://premium.affirmtrust.com:4432/
  415. "1.3.6.1.4.1.34697.2.3": nil,
  416. // AffirmTrust Premium ECC
  417. // https://premiumecc.affirmtrust.com:4433/
  418. "1.3.6.1.4.1.34697.2.4": nil,
  419. // Autoridad de Certificacion Firmaprofesional CIF A62634068
  420. // https://publifirma.firmaprofesional.com/
  421. "1.3.6.1.4.1.13177.10.1.3.10": nil,
  422. // Buypass Class 3 CA 1
  423. // https://valid.evident.ca13.ssl.buypass.no/
  424. "2.16.578.1.26.1.3.3": nil,
  425. // Certification Authority of WoSign
  426. // CA 沃通根证书
  427. // https://root2evtest.wosign.com/
  428. "1.3.6.1.4.1.36305.2": nil,
  429. // CertPlus Class 2 Primary CA (KEYNECTIS)
  430. // https://www.keynectis.com/
  431. "1.3.6.1.4.1.22234.2.5.2.3.1": nil,
  432. // Certum Trusted Network CA
  433. // https://juice.certum.pl/
  434. "1.2.616.1.113527.2.5.1.1": nil,
  435. // China Internet Network Information Center EV Certificates Root
  436. // https://evdemo.cnnic.cn/
  437. "1.3.6.1.4.1.29836.1.10": nil,
  438. // COMODO Certification Authority & USERTrust RSA Certification Authority & UTN-USERFirst-Hardware & AddTrust External CA Root
  439. // https://secure.comodo.com/
  440. // https://usertrustrsacertificationauthority-ev.comodoca.com/
  441. // https://addtrustexternalcaroot-ev.comodoca.com
  442. "1.3.6.1.4.1.6449.1.2.1.5.1": nil,
  443. // Cybertrust Global Root & GTE CyberTrust Global Root & Baltimore CyberTrust Root
  444. // https://evup.cybertrust.ne.jp/ctj-ev-upgrader/evseal.gif
  445. // https://www.cybertrust.ne.jp/
  446. // https://secure.omniroot.com/repository/
  447. "1.3.6.1.4.1.6334.1.100.1": nil,
  448. // DigiCert High Assurance EV Root CA
  449. // https://www.digicert.com
  450. "2.16.840.1.114412.2.1": nil,
  451. // D-TRUST Root Class 3 CA 2 EV 2009
  452. // https://certdemo-ev-valid.ssl.d-trust.net/
  453. "1.3.6.1.4.1.4788.2.202.1": nil,
  454. // Entrust.net Secure Server Certification Authority
  455. // https://www.entrust.net/
  456. "2.16.840.1.114028.10.1.2": nil,
  457. // E-Tugra Certification Authority
  458. // https://sslev.e-tugra.com.tr
  459. "2.16.792.3.0.4.1.1.4": nil,
  460. // GeoTrust Primary Certification Authority
  461. // https://www.geotrust.com/
  462. "1.3.6.1.4.1.14370.1.6": nil,
  463. // GlobalSign Root CA - R2
  464. // https://www.globalsign.com/
  465. "1.3.6.1.4.1.4146.1.1": nil,
  466. // Go Daddy Class 2 Certification Authority & Go Daddy Root Certificate Authority - G2
  467. // https://www.godaddy.com/
  468. // https://valid.gdig2.catest.godaddy.com/
  469. "2.16.840.1.114413.1.7.23.3": nil,
  470. // Izenpe.com - SHA256 root
  471. // The first OID is for businesses and the second for government entities.
  472. // These are the test sites, respectively:
  473. // https://servicios.izenpe.com
  474. // https://servicios1.izenpe.com
  475. // Windows XP finds this, SHA1, root instead. The policy OIDs are the same
  476. // as for the SHA256 root, above.
  477. "1.3.6.1.4.1.14777.6.1.1": nil,
  478. "1.3.6.1.4.1.14777.6.1.2": nil,
  479. // Network Solutions Certificate Authority
  480. // https://www.networksolutions.com/website-packages/index.jsp
  481. "1.3.6.1.4.1.782.1.2.1.8.1": nil,
  482. // QuoVadis Root CA 2
  483. // https://www.quovadis.bm/
  484. "1.3.6.1.4.1.8024.0.2.100.1.2": nil,
  485. // SecureTrust CA, SecureTrust Corporation
  486. // https://www.securetrust.com
  487. // https://www.trustwave.com/
  488. "2.16.840.1.114404.1.1.2.4.1": nil,
  489. // Security Communication RootCA1
  490. // https://www.secomtrust.net/contact/form.html
  491. "1.2.392.200091.100.721.1": nil,
  492. // Staat der Nederlanden EV Root CA
  493. // https://pkioevssl-v.quovadisglobal.com/
  494. "2.16.528.1.1003.1.2.7": nil,
  495. // StartCom Certification Authority
  496. // https://www.startssl.com/
  497. "1.3.6.1.4.1.23223.1.1.1": nil,
  498. // Starfield Class 2 Certification Authority
  499. // https://www.starfieldtech.com/
  500. "2.16.840.1.114414.1.7.23.3": nil,
  501. // Starfield Services Root Certificate Authority - G2
  502. // https://valid.sfsg2.catest.starfieldtech.com/
  503. "2.16.840.1.114414.1.7.24.3": nil,
  504. // SwissSign Gold CA - G2
  505. // https://testevg2.swisssign.net/
  506. "2.16.756.1.89.1.2.1.1": nil,
  507. // Swisscom Root EV CA 2
  508. // https://test-quarz-ev-ca-2.pre.swissdigicert.ch
  509. "2.16.756.1.83.21.0": nil,
  510. // thawte Primary Root CA
  511. // https://www.thawte.com/
  512. "2.16.840.1.113733.1.7.48.1": nil,
  513. // TWCA Global Root CA
  514. // https://evssldemo3.twca.com.tw/index.html
  515. "1.3.6.1.4.1.40869.1.1.22.3": nil,
  516. // T-TeleSec GlobalRoot Class 3
  517. // http://www.telesec.de/ / https://root-class3.test.telesec.de/
  518. "1.3.6.1.4.1.7879.13.24.1": nil,
  519. // VeriSign Class 3 Public Primary Certification Authority - G5
  520. // https://www.verisign.com/
  521. "2.16.840.1.113733.1.7.23.6": nil,
  522. // Wells Fargo WellsSecure Public Root Certificate Authority
  523. // https://nerys.wellsfargo.com/test.html
  524. "2.16.840.1.114171.500.9": nil,
  525. // CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN
  526. // https://www.cfca.com.cn/
  527. "2.16.156.112554.3": nil,
  528. // CN=OISTE WISeKey Global Root GB CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH
  529. // https://www.wisekey.com/repository/cacertificates/
  530. "2.16.756.5.14.7.4.8": nil,
  531. // CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6,O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A...,L=Ankara,C=TR
  532. // https://www.turktrust.com.tr/
  533. "2.16.792.3.0.3.1.1.5": nil,
  534. }
  535. // OrganizationValidationOIDs contains CA specific OV OIDs from
  536. // https://cabforum.org/object-registry/
  537. var OrganizationValidationOIDs = map[string]interface{}{
  538. // CA/Browser Forum OV OID standard
  539. // https://cabforum.org/object-registry/
  540. "2.23.140.1.2.2": nil,
  541. // CA/Browser Forum individually validated
  542. "2.23.140.1.2.3": nil,
  543. // Digicert
  544. "2.16.840.1.114412.1.1": nil,
  545. // D-Trust
  546. "1.3.6.1.4.1.4788.2.200.1": nil,
  547. // GoDaddy
  548. "2.16.840.1.114413.1.7.23.2": nil,
  549. // Logius
  550. "2.16.528.1.1003.1.2.5.6": nil,
  551. // QuoVadis
  552. "1.3.6.1.4.1.8024.0.2.100.1.1": nil,
  553. // Starfield
  554. "2.16.840.1.114414.1.7.23.2": nil,
  555. // TurkTrust
  556. "2.16.792.3.0.3.1.1.2": nil,
  557. }
  558. // DomainValidationOIDs contain OIDs that identify DV certs.
  559. var DomainValidationOIDs = map[string]interface{}{
  560. // Globalsign
  561. "1.3.6.1.4.1.4146.1.10.10": nil,
  562. // Let's Encrypt
  563. "1.3.6.1.4.1.44947.1.1.1": nil,
  564. // Comodo (eNom)
  565. "1.3.6.1.4.1.6449.1.2.2.10": nil,
  566. // Comodo (WoTrust)
  567. "1.3.6.1.4.1.6449.1.2.2.15": nil,
  568. // Comodo (RBC SOFT)
  569. "1.3.6.1.4.1.6449.1.2.2.16": nil,
  570. // Comodo (RegisterFly)
  571. "1.3.6.1.4.1.6449.1.2.2.17": nil,
  572. // Comodo (Central Security Patrols)
  573. "1.3.6.1.4.1.6449.1.2.2.18": nil,
  574. // Comodo (eBiz Networks)
  575. "1.3.6.1.4.1.6449.1.2.2.19": nil,
  576. // Comodo (OptimumSSL)
  577. "1.3.6.1.4.1.6449.1.2.2.21": nil,
  578. // Comodo (WoSign)
  579. "1.3.6.1.4.1.6449.1.2.2.22": nil,
  580. // Comodo (Register.com)
  581. "1.3.6.1.4.1.6449.1.2.2.24": nil,
  582. // Comodo (The Code Project)
  583. "1.3.6.1.4.1.6449.1.2.2.25": nil,
  584. // Comodo (Gandi)
  585. "1.3.6.1.4.1.6449.1.2.2.26": nil,
  586. // Comodo (GlobeSSL)
  587. "1.3.6.1.4.1.6449.1.2.2.27": nil,
  588. // Comodo (DreamHost)
  589. "1.3.6.1.4.1.6449.1.2.2.28": nil,
  590. // Comodo (TERENA)
  591. "1.3.6.1.4.1.6449.1.2.2.29": nil,
  592. // Comodo (GlobalSSL)
  593. "1.3.6.1.4.1.6449.1.2.2.31": nil,
  594. // Comodo (IceWarp)
  595. "1.3.6.1.4.1.6449.1.2.2.35": nil,
  596. // Comodo (Dotname Korea)
  597. "1.3.6.1.4.1.6449.1.2.2.37": nil,
  598. // Comodo (TrustSign)
  599. "1.3.6.1.4.1.6449.1.2.2.38": nil,
  600. // Comodo (Formidable)
  601. "1.3.6.1.4.1.6449.1.2.2.39": nil,
  602. // Comodo (SSL Blindado)
  603. "1.3.6.1.4.1.6449.1.2.2.40": nil,
  604. // Comodo (Dreamscape Networks)
  605. "1.3.6.1.4.1.6449.1.2.2.41": nil,
  606. // Comodo (K Software)
  607. "1.3.6.1.4.1.6449.1.2.2.42": nil,
  608. // Comodo (FBS)
  609. "1.3.6.1.4.1.6449.1.2.2.44": nil,
  610. // Comodo (ReliaSite)
  611. "1.3.6.1.4.1.6449.1.2.2.45": nil,
  612. // Comodo (CertAssure)
  613. "1.3.6.1.4.1.6449.1.2.2.47": nil,
  614. // Comodo (TrustAsia)
  615. "1.3.6.1.4.1.6449.1.2.2.49": nil,
  616. // Comodo (SecureCore)
  617. "1.3.6.1.4.1.6449.1.2.2.50": nil,
  618. // Comodo (Western Digital)
  619. "1.3.6.1.4.1.6449.1.2.2.51": nil,
  620. // Comodo (cPanel)
  621. "1.3.6.1.4.1.6449.1.2.2.52": nil,
  622. // Comodo (BlackCert)
  623. "1.3.6.1.4.1.6449.1.2.2.53": nil,
  624. // Comodo (KeyNet Systems)
  625. "1.3.6.1.4.1.6449.1.2.2.54": nil,
  626. // Comodo
  627. "1.3.6.1.4.1.6449.1.2.2.7": nil,
  628. // Comodo (CSC)
  629. "1.3.6.1.4.1.6449.1.2.2.8": nil,
  630. // Digicert
  631. "2.16.840.1.114412.1.2": nil,
  632. // GoDaddy
  633. "2.16.840.1.114413.1.7.23.1": nil,
  634. // Starfield
  635. "2.16.840.1.114414.1.7.23.1": nil,
  636. // CA/B Forum
  637. "2.23.140.1.2.1": nil,
  638. }
  639. // TODO pull out other types
  640. type AuthorityInfoAccess struct {
  641. OCSPServer []string `json:"ocsp_urls,omitempty"`
  642. IssuingCertificateURL []string `json:"issuer_urls,omitempty"`
  643. }
  644. /*
  645. id-CABFOrganizationIdentifier OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) international-organizations(23) ca-browser-forum(140) certificate-extensions(3) cabf-organization-identifier(1) }
  646. ext-CABFOrganizationIdentifier EXTENSION ::= { SYNTAX CABFOrganizationIdentifier IDENTIFIED BY id-CABFOrganizationIdentifier }
  647. CABFOrganizationIdentifier ::= SEQUENCE {
  648. registrationSchemeIdentifier PrintableString (SIZE(3)),
  649. registrationCountry PrintableString (SIZE(2)),
  650. registrationStateOrProvince [0] IMPLICIT PrintableString OPTIONAL (SIZE(0..128)),
  651. registrationReference UTF8String
  652. }
  653. */
  654. type CABFOrganizationIDASN struct {
  655. RegistrationSchemeIdentifier string `asn1:"printable"`
  656. RegistrationCountry string `asn1:"printable"`
  657. RegistrationStateOrProvince string `asn1:"printable,optional,tag:0"`
  658. RegistrationReference string `asn1:"utf8"`
  659. }
  660. type CABFOrganizationIdentifier struct {
  661. Scheme string `json:"scheme,omitempty"`
  662. Country string `json:"country,omitempty"`
  663. State string `json:"state,omitempty"`
  664. Reference string `json:"reference,omitempty"`
  665. }
  666. func (c *Certificate) jsonifyExtensions() (*CertificateExtensions, UnknownCertificateExtensions) {
  667. exts := new(CertificateExtensions)
  668. unk := make([]pkix.Extension, 0, 2)
  669. for _, e := range c.Extensions {
  670. if e.Id.Equal(oidExtKeyUsage) {
  671. exts.KeyUsage = c.KeyUsage
  672. } else if e.Id.Equal(oidExtBasicConstraints) {
  673. exts.BasicConstraints = new(BasicConstraints)
  674. exts.BasicConstraints.IsCA = c.IsCA
  675. if c.MaxPathLen > 0 || c.MaxPathLenZero {
  676. exts.BasicConstraints.MaxPathLen = new(int)
  677. *exts.BasicConstraints.MaxPathLen = c.MaxPathLen
  678. }
  679. } else if e.Id.Equal(oidExtSubjectAltName) {
  680. exts.SubjectAltName = new(GeneralNames)
  681. exts.SubjectAltName.DirectoryNames = c.DirectoryNames
  682. exts.SubjectAltName.DNSNames = c.DNSNames
  683. exts.SubjectAltName.EDIPartyNames = c.EDIPartyNames
  684. exts.SubjectAltName.EmailAddresses = c.EmailAddresses
  685. exts.SubjectAltName.IPAddresses = c.IPAddresses
  686. exts.SubjectAltName.OtherNames = c.OtherNames
  687. exts.SubjectAltName.RegisteredIDs = c.RegisteredIDs
  688. exts.SubjectAltName.URIs = c.URIs
  689. } else if e.Id.Equal(oidExtIssuerAltName) {
  690. exts.IssuerAltName = new(GeneralNames)
  691. exts.IssuerAltName.DirectoryNames = c.IANDirectoryNames
  692. exts.IssuerAltName.DNSNames = c.IANDNSNames
  693. exts.IssuerAltName.EDIPartyNames = c.IANEDIPartyNames
  694. exts.IssuerAltName.EmailAddresses = c.IANEmailAddresses
  695. exts.IssuerAltName.IPAddresses = c.IANIPAddresses
  696. exts.IssuerAltName.OtherNames = c.IANOtherNames
  697. exts.IssuerAltName.RegisteredIDs = c.IANRegisteredIDs
  698. exts.IssuerAltName.URIs = c.IANURIs
  699. } else if e.Id.Equal(oidExtNameConstraints) {
  700. exts.NameConstraints = new(NameConstraints)
  701. exts.NameConstraints.Critical = c.NameConstraintsCritical
  702. exts.NameConstraints.PermittedDNSNames = c.PermittedDNSNames
  703. exts.NameConstraints.PermittedEmailAddresses = c.PermittedEmailAddresses
  704. exts.NameConstraints.PermittedURIs = c.PermittedURIs
  705. exts.NameConstraints.PermittedIPAddresses = c.PermittedIPAddresses
  706. exts.NameConstraints.PermittedDirectoryNames = c.PermittedDirectoryNames
  707. exts.NameConstraints.PermittedEdiPartyNames = c.PermittedEdiPartyNames
  708. exts.NameConstraints.PermittedRegisteredIDs = c.PermittedRegisteredIDs
  709. exts.NameConstraints.ExcludedEmailAddresses = c.ExcludedEmailAddresses
  710. exts.NameConstraints.ExcludedDNSNames = c.ExcludedDNSNames
  711. exts.NameConstraints.ExcludedURIs = c.ExcludedURIs
  712. exts.NameConstraints.ExcludedIPAddresses = c.ExcludedIPAddresses
  713. exts.NameConstraints.ExcludedDirectoryNames = c.ExcludedDirectoryNames
  714. exts.NameConstraints.ExcludedEdiPartyNames = c.ExcludedEdiPartyNames
  715. exts.NameConstraints.ExcludedRegisteredIDs = c.ExcludedRegisteredIDs
  716. } else if e.Id.Equal(oidCRLDistributionPoints) {
  717. exts.CRLDistributionPoints = c.CRLDistributionPoints
  718. } else if e.Id.Equal(oidExtAuthKeyId) {
  719. exts.AuthKeyID = c.AuthorityKeyId
  720. } else if e.Id.Equal(oidExtExtendedKeyUsage) {
  721. exts.ExtendedKeyUsage = new(ExtendedKeyUsageExtension)
  722. exts.ExtendedKeyUsage.Known = c.ExtKeyUsage
  723. exts.ExtendedKeyUsage.Unknown = c.UnknownExtKeyUsage
  724. } else if e.Id.Equal(oidExtCertificatePolicy) {
  725. exts.CertificatePolicies = new(CertificatePoliciesData)
  726. exts.CertificatePolicies.PolicyIdentifiers = c.PolicyIdentifiers
  727. exts.CertificatePolicies.NoticeRefNumbers = c.NoticeRefNumbers
  728. exts.CertificatePolicies.NoticeRefOrganization = c.ParsedNoticeRefOrganization
  729. exts.CertificatePolicies.ExplicitTexts = c.ParsedExplicitTexts
  730. exts.CertificatePolicies.QualifierId = c.QualifierId
  731. exts.CertificatePolicies.CPSUri = c.CPSuri
  732. } else if e.Id.Equal(oidExtAuthorityInfoAccess) {
  733. exts.AuthorityInfoAccess = new(AuthorityInfoAccess)
  734. exts.AuthorityInfoAccess.OCSPServer = c.OCSPServer
  735. exts.AuthorityInfoAccess.IssuingCertificateURL = c.IssuingCertificateURL
  736. } else if e.Id.Equal(oidExtSubjectKeyId) {
  737. exts.SubjectKeyID = c.SubjectKeyId
  738. } else if e.Id.Equal(oidExtSignedCertificateTimestampList) {
  739. exts.SignedCertificateTimestampList = c.SignedCertificateTimestampList
  740. } else if e.Id.Equal(oidExtensionCTPrecertificatePoison) {
  741. exts.IsPrecert = true
  742. } else if e.Id.Equal(oidBRTorServiceDescriptor) {
  743. exts.TorServiceDescriptors = c.TorServiceDescriptors
  744. } else if e.Id.Equal(oidExtCABFOrganizationID) {
  745. exts.CABFOrganizationIdentifier = c.CABFOrganizationIdentifier
  746. } else if e.Id.Equal(oidExtQCStatements) {
  747. exts.QCStatements = c.QCStatements
  748. } else {
  749. // Unknown extension
  750. unk = append(unk, e)
  751. }
  752. }
  753. return exts, unk
  754. }