In a previous post I discussed the method I used to integrate Paypal's
Encrypted Web Payments in generic SSL terms I hoped would make it easy to
implement from scratch in any language. I've had a request from Ross Poulton to
share the Python code that makes it work using the M2Crypto wrapper. So, here
it is:

fromM2CryptoimportBIO,SMIME,X509fromdjango.confimportsettingsclassPaypalOrder(dict):"""Acts as a dictionary which can be encrypted to Paypal's EWP service"""def__init__(self,*args,**kwargs):dict.__init__(self,*args,**kwargs)self['cert_id']=settings.MY_CERT_IDdefset_notify_url(self,notify_url):self['notify_url']=notify_url# snip more wrapper functionsdefplaintext(self):"""The plaintext for the cryptography operation."""s=''forkinself:s+=u'%s=%s\n'%(k,self[k])returns.encode('utf-8')__str__=plaintextdefencrypt(self):"""Return the contents of this order, encrypted to Paypal's certificate and signed using the private key configured in the Django settings."""# Instantiate an SMIME object.s=SMIME.SMIME()# Load signer's key and cert.s.load_key_bio(BIO.openfile(settings.MY_KEYPAIR),BIO.openfile(settings.MY_CERT))# Sign the buffer.p7=s.sign(BIO.MemoryBuffer(self.plaintext()),flags=SMIME.PKCS7_BINARY)# Load target cert to encrypt the signed message to.x509=X509.load_cert_bio(BIO.openfile(settings.PAYPAL_CERT))sk=X509.X509_Stack()sk.push(x509)s.set_x509_stack(sk)# Set cipher: 3-key triple-DES in CBC mode.s.set_cipher(SMIME.Cipher('des_ede3_cbc'))# Create a temporary buffer.tmp=BIO.MemoryBuffer()# Write the signed message into the temporary buffer.p7.write_der(tmp)# Encrypt the temporary buffer.p7=s.encrypt(tmp,flags=SMIME.PKCS7_BINARY)# Output p7 in mail-friendly format.out=BIO.MemoryBuffer()p7.write(out)returnout.read()

The settings required are as follows:

# path to keypair in PEM formatMY_KEYPAIR='keys/keypair.pem'# path to merchant certificateMY_CERT='keys/merchant.crt'# code which Paypal assign to the certificate when you upload itMY_CERT_ID='ASDF12345'# path to Paypal's own certificatePAYPAL_CERT='keys/paypal.crt'