| #!/usr/bin/env python |
| |
| # |
| # Copyright (c) 2020 Project CHIP Authors |
| # Copyright (c) 2019 Google LLC. |
| # Copyright (c) 2013-2017 Nest Labs, Inc. |
| # All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| |
| # |
| # @file |
| # This file implements a Python script to generate a C/C++ header |
| # for individual ASN1 Object IDs (OIDs) that are used in CHIP |
| # TLV encodings (notably the CHIP Certificate object). |
| # |
| |
| from __future__ import absolute_import |
| from __future__ import print_function |
| import optparse |
| import sys |
| |
| def identity(n): |
| return n |
| |
| |
| # OID labels |
| ansi_X9_62 = identity |
| certicom = identity |
| characteristicTwo = identity |
| chip = identity |
| curve = identity |
| curves = identity |
| digest_algorithm = identity |
| dod = identity |
| ds = identity |
| enterprise = identity |
| organization = identity |
| internet = identity |
| iso = identity |
| itu_t = identity |
| joint_iso_ccitt = identity |
| keyType = identity |
| mechanisms = identity |
| member_body = identity |
| pkcs1 = identity |
| pkcs = identity |
| pkix = identity |
| prime = identity |
| private = identity |
| rsadsi = identity |
| schemes = identity |
| security = identity |
| signatures = identity |
| us = identity |
| zigbee = identity |
| |
| # OID Categories |
| oidCategories = [ |
| ( "PubKeyAlgo", 0x0100 ), |
| ( "SigAlgo", 0x0200 ), |
| ( "AttributeType", 0x0300 ), |
| ( "EllipticCurve", 0x0400 ), |
| ( "Extension", 0x0500 ), |
| ( "KeyPurpose", 0x0600 ) |
| ] |
| |
| # Table of well-known ASN.1 object IDs |
| # |
| oids = [ |
| |
| # !!! WARNING !!! |
| # |
| # The enumerated values associated with individual object IDs are used in CHIP TLV encodings (notably the CHIP Certificate object). |
| # Because of this, the Enum Values assigned to object IDs in this table MUST NOT BE CHANGED once in use. |
| |
| |
| # Enum |
| # Category Name Value Object ID |
| # ----------------- -------------------------- -------- ------------------------------------------------------------------------------------------------ |
| |
| # Public Key Algorithms |
| ( "PubKeyAlgo", "ECPublicKey", 1, [ iso(1), member_body(2), us(840), ansi_X9_62(10045), keyType(2), 1 ] ), |
| |
| # Signature Algorithms |
| # RFC 3279 |
| ( "SigAlgo", "ECDSAWithSHA256", 1, [ iso(1), member_body(2), us(840), ansi_X9_62(10045), signatures(4), 3, 2 ] ), |
| |
| # X.509 Distinguished Name Attribute Types |
| # WARNING -- Assign no values higher than 127. |
| ( "AttributeType", "CommonName", 1, [ joint_iso_ccitt(2), ds(5), 4, 3 ] ), |
| ( "AttributeType", "Surname", 2, [ joint_iso_ccitt(2), ds(5), 4, 4 ] ), |
| ( "AttributeType", "SerialNumber", 3, [ joint_iso_ccitt(2), ds(5), 4, 5 ] ), |
| ( "AttributeType", "CountryName", 4, [ joint_iso_ccitt(2), ds(5), 4, 6 ] ), |
| ( "AttributeType", "LocalityName", 5, [ joint_iso_ccitt(2), ds(5), 4, 7 ] ), |
| ( "AttributeType", "StateOrProvinceName", 6, [ joint_iso_ccitt(2), ds(5), 4, 8 ] ), |
| ( "AttributeType", "OrganizationName", 7, [ joint_iso_ccitt(2), ds(5), 4, 10 ] ), |
| ( "AttributeType", "OrganizationalUnitName", 8, [ joint_iso_ccitt(2), ds(5), 4, 11 ] ), |
| ( "AttributeType", "Title", 9, [ joint_iso_ccitt(2), ds(5), 4, 12 ] ), |
| ( "AttributeType", "Name", 10, [ joint_iso_ccitt(2), ds(5), 4, 41 ] ), |
| ( "AttributeType", "GivenName", 11, [ joint_iso_ccitt(2), ds(5), 4, 42 ] ), |
| ( "AttributeType", "Initials", 12, [ joint_iso_ccitt(2), ds(5), 4, 43 ] ), |
| ( "AttributeType", "GenerationQualifier", 13, [ joint_iso_ccitt(2), ds(5), 4, 44 ] ), |
| ( "AttributeType", "DNQualifier", 14, [ joint_iso_ccitt(2), ds(5), 4, 46 ] ), |
| ( "AttributeType", "Pseudonym", 15, [ joint_iso_ccitt(2), ds(5), 4, 65 ] ), |
| ( "AttributeType", "DomainComponent", 16, [ itu_t(0), 9, 2342, 19200300, 100, 1, 25 ] ), |
| ( "AttributeType", "ChipNodeId", 17, [ iso(1), organization(3), dod(6), internet(1), private(4), enterprise(1), zigbee(37244), chip(1), 1 ] ), |
| ( "AttributeType", "ChipCAId", 18, [ iso(1), organization(3), dod(6), internet(1), private(4), enterprise(1), zigbee(37244), chip(1), 2 ] ), |
| ( "AttributeType", "ChipSoftwarePublisherId", 19, [ iso(1), organization(3), dod(6), internet(1), private(4), enterprise(1), zigbee(37244), chip(1), 3 ] ), |
| ( "AttributeType", "ChipFabricId", 20, [ iso(1), organization(3), dod(6), internet(1), private(4), enterprise(1), zigbee(37244), chip(1), 4 ] ), |
| |
| # Elliptic Curves |
| ( "EllipticCurve", "prime256v1", 1, [ iso(1), member_body(2), us(840), ansi_X9_62(10045), curves(3), prime(1), 7 ] ), |
| |
| # Certificate Extensions |
| ( "Extension", "AuthorityKeyIdentifier", 1, [ joint_iso_ccitt(2), ds(5), 29, 35 ] ), |
| ( "Extension", "SubjectKeyIdentifier", 2, [ joint_iso_ccitt(2), ds(5), 29, 14 ] ), |
| ( "Extension", "KeyUsage", 3, [ joint_iso_ccitt(2), ds(5), 29, 15 ] ), |
| ( "Extension", "BasicConstraints", 4, [ joint_iso_ccitt(2), ds(5), 29, 19 ] ), |
| ( "Extension", "ExtendedKeyUsage", 5, [ joint_iso_ccitt(2), ds(5), 29, 37 ] ), |
| |
| # Key Purposes |
| ( "KeyPurpose", "ServerAuth", 1, [ iso(1), organization(3), dod(6), internet(1), security(5), mechanisms(5), pkix(7), 3, 1 ] ), |
| ( "KeyPurpose", "ClientAuth", 2, [ iso(1), organization(3), dod(6), internet(1), security(5), mechanisms(5), pkix(7), 3, 2 ] ), |
| ( "KeyPurpose", "CodeSigning", 3, [ iso(1), organization(3), dod(6), internet(1), security(5), mechanisms(5), pkix(7), 3, 3 ] ), |
| ( "KeyPurpose", "EmailProtection", 4, [ iso(1), organization(3), dod(6), internet(1), security(5), mechanisms(5), pkix(7), 3, 4 ] ), |
| ( "KeyPurpose", "TimeStamping", 5, [ iso(1), organization(3), dod(6), internet(1), security(5), mechanisms(5), pkix(7), 3, 8 ] ), |
| ( "KeyPurpose", "OCSPSigning", 6, [ iso(1), organization(3), dod(6), internet(1), security(5), mechanisms(5), pkix(7), 3, 9 ] ), |
| ] |
| |
| |
| def encodeOID(oid): |
| |
| assert len(oid) >= 2 |
| |
| oid = [ (oid[0]*40 + oid[1]) ] + oid[2:] |
| |
| encodedOID = [] |
| for val in oid: |
| val, byte = divmod(val, 128) |
| seg = [ byte ] |
| while val > 0: |
| val, byte = divmod(val, 128) |
| seg.insert(0, byte + 0x80) |
| encodedOID += (seg) |
| |
| return encodedOID |
| |
| |
| TEMPLATE = '''/* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2019 Google LLC. |
| * Copyright (c) 2013-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the \"License\"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an \"AS IS\" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| /** |
| * @file |
| * ASN.1 Object ID Definitions |
| * |
| * !!! WARNING !!! WARNING !!! WARNING !!! |
| * |
| * DO NOT EDIT THIS FILE! This file is generated by the |
| * gen-oid-table.py script. |
| * |
| * To make changes, edit the script and re-run it to generate |
| * this file. |
| * |
| */ |
| |
| #pragma once |
| |
| enum OIDCategory |
| %(oid_category_enums)s |
| |
| typedef uint16_t OID; |
| |
| enum |
| %(oid_enums)s |
| |
| struct OIDTableEntry |
| { |
| OID EnumVal; |
| const uint8_t *EncodedOID; |
| uint16_t EncodedOIDLen; |
| }; |
| |
| struct OIDNameTableEntry |
| { |
| OID EnumVal; |
| const char *Name; |
| }; |
| |
| extern const OIDTableEntry sOIDTable[]; |
| extern const OIDNameTableEntry sOIDNameTable[]; |
| extern const size_t sOIDTableSize; |
| |
| #ifdef ASN1_DEFINE_OID_TABLE |
| %(oid_utf8_strings)s |
| |
| const OIDTableEntry sOIDTable[] = |
| %(oid_table)s |
| |
| const size_t sOIDTableSize = sizeof(sOIDTable) / sizeof(OIDTableEntry); |
| |
| #endif // ASN1_DEFINE_OID_TABLE |
| |
| #ifdef ASN1_DEFINE_OID_NAME_TABLE |
| |
| const OIDNameTableEntry sOIDNameTable[] = |
| %(oid_name_table)s |
| |
| #endif // ASN1_DEFINE_OID_NAME_TABLE |
| ''' |
| |
| oid_category_enums ="{\n" |
| for (catName, catEnum) in oidCategories: |
| oid_category_enums +=" kOIDCategory_%s = 0x%04X,\n" % (catName, catEnum) |
| oid_category_enums +=''' |
| kOIDCategory_NotSpecified = 0, |
| kOIDCategory_Unknown = 0x0F00, |
| kOIDCategory_Mask = 0x0F00 |
| };''' |
| |
| oid_enums ="{\n" |
| for (catName, catEnum) in oidCategories: |
| for (oidCatName, oidName, oidEnum, oid) in oids: |
| if (oidCatName == catName): |
| oid_enums +=" kOID_%s_%s = 0x%04X,\n" % (catName, oidName, catEnum + oidEnum) |
| oid_enums +="\n" |
| oid_enums +=''' kOID_NotSpecified = 0, |
| kOID_Unknown = 0xFFFF, |
| kOID_EnumMask = 0x00FF |
| };''' |
| |
| oid_utf8_strings ="\n" |
| for (catName, oidName, oidEnum, oid) in oids: |
| oid_utf8_strings +="static const uint8_t sOID_%s_%s[] = { %s };\n" % (catName, oidName, ", ".join([ "0x%02X" % (x) for x in encodeOID(oid) ])) |
| |
| oid_table ="{\n" |
| for (catName, oidName, oidEnum, oid) in oids: |
| oid_table +=" { kOID_%s_%s, sOID_%s_%s, sizeof(sOID_%s_%s) },\n" % (catName, oidName, catName, oidName, catName, oidName) |
| oid_table +=" { kOID_NotSpecified, NULL, 0 }\n};" |
| |
| oid_name_table ="{\n" |
| for (catName, oidName, oidEnum, oid) in oids: |
| oid_name_table +=" { kOID_%s_%s, \"%s\" },\n" % (catName, oidName, oidName) |
| oid_name_table +=" { kOID_NotSpecified, NULL }\n};" |
| |
| |
| def main(argv): |
| parser = optparse.OptionParser() |
| |
| parser.add_option('--output_file') |
| |
| options, _ = parser.parse_args(argv) |
| |
| template_args = { |
| 'oid_category_enums': oid_category_enums, |
| 'oid_enums': oid_enums, |
| 'oid_utf8_strings': oid_utf8_strings, |
| 'oid_table': oid_table, |
| 'oid_name_table': oid_name_table, |
| } |
| |
| with open(options.output_file, 'w') as asn1oid_file: |
| asn1oid_file.write(TEMPLATE % template_args) |
| |
| return 0 |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |