"""Unit tests for certs module.""" import __builtin__ import datetime import mox import stubout from google.apputils import app from google.apputils import basetest import certs class CertificateTest(mox.MoxTestBase): """Test Certificate object functions.""" def setUp(self): mox.MoxTestBase.setUp(self) self.stubs = stubout.StubOutForTesting() def tearDown(self): self.mox.UnsetStubs() self.stubs.UnsetAll() def StubSetup(self): """Set up stubs.""" self.mox.StubOutWithMock(certs.gmacpyutil, 'RunProcess') def testget(self): # pylint: disable=g-bad-name """Test get.""" self.StubSetup() self.mox.StubOutWithMock(certs.Certificate, '_ParsePEMCertificate') certs.Certificate._ParsePEMCertificate('pem').AndReturn(None) self.mox.ReplayAll() c = certs.Certificate('pem') c.key = 'key' self.assertEqual('key', c.get('key')) self.assertEqual(None, c.get('missing')) self.mox.VerifyAll() def testParsePEMCertificateFails(self): """Test _ParsePEMCertificate.""" self.StubSetup() pem = 'pem' cmd = [certs.CMD_OPENSSL, 'x509', '-sha1', '-nameopt', 'compat', '-noout', '-hash', '-subject', '-issuer', '-startdate', '-enddate', '-fingerprint', '-serial', '-email'] certs.gmacpyutil.RunProcess(cmd, pem).AndReturn(('', '', 1)) self.mox.ReplayAll() self.assertRaises(certs.CertError, certs.Certificate, pem) self.mox.VerifyAll() def testParsePEMCertificateWithoutEmail(self): """Test _ParsePEMCertificate.""" self.StubSetup() pem = 'pem' date = 'Oct 31 12:34:56 1971 GMT' dt_date = datetime.datetime(1971, 10, 31, 12, 34, 56) parsed = {'subject': 'subject', 'issuer': 'issuer', 'certhash': 'hash', 'startdate': [date, dt_date], 'enddate': [date, dt_date], 'fingerprint': 'fing:er:print', 'osx_fingerprint': 'fingerprint', 'email': '', 'serial': '87654321', 'pem': pem} cmd = [certs.CMD_OPENSSL, 'x509', '-sha1', '-nameopt', 'compat', '-noout', '-hash', '-subject', '-issuer', '-startdate', '-enddate', '-fingerprint', '-serial', '-email'] output = ('hash\nsubject= subject\nissuer= issuer\nnotBefore=%s\n' 'notAfter=%s\nSHA1 Fingerprint=fing:er:print\nserial=87654321\n' % (date, date)) certs.gmacpyutil.RunProcess(cmd, pem).AndReturn((output, '', 0)) self.mox.ReplayAll() c = certs.Certificate(pem) self.assertEqual(parsed, c.__dict__) self.mox.VerifyAll() def testParsePEMCertificateWithEmail(self): """Test _ParsePEMCertificate.""" self.StubSetup() pem = 'pem' date = 'Oct 31 12:34:56 1971 GMT' dt_date = datetime.datetime(1971, 10, 31, 12, 34, 56) parsed = {'subject': 'subject', 'issuer': 'issuer', 'certhash': 'hash', 'startdate': [date, dt_date], 'enddate': [date, dt_date], 'fingerprint': 'fing:er:print', 'osx_fingerprint': 'fingerprint', 'serial': '87654321', 'email': 'user@company.com', 'pem': pem} cmd = [certs.CMD_OPENSSL, 'x509', '-sha1', '-nameopt', 'compat', '-noout', '-hash', '-subject', '-issuer', '-startdate', '-enddate', '-fingerprint', '-serial', '-email'] output_with_email = ('hash\nsubject= subject\nissuer= issuer\nnotBefore=%s' '\nnotAfter=%s\nSHA1 Fingerprint=fing:er:print\n' 'serial=87654321\nuser@company.com\n' % (date, date)) certs.gmacpyutil.RunProcess(cmd, pem).AndReturn((output_with_email, '', 0)) self.mox.ReplayAll() c = certs.Certificate(pem) self.assertEqual(parsed, c.__dict__) self.mox.VerifyAll() def testParsePEMCertificateWithMalformedDate(self): """Test _ParsePEMCertificate.""" self.StubSetup() pem = 'pem' parsed = {'subject': 'subject', 'issuer': 'issuer', 'certhash': 'hash', 'startdate': ['bad date', None], 'enddate': ['bad date', None], 'fingerprint': 'fing:er:print', 'osx_fingerprint': 'fingerprint', 'email': '', 'serial': '87654321', 'pem': pem} cmd = [certs.CMD_OPENSSL, 'x509', '-sha1', '-nameopt', 'compat', '-noout', '-hash', '-subject', '-issuer', '-startdate', '-enddate', '-fingerprint', '-serial', '-email'] output_bad_date = ('hash\nsubject= subject\nissuer= issuer\nnotBefore=bad ' 'date\nnotAfter=bad date\nSHA1 Fingerprint=' 'fing:er:print\nserial=87654321\n') certs.gmacpyutil.RunProcess(cmd, pem).AndReturn((output_bad_date, '', 0)) self.mox.ReplayAll() c = certs.Certificate(pem) self.assertEqual(parsed, c.__dict__) self.mox.VerifyAll() class CertsModuleTest(mox.MoxTestBase): """Test certs module-level functions.""" def setUp(self): mox.MoxTestBase.setUp(self) self.stubs = stubout.StubOutForTesting() def tearDown(self): self.mox.UnsetStubs() self.stubs.UnsetAll() def StubSetup(self): """Set up stubs.""" self.mox.StubOutWithMock(certs.gmacpyutil, 'RunProcess') self.mox.StubOutWithMock(certs.logging, 'info') self.mox.StubOutWithMock(certs.logging, 'debug') self.mox.StubOutWithMock(certs.logging, 'error') self.mox.StubOutWithMock(certs.os, 'getuid') self.mox.StubOutWithMock(certs.os, 'uname') self.mox.StubOutWithMock(certs.os.path, 'exists') self.mox.StubOutWithMock(certs.shutil, 'rmtree') self.mox.StubOutWithMock(certs.tempfile, 'mkdtemp') self.mox.StubOutWithMock(__builtin__, 'open') certs.login_keychain = None def testLoginKeychainAsRoot(self): """Test LoginKeychainAsRoot.""" self.StubSetup() certs.os.uname().AndReturn(('Darwin')) certs.os.getuid().AndReturn(0) certs.logging.debug('Root has no access to login keychain.') self.mox.ReplayAll() # running as root certs.LoginKeychain() self.assertEqual(None, certs.login_keychain) self.mox.VerifyAll() def testLoginKeychain(self): """Test LoginKeychain.""" self.StubSetup() command = [certs.CMD_SECURITY, 'login-keychain'] # security returns successfully certs.os.uname().AndReturn(('Darwin')) certs.os.getuid().AndReturn(1337) certs.gmacpyutil.RunProcess(command).AndReturn(('out\n', 'err\n', 0)) # security fails certs.os.uname().AndReturn(('Darwin')) certs.os.getuid().AndReturn(1337) certs.gmacpyutil.RunProcess(command).AndReturn(('out\n', 'err\n', 1)) certs.logging.error( 'Unable to determine login keychain: %s', 'err\n').AndReturn(None) self.mox.ReplayAll() # security returns successfully certs.LoginKeychain() self.assertEqual('out', certs.login_keychain) # security fails certs.LoginKeychain() self.assertEqual(None, certs.login_keychain) self.mox.VerifyAll() def testGetCertificatesNoKeychainSuccess(self): """Test _GetCertificates no keychain specified, successful search.""" self.StubSetup() self.mox.StubOutWithMock(certs, 'Certificate') command = [certs.CMD_SECURITY, 'find-certificate', '-a', '-p'] cert = '%s\n%s\n%s\n' % (certs.PEM_HEADER, 'cert_body', certs.PEM_FOOTER) output = cert * 2 certs.gmacpyutil.RunProcess(command).AndReturn((output, '', 0)) certs.Certificate(cert.strip()).AndReturn('parsed cert') certs.Certificate(cert.strip()).AndReturn('parsed cert') self.mox.ReplayAll() self.assertEqual(['parsed cert', 'parsed cert'], list(certs._GetCertificates())) self.mox.VerifyAll() def testGetCertificatesNoKeychainCertError(self): """Test _GetCertificates with CertError from Certificate class.""" self.StubSetup() self.mox.StubOutWithMock(certs, 'Certificate') command = [certs.CMD_SECURITY, 'find-certificate', '-a', '-p'] cert = '%s\n%s\n%s\n' % (certs.PEM_HEADER, 'cert_body', certs.PEM_FOOTER) output = cert * 2 certs.gmacpyutil.RunProcess(command).AndReturn((output, '', 0)) certs.Certificate(cert.strip()).AndRaise(certs.CertError('err')) certs.logging.info('Encountered an unparseable certificate, continuing.') certs.logging.debug('err') certs.Certificate(cert.strip()).AndReturn('parsed cert') self.mox.ReplayAll() self.assertEqual(['parsed cert'], list(certs._GetCertificates())) self.mox.VerifyAll() def testGetCertificatesNewKeychain(self): """Test _GetCertificates with a newly-created keychain.""" self.StubSetup() self.mox.StubOutWithMock(certs, 'Certificate') command = [certs.CMD_SECURITY, 'find-certificate', '-a', '-p'] certs.gmacpyutil.RunProcess(command).AndReturn(('', '', 9)) self.mox.ReplayAll() self.assertEqual([], list(certs._GetCertificates())) self.mox.VerifyAll() def testGetCertificatesNoKeychainSearchFailed(self): """Test _GetCertificates, no keychain, search failed.""" self.StubSetup() self.mox.StubOutWithMock(certs, 'Certificate') command = [certs.CMD_SECURITY, 'find-certificate', '-a', '-p'] certs.gmacpyutil.RunProcess(command).AndReturn(('', '', 1)) self.mox.ReplayAll() c = certs._GetCertificates() self.assertRaises(certs.CertError, c.next) self.mox.VerifyAll() def testGetCertificatesKeychainSpecifiedSuccess(self): """Test _GetCertificates with keychain specified.""" self.StubSetup() self.mox.StubOutWithMock(certs, 'Certificate') command = [certs.CMD_SECURITY, 'find-certificate', '-a', '-p'] cert = '%s\n%s\n%s\n' % (certs.PEM_HEADER, 'cert_body', certs.PEM_FOOTER) output = cert * 2 command = [certs.CMD_SECURITY, 'find-certificate', '-a', '-p', 'keychain'] certs.gmacpyutil.RunProcess(command).AndReturn((output, '', 0)) certs.Certificate(cert.strip()).AndReturn('parsed cert') certs.Certificate(cert.strip()).AndReturn('parsed cert') self.mox.ReplayAll() self.assertEqual(['parsed cert', 'parsed cert'], list(certs._GetCertificates(keychain='keychain'))) self.mox.VerifyAll() def testDeleteCert(self): """Test DeleteCert.""" self.StubSetup() command = [certs.CMD_SECURITY, 'delete-certificate', '-Z', 'f'] # Successful deletion certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) # Unsuccessful deletion certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 1)) # Successful deletion, custom keychain certs.gmacpyutil.RunProcess(command + ['k'], sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) # Successful deletion, system keychain certs.gmacpyutil.RunProcess(command + [certs.SYSTEM_KEYCHAIN], sudo=True, sudo_password=None).AndReturn(('out', 'err', 0)) self.mox.ReplayAll() self.assertEqual(None, certs.DeleteCert('f')) self.assertRaises(certs.CertError, certs.DeleteCert, 'f') self.assertEqual(None, certs.DeleteCert('f', keychain='k')) self.assertEqual(None, certs.DeleteCert('f', keychain=certs.SYSTEM_KEYCHAIN)) self.mox.VerifyAll() def testFindCertificates(self): """Test FindCertificates.""" self.StubSetup() self.mox.StubOutWithMock(certs, '_GetCertificates') allcerts = [{'subject': 's1', 'issuer': 'i1', 'fingerprint': 'f1'}, {'subject': 's2', 'issuer': 'i1', 'fingerprint': 'f2'}, {'subject': 's3', 'issuer': 'i2', 'fingerprint': 'f3'}] certs._GetCertificates(keychain=None).AndReturn(allcerts) certs._GetCertificates(keychain=None).AndReturn(allcerts) certs._GetCertificates(keychain=None).AndReturn(allcerts) certs._GetCertificates(keychain=None).AndReturn(allcerts) certs._GetCertificates(keychain=None).AndReturn(allcerts) self.mox.ReplayAll() self.assertEqual(allcerts, certs.FindCertificates()) self.assertEqual(allcerts[0:1], certs.FindCertificates(subject='s1')) self.assertEqual(allcerts[0:2], certs.FindCertificates(issuer='i1')) self.assertEqual([], certs.FindCertificates(issuer='i3')) self.assertEqual([], certs.FindCertificates(subject='s1', issuer='i2')) self.mox.VerifyAll() def testCertificateExpired(self): """Test CertificateExpired.""" c = self.mox.CreateMockAnything() self.mox.ReplayAll() expired = datetime.datetime.today() - datetime.timedelta(days=1) c.enddate = [None, expired] self.assertTrue(certs.CertificateExpired(c)) unexpired = datetime.datetime.today() + datetime.timedelta(days=1) c.enddate = [None, unexpired] self.assertFalse(certs.CertificateExpired(c)) self.mox.VerifyAll() def testVerifyIdentityPreference(self): """Test VerifyIdentityPreference.""" self.StubSetup() svc = 'com.apple.eap.identity.preference.test' sstr = '"labl"<blob>="A820662822C2 20C9D09417C7 :4E6DB011"' scn_true = 'A820662822C2 20C9D09417C7 :4E6DB011' scn_false = 'B85065212212 F52D6268A281 :6C09A091' cmd = [certs.CMD_SECURITY, 'get-identity-preference', '-s', svc, '-c'] certs.gmacpyutil.RunProcess(cmd).AndReturn((sstr, 'stderr', 0)) certs.gmacpyutil.RunProcess(cmd).AndReturn((sstr, 'stderr', 0)) self.mox.ReplayAll() self.assertTrue(certs.VerifyIdentityPreference(scn_true, svc)) self.assertFalse(certs.VerifyIdentityPreference(scn_false, svc)) self.mox.VerifyAll() def testClearIdentityPreferences(self): """Test ClearIdentityPreferences.""" self.StubSetup() dump = ('keychain: "/Users/gneagle/Library/Keychains/login.keychain"\n' 'class: "genp"\n' 'attributes:\n' ' 0x00000007 <blob>="com.apple.network.eap.user.identity.wlan"\n' ' 0x00000008 <blob>=<NULL>\n' ' "acct"<blob>="20C9D043F6CF :2EE73EF2 "\n' ' "cdat"<timedate>=0x32303133303932353230333031375A00\n' ' "crtr"<uint32>="aapl"\n' ' "cusi"<sint32>=<NULL>\n' ' "desc"<blob>=<NULL>\n' ' "gena"<blob>=0x737375690000002087191CA30FC911D4849A000\n' ' "icmt"<blob>=<NULL>\n' ' "invi"<sint32>=<NULL>\n' ' "mdat"<timedate>=0x32303133313030373231303833375A00\n' ' "nega"<sint32>=<NULL>\n' ' "prot"<blob>=<NULL>\n' ' "scrp"<sint32>=0x00000000\n' ' "svce"<blob>="com.apple.network.eap.user.identity.wlan.ssid"\n' ' "type"<uint32>="iprf"\n' 'keychain: "/Users/gneagle/Library/Keychains/login.keychain"\n' 'class: "genp\n"' 'attributes:\n' ' 0x00000007 <blob>="com.apple.assistant"\n' ' 0x00000008 <blob>=<NULL>\n' ' "acct"<blob>="675588EC-C24F-4068-88FC-B7BEE228B93C"\n' ' "cdat"<timedate>=0x32303133303431313135333335335A00\n' ' "crtr"<uint32>=<NULL>\n' ' "cusi"<sint32>=<NULL>\n' ' "desc"<blob>=<NULL>\n' ' "gena"<blob>=<NULL>\n' ' "icmt"<blob>=<NULL>\n' ' "invi"<sint32>=<NULL>\n' ' "mdat"<timedate>=0x32303133313030383134323233325A00\n' ' "nega"<sint32>=<NULL>\n' ' "prot"<blob>=<NULL>\n' ' "scrp"<sint32>=<NULL>\n' ' "svce"<blob>="com.apple.assistant"\n' ' "type"<uint32>=<NULL>\n') cmd = [certs.CMD_SECURITY, 'dump-keychain'] certs.gmacpyutil.RunProcess(cmd).AndReturn((dump, None, 0)) cmd = [certs.CMD_SECURITY, 'set-identity-preference', '-n', '-s', 'com.apple.network.eap.user.identity.wlan.ssid'] certs.logging.debug('Removing identity preference: %s', cmd) certs.gmacpyutil.RunProcess( cmd, sudo=False, sudo_password=None).AndReturn((None, None, 0)) self.mox.ReplayAll() certs.ClearIdentityPreferences() self.mox.VerifyAll() def testCreateIdentityPreference(self): """Test CreateIdentityPreference.""" self.StubSetup() self.mox.StubOutWithMock(certs, 'FindCertificates') c = self.mox.CreateMockAnything() c.osx_fingerprint = 'f' # No matching certs found certs.logging.debug('Creating TLS identity preference for %s ' 'in keychain %s', 's', 'k') certs.FindCertificates(issuer_cn='i', keychain='k').AndReturn([]) # Successful ID pref creation certs.logging.debug('Creating TLS identity preference for %s ' 'in keychain %s', 's', 'k') certs.FindCertificates(issuer_cn='i', keychain='k').AndReturn([c]) command = [certs.CMD_SECURITY, 'set-identity-preference', '-Z', 'f', '-s', 's', 'k'] certs.logging.debug('Command: %s', command) certs.gmacpyutil.RunProcess(command).AndReturn(('out', 'err', 0)) certs.logging.debug('Identity preference creation output: %s', 'out') # Error creating ID pref certs.logging.debug('Creating TLS identity preference for %s ' 'in keychain %s', 's', 'k') certs.FindCertificates(issuer_cn='i', keychain='k').AndReturn([c]) command = [certs.CMD_SECURITY, 'set-identity-preference', '-Z', 'f', '-s', 's', 'k'] certs.logging.debug('Command: %s', command) certs.gmacpyutil.RunProcess(command).AndReturn(('out', 'err', 1)) certs.logging.debug('Identity preference creation output: %s', 'out') self.mox.ReplayAll() # No matching certs found self.assertRaises(certs.CertError, certs.CreateIdentityPreference, 'i', 's', keychain='k') # Successful ID pref creation self.assertEquals(None, certs.CreateIdentityPreference('i', 's', keychain='k')) # Error creating ID pref self.assertRaises(certs.CertError, certs.CreateIdentityPreference, 'i', 's', keychain='k') self.mox.VerifyAll() def testInstallCertInKeychainFailIOError(self): self.StubSetup() certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') open_file = self.mox.CreateMockAnything() open('tempdir/private.key', 'w').AndReturn(open_file) open_file.write('key').AndRaise(IOError) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() self.assertRaises(certs.KeychainError, certs.InstallCertInKeychain, 'cert', 'key', keychain='k') self.mox.VerifyAll() def WriteFiles(self): """Mocks the writing of tempfiles for InstallCertInKeychain.""" key = self.mox.CreateMockAnything() open('tempdir/private.key', 'w').AndReturn(key) key.write('key').AndReturn(None) key.close().AndReturn(None) cert = self.mox.CreateMockAnything() open('tempdir/certificate.cer', 'w').AndReturn(cert) cert.write('cert').AndReturn(None) cert.close().AndReturn(None) def testInstallCertInKeychainSuccessNoPassNoApp(self): """Test InstallCertInKeychain success, no passphrase or trusted app.""" self.StubSetup() certs.logging.info('Installing downloaded key into the %s keychain', 'k').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') self.WriteFiles() command = [certs.CMD_SECURITY, 'import', 'tempdir/private.key', '-x', '-k', 'k', '-A'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Private key installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') certs.logging.info('Installing downloaded certificate into the %s keychain', 'k').AndReturn(None) command = [certs.CMD_SECURITY, 'import', 'tempdir/certificate.cer', '-x', '-k', 'k'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallCertInKeychain('cert', 'key', keychain='k') self.mox.VerifyAll() def testInstallCertInKeychainSuccessSystemKeychain(self): """Test InstallCertInKeychain success, system keychain.""" self.StubSetup() certs.logging.info('Installing downloaded key into the %s keychain', certs.SYSTEM_KEYCHAIN).AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') self.WriteFiles() command = [certs.CMD_SECURITY, 'import', 'tempdir/private.key', '-x', '-k', certs.SYSTEM_KEYCHAIN, '-A'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=True, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Private key installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') certs.logging.info('Installing downloaded certificate into the %s keychain', certs.SYSTEM_KEYCHAIN).AndReturn(None) command = [certs.CMD_SECURITY, 'import', 'tempdir/certificate.cer', '-x', '-k', certs.SYSTEM_KEYCHAIN] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=True, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallCertInKeychain('cert', 'key', keychain=certs.SYSTEM_KEYCHAIN) self.mox.VerifyAll() def testInstallCertInKeychainSuccessWithPassNoApp(self): """Test InstallCertInKeychain success, with passphrase, no trusted app.""" self.StubSetup() certs.logging.info('Installing downloaded key into the %s keychain', 'k').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') self.WriteFiles() command = [certs.CMD_SECURITY, 'import', 'tempdir/private.key', '-x', '-k', 'k', '-P', 'passphrase', '-A'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Private key installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') certs.logging.info('Installing downloaded certificate into the %s keychain', 'k').AndReturn(None) command = [certs.CMD_SECURITY, 'import', 'tempdir/certificate.cer', '-x', '-k', 'k'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallCertInKeychain('cert', 'key', keychain='k', passphrase='passphrase') self.mox.VerifyAll() def testInstallCertInKeychainSuccessWithPassWithApp(self): """Test InstallCertInKeychain success, with passphrase and trusted app.""" self.StubSetup() certs.logging.info('Installing downloaded key into the %s keychain', 'k').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') self.WriteFiles() command = [certs.CMD_SECURITY, 'import', 'tempdir/private.key', '-x', '-k', 'k', '-P', 'passphrase', '-T', 'trusted_app_path'] certs.os.path.exists('trusted_app_path').AndReturn(True) certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Private key installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') certs.logging.info('Installing downloaded certificate into the %s keychain', 'k').AndReturn(None) command = [certs.CMD_SECURITY, 'import', 'tempdir/certificate.cer', '-x', '-k', 'k'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallCertInKeychain('cert', 'key', keychain='k', passphrase='passphrase', trusted_app_path='trusted_app_path') self.mox.VerifyAll() def testInstallCertInKeychainSuccessWithMultipleApps(self): """Test InstallCertInKeychain success, with multiple trusted apps.""" self.StubSetup() certs.logging.info('Installing downloaded key into the %s keychain', 'k').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') self.WriteFiles() command = [certs.CMD_SECURITY, 'import', 'tempdir/private.key', '-x', '-k', 'k', '-P', 'passphrase', '-T', 'app1', '-T', 'app2'] certs.os.path.exists('app1').AndReturn(True) certs.os.path.exists('app2').AndReturn(True) certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Private key installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') certs.logging.info('Installing downloaded certificate into the %s keychain', 'k').AndReturn(None) command = [certs.CMD_SECURITY, 'import', 'tempdir/certificate.cer', '-x', '-k', 'k'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallCertInKeychain('cert', 'key', keychain='k', passphrase='passphrase', trusted_app_path=['app1', 'app2']) self.mox.VerifyAll() def testInstallCertInKeychainPrivateFailNoPassNoApp(self): """Test InstallCertInKeychain private key failure, no pass or app.""" self.StubSetup() certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') mock_file = self.mox.CreateMockAnything() open('tempdir/private.key', 'w').AndReturn(mock_file) mock_file.write('key').AndReturn(None) mock_file.close().AndReturn(None) certs.logging.info('Installing downloaded key into the %s keychain', 'k').AndReturn(None) command = [certs.CMD_SECURITY, 'import', 'tempdir/private.key', '-x', '-k', 'k', '-A'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 1)) certs.logging.debug('Private key installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() self.assertRaises(certs.KeychainError, certs.InstallCertInKeychain, 'cert', 'key', keychain='k') self.mox.VerifyAll() def testInstallCertInKeychainCertFailNoPassNoApp(self): """Test InstallCertInKeychain cert failure, no passphrase.""" self.StubSetup() certs.logging.info('Installing downloaded key into the %s keychain', 'k').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') self.WriteFiles() command = [certs.CMD_SECURITY, 'import', 'tempdir/private.key', '-x', '-k', 'k', '-A'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Private key installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') certs.logging.info('Installing downloaded certificate into the %s keychain', 'k').AndReturn(None) command = [certs.CMD_SECURITY, 'import', 'tempdir/certificate.cer', '-x', '-k', 'k'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=False, sudo_password=None).AndReturn(('out', 'err', 1)) certs.logging.debug('Certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() self.assertRaises(certs.KeychainError, certs.InstallCertInKeychain, 'cert', 'key', keychain='k') self.mox.VerifyAll() def testInstallTrustedCertInKeychainSuccess(self): """Test InstallTrustedCertInKeychain success, system keychain.""" self.StubSetup() certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') mock_file = self.mox.CreateMockAnything() open('tempdir/trusted_certificate.pem', 'w').AndReturn(mock_file) mock_file.__enter__().AndReturn(mock_file) mock_file.write('cert') mock_file.__exit__(None, None, None) certs.logging.info('Installing trusted certificate into keychain: %s', certs.SYSTEM_KEYCHAIN).AndReturn(None) command = [certs.CMD_SECURITY, 'add-trusted-cert', '-d', '-r', 'trustAsRoot', '-k', certs.SYSTEM_KEYCHAIN, 'tempdir/trusted_certificate.pem'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=True, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Trusted certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallTrustedCertInKeychain('cert') self.mox.VerifyAll() def testInstallTrustedCertInKeychainRootCASuccess(self): """Test InstallTrustedCertInKeychain success, system keychain.""" self.StubSetup() certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') mock_file = self.mox.CreateMockAnything() open('tempdir/trusted_certificate.pem', 'w').AndReturn(mock_file) mock_file.__enter__().AndReturn(mock_file) mock_file.write('cert') mock_file.__exit__(None, None, None) certs.logging.info('Installing trusted certificate into keychain: %s', certs.SYSTEM_KEYCHAIN).AndReturn(None) command = [certs.CMD_SECURITY, 'add-trusted-cert', '-d', '-r', 'trustRoot', '-k', certs.SYSTEM_KEYCHAIN, 'tempdir/trusted_certificate.pem'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=True, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Trusted certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallTrustedCertInKeychain('cert', root_ca=True) self.mox.VerifyAll() def testInstallTrustedCertInKeychainWithPoliciesSuccess(self): """Test InstallTrustedCertInKeychain success, system keychain.""" self.StubSetup() certs.tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('tempdir') mock_file = self.mox.CreateMockAnything() open('tempdir/trusted_certificate.pem', 'w').AndReturn(mock_file) mock_file.__enter__().AndReturn(mock_file) mock_file.write('cert') mock_file.__exit__(None, None, None) certs.logging.info('Installing trusted certificate into keychain: %s', certs.SYSTEM_KEYCHAIN).AndReturn(None) command = [certs.CMD_SECURITY, 'add-trusted-cert', '-d', '-r', 'trustRoot', '-p', 'ssl', '-p', 'smime', '-p', 'basic', '-k', certs.SYSTEM_KEYCHAIN, 'tempdir/trusted_certificate.pem'] certs.logging.debug('Command: %s', command).AndReturn(None) certs.gmacpyutil.RunProcess(command, sudo=True, sudo_password=None).AndReturn(('out', 'err', 0)) certs.logging.debug('Trusted certificate installation output: %s', 'out').AndReturn(None) certs.shutil.rmtree('tempdir').AndReturn(None) self.mox.ReplayAll() certs.InstallTrustedCertInKeychain('cert', root_ca=True, policies=['ssl', 'smime', 'basic']) self.mox.VerifyAll() def testRemoveIssuerCertsFromKeycahin(self): """Test RemoveIssuerCertsFromKeychain.""" self.StubSetup() self.mox.StubOutWithMock(certs, 'DeleteCert') self.mox.StubOutWithMock(certs, 'FindCertificates') c = self.mox.CreateMockAnything() c.osx_fingerprint = 'f' # Remove is successful certs.FindCertificates(issuer_cn='i', keychain='k').AndReturn([c]) certs.logging.debug( 'Removing cert with fingerprint %s from %s', 'f', 'k').AndReturn(None) certs.DeleteCert('f', password=None, gui=False, keychain='k').AndReturn(None) # Remove fails certs.FindCertificates(issuer_cn='i', keychain='k').AndReturn([c]) certs.logging.debug( 'Removing cert with fingerprint %s from %s', 'f', 'k').AndReturn(None) certs.DeleteCert('f', password=None, gui=False, keychain='k').AndRaise(certs.CertError('err')) certs.logging.error('Cannot delete old certificate: %s', 'err') self.mox.ReplayAll() # Remove is sucessful certs.RemoveIssuerCertsFromKeychain('i', keychain='k') # Remove fails certs.RemoveIssuerCertsFromKeychain('i', keychain='k') self.mox.VerifyAll() def testGenerateCSRNoPassphrase(self): """Test GenerateCSR success with no passphrase.""" self.StubSetup() command = [certs.CMD_OPENSSL, 'genrsa', '2048'] certs.logging.debug('command: %s', command).AndReturn(None) certs.logging.debug('environment: %s', []).AndReturn(None) certs.gmacpyutil.RunProcess(command, env={}).AndReturn(('key', 'err', 0)) certs.logging.debug('Private key generation output: %s', 'key').AndReturn(None) command = [certs.CMD_OPENSSL, 'req', '-new', '-subj', 'subject', '-key', '/dev/stdin'] certs.logging.debug('command: %s', command) certs.logging.debug('environment: %s', []) certs.logging.debug('stdinput: %s', 'key') certs.gmacpyutil.RunProcess(command, 'key', env={}).AndReturn(('csr', 'err', 0)) certs.logging.debug('CSR generation output: %s', 'csr').AndReturn(None) self.mox.ReplayAll() self.assertEqual(('csr', 'key', None), certs.GenerateCSR(subject='subject')) self.mox.VerifyAll() def testGenerateCSRWithPassphrase(self): """Test GenerateCSR success with a passphrase.""" self.StubSetup() command = [certs.CMD_OPENSSL, 'genrsa', '-des3', '-passout', 'env:PASSPHRASE', '2048'] certs.logging.debug('command: %s', command).AndReturn(None) certs.logging.debug('environment: %s', ['PASSPHRASE']).AndReturn(None) certs.gmacpyutil.RunProcess(command, env={'PASSPHRASE': 'pass'}).AndReturn( ('key', 'err', 0)) certs.logging.debug('Private key generation output: %s', 'key').AndReturn(None) command = [certs.CMD_OPENSSL, 'req', '-new', '-subj', 'subject', '-key', '/dev/stdin', '-passin', 'env:PASSPHRASE'] certs.logging.debug('command: %s', command) certs.logging.debug('environment: %s', ['PASSPHRASE']) certs.logging.debug('stdinput: %s', 'key') certs.gmacpyutil.RunProcess(command, 'key', env={'PASSPHRASE': 'pass'}).AndReturn( ('csr', 'err', 0)) certs.logging.debug('CSR generation output: %s', 'csr').AndReturn(None) self.mox.ReplayAll() self.assertEqual(('csr', 'key', 'pass'), certs.GenerateCSR(subject='subject', passphrase='pass')) self.mox.VerifyAll() def testGenerateCSRPrivateKeyFailed(self): """Test GenerateCSR when generating a private key fails.""" self.StubSetup() # Private key generation failed command = [certs.CMD_OPENSSL, 'genrsa', '2048'] certs.logging.debug('command: %s', command).AndReturn(None) certs.logging.debug('environment: %s', []).AndReturn(None) certs.gmacpyutil.RunProcess(command, env={}).AndReturn(('key', 'err', 1)) certs.logging.debug('Private key generation output: %s', 'key').AndReturn(None) self.mox.ReplayAll() self.assertRaises(certs.CertError, certs.GenerateCSR, subject='subject') self.mox.VerifyAll() def testGenerateCSRFailed(self): """Test GenerateCSR when generating the CSR fails.""" self.StubSetup() command = [certs.CMD_OPENSSL, 'genrsa', '2048'] certs.logging.debug('command: %s', command).AndReturn(None) certs.logging.debug('environment: %s', []).AndReturn(None) certs.gmacpyutil.RunProcess(command, env={}).AndReturn(('key', 'err', 0)) certs.logging.debug('Private key generation output: %s', 'key').AndReturn(None) command = [certs.CMD_OPENSSL, 'req', '-new', '-subj', 'subject', '-key', '/dev/stdin'] certs.logging.debug('command: %s', command) certs.logging.debug('environment: %s', []) certs.logging.debug('stdinput: %s', 'key') certs.gmacpyutil.RunProcess(command, 'key', env={}).AndReturn(('csr', 'err', 1)) certs.logging.debug('CSR generation output: %s', 'csr').AndReturn(None) self.mox.ReplayAll() self.assertRaises(certs.CertError, certs.GenerateCSR, subject='subject') self.mox.VerifyAll() def _SudoContextHelper(self): self.password = 'hunter2' self.keychain = certs.SYSTEM_KEYCHAIN def testGetSudoContextWithCertHandler(self): self._SudoContextHelper() self.mox.StubOutWithMock(certs.gmacpyutil, 'RunProcess') certs.gmacpyutil.RunProcess( ['-v'], sudo=True, sudo_password=self.password).AndReturn(['', '', 0]) self.mox.ReplayAll() sudo, sudo_pass = certs._GetSudoContext(self.keychain, gui=True, password=self.password) self.mox.VerifyAll() self.assertTrue(sudo) self.assertEqual(sudo_pass, 'hunter2') def testGetSudoContextWithoutCertHandlerGUIError(self): self._SudoContextHelper() self.mox.StubOutWithMock(certs.logging, 'exception') self.mox.StubOutWithMock(certs.getauth, 'GetPassword') certs.getauth.GetPassword( gui=True, title='Get sudo Password', prompt='sudo password', text='Enter local machine password').AndRaise(EOFError) certs.logging.exception( 'Could not get sudo password from GUI prompt').AndReturn(None) self.mox.ReplayAll() self.assertRaises(EOFError, certs._GetSudoContext, self.keychain, gui=True) self.mox.VerifyAll() def testGetSudoContextWithoutCertHandler(self): self._SudoContextHelper() self.mox.StubOutWithMock(certs.getauth, 'GetPassword') certs.getauth.GetPassword( gui=True, title='Get sudo Password', prompt='sudo password', text='Enter local machine password').AndReturn('pass') self.mox.ReplayAll() sudo, sudo_pass = certs._GetSudoContext(self.keychain, gui=True) self.mox.VerifyAll() self.assertTrue(sudo) self.assertEqual(sudo_pass, 'pass') def testGetSudoContextNoSudo(self): self._SudoContextHelper() self.mox.ReplayAll() sudo, sudo_pass = certs._GetSudoContext('notsystemkeychain') self.mox.VerifyAll() self.assertFalse(sudo) self.assertEqual(sudo_pass, None) def main(unused_argv): basetest.main() if __name__ == '__main__': app.run()