Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1428)

Side by Side Diff: tools/origin_trials/generate_token.py

Issue 2456053004: Validate origins when generating subdomain tokens (Closed)
Patch Set: Rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2016 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 5
6 """Utility for generating experimental API tokens 6 """Utility for generating experimental API tokens
7 7
8 usage: generate_token.py [-h] [--key-file KEY_FILE] 8 usage: generate_token.py [-h] [--key-file KEY_FILE]
9 [--expire-days EXPIRE_DAYS | 9 [--expire-days EXPIRE_DAYS |
10 --expire-timestamp EXPIRE_TIMESTAMP] 10 --expire-timestamp EXPIRE_TIMESTAMP]
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 if not port: 79 if not port:
80 port = {"https": 443, "http": 80}[origin.scheme] 80 port = {"https": 443, "http": 80}[origin.scheme]
81 # Strip any extra components and return the origin URL: 81 # Strip any extra components and return the origin URL:
82 return "{0}://{1}:{2}".format(origin.scheme, origin.hostname, port) 82 return "{0}://{1}:{2}".format(origin.scheme, origin.hostname, port)
83 83
84 def ExpiryFromArgs(args): 84 def ExpiryFromArgs(args):
85 if args.expire_timestamp: 85 if args.expire_timestamp:
86 return int(args.expire_timestamp) 86 return int(args.expire_timestamp)
87 return (int(time.time()) + (int(args.expire_days) * 86400)) 87 return (int(time.time()) + (int(args.expire_days) * 86400))
88 88
89 def ValidateSubdomainTokenOrigin(origin):
90 """ Calls validate_subdomain_origin utility to check the origin
91
92 If the utility is not found, prints a warning for manual validation, and
93 returns True
94 """
95 utility_path = "bin/validate_subdomain_origin"
iclelland 2016/11/02 15:25:47 How does this utility end up in a bin/ directory?
chasej 2016/11/03 19:23:39 I forgot to add instructions, but I just used a sy
96 if not os.path.exists(utility_path):
97 print "WARNING!"
98 print "Origin not validated for use in subdomain token"
99 print " (missing '%s' utility)" % utility_path
100 print "Must manually check origin against the Public Suffix List"
101 print
102 return True
103
104 rc = os.system("%s %s >/dev/null 2>&1" % (utility_path, origin))
105 return rc == 0
iclelland 2016/11/02 15:25:47 It is also possible for other non-zero status to b
chasej 2016/11/03 19:23:39 Done.
106
89 def GenerateTokenData(origin, is_subdomain, feature_name, expiry): 107 def GenerateTokenData(origin, is_subdomain, feature_name, expiry):
90 data = {"origin": origin, 108 data = {"origin": origin,
91 "feature": feature_name, 109 "feature": feature_name,
92 "expiry": expiry} 110 "expiry": expiry}
93 if is_subdomain is not None: 111 if is_subdomain is not None:
94 data["isSubdomain"] = is_subdomain 112 data["isSubdomain"] = is_subdomain
95 return json.dumps(data).encode('utf-8') 113 return json.dumps(data).encode('utf-8')
96 114
97 def GenerateDataToSign(version, data): 115 def GenerateDataToSign(version, data):
98 return version + struct.pack(">I",len(data)) + data 116 return version + struct.pack(">I",len(data)) + data
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 private_key = key_file.read(64) 170 private_key = key_file.read(64)
153 171
154 # Validate that the key file read was a proper Ed25519 key -- running the 172 # Validate that the key file read was a proper Ed25519 key -- running the
155 # publickey method on the first half of the key should return the second 173 # publickey method on the first half of the key should return the second
156 # half. 174 # half.
157 if (len(private_key) < 64 or 175 if (len(private_key) < 64 or
158 ed25519.publickey(private_key[:32]) != private_key[32:]): 176 ed25519.publickey(private_key[:32]) != private_key[32:]):
159 print("Unable to use the specified private key file.") 177 print("Unable to use the specified private key file.")
160 sys.exit(1) 178 sys.exit(1)
161 179
180 # For subdomain tokens, validate that the origin is allowed
181 if args.is_subdomain:
182 if not ValidateSubdomainTokenOrigin(args.origin):
183 print "The specified origin is not valid for use in a subdomain token."
184 sys.exit(1)
185
162 token_data = GenerateTokenData(args.origin, args.is_subdomain, 186 token_data = GenerateTokenData(args.origin, args.is_subdomain,
163 args.trial_name, expiry) 187 args.trial_name, expiry)
164 data_to_sign = GenerateDataToSign(VERSION, token_data) 188 data_to_sign = GenerateDataToSign(VERSION, token_data)
165 signature = Sign(private_key, data_to_sign) 189 signature = Sign(private_key, data_to_sign)
166 190
167 # Verify that that the signature is correct before printing it. 191 # Verify that that the signature is correct before printing it.
168 try: 192 try:
169 ed25519.checkvalid(signature, data_to_sign, private_key[32:]) 193 ed25519.checkvalid(signature, data_to_sign, private_key[32:])
170 except Exception, exc: 194 except Exception, exc:
171 print "There was an error generating the signature." 195 print "There was an error generating the signature."
172 print "(The original error was: %s)" % exc 196 print "(The original error was: %s)" % exc
173 sys.exit(1) 197 sys.exit(1)
174 198
175 199
176 # Output the token details 200 # Output the token details
177 print "Token details:" 201 print "Token details:"
178 print " Origin: %s" % args.origin 202 print " Origin: %s" % args.origin
179 print " Is Subdomain: %s" % args.is_subdomain 203 print " Is Subdomain: %s" % args.is_subdomain
180 print " Feature: %s" % args.trial_name 204 print " Feature: %s" % args.trial_name
181 print " Expiry: %d (%s UTC)" % (expiry, datetime.utcfromtimestamp(expiry)) 205 print " Expiry: %d (%s UTC)" % (expiry, datetime.utcfromtimestamp(expiry))
182 print 206 print
183 207
184 # Output the properly-formatted token. 208 # Output the properly-formatted token.
185 print FormatToken(VERSION, signature, token_data) 209 print FormatToken(VERSION, signature, token_data)
186 210
187 if __name__ == "__main__": 211 if __name__ == "__main__":
188 main() 212 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698