extensions.go 28 KB

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