def decrypt_verify(p7file, recip_key, signer_cert, ca_cert): s = SMIME.SMIME() # Load decryption private key. s.load_key(recip_key) # Extract PKCS#7 blob from input. p7, bio = SMIME.smime_load_pkcs7_bio(p7file) # Decrypt. data = s.decrypt(p7) # Because we passed in a SignAndEnveloped blob, the output # of our decryption is a Signed blob. We now verify it. # Load the signer's cert. sk = X509.X509_Stack() s.set_x509_stack(sk) # Load the CA cert. st = X509.X509_Store() st.load_info(ca_cert) s.set_x509_store(st) # Verify. p7, bio = SMIME.smime_load_pkcs7_bio(BIO.MemoryBuffer(data)) if bio is not None: # Netscape Messenger clear-signs, when also encrypting. data = s.verify(p7, bio) else: # M2Crypto's sendsmime.py opaque-signs, when also encrypting. data = s.verify(p7) print data
def verify(self, data, signature, ca_name, detached=True): """Verify detached SMIME signature. Requires CA cert. Returns tuple (data, signer_details_dict). """ sm = self.get_verify_ctx(ca_name) # init data bsign = BIO.MemoryBuffer(signature) if RAW_MESSAGES: pk = load_pkcs7_bio_der(bsign) else: pk = SMIME.load_pkcs7_bio(bsign) # check signature if detached: bdata = BIO.MemoryBuffer(data) data2 = sm.verify(pk, bdata, flags = SMIME.PKCS7_BINARY | SMIME.PKCS7_DETACHED) assert data2 == data elif data: raise Exception('Have data when detached=False') else: data2 = sm.verify(pk, flags = SMIME.PKCS7_BINARY) return data2, self.get_signature_info(sm, pk)
def test_verify_with_static_callback(self): s = SMIME.SMIME() x509 = X509.load_cert('tests/signer.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) st = X509.X509_Store() st.load_info('tests/ca.pem') st.set_verify_cb(verify_cb_rejects_cert_from_heikki_toivonen) s.set_x509_store(st) p7, data = SMIME.smime_load_pkcs7_bio(self.signed) self.assertIsInstance(p7, SMIME.PKCS7, p7) # Should reject certificate issued by Heikki Toivonen: with self.assertRaises(SMIME.PKCS7_Error): s.verify(p7, data) st.set_verify_cb(verify_cb_dummy_function) v = s.verify(p7, data) self.assertEqual(v, self.cleartext) st.set_verify_cb() v = s.verify(p7, data) self.assertEqual(v, self.cleartext)
def verify_signers(self,signature_place): """ The module will control the signers in the pkcs7 doc 1)If they are valid 2)If they are modified 3)is a valid chain 4)check with db if it is there If all Ok return true else false""" try: if not os.path.exists(signature_place): print "No signature file" return False tempSt=self.get_cert_from_sign(signature_place) if not tempSt: return False #Loading the document in p7 object for upper method self.__p7=SMIME.load_pkcs7(signature_place) #---The OLD Code----- #sk = X509.X509_Stack() #print "The p7 file loaded" #print self.__p7.get0_signers(sk) #del sk except SMIME.SMIME_Error,e: print "Error while setting pkcs7 verification process :",e return False
def verify_pkcs7(pkcs7_sig, document): try: # raw_sig = pkcs7_sig raw_sig = str(pkcs7_sig).encode('ascii') msg = document sm_obj = SMIME.SMIME() x509 = X509.load_cert(os.path.join(config.APP_STATIC, 'AWSpubkey')) # public key cert used by the remote # client when signing the message sk = X509.X509_Stack() sk.push(x509) sm_obj.set_x509_stack(sk) st = X509.X509_Store() st.load_info(os.path.join(config.APP_STATIC, 'AWSpubkey')) # Public cert for the CA which signed # the above certificate sm_obj.set_x509_store(st) # re-wrap signature so that it fits base64 standards cooked_sig = '\n'.join(raw_sig[pos:pos + 76] for pos in xrange(0, len(raw_sig), 76)) # cooked_sig = raw_sig # now, wrap the signature in a PKCS7 block sig = ("-----BEGIN PKCS7-----\n" + cooked_sig + "\n-----END PKCS7-----").encode('ascii') # and load it into an SMIME p7 object through the BIO I/O buffer: buf = BIO.MemoryBuffer(sig) p7 = SMIME.load_pkcs7_bio(buf) # finally, try to verify it: if dict(json.loads(sm_obj.verify(p7))) == dict(json.loads(msg)): return True else: return False except Exception as e: raise Exception("INVALID CLIENT MESSAGE SIGNATURE")
def verify(certificate_path, ca_certificate_path, sign_request_path, output): certificate = None try: certificate = X509.load_cert(certificate_path) except (X509.X509Error, IOError): print('ERROR verify: Could not load certificate for verifying') exit(1) smime = SMIME.SMIME() stack = X509.X509_Stack() stack.push(certificate) smime.set_x509_stack(stack) store = X509.X509_Store() store.load_info(ca_certificate_path) smime.set_x509_store(store) pks7, data = SMIME.smime_load_pkcs7(sign_request_path) clear_text = smime.verify(pks7, data) if not output: output = path.abspath(path.curdir) + '/%s.csr' % DEFAULT_FIELDS['CN'] if clear_text: request = X509.load_request_string(clear_text) request.save(output) print('Verification OK') print('Request file was saved to %s' % output) else: print('Verification failed')
def sv(): print 'test sign/verify...', buf = makebuf() s = SMIME.SMIME() # Load a private key. s.load_key('client.pem') # Sign. p7 = s.sign(buf, SMIME.PKCS7_DETACHED) # Output the stuff. buf = makebuf() # Recreate buf, because sign() has consumed it. bio = BIO.MemoryBuffer() s.write(bio, p7, buf) # Plumbing for verification: CA's cert. st = X509.X509_Store() st.load_info('ca.pem') s.set_x509_store(st) # Plumbing for verification: Signer's cert. x509 = X509.load_cert('client.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Verify. p7, buf = SMIME.smime_load_pkcs7_bio(bio) v = s.verify(p7, buf, flags=SMIME.PKCS7_DETACHED) if v: print 'ok' else: print 'not ok'
def verify_mdm_signature(mdm_sig, req_data): '''Verify the client's supplied MDM signature and return the client certificate included in the signature.''' pkcs7_pem_sig = base64_to_pem('PKCS7', mdm_sig) p7_bio = BIO.MemoryBuffer(str(pkcs7_pem_sig)) p7 = SMIME.load_pkcs7_bio(p7_bio) p7_signers = p7.get0_signers(X509.X509_Stack()) mdm_ca = get_ca() # can probably directly use m2 certificate here ca_x509_bio = BIO.MemoryBuffer(mdm_ca.get_cacert().get_pem()) ca_x509 = X509.load_cert_bio(ca_x509_bio) cert_store = X509.X509_Store() cert_store.add_x509(ca_x509) signer = SMIME.SMIME() signer.set_x509_store(cert_store) signer.set_x509_stack(p7_signers) # NOTE: may need to do something special if we can't cleanly convert # to string from Unicode. must be byte-accurate as the signature won't # match otherwise data_bio = BIO.MemoryBuffer(req_data) # will raise an exception if verification fails # if no CA certificate we get an: # PKCS7_Error: certificate verify error signer.verify(p7, data_bio) return p7_signers[0].as_pem()
def test_load_smime_bio(self): with open(self.filenameSmime, 'rb') as f: buf = BIO.MemoryBuffer(f.read()) a, b = SMIME.smime_load_pkcs7_bio(buf) self.assertIsInstance(a, SMIME.PKCS7, a) self.assertIsInstance(b, BIO.BIO, b) self.assertEqual(a.type(), SMIME.PKCS7_SIGNED)
def decrypt_payload(payload, key, passphrase): global key_pass key_pass = passphrase privkey = SMIME.SMIME() privkey.load_key(key, callback=getKeyPassphrase) # Load the encrypted data. p7, data = SMIME.smime_load_pkcs7_bio(BIO.MemoryBuffer(payload)) return privkey.decrypt(p7)
def test_signEncryptDecryptVerify(self): # sign buf = BIO.MemoryBuffer(self.cleartext) s = SMIME.SMIME() s.load_key('test/signer_key.pem', 'test/signer.pem') p7 = s.sign(buf) # encrypt x509 = X509.load_cert('test/recipient.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) s.set_cipher(SMIME.Cipher('des_ede3_cbc')) tmp = BIO.MemoryBuffer() s.write(tmp, p7) p7 = s.encrypt(tmp) signedEncrypted = BIO.MemoryBuffer() s.write(signedEncrypted, p7) # decrypt s = SMIME.SMIME() s.load_key('test/recipient_key.pem', 'test/recipient.pem') p7, data = SMIME.smime_load_pkcs7_bio(signedEncrypted) out = s.decrypt(p7) # verify x509 = X509.load_cert('test/signer.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) st = X509.X509_Store() st.load_info('test/ca.pem') s.set_x509_store(st) p7_bio = BIO.MemoryBuffer(out) p7, data = SMIME.smime_load_pkcs7_bio(p7_bio) v = s.verify(p7) assert v == self.cleartext
def get_keyfile(directory, name, ext='yaml'): """Returns the DECRYPTED keyfile named by the given `directory', `name' and `ext' (as passed to ``keyfile_path'').""" s = SMIME.SMIME() s.load_key(env.ec2.pk, env.ec2.cert) p7, data = SMIME.smime_load_pkcs7(keyfile_path(directory, name, ext)) return s.decrypt(p7)
def test_load_bad(self): s = SMIME.SMIME() with self.assertRaises(EVP.EVPError): s.load_key('tests/signer.pem', 'tests/signer.pem') with self.assertRaises(BIO.BIOError): SMIME.load_pkcs7('nosuchfile-dfg456') with self.assertRaises(SMIME.PKCS7_Error): SMIME.load_pkcs7('tests/signer.pem') with self.assertRaises(SMIME.PKCS7_Error): SMIME.load_pkcs7_bio(BIO.MemoryBuffer('no pkcs7')) with self.assertRaises(SMIME.SMIME_Error): SMIME.smime_load_pkcs7('tests/signer.pem') with self.assertRaises(SMIME.SMIME_Error): SMIME.smime_load_pkcs7_bio(BIO.MemoryBuffer('no pkcs7'))
def test_load_smime_bio(self): f = open(self.filenameSmime, 'rb') buf = BIO.MemoryBuffer(f.read()) f.close() a, b = SMIME.smime_load_pkcs7_bio(buf) assert isinstance(a, SMIME.PKCS7), a assert isinstance(b, BIO.BIO), b assert a.type() == SMIME.PKCS7_SIGNED
def Process(self,inputString): self.verified = False # Note we cast to a String type as unicode will not verify buf = BIO.MemoryBuffer(str(inputString)) sk = X509.X509_Stack() try: InputP7, Inputdata = SMIME.smime_load_pkcs7_bio(buf) except SMIME.SMIME_Error , e: raise smimeX509ValidationError(e)
def validate_text(self,text_to_verify): buf = BIO.MemoryBuffer(text_to_verify) sk = X509.X509_Stack() p7, data = SMIME.smime_load_pkcs7_bio(buf) try: supplied_stack = p7.get0_signers(sk) except AttributeError, e: if str(e) == "PKCS7 instance has no attribute 'get0_signers'": self.logger.error('m2crypto version 0.18 is the minimum supported, please upgrade.') raise e
def verify_payload(msg, raw_sig, cert, ca_cert, verify_cert): signer = SMIME.SMIME() signerKey = X509.X509_Stack() signerKey.push(X509.load_cert(cert)) signer.set_x509_stack(signerKey) signerStore = X509.X509_Store() signerStore.load_info(ca_cert) signer.set_x509_store(signerStore) if raw_sig: raw_sig.strip() sig = "-----BEGIN PKCS7-----\n%s\n-----END PKCS7-----\n"%raw_sig.replace('\r\n','\n') p7 = SMIME.load_pkcs7_bio(BIO.MemoryBuffer(sig)) data_bio = BIO.MemoryBuffer(msg) if verify_cert: signer.verify(p7, data_bio) else: signer.verify(p7, data_bio,SMIME.PKCS7_NOVERIFY) else: p7, data_bio = SMIME.smime_load_pkcs7_bio(BIO.MemoryBuffer(msg)) signer.verify(p7, data_bio)
def test_decryptBad(self): s = SMIME.SMIME() s.load_key('test/signer_key.pem', 'test/signer.pem') p7, data = SMIME.smime_load_pkcs7_bio(self.encrypted) assert isinstance(p7, SMIME.PKCS7), p7 self.assertRaises(SMIME.SMIME_Error, s.verify, p7) # No signer # Cannot decrypt: no recipient matches certificate self.assertRaises(SMIME.PKCS7_Error, s.decrypt, p7)
def verify_sig_cert(sig, sender, local_domain): import certvld p7 = SMIME.load_pkcs7_bio(BIO.MemoryBuffer(sig)) certs = p7.get0_signers(X509.X509_Stack()) if len(certs) == 0: return False for cert in certs: if certvld.verify_cert(cert, local_domain, sender) and certvld.verify_binding(cert, sender, sender.partition('@')[2], True): return True return False
def test_decrypt(self): s = SMIME.SMIME() s.load_key('test/recipient_key.pem', 'test/recipient.pem') p7, data = SMIME.smime_load_pkcs7_bio(self.encrypted) assert isinstance(p7, SMIME.PKCS7), p7 self.assertRaises(SMIME.SMIME_Error, s.verify, p7) # No signer out = s.decrypt(p7) assert out == self.cleartext
def test_decrypt(self): s = SMIME.SMIME() s.load_key('tests/recipient_key.pem', 'tests/recipient.pem') p7, data = SMIME.smime_load_pkcs7_bio(self.encrypted) self.assertIsInstance(p7, SMIME.PKCS7, p7) with self.assertRaises(SMIME.SMIME_Error): s.verify(p7) # No signer out = s.decrypt(p7) self.assertEqual(out, self.cleartext)
def verify_netscape(): print 'test load & verify netscape messager output...', s = SMIME.SMIME() #x509 = X509.load_cert('client.pem') sk = X509.X509_Stack() #sk.push(x509) s.set_x509_stack(sk) st = X509.X509_Store() st.load_info('ca.pem') s.set_x509_store(st) p7, data = SMIME.smime_load_pkcs7('ns.p7') v = s.verify(p7, data) print '\n', v, '\n...ok'
def _run(self, scanObject, result, depth, args): moduleResult = [] flags = [] buffer = scanObject.buffer cert = None try: #scanObject.addMetadata(self.module_name, key, value) input_bio = BIO.MemoryBuffer(buffer) #Check for PEM or DER if buffer[:1] == "0": #DER p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1) else: #PEM p7 = SMIME.load_pkcs7_bio(input_bio) certs = p7.get0_signers(X509.X509_Stack()) #some pkcs7's should have more than one certificate in them. openssl can extract them handily. #openssl pkcs7 -inform der -print_certs -in MYKEY.DSA i=0 for cert in certs: cert_filename = "%x.der" % (cert.get_serial_number()) moduleResult.append(ModuleObject(buffer=cert.as_der(),externalVars=ExternalVars(filename=cert_filename))) i = i + 1 except (QuitScanException, GlobalScanTimeoutError, GlobalModuleTimeoutError): raise except: exc_type, exc_value, exc_traceback = sys.exc_info() logging.exception("Error parsing cert in "+str(get_scanObjectUID(getRootObject(result)))) ugly_error_string = str(exc_value) #nicer_error_string = string.split(string.split(ugly_error_string,":")[4])[0] nicer_error_string = ugly_error_string.split(":")[4].split()[0] scanObject.addFlag("pkcs7:err:"+nicer_error_string) return moduleResult
def test_verifyBad(self): s = SMIME.SMIME() x509 = X509.load_cert('test/recipient.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) st = X509.X509_Store() st.load_info('test/recipient.pem') s.set_x509_store(st) p7, data = SMIME.smime_load_pkcs7_bio(self.signed) assert isinstance(p7, SMIME.PKCS7), p7 self.assertRaises(SMIME.PKCS7_Error, s.verify, p7) # Bad signer
def decrypt(input_bio, private_key, cert, keyring_source, type): """ Decrypts the input data with the private key and the certificate from keyring source. @type input_bio: M2Crypto.BIO @param input_bio: input data to sign. @type private_key: filepath or M2Crypto.BIO or M2Crypto.EVP.PKey @param private_key: recipient private key reference, could be from file, from memory or from pkcs11 smartcard, based on keyring_soruce input parameter. @type cert: filepath or M2Crypto.BIO or M2Crypto.X509.X509 @param cert: recipient certificate, could be from filepath, from memory or from pkcs11 smartcard, based on keyring_soruce input parameter. @type keyring_source: str @keyword keyring_source: the type of the source for input certificate, used to recall the appropriate method for decrypter settings. Ammitted values are: file, memory, pkcs11. @type type: str @keyword type: specifies the type of input PKCS#7 data: PEM or DER @rtype: str @return: the decrypted data in plain form. @raise BadPKCS7Type: The requested PKCS#7 type is not valid. Ammitted values are PEM and DER. """ decrypter = SMIME.SMIME() set_keyring(decrypter, private_key, cert, keyring_source) try: if type == 'PEM': p7, data_bio = SMIME.smime_load_pkcs7_bio(input_bio) elif type == 'DER': p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1) else: logging.error('pkcs7 type error: unknown type') raise BadPKCS7Type('unknown type: ' + type + '; possible values: PEM, DER') except SMIME.SMIME_Error as e: logging.error('load pkcs7 error: ' + str(e)) pass try: decrypted_data = decrypter.decrypt(p7) except SMIME.SMIME_Error as e: logging.error('smime error: ' + str(e)) raise except SMIME.PKCS7_Error as e: logging.error('pkcs7 error: ' + str(e)) raise return decrypted_data.replace(b'\r', b'')
def verify(self, text): """ verifies a signed SMIME email returns a list of certificates used to sign the SMIME message on success text - string containing the SMIME signed message >>> v = Verifier('/etc/apache/ssl.crt/ca-bundle.crt') >>> v.verify('pippo') Traceback (most recent call last): File "<stdin>", line 1, in ? File "signer.py", line 23, in __init__ raise VerifierError, e VerifierError: cannot extract payloads from message >>> >>> certs = v.verify(test_email) >>> isinstance(certs, list) and len(certs) > 0 True >>> """ if self._smime is None: self._setup() buf = BIO.MemoryBuffer(text) try: p7, data_bio = SMIME.smime_load_pkcs7_bio(buf) except SystemError: # uncaught exception in M2Crypto raise VerifierError, "cannot extract payloads from message" if data_bio is not None: data = data_bio.read() data_bio = BIO.MemoryBuffer(data) sk3 = p7.get0_signers(X509.X509_Stack()) if len(sk3) == 0: raise VerifierError, "no certificates found in message" signer_certs = [] for cert in sk3: signer_certs.append( "-----BEGIN CERTIFICATE-----\n%s-----END CERTIFICATE-----" \ % base64.encodestring(cert.as_der())) self._smime.set_x509_stack(sk3) try: if data_bio is not None: v = self._smime.verify(p7, data_bio) else: v = self._smime.verify(p7) except SMIME.SMIME_Error, e: raise VerifierError, "message verification failed: %s" % e
def verify_opaque(): print 'test load & verify opaque...', s = SMIME.SMIME() x509 = X509.load_cert('client.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) st = X509.X509_Store() st.load_info('ca.pem') s.set_x509_store(st) p7, data = SMIME.smime_load_pkcs7('opaque.p7') v = s.verify(p7, data) if v: print 'ok' else: print 'not ok'
def image_by_sha512_writefile_json(self,treess,sha512,path): query_image = self.session.query(model.ImageInstance,model.ImageListInstance).\ filter(model.ImageInstance.fkimagelistinstance == model.ImageListInstance.id).\ filter(model.ImageInstance.sha512 == sha512) if query_image.count() == 0: self.log.warning('Message not found') return False fp = open(path,'w') for touple_set in query_image: image = touple_set[0] image_list = touple_set[1] buf = BIO.MemoryBuffer(str(image_list.data)) sk = X509.X509_Stack() p7, data = SMIME.smime_load_pkcs7_bio(buf) data_str = data.read() fp.write(data_str) fp.close()
def decrypt(self, ciphtext, receiver_name): """Decrypt message. Requires private key and it's cert. Returns decrypted message. """ sm = self.get_decrypt_ctx(receiver_name) # decrypt bdata = BIO.MemoryBuffer(ciphtext) if RAW_MESSAGES: pk = load_pkcs7_bio_der(bdata) else: pk = SMIME.load_pkcs7_bio(bdata) return sm.decrypt(pk, SMIME.PKCS7_BINARY)
def test_verify_with_method_callback(self): s = SMIME.SMIME() x509 = X509.load_cert('tests/signer.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) st = X509.X509_Store() st.load_info('tests/ca.pem') st.set_verify_cb(self.verify_cb_dummy_method) s.set_x509_store(st) p7, data = SMIME.smime_load_pkcs7_bio(self.signed) self.assertIsInstance(p7, SMIME.PKCS7, p7) v = s.verify(p7, data) self.assertEqual(v, self.cleartext)
def test_load_smime(self): a, b = SMIME.smime_load_pkcs7(self.filenameSmime) assert isinstance(a, SMIME.PKCS7), a assert isinstance(b, BIO.BIO), b assert a.type() == SMIME.PKCS7_SIGNED
from M2Crypto import BIO, SMIME, X509 # Instantiate an SMIME object. s = SMIME.SMIME() # ------------ DECRYPT # Load private key and cert. s.load_key('sample_keys/recipient_key.pem', 'sample_keys/recipient.pem') # Load the encrypted data. p7, data = SMIME.smime_load_pkcs7('se.p7') # Decrypt p7. out = s.decrypt(p7) # ------------ VERIFY # load the signer's cert x509 = X509.load_cert('sample_keys/signer.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # load the signer's CA cert (in this case, the signer's # cert itself because it is self-signed) st = X509.X509_Store() st.load_info('sample_keys/signer.pem') s.set_x509_store(st) p7_bio = BIO.MemoryBuffer(out)
from M2Crypto import SMIME, X509 # Instantiate an SMIME object. s = SMIME.SMIME() # Load the signer's cert. x509 = X509.load_cert('signer.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Load the signer's CA cert. In this case, because the signer's # cert is self-signed, it is the signer's cert itself. st = X509.X509_Store() st.load_info('signer.pem') s.set_x509_store(st) # Load the data, verify it. p7, data = SMIME.smime_load_pkcs7('sign.p7') ''' v = s.verify(p7,data) print v print data print data.read() '''
def check_if_singed(self, pe) -> list: ''' check file if it has Signature or not ''' i = 0 _list = [] _extracted = {} Problems = False address = pe.OPTIONAL_HEADER.DATA_DIRECTORY[ DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress if address != 0: try: sig = pe.write()[address + 8:] m2cbio = BIO.MemoryBuffer(bytes(sig)) if m2cbio: pkcs7bio = m2.pkcs7_read_bio_der(m2cbio.bio_ptr()) if pkcs7bio: pkcs7 = SMIME.PKCS7(pkcs7bio) for cert in pkcs7.get0_signers(X509.X509_Stack()): tempcert = "CERT_{}".format(i) _extracted[tempcert] = { "CommonName": None, "OrganizationalUnit": None, "Organization": None, "Locality": None, "StateOrProvinceName": None, "CountryName": None, "Start": None, "Ends": None, "SerialNumber": None } try: _extracted[tempcert][ "CommonName"] = cert.get_subject().CN except: pass try: _extracted[tempcert][ "OrganizationalUnit"] = cert.get_subject( ).OU except: pass try: _extracted[tempcert][ "Organization"] = cert.get_subject().O except: pass try: _extracted[tempcert][ "Locality"] = cert.get_subject().L except: pass try: _extracted[tempcert][ "StateOrProvinceName"] = cert.get_subject( ).S except: pass try: _extracted[tempcert][ "CountryName"] = cert.get_subject().C except: pass try: _extracted[tempcert][ "Email"] = cert.get_subject().Email except: pass try: _extracted[tempcert]["Start"] = str( cert.get_not_before()) except: pass try: _extracted[tempcert]["Ends"] = str( cert.get_not_after()) except: pass try: _extracted[tempcert][ "SerialNumber"] = cert.get_serial_number() _extracted[tempcert][ "SerialNumberMD5"] = cert.get_fingerprint( 'md5').lower().rjust(32, '0') except: pass except: Problems = True sighex = "".join("{:02x}".format(x) for x in sig) _list.append({"Wrong": Problems, "SignatureHex": sighex}) return _list, _extracted
x509_sign_keyfile or self.settings.x509_sign_certfile # crypt certfiles could be a string or a list x509_crypt_certfiles = x509_crypt_certfiles or self.settings.x509_crypt_certfiles x509_nocerts = x509_nocerts or\ self.settings.x509_nocerts # need m2crypto try: from M2Crypto import BIO, SMIME, X509 except Exception, e: self.error = "Can't load M2Crypto module" return False msg_bio = BIO.MemoryBuffer(payload_in.as_string()) s = SMIME.SMIME() # SIGN if sign: # key for signing try: keyfile_bio = BIO.openfile(x509_sign_keyfile)\ if os.path.isfile(x509_sign_keyfile)\ else BIO.MemoryBuffer(x509_sign_keyfile) sign_certfile_bio = BIO.openfile(x509_sign_certfile)\ if os.path.isfile(x509_sign_certfile)\ else BIO.MemoryBuffer(x509_sign_certfile) s.load_key_bio(keyfile_bio, sign_certfile_bio, callback=lambda x: sign_passphrase) if x509_sign_chainfile: sk = X509.X509_Stack()
def sign_tra(tra, cert=CERT, privatekey=PRIVATEKEY, passphrase=""): "Firmar PKCS#7 el TRA y devolver CMS (recortando los headers SMIME)" if BIO: print("pudo importar m2crypto") # Firmar el texto (tra) usando m2crypto (openssl bindings para python) buf = BIO.MemoryBuffer(tra) # Crear un buffer desde el texto #Rand.load_file('randpool.dat', -1) # Alimentar el PRNG s = SMIME.SMIME() # Instanciar un SMIME # soporte de contraseña de encriptación (clave privada, opcional) callback = lambda *args, **kwarg: passphrase # Cargar clave privada y certificado if not privatekey.startswith("-----BEGIN RSA PRIVATE KEY-----"): # leer contenido desde archivo (evitar problemas Applink / MSVCRT) if os.path.exists(privatekey) and os.path.exists(cert): privatekey = open(privatekey).read() cert = open(cert).read() else: raise RuntimeError("Archivos no encontrados: %s, %s" % (privatekey, cert)) # crear buffers en memoria de la clave privada y certificado: key_bio = BIO.MemoryBuffer(privatekey.encode('utf8')) crt_bio = BIO.MemoryBuffer(cert.encode('utf8')) s.load_key_bio(key_bio, crt_bio, callback) # (desde buffer) p7 = s.sign(buf, 0) # Firmar el buffer out = BIO.MemoryBuffer() # Crear un buffer para la salida s.write(out, p7) # Generar p7 en formato mail # Rand.save_file('randpool.dat') # Guardar el estado del PRNG's # extraer el cuerpo del mensaje (parte firmada) msg = email.message_from_string(out.read().decode('utf8')) for part in msg.walk(): filename = part.get_filename() if filename == "smime.p7m": # es la parte firmada? return part.get_payload(decode=False) # devolver CMS else: # Firmar el texto (tra) usando OPENSSL directamente try: if sys.platform.startswith("linux"): openssl = "openssl" else: path_openssl = LeerIni(clave="openssl", key="WSAA") if path_openssl != '': openssl = path_openssl else: if sys.maxsize <= 2**32: openssl = r"c:\OpenSSL-Win32\bin\openssl.exe" else: openssl = r"c:\OpenSSL-Win64\bin\openssl.exe" # NOTE: workaround if certificate is not already stored in a file # SECURITY WARNING: the private key will be exposed a bit in /tmp # (in theory only for the current user) if cert.startswith("-----BEGIN CERTIFICATE-----"): cert_f = NamedTemporaryFile() cert_f.write(cert.encode('utf-8')) cert_f.flush() cert = cert_f.name else: cert_f = None if privatekey.startswith("-----BEGIN RSA PRIVATE KEY-----"): key_f = NamedTemporaryFile() key_f.write(privatekey.encode('utf-8')) key_f.flush() privatekey = key_f.name else: key_f = None try: out = Popen([ openssl, "smime", "-sign", "-signer", cert, "-inkey", privatekey, "-outform", "DER", "-nodetach" ], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(tra)[0] finally: # close temp files to delete them (just in case): if cert_f: cert_f.close() if key_f: key_f.close() return b64encode(out).decode("utf8") except OSError as e: if e.errno == 2: warnings.warn( "El ejecutable de OpenSSL no esta disponible en el PATH") raise
def test_load_pkcs7_bio(self): with open(self.filename, 'rb') as f: buf = BIO.MemoryBuffer(f.read()) self.assertEqual(SMIME.load_pkcs7_bio(buf).type(), SMIME.PKCS7_SIGNED)
def test_sign_nondefault_digest(self): buf = BIO.MemoryBuffer(self.cleartext) s = SMIME.SMIME() s.load_key('tests/signer_key.pem', 'tests/signer.pem') p7 = s.sign(buf, flags=SMIME.PKCS7_DETACHED, algo='sha512') self.assertEqual(p7.type(), SMIME.PKCS7_SIGNED)
with open('message.txt') as f: message = f.read() def makebuf(text): return BIO.MemoryBuffer(bytes(text, 'utf-8')) # Make a MemoryBuffer of the message. buf = makebuf(message) # Seed the PRNG. Rand.load_file('randpool.dat', -1) # Instantiate an SMIME object; set it up; sign the buffer. s = SMIME.SMIME() s.load_key('sample_keys/signer_key.pem', 'sample_keys/signer.pem') p7 = s.sign(buf, SMIME.PKCS7_DETACHED) # Recreate buf. buf = makebuf(message) # Output p7 in mail-friendly format. out = BIO.MemoryBuffer() out.write('From: [email protected]\n') out.write('To: [email protected]\n') out.write('Subject: M2Crypto S/MIME testing\n') s.write(out, p7, buf) stringResult = str(out.read(), 'utf-8')
def download(self): downloadsneeded = {} QueryResults = self.Session.query(model.Subscription,model.ImageDefinition,model.ImageListInstance,model.ImageInstance).\ filter(model.ImageDefinition.cache == 1).\ filter(model.ImageDefinition.latest == model.ImageInstance.id).\ filter(model.ImageDefinition.id == model.ImageInstance.fkIdentifier).\ filter(model.ImageListInstance.expired == None).\ filter(model.Subscription.authorised == True).\ filter(model.Subscription.imagelist_latest == model.ImageListInstance.id).\ filter(model.ImageDefinition.subscription == model.Subscription.id).\ filter(model.ImageListInstance.id == model.ImageInstance.fkimagelistinstance) for line in QueryResults: sub = line[0] imageDef = line[1] imageListInst = line[2] ImageInst = line[3] uuid = imageDef.identifier details = { 'hv:uri': str(ImageInst.uri), 'sl:checksum:sha512': str(ImageInst.sha512), 'hv:size': int(ImageInst.size), 'dc:identifier': uuid, 'message': str(imageListInst.data), 'hv:imagelist.dc:identifier': str(sub.identifier), 'msgHash': str(imageListInst.data_hash), 'dc:title': str(ImageInst.title), 'dc:description': str(ImageInst.description), 'hv:version': str(ImageInst.version), 'hv:hypervisor': str(ImageInst.hypervisor), 'sl:arch': str(ImageInst.arch), 'sl:comments': str(ImageInst.comments), 'sl:os': str(ImageInst.os), 'sl:osversion': str(ImageInst.osversion), # And now the legacy values 'uri': str(ImageInst.uri), 'sha512': str(ImageInst.sha512), 'size': int(ImageInst.size), 'uuid': uuid, } # read message buf = BIO.MemoryBuffer(str(imageListInst.data)) sk = X509.X509_Stack() p7, data = SMIME.smime_load_pkcs7_bio(buf) data_str = data.read() try: jsonData = json.loads(str(data_str)) except ValueError: self.log.error("proiblem reading JSON") continue if jsonData == None: self.log.error("Downlaoded jsonData was not valid image.") continue vmilist = VMimageListDecoder(jsonData) if vmilist == None: self.log.error( "Downlaoded metadata from '%s' was not valid image list Object." % (subscriptionKey)) # For Vo handling imagelist_vo = vmilist.metadata.get(u'ad:vo') if imagelist_vo != None: if len(imagelist_vo) > 0: details['hv:imagelist.ad:vo'] = imagelist_vo matchingImage = None for image in vmilist.images: if "dc:identifier" in image.metadata.keys(): if uuid == image.metadata["dc:identifier"]: matchingImage = image if matchingImage != None: for metafield in matchingImage.metadata.keys(): newfield = "hv:image.%s" % (metafield) details[newfield] = matchingImage.metadata[metafield] if not uuid in self.cacheDir.index.keys(): downloadsneeded[uuid] = details continue if self.cacheDir.index[uuid]['sha512'] != str(ImageInst.sha512): downloadsneeded[uuid] = details continue for key in downloadsneeded.keys(): if not self.DownloadDir.indexAdd(downloadsneeded[key]): self.log.error( "Failed to add metadata request to download file '%s'." % (key)) continue if not self.DownloadDir.download(key): self.log.error("Failed to download file '%s'." % (key)) self.DownloadDir.indexSave() continue if self.callbackEventAvailablePrefix != None: metadata = {} metadata.update(dict(downloadsneeded[key])) metadata.update(dict(self.DownloadDir.index[key])) #for pkey in metadata.keys(): # print "%s---%s" % (pkey, metadata[pkey]) self.callbackEventAvailablePrefix(metadata) if not self.cacheDir.moveFrom(self.DownloadDir, key): self.log.error( "Failed to Move file '%s' into the enbdorsed directory." % (key)) continue self.DownloadDir.indexSave() self.cacheDir.indexSave() self.log.info("moved file %s" % (key)) if self.callbackEventAvailablePostfix != None: metadata = {} #metadata.update(dict(ddownloadsneeded[key])) metadata.update(dict(self.cacheDir.index[key])) self.callbackEventAvailablePostfix(metadata) return True
def test_crlf(self): self.assertEqual(SMIME.text_crlf('foobar'), 'Content-Type: text/plain\r\n\r\nfoobar') self.assertEqual(SMIME.text_crlf_bio(BIO.MemoryBuffer('foobar')).read(), 'Content-Type: text/plain\r\n\r\nfoobar')
def verify(input_bio, certstore_path, AUTO_SIGNED_CERT, type): """ Retrieves X.509 certificate from input data and verifies signed message using as certificate store input certstore, inspired by: U{http://code.activestate.com/recipes/285211/}. @type input_bio: M2Crypto.BIO @param input_bio: input data to verify @type certstore_path: filepath @param certstore_path: path to the file of the trusted certificates, for example /etc/ssl/certs/ca-certificats.crt. @type type: str @keyword type: specifies the type of input PKCS#7 data: PEM or DER @type AUTO_SIGNED_CERT: boolean @keyword AUTOSIGNED_CERT: to accept or not auto signed certificates as valid for verification. @rtype: list or None @return: a list of verified certificates retrieved from the original data if verification success, else None. @raise CertStoreNotAvailable: the reference certstore for verification is not available. @raise MissingSignerCertificate: the input PKCS#7 is not a signed PKCS#7. """ signer = SMIME.SMIME() cert_store = X509.X509_Store() if not os.access(certstore_path, os.R_OK): logging.error('certstore not available for verify') raise CertStoreNotAvailable('certstore not available %' % (certstore_path)) cert_store.load_info(certstore_path) signer.set_x509_store(cert_store) data_bio = None try: if type == 'PEM': p7, data_bio = SMIME.smime_load_pkcs7_bio(input_bio) elif type == 'DER': p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1) else: logging.error('pkcs7 type error: unknown type') raise BadPKCS7Type('unknown type: ' + type + '; possible values: PEM, DER') except SMIME.SMIME_Error as e: logging.error('load pkcs7 error: ' + str(e)) raise if data_bio is not None: data = data_bio.read() data_bio = BIO_from_buffer(data) sk3 = p7.get0_signers(X509.X509_Stack()) if len(sk3) == 0: logging.error('missing certificate') raise MissingSignerCertificate('missing certificate') signer_certs = [] for cert in sk3: signer_certs.append( "-----BEGIN CERTIFICATE-----\n{}-----END CERTIFICATE-----\n". format(base64.encodestring(cert.as_der()).decode('ascii'))) signer.set_x509_stack(sk3) v = None try: if AUTO_SIGNED_CERT: v = signer.verify(p7, data_bio, flags=SMIME.PKCS7_NOVERIFY) else: v = signer.verify(p7, data_bio) except SMIME.SMIME_Error as e: logging.error('smime error: ' + str(e)) raise except SMIME.PKCS7_Error as e: logging.error('pkcs7 error: ' + str(e)) raise if data_bio is not None and data != v and v is not None: return return signer_certs
def enroll(): if request.method == 'POST' and \ request.headers.get('Content-type', '').lower() == \ 'application/pkcs7-signature': # DEP request # base64 encode the DER data, and wrap in a PEM-ish format for SMIME.load_pkcs7_bio() req_data = base64_to_pem('PKCS7', base64.b64encode(request.data)) p7_bio = BIO.MemoryBuffer(str(req_data)) p7 = SMIME.load_pkcs7_bio(p7_bio) p7_signers = p7.get0_signers(X509.X509_Stack()) signer = SMIME.SMIME() signer.set_x509_store(X509.X509_Store()) signer.set_x509_stack(p7_signers) # TODO/XXX: not verifying ANY certificates! # # spec says we should verify against the "Apple Root CA" and that this # CMS message contains all intermediates to do that verification. # M2Crypto has no way to get at all the intermediate certificates to # do this manually we'd need to extract all of the certificates and # verify the chain aginst it. Note as of 2016-03-14 on a brand new # iPad Apple was including an expired certificate in this chain. Note # also that at least one of the intermediate certificates had a # certificate purpose apparently not appropraite for CMS/SMIME # verification. For now just verify with no CA and skip any # verification. plist_text = signer.verify(p7, None, flags=SMIME.PKCS7_NOVERIFY) plist = plistlib.readPlistFromString(plist_text) try: device = db_session.query(Device).filter( or_(Device.serial_number == plist['SERIAL'], Device.udid == plist['UDID'])).one() # assign in case absent (UDID present only - not likely due to spec) device.serial_number = plist['SERIAL'] # assign in case different (e.g. changing serial UDIDs i.e. VM testing) device.udid = plist['UDID'] except NoResultFound: # should never get here, we could take benefit of the doubt and # allow the enrollment anyway, though..? current_app.logger.warn( 'DEP enrollment attempt but no serial number nor UDID found!') device = Device() device.serial_number = plist['SERIAL'] device.udid = plist['UDID'] # TODO: do we care about PRODUCT, VERSION, or LANGUAGE here? db_session.add(device) db_session.commit() # TODO: except too many results (e.g. perhaps both a UDID and a SERIAL found?) else: device = None mdm_ca = get_ca() config = db_session.query(MDMConfig).first() if not config: abort( 500, 'No MDM configuration present; cannot generate enrollment profile') if not config.prefix or not config.prefix.strip(): abort(500, 'MDM configuration has no profile prefix') profile = Profile(config.prefix + '.enroll', PayloadDisplayName=config.mdm_name) print mdm_ca.get_cacert().to_pem() ca_cert_payload = PEMCertificatePayload( config.prefix + '.mdm-ca', str(mdm_ca.get_cacert().to_pem()).strip(), PayloadDisplayName='MDM CA Certificate') profile.append_payload(ca_cert_payload) # find and include all mdm.webcrt's q = db_session.query(DBCertificate).filter( DBCertificate.cert_type == 'mdm.webcrt') for i, cert in enumerate(q): print cert.pem_certificate new_webcrt_profile = PEMCertificatePayload( config.prefix + '.webcrt.%d' % i, str(cert.pem_certificate).strip(), PayloadDisplayName='Web Server Certificate') profile.append_payload(new_webcrt_profile) push_cert = config.push_cert.to_x509(cert_type=PushCertificate) topic = push_cert.get_topic() # NOTE: any device requesting non-SCEP enrollment will be generating new # CA-signed certificates. may want to gate the enrollment page by password # or other authentication if config.device_identity_method == 'provide': # make new device privkey, certificate then CA sign and persist # certificate finally return new Identity object new_dev_ident, db_dev_cert = mdm_ca.gen_new_device_identity() # random password for PKCS12 payload p12pw = urandom(20).encode('hex') # generate PCKS12 profile payload new_dev_ident_payload = PKCS12CertificatePayload( config.prefix + '.id-cert', new_dev_ident.to_pkcs12(p12pw), p12pw, PayloadDisplayName='Device Identity Certificate') profile.append_payload(new_dev_ident_payload) cert_uuid = new_dev_ident_payload.get_uuid() elif config.device_identity_method == 'ourscep': # SCEP is preferred scep_config = db_session.query(SCEPConfig).one() scep_payload = SCEPPayload( config.prefix + '.mdm-scep', config.scep_url, PayloadContent=dict( Keysize=2048, Challenge=scep_config.challenge, # CAFingerprint=plistlib.Data(mdm_ca.get_cacert().get_m2_cert().get_fingerprint('sha1').decode('hex')), # Subject=[ # [ ['CN', 'MDM Enrollment'] ], # ], ), PayloadDisplayName='MDM SCEP') profile.append_payload(scep_payload) cert_uuid = scep_payload.get_uuid() else: abort(500, 'Invalid device identity method') new_mdm_payload = MDMPayload( config.prefix + '.mdm', cert_uuid, topic, # APNs push topic config.mdm_url, config.access_rights, CheckInURL=config.checkin_url, # we can validate MDM device client certs provided via SSL/TLS. # however this requires an SSL framework that is able to do that. # alternatively we may optionally have the client digitally sign the # MDM messages in an HTTP header. this method is most portable across # web servers so we'll default to using that method. note it comes # with the disadvantage of adding something like 2KB to every MDM # request SignMessage=True, CheckOutWhenRemoved=True, ServerCapabilities=[ 'com.apple.mdm.per-user-connections' ], # per-network user & mobile account authentication (OS X extensions) PayloadDisplayName='Device Configuration and Management') profile.append_payload(new_mdm_payload) resp = make_response(profile.generate_plist()) resp.headers['Content-Type'] = PROFILE_CONTENT_TYPE return resp
import http.client, urllib.parse from M2Crypto import BIO, SMIME, X509 conn = http.client.HTTPConnection("localhost:9095") conn.request("GET", "/smime/encrypted") res = conn.getresponse() if res.status != 200: print((res.status)) raise Exception("Failed to connect") contentType = res.getheader("content-type") data = res.read() # Need to reconstruct a Mail message with content type # as SMIME wants it in that format bio = BIO.MemoryBuffer(b"Content-Type: ") bio.write(contentType) bio.write("\r\n\r\n") bio.write(data) s = SMIME.SMIME() s.load_key('src/main/resources/private.pem', 'src/main/resources/cert.pem') p7, d = SMIME.smime_load_pkcs7_bio(bio) out = s.decrypt(p7) print("--- Received Data ---") # It may contain headers like Content-Type, so you'll have to parse it print(out)
def testAllTheThings(self): """ Test the full scenario: multiple encrypted and plaintext recipients. Tests that multiple recipients can all read a message, and that recipients with no Identity records get plain text. """ count = 1 sender = Identity.objects.get(address="*****@*****.**") recipients = [identity.address for identity in Identity.objects.all()] recipients.extend(["*****@*****.**", "*****@*****.**"]) message = mail.EmailMultiAlternatives( self.text_template % count, self.text_template % count, sender.address, recipients, ) message.attach_alternative(self.html_template % count, "text/html") message.send() backend = mail.get_connection() self.assertEqual(len(backend.messages), 2) # # verify the encryption and signature # s = SMIME.SMIME() # Load the sender's cert. x509 = X509.load_cert_string(data.RECIPIENT1_CERTIFICATE) sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Load the sender's CA cert. st = X509.X509_Store() st.add_x509(x509) s.set_x509_store(st) # Decrypt the message as both encrypted recipients # # recipient 1 # recipient1_cert = BIO.MemoryBuffer( data.RECIPIENT1_CERTIFICATE.encode("UTF-8")) recipient1_key = BIO.MemoryBuffer(data.RECIPIENT1_KEY.encode("UTF-8")) s.load_key_bio(recipient1_key, recipient1_cert) msg = BIO.MemoryBuffer(backend.messages[1]["message"].encode("UTF-8")) p7, msg_data = SMIME.smime_load_pkcs7_bio(msg) out = s.decrypt(p7) # Verify the message msg = BIO.MemoryBuffer(out) p7, msg_data = SMIME.smime_load_pkcs7_bio(msg) verified_msg = s.verify(p7, msg_data) self.assertTrue(verified_msg) # # recipient 2 # recipient2_cert = BIO.MemoryBuffer( data.RECIPIENT2_CERTIFICATE.encode("UTF-8")) recipient2_key = BIO.MemoryBuffer(data.RECIPIENT2_KEY.encode("UTF-8")) s.load_key_bio(recipient2_key, recipient2_cert) msg = BIO.MemoryBuffer(backend.messages[1]["message"].encode("UTF-8")) p7, msg_data = SMIME.smime_load_pkcs7_bio(msg) out = s.decrypt(p7) # Verify the message msg = BIO.MemoryBuffer(out) p7, msg_data = SMIME.smime_load_pkcs7_bio(msg) self.assertTrue(s.verify(p7, msg_data)) # verify that the plaintext also got through msg = BIO.MemoryBuffer(backend.messages[1]["message"].encode("UTF-8"))
def PUT(self): global sm_obj, device_list HIGH = '[1;31m' LOW = '[0;32m' NORMAL = '[0;39m' i = web.data() pl = readPlistFromString(i) if 'HTTP_MDM_SIGNATURE' in web.ctx.environ: raw_sig = web.ctx.environ['HTTP_MDM_SIGNATURE'] cooked_sig = '\n'.join(raw_sig[pos:pos + 76] for pos in xrange(0, len(raw_sig), 76)) signature = '\n-----BEGIN PKCS7-----\n%s\n-----END PKCS7-----\n' % cooked_sig # Verify client signature - necessary? buf = BIO.MemoryBuffer(signature) p7 = SMIME.load_pkcs7_bio(buf) data_bio = BIO.MemoryBuffer(i) try: v = sm_obj.verify(p7, data_bio) if v: print "Client signature verified." except: print "*** INVALID CLIENT MESSAGE SIGNATURE ***" print "%sReceived %4d bytes: %s" % (HIGH, len(web.data()), NORMAL), if pl.get('Status') == 'Idle': print HIGH + "Idle Status" + NORMAL print "*FETCHING CMD TO BE SENT FROM DEVICE:", pl['UDID'] rd = device_list[pl['UDID']].sendCommand() # If no commands in queue, return empty string to avoid infinite idle loop if (not rd): return '' print "%sSent: %s%s" % (HIGH, rd['Command']['RequestType'], NORMAL) elif pl.get('MessageType') == 'TokenUpdate': print HIGH + "Token Update" + NORMAL rd = do_TokenUpdate(pl) print HIGH + "Device Enrolled!" + NORMAL elif pl.get('Status') == 'Acknowledged': print HIGH + "Acknowledged" + NORMAL rd = dict() # A command has returned a response # Add the response to the given device print "*CALLING ADD RESPONSE TO CMD:", pl['CommandUUID'] device_list[pl['UDID']].addResponse(pl['CommandUUID'], pl) # If we grab device information, we should also update the device info if pl.get('QueryResponses'): print "DeviceInformation should update here..." p = pl['QueryResponses'] device_list[pl['UDID']].updateInfo(p['DeviceName'], p['ModelName'], p['OSVersion']) # Update pickle file with new response store_devices() else: rd = dict() if pl.get('MessageType') == 'Authenticate': print HIGH + "Authenticate" + NORMAL elif pl.get('MessageType') == 'CheckOut': print HIGH + "Device leaving MDM" + NORMAL elif pl.get('Status') == 'Error': print "*CALLING ADD RESPONSE WITH ERROR TO CMD:", pl[ 'CommandUUID'] device_list[pl['UDID']].addResponse(pl['CommandUUID'], pl) else: print HIGH + "(other)" + NORMAL print HIGH, pl, NORMAL log_data(pl) log_data(rd) out = writePlistToString(rd) #print LOW, out, NORMAL return out
def send(self, to, subject='None', message='None', attachments=None, cc=None, bcc=None, reply_to=None, encoding='utf-8', raw=False, headers={}): """ Sends an email using data specified in constructor Arguments: to: list or tuple of receiver addresses; will also accept single object subject: subject of the email message: email body text; depends on type of passed object: if 2-list or 2-tuple is passed: first element will be source of plain text while second of html text; otherwise: object will be the only source of plain text and html source will be set to None; If text or html source is: None: content part will be ignored, string: content part will be set to it, file-like object: content part will be fetched from it using it's read() method attachments: list or tuple of Mail.Attachment objects; will also accept single object cc: list or tuple of carbon copy receiver addresses; will also accept single object bcc: list or tuple of blind carbon copy receiver addresses; will also accept single object reply_to: address to which reply should be composed encoding: encoding of all strings passed to this method (including message bodies) headers: dictionary of headers to refine the headers just before sending mail, e.g. {'Return-Path' : '*****@*****.**'} Examples: #Send plain text message to single address: mail.send('*****@*****.**', 'Message subject', 'Plain text body of the message') #Send html message to single address: mail.send('*****@*****.**', 'Message subject', '<html>Plain text body of the message</html>') #Send text and html message to three addresses (two in cc): mail.send('*****@*****.**', 'Message subject', ('Plain text body', '<html>html body</html>'), cc=['*****@*****.**', '*****@*****.**']) #Send html only message with image attachment available from the message by 'photo' content id: mail.send('*****@*****.**', 'Message subject', (None, '<html><img src="cid:photo" /></html>'), Mail.Attachment('/path/to/photo.jpg' content_id='photo')) #Send email with two attachments and no body text mail.send('[email protected], 'Message subject', None, [Mail.Attachment('/path/to/fist.file'), Mail.Attachment('/path/to/second.file')]) Returns True on success, False on failure. Before return, method updates two object's fields: self.result: return value of smtplib.SMTP.sendmail() or GAE's mail.send_mail() method self.error: Exception message or None if above was successful """ def encode_header(key): if [c for c in key if 32 > ord(c) or ord(c) > 127]: return Header.Header(key.encode('utf-8'), 'utf-8') else: return key # encoded or raw text def encoded_or_raw(text): if raw: text = encode_header(text) return text if not isinstance(self.server, str): raise Exception('Server address not specified') if not isinstance(self.sender, str): raise Exception('Sender address not specified') if not raw: payload_in = MIMEMultipart.MIMEMultipart('mixed') else: # no encoding configuration for raw messages if isinstance(message, basestring): text = message.decode(encoding).encode('utf-8') else: text = message.read().decode(encoding).encode('utf-8') # No charset passed to avoid transport encoding # NOTE: some unicode encoded strings will produce # unreadable mail contents. payload_in = MIMEText.MIMEText(text) if to: if not isinstance(to, (list, tuple)): to = [to] else: raise Exception('Target receiver address not specified') if cc: if not isinstance(cc, (list, tuple)): cc = [cc] if bcc: if not isinstance(bcc, (list, tuple)): bcc = [bcc] if message is None: text = html = None elif isinstance(message, (list, tuple)): text, html = message elif message.strip().startswith('<html') and message.strip().endswith( '</html>'): text = self.server == 'gae' and message or None html = message else: text = message html = None if (not text is None or not html is None) and (not raw): attachment = MIMEMultipart.MIMEMultipart('alternative') if not text is None: if isinstance(text, basestring): text = text.decode(encoding).encode('utf-8') else: text = text.read().decode(encoding).encode('utf-8') attachment.attach(MIMEText.MIMEText(text, _charset='utf-8')) if not html is None: if isinstance(html, basestring): html = html.decode(encoding).encode('utf-8') else: html = html.read().decode(encoding).encode('utf-8') attachment.attach( MIMEText.MIMEText(html, 'html', _charset='utf-8')) payload_in.attach(attachment) if (attachments is None) or raw: pass elif isinstance(attachments, (list, tuple)): for attachment in attachments: payload_in.attach(attachment) else: payload_in.attach(attachments) ####################################################### # CIPHER # ####################################################### cipher_type = self.cipher_type sign = self.sign sign_passphrase = self.sign_passphrase encrypt = self.encrypt ####################################################### # GPGME # ####################################################### if cipher_type == 'gpg': if self.gpg_home: # Set GNUPGHOME environment variable to set home of gnupg import os os.environ['GNUPGHOME'] = self.gpg_home if not sign and not encrypt: self.error = "No sign and no encrypt is set but cipher type to gpg" return False # need a python-pyme package and gpgme lib from pyme import core, errors from pyme.constants.sig import mode ############################################ # sign # ############################################ if sign: import string core.check_version(None) pin = string.replace(payload_in.as_string(), '\n', '\r\n') plain = core.Data(pin) sig = core.Data() c = core.Context() c.set_armor(1) c.signers_clear() # search for signing key for From: for sigkey in c.op_keylist_all(self.sender, 1): if sigkey.can_sign: c.signers_add(sigkey) if not c.signers_enum(0): self.error = 'No key for signing [%s]' % self.sender return False c.set_passphrase_cb(lambda x, y, z: sign_passphrase) try: # make a signature c.op_sign(plain, sig, mode.DETACH) sig.seek(0, 0) # make it part of the email payload = MIMEMultipart.MIMEMultipart( 'signed', boundary=None, _subparts=None, **dict(micalg="pgp-sha1", protocol="application/pgp-signature")) # insert the origin payload payload.attach(payload_in) # insert the detached signature p = MIMEBase.MIMEBase("application", 'pgp-signature') p.set_payload(sig.read()) payload.attach(p) # it's just a trick to handle the no encryption case payload_in = payload except errors.GPGMEError: self.error = "GPG error: %s" return False ############################################ # encrypt # ############################################ if encrypt: core.check_version(None) plain = core.Data(payload_in.as_string()) cipher = core.Data() c = core.Context() c.set_armor(1) # collect the public keys for encryption recipients = [] rec = to[:] if cc: rec.extend(cc) if bcc: rec.extend(bcc) for addr in rec: c.op_keylist_start(addr, 0) r = c.op_keylist_next() if r is None: self.error = 'No key for [%s]' % addr return False recipients.append(r) try: # make the encryption c.op_encrypt(recipients, 1, plain, cipher) cipher.seek(0, 0) # make it a part of the email payload = MIMEMultipart.MIMEMultipart( 'encrypted', boundary=None, _subparts=None, **dict(protocol="application/pgp-encrypted")) p = MIMEBase.MIMEBase("application", 'pgp-encrypted') p.set_payload("Version: 1\r\n") payload.attach(p) p = MIMEBase.MIMEBase("application", 'octet-stream') p.set_payload(cipher.read()) payload.attach(p) except errors.GPGMEError: self.error = "GPG error: %s" return False ####################################################### # X.509 # ####################################################### elif cipher_type == 'x509': if not sign and not encrypt: self.error = "No sign and no encrypt is set but cipher type to x509" return False x509_sign_keyfile = self.x509_sign_keyfile if self.x509_sign_certfile: x509_sign_certfile = self.x509_sign_certfile else: # if there is no sign certfile we'll assume the # cert is in keyfile x509_sign_certfile = self.x509_sign_keyfile # crypt certfiles could be a string or a list x509_crypt_certfiles = self.x509_crypt_certfiles x509_nocerts = self.x509_nocerts # need m2crypto try: from M2Crypto import BIO, SMIME, X509 except Exception: self.error = "Can't load M2Crypto module" return False msg_bio = BIO.MemoryBuffer(payload_in.as_string()) s = SMIME.SMIME() # SIGN if sign: #key for signing try: s.load_key(x509_sign_keyfile, x509_sign_certfile, callback=lambda x: sign_passphrase) except Exception: self.error = "Something went wrong on certificate / private key loading: <%s>" % str( e) return False try: if x509_nocerts: flags = SMIME.PKCS7_NOCERTS else: flags = 0 if not encrypt: flags += SMIME.PKCS7_DETACHED p7 = s.sign(msg_bio, flags=flags) msg_bio = BIO.MemoryBuffer(payload_in.as_string( )) # Recreate coz sign() has consumed it. except Exception: self.error = "Something went wrong on signing: <%s> %s" return False # ENCRYPT if encrypt: try: sk = X509.X509_Stack() if not isinstance(x509_crypt_certfiles, (list, tuple)): x509_crypt_certfiles = [x509_crypt_certfiles] # make an encryption cert's stack for x in x509_crypt_certfiles: sk.push(X509.load_cert(x)) s.set_x509_stack(sk) s.set_cipher(SMIME.Cipher('des_ede3_cbc')) tmp_bio = BIO.MemoryBuffer() if sign: s.write(tmp_bio, p7) else: tmp_bio.write(payload_in.as_string()) p7 = s.encrypt(tmp_bio) except Exception: self.error = "Something went wrong on encrypting: <%s>" return False # Final stage in sign and encryption out = BIO.MemoryBuffer() if encrypt: s.write(out, p7) else: if sign: s.write(out, p7, msg_bio, SMIME.PKCS7_DETACHED) else: out.write('\r\n') out.write(payload_in.as_string()) out.close() st = str(out.read()) payload = message_from_string(st) else: # no cryptography process as usual payload = payload_in payload['From'] = encoded_or_raw(self.sender.decode(encoding)) origTo = to[:] if to: payload['To'] = encoded_or_raw(', '.join(to).decode(encoding)) if reply_to: payload['Reply-To'] = encoded_or_raw(reply_to.decode(encoding)) if cc: payload['Cc'] = encoded_or_raw(', '.join(cc).decode(encoding)) to.extend(cc) if bcc: to.extend(bcc) payload['Subject'] = encoded_or_raw(subject.decode(encoding)) payload['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) for k, v in headers.iteritems(): payload[k] = encoded_or_raw(v.decode(encoding)) result = {} try: if self.server == 'logging': logger.warn('email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' % \ ('-'*40,self.sender, ', '.join(to),subject, text or html,'-'*40)) elif self.server == 'gae': xcc = dict() if cc: xcc['cc'] = cc if bcc: xcc['bcc'] = bcc if reply_to: xcc['reply_to'] = reply_to from google.appengine.api import mail attachments = attachments and [(a.my_filename, a.my_payload) for a in attachments if not raw] if attachments: result = mail.send_mail(sender=self.sender, to=origTo, subject=subject, body=text, html=html, attachments=attachments, **xcc) elif html and (not raw): result = mail.send_mail(sender=self.sender, to=origTo, subject=subject, body=text, html=html, **xcc) else: result = mail.send_mail(sender=self.sender, to=origTo, subject=subject, body=text, **xcc) else: smtp_args = self.server.split(':') if self.ssl: server = smtplib.SMTP_SSL(*smtp_args) else: server = smtplib.SMTP(*smtp_args) if self.tls and not self.ssl: server.ehlo() server.starttls() server.ehlo() if self.login: server.login(*self.login.split(':', 1)) result = server.sendmail(self.sender, to, payload.as_string()) server.quit() except Exception: self.result = result self.error = None return False self.result = result self.error = None return True
def test_load_pkcs7(self): assert SMIME.load_pkcs7(self.filename).type() == SMIME.PKCS7_SIGNED
def validate_text(self, text_to_verify): buf = BIO.MemoryBuffer(text_to_verify) sk = X509.X509_Stack() p7, data = SMIME.smime_load_pkcs7_bio(buf) try: supplied_stack = p7.get0_signers(sk) except AttributeError as e: if str(e) == "PKCS7 instance has no attribute 'get0_signers'": self.logger.error( 'm2crypto version 0.18 is the minimum supported, please upgrade.' ) raise e issuer_dn = None signer_dn = None signer_serial_number = None supplied_list = [] while True: one = supplied_stack.pop() if one == None: break else: supplied_list.append(one) certdictionary = [] for item in supplied_list: itemdictionary = {} issuer_dn = str(item.get_issuer()) signer_dn = str(item.get_subject()) cert_sn = str(item.get_serial_number()) itemdictionary['subject'] = signer_dn itemdictionary['issuer'] = issuer_dn itemdictionary['serial_number'] = cert_sn certdictionary.append(itemdictionary) # Only validate files signed with a certificate issued a correct CA if not len(certdictionary) == 1: if len(certdictionary) > 1: raise SmimeX509ValidationError( "To many keys in signature file.") if len(certdictionary) == 0: raise SmimeX509ValidationError("No keys found signature file.") baseCert = certdictionary[0] if not self.ca_name_spaces.checkCrlHeirarchy( baseCert['subject'], baseCert['issuer'], baseCert['serial_number']): raise SmimeX509ValidationError("Cert %s is expired") CaHeirarchy = self.ca_name_spaces.GetCaHeirarchListWithCaDn( baseCert['issuer']) s = SMIME.SMIME() sk = X509.X509_Stack() for item in CaHeirarchy: foundKey = self.ca_name_spaces.GetKeyByDn(item) if foundKey == None: raise SmimeX509ValidationError("No trusted Key for '%s'" % (item)) sk.push(foundKey) s.set_x509_stack(sk) st = X509.X509_Store() #print self.ca_name_spaces.ca[correct_issuer_dn].ca_filename for item in CaHeirarchy: foundKey = self.ca_name_spaces.GetKeyByDn(item) if foundKey == None: raise SmimeX509ValidationError("No trusted Key for '%s'" % (item)) st.add_cert(foundKey) s.set_x509_store(st) try: v = s.verify(p7, data) #when python 2.6 is the min version of supported #change back to #except SMIME.PKCS7_Error as e: except SMIME.PKCS7_Error as e: raise SmimeX509ValidationError(e) output = { 'signer_dn': signer_dn, 'issuer_dn': issuer_dn, 'data': data.read() } return output
def test_load_pkcs7_bio(self): f = open(self.filename, 'rb') buf = BIO.MemoryBuffer(f.read()) f.close() assert SMIME.load_pkcs7_bio(buf).type() == SMIME.PKCS7_SIGNED
# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os from run_config import * from M2Crypto import SMIME, X509, BIO BASE_DIR = os.path.dirname(os.path.dirname(__file__)) path_to_certificates = BASE_DIR + '/LMP/certificates/' # configure the app app.config.from_object(__name__) app.secret_key = os.urandom(24) app.debug = True app.root = os.path.abspath(os.path.dirname(__file__)) app.config['SESSION_TYPE'] = 'filesystem' #app.ssl_context = context # Set up some smime objects to verify signed messages coming from devices sm_obj = SMIME.SMIME() x509 = X509.load_cert(path_to_certificates + 'identity.crt') sk = X509.X509_Stack() sk.push(x509) sm_obj.set_x509_stack(sk) st = X509.X509_Store() st.load_info(path_to_certificates + 'CA.crt') sm_obj.set_x509_store(st)
def load_pkcs7_bio_der(p7_bio): p7_ptr = m2.pkcs7_read_bio_der(p7_bio._ptr()) if p7_ptr is None: raise SMIME.PKCS7_Error(Err.get_error()) return SMIME.PKCS7(p7_ptr, 1)
from M2Crypto import BIO, SMIME pf = BIO.openfile('pkcs7-thawte.pem') p7 = SMIME.load_pkcs7_bio(pf) print p7.type(1)
try: pubKeyIsInvalid = False cert = X509.load_cert(sys.argv[1]) x509Stack = X509.X509_Stack() x509Stack.push(cert) except: pubKeyIsInvalid = True if pubKeyIsInvalid: sys.stdout.write("X-Crypt: Encryption by <" + socket.gethostname() + "> failed due to bad key." + lineFeedType) sys.stdout.write(emailData) sys.exit(0) # Encrypt message. smimeObj = SMIME.SMIME() smimeObj.set_x509_stack(x509Stack) smimeObj.set_cipher(SMIME.Cipher('des_ede3_cbc')) encryptedEmailBody = smimeObj.encrypt(BIO.MemoryBuffer(emailNewBody)) # Compose encrypted email out of prepared parts. # According to RFC 822 and RFC 2822, every email must have a message # field ID that "provides a unique message identifier that refers to a # particular version of a particular message. The uniqueness of # the message identifier is guaranteed by the host that generates it" # Therefore, a new message ID must be genereated. out = BIO.MemoryBuffer() out.write("X-Crypt: This message has been encrypted by <" + socket.gethostname() + ">" + lineFeedType) out.write("Message-ID: " + emailUUID + "@" + socket.gethostname() + lineFeedType)
from M2Crypto import BIO, SMIME, X509 s = SMIME.SMIME() s.load_key('mycert-private.pem', 'mycert.pem') p7, data = SMIME.smime_load_pkcs7('smime.txt') out = s.decrypt(p7) print out
def test_write_pkcs7_der(self): buf = BIO.MemoryBuffer() assert SMIME.load_pkcs7(self.filename).write_der(buf) == 1 s = buf.read() assert len(s) in (1188, 1204, 1243, 1678), len(s)
def test_load_pkcs7(self): self.assertEqual( SMIME.load_pkcs7(self.filename).type(), SMIME.PKCS7_SIGNED)
def verify_cms(self, data): """Verify a pkcs7 SMIME message""" from M2Crypto import SMIME, X509, BIO import base64, TLV_utils, os data3 = "-----BEGIN PKCS7-----\n" data3 += base64.encodestring(data) data3 += "-----END PKCS7-----" #print data3 p7_bio = BIO.MemoryBuffer(data3) # Instantiate an SMIME object. s = SMIME.SMIME() # TODO: ugly hack for M2Crypto body = TLV_utils.tlv_find_tag(TLV_utils.unpack(data), 0xA0, 1)[0][2] thecert = TLV_utils.tlv_find_tag(body, 0xA0, 2)[1][2] cert_bio = BIO.MemoryBuffer(TLV_utils.pack(thecert)) # Load the signer's cert. x509 = X509.load_cert_bio(cert_bio, format=0) sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) country = str(x509.get_issuer()).split('/')[1][2:] #print country cacert = country + "-cacert.der" #print cacert msgErr = "couldn't parse certificate to determine URL for CACert, search the intertubes," msg = "download CACert (convert to DER if necessary) and save it as \n\"%s\"" % cacert if not os.path.isfile(cacert): try: v = x509.get_ext("certificatePolicies").get_value() start = v.find("CPS: ") if start != -1: url = v[start + 5:-1] print "visit %s" % url, msg else: print msgErr, msg except Exception: print msgErr, msg return "" # Load the signer's CA cert. st = X509.X509_Store() #st.load_info('main') x509CA = X509.load_cert(cacert, format=0) st.add_x509(x509CA) s.set_x509_store(st) # Load the data, verify it. #p7, data = SMIME.smime_load_pkcs7_bio(p7_bio) p7 = SMIME.load_pkcs7_bio(p7_bio) v = s.verify(p7) return v
def paypal_encrypt(attributes, sitesettings): """ Takes a list of attributes for working with PayPal (in our case adding to the shopping cart), and encrypts them for secure transmission of item details and prices. @type attributes: dictionary @param attributes: a dictionary of the PayPal request attributes. An example attribute set is: >>> attributes = {"cert_id":sitesettings.paypal_cert_id, "cmd":"_cart", "business":sitesettings.cart_business, "add":"1", "custom":auth.user.id, "item_name":"song 1 test", "item_number":"song-1", "amount":"0.99", "currency_code":"USD", "shopping_url":'http://'+\ Storage(globals()).request.env.http_host+\ URL(args=request.args), "return":'http://'+\ Storage(globals()).request.env.http_host+\ URL('account', 'downloads'), } @type sitesettings: SQLStorage @param sitesettings: The settings stored in the database. this method requires I{tenthrow_private_key}, I{tenthrow_public_cert}, and I{paypal_public_cert} to function @rtype: string @return: encrupted attribute string """ plaintext = '' for key, value in attributes.items(): plaintext += u'%s=%s\n' % (key, value) plaintext = plaintext.encode('utf-8') # Instantiate an SMIME object. s = SMIME.SMIME() # Load signer's key and cert. Sign the buffer. s.pkey = EVP.load_key_string(sitesettings.tenthrow_private_key) s.x509 = X509.load_cert_string(sitesettings.tenthrow_public_cert) #s.load_key_bio(BIO.openfile(settings.MY_KEYPAIR), # BIO.openfile(settings.MY_CERT)) p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY) # Load target cert to encrypt the signed message to. #x509 = X509.load_cert_bio(BIO.openfile(settings.PAYPAL_CERT)) x509 = X509.load_cert_string(sitesettings.paypal_public_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) return out.read()
from M2Crypto import BIO, SMIME, X509 s = SMIME.SMIME() # Load private key and cert. s.load_key('mycert-private.pem', 'mycert.pem') # Load the signed/encrypted data. p7, data = SMIME.smime_load_pkcs7('target/python_encrypted_signed.txt') # After the above step, 'data' == None. # Decrypt p7. 'out' now contains a PKCS #7 signed blob. out = s.decrypt(p7) # Load the signer's cert. x509 = X509.load_cert('mycert.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Load the signer's CA cert. In this case, because the signer's # cert is self-signed, it is the signer's cert itself. st = X509.X509_Store() st.load_info('mycert.pem') s.set_x509_store(st) # Recall 'out' contains a PKCS #7 blob. # Transform 'out'; verify the resulting PKCS #7 blob. p7_bio = BIO.MemoryBuffer(out) p7, data = SMIME.smime_load_pkcs7_bio(p7_bio) v = s.verify(p7, data)