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

Side by Side Diff: net/tools/testserver/device_management.py

Issue 12183017: Verify the signature on user cloud policy downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « chrome/common/chrome_paths.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """A bare-bones test server for testing cloud policy support. 5 """A bare-bones test server for testing cloud policy support.
6 6
7 This implements a simple cloud policy test server that can be used to test 7 This implements a simple cloud policy test server that can be used to test
8 chrome's device management service client. The policy information is read from 8 chrome's device management service client. The policy information is read from
9 the file named device_management in the server's data directory. It contains 9 the file named device_management in the server's data directory. It contains
10 enforced and recommended policies for the device and user scope, and a list 10 enforced and recommended policies for the device and user scope, and a list
(...skipping 27 matching lines...) Expand all
38 }, 38 },
39 "google/chromeos/publicaccount/user@example.com" : { 39 "google/chromeos/publicaccount/user@example.com" : {
40 "mandatory" : { 40 "mandatory" : {
41 "HomepageLocation" : "http://www.chromium.org" 41 "HomepageLocation" : "http://www.chromium.org"
42 }, 42 },
43 "recommended" : { 43 "recommended" : {
44 } 44 }
45 }, 45 },
46 "managed_users" : [ 46 "managed_users" : [
47 "secret123456" 47 "secret123456"
48 ] 48 ],
49 "current_key_index": 0
49 } 50 }
50 51
51 """ 52 """
52 53
53 import cgi 54 import cgi
54 import hashlib 55 import hashlib
55 import logging 56 import logging
56 import os 57 import os
57 import random 58 import random
58 import re 59 import re
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 if msg.policy_type in token_info['allowed_policy_types']: 449 if msg.policy_type in token_info['allowed_policy_types']:
449 if (msg.policy_type == 'google/chromeos/user' or 450 if (msg.policy_type == 'google/chromeos/user' or
450 msg.policy_type == 'google/chrome/user' or 451 msg.policy_type == 'google/chrome/user' or
451 msg.policy_type == 'google/chromeos/publicaccount'): 452 msg.policy_type == 'google/chromeos/publicaccount'):
452 settings = cp.CloudPolicySettings() 453 settings = cp.CloudPolicySettings()
453 self.GatherUserPolicySettings(settings, policy.get(policy_key, {})) 454 self.GatherUserPolicySettings(settings, policy.get(policy_key, {}))
454 elif msg.policy_type == 'google/chromeos/device': 455 elif msg.policy_type == 'google/chromeos/device':
455 settings = dp.ChromeDeviceSettingsProto() 456 settings = dp.ChromeDeviceSettingsProto()
456 self.GatherDevicePolicySettings(settings, policy.get(policy_key, {})) 457 self.GatherDevicePolicySettings(settings, policy.get(policy_key, {}))
457 458
458 # Figure out the key we want to use. If multiple keys are configured, the 459 # Sign with 'current_key_index', defaulting to key 0.
459 # server will rotate through them in a round-robin fashion.
460 signing_key = None 460 signing_key = None
461 req_key = None 461 req_key = None
462 key_version = 1 462 current_key_index = policy.get('current_key_index', 0)
463 nkeys = len(self._server.keys) 463 nkeys = len(self._server.keys)
464 if msg.signature_type == dm.PolicyFetchRequest.SHA1_RSA and nkeys > 0: 464 if (msg.signature_type == dm.PolicyFetchRequest.SHA1_RSA and
465 current_key_index in range(nkeys)):
466 signing_key = self._server.keys[current_key_index]
465 if msg.public_key_version in range(1, nkeys + 1): 467 if msg.public_key_version in range(1, nkeys + 1):
466 # requested key exists, use for signing and rotate. 468 # requested key exists, use for signing and rotate.
467 req_key = self._server.keys[msg.public_key_version - 1]['private_key'] 469 req_key = self._server.keys[msg.public_key_version - 1]['private_key']
468 key_version = (msg.public_key_version % nkeys) + 1
469 signing_key = self._server.keys[key_version - 1]
470 470
471 # Fill the policy data protobuf. 471 # Fill the policy data protobuf.
472 policy_data = dm.PolicyData() 472 policy_data = dm.PolicyData()
473 policy_data.policy_type = msg.policy_type 473 policy_data.policy_type = msg.policy_type
474 policy_data.timestamp = int(time.time() * 1000) 474 policy_data.timestamp = int(time.time() * 1000)
475 policy_data.request_token = token_info['device_token'] 475 policy_data.request_token = token_info['device_token']
476 policy_data.policy_value = settings.SerializeToString() 476 policy_data.policy_value = settings.SerializeToString()
477 policy_data.machine_name = token_info['machine_name'] 477 policy_data.machine_name = token_info['machine_name']
478 policy_data.valid_serial_number_missing = ( 478 policy_data.valid_serial_number_missing = (
479 token_info['machine_id'] in BAD_MACHINE_IDS) 479 token_info['machine_id'] in BAD_MACHINE_IDS)
480 policy_data.settings_entity_id = msg.settings_entity_id 480 policy_data.settings_entity_id = msg.settings_entity_id
481 481
482 if signing_key: 482 if signing_key:
483 policy_data.public_key_version = key_version 483 policy_data.public_key_version = current_key_index + 1
484 if msg.policy_type == 'google/chromeos/publicaccount': 484 if msg.policy_type == 'google/chromeos/publicaccount':
485 policy_data.username = msg.settings_entity_id 485 policy_data.username = msg.settings_entity_id
486 else: 486 else:
487 # For regular user/device policy, there is no way for the testserver to 487 # For regular user/device policy, there is no way for the testserver to
488 # know the user name belonging to the GAIA auth token we received (short 488 # know the user name belonging to the GAIA auth token we received (short
489 # of actually talking to GAIA). To address this, we read the username from 489 # of actually talking to GAIA). To address this, we read the username from
490 # the policy configuration dictionary, or use a default. 490 # the policy configuration dictionary, or use a default.
491 policy_data.username = policy.get('policy_user', 'user@example.com') 491 policy_data.username = policy.get('policy_user', 'user@example.com')
492 policy_data.device_id = token_info['device_id'] 492 policy_data.device_id = token_info['device_id']
493 signed_data = policy_data.SerializeToString() 493 signed_data = policy_data.SerializeToString()
494 494
495 response = dm.DeviceManagementResponse() 495 response = dm.DeviceManagementResponse()
496 fetch_response = response.policy_response.response.add() 496 fetch_response = response.policy_response.response.add()
497 fetch_response.policy_data = signed_data 497 fetch_response.policy_data = signed_data
498 if signing_key: 498 if signing_key:
499 fetch_response.policy_data_signature = ( 499 fetch_response.policy_data_signature = (
500 signing_key['private_key'].hashAndSign(signed_data).tostring()) 500 signing_key['private_key'].hashAndSign(signed_data).tostring())
501 if msg.public_key_version != key_version: 501 if msg.public_key_version != current_key_index + 1:
502 fetch_response.new_public_key = signing_key['public_key'] 502 fetch_response.new_public_key = signing_key['public_key']
503 if req_key: 503 if req_key:
504 fetch_response.new_public_key_signature = ( 504 fetch_response.new_public_key_signature = (
505 req_key.hashAndSign(fetch_response.new_public_key).tostring()) 505 req_key.hashAndSign(fetch_response.new_public_key).tostring())
506 506
507 self.DumpMessage('Response', response) 507 self.DumpMessage('Response', response)
508 508
509 return (200, response.SerializeToString()) 509 return (200, response.SerializeToString())
510 510
511 def CheckToken(self): 511 def CheckToken(self):
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 for key_path in private_key_paths: 565 for key_path in private_key_paths:
566 try: 566 try:
567 key = tlslite.api.parsePEMKey(open(key_path).read(), private=True) 567 key = tlslite.api.parsePEMKey(open(key_path).read(), private=True)
568 except IOError: 568 except IOError:
569 print 'Failed to load private key from %s' % key_path 569 print 'Failed to load private key from %s' % key_path
570 continue 570 continue
571 571
572 assert key is not None 572 assert key is not None
573 self.keys.append({ 'private_key' : key }) 573 self.keys.append({ 'private_key' : key })
574 else: 574 else:
575 # Generate a key if none were specified. 575 # Generate 2 private keys if none were passed from the command line.
576 key = tlslite.api.generateRSAKey(1024) 576 for i in range(2):
577 assert key is not None 577 key = tlslite.api.generateRSAKey(512)
578 self.keys.append({ 'private_key' : key }) 578 assert key is not None
579 self.keys.append({ 'private_key' : key })
579 580
580 # Derive the public keys from the loaded private keys. 581 # Derive the public keys from the private keys.
581 for entry in self.keys: 582 for entry in self.keys:
582 key = entry['private_key'] 583 key = entry['private_key']
583 584
584 algorithm = asn1der.Sequence( 585 algorithm = asn1der.Sequence(
585 [ asn1der.Data(asn1der.OBJECT_IDENTIFIER, PKCS1_RSA_OID), 586 [ asn1der.Data(asn1der.OBJECT_IDENTIFIER, PKCS1_RSA_OID),
586 asn1der.Data(asn1der.NULL, '') ]) 587 asn1der.Data(asn1der.NULL, '') ])
587 rsa_pubkey = asn1der.Sequence([ asn1der.Integer(key.n), 588 rsa_pubkey = asn1der.Sequence([ asn1der.Integer(key.n),
588 asn1der.Integer(key.e) ]) 589 asn1der.Integer(key.e) ])
589 pubkey = asn1der.Sequence([ algorithm, asn1der.Bitstring(rsa_pubkey) ]) 590 pubkey = asn1der.Sequence([ algorithm, asn1der.Bitstring(rsa_pubkey) ])
590 entry['public_key'] = pubkey; 591 entry['public_key'] = pubkey;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 return self._registered_tokens.get(dmtoken, None) 677 return self._registered_tokens.get(dmtoken, None)
677 678
678 def UnregisterDevice(self, dmtoken): 679 def UnregisterDevice(self, dmtoken):
679 """Unregisters a device identified by the given DM token. 680 """Unregisters a device identified by the given DM token.
680 681
681 Args: 682 Args:
682 dmtoken: The device management token provided by the client. 683 dmtoken: The device management token provided by the client.
683 """ 684 """
684 if dmtoken in self._registered_tokens.keys(): 685 if dmtoken in self._registered_tokens.keys():
685 del self._registered_tokens[dmtoken] 686 del self._registered_tokens[dmtoken]
OLDNEW
« no previous file with comments | « chrome/common/chrome_paths.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698