Add migrate certificates

This commit is contained in:
Mauricio Baeza 2021-01-06 21:30:31 -06:00
parent 39071be43b
commit 4b9df44dac
6 changed files with 73 additions and 33 deletions

View File

@ -17,7 +17,9 @@ con su respectiva contraseña, te quedarás sin poder timbrar.
menú "Emisor" ficha "Otros Datos", usuario y token de timbrado. menú "Emisor" ficha "Otros Datos", usuario y token de timbrado.
1. Agregar nuevo requerimiento `pip install xmlsec` 1. Agregar nuevo requerimiento `pip install xmlsec`
1. Actualizar `git pull origin master` 1. Actualizar `git pull origin master`
1. Entrar a `source/app/controllers/pacs` y copiar `conf.py.example` a `conf.py` 1. Entrar a `source/app/controllers/pacs/comerciodigital` y copiar `conf.py.example` a `conf.py`
1. Entrar a `source/app/controllers/pacs/finkok` y copiar `conf.py.example` a `conf.py`
1. Agregar la variable `TOKEN` al archivo `source/app/conf.py`
1. Reiniciar el servicio: `sudo systemctl restart empresalibre` 1. Reiniciar el servicio: `sudo systemctl restart empresalibre`
1. Sube de nuevo tus certificados en el menú "Emisor" ficha "Certificado". 1. Sube de nuevo tus certificados en el menú "Emisor" ficha "Certificado".
1. Ve al menú "Opciones", ficha "Otros". 1. Ve al menú "Opciones", ficha "Otros".

View File

@ -13,13 +13,7 @@ TITLE_APP = 'Empresa Libre'
#~ Establece una ruta accesible para el servidor web #~ Establece una ruta accesible para el servidor web
LOG_PATH = '/var/log/empresalibre/empresa-libre.log' LOG_PATH = '/var/log/empresalibre/empresa-libre.log'
# ~ Establece los valores para sincronizar los backups de la base de datos # ~ Establece un token personalizado para encriptar las claves
# ~ por ejemplo # ~ from secrets import token_hex
# ~ SEAFILE_SERVER = { # ~ token_hex(32)
# ~ 'URL': 'https://tu_servidor_seafile', TOKEN = ''
# ~ 'USER': 'tu_usuario',
# ~ 'PASS': 'tu_contraseña',
# ~ 'REPO': 'id_repo',
# ~ }
SEAFILE_SERVER = {}

View File

@ -4,6 +4,7 @@ import argparse
import base64 import base64
import datetime import datetime
import getpass import getpass
import subprocess
from pathlib import Path from pathlib import Path
import xmlsec import xmlsec
@ -211,6 +212,40 @@ class SATCertificate(object):
def error(self): def error(self):
return self._error return self._error
@classmethod
def save_cert(cls, obj):
import hashlib
cer = x509.load_pem_x509_certificate(obj.cer_pem.encode(), default_backend())
cer_der = cer.public_bytes(serialization.Encoding.DER)
token = hashlib.md5(obj.rfc.encode()).hexdigest()
path = Path(f'/tmp/{obj.rfc}.key')
path.write_text(obj.key_enc)
args = f'openssl rsa -inform PEM -outform PEM -in "{str(path)}" -passin pass:{token}'
pem = subprocess.check_output(args, shell=True).decode()
key = serialization.load_pem_private_key(pem.encode(), password=None)
digest = hashes.Hash(hashes.SHA512(), default_backend())
digest.update(obj.rfc.encode())
digest.update(obj.serie.encode())
digest.update(TOKEN.encode())
p = digest.finalize()
key_enc = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.BestAvailableEncryption(p)
)
cert = SATCertificate(cer_der, key_enc)
obj.key_enc = cert.key_enc
obj.cer = cert.cer
obj.serie = cert.serial_number
obj.desde = cert.not_before
obj.hasta = cert.not_after
obj.save()
return
def main(args): def main(args):
# ~ contra = getpass.getpass('Introduce la contraseña del archivo KEY: ') # ~ contra = getpass.getpass('Introduce la contraseña del archivo KEY: ')

View File

@ -78,8 +78,6 @@ class PACComercioDigital(object):
def __init__(self): def __init__(self):
self.error = '' self.error = ''
# ~ self.cfdi_uuid = ''
# ~ self.date_stamped = ''
def _error(self, msg): def _error(self, msg):
self.error = str(msg) self.error = str(msg)

View File

@ -460,26 +460,6 @@ def _get_uuid_fecha(xml):
return node.attrib['UUID'], node.attrib['FechaTimbrado'] return node.attrib['UUID'], node.attrib['FechaTimbrado']
def _ecodex_timbra_xml(xml):
from .pac import Ecodex as PAC
from .configpac import ecodex
auth, url = ecodex(DEBUG)
pac = PAC(auth, url)
xml = pac.timbra_xml(xml)
if xml:
data = {'ok': True, 'error': ''}
data['xml'] = xml
uuid, fecha = _get_uuid_fecha(xml)
data['uuid'] = uuid
data['fecha'] = fecha
return data
msg = pac.error
return {'ok': False, 'error': msg}
def get_sat(xml): def get_sat(xml):
from .pac import get_status_sat from .pac import get_status_sat
return get_status_sat(xml) return get_status_sat(xml)

View File

@ -10492,6 +10492,29 @@ def _change_pass(rfc):
return return
def _export_cert():
rfc = input('Introduce el RFC: ').strip().upper()
if not rfc:
msg = 'El RFC es requerido'
log.error(msg)
return
args = util.get_con(rfc)
if not args:
return
conectar(args)
log.info('Exportando certificados...')
obj = Certificado.get(Certificado.es_fiel==False)
cert = utils.SATCertificate
cert.save_cert(obj)
desconectar()
log.info('Proceso terminado correctamente...')
return
def _process_command_line_arguments(): def _process_command_line_arguments():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Empresa Libre') description='Empresa Libre')
@ -10516,6 +10539,9 @@ def _process_command_line_arguments():
parser.add_argument('-ed', '--export-documents', dest='export_documents', parser.add_argument('-ed', '--export-documents', dest='export_documents',
action='store_true', default=False, required=False) action='store_true', default=False, required=False)
parser.add_argument('-ec', '--export-cert', dest='export_cert',
action='store_true', default=False, required=False)
parser.add_argument('-r', '--rfc', dest='rfc', default='') parser.add_argument('-r', '--rfc', dest='rfc', default='')
return parser.parse_args() return parser.parse_args()
@ -10555,6 +10581,11 @@ def main(args):
if args.export_documents: if args.export_documents:
_export_documents() _export_documents()
return
if args.export_cert:
_export_cert()
return
return return