json.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  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. "crypto/ecdsa"
  7. "crypto/rsa"
  8. "encoding/json"
  9. "errors"
  10. "net"
  11. "sort"
  12. "strings"
  13. "time"
  14. "github.com/zmap/zcrypto/dsa"
  15. "github.com/zmap/zcrypto/encoding/asn1"
  16. jsonKeys "github.com/zmap/zcrypto/json"
  17. "github.com/zmap/zcrypto/util"
  18. "github.com/zmap/zcrypto/x509/pkix"
  19. )
  20. var kMinTime, kMaxTime time.Time
  21. func init() {
  22. var err error
  23. kMinTime, err = time.Parse(time.RFC3339, "0001-01-01T00:00:00Z")
  24. if err != nil {
  25. panic(err)
  26. }
  27. kMaxTime, err = time.Parse(time.RFC3339, "9999-12-31T23:59:59Z")
  28. if err != nil {
  29. panic(err)
  30. }
  31. }
  32. type auxKeyUsage struct {
  33. DigitalSignature bool `json:"digital_signature,omitempty"`
  34. ContentCommitment bool `json:"content_commitment,omitempty"`
  35. KeyEncipherment bool `json:"key_encipherment,omitempty"`
  36. DataEncipherment bool `json:"data_encipherment,omitempty"`
  37. KeyAgreement bool `json:"key_agreement,omitempty"`
  38. CertificateSign bool `json:"certificate_sign,omitempty"`
  39. CRLSign bool `json:"crl_sign,omitempty"`
  40. EncipherOnly bool `json:"encipher_only,omitempty"`
  41. DecipherOnly bool `json:"decipher_only,omitempty"`
  42. Value uint32 `json:"value"`
  43. }
  44. // MarshalJSON implements the json.Marshaler interface
  45. func (k KeyUsage) MarshalJSON() ([]byte, error) {
  46. var enc auxKeyUsage
  47. enc.Value = uint32(k)
  48. if k&KeyUsageDigitalSignature > 0 {
  49. enc.DigitalSignature = true
  50. }
  51. if k&KeyUsageContentCommitment > 0 {
  52. enc.ContentCommitment = true
  53. }
  54. if k&KeyUsageKeyEncipherment > 0 {
  55. enc.KeyEncipherment = true
  56. }
  57. if k&KeyUsageDataEncipherment > 0 {
  58. enc.DataEncipherment = true
  59. }
  60. if k&KeyUsageKeyAgreement > 0 {
  61. enc.KeyAgreement = true
  62. }
  63. if k&KeyUsageCertSign > 0 {
  64. enc.CertificateSign = true
  65. }
  66. if k&KeyUsageCRLSign > 0 {
  67. enc.CRLSign = true
  68. }
  69. if k&KeyUsageEncipherOnly > 0 {
  70. enc.EncipherOnly = true
  71. }
  72. if k&KeyUsageDecipherOnly > 0 {
  73. enc.DecipherOnly = true
  74. }
  75. return json.Marshal(&enc)
  76. }
  77. // UnmarshalJSON implements the json.Unmarshler interface
  78. func (k *KeyUsage) UnmarshalJSON(b []byte) error {
  79. var aux auxKeyUsage
  80. if err := json.Unmarshal(b, &aux); err != nil {
  81. return err
  82. }
  83. // TODO: validate the flags match
  84. v := int(aux.Value)
  85. *k = KeyUsage(v)
  86. return nil
  87. }
  88. // JSONSignatureAlgorithm is the intermediate type
  89. // used when marshaling a PublicKeyAlgorithm out to JSON.
  90. type JSONSignatureAlgorithm struct {
  91. Name string `json:"name,omitempty"`
  92. OID pkix.AuxOID `json:"oid"`
  93. }
  94. // MarshalJSON implements the json.Marshaler interface
  95. // MAY NOT PRESERVE ORIGINAL OID FROM CERTIFICATE -
  96. // CONSIDER USING jsonifySignatureAlgorithm INSTEAD!
  97. func (s *SignatureAlgorithm) MarshalJSON() ([]byte, error) {
  98. aux := JSONSignatureAlgorithm{
  99. Name: s.String(),
  100. }
  101. for _, val := range signatureAlgorithmDetails {
  102. if val.algo == *s {
  103. aux.OID = make([]int, len(val.oid))
  104. for idx := range val.oid {
  105. aux.OID[idx] = val.oid[idx]
  106. }
  107. }
  108. }
  109. return json.Marshal(&aux)
  110. }
  111. // UnmarshalJSON implements the json.Unmarshler interface
  112. func (s *SignatureAlgorithm) UnmarshalJSON(b []byte) error {
  113. var aux JSONSignatureAlgorithm
  114. if err := json.Unmarshal(b, &aux); err != nil {
  115. return err
  116. }
  117. *s = UnknownSignatureAlgorithm
  118. oid := asn1.ObjectIdentifier(aux.OID.AsSlice())
  119. if oid.Equal(oidSignatureRSAPSS) {
  120. pssAlgs := []SignatureAlgorithm{SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS}
  121. for _, alg := range pssAlgs {
  122. if strings.Compare(alg.String(), aux.Name) == 0 {
  123. *s = alg
  124. break
  125. }
  126. }
  127. } else {
  128. for _, val := range signatureAlgorithmDetails {
  129. if val.oid.Equal(oid) {
  130. *s = val.algo
  131. break
  132. }
  133. }
  134. }
  135. return nil
  136. }
  137. // jsonifySignatureAlgorithm gathers the necessary fields in a Certificate
  138. // into a JSONSignatureAlgorithm, which can then use the default
  139. // JSON marhsalers and unmarshalers. THIS FUNCTION IS PREFERED OVER
  140. // THE CUSTOM JSON MARSHALER PRESENTED ABOVE FOR SIGNATUREALGORITHM
  141. // BECAUSE THIS METHOD PRESERVES THE OID ORIGINALLY IN THE CERTIFICATE!
  142. // This reason also explains why we need this function -
  143. // the OID is unfortunately stored outside the scope of a
  144. // SignatureAlgorithm struct and cannot be recovered without access to the
  145. // entire Certificate if we do not know the signature algorithm.
  146. func (c *Certificate) jsonifySignatureAlgorithm() JSONSignatureAlgorithm {
  147. aux := JSONSignatureAlgorithm{}
  148. if c.SignatureAlgorithm == 0 {
  149. aux.Name = "unknown_algorithm"
  150. } else {
  151. aux.Name = c.SignatureAlgorithm.String()
  152. }
  153. aux.OID = make([]int, len(c.SignatureAlgorithmOID))
  154. for idx := range c.SignatureAlgorithmOID {
  155. aux.OID[idx] = c.SignatureAlgorithmOID[idx]
  156. }
  157. return aux
  158. }
  159. type auxPublicKeyAlgorithm struct {
  160. Name string `json:"name,omitempty"`
  161. OID *pkix.AuxOID `json:"oid,omitempty"`
  162. }
  163. var publicKeyNameToAlgorithm = map[string]PublicKeyAlgorithm{
  164. "RSA": RSA,
  165. "DSA": DSA,
  166. "ECDSA": ECDSA,
  167. }
  168. // MarshalJSON implements the json.Marshaler interface
  169. func (p *PublicKeyAlgorithm) MarshalJSON() ([]byte, error) {
  170. aux := auxPublicKeyAlgorithm{
  171. Name: p.String(),
  172. }
  173. return json.Marshal(&aux)
  174. }
  175. // UnmarshalJSON implements the json.Unmarshaler interface
  176. func (p *PublicKeyAlgorithm) UnmarshalJSON(b []byte) error {
  177. var aux auxPublicKeyAlgorithm
  178. if err := json.Unmarshal(b, &aux); err != nil {
  179. return err
  180. }
  181. *p = publicKeyNameToAlgorithm[aux.Name]
  182. return nil
  183. }
  184. func clampTime(t time.Time) time.Time {
  185. if t.Before(kMinTime) {
  186. return kMinTime
  187. }
  188. if t.After(kMaxTime) {
  189. return kMaxTime
  190. }
  191. return t
  192. }
  193. type auxValidity struct {
  194. Start string `json:"start"`
  195. End string `json:"end"`
  196. ValidityPeriod int `json:"length"`
  197. }
  198. func (v *validity) MarshalJSON() ([]byte, error) {
  199. aux := auxValidity{
  200. Start: clampTime(v.NotBefore.UTC()).Format(time.RFC3339),
  201. End: clampTime(v.NotAfter.UTC()).Format(time.RFC3339),
  202. ValidityPeriod: int(v.NotAfter.Unix() - v.NotBefore.Unix()),
  203. }
  204. return json.Marshal(&aux)
  205. }
  206. func (v *validity) UnmarshalJSON(b []byte) error {
  207. var aux auxValidity
  208. if err := json.Unmarshal(b, &aux); err != nil {
  209. return err
  210. }
  211. var err error
  212. if v.NotBefore, err = time.Parse(time.RFC3339, aux.Start); err != nil {
  213. return err
  214. }
  215. if v.NotAfter, err = time.Parse(time.RFC3339, aux.End); err != nil {
  216. return err
  217. }
  218. return nil
  219. }
  220. // ECDSAPublicKeyJSON - used to condense several fields from a
  221. // ECDSA public key into one field for use in JSONCertificate.
  222. // Uses default JSON marshal and unmarshal methods
  223. type ECDSAPublicKeyJSON struct {
  224. B []byte `json:"b"`
  225. Curve string `json:"curve"`
  226. Gx []byte `json:"gx"`
  227. Gy []byte `json:"gy"`
  228. Length int `json:"length"`
  229. N []byte `json:"n"`
  230. P []byte `json:"p"`
  231. Pub []byte `json:"pub,omitempty"`
  232. X []byte `json:"x"`
  233. Y []byte `json:"y"`
  234. }
  235. // DSAPublicKeyJSON - used to condense several fields from a
  236. // DSA public key into one field for use in JSONCertificate.
  237. // Uses default JSON marshal and unmarshal methods
  238. type DSAPublicKeyJSON struct {
  239. G []byte `json:"g"`
  240. P []byte `json:"p"`
  241. Q []byte `json:"q"`
  242. Y []byte `json:"y"`
  243. }
  244. // GetDSAPublicKeyJSON - get the DSAPublicKeyJSON for the given standard DSA PublicKey.
  245. func GetDSAPublicKeyJSON(key *dsa.PublicKey) *DSAPublicKeyJSON {
  246. return &DSAPublicKeyJSON{
  247. P: key.P.Bytes(),
  248. Q: key.Q.Bytes(),
  249. G: key.G.Bytes(),
  250. Y: key.Y.Bytes(),
  251. }
  252. }
  253. // GetRSAPublicKeyJSON - get the jsonKeys.RSAPublicKey for the given standard RSA PublicKey.
  254. func GetRSAPublicKeyJSON(key *rsa.PublicKey) *jsonKeys.RSAPublicKey {
  255. rsaKey := new(jsonKeys.RSAPublicKey)
  256. rsaKey.PublicKey = key
  257. return rsaKey
  258. }
  259. // GetECDSAPublicKeyJSON - get the GetECDSAPublicKeyJSON for the given standard ECDSA PublicKey.
  260. func GetECDSAPublicKeyJSON(key *ecdsa.PublicKey) *ECDSAPublicKeyJSON {
  261. params := key.Params()
  262. return &ECDSAPublicKeyJSON{
  263. P: params.P.Bytes(),
  264. N: params.N.Bytes(),
  265. B: params.B.Bytes(),
  266. Gx: params.Gx.Bytes(),
  267. Gy: params.Gy.Bytes(),
  268. X: key.X.Bytes(),
  269. Y: key.Y.Bytes(),
  270. Curve: key.Curve.Params().Name,
  271. Length: key.Curve.Params().BitSize,
  272. }
  273. }
  274. // GetAugmentedECDSAPublicKeyJSON - get the GetECDSAPublicKeyJSON for the given "augmented"
  275. // ECDSA PublicKey.
  276. func GetAugmentedECDSAPublicKeyJSON(key *AugmentedECDSA) *ECDSAPublicKeyJSON {
  277. params := key.Pub.Params()
  278. return &ECDSAPublicKeyJSON{
  279. P: params.P.Bytes(),
  280. N: params.N.Bytes(),
  281. B: params.B.Bytes(),
  282. Gx: params.Gx.Bytes(),
  283. Gy: params.Gy.Bytes(),
  284. X: key.Pub.X.Bytes(),
  285. Y: key.Pub.Y.Bytes(),
  286. Curve: key.Pub.Curve.Params().Name,
  287. Length: key.Pub.Curve.Params().BitSize,
  288. Pub: key.Raw.Bytes,
  289. }
  290. }
  291. // jsonifySubjectKey - Convert public key data in a Certificate
  292. // into json output format for JSONCertificate
  293. func (c *Certificate) jsonifySubjectKey() JSONSubjectKeyInfo {
  294. j := JSONSubjectKeyInfo{
  295. KeyAlgorithm: c.PublicKeyAlgorithm,
  296. SPKIFingerprint: c.SPKIFingerprint,
  297. }
  298. switch key := c.PublicKey.(type) {
  299. case *rsa.PublicKey:
  300. rsaKey := new(jsonKeys.RSAPublicKey)
  301. rsaKey.PublicKey = key
  302. j.RSAPublicKey = rsaKey
  303. case *dsa.PublicKey:
  304. j.DSAPublicKey = &DSAPublicKeyJSON{
  305. P: key.P.Bytes(),
  306. Q: key.Q.Bytes(),
  307. G: key.G.Bytes(),
  308. Y: key.Y.Bytes(),
  309. }
  310. case *ecdsa.PublicKey:
  311. params := key.Params()
  312. j.ECDSAPublicKey = &ECDSAPublicKeyJSON{
  313. P: params.P.Bytes(),
  314. N: params.N.Bytes(),
  315. B: params.B.Bytes(),
  316. Gx: params.Gx.Bytes(),
  317. Gy: params.Gy.Bytes(),
  318. X: key.X.Bytes(),
  319. Y: key.Y.Bytes(),
  320. Curve: key.Curve.Params().Name,
  321. Length: key.Curve.Params().BitSize,
  322. }
  323. case *AugmentedECDSA:
  324. params := key.Pub.Params()
  325. j.ECDSAPublicKey = &ECDSAPublicKeyJSON{
  326. P: params.P.Bytes(),
  327. N: params.N.Bytes(),
  328. B: params.B.Bytes(),
  329. Gx: params.Gx.Bytes(),
  330. Gy: params.Gy.Bytes(),
  331. X: key.Pub.X.Bytes(),
  332. Y: key.Pub.Y.Bytes(),
  333. Curve: key.Pub.Curve.Params().Name,
  334. Length: key.Pub.Curve.Params().BitSize,
  335. Pub: key.Raw.Bytes,
  336. }
  337. }
  338. return j
  339. }
  340. // JSONSubjectKeyInfo - used to condense several fields from x509.Certificate
  341. // related to the subject public key into one field within JSONCertificate
  342. // Unfortunately, this struct cannot have its own Marshal method since it
  343. // needs information from multiple fields in x509.Certificate
  344. type JSONSubjectKeyInfo struct {
  345. KeyAlgorithm PublicKeyAlgorithm `json:"key_algorithm"`
  346. RSAPublicKey *jsonKeys.RSAPublicKey `json:"rsa_public_key,omitempty"`
  347. DSAPublicKey *DSAPublicKeyJSON `json:"dsa_public_key,omitempty"`
  348. ECDSAPublicKey *ECDSAPublicKeyJSON `json:"ecdsa_public_key,omitempty"`
  349. SPKIFingerprint CertificateFingerprint `json:"fingerprint_sha256"`
  350. }
  351. // JSONSignature - used to condense several fields from x509.Certificate
  352. // related to the signature into one field within JSONCertificate
  353. // Unfortunately, this struct cannot have its own Marshal method since it
  354. // needs information from multiple fields in x509.Certificate
  355. type JSONSignature struct {
  356. SignatureAlgorithm JSONSignatureAlgorithm `json:"signature_algorithm"`
  357. Value []byte `json:"value"`
  358. Valid bool `json:"valid"`
  359. SelfSigned bool `json:"self_signed"`
  360. }
  361. // JSONValidity - used to condense several fields related
  362. // to validity in x509.Certificate into one field within JSONCertificate
  363. // Unfortunately, this struct cannot have its own Marshal method since it
  364. // needs information from multiple fields in x509.Certificate
  365. type JSONValidity struct {
  366. validity
  367. ValidityPeriod int
  368. }
  369. // JSONCertificate - used to condense data from x509.Certificate when marhsaling
  370. // into JSON. This struct has a distinct and independent layout from
  371. // x509.Certificate, mostly for condensing data across repetitive
  372. // fields and making it more presentable.
  373. type JSONCertificate struct {
  374. Version int `json:"version"`
  375. SerialNumber string `json:"serial_number"`
  376. SignatureAlgorithm JSONSignatureAlgorithm `json:"signature_algorithm"`
  377. Issuer pkix.Name `json:"issuer"`
  378. IssuerDN string `json:"issuer_dn,omitempty"`
  379. Validity JSONValidity `json:"validity"`
  380. Subject pkix.Name `json:"subject"`
  381. SubjectDN string `json:"subject_dn,omitempty"`
  382. SubjectKeyInfo JSONSubjectKeyInfo `json:"subject_key_info"`
  383. Extensions *CertificateExtensions `json:"extensions,omitempty"`
  384. UnknownExtensions UnknownCertificateExtensions `json:"unknown_extensions,omitempty"`
  385. Signature JSONSignature `json:"signature"`
  386. FingerprintMD5 CertificateFingerprint `json:"fingerprint_md5"`
  387. FingerprintSHA1 CertificateFingerprint `json:"fingerprint_sha1"`
  388. FingerprintSHA256 CertificateFingerprint `json:"fingerprint_sha256"`
  389. FingerprintNoCT CertificateFingerprint `json:"tbs_noct_fingerprint"`
  390. SPKISubjectFingerprint CertificateFingerprint `json:"spki_subject_fingerprint"`
  391. TBSCertificateFingerprint CertificateFingerprint `json:"tbs_fingerprint"`
  392. ValidationLevel CertValidationLevel `json:"validation_level"`
  393. Names []string `json:"names,omitempty"`
  394. Redacted bool `json:"redacted"`
  395. }
  396. // CollectAllNames - Collect and validate all DNS / URI / IP Address names for a given certificate
  397. func (c *Certificate) CollectAllNames() []string {
  398. var names []string
  399. if isValidName(c.Subject.CommonName) {
  400. names = append(names, c.Subject.CommonName)
  401. }
  402. for _, name := range c.DNSNames {
  403. if isValidName(name) {
  404. names = append(names, name)
  405. } else if !strings.Contains(name, ".") { //just a TLD
  406. names = append(names, name)
  407. }
  408. }
  409. for _, name := range c.URIs {
  410. if util.IsURL(name) {
  411. names = append(names, name)
  412. }
  413. }
  414. for _, name := range c.IPAddresses {
  415. str := name.String()
  416. if util.IsURL(str) {
  417. names = append(names, str)
  418. }
  419. }
  420. return purgeNameDuplicates(names)
  421. }
  422. func (c *Certificate) MarshalJSON() ([]byte, error) {
  423. // Fill out the certificate
  424. jc := new(JSONCertificate)
  425. jc.Version = c.Version
  426. jc.SerialNumber = c.SerialNumber.String()
  427. jc.Issuer = c.Issuer
  428. jc.IssuerDN = c.Issuer.String()
  429. jc.Validity.NotBefore = c.NotBefore
  430. jc.Validity.NotAfter = c.NotAfter
  431. jc.Validity.ValidityPeriod = c.ValidityPeriod
  432. jc.Subject = c.Subject
  433. jc.SubjectDN = c.Subject.String()
  434. jc.Names = c.CollectAllNames()
  435. jc.Redacted = false
  436. for _, name := range jc.Names {
  437. if strings.HasPrefix(name, "?") {
  438. jc.Redacted = true
  439. }
  440. }
  441. jc.SubjectKeyInfo = c.jsonifySubjectKey()
  442. jc.Extensions, jc.UnknownExtensions = c.jsonifyExtensions()
  443. // TODO: Handle the fact this might not match
  444. jc.SignatureAlgorithm = c.jsonifySignatureAlgorithm()
  445. jc.Signature.SignatureAlgorithm = jc.SignatureAlgorithm
  446. jc.Signature.Value = c.Signature
  447. jc.Signature.Valid = c.validSignature
  448. jc.Signature.SelfSigned = c.SelfSigned
  449. if c.SelfSigned {
  450. jc.Signature.Valid = true
  451. }
  452. jc.FingerprintMD5 = c.FingerprintMD5
  453. jc.FingerprintSHA1 = c.FingerprintSHA1
  454. jc.FingerprintSHA256 = c.FingerprintSHA256
  455. jc.FingerprintNoCT = c.FingerprintNoCT
  456. jc.SPKISubjectFingerprint = c.SPKISubjectFingerprint
  457. jc.TBSCertificateFingerprint = c.TBSCertificateFingerprint
  458. jc.ValidationLevel = c.ValidationLevel
  459. return json.Marshal(jc)
  460. }
  461. // UnmarshalJSON - intentionally implimented to always error,
  462. // as this method should not be used. The MarshalJSON method
  463. // on Certificate condenses data in a way that is not recoverable.
  464. // Use the x509.ParseCertificate function instead or
  465. // JSONCertificateWithRaw Marshal method
  466. func (jc *JSONCertificate) UnmarshalJSON(b []byte) error {
  467. return errors.New("Do not unmarshal cert JSON directly, use JSONCertificateWithRaw or x509.ParseCertificate function")
  468. }
  469. // UnmarshalJSON - intentionally implimented to always error,
  470. // as this method should not be used. The MarshalJSON method
  471. // on Certificate condenses data in a way that is not recoverable.
  472. // Use the x509.ParseCertificate function instead or
  473. // JSONCertificateWithRaw Marshal method
  474. func (c *Certificate) UnmarshalJSON(b []byte) error {
  475. return errors.New("Do not unmarshal cert JSON directly, use JSONCertificateWithRaw or x509.ParseCertificate function")
  476. }
  477. // JSONCertificateWithRaw - intermediate struct for unmarshaling json
  478. // of a certificate - the raw is require since the
  479. // MarshalJSON method on Certificate condenses data in a way that
  480. // makes extraction to the original in Unmarshal impossible.
  481. // The JSON output of Marshal is not even used to construct
  482. // a certificate, all we need is raw
  483. type JSONCertificateWithRaw struct {
  484. Raw []byte `json:"raw,omitempty"`
  485. }
  486. // ParseRaw - for converting the intermediate object
  487. // JSONCertificateWithRaw into a parsed Certificate
  488. // see description of JSONCertificateWithRaw for
  489. // why this is used instead of UnmarshalJSON methods
  490. func (c *JSONCertificateWithRaw) ParseRaw() (*Certificate, error) {
  491. return ParseCertificate(c.Raw)
  492. }
  493. func purgeNameDuplicates(names []string) (out []string) {
  494. hashset := make(map[string]bool, len(names))
  495. for _, name := range names {
  496. if _, inc := hashset[name]; !inc {
  497. hashset[name] = true
  498. }
  499. }
  500. out = make([]string, 0, len(hashset))
  501. for key := range hashset {
  502. out = append(out, key)
  503. }
  504. sort.Strings(out) // must sort to ensure output is deterministic!
  505. return
  506. }
  507. func isValidName(name string) (ret bool) {
  508. // Check for wildcards and redacts, ignore malformed urls
  509. if strings.HasPrefix(name, "?.") || strings.HasPrefix(name, "*.") {
  510. ret = isValidName(name[2:])
  511. } else {
  512. ret = util.IsURL(name)
  513. }
  514. return
  515. }
  516. func orMask(ip net.IP, mask net.IPMask) net.IP {
  517. if len(ip) == 0 || len(mask) == 0 {
  518. return nil
  519. }
  520. if len(ip) != net.IPv4len && len(ip) != net.IPv6len {
  521. return nil
  522. }
  523. if len(ip) != len(mask) {
  524. return nil
  525. }
  526. out := make([]byte, len(ip))
  527. for idx := range ip {
  528. out[idx] = ip[idx] | mask[idx]
  529. }
  530. return out
  531. }
  532. func invertMask(mask net.IPMask) net.IPMask {
  533. if mask == nil {
  534. return nil
  535. }
  536. out := make([]byte, len(mask))
  537. for idx := range mask {
  538. out[idx] = ^mask[idx]
  539. }
  540. return out
  541. }
  542. type auxGeneralSubtreeIP struct {
  543. CIDR string `json:"cidr,omitempty"`
  544. Begin string `json:"begin,omitempty"`
  545. End string `json:"end,omitempty"`
  546. Mask string `json:"mask,omitempty"`
  547. }
  548. func (g *GeneralSubtreeIP) MarshalJSON() ([]byte, error) {
  549. aux := auxGeneralSubtreeIP{}
  550. aux.CIDR = g.Data.String()
  551. // Check to see if the subnet is valid. An invalid subnet will return 0,0
  552. // from Size(). If the subnet is invalid, only output the CIDR.
  553. ones, bits := g.Data.Mask.Size()
  554. if ones == 0 && bits == 0 {
  555. return json.Marshal(&aux)
  556. }
  557. // The first IP in the range should be `ip & mask`.
  558. begin := g.Data.IP.Mask(g.Data.Mask)
  559. if begin != nil {
  560. aux.Begin = begin.String()
  561. }
  562. // The last IP (inclusive) is `ip & (^mask)`.
  563. inverseMask := invertMask(g.Data.Mask)
  564. end := orMask(g.Data.IP, inverseMask)
  565. if end != nil {
  566. aux.End = end.String()
  567. }
  568. // Output the mask as an IP, but enforce it can be formatted correctly.
  569. // net.IP.String() only works on byte arrays of the correct length.
  570. maskLen := len(g.Data.Mask)
  571. if maskLen == net.IPv4len || maskLen == net.IPv6len {
  572. maskAsIP := net.IP(g.Data.Mask)
  573. aux.Mask = maskAsIP.String()
  574. }
  575. return json.Marshal(&aux)
  576. }
  577. func (g *GeneralSubtreeIP) UnmarshalJSON(b []byte) error {
  578. aux := auxGeneralSubtreeIP{}
  579. if err := json.Unmarshal(b, &aux); err != nil {
  580. return err
  581. }
  582. ip, ipNet, err := net.ParseCIDR(aux.CIDR)
  583. if err != nil {
  584. return err
  585. }
  586. g.Data.IP = ip
  587. g.Data.Mask = ipNet.Mask
  588. g.Min = 0
  589. g.Max = 0
  590. return nil
  591. }