| OLD | NEW |
| 1 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 1 # Copyright (c) 2011 The Chromium OS 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 import logging, os, tempfile | 5 import logging, os, tempfile |
| 6 from autotest_lib.client.bin import utils | 6 from autotest_lib.client.bin import utils |
| 7 from autotest_lib.client.common_lib import autotemp, error | 7 from autotest_lib.client.common_lib import autotemp, error |
| 8 import common | 8 import common |
| 9 import constants, cryptohome, login | 9 import constants, cryptohome, login |
| 10 | 10 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 def system_output_on_fail(cmd): | 40 def system_output_on_fail(cmd): |
| 41 """Run a |cmd|, capturing output and logging it only on error.""" | 41 """Run a |cmd|, capturing output and logging it only on error.""" |
| 42 output = None | 42 output = None |
| 43 try: | 43 try: |
| 44 output = utils.system_output(cmd) | 44 output = utils.system_output(cmd) |
| 45 except: | 45 except: |
| 46 logging.error(output) | 46 logging.error(output) |
| 47 raise | 47 raise |
| 48 | 48 |
| 49 | 49 |
| 50 def __unlink(filename): |
| 51 try: |
| 52 os.unlink(filename) |
| 53 except (IOError, OSError) as error: |
| 54 logging.info(error) |
| 55 |
| 56 |
| 57 def clear_ownership(): |
| 58 __unlink(constants.OWNER_KEY_FILE) |
| 59 __unlink(constants.SIGNED_PREFERENCES_FILE) |
| 60 __unlink(constants.SIGNED_POLICY_FILE) |
| 61 |
| 62 |
| 50 NSSDB = constants.CRYPTOHOME_MOUNT_PT + '/.pki/nssdb' | 63 NSSDB = constants.CRYPTOHOME_MOUNT_PT + '/.pki/nssdb' |
| 51 PK12UTIL = 'nsspk12util' | 64 PK12UTIL = 'nsspk12util' |
| 52 OPENSSLP12 = 'openssl pkcs12' | 65 OPENSSLP12 = 'openssl pkcs12' |
| 53 OPENSSLX509 = 'openssl x509' | 66 OPENSSLX509 = 'openssl x509' |
| 54 OPENSSLRSA = 'openssl rsa' | 67 OPENSSLRSA = 'openssl rsa' |
| 55 OPENSSLREQ = 'openssl req' | 68 OPENSSLREQ = 'openssl req' |
| 56 OPENSSLCRYPTO = 'openssl sha1' | 69 OPENSSLCRYPTO = 'openssl sha1' |
| 57 | 70 |
| 58 | 71 |
| 59 def pairgen(): | 72 def pairgen(): |
| 60 """Generate a self-signed cert and associated private key. | 73 """Generate a self-signed cert and associated private key. |
| 61 | 74 |
| 62 Generates a self-signed X509 certificate and the associated private key. | 75 Generates a self-signed X509 certificate and the associated private key. |
| 63 The key is 2048 bits. The generated material is stored in PEM format | 76 The key is 2048 bits. The generated material is stored in PEM format |
| 64 and the paths to the two files are returned. | 77 and the paths to the two files are returned. |
| 65 | 78 |
| 66 The caller is responsible for cleaning up these files. | 79 The caller is responsible for cleaning up these files. |
| 67 """ | 80 """ |
| 68 keyfile = scoped_tempfile.tempdir.name + '/private.key' | 81 keyfile = scoped_tempfile.tempdir.name + '/private.key' |
| 69 certfile = scoped_tempfile.tempdir.name + '/cert.pem' | 82 certfile = scoped_tempfile.tempdir.name + '/cert.pem' |
| 70 cmd = '%s -x509 -subj %s -newkey rsa:2048 -nodes -keyout %s -out %s' % ( | 83 cmd = '%s -x509 -subj %s -newkey rsa:2048 -nodes -keyout %s -out %s' % ( |
| 71 OPENSSLREQ, '/CN=me', keyfile, certfile) | 84 OPENSSLREQ, '/CN=me', keyfile, certfile) |
| 72 system_output_on_fail(cmd) | 85 system_output_on_fail(cmd) |
| 73 return (keyfile, certfile) | 86 return (keyfile, certfile) |
| 74 | 87 |
| 75 | 88 |
| 89 def pairgen_as_data(): |
| 90 """Generates keypair, returns keys as data. |
| 91 |
| 92 Generates a fresh owner keypair and then passes back the |
| 93 PEM-formatted private key and the DER-encoded public key. |
| 94 """ |
| 95 (keypath, certpath) = pairgen() |
| 96 keyfile = scoped_tempfile(keypath) |
| 97 certfile = scoped_tempfile(certpath) |
| 98 return (utils.read_file(keyfile.name), |
| 99 cert_extract_pubkey_der(certfile.name)) |
| 100 |
| 101 |
| 76 def push_to_nss(keyfile, certfile, nssdb): | 102 def push_to_nss(keyfile, certfile, nssdb): |
| 77 """Takes a pre-generated key pair and pushes them to an NSS DB. | 103 """Takes a pre-generated key pair and pushes them to an NSS DB. |
| 78 | 104 |
| 79 Given paths to a private key and cert in PEM format, stores the pair | 105 Given paths to a private key and cert in PEM format, stores the pair |
| 80 in the provided nssdb. | 106 in the provided nssdb. |
| 81 """ | 107 """ |
| 82 for_push = scoped_tempfile(scoped_tempfile.tempdir.name + 'for_push.p12') | 108 for_push = scoped_tempfile(scoped_tempfile.tempdir.name + '/for_push.p12') |
| 83 cmd = '%s -export -in %s -inkey %s -out %s ' % ( | 109 cmd = '%s -export -in %s -inkey %s -out %s ' % ( |
| 84 OPENSSLP12, certfile, keyfile, for_push.name) | 110 OPENSSLP12, certfile, keyfile, for_push.name) |
| 85 cmd += '-passin pass: -passout pass:' | 111 cmd += '-passin pass: -passout pass:' |
| 86 system_output_on_fail(cmd) | 112 system_output_on_fail(cmd) |
| 87 cmd = '%s -d "sql:%s" -i %s -W ""' % (PK12UTIL, | 113 cmd = '%s -d "sql:%s" -i %s -W ""' % (PK12UTIL, |
| 88 nssdb, | 114 nssdb, |
| 89 for_push.name) | 115 for_push.name) |
| 90 system_output_on_fail(cmd) | 116 system_output_on_fail(cmd) |
| 91 | 117 |
| 92 | 118 |
| 93 def generate_owner_creds(): | 119 def generate_owner_creds(): |
| 94 """Generates a keypair, registered with NSS, and returns key and cert. | 120 """Generates a keypair, registered with NSS, and returns key and cert. |
| 95 | 121 |
| 96 Generates a fresh self-signed cert and private key. Registers them | 122 Generates a fresh self-signed cert and private key. Registers them |
| 97 with NSS and then passes back paths to files containing the | 123 with NSS and then passes back paths to files containing the |
| 98 PEM-formatted private key and certificate. | 124 PEM-formatted private key and certificate. |
| 99 """ | 125 """ |
| 100 (keyfile, certfile) = pairgen() | 126 (keyfile, certfile) = pairgen() |
| 101 push_to_nss(keyfile, certfile, NSSDB) | 127 push_to_nss(keyfile, certfile, NSSDB) |
| 102 return (keyfile, certfile) | 128 return (keyfile, certfile) |
| 103 | 129 |
| 104 | 130 |
| 105 | 131 |
| 106 def cert_extract_pubkey_der(pem): | 132 def cert_extract_pubkey_der(pem): |
| 107 """Given a PEM-formatted cert, extracts the public key in DER format. | 133 """Given a PEM-formatted cert, extracts the public key in DER format. |
| 108 | 134 |
| 109 Pass in an X509 certificate in PEM format, and you'll get back the | 135 Pass in an X509 certificate in PEM format, and you'll get back the |
| 110 DER-formatted public key as a string. | 136 DER-formatted public key as a string. |
| 111 """ | 137 """ |
| 112 outfile = scoped_tempfile(scoped_tempfile.tempdir.name + 'pubkey.der') | 138 outfile = scoped_tempfile(scoped_tempfile.tempdir.name + '/pubkey.der') |
| 113 cmd = '%s -in %s -pubkey -noout ' % (OPENSSLX509, pem) | 139 cmd = '%s -in %s -pubkey -noout ' % (OPENSSLX509, pem) |
| 114 cmd += '| %s -outform DER -pubin -out %s' % (OPENSSLRSA, | 140 cmd += '| %s -outform DER -pubin -out %s' % (OPENSSLRSA, |
| 115 outfile.name) | 141 outfile.name) |
| 116 system_output_on_fail(cmd) | 142 system_output_on_fail(cmd) |
| 117 der = utils.read_file(outfile.name) | 143 der = utils.read_file(outfile.name) |
| 118 return der | 144 return der |
| 119 | 145 |
| 120 | 146 |
| 121 def generate_and_register_owner_keypair(testuser, testpass): | 147 def generate_and_register_keypair(testuser, testpass): |
| 122 """Generates keypair, registers with NSS, sets owner key, returns pkey. | 148 """Generates keypair, registers with NSS, sets owner key, returns keypair. |
| 123 | 149 |
| 124 Generates a fresh owner keypair. Registers keys with NSS, | 150 Generates a fresh owner keypair. Registers keys with NSS, |
| 125 puts the owner public key in the right place, ensures that the | 151 puts the owner public key in the right place, ensures that the |
| 126 session_manager picks it up, ensures the owner's home dir is | 152 session_manager picks it up, ensures the owner's home dir is |
| 127 mounted, and then passes back paths to a file containing the | 153 mounted, and then passes back the PEM-formatted private key and the |
| 128 PEM-formatted private key. | 154 DER-encoded public key. |
| 129 """ | 155 """ |
| 130 (keyfile, certfile) = generate_owner_creds() | 156 (keypath, certpath) = generate_owner_creds() |
| 131 utils.open_write_close(constants.OWNER_KEY_FILE, | 157 keyfile = scoped_tempfile(keypath) |
| 132 cert_extract_pubkey_der(certfile)) | 158 certfile = scoped_tempfile(certpath) |
| 159 |
| 160 pubkey = cert_extract_pubkey_der(certfile.name) |
| 161 utils.open_write_close(constants.OWNER_KEY_FILE, pubkey) |
| 162 |
| 133 login.refresh_login_screen() | 163 login.refresh_login_screen() |
| 134 cryptohome.mount_vault(testuser, testpass, create=False) | 164 cryptohome.mount_vault(testuser, testpass, create=False) |
| 135 return keyfile | 165 return (utils.read_file(keyfile.name), pubkey) |
| 136 | 166 |
| 137 | 167 |
| 138 def sign(pem_key_file, data): | 168 def sign(pem_key, data): |
| 139 """Signs |data| with key from |pem_key_file|, returns signature. | 169 """Signs |data| with key from |pem_key|, returns signature. |
| 140 | 170 |
| 141 Using the PEM-formatted private key in |pem_key_file|, generates an | 171 Using the PEM-formatted private key in |pem_key|, generates an |
| 142 RSA-with-SHA1 signature over |data| and returns the signature in | 172 RSA-with-SHA1 signature over |data| and returns the signature in |
| 143 a string. | 173 a string. |
| 144 """ | 174 """ |
| 145 sig = scoped_tempfile() | 175 sig = scoped_tempfile() |
| 146 err = scoped_tempfile() | 176 err = scoped_tempfile() |
| 147 data_file = scoped_tempfile() | 177 data_file = scoped_tempfile() |
| 148 data_file.fo.write(data) | 178 data_file.fo.write(data) |
| 149 data_file.fo.seek(0) | 179 data_file.fo.seek(0) |
| 150 | 180 |
| 151 cmd = '%s -sign %s' % (OPENSSLCRYPTO, pem_key_file) | 181 pem_key_file = scoped_tempfile(scoped_tempfile.tempdir.name + '/pkey.pem') |
| 182 utils.open_write_close(pem_key_file.name, pem_key) |
| 183 |
| 184 cmd = '%s -sign %s' % (OPENSSLCRYPTO, pem_key_file.name) |
| 152 try: | 185 try: |
| 153 utils.run(cmd, | 186 utils.run(cmd, |
| 154 stdin=data_file.fo, | 187 stdin=data_file.fo, |
| 155 stdout_tee=sig.fo, | 188 stdout_tee=sig.fo, |
| 156 stderr_tee=err.fo) | 189 stderr_tee=err.fo) |
| 157 except: | 190 except: |
| 158 err.fo.seek(0) | 191 err.fo.seek(0) |
| 159 logging.error(err.fo.read()) | 192 logging.error(err.fo.read()) |
| 160 raise | 193 raise |
| 161 | 194 |
| 162 sig.fo.seek(0) | 195 sig.fo.seek(0) |
| 163 sig_data = sig.fo.read() | 196 sig_data = sig.fo.read() |
| 164 if not sig_data: | 197 if not sig_data: |
| 165 raise error.TestFail('Empty signature!') | 198 raise error.TestFail('Empty signature!') |
| 166 return sig_data | 199 return sig_data |
| OLD | NEW |