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