X-Git-Url: http://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=ctypescrypto%2Fcms.py;h=2c038985aba8ae9488f37083115dc5dd69bb4e6b;hb=3af16f1cbc516e55cfc31af5dee0bc367a9ecbae;hp=f1a4dbbefa26bc1787fca3af1ae0763ebbd675d4;hpb=1dccf4b415022f7155d24132cc71e1826fedc359;p=oss%2Fctypescrypto.git diff --git a/ctypescrypto/cms.py b/ctypescrypto/cms.py index f1a4dbb..2c03898 100644 --- a/ctypescrypto/cms.py +++ b/ctypescrypto/cms.py @@ -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