diff options
author | Adam Vartanian <flooey@google.com> | 2017-03-16 14:26:08 +0000 |
---|---|---|
committer | Adam Vartanian <flooey@google.com> | 2017-03-16 14:26:08 +0000 |
commit | befc86a711b876ed6523fbe453dfa7a9adb345af (patch) | |
tree | dd1177808bde0e31927055b8b17331f3a1cdfc90 | |
parent | 4980cf459974e7595ae13be09bd4801ffef694f1 (diff) |
Add special table formatting for Cipher.
Extracts a new file for JSON loading and cleans up a couple style issues.
Updates the support for GCM to 10+, it was available at least in that
version.
Bug: 35793879
Test: Manual inspection of output
Change-Id: I84f74fd14506cb36e0744a77c0223f5e3b86ca1b
-rw-r--r-- | tools/docs/crypto/crypto_docs.py | 31 | ||||
-rw-r--r-- | tools/docs/crypto/data/crypto_support.json | 4 | ||||
-rwxr-xr-x | tools/docs/crypto/format_supported_algorithm_table.py | 126 | ||||
-rwxr-xr-x | tools/docs/crypto/update_crypto_support.py | 13 |
4 files changed, 154 insertions, 20 deletions
diff --git a/tools/docs/crypto/crypto_docs.py b/tools/docs/crypto/crypto_docs.py new file mode 100644 index 0000000000..d1f220dc87 --- /dev/null +++ b/tools/docs/crypto/crypto_docs.py @@ -0,0 +1,31 @@ +# Copyright (C) 2017 The Android Open Source Project +# +# 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. + +'''Utility functions for crypto doc updating tools.''' + +import json + + +def load_json(filename): + '''Returns an object containing the JSON data from the provided file.''' + f = open(filename) + # JSON doesn't allow comments, but we have some header docs in our file, + # so strip comments out before parsing + stripped_contents = '' + for line in f: + if not line.strip().startswith('#'): + stripped_contents += line + data = json.loads(stripped_contents) + f.close() + return data diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json index 8e6cc4f8de..0a32e5716f 100644 --- a/tools/docs/crypto/data/crypto_support.json +++ b/tools/docs/crypto/data/crypto_support.json @@ -224,7 +224,7 @@ }, { "name": "AES/GCM/NOPADDING", - "supported_api_levels": "21+" + "supported_api_levels": "10+" }, { "name": "AES/OFB/ISO10126PADDING", @@ -1227,5 +1227,5 @@ "name": "TrustManagerFactory" } ], - "last_updated": "2017-03-16 10:29:21 UTC" + "last_updated": "2017-03-16 12:35:47 UTC" }
\ No newline at end of file diff --git a/tools/docs/crypto/format_supported_algorithm_table.py b/tools/docs/crypto/format_supported_algorithm_table.py index f07f9d9c5e..1460099078 100755 --- a/tools/docs/crypto/format_supported_algorithm_table.py +++ b/tools/docs/crypto/format_supported_algorithm_table.py @@ -20,9 +20,11 @@ Outputs HTML tables suitable for inclusion in the Android documentation that reflect the crypto algorithm support shown in the provided data file. """ -import json +import operator import sys +import crypto_docs + def sort_by_name(seq): return sorted(seq, key=lambda x: x['name']) @@ -32,7 +34,7 @@ def main(): if len(sys.argv) < 2: print 'Must supply argument to data file.' sys.exit(1) - data = json.load(open(sys.argv[1])) + data = crypto_docs.load_json(sys.argv[1]) categories = sort_by_name(data['categories']) print '<h2 id="SupportedAlgorithms">Supported Algorithms</h2>' print @@ -42,25 +44,131 @@ def main(): '<code>{name}</code></a></li>'.format(**category)) print '</ul>' for category in categories: - print ''' + if category['name'] == 'Cipher': + # We display ciphers in a four-column table to conserve space and + # so that it's more comprehensible. To do this, we have to + # collapse all our ciphers into "equivalence classes" of a sort. + + # First, collect the relevant data for each algorithm into a tuple. + # The mode and padding are in lists because we are going to collapse + # multiple tuples with those in later steps. + algorithms = sort_by_name(category['algorithms']) + tuples = [] + for algorithm in algorithms: + name, mode, padding = algorithm['name'].split('/') + tuples.append(( + name, + [mode], + [padding], + algorithm['supported_api_levels'], + 'deprecated' in algorithm and algorithm['deprecated'])) + # Sort the tuples by all items except padding, then collapse + # items with all non-padding values the same (which will always be + # neighboring items) into a single item. + tuples.sort(key=operator.itemgetter(0, 1, 3, 4)) + i = 0 + while i < len(tuples) - 1: + if (tuples[i][0] == tuples[i+1][0] + and tuples[i][1] == tuples[i+1][1] + and tuples[i][3] == tuples[i+1][3] + and tuples[i][4] == tuples[i+1][4]): + tuples[i][2].extend(tuples[i+1][2]) + del tuples[i+1] + else: + i += 1 + # Do the same thing as above, but with modes. + tuples.sort(key=operator.itemgetter(0, 2, 3, 4)) + i = 0 + while i < len(tuples) - 1: + if (tuples[i][0] == tuples[i+1][0] + and tuples[i][2] == tuples[i+1][2] + and tuples[i][3] == tuples[i+1][3] + and tuples[i][4] == tuples[i+1][4]): + tuples[i][1].extend(tuples[i+1][1]) + del tuples[i+1] + else: + i += 1 + # Display the table with rowspans for those entries where all the + # items have the same algorithm, mode, etc + print ''' <h3 id="Supported{name}">{name}</h3> <table> <thead> <th>Algorithm</th> + <th>Modes</th> + <th>Paddings</th> <th>Supported API Levels</th> </thead> <tbody>'''.format(**category) - algorithms = sort_by_name(category['algorithms']) - for algorithm in algorithms: - dep_class = '' - if 'deprecated' in algorithm and algorithm['deprecated']: - dep_class = ' class="deprecated"' + tuples.sort(key=operator.itemgetter(0, 4, 1, 2, 3)) + i = 0 + cur_deprecated = None + cur_algorithm = None + cur_mode = None + while i < len(tuples): + row = tuples[i] + if row[4] != cur_deprecated: + cur_deprecated = row[4] + cur_algorithm = None + cur_mode = None + if cur_deprecated: + print ' <tr class="deprecated">' + else: + print ' <tr>' + if row[0] != cur_algorithm: + cur_algorithm = row[0] + cur_mode = None + j = i + 1 + while (j < len(tuples) + and tuples[j][4] == cur_deprecated + and tuples[j][0] == cur_algorithm): + j += 1 + rowspan = j - i + if rowspan > 1: + print ' <td rowspan="%d">%s</td>' % (rowspan, cur_algorithm) + else: + print ' <td>%s</td>' % cur_algorithm + if row[1] != cur_mode: + cur_mode = row[1] + j = i + 1 + while (j < len(tuples) + and tuples[j][4] == cur_deprecated + and tuples[j][0] == cur_algorithm + and tuples[j][1] == cur_mode): + j += 1 + rowspan = j - i + modestring = '<br>'.join(cur_mode) + if rowspan > 1: + print ' <td rowspan="%d">%s</td>' % (rowspan, modestring) + else: + print ' <td>%s</td>' % modestring + print ' <td>%s</td>' % '<br>'.join(row[2]) + print ' <td>%s</td>' % row[3] + print ' </tr>' + i += 1 print ''' + </tbody> +</table>''' + else: + print ''' +<h3 id="Supported{name}">{name}</h3> +<table> + <thead> + <th>Algorithm</th> + <th>Supported API Levels</th> + </thead> + <tbody>'''.format(**category) + algorithms = sort_by_name(category['algorithms']) + for algorithm in algorithms: + dep_class = '' + if 'deprecated' in algorithm and algorithm['deprecated']: + dep_class = ' class="deprecated"' + print ''' <tr{deprecated_class}> <td>{name}</td> <td>{supported_api_levels}</td> </tr>'''.format(deprecated_class=dep_class, **algorithm) - print ''' + print ''' </tbody> </table>''' diff --git a/tools/docs/crypto/update_crypto_support.py b/tools/docs/crypto/update_crypto_support.py index 7d7861f975..8d39cf8638 100755 --- a/tools/docs/crypto/update_crypto_support.py +++ b/tools/docs/crypto/update_crypto_support.py @@ -29,6 +29,8 @@ import datetime import json import sys +import crypto_docs + SUPPORTED_CATEGORIES = [ 'AlgorithmParameterGenerator', 'AlgorithmParameters', @@ -81,6 +83,7 @@ def normalize_name(name): name = name[:-1 * len("/PKCS7PADDING")] + "/PKCS5PADDING" return name + def get_current_data(f): """Returns a map of the algorithms in the given input. @@ -205,15 +208,7 @@ def main(): help='The JSON file to update') args = parser.parse_args() - f = open(args.file) - # JSON doesn't allow comments, but we have some header docs in our file, - # so strip comments out before parsing - stripped_contents = '' - for line in f: - if not line.strip().startswith('#'): - stripped_contents += line - prev_data = json.loads(stripped_contents) - f.close() + prev_data = crypto_docs.load_json(args.file) current_data = get_current_data(sys.stdin) |