]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blobdiff - ctypescrypto/x509.py
Add X509 to __all__. Add pem() method to X509
[oss/ctypescrypto.git] / ctypescrypto / x509.py
index 358ce7d81d7d244ca1d44b2dfc34769e2c1e0f9d..bd81fdd01c207f04b024f5d75d3b673d97a9b628 100644 (file)
@@ -18,9 +18,9 @@ from datetime import datetime
 try:
        from pytz import utc
 except ImportError:
-       from datetime import timedelta
+       from datetime import timedelta,tzinfo
        ZERO=timedelta(0)
-       class UTC(datetime.tzinfo):
+       class UTC(tzinfo):
                """tzinfo object for UTC. 
                        If no pytz is available, we would use it.
                """
@@ -36,7 +36,7 @@ except ImportError:
 
        utc=UTC()
 
-__all__ = ['X509Error','X509Name','X509Store','StackOfX509']
+__all__ = ['X509','X509Error','X509Name','X509Store','StackOfX509']
 
 class _validity(Structure):
        """ ctypes representation of X509_VAL structure 
@@ -83,7 +83,7 @@ class X509Error(LibCryptoError):
        pass
 
 
-class X509Name:
+class X509Name(object):
        """
        Class which represents X.509 distinguished name - typically 
        a certificate subject name or an issuer name.
@@ -148,13 +148,13 @@ class X509Name:
                        # Return first matching field
                        idx=libcrypto.X509_NAME_get_index_by_NID(self.ptr,key.nid,-1)
                        if idx<0:
-                               raise KeyError("Key not found "+repr(Oid))
+                               raise KeyError("Key not found "+str(Oid))
                        entry=libcrypto.X509_NAME_get_entry(self.ptr,idx)
                        s=libcrypto.X509_NAME_ENTRY_get_data(entry)
                        b=Membio()
                        libcrypto.ASN1_STRING_print_ex(b.bio,s,self.PRINT_FLAG)
                        return unicode(b)
-               elif isinstance(key,int):
+               elif isinstance(key,(int,long)):
                        # Return OID, string tuple
                        entry=libcrypto.X509_NAME_get_entry(self.ptr,key)
                        if entry is None:
@@ -164,10 +164,21 @@ class X509Name:
                        b=Membio()
                        libcrypto.ASN1_STRING_print_ex(b.bio,s,self.PRINT_FLAG)
                        return (oid,unicode(b))
+               else:
+                       raise TypeError("X509 NAME can be indexed by Oids or integers only")
 
        def __setitem__(self,key,val):
                if not self.writable:
                        raise ValueError("Attempt to modify constant X509 object")
+               else:
+                       raise NotImplementedError
+       def __delitem__(self,key):
+               if not self.writable:
+                       raise ValueError("Attempt to modify constant X509 object")
+               else:
+                       raise NotImplementedError
+       def __hash__(self):
+               return libcrypto.X509_NAME_hash(self.ptr)
 
 class _x509_ext(Structure):
        """ Represens C structure X509_EXTENSION """
@@ -191,7 +202,6 @@ class X509_EXT(object):
        def __str__(self):
                b=Membio()
                libcrypto.X509V3_EXT_print(b.bio,self.ptr,0x20010,0)
-               libcrypto.X509V3_EXT_print.argtypes=(c_void_p,POINTER(_x509_ext),c_long,c_int)
                return str(b)
        def __unicode__(self):
                b=Membio()
@@ -295,6 +305,12 @@ class X509(object):
        def pubkey(self):
                """EVP PKEy object of certificate public key"""
                return PKey(ptr=libcrypto.X509_get_pubkey(self.cert,False))
+       def pem(self):
+               """ Returns PEM represntation of the certificate """
+               b=Membio()
+               if libcrypto.PEM_write_bio_X509(b.bio,self.cert)==0:
+                       raise X509Error("error serializing certificate")
+               return str(b)
        def verify(self,store=None,chain=[],key=None):  
                """ 
                Verify self. Supports verification on both X509 store object 
@@ -376,7 +392,7 @@ class X509(object):
        def check_ca(self):
                """ Returns True if certificate is CA certificate """
                return libcrypto.X509_check_ca(self.cert)>0
-class X509Store:
+class X509Store(object):
        """
                Represents trusted certificate store. Can be used to lookup CA 
                certificates to verify
