def pkcs7_unseal(self, text, sender=None): if (None==sender): sender=self.barium_cert sm = SMIME.SMIME() sm.pkey = self.my_pkey sm.x509 = self.my_cert bio = BIO.MemoryBuffer(text) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr())) out = sm.decrypt(p7) stk = X509.X509_Stack() stk.push(sender) store = self.ssl_ctx.get_cert_store() p7b = makebuf(out) p7final = m2.pkcs7_read_bio_der(p7b._ptr()) return m2.pkcs7_verify0(p7final, stk._ptr(), store._ptr(), 0)
def from_pkcs7_der(cls, pkcs7_der): m2_p7_bio = BIO.MemoryBuffer(pkcs7_der) m2_p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(m2_p7_bio._ptr()), 1) ct_p7 = cast(c_void_p(long(m2_p7._ptr())), POINTER(PKCS7)) ct_sis = get_lc().PKCS7_get_signer_info(ct_p7) assert get_lc().sk_num(ct_sis) == 1 ct_si = cast(c_void_p(get_lc().sk_value(ct_sis, 0)), POINTER(PKCS7_SIGNER_INFO)) ct_x509 = get_lc().X509_find_by_issuer_and_serial( ct_p7.contents.d.sign.contents.cert, ct_si.contents.issuer_and_serial.contents.issuer, ct_si.contents.issuer_and_serial.contents.serial) signing_cert_int = m2_x509_from_ct_ptr(ct_x509) signing_cert = X509.X509(m2.x509_dup(signing_cert_int._ptr())) m2_p7buf = BIO.MemoryBuffer() ct_p7buf = c_void_p(long(m2_p7buf._ptr())) assert get_lc().PKCS7_signatureVerify(ct_p7buf, ct_p7, ct_si, ct_x509) >= 0 assert ct_si.contents.auth_attr assert get_lc().sk_num(ct_si.contents.auth_attr) attrs = [] for i in xrange(0, get_lc().sk_num(ct_si.contents.auth_attr)): # loop through the signed attributes ct_x509_attr_p = get_lc().sk_value(ct_si.contents.auth_attr, i) assert ct_x509_attr_p ct_x509_attr = cast(ct_x509_attr_p, POINTER(X509_ATTRIBUTE)) try: # try to find a matching OID attribute that we handle oid_obj = SCEPAttribute.find_by_matching_x509_attr_asn1_obj(ct_x509_attr) except SCEPAttributeKeyError: continue attrs.append((oid_obj, oid_obj.get_string(ct_x509_attr))) message_types = [attr for attr in attrs if issubclass(attr[0], MessageType)] assert message_types message_type = message_types[0] attrs.remove(message_types[0]) ct_p7bio = get_lc().PKCS7_dataInit(ct_p7, None) assert ct_p7bio m2_p7bio = m2_MemoryBuffer_from_ct_ptr(ct_p7bio) ncls = SCEPMessage.find_by_message_type(message_type[1])() ncls.signing_cert = signing_cert ncls.signedcontent = m2_p7bio.read() ncls._set_attrs(attrs) return ncls
def verify_signature_block(certificate_file, content, signature): """ Verifies the 'signature' over the 'content', trusting the 'certificate'. :param certificate_file: the trusted certificate (PEM format) :type certificate_file: str :param content: The signature should match this content :type content: str :param signature: data (DER format) subject to check :type signature: str :return None if the signature validates. :exception SignatureBlockVerificationError """ sig_bio = BIO.MemoryBuffer(signature) pkcs7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(sig_bio._ptr()), 1) signers_cert_stack = pkcs7.get0_signers(X509.X509_Stack()) trusted_cert_store = X509.X509_Store() trusted_cert_store.set_verify_cb(ignore_missing_email_protection_eku_cb) trusted_cert_store.load_info(certificate_file) smime = SMIME.SMIME() smime.set_x509_stack(signers_cert_stack) smime.set_x509_store(trusted_cert_store) data_bio = BIO.MemoryBuffer(content) try: smime.verify(pkcs7, data_bio) except SMIME.PKCS7_Error as message: raise SignatureBlockVerificationError(message) else: return None
def verify_signature_block(certificate_file, content, signature): """ Verifies the 'signature' over the 'content', trusting the 'certificate'. :param certificate_file: the trusted certificate (PEM format) :type certificate_file: str :param content: The signature should match this content :type content: str :param signature: data (DER format) subject to check :type signature: str :return None if the signature validates. :exception SignatureBlockVerificationError """ sig_bio = BIO.MemoryBuffer(signature) pkcs7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(sig_bio._ptr()), 1) signers_cert_stack = pkcs7.get0_signers(X509.X509_Stack()) trusted_cert_store = X509.X509_Store() trusted_cert_store.set_verify_cb(ignore_missing_email_protection_eku_cb) trusted_cert_store.load_info(certificate_file) smime = SMIME.SMIME() smime.set_x509_stack(signers_cert_stack) smime.set_x509_store(trusted_cert_store) data_bio = BIO.MemoryBuffer(content) try: smime.verify(pkcs7, data_bio) except SMIME.PKCS7_Error as message: raise SignatureBlockVerificationError(message) else: return None
def _get_digital_signers(self): if not self.pe: return None retlist = None if HAVE_CRYPTO: address = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress #check if file is digitally signed if address == 0: return retlist signature = self.pe.write()[address+8:] bio = BIO.MemoryBuffer(signature) if bio: swig_pkcs7 = m2.pkcs7_read_bio_der(bio.bio_ptr()) if swig_pkcs7: p7 = SMIME.PKCS7(swig_pkcs7) xst = p7.get0_signers(X509.X509_Stack()) retlist = [] if xst: for cert in xst: sn = cert.get_serial_number() sha1_fingerprint = cert.get_fingerprint('sha1').lower() md5_fingerprint = cert.get_fingerprint('md5').lower() subject_str = str(cert.get_subject()) cn = subject_str[subject_str.index("/CN=")+len("/CN="):] retlist.append({"sn":str(sn), "cn":cn, "sha1_fingerprint" : sha1_fingerprint, "md5_fingerprint" : md5_fingerprint }) return retlist
def decrypt_email_body(client: Client, args: Dict, file_path=None): """ Decrypt the message Args: client: Client args: Dict file_path: relevant for the test module """ if file_path: encrypt_message = file_path else: encrypt_message = demisto.getFilePath(args.get('encrypt_message')) client.smime.load_key(client.private_key_file, client.public_key_file) try: p7, data = SMIME.smime_load_pkcs7(encrypt_message['path']) out = client.smime.decrypt(p7).decode('utf-8') except SMIME.SMIME_Error as e: if str( e ) == 'no content type': # If no content type; see if we can process as DER format with open(encrypt_message['path'], "rb") as message_file: p7data = message_file.read() p7bio = BIO.MemoryBuffer(p7data) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(p7bio._ptr())) out = client.smime.decrypt( p7, flags=SMIME.PKCS7_NOVERIFY).decode('utf-8') entry_context = {'SMIME.Decrypted': {'Message': out}} human_readable = f'The decrypted message is: \n{out}' return human_readable, entry_context
def verify_signature_block(certificate_file, content_file, signature): """Verifies the 'signature' over the 'content', trusting the 'certificate'. :param certificate_file: the trusted certificate (PEM format) :type certificate_file: str :param content_file: The signature should match this content :type content_file: str :param signature: data (DER format) subject to check :type signature: str :return: Error message, or None if the signature validates. :rtype: str """ sig_bio = BIO.MemoryBuffer(signature) pkcs7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(sig_bio._ptr()), 1) signers_cert_stack = pkcs7.get0_signers(X509.X509_Stack()) trusted_cert_store = X509.X509_Store() trusted_cert_store.load_info(certificate_file) smime = SMIME.SMIME() smime.set_x509_stack(signers_cert_stack) smime.set_x509_store(trusted_cert_store) data_bio = BIO.openfile(content_file) try: smime.verify(pkcs7, data_bio) except SMIME.PKCS7_Error, message: return "Signature verification error: %s" % message
def _get_digital_signers(self): if not self.pe: return None retlist = None if HAVE_CRYPTO: address = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress #check if file is digitally signed if address == 0: return retlist signature = self.pe.write()[address+8:] bio = BIO.MemoryBuffer(signature) if bio: swig_pkcs7 = m2.pkcs7_read_bio_der(bio.bio_ptr()) if swig_pkcs7: p7 = SMIME.PKCS7(swig_pkcs7) xst = p7.get0_signers(X509.X509_Stack()) retlist = [] if xst: for cert in xst: sn = cert.get_serial_number() sha1_fingerprint = cert.get_fingerprint('sha1').lower() md5_fingerprint = cert.get_fingerprint('md5').lower() subject_str = str(cert.get_subject()) cn = subject_str[subject_str.index("/CN=")+len("/CN="):] retlist.append({"sn":str(sn), "cn":cn, "sha1_fingerprint" : sha1_fingerprint, "md5_fingerprint" : md5_fingerprint }) return retlist
def response_to_pkcs7(blob): der = b64decode(blob) pkcs7_buf = MemoryBuffer(der) if pkcs7_buf is None: raise BIOError(Err.get_error()) p7_ptr = pkcs7_read_bio_der(pkcs7_buf.bio) pkcs7 = PKCS7(p7_ptr, 1) return pkcs7
def response_to_pkcs7(blob): der = b64decode(blob) pkcs7_buf = MemoryBuffer(der) if pkcs7_buf is None: raise BIOError(Err.get_error()) p7_ptr = pkcs7_read_bio_der(pkcs7_buf.bio) pkcs7 = PKCS7(p7_ptr, 1) return pkcs7
def run(self): """Run analysis. @return: analysis results dict or None. """ if not os.path.exists(self.file_path): return None try: self.pe = pefile.PE(self.file_path) except pefile.PEFormatError: return None results = {} results["peid_signatures"] = self._get_peid_signatures() results["pe_imports"] = self._get_imported_symbols() results["pe_exports"] = self._get_exported_symbols() results["pe_dirents"] = self._get_directory_entries() results["pe_sections"] = self._get_sections() results["pe_overlay"] = self._get_overlay() results["pe_resources"] = self._get_resources() results["pe_versioninfo"] = self._get_versioninfo() results["pe_imphash"] = self._get_imphash() results["pe_timestamp"] = self._get_timestamp() results["imported_dll_count"] = len( [x for x in results["pe_imports"] if x.get("dll")]) if HAVE_CRYPTO: address = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[ pefile.DIRECTORY_ENTRY[ 'IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress #check if file is digitally signed if address == 0: return results signature = self.pe.write()[address + 8:] bio = BIO.MemoryBuffer(signature) if bio: swig_pkcs7 = m2.pkcs7_read_bio_der(bio.bio_ptr()) if swig_pkcs7: p7 = SMIME.PKCS7(swig_pkcs7) xst = p7.get0_signers(X509.X509_Stack()) results["digital_signer"] = {} if xst: for cert in xst: sn = cert.get_serial_number() subject_str = str(cert.get_subject()) cn = subject_str[subject_str.index("/CN=") + len("/CN="):] results["digital_signer"] = [{ "sn": str(sn), "cn": cn }] return results
def verify_file_with_ds_certificate(self, filename, p7filename, is_self_signed=True): if not os.access(filename, os.R_OK): self.logger.error("No filename to verify '%s' found" % filename) return None if not os.access(p7filename, os.R_OK): self.logger.error("No filename to verify '%s' found" % filename) return None if not self.load_engine(): return None # nel caso sia fallito il caricamento smartcard_atr = SmartcardFetcher.get_smartcard_atr(self.logger) smartcard_library = SmartcardFetcher.get_smartcard_library( smartcard_atr, self.config, self.logger ) smartcard = SmartcardFetcher.SmartcardFetcher(smartcard_library, self.logger) self.logger.status('get ds id') ds_id = smartcard.get_ds_id() # ottengo l'id per estrarre il certificato dall smartcard self.logger.status('get ds certificate') certificate = self.get_ds_certificate(ds_id) # ottengo il certificato if certificate is None: return None # creo uno store di certificati store_stack = X509.X509_Stack() store_stack.push(certificate) store = X509.X509_Store() store.add_x509(certificate) signer = SMIME.SMIME() signer.set_x509_stack(store_stack) signer.set_x509_store(store) #p7, data = SMIME.load_pkcs7(p7m_file) # carico il file firmato in formato PEM self.logger.status('read p7mfile %s' % p7filename) p7m_fd = open(p7filename, "rb") p7_input_bio = BIO.File(p7m_fd) # carico il file p7m p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(p7_input_bio._ptr()), 1) # al momento non c'e' nessun modo per estrarre i dati del DER dal certificato # p7, data = SMIME.load_pkcs7_bio(p7_input_bio) # l'input bio deve essere in formato PEM (basa64) data_bio = None try: if is_self_signed: self.logger.status('verifing file') v = signer.verify(p7, data_bio, flags=SMIME.PKCS7_NOVERIFY) else: v = signer.verify(p7, data_bio) except SMIME.SMIME_Error, e: self.logger.error('smime error: ' + str(e)) return None
def run(self): """Run analysis. @return: analysis results dict or None. """ if not os.path.exists(self.file_path): return None try: self.pe = pefile.PE(self.file_path) except pefile.PEFormatError: return None results = {} results["peid_signatures"] = self._get_peid_signatures() results["pe_imagebase"] = self._get_imagebase() results["pe_entrypoint"] = self._get_entrypoint() results["pe_imports"] = self._get_imported_symbols() results["pe_exports"] = self._get_exported_symbols() results["pe_dirents"] = self._get_directory_entries() results["pe_sections"] = self._get_sections() results["pe_overlay"] = self._get_overlay() results["pe_resources"] = self._get_resources() results["pe_icon"] = self._get_icon() results["pe_versioninfo"] = self._get_versioninfo() results["pe_imphash"] = self._get_imphash() results["pe_timestamp"] = self._get_timestamp() results["imported_dll_count"] = len([x for x in results["pe_imports"] if x.get("dll")]) if HAVE_CRYPTO: address = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress #check if file is digitally signed if address == 0: return results signature = self.pe.write()[address+8:] bio = BIO.MemoryBuffer(signature) if bio: swig_pkcs7 = m2.pkcs7_read_bio_der(bio.bio_ptr()) if swig_pkcs7: p7 = SMIME.PKCS7(swig_pkcs7) xst = p7.get0_signers(X509.X509_Stack()) results["digital_signers"] = [] if xst: for cert in xst: sn = cert.get_serial_number() sha1_fingerprint = cert.get_fingerprint('sha1').lower() md5_fingerprint = cert.get_fingerprint('md5').lower() subject_str = str(cert.get_subject()) cn = subject_str[subject_str.index("/CN=")+len("/CN="):] results["digital_signers"].append({"sn":str(sn), "cn":cn, "sha1_fingerprint" : sha1_fingerprint, "md5_fingerprint" : md5_fingerprint }) return results
def processSignedPlist(infile): certstore_path = "/etc/ssl/certs/ca-certificates.crt" file_descriptor = infile input_bio = BIO.MemoryBuffer(file_descriptor) signer = SMIME.SMIME() cert_store = X509.X509_Store() cert_store.load_info(certstore_path) signer.set_x509_store(cert_store) try: p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1) except SMIME.SMIME_Error, e: logging.error('load pkcs7 error: ' + str(e))
def load_pkcs7_der(p7file): # type: (AnyStr) -> PKCS7 bio = m2.bio_new_file(p7file, 'r') if bio is None: raise BIO.BIOError(Err.get_error()) try: p7_ptr = m2.pkcs7_read_bio_der(bio) finally: m2.bio_free(bio) if p7_ptr is None: raise PKCS7_Error(Err.get_error()) return PKCS7(p7_ptr, 1)
def load_pkcs7_der(p7file): # type: (AnyStr) -> PKCS7 bio = m2.bio_new_file(p7file, 'r') if bio is None: raise BIO.BIOError(Err.get_error()) try: p7_ptr = m2.pkcs7_read_bio_der(bio) finally: m2.bio_free(bio) if p7_ptr is None: raise PKCS7_Error(Err.get_error()) return PKCS7(p7_ptr, 1)
def load_pkcs7_bio_der(p7_der): """ Load a PKCS7 object from a PKCS7 DER blob. Return PKCS7 object. """ bio = BIO.MemoryBuffer(p7_der) if bio is None: raise PKCS7VerifyError(Err.get_error()) p7_ptr = m2.pkcs7_read_bio_der(bio._ptr()) if p7_ptr is None: raise PKCS7VerifyError(Err.get_error()) return PKCS7(p7_ptr, 1)
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 _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 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 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 get_signature_serial_number(pkcs7): """ Extracts the serial number out of a DER formatted, detached PKCS7 signature buffer """ pkcs7_buf = MemoryBuffer(pkcs7) if pkcs7_buf is None: raise BIOError(Err.get_error()) p7_ptr = pkcs7_read_bio_der(pkcs7_buf.bio) p = PKCS7(p7_ptr, 1) # Fetch the certificate stack that is the list of signers # Since there should only be one in this use case, take the zeroth # cert in the stack and return its serial number return p.get0_signers(X509_Stack())[0].get_serial_number()
def getCertificateDetails(filename): basename = "" cert_details = {} basename = os.path.basename(filename).split('.')[0] cert_name = "%s_digisig.crt" % basename try: if _extractDigitalSignature(filename, signatureFile=cert_name) != None: bio=BIO.File(open(cert_name)) smime_object = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr())) signers = smime_object.get0_signers(X509.X509_Stack()) cert_details["cert_issued_by"] = signers[0].get_issuer().CN cert_details["cert_issued_to"] = signers[0].get_subject().CN validity = signers[0].get_not_after().get_datetime() cert_details["cert_expiration"] = "%s-%s-%s" % (validity.year, validity.month, validity.day) except Exception, ex: print "ERROR: Problem in retrieving certificate details : %s" % ex
def test_signing(): """ This test can only run locally if you provide your personal Apple Wallet certificates, private key and password. It would not be wise to add them to git. Store them in the files indicated below, they are ignored by git. """ try: with open(password_file) as file_: password = file_.read().strip() except IOError: password = '' passfile = create_shell_pass() manifest_json = passfile._createManifest(passfile._createPassJson()) signature = passfile._createSignature( manifest_json, certificate, key, wwdr_certificate, password, ) smime_obj = SMIME.SMIME() store = X509.X509_Store() store.load_info(str(wwdr_certificate)) smime_obj.set_x509_store(store) signature_bio = BIO.MemoryBuffer(signature) signature_p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(signature_bio._ptr()), 1) stack = signature_p7.get0_signers(X509.X509_Stack()) smime_obj.set_x509_stack(stack) data_bio = BIO.MemoryBuffer(manifest_json) # PKCS7_NOVERIFY = do not verify the signers certificate of a signed message. assert smime_obj.verify( signature_p7, data_bio, flags=SMIME.PKCS7_NOVERIFY ) == manifest_json tampered_manifest = '{"pass.json": "foobar"}' data_bio = BIO.MemoryBuffer(tampered_manifest) # Verification MUST fail! with pytest.raises(SMIME.PKCS7_Error): smime_obj.verify(signature_p7, data_bio, flags=SMIME.PKCS7_NOVERIFY)
def test_signing(): """ This test can only run locally if you provide your personal Apple Wallet certificates, private key and password. It would not be wise to add them to git. Store them in the files indicated below, they are ignored by git. """ try: with open(password_file) as file_: password = file_.read().strip() except IOError: password = '' passfile = create_shell_pass() manifest_json = passfile._createManifest(passfile._createPassJson()) signature = passfile._createSignature( manifest_json, certificate, key, wwdr_certificate, password, ) smime_obj = SMIME.SMIME() store = X509.X509_Store() store.load_info(str(wwdr_certificate)) smime_obj.set_x509_store(store) signature_bio = BIO.MemoryBuffer(signature) signature_p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(signature_bio._ptr()), 1) stack = signature_p7.get0_signers(X509.X509_Stack()) smime_obj.set_x509_stack(stack) data_bio = BIO.MemoryBuffer(manifest_json) # PKCS7_NOVERIFY = do not verify the signers certificate of a signed message. assert smime_obj.verify( signature_p7, data_bio, flags=SMIME.PKCS7_NOVERIFY ) == manifest_json tampered_manifest = '{"pass.json": "foobar"}' data_bio = BIO.MemoryBuffer(tampered_manifest) # Verification MUST fail! with pytest.raises(SMIME.PKCS7_Error): smime_obj.verify(signature_p7, data_bio, flags=SMIME.PKCS7_NOVERIFY)
def load_pkcs7_der(p7file): """ Load a PKCS7 object from a PKCS7 DER file. Return PKCS7 object. """ bio = m2.bio_new_file(p7file, 'r') if bio is None: raise PKCS7VerifyError(Err.get_error()) try: p7_ptr = m2.pkcs7_read_bio_der(bio) finally: m2.bio_free(bio) if p7_ptr is None: raise PKCS7VerifyError(Err.get_error()) return PKCS7(p7_ptr, 1)
def getCertificateDetails(filename): basename = "" cert_details = {} basename = os.path.basename(filename).split('.')[0] cert_name = "%s_digisig.crt" % basename try: if _extractDigitalSignature(filename, signatureFile=cert_name) != None: bio=BIO.File(open(cert_name)) smime_object = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr())) signers = smime_object.get0_signers(X509.X509_Stack()) cert_details["cert_issued_by"] = signers[0].get_issuer().CN cert_details["cert_issued_to"] = signers[0].get_subject().CN validity = signers[0].get_not_after().get_datetime() cert_details["cert_expiration"] = "%s-%s-%s" % (validity.year, validity.month, validity.day) bio.close() del bio except Exception, ex: print "ERROR: Problem in retrieving certificate details : %s" % ex
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, e: logging.error('load pkcs7 error: ' + str(e)) raise
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, e: logging.error('load pkcs7 error: ' + str(e)) raise
def upload_encr(): mdm_ca = get_ca() upl_encrypt = unhexlify(request.files['upload_encr_file'].stream.read()) s = SMIME.SMIME() bio = BIO.MemoryBuffer(upl_encrypt) s.load_key_bio( BIO.MemoryBuffer(mdm_ca.get_private_key().to_pem()), BIO.MemoryBuffer(mdm_ca.get_cacert().to_pem())) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr())) out = s.decrypt(p7) response = make_response(out) response.headers['Content-Type'] = 'application/octet-stream' response.headers['Content-Disposition'] = 'attachment; filename=mdm_signed_request.%s.plist.b64' % datetime.datetime.now().strftime('%Y%m%d_%H%M%S') return response
def upload_encr(): mdm_ca = get_ca() upl_encrypt = unhexlify(request.files['upload_encr_file'].stream.read()) s = SMIME.SMIME() bio = BIO.MemoryBuffer(upl_encrypt) s.load_key_bio(BIO.MemoryBuffer(mdm_ca.get_private_key().to_pem()), BIO.MemoryBuffer(mdm_ca.get_cacert().to_pem())) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr())) out = s.decrypt(p7) response = make_response(out) response.headers['Content-Type'] = 'application/octet-stream' response.headers[ 'Content-Disposition'] = 'attachment; filename=mdm_signed_request.%s.plist.b64' % datetime.datetime.now( ).strftime('%Y%m%d_%H%M%S') return response
def verify(client: Client, args: Dict): """ Verify the signature Args: client: Client args: Dict """ signed_message = demisto.getFilePath(args.get('signed_message')) x509 = X509.load_cert(client.public_key_file) sk = X509.X509_Stack() sk.push(x509) client.smime.set_x509_stack(sk) st = X509.X509_Store() st.load_info(client.public_key_file) client.smime.set_x509_store(st) try: p7, data = SMIME.smime_load_pkcs7(signed_message['path']) v = client.smime.verify(p7, data, flags=SMIME.PKCS7_NOVERIFY) human_readable = f'The signature verified\n\n{v}' except SMIME.SMIME_Error as e: if str( e ) == 'no content type': # If no content type; see if we can process as DER format with open(signed_message['path'], "rb") as message_file: p7data = message_file.read() p7bio = BIO.MemoryBuffer(p7data) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(p7bio._ptr())) v = client.smime.verify(p7, flags=SMIME.PKCS7_NOVERIFY) return_results( fileResult('unwrapped-' + signed_message.get('name'), v)) human_readable = 'The signature verified\n\n' return human_readable, {}
def load_pkcs7_der(p7file): # type: (AnyStr) -> PKCS7 with BIO.openfile(p7file, 'rb') as bio: p7_ptr = m2.pkcs7_read_bio_der(bio.bio) return PKCS7(p7_ptr, 1)
def load_pkcs7_bio_der(p7_bio): # type: (BIO.BIO) -> PKCS7 p7_ptr = m2.pkcs7_read_bio_der(p7_bio._ptr()) return PKCS7(p7_ptr, 1)
def load_pkcs7_der(p7file): # type: (AnyStr) -> PKCS7 with BIO.openfile(p7file, 'rb') as bio: p7_ptr = m2.pkcs7_read_bio_der(bio.bio) return PKCS7(p7_ptr, 1)
# To run, provide the path to a signed profile at the command line: # ./unsignprofile.py SignedProfile.mobileconfig from M2Crypto import SMIME, X509, m2, BIO from plistlib import * import sys import logging # Can be any file probably since we're not verifying. certstore_path = "/etc/ssl/certs/ca-certificates.crt" file_descriptor = open(sys.argv[1], 'rb') input_bio = BIO.File(file_descriptor) signer = SMIME.SMIME() cert_store = X509.X509_Store() cert_store.load_info(certstore_path) signer.set_x509_store(cert_store) try: p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1) except SMIME.SMIME_Error, e: logging.error('load pkcs7 error: ' + str(e)) sk3 = p7.get0_signers(X509.X509_Stack()) signer.set_x509_stack(sk3) data_bio = None content = signer.verify(p7, data_bio, flags=SMIME.PKCS7_NOVERIFY) # Printing the contents of the profile/plist, modify to save to file with write() print readPlistFromString(content)
def get_decrypted_envelope_data(self, x509, evpkey): buf = BIO.MemoryBuffer(self.signedcontent) p7 = m2.pkcs7_read_bio_der(buf._ptr()) return m2.pkcs7_decrypt(p7, evpkey._ptr(), x509._ptr(), 0)
def load_pkcs7_bio_der(p7_bio): # type: (BIO.BIO) -> PKCS7 p7_ptr = m2.pkcs7_read_bio_der(p7_bio._ptr()) if p7_ptr is None: raise PKCS7_Error(Err.get_error()) return PKCS7(p7_ptr, 1)
def verify_file_with_ds_certificate(self, filename, p7filename, is_self_signed=True): if not os.access(filename, os.R_OK): self.logger.error("No filename to verify '%s' found" % filename) return None if not os.access(p7filename, os.R_OK): self.logger.error("No filename to verify '%s' found" % filename) return None if not self.load_engine(): return None # nel caso sia fallito il caricamento smartcard_atr = SmartcardFetcher.get_smartcard_atr(self.logger) smartcard_library = SmartcardFetcher.get_smartcard_library( smartcard_atr, self.config, self.logger) smartcard = SmartcardFetcher.SmartcardFetcher(smartcard_library, self.logger) self.logger.status('get ds id') ds_id = smartcard.get_ds_id( ) # ottengo l'id per estrarre il certificato dall smartcard self.logger.status('get ds certificate') certificate = self.get_ds_certificate(ds_id) # ottengo il certificato if certificate is None: return None # creo uno store di certificati store_stack = X509.X509_Stack() store_stack.push(certificate) store = X509.X509_Store() store.add_x509(certificate) signer = SMIME.SMIME() signer.set_x509_stack(store_stack) signer.set_x509_store(store) #p7, data = SMIME.load_pkcs7(p7m_file) # carico il file firmato in formato PEM self.logger.status('read p7mfile %s' % p7filename) p7m_fd = open(p7filename, "rb") p7_input_bio = BIO.File(p7m_fd) # carico il file p7m p7 = SMIME.PKCS7( m2.pkcs7_read_bio_der(p7_input_bio._ptr()), 1 ) # al momento non c'e' nessun modo per estrarre i dati del DER dal certificato # p7, data = SMIME.load_pkcs7_bio(p7_input_bio) # l'input bio deve essere in formato PEM (basa64) data_bio = None try: if is_self_signed: self.logger.status('verifing file') v = signer.verify(p7, data_bio, flags=SMIME.PKCS7_NOVERIFY) else: v = signer.verify(p7, data_bio) except SMIME.SMIME_Error, e: self.logger.error('smime error: ' + str(e)) return None
def pkioperation(data): input_bio = BIO.MemoryBuffer(data) signer = SMIME.SMIME() cert_store = X509.X509_Store() cert_store.load_info(certstore_path) signer.set_x509_store(cert_store) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1) signers = p7.get0_signers(X509.X509_Stack()) f = open('p7signers.pem', 'w') f.write(signers.pop().as_pem()) f.close() signer.set_x509_stack(signers) data = signer.verify(p7, flags=SMIME.PKCS7_NOVERIFY) ########################### #Decrypt #### s = SMIME.SMIME() # Load private key and cert. s.load_key(key_path, certstore_path) input_der = BIO.MemoryBuffer(data) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_der._ptr()), 1) # Decrypt p7. out = s.decrypt(p7) #f = open('csr.der', 'w') #f.write(out) #f.close() #### #Convert the certificate to pem ##### #openssl_convert = 'openssl req -in csr.der -inform der -out csr.pem' #call(cmd(openssl_convert)) x509_request = X509.load_request_der_string(out) x509_request.save_pem('csr.pem') ################################# # After decryption, we will get csr # and generate cert. For now, we will use an existing certificate ################################# openssl_create_cert = 'openssl x509 -req -in csr.pem \ -extensions v3_ios -CA {} -CAkey {} -CAserial {} -out device_cert.pem \ -extfile {}'.format( certstore_path, key_path, serial_path, PKI_DIR + '/openssl.cnf') print openssl_create_cert call(cmd(openssl_create_cert)) ###### #Create degenerate pkcs7 der from the cert file #### openssl_degenerate = 'openssl crl2pkcs7 -nocrl -certfile device_cert.pem \ -out degenerate_cert.p7b -outform der' print openssl_degenerate call(cmd(openssl_degenerate)) degen_der = open('degenerate_cert.p7b').read() ##### # Encrypt openssl_encrypt = 'openssl smime -encrypt -des3 \ -in degenerate_cert.p7b -out enc_cert.der -outform der -binary p7signers.pem' print openssl_encrypt call(cmd(openssl_encrypt)) ###Sign openssl_sign = 'openssl smime -sign -signer ra_cert.pem \ -in enc_cert.der -binary -out final_response_python.der -outform der -inkey ra_private.pem' #call(cmd(openssl_sign)) sign_data = open('enc_cert.der').read() buf = BIO.MemoryBuffer(sign_data) s = SMIME.SMIME() s.load_key(key_path, certstore_path) p7 = s.sign(buf, flags=SMIME.PKCS7_BINARY) f = BIO.File(open('final_response_python.der', 'w')) p7.write_der(f) f.close() f = open('final_response_python.der') data = f.read() print "Goodbye" return data
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 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)
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 load_pkcs7_bio_der(p7_bio): # type: (BIO.BIO) -> PKCS7 p7_ptr = m2.pkcs7_read_bio_der(p7_bio._ptr()) if p7_ptr is None: raise PKCS7_Error(Err.get_error()) return PKCS7(p7_ptr, 1)
def load_pkcs7_bio_der(p7_bio): # type: (BIO.BIO) -> PKCS7 p7_ptr = m2.pkcs7_read_bio_der(p7_bio._ptr()) return PKCS7(p7_ptr, 1)
def checkin(request): logger = logging.getLogger('django') logger.debug('WWW Query: %s', request.body) if settings.USE_CERTIFICATE == True: # Get the certificate fingerprint try: bio = BIO.MemoryBuffer(base64.b64decode(request.META['HTTP_MDM_SIGNATURE'])) p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr()), 1) stk = X509.X509_Stack() sk3 = p7.get0_signers(stk) cert = sk3.pop() fingerprint = cert.get_fingerprint('md5') if len(fingerprint) == 31: fingerprint = '0' + fingerprint except: fingerprint = None logger.debug('Fingerprint: %s', fingerprint) # If no certificate supplied, permission denied. if fingerprint == None and settings.REQUIRE_CERTIFICATE == True: return HttpResponseForbidden() # If no certificate found, permission denied. certificate = Certificate.objects.filter(md5=fingerprint).first() if certificate == None and settings.REQUIRE_CERTIFICATE == True: return HttpResponseForbidden() # If certificate does not match device, permission denied. # TODO else: certificate = None # Prepare handling of checkin request and response commands. responseData = plistlib.writePlistToString(dict()) standard_commands.initialize() try: plist = plistlib.readPlistFromString(request.body) except: plist = dict() if 'MessageType' in plist: if plist['MessageType'] == 'Authenticate': if 'UserID' in plist: return HttpResponseBadRequest('User binding not currently supported') device = Device.objects.filter(udid=plist['UDID']).first() if device == None: device = Device(udid=plist['UDID'], push_topic=plist['Topic']) device.last_checkin = datetime.now() device.last_notification = datetime.now() device.save() if certificate != None: certificate.device = device certificate.save() try: group = DeviceGroup.objects.filter(uuid=settings.DEFAULT_DEVICE_GROUP).first() group.devices.add(device) group.save() except: pass elif plist['MessageType'] == 'TokenUpdate': if 'UserID' in plist: return HttpResponseBadRequest('User binding not currently supported') device = Device.objects.get(udid=plist['UDID']) device.push_topic = plist['Topic'] device.push_token = plist['Token'].asBase64(maxlinelength=8000) device.push_magic = plist['PushMagic'] device.last_checkin = datetime.now() device.save() DeviceCommand.NewDeviceInformation(device) DeviceCommand.NewProfileList(device) DeviceCommand.NewInstalledApplicationList(device) push.push_notification(device) elif plist['MessageType'] == 'CheckOut': if 'UserID' in plist: return HttpResponseBadRequest('User binding not currently supported') Device.objects.get(udid=plist['UDID']).delete() else: print 'Unknown message type: ' + plist['MessageType'] print plist elif 'Status' in plist: responseData = '' # Update device checkin time device = Device.objects.get(udid=plist['UDID']) device.last_checkin = datetime.now() device.save() # Update device location if it has been 15 minutes since last. since = datetime.now() - timedelta(minutes=15) location = DeviceCheckin.objects.filter(device=device).order_by('-end_date').first() if location and location.ip == request.META['REMOTE_ADDR']: location.end_date = datetime.now() location.save() else: location = DeviceCheckin(device=device) location.start_date = datetime.now() location.end_date = datetime.now() location.ip = request.META['REMOTE_ADDR'] loc = geo.geocode(request.META['REMOTE_ADDR']) location.latitude = loc['latitude'] location.longitude = loc['longitude'] location.country_code = loc['country_code'] location.region_code = loc['region_code'] location.city = loc['city'] if 'country_name' in loc: location.country_name = loc['country_name'] if 'region_name' in loc: location.region_name = loc['region_name'] location.save() if plist['Status'] == 'Acknowledged': cmd = DeviceCommand.objects.get(uuid=plist['CommandUUID']) cmd.status = DeviceCommand.SUCCESS cmd.date_completed = datetime.now() cmd.save() commands.handleCommandResponse(cmd, plist) elif plist['Status'] == 'Error' or plist['Status'] == 'CommandFormatError': cmd = DeviceCommand.objects.get(uuid=plist['CommandUUID']) cmd.status = DeviceCommand.FAILED cmd.date_completed = datetime.now() cmd.save() elif plist['Status'] == 'NotNow': cmd = DeviceCommand.objects.get(uuid=plist['CommandUUID']) cmd.status = DeviceCommand.PENDING cmd.attempts = 0 cmd.save() if plist['Status'] == 'Idle' or plist['Status'] == 'Acknowledged': # Look for the next command, mark as failed if too many attempts. cmd = DeviceCommand.objects.filter(device=device, status__in=[DeviceCommand.PENDING, DeviceCommand.RUNNING]).first() while cmd and cmd.attempts >= 3: cmd.status = DeviceCommand.FAILED cmd.save() cmd = DeviceCommand.objects.filter(device=device, status__in=[DeviceCommand.PENDING, DeviceCommand.RUNNING]).first() # Run the next command. if cmd: data = commands.dataForCommand(cmd) responseData = plistlib.writePlistToString(data) cmd.status = DeviceCommand.RUNNING cmd.attempts += 1 cmd.save() logger.debug('WWW Result: %s', responseData) response = HttpResponse(responseData, content_type = 'application/xml; charset=UTF-8') response['Content-Length'] = len(responseData) return response
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
from M2Crypto import SMIME, X509, BIO, m2 import plistlib import sys if len(sys.argv) < 3: print "Usage: %s [Provisioning Profile] [Out .xcconfig]" % __file__ exit() inProfile = sys.argv[1] outXcConfig = sys.argv[2] provision = open(inProfile, 'r') inBio = BIO.File(provision) pkcs7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(inBio._ptr())) smime = SMIME.SMIME() stack = X509.X509_Stack() smime.set_x509_stack(stack) store = X509.X509_Store() smime.set_x509_store(store) dataBio = None blob = smime.verify(pkcs7, dataBio, SMIME.PKCS7_NOVERIFY | SMIME.PKCS7_NOSIGS) certs = pkcs7.get0_signers(stack) signer = certs[0] items = signer.get_subject().get_entries_by_nid(X509.X509_Name.nid["CN"])
def verify_file(path): with open(path, 'rb') as ota_file: ota_file.seek(0, 2) length = ota_file.tell() ota_file.seek(-FOOTER_SIZE, 2) footer = bytearray(ota_file.read()) if (footer[2] != 0xff or footer[3] != 0xff): print("This zip is not signed!") return False comment_size = footer[4] + (footer[5] << 8) signature_start = footer[0] + (footer[1] << 8) print("Comment is %d bytes; signature %d bytes from end." % (comment_size, signature_start)) eocd_size = comment_size + EOCD_HEADER_SIZE ota_file.seek(-eocd_size, 2) signed_len = ota_file.tell() + EOCD_HEADER_SIZE - 2 eocd = bytearray(ota_file.read(eocd_size)) if (eocd[0] != 0x50 or eocd[1] != 0x4b or eocd[2] != 0x05 or eocd[3] != 0x06): print("Signature length doesn't match EOCD marker.") return False for i in range(4, eocd_size-3): if (eocd[i] == 0x50 and eocd[i+1] == 0x4b and eocd[i+2] == 0x05 and eocd[i+3] == 0x06): print("EOCD marker occurs after start of EOCD") return False ota_file.seek(0,0) zip_content = bytearray(ota_file.read(signed_len)) sha1 = hashlib.sha1() sha1.update(zip_content) signature_size = signature_start - FOOTER_SIZE signature = eocd[eocd_size-signature_start:signature_size] print("Signature (offset: %x, length: %d):" % (length-signature_start, signature_size)) s = SMIME.SMIME() # Load the signer's cert. x509 = X509.load_cert('certificate.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('certificate.pem') s.set_x509_store(st) # Load the data, verify it. # signature is a buffer containing the signature in pkcs#7 DER format p7bio = BIO.MemoryBuffer(signature) contentbio = BIO.MemoryBuffer(zip_content) contentbio = BIO.openfile('ota-unsign.zip') p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(p7bio._ptr())) md = EVP.MessageDigest('sha1') md.update(zip_content) print binascii.b2a_hex(md.digest()) v = s.verify(p7) v = s.verify(p7, contentbio) print v