Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

733 Zeilen
21 KiB

  1. // Copyright (c) 2016, Google Inc.
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. package main
  15. import (
  16. "bufio"
  17. "bytes"
  18. "errors"
  19. "fmt"
  20. "io/ioutil"
  21. "os"
  22. "os/exec"
  23. "sort"
  24. "strconv"
  25. "strings"
  26. )
  27. func sanitizeName(in string) string {
  28. in = strings.Replace(in, "-", "_", -1)
  29. in = strings.Replace(in, ".", "_", -1)
  30. in = strings.Replace(in, " ", "_", -1)
  31. return in
  32. }
  33. type object struct {
  34. name string
  35. // shortName and longName are the short and long names, respectively. If
  36. // one is missing, it takes the value of the other, but the
  37. // corresponding SN_foo or LN_foo macro is not defined.
  38. shortName, longName string
  39. hasShortName, hasLongName bool
  40. oid []int
  41. encoded []byte
  42. }
  43. type objects struct {
  44. // byNID is the list of all objects, indexed by nid.
  45. byNID []object
  46. // nameToNID is a map from object name to nid.
  47. nameToNID map[string]int
  48. }
  49. func readNumbers(path string) (nameToNID map[string]int, numNIDs int, err error) {
  50. in, err := os.Open(path)
  51. if err != nil {
  52. return nil, 0, err
  53. }
  54. defer in.Close()
  55. nameToNID = make(map[string]int)
  56. nidsSeen := make(map[int]struct{})
  57. // Reserve NID 0 for NID_undef.
  58. numNIDs = 1
  59. nameToNID["undef"] = 0
  60. nidsSeen[0] = struct{}{}
  61. var lineNo int
  62. scanner := bufio.NewScanner(in)
  63. for scanner.Scan() {
  64. line := scanner.Text()
  65. lineNo++
  66. withLine := func(err error) error {
  67. return fmt.Errorf("%s:%d: %s", path, lineNo, err)
  68. }
  69. fields := strings.Fields(line)
  70. if len(fields) == 0 {
  71. // Skip blank lines.
  72. continue
  73. }
  74. // Each line is a name and a nid, separated by space.
  75. if len(fields) != 2 {
  76. return nil, 0, withLine(errors.New("syntax error"))
  77. }
  78. name := fields[0]
  79. nid, err := strconv.Atoi(fields[1])
  80. if err != nil {
  81. return nil, 0, withLine(err)
  82. }
  83. if nid < 0 {
  84. return nil, 0, withLine(errors.New("invalid NID"))
  85. }
  86. // NID_undef is implicitly defined.
  87. if name == "undef" && nid == 0 {
  88. continue
  89. }
  90. // Forbid duplicates.
  91. if _, ok := nameToNID[name]; ok {
  92. return nil, 0, withLine(fmt.Errorf("duplicate name %q", name))
  93. }
  94. if _, ok := nidsSeen[nid]; ok {
  95. return nil, 0, withLine(fmt.Errorf("duplicate NID %d", nid))
  96. }
  97. nameToNID[name] = nid
  98. nidsSeen[nid] = struct{}{}
  99. if nid >= numNIDs {
  100. numNIDs = nid + 1
  101. }
  102. }
  103. if err := scanner.Err(); err != nil {
  104. return nil, 0, fmt.Errorf("error reading %s: %s", path, err)
  105. }
  106. return nameToNID, numNIDs, nil
  107. }
  108. func parseOID(aliases map[string][]int, in []string) (oid []int, err error) {
  109. if len(in) == 0 {
  110. return
  111. }
  112. // The first entry may be a reference to a previous alias.
  113. if alias, ok := aliases[sanitizeName(in[0])]; ok {
  114. in = in[1:]
  115. oid = append(oid, alias...)
  116. }
  117. for _, c := range in {
  118. val, err := strconv.Atoi(c)
  119. if err != nil {
  120. return nil, err
  121. }
  122. if val < 0 {
  123. return nil, fmt.Errorf("negative component")
  124. }
  125. oid = append(oid, val)
  126. }
  127. return
  128. }
  129. func appendBase128(dst []byte, value int) []byte {
  130. // Zero is encoded with one, not zero bytes.
  131. if value == 0 {
  132. return append(dst, 0)
  133. }
  134. // Count how many bytes are needed.
  135. var l int
  136. for n := value; n != 0; n >>= 7 {
  137. l++
  138. }
  139. for ; l > 0; l-- {
  140. b := byte(value>>uint(7*(l-1))) & 0x7f
  141. if l > 1 {
  142. b |= 0x80
  143. }
  144. dst = append(dst, b)
  145. }
  146. return dst
  147. }
  148. func encodeOID(oid []int) []byte {
  149. if len(oid) < 2 {
  150. return nil
  151. }
  152. var der []byte
  153. der = appendBase128(der, 40*oid[0]+oid[1])
  154. for _, value := range oid[2:] {
  155. der = appendBase128(der, value)
  156. }
  157. return der
  158. }
  159. func readObjects(numPath, objectsPath string) (*objects, error) {
  160. nameToNID, numNIDs, err := readNumbers(numPath)
  161. if err != nil {
  162. return nil, err
  163. }
  164. in, err := os.Open(objectsPath)
  165. if err != nil {
  166. return nil, err
  167. }
  168. defer in.Close()
  169. // Implicitly define NID_undef.
  170. objs := &objects{
  171. byNID: make([]object, numNIDs),
  172. nameToNID: make(map[string]int),
  173. }
  174. objs.byNID[0] = object{
  175. name: "undef",
  176. shortName: "UNDEF",
  177. longName: "undefined",
  178. hasShortName: true,
  179. hasLongName: true,
  180. }
  181. objs.nameToNID["undef"] = 0
  182. var module, nextName string
  183. var lineNo int
  184. longNamesSeen := make(map[string]struct{})
  185. shortNamesSeen := make(map[string]struct{})
  186. aliases := make(map[string][]int)
  187. scanner := bufio.NewScanner(in)
  188. for scanner.Scan() {
  189. line := scanner.Text()
  190. lineNo++
  191. withLine := func(err error) error {
  192. return fmt.Errorf("%s:%d: %s", objectsPath, lineNo, err)
  193. }
  194. // Remove comments.
  195. idx := strings.IndexRune(line, '#')
  196. if idx >= 0 {
  197. line = line[:idx]
  198. }
  199. // Skip empty lines.
  200. line = strings.TrimSpace(line)
  201. if len(line) == 0 {
  202. continue
  203. }
  204. if line[0] == '!' {
  205. args := strings.Fields(line)
  206. switch args[0] {
  207. case "!module":
  208. if len(args) != 2 {
  209. return nil, withLine(errors.New("too many arguments"))
  210. }
  211. module = sanitizeName(args[1]) + "_"
  212. case "!global":
  213. module = ""
  214. case "!Cname":
  215. // !Cname directives override the name for the
  216. // next object.
  217. if len(args) != 2 {
  218. return nil, withLine(errors.New("too many arguments"))
  219. }
  220. nextName = sanitizeName(args[1])
  221. case "!Alias":
  222. // !Alias directives define an alias for an OID
  223. // without emitting an object.
  224. if len(nextName) != 0 {
  225. return nil, withLine(errors.New("!Cname directives may not modify !Alias directives."))
  226. }
  227. if len(args) < 3 {
  228. return nil, withLine(errors.New("not enough arguments"))
  229. }
  230. aliasName := module + sanitizeName(args[1])
  231. oid, err := parseOID(aliases, args[2:])
  232. if err != nil {
  233. return nil, withLine(err)
  234. }
  235. if _, ok := aliases[aliasName]; ok {
  236. return nil, withLine(fmt.Errorf("duplicate name '%s'", aliasName))
  237. }
  238. aliases[aliasName] = oid
  239. default:
  240. return nil, withLine(fmt.Errorf("unknown directive '%s'", args[0]))
  241. }
  242. continue
  243. }
  244. fields := strings.Split(line, ":")
  245. if len(fields) < 2 || len(fields) > 3 {
  246. return nil, withLine(errors.New("invalid field count"))
  247. }
  248. obj := object{name: nextName}
  249. nextName = ""
  250. var err error
  251. obj.oid, err = parseOID(aliases, strings.Fields(fields[0]))
  252. if err != nil {
  253. return nil, withLine(err)
  254. }
  255. obj.encoded = encodeOID(obj.oid)
  256. obj.shortName = strings.TrimSpace(fields[1])
  257. if len(fields) == 3 {
  258. obj.longName = strings.TrimSpace(fields[2])
  259. }
  260. // Long and short names default to each other if missing.
  261. if len(obj.shortName) == 0 {
  262. obj.shortName = obj.longName
  263. } else {
  264. obj.hasShortName = true
  265. }
  266. if len(obj.longName) == 0 {
  267. obj.longName = obj.shortName
  268. } else {
  269. obj.hasLongName = true
  270. }
  271. if len(obj.shortName) == 0 || len(obj.longName) == 0 {
  272. return nil, withLine(errors.New("object with no name"))
  273. }
  274. // If not already specified, prefer the long name if it has no
  275. // spaces, otherwise the short name.
  276. if len(obj.name) == 0 && strings.IndexRune(obj.longName, ' ') < 0 {
  277. obj.name = sanitizeName(obj.longName)
  278. }
  279. if len(obj.name) == 0 {
  280. obj.name = sanitizeName(obj.shortName)
  281. }
  282. obj.name = module + obj.name
  283. // Check for duplicate names.
  284. if _, ok := aliases[obj.name]; ok {
  285. return nil, withLine(fmt.Errorf("duplicate name '%s'", obj.name))
  286. }
  287. if _, ok := shortNamesSeen[obj.shortName]; ok && len(obj.shortName) > 0 {
  288. return nil, withLine(fmt.Errorf("duplicate short name '%s'", obj.shortName))
  289. }
  290. if _, ok := longNamesSeen[obj.longName]; ok && len(obj.longName) > 0 {
  291. return nil, withLine(fmt.Errorf("duplicate long name '%s'", obj.longName))
  292. }
  293. // Allocate a NID.
  294. nid, ok := nameToNID[obj.name]
  295. if !ok {
  296. nid = len(objs.byNID)
  297. objs.byNID = append(objs.byNID, object{})
  298. }
  299. objs.byNID[nid] = obj
  300. objs.nameToNID[obj.name] = nid
  301. longNamesSeen[obj.longName] = struct{}{}
  302. shortNamesSeen[obj.shortName] = struct{}{}
  303. aliases[obj.name] = obj.oid
  304. }
  305. if err := scanner.Err(); err != nil {
  306. return nil, err
  307. }
  308. return objs, nil
  309. }
  310. func writeNumbers(path string, objs *objects) error {
  311. out, err := os.Create(path)
  312. if err != nil {
  313. return err
  314. }
  315. defer out.Close()
  316. for nid, obj := range objs.byNID {
  317. if len(obj.name) == 0 {
  318. continue
  319. }
  320. if _, err := fmt.Fprintf(out, "%s\t\t%d\n", obj.name, nid); err != nil {
  321. return err
  322. }
  323. }
  324. return nil
  325. }
  326. func clangFormat(input string) (string, error) {
  327. var b bytes.Buffer
  328. cmd := exec.Command("clang-format")
  329. cmd.Stdin = strings.NewReader(input)
  330. cmd.Stdout = &b
  331. cmd.Stderr = os.Stderr
  332. if err := cmd.Run(); err != nil {
  333. return "", err
  334. }
  335. return b.String(), nil
  336. }
  337. func writeHeader(path string, objs *objects) error {
  338. var b bytes.Buffer
  339. fmt.Fprintf(&b, `/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
  340. * All rights reserved.
  341. *
  342. * This package is an SSL implementation written
  343. * by Eric Young (eay@cryptsoft.com).
  344. * The implementation was written so as to conform with Netscapes SSL.
  345. *
  346. * This library is free for commercial and non-commercial use as long as
  347. * the following conditions are aheared to. The following conditions
  348. * apply to all code found in this distribution, be it the RC4, RSA,
  349. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  350. * included with this distribution is covered by the same copyright terms
  351. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  352. *
  353. * Copyright remains Eric Young's, and as such any Copyright notices in
  354. * the code are not to be removed.
  355. * If this package is used in a product, Eric Young should be given attribution
  356. * as the author of the parts of the library used.
  357. * This can be in the form of a textual message at program startup or
  358. * in documentation (online or textual) provided with the package.
  359. *
  360. * Redistribution and use in source and binary forms, with or without
  361. * modification, are permitted provided that the following conditions
  362. * are met:
  363. * 1. Redistributions of source code must retain the copyright
  364. * notice, this list of conditions and the following disclaimer.
  365. * 2. Redistributions in binary form must reproduce the above copyright
  366. * notice, this list of conditions and the following disclaimer in the
  367. * documentation and/or other materials provided with the distribution.
  368. * 3. All advertising materials mentioning features or use of this software
  369. * must display the following acknowledgement:
  370. * "This product includes cryptographic software written by
  371. * Eric Young (eay@cryptsoft.com)"
  372. * The word 'cryptographic' can be left out if the rouines from the library
  373. * being used are not cryptographic related :-).
  374. * 4. If you include any Windows specific code (or a derivative thereof) from
  375. * the apps directory (application code) you must include an acknowledgement:
  376. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  377. *
  378. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG `+"``"+`AS IS'' AND
  379. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  380. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  381. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  382. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  383. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  384. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  385. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  386. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  387. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  388. * SUCH DAMAGE.
  389. *
  390. * The licence and distribution terms for any publically available version or
  391. * derivative of this code cannot be changed. i.e. this code cannot simply be
  392. * copied and put under another distribution licence
  393. * [including the GNU Public Licence.] */
  394. /* This file is generated by crypto/obj/objects.go. */
  395. #ifndef OPENSSL_HEADER_NID_H
  396. #define OPENSSL_HEADER_NID_H
  397. #include <openssl/base.h>
  398. #if defined(__cplusplus)
  399. extern "C" {
  400. #endif
  401. /* The nid library provides numbered values for ASN.1 object identifiers and
  402. * other symbols. These values are used by other libraries to identify
  403. * cryptographic primitives.
  404. *
  405. * A separate objects library, obj.h, provides functions for converting between
  406. * nids and object identifiers. However it depends on large internal tables with
  407. * the encodings of every nid defined. Consumers concerned with binary size
  408. * should instead embed the encodings of the few consumed OIDs and compare
  409. * against those.
  410. *
  411. * These values should not be used outside of a single process; they are not
  412. * stable identifiers. */
  413. `)
  414. for nid, obj := range objs.byNID {
  415. if len(obj.name) == 0 {
  416. continue
  417. }
  418. if obj.hasShortName {
  419. fmt.Fprintf(&b, "#define SN_%s \"%s\"\n", obj.name, obj.shortName)
  420. }
  421. if obj.hasLongName {
  422. fmt.Fprintf(&b, "#define LN_%s \"%s\"\n", obj.name, obj.longName)
  423. }
  424. fmt.Fprintf(&b, "#define NID_%s %d\n", obj.name, nid)
  425. // Although NID_undef does not have an OID, OpenSSL emits
  426. // OBJ_undef as if it were zero.
  427. oid := obj.oid
  428. if nid == 0 {
  429. oid = []int{0}
  430. }
  431. if len(oid) != 0 {
  432. var oidStr string
  433. for _, val := range oid {
  434. if len(oidStr) != 0 {
  435. oidStr += ","
  436. }
  437. oidStr += fmt.Sprintf("%dL", val)
  438. }
  439. fmt.Fprintf(&b, "#define OBJ_%s %s\n", obj.name, oidStr)
  440. }
  441. fmt.Fprintf(&b, "\n")
  442. }
  443. fmt.Fprintf(&b, `
  444. #if defined(__cplusplus)
  445. } /* extern C */
  446. #endif
  447. #endif /* OPENSSL_HEADER_NID_H */
  448. `)
  449. formatted, err := clangFormat(b.String())
  450. if err != nil {
  451. return err
  452. }
  453. return ioutil.WriteFile(path, []byte(formatted), 0666)
  454. }
  455. // TODO(davidben): Replace this with sort.Slice once Go 1.8 is sufficiently
  456. // common.
  457. type nidSorter struct {
  458. nids []int
  459. objs *objects
  460. cmp func(a, b object) bool
  461. }
  462. func (a nidSorter) obj(i int) object { return a.objs.byNID[a.nids[i]] }
  463. func (a nidSorter) Len() int { return len(a.nids) }
  464. func (a nidSorter) Swap(i, j int) { a.nids[i], a.nids[j] = a.nids[j], a.nids[i] }
  465. func (a nidSorter) Less(i, j int) bool { return a.cmp(a.obj(i), a.obj(j)) }
  466. func sortNIDs(nids []int, objs *objects, cmp func(a, b object) bool) {
  467. sort.Sort(&nidSorter{nids, objs, cmp})
  468. }
  469. func writeData(path string, objs *objects) error {
  470. var b bytes.Buffer
  471. fmt.Fprintf(&b, `/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
  472. * All rights reserved.
  473. *
  474. * This package is an SSL implementation written
  475. * by Eric Young (eay@cryptsoft.com).
  476. * The implementation was written so as to conform with Netscapes SSL.
  477. *
  478. * This library is free for commercial and non-commercial use as long as
  479. * the following conditions are aheared to. The following conditions
  480. * apply to all code found in this distribution, be it the RC4, RSA,
  481. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  482. * included with this distribution is covered by the same copyright terms
  483. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  484. *
  485. * Copyright remains Eric Young's, and as such any Copyright notices in
  486. * the code are not to be removed.
  487. * If this package is used in a product, Eric Young should be given attribution
  488. * as the author of the parts of the library used.
  489. * This can be in the form of a textual message at program startup or
  490. * in documentation (online or textual) provided with the package.
  491. *
  492. * Redistribution and use in source and binary forms, with or without
  493. * modification, are permitted provided that the following conditions
  494. * are met:
  495. * 1. Redistributions of source code must retain the copyright
  496. * notice, this list of conditions and the following disclaimer.
  497. * 2. Redistributions in binary form must reproduce the above copyright
  498. * notice, this list of conditions and the following disclaimer in the
  499. * documentation and/or other materials provided with the distribution.
  500. * 3. All advertising materials mentioning features or use of this software
  501. * must display the following acknowledgement:
  502. * "This product includes cryptographic software written by
  503. * Eric Young (eay@cryptsoft.com)"
  504. * The word 'cryptographic' can be left out if the rouines from the library
  505. * being used are not cryptographic related :-).
  506. * 4. If you include any Windows specific code (or a derivative thereof) from
  507. * the apps directory (application code) you must include an acknowledgement:
  508. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  509. *
  510. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG `+"``"+`AS IS'' AND
  511. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  512. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  513. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  514. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  515. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  516. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  517. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  518. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  519. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  520. * SUCH DAMAGE.
  521. *
  522. * The licence and distribution terms for any publically available version or
  523. * derivative of this code cannot be changed. i.e. this code cannot simply be
  524. * copied and put under another distribution licence
  525. * [including the GNU Public Licence.] */
  526. /* This file is generated by crypto/obj/objects.go. */
  527. `)
  528. fmt.Fprintf(&b, "#define NUM_NID %d\n", len(objs.byNID))
  529. // Emit each object's DER encoding, concatenated, and save the offsets.
  530. fmt.Fprintf(&b, "\nstatic const uint8_t kObjectData[] = {\n")
  531. offsets := make([]int, len(objs.byNID))
  532. var nextOffset int
  533. for nid, obj := range objs.byNID {
  534. if len(obj.name) == 0 || len(obj.encoded) == 0 {
  535. offsets[nid] = -1
  536. continue
  537. }
  538. offsets[nid] = nextOffset
  539. nextOffset += len(obj.encoded)
  540. fmt.Fprintf(&b, "/* NID_%s */\n", obj.name)
  541. for _, val := range obj.encoded {
  542. fmt.Fprintf(&b, "0x%02x, ", val)
  543. }
  544. fmt.Fprintf(&b, "\n")
  545. }
  546. fmt.Fprintf(&b, "};\n")
  547. // Emit an ASN1_OBJECT for each object.
  548. fmt.Fprintf(&b, "\nstatic const ASN1_OBJECT kObjects[NUM_NID] = {\n")
  549. for nid, obj := range objs.byNID {
  550. if len(obj.name) == 0 {
  551. fmt.Fprintf(&b, "{NULL, NULL, NID_undef, 0, NULL, 0},\n")
  552. continue
  553. }
  554. fmt.Fprintf(&b, "{\"%s\", \"%s\", NID_%s, ", obj.shortName, obj.longName, obj.name)
  555. if offset := offsets[nid]; offset >= 0 {
  556. fmt.Fprintf(&b, "%d, &kObjectData[%d], 0},\n", len(obj.encoded), offset)
  557. } else {
  558. fmt.Fprintf(&b, "0, NULL, 0},\n")
  559. }
  560. }
  561. fmt.Fprintf(&b, "};\n")
  562. // Emit a list of NIDs sorted by short name.
  563. var nids []int
  564. for nid, obj := range objs.byNID {
  565. if len(obj.name) == 0 || len(obj.shortName) == 0 {
  566. continue
  567. }
  568. nids = append(nids, nid)
  569. }
  570. sortNIDs(nids, objs, func(a, b object) bool { return a.shortName < b.shortName })
  571. fmt.Fprintf(&b, "\nstatic const unsigned kNIDsInShortNameOrder[] = {\n")
  572. for _, nid := range nids {
  573. fmt.Fprintf(&b, "%d /* %s */,\n", nid, objs.byNID[nid].shortName)
  574. }
  575. fmt.Fprintf(&b, "};\n")
  576. // Emit a list of NIDs sorted by long name.
  577. nids = nil
  578. for nid, obj := range objs.byNID {
  579. if len(obj.name) == 0 || len(obj.longName) == 0 {
  580. continue
  581. }
  582. nids = append(nids, nid)
  583. }
  584. sortNIDs(nids, objs, func(a, b object) bool { return a.longName < b.longName })
  585. fmt.Fprintf(&b, "\nstatic const unsigned kNIDsInLongNameOrder[] = {\n")
  586. for _, nid := range nids {
  587. fmt.Fprintf(&b, "%d /* %s */,\n", nid, objs.byNID[nid].longName)
  588. }
  589. fmt.Fprintf(&b, "};\n")
  590. // Emit a list of NIDs sorted by OID.
  591. nids = nil
  592. for nid, obj := range objs.byNID {
  593. if len(obj.name) == 0 || len(obj.encoded) == 0 {
  594. continue
  595. }
  596. nids = append(nids, nid)
  597. }
  598. sortNIDs(nids, objs, func(a, b object) bool {
  599. // This comparison must match the definition of |obj_cmp|.
  600. if len(a.encoded) < len(b.encoded) {
  601. return true
  602. }
  603. if len(a.encoded) > len(b.encoded) {
  604. return false
  605. }
  606. return bytes.Compare(a.encoded, b.encoded) < 0
  607. })
  608. fmt.Fprintf(&b, "\nstatic const unsigned kNIDsInOIDOrder[] = {\n")
  609. for _, nid := range nids {
  610. obj := objs.byNID[nid]
  611. fmt.Fprintf(&b, "%d /* ", nid)
  612. for i, c := range obj.oid {
  613. if i > 0 {
  614. fmt.Fprintf(&b, ".")
  615. }
  616. fmt.Fprintf(&b, "%d", c)
  617. }
  618. fmt.Fprintf(&b, " (OBJ_%s) */,\n", obj.name)
  619. }
  620. fmt.Fprintf(&b, "};\n")
  621. formatted, err := clangFormat(b.String())
  622. if err != nil {
  623. return err
  624. }
  625. return ioutil.WriteFile(path, []byte(formatted), 0666)
  626. }
  627. func main() {
  628. objs, err := readObjects("obj_mac.num", "objects.txt")
  629. if err != nil {
  630. fmt.Fprintf(os.Stderr, "Error reading objects: %s\n", err)
  631. os.Exit(1)
  632. }
  633. if err := writeNumbers("obj_mac.num", objs); err != nil {
  634. fmt.Fprintf(os.Stderr, "Error writing numbers: %s\n", err)
  635. os.Exit(1)
  636. }
  637. if err := writeHeader("../../include/openssl/nid.h", objs); err != nil {
  638. fmt.Fprintf(os.Stderr, "Error writing header: %s\n", err)
  639. os.Exit(1)
  640. }
  641. if err := writeData("obj_dat.h", objs); err != nil {
  642. fmt.Fprintf(os.Stderr, "Error writing data: %s\n", err)
  643. os.Exit(1)
  644. }
  645. }