From 55c10d02095c6d708c72753f9915ae0076cf5d02 Mon Sep 17 00:00:00 2001 From: Victor Wagner Date: Mon, 27 Oct 2014 12:13:39 +0300 Subject: [PATCH] Added tests for X509Store certificate verification --- ctypescrypto/x509.py | 21 +++++++++----- tests/testx509.py | 66 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/ctypescrypto/x509.py b/ctypescrypto/x509.py index 5d5d448..d254c5a 100644 --- a/ctypescrypto/x509.py +++ b/ctypescrypto/x509.py @@ -1,10 +1,9 @@ -from ctypes import c_void_p,create_string_buffer,c_long,c_int +from ctypes import c_void_p,create_string_buffer,c_long,c_int,POINTER,c_char_p from ctypescrypto.bio import Membio from ctypescrypto.pkey import PKey from ctypescrypto.oid import Oid from ctypescrypto.exception import LibCryptoError from ctypescrypto import libcrypto - class X509Error(LibCryptoError): """ Exception, generated when some openssl function fail @@ -178,7 +177,7 @@ class X509: ctx=libcrypto.X509_STORE_CTX_new() if ctx is None: raise X509Error("Error allocating X509_STORE_CTX") - if libcrypto.X509_STORE_CTX_init(ctx,store.ptr,self.cert,None) < 0: + if libcrypto.X509_STORE_CTX_init(ctx,store.store,self.cert,None) < 0: raise X509Error("Error allocating X509_STORE_CTX") res= libcrypto.X509_verify_cert(ctx) libcrypto.X509_STORE_CTX_free(ctx) @@ -243,21 +242,22 @@ class X509Store: # Todo - set verification flags # self.store=libcrypto.X509_STORE_new() + if self.store is None: + raise X509Error("allocating store") lookup=libcrypto.X509_STORE_add_lookup(self.store,libcrypto.X509_LOOKUP_file()) if lookup is None: raise X509Error("error installing file lookup method") if (file is not None): - if not libcrypto.X509_LOOKUP_loadfile(lookup,file,1): + if not libcrypto.X509_LOOKUP_ctrl(lookup,1,file,1,None)>0: raise X509Error("error loading trusted certs from file "+file) - lookup=libcrypto.X509_STORE_add_lookup(self.store,libcrypto.X509_LOOKUP_hash_dir()) if lookup is None: raise X509Error("error installing hashed lookup method") if dir is not None: - if not libcrypto.X509_LOOKUP_add_dir(lookup,dir,1): + if not libcrypto.X509_LOOKUP_ctrl(lookup,2,dir,1,None)>0: raise X509Error("error adding hashed trusted certs dir "+dir) if default: - if not libcrypto.X509_LOOKUP.add_dir(lookup,None,3): + if not libcrypto.X509_LOOKUP_ctrl(lookup,2,None,3,None)>0: raise X509Error("error adding default trusted certs dir ") def add_cert(self,cert): """ @@ -302,3 +302,10 @@ libcrypto.X509_NAME_ENTRY_get_object.argtypes=(c_void_p,) libcrypto.OBJ_obj2nid.argtypes=(c_void_p,) libcrypto.X509_NAME_get_entry.restype=c_void_p libcrypto.X509_NAME_get_entry.argtypes=(c_void_p,c_int) +libcrypto.X509_STORE_new.restype=c_void_p +libcrypto.X509_STORE_add_lookup.restype=c_void_p +libcrypto.X509_STORE_add_lookup.argtypes=(c_void_p,c_void_p) +libcrypto.X509_LOOKUP_file.restype=c_void_p +libcrypto.X509_LOOKUP_hash_dir.restype=c_void_p +libcrypto.X509_LOOKUP_ctrl.restype=c_int +libcrypto.X509_LOOKUP_ctrl.argtypes=(c_void_p,c_int,c_char_p,c_long,POINTER(c_char_p)) diff --git a/tests/testx509.py b/tests/testx509.py index 65b4a7a..2a09e78 100644 --- a/tests/testx509.py +++ b/tests/testx509.py @@ -3,6 +3,7 @@ from ctypescrypto.x509 import X509,X509Store from ctypescrypto.oid import Oid +from tempfile import NamedTemporaryFile import unittest @@ -67,6 +68,47 @@ WSaUuftL/+yFk729xDoYkOZhFwUSUM5SbEZ0JpufWFjDi3Qwj3ZOTXliHC3e4C71 iFTXJP8/Au8kfezlA4b+eS81zWq2BFvNlBQsgf04S88oew0CuBBgtjUIIw7XZkS0 3QIDAQAB -----END PUBLIC KEY----- +""" + digicert_cert="""digicert.crt +-----BEGIN CERTIFICATE----- +MIIG5jCCBc6gAwIBAgIQAze5KDR8YKauxa2xIX84YDANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA3MTEwOTEyMDAwMFoXDTIxMTExMDAwMDAwMFowaTEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTEoMCYGA1UEAxMfRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgQ0EtMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPOWYth1bhn/ +PzR8SU8xfg0ETpmB4rOFVZEwscCvcLssqOcYqj9495BoUoYBiJfiOwZlkKq9ZXbC +7L4QWzd4g2B1Rca9dKq2n6Q6AVAXxDlpufFP74LByvNK28yeUE9NQKM6kOeGZrzw +PnYoTNF1gJ5qNRQ1A57bDIzCKK1Qss72kaPDpQpYSfZ1RGy6+c7pqzoC4E3zrOJ6 +4GAiBTyC01Li85xH+DvYskuTVkq/cKs+6WjIHY9YHSpNXic9rQpZL1oRIEDZaARo +LfTAhAsKG3jf7RpY3PtBWm1r8u0c7lwytlzs16YDMqbo3rcoJ1mIgP97rYlY1R4U +pPKwcNSgPqcCAwEAAaOCA4UwggOBMA4GA1UdDwEB/wQEAwIBhjA7BgNVHSUENDAy +BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUH +AwgwggHEBgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwCATCCAaQwOgYIKwYBBQUH +AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5o +dG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0 +AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1 +AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABp +AGcAaQBDAGUAcgB0ACAARQBWACAAQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBl +AGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBo +AGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAg +AGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAg +AGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wEgYDVR0TAQH/BAgwBgEB/wIBADCB +gwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy +dC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NBQ2Vy +dHMvRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3J0MIGPBgNVHR8EgYcw +gYQwQKA+oDyGOmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hB +c3N1cmFuY2VFVlJvb3RDQS5jcmwwQKA+oDyGOmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 +LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwHQYDVR0OBBYE +FExYyyXwQU9S9CjIgUObpqig5pLlMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSYJhoI +Au9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQBMeheHKF0XvLIyc7/NLvVYMR3wsXFU +nNabZ5PbLwM+Fm8eA8lThKNWYB54lBuiqG+jpItSkdfdXJW777UWSemlQk808kf/ +roF/E1S3IMRwFcuBCoHLdFfcnN8kpCkMGPAc5K4HM+zxST5Vz25PDVR708noFUjU +xbvcNRx3RQdIRYW9135TuMAW2ZXNi419yWBP0aKb49Aw1rRzNubS+QOy46T15bg+ +BEkAui6mSnKDcp33C4ypieez12Qf1uNgywPE3IjpnSUBAHHLA7QpYCWP+UbRe3Gu +zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA +-----END CERTIFICATE----- """ def test_readpubkey(self): c=X509(self.cert1) @@ -104,7 +146,31 @@ iFTXJP8/Au8kfezlA4b+eS81zWq2BFvNlBQsgf04S88oew0CuBBgtjUIIw7XZkS0 pk2=c.pubkey self.assertFalse(c.verify(key=pk2)) self.assertTrue(c.verify(key=pubkey)) + def test_default_filestore(self): + store=X509Store(default=True) + c1=X509(self.cert1) + # Cert signed by our CA shouldn't be successfully verified + # by default CA store + self.assertFalse(c1.verify(store)) + # but cert, downloaded from some commercial CA - should. + c2=X509(self.digicert_cert) + self.assertTrue(c2.verify(store)) def test_verify_by_filestore(self): + trusted=NamedTemporaryFile() + trusted.write(self.ca_cert) + trusted.flush() + goodcert=X509(self.cert1) + badcert=X509(self.cert1[0:-30]+"GG"+self.cert1[-28:]) + gitcert=X509(self.digicert_cert) + store=X509Store(file=trusted.name) + # We should successfuly verify certificate signed by our CA cert + self.assertTrue(goodcert.verify(store)) + # We should reject corrupted certificate + self.assertFalse(badcert.verify(store)) + # And if we specify explicitely certificate file, certificate, + # signed by some commercial CA should be rejected too + self.assertFalse(gitcert.verify(store)) + trusted.close() pass def test_verify_by_dirstore(self): pass -- 2.39.2