]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blobdiff - ctypescrypto/cms.py
StackOfX509 (untested)
[oss/ctypescrypto.git] / ctypescrypto / cms.py
index f1a4dbbefa26bc1787fca3af1ae0763ebbd675d4..2c038985aba8ae9488f37083115dc5dd69bb4e6b 100644 (file)
@@ -97,20 +97,26 @@ class CMSBase:
                
 class SignedData(CMSBase):
        @staticmethod
-       def create(data,cert,pkey,flags=Flags.BINARY):
+       def create(data,cert,pkey,flags=Flags.BINARY,certs=[]):
                """
                        Creates SignedData message by signing data with pkey and
                        certificate.
 
                        @param data - data to sign
                        @param pkey - pkey object with private key to sign
+                       @param flags - OReed combination of Flags constants
+                       @param certs - list of X509 objects to include into CMS
                """
                if not pkey.cansign:
                        raise ValueError("Specified keypair has no private part")
                if cert.pubkey!=pkey:
                        raise ValueError("Certificate doesn't match public key")
                b=Membio(data)
-               ptr=libcrypto.CMS_sign(cert.cert,pkey.ptr,None,b.bio,flags)
+               if certs is not None and len(certs)>0:
+                       certstack=StackOfX509(certs)
+               else:
+                       certstack=None
+               ptr=libcrypto.CMS_sign(cert.cert,pkey.ptr,certstack,b.bio,flags)
                if ptr is None:
                        raise CMSError("signing message")
                return SignedData(ptr)
@@ -142,27 +148,37 @@ class SignedData(CMSBase):
                        res= libcrypto.CMS_final(self.ptr,biodata,None,flags)
                        if res<=0:
                                raise CMSError
-       def verify(self,store,flags,data=None):
+       def verify(self,store,flags,data=None,certs=[]):
                """
                Verifies signature under CMS message using trusted cert store
 
                @param store -  X509Store object with trusted certs
                @param flags - OR-ed combination of flag consants
                @param data - message data, if messge has detached signature
+               param certs - list of certificates to use during verification
+                               If Flags.NOINTERN is specified, these are only
+                               sertificates to search for signing certificates
                @returns True if signature valid, False otherwise
                """
                bio=None
                if data!=None:
                        b=Membio(data)
                        bio=b.bio
-               res=libcrypto.CMS_verify(self.ptr,None,store.store,bio,None,flags)
+               if certs is not None and len(certs)>0:
+                       certstack=StackOfX509(certs)
+               else:
+                       certstack=None
+               res=libcrypto.CMS_verify(self.ptr,certstack,store.store,bio,None,flags)
                return res>0
        @property       
        def signers(self,store=None):
                """
                Return list of signer's certificates
                """
-               raise NotImplementedError
+               p=libcrypto.CMS_get0_signers(self.ptr)
+               if p is None:
+                       raise CMSError
+               return StackOfX509(ptr=p,disposable=False)
        @property
        def data(self):
                """
@@ -177,7 +193,8 @@ class SignedData(CMSBase):
                Adds a certificate (probably intermediate CA) to the SignedData
                structure
                """
-               raise NotImplementedError
+               if libcrypto.CMS_add1_cert(self.ptr,cert.cert)<=0:
+                       raise CMSError("adding cert")
        def addcrl(self,crl):
                """
                Adds a CRL to the signed data structure
@@ -188,7 +205,10 @@ class SignedData(CMSBase):
                """
                List of the certificates contained in the structure
                """
-               raise NotImplementedError
+               p=CMS_get1_certs(self.ptr)
+               if p is None:
+                       raise CMSError("getting certs")
+               return StackOfX509(ptr=p,disposable=True)
        @property
        def crls(self):
                """
@@ -206,8 +226,12 @@ class EnvelopedData(CMSBase):
                @param cipher - CipherType object
                @param flags - flag
                """
-               # Need to be able to handle OPENSSL stacks
-               raise NotImplementedError       
+               recp=StackOfX509(recipients)
+               b=Membio(data)
+               p=libcrypto.CMS_encrypt(recp.ptr,b.bio,cipher.cipher_type,flags)
+               if p is None:
+                       raise CMSError("encrypt EnvelopedData")
+               return EnvelopedData(p)
        def decrypt(self,pkey,cert,flags=0):
                """
                Decrypts message