OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2015 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2016 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 # TODO(svaldez): Deduplicate various annotate_test_data. |
5 | 6 |
6 """This script is called without any arguments to re-format all of the *.pem | 7 """This script is called without any arguments to re-format all of the *.pem |
7 files in the script's parent directory. | 8 files in the script's parent directory. |
8 | 9 |
9 The main formatting change is to run "openssl asn1parse" for each of the PEM | 10 The main formatting change is to run "openssl asn1parse" for each of the PEM |
10 block sections (except for DATA), and add that output to the comment. | 11 block sections, and add that output to the comment. It also runs the command |
| 12 on the OCTET STRING representing BasicOCSPResponse. |
11 | 13 |
12 Refer to the README file for more information. | |
13 """ | 14 """ |
14 | 15 |
15 import glob | 16 import glob |
16 import os | 17 import os |
17 import re | 18 import re |
18 import base64 | 19 import base64 |
19 import subprocess | 20 import subprocess |
20 | 21 |
21 | 22 |
22 def Transform(file_data): | 23 def Transform(file_data): |
23 """Returns a transformed (formatted) version of file_data""" | 24 """Returns a transformed (formatted) version of file_data""" |
24 | 25 |
25 result = '' | 26 result = '' |
26 | 27 |
27 for block in GetPemBlocks(file_data): | 28 for block in GetPemBlocks(file_data): |
28 if len(result) != 0: | 29 if len(result) != 0: |
29 result += '\n' | 30 result += '\n' |
30 | 31 |
31 # If there was a user comment (non-script-generated comment) associated | 32 # If there was a user comment (non-script-generated comment) associated |
32 # with the block, output it immediately before the block. | 33 # with the block, output it immediately before the block. |
33 user_comment = GetUserComment(block.comment) | 34 user_comment = GetUserComment(block.comment) |
34 if user_comment: | 35 if user_comment: |
35 result += user_comment | 36 result += user_comment + '\n' |
36 | 37 |
37 # For every block except for DATA, try to pretty print the parsed ASN.1. | 38 generated_comment = GenerateCommentForBlock(block.name, block.data) |
38 # DATA blocks likely would be DER in practice, but for the purposes of | 39 result += generated_comment + '\n' |
39 # these tests seeing its structure doesn't clarify | |
40 # anything and is just a distraction. | |
41 if block.name != 'DATA': | |
42 generated_comment = GenerateCommentForBlock(block.name, block.data) | |
43 result += generated_comment + '\n' | |
44 | 40 |
45 | 41 |
46 result += MakePemBlockString(block.name, block.data) | 42 result += MakePemBlockString(block.name, block.data) |
47 | 43 |
48 return result | 44 return result |
49 | 45 |
50 | 46 |
51 def GenerateCommentForBlock(block_name, block_data): | 47 def GenerateCommentForBlock(block_name, block_data): |
52 """Returns a string describing the ASN.1 structure of block_data""" | 48 """Returns a string describing the ASN.1 structure of block_data""" |
53 | 49 |
54 p = subprocess.Popen(['openssl', 'asn1parse', '-i', '-inform', 'DER'], | 50 p = subprocess.Popen(['openssl', 'asn1parse', '-i', '-inform', 'DER'], |
55 stdout=subprocess.PIPE, stdin=subprocess.PIPE, | 51 stdout=subprocess.PIPE, stdin=subprocess.PIPE, |
56 stderr=subprocess.PIPE) | 52 stderr=subprocess.PIPE) |
57 stdout_data, stderr_data = p.communicate(input=block_data) | 53 stdout_data, stderr_data = p.communicate(input=block_data) |
58 generated_comment = '$ openssl asn1parse -i < [%s]\n%s' % (block_name, | 54 generated_comment = '$ openssl asn1parse -i < [%s]\n%s' % (block_name, |
59 stdout_data) | 55 stdout_data) |
| 56 |
| 57 # The OCTET STRING encoded BasicOCSPResponse is also parsed out using |
| 58 #'openssl asn1parse'. |
| 59 if block_name == 'OCSP RESPONSE': |
| 60 if '[HEX DUMP]:' in generated_comment: |
| 61 (generated_comment, response) = generated_comment.split('[HEX DUMP]:', 1) |
| 62 response = response.replace('\n', '') |
| 63 if len(response) % 2 != 0: |
| 64 response = '0' + response |
| 65 response = GenerateCommentForBlock('INNER', response.decode('hex')) |
| 66 response = response.split('\n', 1)[1] |
| 67 response = response.replace(': ', ': ') |
| 68 generated_comment += '\n%s' % (response) |
60 return generated_comment.strip('\n') | 69 return generated_comment.strip('\n') |
61 | 70 |
62 | 71 |
63 | 72 |
64 def GetUserComment(comment): | 73 def GetUserComment(comment): |
65 """Removes any script-generated lines (everything after the $ openssl line)""" | 74 """Removes any script-generated lines (everything after the $ openssl line)""" |
66 | 75 |
67 # Consider everything after "$ openssl" to be a generated comment. | 76 # Consider everything after "$ openssl" to be a generated comment. |
68 comment = comment.split('$ openssl asn1parse -i', 1)[0] | 77 comment = comment.split('$ openssl asn1parse -i', 1)[0] |
69 if IsEntirelyWhiteSpace(comment): | 78 if IsEntirelyWhiteSpace(comment): |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 print "Processing %s ..." % (path) | 164 print "Processing %s ..." % (path) |
156 original_data = ReadFileToString(path) | 165 original_data = ReadFileToString(path) |
157 transformed_data = Transform(original_data) | 166 transformed_data = Transform(original_data) |
158 if original_data != transformed_data: | 167 if original_data != transformed_data: |
159 WriteStringToFile(transformed_data, path) | 168 WriteStringToFile(transformed_data, path) |
160 print "Rewrote %s" % (path) | 169 print "Rewrote %s" % (path) |
161 | 170 |
162 | 171 |
163 if __name__ == "__main__": | 172 if __name__ == "__main__": |
164 main() | 173 main() |
OLD | NEW |