@@ -467,7 +483,7 @@ class X509Store:
                else:
                        raise TypeError("datetime.date, datetime.datetime or integer is required as time argument")
                raise NotImplementedError
-class StackOfX509:
+class StackOfX509(object):
        """
        Implements OpenSSL STACK_OF(X509) object.
        It looks much like python container types
@@ -486,11 +502,11 @@ class StackOfX509:
                """
                if  ptr is None:
                        self.need_free = True
-                       self.ptr=libcrypt.sk_new_null()
+                       self.ptr=libcrypto.sk_new_null()
                        if certs is not None:
                                for crt in certs:
                                        self.append(crt)
-               elif not certs is None:
+               elif certs is not None:
                                raise ValueError("cannot handle certs an ptr simultaneously")
                else:
                        self.need_free = disposable
@@ -502,12 +518,15 @@ class StackOfX509:
                        raise IndexError
                p=libcrypto.sk_value(self.ptr,index)
                return X509(ptr=libcrypto.X509_dup(p))
-       def __putitem__(self,index,value):
+       def __setitem__(self,index,value):
                if not self.need_free:
                        raise ValueError("Stack is read-only")
                if index <0 or index>=len(self):
                        raise IndexError
-               p=libcrypto.sk_set(self.ptr,index,libcrypto.X509_dup(value.cert))
+               if not isinstance(value,X509):
+                       raise TypeError('StackOfX508 can contain only X509 objects')
+               p=libcrypto.sk_value(self.ptr,index)
+               libcrypto.sk_set(self.ptr,index,libcrypto.X509_dup(value.cert))
                libcrypto.X509_free(p)
        def __delitem__(self,index):    
                if not self.need_free:
@@ -522,9 +541,15 @@ class StackOfX509:
        def append(self,value):
                if not self.need_free:
                        raise ValueError("Stack is read-only")
+               if not isinstance(value,X509):
+                       raise TypeError('StackOfX508 can contain only X509 objects')
                libcrypto.sk_push(self.ptr,libcrypto.X509_dup(value.cert))
 libcrypto.i2a_ASN1_INTEGER.argtypes=(c_void_p,c_void_p)
 libcrypto.ASN1_STRING_print_ex.argtypes=(c_void_p,c_void_p,c_long)
+libcrypto.PEM_read_bio_X509.restype=c_void_p
+libcrypto.PEM_read_bio_X509.argtypes=(c_void_p,POINTER(c_void_p),c_void_p,c_void_p)
+libcrypto.PEM_write_bio_X509.restype=c_int
+libcrypto.PEM_write_bio_X509.argtypes=(c_void_p,c_void_p)
 libcrypto.ASN1_TIME_print.argtypes=(c_void_p,c_void_p)
 libcrypto.ASN1_INTEGER_get.argtypes=(c_void_p,)
 libcrypto.ASN1_INTEGER_get.restype=c_long
@@ -547,3 +572,13 @@ libcrypto.X509_EXTENSION_dup.restype=POINTER(_x509_ext)
 libcrypto.X509V3_EXT_print.argtypes=(c_void_p,POINTER(_x509_ext),c_long,c_int)
 libcrypto.X509_get_ext.restype=c_void_p
 libcrypto.X509_get_ext.argtypes=(c_void_p,c_int)
+libcrypto.X509V3_EXT_print.argtypes=(c_void_p,POINTER(_x509_ext),c_long,c_int)
+libcrypto.sk_set.argtypes=(c_void_p,c_int,c_void_p)
+libcrypto.sk_set.restype=c_void_p
+libcrypto.sk_value.argtypes=(c_void_p,c_int)
+libcrypto.sk_value.restype=c_void_p
+libcrypto.X509_dup.restype=c_void_p
+libcrypto.sk_new_null.restype=c_void_p
+libcrypto.X509_dup.argtypes=(c_void_p,)
+libcrypto.X509_NAME_hash.restype=c_long
+libcrypto.X509_NAME_hash.argtypes=(c_void_p,)