def __init__(self, cer=None, key=None, cer_pem=None, test=False): self.files = {} path_file_key = tmp_dir_o_file + id_generator(size=SIZE_NAME) path_file_keypem = tmp_dir_o_file + id_generator(size=SIZE_NAME) path_file_cer = tmp_dir_o_file + id_generator(size=SIZE_NAME) if cer_pem is None: path_file_cerpem = tmp_dir_o_file + id_generator(size=SIZE_NAME) else: path_file_cerpem = cer_pem self.files["key"] = {"der": path_file_key, "pem": path_file_keypem} self.files["cer"] = { "der": path_file_cer, "pem": path_file_cerpem, "pubkey": None } self.files["sign"] = { "digest": None, "base64": None, "o_string": None, "sello": None, "pkcs7": None } self.files["transform"] = {} self.user_info_cer = None self.test = test if cer is not None: save_file(path_file_cer, cer) error = self.cer2pem() if error: self.clean() raise Exception, "PEM", "No se puede convertir a pem el certificado" if key is not None: save_file(path_file_key, key)
def handle(self, *args, **options): user_document_sign_id = options.get('user_document_sign_id', "") user_document_sign = UserDocumentSign.objects.get( id=user_document_sign_id) transaction_number = user_document_sign.transaction.number new_base_path_dir_pdf = "%sT%s" % (tmp_dir_pdf_file, transaction_number) new_base_path_dir_xml = "%sT%s" % (tmp_dir_xml_file, transaction_number) try: pdf_file = user_document_sign.document.path except SuspiciousFileOperation: pdf_file = user_document_sign.document.url try: xml_file = user_document_sign.xml.path except SuspiciousFileOperation: xml_file = user_document_sign.xml.url n_pdf_file = new_base_path_dir_pdf + "/" + id_generator(size=SIZE_NAME) n_xml_file = new_base_path_dir_xml + "/" + id_generator(size=SIZE_NAME) call(["cp", pdf_file, n_pdf_file]) call(["cp", xml_file, n_xml_file]) user_document_sign.document = n_pdf_file user_document_sign.xml = n_xml_file user_document_sign.save() print("moved PDF from {}".format(pdf_file)) print("to {}".format(n_pdf_file)) print("moved XML from {}".format(xml_file)) print("to {}".format(n_xml_file)) os.remove(pdf_file) os.remove(xml_file)
def sign(self, documento, password, issuer_cer_path, ocsp_cer, chain_cer): VALID_CERT = [ "O=Servicio de Administraci\\xC3\\xB3n Tributaria", "O=Inmegen", "0=Test CA" ] data_info = self.get_info_cer() error = self.key2pem(password) if error: self.clean() return error, "PEM", "La contraseña es incorrecta" elif not data_info["io"] in VALID_CERT: self.clean() return "", "SIGN", "El firmante del certificado no es válido" elif not self.key_match_cer(): self.clean() return "", "SIGN", "El certificado no corresponde a la llave" elif not self.is_valid_ca_cer(chain_cer) and self.test is False: self.clean() return "", "SIGN", "El certificado no corresponde a la cadena de certificados" elif not self.cert_is_valid(issuer_cer_path, ocsp_cer): self.clean() return "", "SIGN", "El certificado no es válido por el ocsp" self.files["sign"]["digest"] = tmp_dir_o_file + id_generator( size=SIZE_NAME) self.files["sign"]["base64"] = tmp_dir_o_file + id_generator( size=SIZE_NAME) self.original_string(documento) self.digest_binary(self.files["sign"]["o_string"], self.files["sign"]["digest"]) self.base64(self.files["sign"]["digest"], self.files["sign"]["base64"])
def verify_digest(self): pubkey = self.get_pubkey() self.files["cer"]["pubkey"] = tmp_dir_o_file + id_generator( size=SIZE_NAME) self.files["sign"]["sello"] = tmp_dir_o_file + id_generator( size=SIZE_NAME) with open(self.files["cer"]["pubkey"], "wb") as f: f.write(pubkey) self.__dec(self.files["sign"]["sello"], self.files["sign"]["base64"]) return self.__verify_digest( self.files["sign"]["sello"], self.files["sign"]["o_string"]).find("Verified OK") != -1
def to_pkcs12(self, password): self.key2pem(password) self.__pkcs12(password) tmp_file = tmp_dir_o_file + id_generator(size=SIZE_NAME) self.base64(self.files["transform"]["pkcs12"], tmp_file) with open(tmp_file, 'rb') as f: base64 = f.read() clean([tmp_file]) return base64
def __pkcs12(self, password): self.files["transform"]["pkcs12"] = tmp_dir_o_file + id_generator( size=SIZE_NAME) command = "openssl pkcs12 -export -inkey {key_pem} -in {cer_pem} -out {pfx_file} -password pass:{password}".format( key_pem=self.files["key"]["pem"], cer_pem=self.files["cer"]["pem"], pfx_file=self.files["transform"]["pkcs12"], password=password) return command
def sign_pkcs7(self, pkcs7_dir, xml_url): new_base_path_dir_pkcs7 = "{name_dir}/{name_file}".format( name_dir=pkcs7_dir, name_file=id_generator(size=SIZE_NAME)) command = "openssl cms -sign -binary -nodetach -noattr -md sha256 -in {xml_file} -outform DER -out {pkcs7_file} -signer {cer_pem} -inkey {key_pem}".format( xml_file=xml_url, pkcs7_file=new_base_path_dir_pkcs7, cer_pem=self.files["cer"]["pem"], key_pem=self.files["key"]["pem"]) self.set_pkcs7(new_base_path_dir_pkcs7) return command
def sign(password, cer, key, file_, test=True): from django.conf import settings import base64 cer_f = io.BytesIO(base64.b64decode(cer)) key_f = io.BytesIO(base64.b64decode(key)) tmp_file = "/tmp/" + id_generator(size=30) with open(tmp_file, 'wb') as f: f.write(base64.b64decode(file_)) digital_sign = GenericDigitalSign(cer=cer_f, key=key_f, test=test) cer_f.close() key_f.close() organization = digital_sign.get_info_cer()["o"] number = digital_sign.get_ocsp_origin() OCSP_NUMBER = "C" + number if test is True: OCSP_NUMBER = "C0" info = digital_sign.sign(tmp_file, password, settings.CERTS[OCSP_NUMBER]["issuer"], settings.CERTS[OCSP_NUMBER]["ocsp"], settings.CERTS[OCSP_NUMBER]["chain"]) if info is not None: return {"status": "error", "msg": info[2]} #print("SIGN: ", digital_sign.verify_digest()) no_cert = digital_sign.get_no_certificado() base64_sign = digital_sign.view_base64_sign() clean([tmp_file]) digital_sign.clean() return { "status": "ok", "data": { "no_cert": no_cert, "base64": base64_sign, "organization": organization } }
def xslt_xml_transform(self, xml_filename): self.files["sign"]["o_string"] = tmp_dir_o_file + id_generator( size=SIZE_NAME) command = "xsltproc {} {} --noout --output {}".format( settings.XSLT, xml_filename, self.files["sign"]["o_string"]) return command