| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import base64 |
| import json |
| import logging |
| import os.path |
| import tempfile |
| |
| import common |
| from autotest_lib.client.bin import test |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.common_lib import utils |
| |
| # This modifies the include path to include the shill test-scripts. |
| # pylint: disable=W0611 |
| from autotest_lib.client.cros import flimflam_test_path |
| # pylint: enable=W0611 |
| import crypto_util_pb2 |
| |
| |
| TEST_DATA1 = """{ |
| "connected":false, |
| "debug_build":true, |
| "has_update":false, |
| "hotspot_bssid":"00:1A:11:FF:AC:DF", |
| "locale":"en_US", |
| "location": { |
| "latitude":37.4193105, |
| "longitude":-122.07878869999999 |
| }, |
| "mac_address":"4C:AA:16:A5:AC:DF", |
| "name":"eureka8997", |
| "public_key":"MIGJAoGBAK3SXmWZBOhJibv8It05qIbgHXXhnCXxHkW+C6jNMHR5sZgDpFaOY1xwXERjKdJxcwrEy3VAT5Uv9MgHPBvxxJku76HYh1yVfIw1rhLnHBTHSxwUzJNCrgc3l3t/UACacLjVNIzccDpYf2vnOcA+t1t6IXRjzuU2NdwY4dJXNtWPAgMBAAE=", |
| "setup_state":11, |
| "sign": { |
| "certificate":"-----BEGIN CERTIFICATE-----\\nMIIDhzCCAm8CBFE2SCMwDQYJKoZIhvcNAQEFBQAwfTELMAkGA1UEBhMCVVMxEzAR\\nBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEzARBgNV\\nBAoMCkdvb2dsZSBJbmMxEjAQBgNVBAsMCUdvb2dsZSBUVjEYMBYGA1UEAwwPRXVy\\nZWthIEdlbjEgSUNBMB4XDTEzMDMwNTE5MzE0N1oXDTMzMDIyODE5MzE0N1owgYMx\\nFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEjAQBgNVBAsTCUdvb2dsZSBUVjETMBEG\\nA1UEChMKR29vZ2xlIEluYzETMBEGA1UECBMKQ2FsaWZvcm5pYTELMAkGA1UEBhMC\\nVVMxHjAcBgNVBAMUFWV2dF9lMTYxIDAwMWExMWZmYWNkZjCCASIwDQYJKoZIhvcN\\nAQEBBQADggEPADCCAQoCggEBAPHGDV0lLoTYK78q13y/2u77YTjgbBlWAOxgrSNc\\nMmGHx1K0aPyo50p99dGQnjapW6jtGrMzReWV2Wz3VL8rYlqY7oWjeJwsLQwo2tcn\\n7vIZ/PuvPz9xgnGMUbBOfhCf3Epb1N4Jz82pxxrOFhUawWAglC9C4fUeZLCZpOJs\\nQd4QeAznkydl3xbqdSm74kwxE6vkGEzSCDnC7aYx0Rvvr1mZOKdl4AinYrxzWgmV\\nsTnaFT1soSjmC5e/i6Jcrs4dDFgY6mKy9Qtly2XPSCYljm6L4SgqgJNmlpY0qYJg\\nO++BdofIbU2jsOiCMvIuKkbMn72NsPQG0QhnVMwk7kYg6kkCAwEAAaMNMAswCQYD\\nVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAW0bQl9yjBc7DgMp94i7ZDOUxKQrz\\nthephuwzb3/wWiTHcw6KK6FRPefXn6NPWxKKeQmv/tBxHbVlmYRXUbrhksnD0aUk\\ni4InvtL2m0H1fPfMxmJRFE+HoSXu+s0sGON831JaMcYRbAku5uHnltaGNzOI0KPH\\nFGoCDmjAZD+IuoR2LR4FuuTrECK7KLjkdf//z5d5j7nBDPZS7uTCwC/BwM9asRj3\\ntJA5VRFbLbsit1VI7IaRCk9rsSKkpBUaVeKbPLz+y/Z6JonXXT6AxsfgUSKDd4B7\\nMYLrTwMQfGuUaaaKko6ldKIrovjrcPloQr1Hxb2bipFcjLmG7nxQLoS6vQ==\\n-----END CERTIFICATE-----\\n", |
| "nonce":"+6KSGuRu833m1+TP", |
| "signed_data":"vwMBgANrp5XpCswLyk/OTXT56ORPeIWjH7xAdCk3qgjkwI6+8o56zJS02+tC5hhIHWh7oppTmWYF4tKvBQ3GeCz7IW9f7HWDMtO7x7yRWxzJyehaJbCfXvLdfs0/WKllzvGVBgNpcIAwU2NSFUG/jpXclntFzds0EUJG9wHxS6PXXSYRu+PlIFdCDcQJsUlnwO9AGFOJRV/aARGh8YUTWCFIQPOtPEqT5eegt+TLf01Gq0YcrRwSTKy1I3twOnWiMfIdkJdQKPtBwwbvuAyGuqYFocfjKABbnH9Tvl04yyO3euKbYlSqaF/l8CXmzDJTyO7tDOFK59bV9auE4KljrQ==" |
| }, |
| "ssdp_udn":"c5b2a83b-5958-7ce6-b179-e1f44699429b", |
| "ssid":"", |
| "timezone":"America/Los_Angeles", |
| "uptime":1991.7, |
| "version":4, |
| "wpa_configured":false, |
| "wpa_state":1 |
| } """ |
| TEST_DATA2 = """{ |
| "connected": false, |
| "debug_build": true, |
| "has_update": false, |
| "hotspot_bssid": "00:1A:11:FF:AC:1E", |
| "ip_address": "192.168.43.32", |
| "locale": "en_US", |
| "mac_address": "B0:EE:45:49:AC:1E", |
| "name": "Greg's Eureka", |
| "noise_level": -85, |
| "public_key": "MIGJAoGBAOe+6bF51A7wFVMbyPiHYLdgAmP6sdhOUohqCHn4qHSfDY41AbAbVmXLbUZ5BF2KSdDYqU4fAXoaI8V8D5DRWh57Ax10Sl1/6M1u22KT6FYQyUToXGPcXldBzRRMok8H4XyiebDVevjvvV6yuABSYYhfSlrMdGj8qxRVwTxx0CItAgMBAAE=", |
| "release_track": "beta-channel", |
| "setup_state": 50, |
| "sign": { |
| "certificate": "-----BEGIN CERTIFICATE-----\\nMIIDejCCAmICBFEtN4wwDQYJKoZIhvcNAQEFBQAwfTELMAkGA1UEBhMCVVMxEzAR\\nBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEzARBgNV\\nBAoMCkdvb2dsZSBJbmMxEjAQBgNVBAsMCUdvb2dsZSBUVjEYMBYGA1UEAwwPRXVy\\nZWthIEdlbjEgSUNBMB4XDTEzMDIyNjIyMzAzNloXDTMzMDIyMTIyMzAzNlowdzET\\nMBEGA1UECBMKQ2FsaWZvcm5pYTELMAkGA1UEBhMCVVMxFjAUBgNVBAcTDU1vdW50\\nYWluIFZpZXcxEjAQBgNVBAsTCUdvb2dsZSBUVjETMBEGA1UEChMKR29vZ2xlIElu\\nYzESMBAGA1UEAxQJZXZ0X2UxMjYyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\\nCgKCAQEAo7Uu+bdyCjtiUYpmNU4ZvRjDg6VkEh/g0YPDG2pICBU4XKvsqHH1i0hb\\ntWp1J79hV9Rqst1yHT02Oeh3o1SOd2zeamYzmvXRVN7AZqfQlzWxwxk/ltpXGwew\\nm+EIR2bP4kpvyEKvvziTMtTxviOK+A395QyodMhMXClKTus/Gme2r1fBoQqJJR/z\\nrmwXCsl5kpdhj7FOIII3BCYV0zejjQquzywjsKfCVON28VGgJdaKgmXxkeRYYWVN\\nnuTNna57vXe16FP6hS1ty1U77ESffLTpNJ/M4tsd2dMVVTDuGeX3q8Ix4TN8cqpq\\nu1AKEf59hygys9j6cHZRKR/div0+uQIDAQABow0wCzAJBgNVHRMEAjAAMA0GCSqG\\nSIb3DQEBBQUAA4IBAQAZx6XyEK9SLHE+rbKCVsLN9+hTEa50aikPmxOZt+lFuB4+\\nVJZ/GCPQCZJIde2tlWUe2YBgoZw2xUKgIsM3Yq42Gawi35/oZ3qycTgYU8KJP9kU\\nMbYNAH90mz9BDH7MmnRID5dFexHyBCG88EJ+ZvxmUVn0EVDcsSMt11wIAZ/T+/gs\\nE1120d/GxhjYQ9YZz7SZXBQfRdqCdcPNl2+QSHHl+WvYLzdJa2xYj39/kQu47Vp7\\nX5rZrHSBvzdVymH0Od2D18t+Q6lxbSdyUNhP1MVhdkT1Ct4OmRS3FJ4aannXMhfq\\nNg7k4Sfif5iktYT4VRKpThe0EGJNfqKJKYtvHEVC\\n-----END CERTIFICATE-----\\n", |
| "nonce": "pTwRhdsB5cb3Ev8o", |
| "signed_data": "WIvN6Ujo4CoxUNcsm1YaLRUe1KJVEG+oXorUBJae/fKQrLfnH9ChDfxzW+EDZlLBLPk9u5EAptr8LKK6AunbBTDIeBkjzXv3nS+xlmV9ZdA71imitva88HPzC+a2H61dJL8puNbZu9j1Zs3sCybw2F+qZbDBhbG0sJTEXytPjewqAl8iBZSAS0BoNJZYA7Q/bCPI07pg404pI392cKP8FYJR08Y4xoV94Em+jnZ2nZabSsmsScYGvpWVNeS2z+f0to6ureOxaqgT+AAckqtCRcHd66QtLGwKXWviaevKte1z185f4r55U4P5pkQi+xd6lZRsMQydwUzLxgk7UY5U3Q==" |
| }, |
| "signal_level": -42, |
| "ssdp_udn": "cd7c1f15-2f49-076b-51ac-9d651872c784", |
| "ssid": "Greg's Phone", |
| "timezone": "America/Los_Angeles", |
| "uptime": 207.33, |
| "version": 4, |
| "wpa_configured": true, |
| "wpa_id": 0, |
| "wpa_state": 10 |
| } |
| """ |
| TEST_DATA3 = """{ |
| "build_version":"10566", |
| "connected":false, |
| "has_update":false, |
| "hotspot_bssid":"FA:8F:CA:30:08:26", |
| "locale":"en_US", |
| "mac_address":"B0:EE:45:68:B5:52", |
| "name":"Chromekey Greg", |
| "public_key":"MIIBCgKCAQEApQoxFRJWEP9Oa+lSF2PCMBCpd2LYeyPMHjVKCF2IlrGbrgQ3U9wI6tBvLkHg570KSA6onL/7e9J31RLwA8gIE0zJ9M7NToxj1cVa8jOqXPIllJP7uY/TmtMIwCvuMCu6KBNW/wzKK6jkT7wScwrPJscmwWr/0h6lKXZrv0DhwvVv3i6VGsasZzVYlOoZ7eRe1OHiJgehPFUh0Vp7lVRDzumtJ0N6hybWP/Ap6dNlcO9Hq67bljHRrgwuBT2iRJBIdZt6m4xZlf78dH6Y2gfeQ3GBtDZWbZ5v6hzaYeIxlMTelz6ZlEQa0fPegK1dsxCddvLhRCDQr2bZlwyRdof6uwIDAQAB", |
| "release_track":"beta-channel", |
| "setup_state":11, |
| "sign": { |
| "certificate": "-----BEGIN CERTIFICATE-----\\nMIIDpjCCAo4CBFFfTz8wDQYJKoZIhvcNAQEFBQAwfTELMAkGA1UEBhMCVVMxEzAR\\nBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEzARBgNV\\nBAoMCkdvb2dsZSBJbmMxEjAQBgNVBAsMCUdvb2dsZSBUVjEYMBYGA1UEAwwPRXVy\\nZWthIEdlbjEgSUNBMB4XDTEzMDQwNTIyMjUwM1oXDTMzMDMzMTIyMjUwM1owgYAx\\nCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRMwEQYDVQQKEwpHb29n\\nbGUgSW5jMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRIwEAYDVQQLEwlHb29nbGUg\\nVFYxGzAZBgNVBAMTElpaQUlNIEZBOEZDQTMwMDgyNjCCASIwDQYJKoZIhvcNAQEB\\nBQADggEPADCCAQoCggEBALmAGRcIQt/k7WfoUHDCWQhzQ/FrHDnNiHcVj09Tyu7/\\n2pIB+pVnLac8pfFwdVAcDG4xmjnROIHeajz627uq8bHEVDfPCHe8WiM+CsPrMC85\\nlQOq8rBwNw3WO82suvWL8wjdqFy0uQHajp9e9ix3FXzfZDAuf7ABHmVZnPMWQz0a\\nR3zDCCF2NhEVhBwq+IGKNNvuIPhVF/5tkdWPmihFukJabmV2kjFUuPbEf4T1OMu+\\nhyqZ+lsTc/XVIqICRIq9ZE36MquAw0g9Hoah8OFFpkq2xJqlCY+HKvdhiA1HybfY\\nXSxOsI2rTQk3YHFMrAGMu16UYuOA+CRHD+UC8SI0fqkCAwEAAaMvMC0wCQYDVR0T\\nBAIwADALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcN\\nAQEFBQADggEBAJGyWBoDvwZBlDcyX31l5kwGVf6nVZR4KedcQMGpm76C6fgzeLHt\\nAq7OQhZgifFVLvzG7kqYgRRsW7WQKTF/QmHn8rnCdY16YtZv3vFzLbdBWkmSqAxD\\nqmBum9oD74AYeJaR0v68KCGvAVG0juRSs3H93s8k/fhY+LespUMlHwB4DwRYxDNP\\nIu3HX8NEmOBwjodKDDa8yu1weYUf8GFXH3b+tu7IHRzQpPzbSSibs+AXc8WbJWk3\\nrtQSugqegiiM/OAdRuSvkXtc1DJP9F7OLsVpF9i/VZ2k/QDPCu06vXB2w3wlRyR3\\nf6nQGB1Ej8Klsxlo8B+rmQ6N8C7f48GMI8s=\\n-----END CERTIFICATE-----\\n", |
| "nonce": "E1oqNODwWVIfSjUs", |
| "signed_data": "aaT56/P7KiMxVbWCedpSNIikpxh0EzdjgEuP153pCNfYys2KmlVtvEnXeFGYKJP2ypsX0qx/9Bx2C18T8HZ4PvNW0fUEheScvkzbDTn/gBpwUJv3XT+55XneUdjIAQu83qNR/AjxYa9cDGzxbnZJL91Fd1Grw/fNaKEMiedWRiESABQREiS2OW+iZ3Z/JRs99o4M6m+6f/mvNkgZ3GrFxNnPEXe7g1sYjspPhnDLvASNzd9j24YIxu+PTWZCNL6clps+/ghNA/0fB3PBDILrcGnER36Vc8gNhjD1r1f/ACU1qk06yMNC/Kgt2pMQkpjaXby+B75Z9yrogNHs4f5tIA==" |
| }, |
| "ssdp_udn":"b91027b5-f19e-7df6-6533-5056ad190575", |
| "ssid":"Greg's Phone", |
| "uptime":262650.75, |
| "version":4, |
| "wpa_configured":false, |
| "wpa_id":0, |
| "wpa_state":1 |
| }""" |
| # This is just a DER formatted public key with the first 22 bytes stripped. |
| # Technically, this is called RSAPublicKey format. |
| ENCRYPTION_PUBLIC_KEY = ( |
| '0\x81\x89\x02\x81\x81\x00\xd4\xe3z\x82\x0b6D\x8a\x1dY' |
| '\x1d\xdel\xbf\xad,\r\x8b\xefm\xe3\xbd\xef<\x954\x96C<' |
| '\x9e\x7fB\xef\xe8&h\xfb\xc4Z\x0e\x196C\x1d\xd7f\x88\\5' |
| '\xd5\x1e\xb8\xe0\x8d\xc4\xbc\xd1\xb3\xc4\xd3)!7\xd2{' |
| '\x11\x89\t\xfb\x8d\xe8\xbaRL\xacI\xf2\x0f.JB\x8e\xd4' |
| '\xdc\xc2\x81v6\x8a\x154\xbe8\xfc\xa8\x84zH\xf0j\x87(' |
| '\xcf\x142B\xcfV\xd0\n\xbbPW\x80d\xd2\x0e\xf1\x1a\x04' |
| '\x0b\xa8U=\x8f3\x85\xcd\x02\x03\x01\x00\x01' |
| ) |
| # This is the matching private key. Note that the public key is |
| # a subset of this information should you need it for debugging. |
| ENCRYPTION_PRIVATE_KEY = """ |
| -----BEGIN RSA PRIVATE KEY----- |
| MIICXQIBAAKBgQDU43qCCzZEih1ZHd5sv60sDYvvbeO97zyVNJZDPJ5/Qu/oJmj7 |
| xFoOGTZDHddmiFw11R644I3EvNGzxNMpITfSexGJCfuN6LpSTKxJ8g8uSkKO1NzC |
| gXY2ihU0vjj8qIR6SPBqhyjPFDJCz1bQCrtQV4Bk0g7xGgQLqFU9jzOFzQIDAQAB |
| AoGBALfdR/9s44/KoZJIQ8Q0v8HeaU9+30U5jF9pLaYggtty2nTsR5u6d/TZPY42 |
| BcVeXBV6XbBa8NZMJelXQvCw6d3hrirtRgqo+R9n6Z5Ji9oKA9NR0ZD0d66OLgRz |
| 7U1w2wiM9KqfjRpRhuID1MrDF8R0mxORSFnlMeoHD74ncK6ZAkEA+NBV2OOigyU/ |
| CVWCTKmOpxUGb6bRZfvQRln4XlVUhSgZU0Acf0APl3Av1vUPyPjRIXRnMS5ZBDFK |
| YoUqWH3ymwJBANsJhX3HHYXk7aDrmPKE7q25xR7Eu4C7XEdiG0SSl8PNAicU0APy |
| zFs9GLhTgGCTZf/SCzH6ejEIiOC/RZeqW7cCQCapAF3F6O9lryi9H5TX17GAY9Kf |
| YfPtr4vu2NeXfJ2AAIdd88+V3ZZTOSu2QjCg8KW5F3udzvkGy58JP+4mC7cCQBEU |
| +gMoHyZNBzcwiHoJYe/MeBIBN7o/Yl/yx7ueTxWnDE7t8ZcNPWC0MBRX9sARXrgH |
| snXQWe0vBDW61PuR/psCQQDthOoMBnuWamOEZrEJr+itK5+ZPlE+KpT3ladXui57 |
| zvz3CljmlLwyufahWaF+LzfohVAG5CLr4Zi/bv7j1lnJ |
| -----END RSA PRIVATE KEY----- |
| """ |
| |
| |
| def unicode2str(value): |
| """ |
| Recurses through value, converting unicode to strings. |
| |
| The output of the json python decoder looks like a dictionary with |
| unicode keys mapping to more unicode strings, and possibly |
| dictionaries. Convert those unicode strings to ASCII strings |
| recursively with this function. |
| |
| @param value: dict or unicode. |
| @returns value with unicode recursively replaced with string. |
| |
| """ |
| if isinstance(value, dict): |
| ret = {} |
| for k,v in value.items(): |
| ret[unicode2str(k)] = unicode2str(v) |
| return ret |
| |
| if isinstance(value, unicode): |
| return str(value) |
| |
| return value |
| |
| |
| class network_DestinationVerification(test.test): |
| """Tests that the destination verification logic in shill works. |
| |
| This logic allows us to verify that (for instance) we trust the |
| credentials of a Chromekey. |
| |
| """ |
| version = 1 |
| |
| |
| @property |
| def shim_path(self): |
| """@return path to crypto-util shim.""" |
| lib_paths = ['lib', 'lib64'] |
| shim_path = '/usr/%s/shill/shims/crypto-util' |
| for lib in lib_paths: |
| path = shim_path % lib |
| if os.path.exists(path): |
| return path |
| raise error.TestFail('Unable to find crypto-util.') |
| |
| |
| def _call_shim_with_args(self, args, protobuffer): |
| """Calls the crypto_util shim with args and stdin as specified. |
| |
| Calls crypto shim with args for paramters, and the serialized form of |
| protobuffer on stdin. Asserts that the command completes successfully |
| and returns the raw output bytestring. |
| |
| @param args: tuple of string arguments to the shim. |
| @param protobuffer: python protocol buffer object. |
| @return stdout of the shim call as string. |
| |
| """ |
| raw_input_bytes = protobuffer.SerializeToString() |
| result = utils.run(self.shim_path, |
| stderr_tee=utils.TEE_TO_LOGS, |
| stdin=raw_input_bytes, |
| verbose=True, |
| args=args, |
| timeout=10, |
| ignore_status=True) |
| if result.exit_status: |
| return None |
| raw_output = result.stdout |
| logging.debug('Got raw output: %s.', |
| ''.join([hex(ord(c)) for c in raw_output])) |
| return raw_output |
| |
| |
| def _test_verify(self, test_data, expect_failure=False): |
| """Test that shim verify operation works correctly. |
| |
| Call into the shim to perform a verify operation, check that the call |
| succeeds unless |expect_failure|. |test_data| looks like the decoded |
| json data we're given by the destination. |
| |
| @param test_data: dictionary of test data to use with the call. |
| @param expect_failure: bool true if test_data should fail to verify. |
| |
| @raises TestFail when verification doesn't go as expected. |
| |
| """ |
| # See doc/manager-api.txt, but the format goes roughly: |
| # ssid,udn,bssid,key,nonce |
| sign_bundle = test_data['sign'] |
| unsigned_data = '%s,%s,%s,%s,%s' % (test_data['name'], |
| test_data['ssdp_udn'], |
| test_data['hotspot_bssid'], |
| test_data['public_key'], |
| sign_bundle['nonce']) |
| message = crypto_util_pb2.VerifyCredentialsMessage() |
| message.certificate = sign_bundle['certificate'] |
| message.signed_data = base64.b64decode(sign_bundle['signed_data']) |
| message.unsigned_data = unsigned_data |
| message.mac_address = test_data['hotspot_bssid'] |
| output = self._call_shim_with_args(('verify',), message) |
| if expect_failure: |
| if output is None: |
| # Expected a failure, and got it. We're done here. |
| return |
| raise error.TestFail('Expected verification to fail, but it ' |
| 'succeeded.') |
| |
| if not output: |
| raise error.TestFail('Verification failed unexpectedly.') |
| |
| response = crypto_util_pb2.VerifyCredentialsResponse() |
| response.ParseFromString(output) |
| if response.ret != crypto_util_pb2.OK: |
| raise error.TestFail('Expected verification success, ' |
| 'but got: %d.' % response.ret) |
| |
| |
| def _test_encrypt(self, public_key, data_to_encrypt, expect_failure=False): |
| """Test that shim encrypt operation works correctly. |
| |
| Call into the shim to perform an encrypt operation. |
| Raise a test error if the call fails, unless |expect_failure|. |
| |
| @param public_key: string containing RSAPublicKey format RSA key. |
| @param data_to_encrypt: string data to encrypt. |
| @param expect_failure: bool true if encrypt should fail. |
| |
| """ |
| message = crypto_util_pb2.EncryptDataMessage() |
| message.public_key = public_key |
| message.data = data_to_encrypt |
| output = self._call_shim_with_args(('encrypt',), message) |
| if expect_failure: |
| if output is None: |
| # Expected a failure, and got it. We're done here. |
| return |
| raise error.TestFail('Expected encryption to fail, ' |
| 'but it did not.') |
| |
| if not output: |
| raise error.TestFail('Encryption failed unexpectedly.') |
| |
| response = crypto_util_pb2.EncryptDataResponse() |
| response.ParseFromString(output) |
| if response.ret != crypto_util_pb2.OK: |
| raise error.TestFail('Data encryption failed.') |
| |
| logging.debug('Decrypting %d bytes of encrypted data to confirm match.', |
| len(response.encrypted_data)) |
| try: |
| private_key = tempfile.NamedTemporaryFile() |
| encrypted_data = tempfile.NamedTemporaryFile() |
| private_key.write(ENCRYPTION_PRIVATE_KEY) |
| private_key.flush() |
| encrypted_data.write(response.encrypted_data) |
| encrypted_data.flush() |
| result = utils.run('openssl rsautl -decrypt -inkey %s -in %s' % |
| (private_key.name, encrypted_data.name), |
| stdin=response.encrypted_data, |
| stderr_tee=utils.TEE_TO_LOGS, |
| verbose=True, |
| ignore_status=True) |
| if result.exit_status: |
| if data_to_encrypt == '': |
| # Due to an open bug in OpenSSL, rsautl doesn't handle this |
| # case correctly. For now, just pass and assume that |
| # we're doing this correctly. |
| # http://rt.openssl.org/Ticket/Display.html?id=2018 |
| return |
| raise error.TestFail('Failed to decrypt shim output.') |
| |
| if result.stdout != data_to_encrypt: |
| raise error.TestFail('Data encyption failed: ' |
| 'expected: %s, but got: %s' % |
| (data_to_encrypt, result.stdout)) |
| |
| finally: |
| private_key.close() |
| encrypted_data.close() |
| |
| |
| def run_once(self): |
| """Body of the test.""" |
| logging.info('Checking basic encryption operation of the shim.') |
| self._test_encrypt(ENCRYPTION_PUBLIC_KEY, 'disco boy') |
| |
| logging.info('Checking graceful fail for too much data to encrypt.') |
| self._test_encrypt(ENCRYPTION_PUBLIC_KEY, |
| ''.join(['x' for i in range(500)]), |
| expect_failure=True) |
| |
| logging.info('Checking graceful fail for a bad key format.') |
| self._test_encrypt('this will not parse in openssl', |
| 'disco boy', |
| expect_failure=True) |
| |
| logging.info('Checking that we encrypt the empty string correctly.') |
| self._test_encrypt(ENCRYPTION_PUBLIC_KEY, '') |
| |
| logging.info('Checking basic verification operation.') |
| test_data = unicode2str(json.loads(TEST_DATA1)) |
| self._test_verify(test_data) |
| |
| logging.info('Checking bad nonce in unsigned_data.') |
| test_data = unicode2str(json.loads(TEST_DATA1)) |
| test_data['sign']['nonce'] = 'does not match' |
| self._test_verify(test_data, expect_failure=True) |
| |
| logging.info('Checking for graceful fail for invalid ' |
| 'certificate format') |
| test_data = unicode2str(json.loads(TEST_DATA1)) |
| test_data['sign']['certificate'] = 'not a certificate' |
| self._test_verify(test_data, expect_failure=True) |
| |
| logging.info('Verification fails when the certificate is signed, but ' |
| 'subject is malformed.') |
| test_data = unicode2str(json.loads(TEST_DATA2)) |
| self._test_verify(test_data, expect_failure=True) |
| |
| logging.info('Verification should succeed on third set of data.') |
| test_data = unicode2str(json.loads(TEST_DATA3)) |
| self._test_verify(test_data) |
| |
| logging.info('Test completed successfully.') |