diff options
Diffstat (limited to 'scripts/build-attributes')
-rwxr-xr-x | scripts/build-attributes | 526 |
1 files changed, 263 insertions, 263 deletions
diff --git a/scripts/build-attributes b/scripts/build-attributes index 7a36bdc..e7c500e 100755 --- a/scripts/build-attributes +++ b/scripts/build-attributes @@ -47,318 +47,318 @@ import argparse def define_flags(flag_names): - """ - Flag definitions. Called later, here at front of program just to - make them easier to find. - """ - - flag_names.create("DEFAULT_VALUE", "Value field contains default") - flag_names.footnote( 1, "REQUIRED_BY_CREATEOBJECT") - flag_names.footnote( 2, "FORBIDDEN_BY_CREATEOBJECT") - flag_names.footnote( 3, "REQUIRED_BY_GENERATE") - flag_names.footnote( 4, "FORBIDDEN_BY_GENERATE") - flag_names.footnote( 5, "REQUIRED_BY_UNWRAP") - flag_names.footnote( 6, "FORBIDDEN_BY_UNWRAP") - flag_names.footnote( 7, "SENSITIVE") - flag_names.footnote( 8, "PERHAPS_MODIFIABLE") - flag_names.footnote( 9, "DEFAULT_IS_TOKEN_SPECIFIC") - flag_names.footnote(10, "ONLY_SO_USER_CAN_SET") - flag_names.footnote(11, "LATCHES_WHEN_TRUE") - flag_names.footnote(12, "LATCHES_WHEN_FALSE") + """ + Flag definitions. Called later, here at front of program just to + make them easier to find. + """ + + flag_names.create("DEFAULT_VALUE", "Value field contains default") + flag_names.footnote( 1, "REQUIRED_BY_CREATEOBJECT") + flag_names.footnote( 2, "FORBIDDEN_BY_CREATEOBJECT") + flag_names.footnote( 3, "REQUIRED_BY_GENERATE") + flag_names.footnote( 4, "FORBIDDEN_BY_GENERATE") + flag_names.footnote( 5, "REQUIRED_BY_UNWRAP") + flag_names.footnote( 6, "FORBIDDEN_BY_UNWRAP") + flag_names.footnote( 7, "SENSITIVE") + flag_names.footnote( 8, "PERHAPS_MODIFIABLE") + flag_names.footnote( 9, "DEFAULT_IS_TOKEN_SPECIFIC") + flag_names.footnote(10, "ONLY_SO_USER_CAN_SET") + flag_names.footnote(11, "LATCHES_WHEN_TRUE") + flag_names.footnote(12, "LATCHES_WHEN_FALSE") class PKCS11ParseError(Exception): - "Failure parsing PCKS #11 object definitions from YAML data." + "Failure parsing PCKS #11 object definitions from YAML data." def write_lines(*lines, **d): - """ - Utility to simplify writing formatted text to the output stream. - """ - - for line in lines: - args.output_file.write((line % d) + "\n") - - -class Flags(object): - """ - Descriptor flag database. - - Many of these are derived from PKCS #11 Table 15 footnotes - """ - - prefix = "P11_DESCRIPTOR_" # Prefix string for all descriptor flags - - def __init__(self): - self.names = [] - self.notes = {} - self.width = 0 - - def create(self, name, comment = None): """ - Create a descriptor flag. + Utility to simplify writing formatted text to the output stream. """ - assert len(self.names) < 32 - name = self.prefix + name - self.names.append((name, comment)) - if len(name) > self.width: - self.width = len(name) - - def footnote(self, number, name): - """ - Create a descriptor flag for a PKCS #11 table 15 footnote. - """ + for line in lines: + args.output_file.write((line % d) + "\n") - assert number not in self.notes - self.create(name, "Section 10.2 table 15 footnote #%2d" % number) - self.notes[number] = self.prefix + name - def write(self): +class Flags(object): """ - Generate the flags, assigning bit positions as we go. + Descriptor flag database. + + Many of these are derived from PKCS #11 Table 15 footnotes """ - assert len(self.names) < 32 - self.width = (((self.width + 4) >> 2) << 2) - 1 - bit = 1 - for name, comment in self.names: - format = "#define %(name)s 0x%(bit)08x" - if comment is not None: - format += " /* %(comment)s */" - write_lines(format, bit = bit, comment = comment, name = "%-*s" % (self.width, name)) - bit <<= 1 + prefix = "P11_DESCRIPTOR_" # Prefix string for all descriptor flags + def __init__(self): + self.names = [] + self.notes = {} + self.width = 0 -class AttributeNumbers(dict): - """ - Attribute names and numbers scraped (yuck) from pkcs11t.h. - """ - - def __init__(self, filename): - with open(filename, "r") as f: - for line in f: - word = line.split() - if len(word) <= 2 or word[0] != "#define" or not word[1].startswith("CKA_"): - continue - if word[2] in self: - continue - if word[2].startswith("(CKF_ARRAY_ATTRIBUTE|"): - word[2] = word[2].translate(None, "()").split("|")[1] - self[word[1]] = int(word[2], 16) + def create(self, name, comment = None): + """ + Create a descriptor flag. + """ + assert len(self.names) < 32 + name = self.prefix + name + self.names.append((name, comment)) + if len(name) > self.width: + self.width = len(name) -class Attribute(object): - """ - Definition of one attribute. - """ - - def __init__(self, name, type = None, footnotes = None, default = None, value = None, unimplemented = False): - assert value is None or default is None - self.name = name - self.type = type - self.footnotes = footnotes - self.default = self.convert_integers(default) - self.value = self.convert_integers(value) - self.unimplemented = unimplemented - - @staticmethod - def convert_integers(val): - """ - Convert a non-negative integer initialization value into a byte array. - """ + def footnote(self, number, name): + """ + Create a descriptor flag for a PKCS #11 table 15 footnote. + """ - if not isinstance(val, (int, long)): - return val - if val < 0: - raise ValueError("Negative integers not legal here: %s" % val) - bytes = [] - while val > 0: - bytes.insert(0, val & 0xFF) - val >>= 8 - return bytes or [0] - - def inherit(self, other): - """ - Merge values from paraent attribute definition, if any. - """ + assert number not in self.notes + self.create(name, "Section 10.2 table 15 footnote #%2d" % number) + self.notes[number] = self.prefix + name - for k in ("type", "footnotes", "default", "value"): - if getattr(self, k) is None: - setattr(self, k, getattr(other, k)) - self.unimplemented = self.unimplemented or other.unimplemented + def write(self): + """ + Generate the flags, assigning bit positions as we go. + """ - def format_flags(self): - """ - Generate the descriptor flags field. - """ + assert len(self.names) < 32 + self.width = (((self.width + 4) >> 2) << 2) - 1 + bit = 1 + for name, comment in self.names: + format = "#define %(name)s 0x%(bit)08x" + if comment is not None: + format += " /* %(comment)s */" + write_lines(format, bit = bit, comment = comment, name = "%-*s" % (self.width, name)) + bit <<= 1 - flags = [] - if self.footnotes: - flags.extend(flag_names.notes[f] for f in self.footnotes) - if self.value is None and self.default is not None: - flags.append("P11_DESCRIPTOR_DEFAULT_VALUE") - flags = " | ".join(flags) - return flags or "0" - def format_size(self): +class AttributeNumbers(dict): """ - Generate the descriptor size field. + Attribute names and numbers scraped (yuck) from pkcs11t.h. """ - if isinstance(self.type, str) and self.type.startswith("CK_"): - return "sizeof(%s)" % self.type - elif self.type in ("rfc2279string", "biginteger", "bytearray"): - return "0" - else: - raise PKCS11ParseError("Unknown meta-type %r" % self.type) - - def format_length(self): - """ - Generate the descriptor length field. - """ + def __init__(self, filename): + with open(filename, "r") as f: + for line in f: + word = line.split() + if len(word) <= 2 or word[0] != "#define" or not word[1].startswith("CKA_"): + continue + if word[2] in self: + continue + if word[2].startswith("(CKF_ARRAY_ATTRIBUTE|"): + word[2] = word[2].translate(None, "()").split("|")[1] + self[word[1]] = int(word[2], 16) - value = self.value or self.default - if isinstance(value, list): - return "sizeof(const_0x%s)" % "".join("%02x" % v for v in value) - elif value and isinstance(self.type, str) and self.type.startswith("CK_"): - return "sizeof(%s)" % self.type - else: - return "0" - def format_value(self): - """ - Generate the descriptor value field. +class Attribute(object): """ + Definition of one attribute. + """ + + def __init__(self, name, type = None, footnotes = None, default = None, value = None, unimplemented = False): + assert value is None or default is None + self.name = name + self.type = type + self.footnotes = footnotes + self.default = self.convert_integers(default) + self.value = self.convert_integers(value) + self.unimplemented = unimplemented + + @staticmethod + def convert_integers(val): + """ + Convert a non-negative integer initialization value into a byte array. + """ + + if not isinstance(val, int): + return val + if val < 0: + raise ValueError("Negative integers not legal here: %s" % val) + bytes = [] + while val > 0: + bytes.insert(0, val & 0xFF) + val >>= 8 + return bytes or [0] + + def inherit(self, other): + """ + Merge values from paraent attribute definition, if any. + """ + + for k in ("type", "footnotes", "default", "value"): + if getattr(self, k) is None: + setattr(self, k, getattr(other, k)) + self.unimplemented = self.unimplemented or other.unimplemented + + def format_flags(self): + """ + Generate the descriptor flags field. + """ + + flags = [] + if self.footnotes: + flags.extend(flag_names.notes[f] for f in self.footnotes) + if self.value is None and self.default is not None: + flags.append("P11_DESCRIPTOR_DEFAULT_VALUE") + flags = " | ".join(flags) + return flags or "0" + + def format_size(self): + """ + Generate the descriptor size field. + """ + + if isinstance(self.type, str) and self.type.startswith("CK_"): + return "sizeof(%s)" % self.type + elif self.type in ("rfc2279string", "biginteger", "bytearray"): + return "0" + else: + raise PKCS11ParseError("Unknown meta-type %r" % self.type) + + def format_length(self): + """ + Generate the descriptor length field. + """ + + value = self.value or self.default + if isinstance(value, list): + return "sizeof(const_0x%s)" % "".join("%02x" % v for v in value) + elif value and isinstance(self.type, str) and self.type.startswith("CK_"): + return "sizeof(%s)" % self.type + else: + return "0" + + def format_value(self): + """ + Generate the descriptor value field. + """ + + value = self.value or self.default + if not value: + return "NULL_PTR" + elif isinstance(value, list): + return "const_0x" + "".join("%02x" % v for v in value) + else: + return "&const_" + value + + def format_constant(self, constants): + """ + Generate constant initializer values. These are merged so that we + only end up declaring one copy of each initializer value no matter + how many attributes use it. + """ + + value = self.value or self.default + if not self.unimplemented and value: + if isinstance(value, list): + constants.add("static const CK_BYTE const_%s[] = { %s };" % ( + "0x" + "".join("%02x" % v for v in value), + ", ".join("0x%02x" % v for v in value))) + else: + constants.add("static const %s const_%s = %s;" % (self.type, value, value)) + + def generate(self): + """ + Generate the descriptor line for this attribute. + """ + + if not self.unimplemented: + args.output_file.write(" { %s, %s, %s, %s, %s },\n" % ( + self.name, self.format_size(), self.format_length(), self.format_value(), self.format_flags())) - value = self.value or self.default - if not value: - return "NULL_PTR" - elif isinstance(value, list): - return "const_0x" + "".join("%02x" % v for v in value) - else: - return "&const_" + value - def format_constant(self, constants): +class Class(object): """ - Generate constant initializer values. These are merged so that we - only end up declaring one copy of each initializer value no matter - how many attributes use it. + A PKCS #11 class. """ - value = self.value or self.default - if not self.unimplemented and value: - if isinstance(value, list): - constants.add("static const CK_BYTE const_%s[] = { %s };" % ( - "0x" + "".join("%02x" % v for v in value), - ", ".join("0x%02x" % v for v in value))) - else: - constants.add("static const %s const_%s = %s;" % (self.type, value, value)) + def __init__(self, db, name, superclass = None, concrete = False, **attrs): + assert all(a.startswith("CKA_") for a in attrs), "Non-attribute: %r" % [a for a in attrs if not a.startswith("CKA_")] + self.attributes = dict((k, Attribute(k, **v)) for k, v in attrs.items()) + self.db = db + self.name = name + self.superclass = superclass + self.concrete = concrete - def generate(self): - """ - Generate the descriptor line for this attribute. - """ + def inherit(self, other): + """ + Inherit attributes from parent type. + """ - if not self.unimplemented: - args.output_file.write(" { %s, %s, %s, %s, %s },\n" % ( - self.name, self.format_size(), self.format_length(), self.format_value(), self.format_flags())) + for k, v in other.attributes.items(): + if k not in self.attributes: + self.attributes[k] = v + else: + self.attributes[k].inherit(v) + def collect_constants(self, constants): + """ + Collect initialization constants for all attributes. + """ -class Class(object): - """ - A PKCS #11 class. - """ - - def __init__(self, db, name, superclass = None, concrete = False, **attrs): - assert all(a.startswith("CKA_") for a in attrs), "Non-attribute: %r" % [a for a in attrs if not a.startswith("CKA_")] - self.attributes = dict((k, Attribute(k, **v)) for k, v in attrs.iteritems()) - self.db = db - self.name = name - self.superclass = superclass - self.concrete = concrete - - def inherit(self, other): - """ - Inherit attributes from parent type. - """ + if self.concrete: + for a in self.attributes.values(): + a.format_constant(constants) - for k, v in other.attributes.iteritems(): - if k not in self.attributes: - self.attributes[k] = v - else: - self.attributes[k].inherit(v) + def generate(self): + """ + Generate a descriptor for this type. + """ - def collect_constants(self, constants): - """ - Collect initialization constants for all attributes. - """ + if self.concrete: - if self.concrete: - for a in self.attributes.itervalues(): - a.format_constant(constants) + write_lines("", + "static const p11_attribute_descriptor_t p11_attribute_descriptor_%(name)s[] = {", + name = self.name) - def generate(self): - """ - Generate a descriptor for this type. - """ + for a in sorted(self.attributes, key = lambda x: attribute_numbers[x]): + self.attributes[a].generate() - if self.concrete: + write_lines("};", + "", + "static const p11_descriptor_t p11_descriptor_%(name)s = {", + " p11_attribute_descriptor_%(name)s,", + " sizeof(p11_attribute_descriptor_%(name)s)/sizeof(p11_attribute_descriptor_t)", + "};", + name = self.name) - write_lines("", - "static const p11_attribute_descriptor_t p11_attribute_descriptor_%(name)s[] = {", - name = self.name) + def keyclassmap(self): + """ + Generate a keyclass map entry if this is a concrete key type. + """ - for a in sorted(self.attributes, key = lambda x: attribute_numbers[x]): - self.attributes[a].generate() - - write_lines("};", - "", - "static const p11_descriptor_t p11_descriptor_%(name)s = {", - " p11_attribute_descriptor_%(name)s,", - " sizeof(p11_attribute_descriptor_%(name)s)/sizeof(p11_attribute_descriptor_t)", - "};", - name = self.name) - - def keyclassmap(self): - """ - Generate a keyclass map entry if this is a concrete key type. - """ - - if self.concrete and all(k in self.attributes and self.attributes[k].value for k in ("CKA_CLASS", "CKA_KEY_TYPE")): - write_lines(" { %s, %s, &p11_descriptor_%s }," % ( - self.attributes["CKA_CLASS"].value, self.attributes["CKA_KEY_TYPE"].value, self.name)) + if self.concrete and all(k in self.attributes and self.attributes[k].value for k in ("CKA_CLASS", "CKA_KEY_TYPE")): + write_lines(" { %s, %s, &p11_descriptor_%s }," % ( + self.attributes["CKA_CLASS"].value, self.attributes["CKA_KEY_TYPE"].value, self.name)) class DB(object): - """ - Object type database parsed from YAML - """ - - def __init__(self, y): - self.ordered = [Class(self, **y) for y in y] - self.named = dict((c.name, c) for c in self.ordered) - for c in self.ordered: - if c.superclass is not None: - c.inherit(self.named[c.superclass]) - - def generate(self): """ - Generate output for everything in the database. - """ - - constants = set() - for c in self.ordered: - c.collect_constants(constants) - for constant in sorted(constants): - write_lines(constant) - for c in self.ordered: - c.generate() - write_lines("", - "static const p11_descriptor_keyclass_map_t p11_descriptor_keyclass_map[] = {") - for c in self.ordered: - c.keyclassmap() - write_lines("};") + Object type database parsed from YAML + """ + + def __init__(self, y): + self.ordered = [Class(self, **y) for y in y] + self.named = dict((c.name, c) for c in self.ordered) + for c in self.ordered: + if c.superclass is not None: + c.inherit(self.named[c.superclass]) + + def generate(self): + """ + Generate output for everything in the database. + """ + + constants = set() + for c in self.ordered: + c.collect_constants(constants) + for constant in sorted(constants): + write_lines(constant) + for c in self.ordered: + c.generate() + write_lines("", + "static const p11_descriptor_keyclass_map_t p11_descriptor_keyclass_map[] = {") + for c in self.ordered: + c.keyclassmap() + write_lines("};") # Main program |