def charger_cle_cert(self):
        clecert = EnveloppeCleCert()

        with open(
                '%s/%s.key.pem' %
            (self.folder_output,
             ConstantesGenerateurCertificat.ROLE_DEPLOYEUR), 'rb') as fichier:
            key_bytes = fichier.read()
            clecert.key_from_pem_bytes(key_bytes)

        with open(
                '%s/%s.cert.pem' %
            (self.folder_output,
             ConstantesGenerateurCertificat.ROLE_DEPLOYEUR), 'rb') as fichier:
            cert_bytes = fichier.read()
            clecert.cert_from_pem_bytes(cert_bytes)

        # Verifier que les cles correspondent
        corresp = clecert.cle_correspondent()
        print("Cle et cert deployeur correspondent: %s" % corresp)

        with open(
                '%s/%s.cert.pem' %
            (self.folder_output, ConstantesGenerateurCertificat.ROLE_MQ),
                'rb') as fichier:
            cert_bytes = fichier.read()
            clecert.cert_from_pem_bytes(cert_bytes)

        # Verifier que les cles ne correspondent pas
        corresp = clecert.cle_correspondent()
        print("Cle deployeur et cert mq correspondent: %s" % corresp)
    def traiter_reception_certificat(self, pems):
        cert = pems[0]
        clecert = EnveloppeCleCert()
        clecert.cert_from_pem_bytes(cert.encode('utf-8'))
        subject_dict = clecert.formatter_subject()
        role = subject_dict['organizationalUnitName']

        if role == 'mongo':
            # Pour MongoDB on insere la cle (en memoire) et le nouveau certificat dans le meme secret (une key_cert)
            label_role_cert = 'pki.%s.cert' % role
            label_role_key = 'pki.%s.key' % role

            chaine = '\n'.join(pems)
            cle_mongo = self._recuperer_cle_memorisee(
                role)  # Note : efface la cle en memoire
            if not cle_mongo:
                raise ValueError("Cle mongo n'est pas presente en memoire")
            key_cert = str(cle_mongo, 'utf-8') + '\n' + chaine

            # Inserer la chaine de certificat
            nom_cle = self._service_monitor.gestionnaire_certificats.ajouter_secret(
                label_role_key, key_cert)
            date_key = nom_cle.split('.')[-1]
            self._service_monitor.gestionnaire_certificats.ajouter_config(
                label_role_cert, chaine, date_key)
        else:
            super().traiter_reception_certificat(pems)
예제 #3
0
    def __entretien_comptes(self):

        if not self._comptes_middleware_ok or not self._comptes_mq_ok:
            comptes_mq_ok = True  # Va etre mis a false si un compte n'esp pas ajoute correctement
            try:
                idmg = self._configuration.idmg
                igmd_tronque = idmg[0:12]
                roles_comptes = [info['role'] for info in MonitorConstantes.DICT_MODULES_PROTEGES.values() if info.get('role')]
                roles_comptes = ['%s.pki.%s.cert' % (igmd_tronque, role) for role in roles_comptes]

                roles_mongo = [
                    ConstantesGenerateurCertificat.ROLE_TRANSACTIONS,
                    ConstantesGenerateurCertificat.ROLE_DOMAINES,
                    ConstantesGenerateurCertificat.ROLE_MAITREDESCLES,
                ]
                for role in roles_comptes:
                    filtre = {'name': role}
                    configs = self._docker.configs.list(filters=filtre)

                    if len(configs) > 0:
                        dict_configs = dict()
                        for config in configs:
                            dict_configs[config.name] = config

                        # Choisir plus recent certificat
                        liste_configs_str = list(dict_configs.keys())
                        liste_configs_str.sort()
                        nom_config = liste_configs_str[-1]
                        config_cert = dict_configs[nom_config]

                        # Extraire certificat
                        cert_pem = b64decode(config_cert.attrs['Spec']['Data'])
                        clecert = EnveloppeCleCert()
                        clecert.cert_from_pem_bytes(cert_pem)

                        # Creer compte
                        roles_cert = clecert.get_roles
                        if any([role in roles_mongo for role in roles_cert]):
                            try:
                                self.__mongo.creer_compte(clecert)
                            except DuplicateKeyError:
                                self.__logger.debug("Compte mongo (deja) cree : %s", nom_config)

                        try:
                            gestionnaire_mq: GestionnaireComptesMQ = self._service_monitor.gestionnaire_mq
                            gestionnaire_mq.ajouter_compte(clecert)
                        except ValueError:
                            comptes_mq_ok = False

                self._comptes_middleware_ok = True

            except Exception:
                self.__logger.exception("Erreur enregistrement comptes")

            self._comptes_mq_ok = comptes_mq_ok
    def preparer_fichiers(self):
        # Creer nouveau repertoire temporaire pour fichiers

        self.__temp_folder = tempfile.mkdtemp(dir='/tmp')
        os.chmod(self.__temp_folder, mode=0o700)

        chaine_hote = '\n'.join(self.__config_hebergement['chaine_hote'])
        fp, fichier_chaine_hote = tempfile.mkstemp(suffix='.pem',
                                                   dir=self.__temp_folder)
        os.write(fp, chaine_hote.encode('utf-8'))
        os.close(fp)

        chaine_cert = '\n'.join(self.__config_hebergement['chaine_cert'])
        fp, fichier_chaine_cert = tempfile.mkstemp(suffix='.pem',
                                                   dir=self.__temp_folder)
        os.write(fp, chaine_cert.encode('utf-8'))
        os.close(fp)

        cert_millegrille = self.__config_hebergement['millegrille']
        fp, fichier_cert_millegrille = tempfile.mkstemp(suffix='.pem',
                                                        dir=self.__temp_folder)
        os.write(fp, cert_millegrille.encode('utf-8'))
        os.close(fp)

        cle = self.__config_hebergement['cle']
        fp, fichier_cle = tempfile.mkstemp(suffix='.pem',
                                           dir=self.__temp_folder)
        os.write(fp, cle.encode('utf-8'))
        os.close(fp)

        # Batir chaine avec certificat XS pour connecter au middleware hote
        self.__parametres[Constantes.CONFIG_MQ_CERTFILE] = fichier_chaine_hote
        self.__parametres[Constantes.CONFIG_MQ_KEYFILE] = fichier_cle

        # Batir PKI pour la MilleGrille hebergee, avec son propre certificat de millegrille
        self.__parametres[Constantes.CONFIG_PKI_CERTFILE] = fichier_chaine_cert
        self.__parametres[Constantes.CONFIG_PKI_KEYFILE] = fichier_cle
        self.__parametres[
            Constantes.CONFIG_PKI_CERT_MILLEGRILLE] = fichier_cert_millegrille

        # Override de l'info intermediaire, garde les fichiers en memoire
        intermediaire_clecert = self.__config_hebergement.get(
            'intermediaire_clecert')
        if intermediaire_clecert:
            self.__parametres[
                Constantes.
                CONFIG_PKI_CLECERT_INTERMEDIAIRE] = intermediaire_clecert

        # Charger idmg a partir du certificat
        cert = self.__config_hebergement['chaine_hote'][0]
        clecert = EnveloppeCleCert()
        clecert.cert_from_pem_bytes(cert.encode('utf-8'))
        subject = clecert.formatter_subject()
        self.__parametres[Constantes.CONFIG_IDMG] = subject['organizationName']
    def traiter_message(self, ch, method, properties, body):
        print("Message recu, correlationId: %s" % properties.correlation_id)
        print(body)

        message_dict = json.loads(body)
        certificat_pem = message_dict.get('certificat')
        if certificat_pem is not None:
            cert = EnveloppeCleCert()
            cert.cert_from_pem_bytes(certificat_pem.encode('utf-8'))
            self.certificat_maitredescles = cert
            self.cert_maitredescles_recu.set()
        else:
            self.event_recu.set()
            print(json.dumps(message_dict, indent=4))
예제 #6
0
class EnvCert:
    def __init__(self):
        self._logger = logging.getLogger('%s.%s' %
                                         (__name__, self.__class__.__name__))

        self.dict_ca = dict()
        self.cle_millegrille = EnveloppeCleCert()  # EnveloppeCleCert
        self.ca_autorite = EnveloppeCleCert()  # EnveloppeCleCert
        self.renouvelleur = None

    def charger(self):
        with open('/home/mathieu/mgdev/certs/pki.ca.root.cert', 'rb') as f:
            ca_cert = f.read()
            self.ca_autorite.cert_from_pem_bytes(ca_cert)

        with open('/home/mathieu/mgdev/certs/pki.ca.passwords', 'r') as f:
            passwords = json.load(f)

        with open('/home/mathieu/mgdev/certs/pki.ca.millegrille.cert',
                  'rb') as f:
            mg_cert = f.read()
        with open('/home/mathieu/mgdev/certs/pki.ca.millegrille.key',
                  'rb') as f:
            mg_key = f.read()

        self.cle_millegrille.from_pem_bytes(
            mg_key, mg_cert, passwords['pki.ca.millegrille'].encode('utf-8'))

        self.charger_ca_chaine()
        self.renouvelleur = RenouvelleurCertificat('testMG', self.dict_ca,
                                                   self.cle_millegrille,
                                                   self.ca_autorite)

    def charger_ca_chaine(self):
        self.dict_ca = dict()

        ca_chain_file = '/home/mathieu/mgdev/certs/pki.ca.millegrille.fullchain'
        with open(ca_chain_file, 'r') as fichier:
            chaine = fichier.read()
            certs = chaine.split('-----END CERTIFICATE-----')
            for cert in certs[0:-1]:
                cert = '%s-----END CERTIFICATE-----\n' % cert
                self._logger.warning("Loading CA cert :\n%s" % cert)
                cert = cert.encode('utf-8')
                x509_cert = x509.load_pem_x509_certificate(
                    cert, backend=default_backend())
                skid = EnveloppeCleCert.get_subject_identifier(x509_cert)
                self.dict_ca[skid] = x509_cert
    def traiter_reception_certificat(self, pems):
        cert = pems[0]
        clecert = EnveloppeCleCert()
        clecert.cert_from_pem_bytes(cert.encode('utf-8'))
        subject_dict = clecert.formatter_subject()
        role = subject_dict['organizationalUnitName']

        # Trouver cle correspondante (date)
        label_role_cert = 'pki.%s.cert' % role
        label_role_key = 'pki.%s.key' % role
        info_role_key = self._service_monitor.gestionnaire_docker.trouver_secret(
            label_role_key)
        date_key = info_role_key['date']

        # Inserer la chaine de certificat
        chaine = '\n'.join(pems)
        self._service_monitor.gestionnaire_certificats.ajouter_config(
            label_role_cert, chaine, date_key)
예제 #8
0
    def traiter_message(self, ch, method, properties, body):
        print("Message recu, correlationId: %s" % properties.correlation_id)
        print(body)

        message_dict = json.loads(body)
        certificat_pem = message_dict.get('certificat')
        if certificat_pem is not None:
            cert = EnveloppeCleCert()
            try:
                cert.cert_from_pem_bytes(certificat_pem[0].encode('utf-8'))
                self.certificat_maitredescles = cert
                print("Recu certificat %s" % cert.fingerprint_b64)
            except:
                print("Erreur traitement certificat_pem")
            self.cert_maitredescles_recu.set()
        else:
            self.event_recu.set()
            if message_dict.get('certificats_pem'):
                for cert in message_dict.get('certificats_pem'):
                    print(cert)

        print(json.dumps(message_dict, indent=4))
    def _ajouter_compte_pem(self, cert_pem, commande):
        # Charger pem
        certificat = EnveloppeCleCert()
        certificat.cert_from_pem_bytes(cert_pem.encode('utf-8'))
        try:
            gestionnaire_mongo: GestionnaireComptesMongo = self._service_monitor.gestionnaire_mongo
            if gestionnaire_mongo:
                gestionnaire_mongo.creer_compte(certificat)
        except DuplicateKeyError:
            self.__logger.info("Compte mongo deja cree : " +
                               certificat.subject_rfc4514_string_mq())
        except KeyError as kerr:
            self.__logger.debug("Certificat ignore " + str(kerr))
        gestionnaire_comptes_mq: GestionnaireComptesMQ = self._service_monitor.gestionnaire_mq
        gestionnaire_comptes_mq.ajouter_compte(certificat)
        # Transmettre reponse d'ajout de compte, au besoin
        properties = commande.get('properties')
        if properties:
            reply_to = properties.reply_to
            correlation_id = properties.correlation_id

            if reply_to and correlation_id:
                self._service_monitor.generateur_transactions.transmettre_reponse(
                    {'resultat_ok': True}, reply_to, correlation_id)
예제 #10
0
class MessagesSample(BaseCallback):

    def __init__(self):
        super().__init__(contexte)
        self.contexte.message_dao.register_channel_listener(self)
        self.generateur = GenerateurTransaction(self.contexte)
        self.channel = None
        self.event_recu = Event()
        # self.thread_ioloop = Thread(target=self.run_ioloop)

        self.certificat_maitredescles = None
        self.cert_maitredescles_recu = Event()

        self.mot_de_passe = 'sjdpo-1824-JWAZ'

        # Charger cert MaitreDesCles pour pouvoir crypter contenu a transmettre
        with open('/home/mathieu/mgdev/certs/pki.maitrecles.cert', 'rb') as certificat_pem:
            self.certificat_courant_pem = certificat_pem.read()
            self.clecert = EnveloppeCleCert()
            self.clecert.set_chaine_str(self.certificat_courant_pem.decode('utf-8'))
            self.clecert.cert_from_pem_bytes(self.certificat_courant_pem)
            # cert = x509.load_pem_x509_certificate(
            #     certificat_courant_pem,
            #     backend=default_backend()
            # )
            self.certificat_courant = self.clecert.cert
            self.certificat_courant_pem = self.certificat_courant_pem.decode('utf8')

        with open('/home/mathieu/mgdev/certs/pki.millegrille.cert', 'rb') as certificat_pem:
            self.certificat_millegrille_pem = certificat_pem.read()
            self.clecert_millegrille = EnveloppeCleCert()
            self.clecert_millegrille.set_chaine_str(self.certificat_millegrille_pem.decode('utf-8'))
            self.clecert_millegrille.cert_from_pem_bytes(self.certificat_millegrille_pem)
            # cert = x509.load_pem_x509_certificate(
            #     certificat_courant_pem,
            #     backend=default_backend()
            # )
            self.cert_millegrille = self.clecert_millegrille.cert
            self.cert_millegrille_pem = self.certificat_millegrille_pem.decode('utf8')

    def on_channel_open(self, channel):
        # Enregistrer la reply-to queue
        self.channel = channel
        channel.queue_declare(durable=True, exclusive=True, callback=self.queue_open)

    def queue_open(self, queue):
        self.queue_name = queue.method.queue
        print("Queue: %s" % str(self.queue_name))

        self.channel.basic_consume(self.callbackAvecAck, queue=self.queue_name, no_ack=False)
        # self.event_recu.set()
        self.requete_cert_maitredescles()
        thread_executer = Thread(name="exec", target=self.executer)
        thread_executer.start()

    # def run_ioloop(self):
    #     self.contexte.message_dao.run_ioloop()

    def deconnecter(self):
        self.contexte.message_dao.deconnecter()

    def traiter_message(self, ch, method, properties, body):
        print("Message recu, correlationId: %s" % properties.correlation_id)
        print(body)

        message_dict = json.loads(body)
        certificat_pem = message_dict.get('certificat')
        if certificat_pem is not None:
            cert = EnveloppeCleCert()
            try:
                cert.cert_from_pem_bytes(certificat_pem[0].encode('utf-8'))
                self.certificat_maitredescles = cert
                print("Recu certificat %s" % cert.fingerprint_b64)
            except:
                print("Erreur traitement certificat_pem")
            self.cert_maitredescles_recu.set()
        else:
            self.event_recu.set()
            if message_dict.get('certificats_pem'):
                for cert in message_dict.get('certificats_pem'):
                    print(cert)

        print(json.dumps(message_dict, indent=4))

    def requete_cert_maitredescles(self):
        requete_cert_maitredescles = {
            # Constantes.TRANSACTION_MESSAGE_LIBELLE_EVENEMENT: ConstantesMaitreDesCles.REQUETE_CERT_MAITREDESCLES
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cert_maitredescles,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_CERT_MAITREDESCLES,
            'abcd-1234',
            self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def requete_trousseau_hebergement(self):
        requete = {
            'idmg': ['2aMvfBTqyfeQsMgSsYbtJuMeqUJ5TZV2iNiy2ES']
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete,
            'millegrilles.domaines.MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_TROUSSEAU_HEBERGEMENT,
            'abcd-1234',
            self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def requete_decryptage_cle_fuuid(self):
        requete_cert_maitredescles = {
            'fuuid': "ddb0d8f0-f7b4-11ea-89ec-13126005a8b0"
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cert_maitredescles,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_DECRYPTAGE_GROSFICHIER,
            'abcd-1234',
            self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def requete_cle_document(self):
        fingerprint = self.clecert.fingerprint

        requete_cert_maitredescles = {
            'fingerprint': fingerprint,
            'certificat': self.certificat_courant_pem,
            'domaine': 'MaitreDesComptes',
            'identificateurs_document': {
                "libelle": "proprietaire",
                "champ": "totp"
            }
        }

        print(requete_cert_maitredescles)

        self.generateur.transmettre_requete(
            requete_cert_maitredescles,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_DECRYPTAGE_DOCUMENT,
            'abcd-1234',
            self.queue_name
        )

    def requete_decryptage_cle_fuuid_avecfingerprint(self):
        requete_cert_maitredescles = {
            'fuuid': "b4ecca10-1c2b-11ea-904a-7b4d1a2d4432",
            'fingerprint': '74fd5742aec60dd37f99c75df423008a10149018'
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cert_maitredescles,
            'millegrilles.domaines.MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_DECRYPTAGE_GROSFICHIER,
            'abcd-1234',
            self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def requete_cle_racine(self):
        # Attendre le certificat de maitre des cles pour chiffrer la cle
        self.cert_maitredescles_recu.wait(5)

        mot_de_passe_chiffre, fingerprint = self.certificat_maitredescles.chiffrage_asymmetrique(self.mot_de_passe.encode('utf-8'))

        requete_cle_racine = {
            'fingerprint': '',
            'mot_de_passe_chiffre': str(b64encode(mot_de_passe_chiffre), 'utf-8'),
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cle_racine,
            'millegrilles.domaines.MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_CLE_RACINE,
            'abcd-1234',
            self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def requete_cle_backup(self):
        requete_cert_maitredescles = {
            'certificat': self.certificat_courant_pem,
            'domaine': 'Topologie',
            'identificateurs_document': {
                'transactions_nomfichier': 'Topologie_transactions_2020100323_3.protege.jsonl.xz.mgs1',
            },
            "cles": {
                "cGrSTYhEB19QGjiipURder6/IRc=Z": "aVA+CkgvSqP496IBrDbFa2SVP11f+BKq8oc3vJ2+8g4Ypo4u2c5ZnYvNPTFEnoAGcggGRDDQY2wkCNUGOjh2gTMnItUOdWJNq5vmjs0XNTOpiEkJpq7U5ZzPTssn2m6V1JbG0TmTu5/f24K1HAhae2lz95mlVdwufm+kQolwL5rzULOzGGV+mX8PGuaQkCHPdcletVj9IUwgkwrwYAgjYHt9qPjGUHO7Bcyiw1t7dWTUTbvt59uh41J53IB79hRqwx8BMeY7rMsWoY5ffVIWBorV//XxcsnEqiXgEOUJoC/LmQfI21FxPNV6mBIzs4hakvOgET5D2yGoAlYX4wJnxg==",
                "OaUo6vkTDQ26S9hbdFqeKYS3NyI=": "jYYDIgn4ShniCGkBgfJ1tIzOARRl1wBAps/SQwKBDMZnL+uH3MAhsieg6XW5vtdZyC/hh+hZ2q++2GGsgSUHAKbJlTn8YWS4WuRpUQssg4agpfCVPndkRoN1qf7QaQiN27HZJhMawqif0KDx7ZU0MsJoHF1l0X0E+frNuVg+WY+8DpHRxxc15CeHcLToSYn1V15WDiCTbrfvZ0zONEF2btie7eQ/B81prcTnUNrJe5xoHraEaQOcD4NOW1gCV0D8YfGcKZ2/by9zad3aJL5iUvGW4AeftewOaaKu4tM5bjdqSeICoeaI0fXwk7L/q2bBR2FOMM/P4so3JbabOaShHA=="
            },
            "iv": "16ldjBWXospiToJEKEIWGw==",
        }

        print(requete_cert_maitredescles)

        self.generateur.transmettre_requete(
            requete_cert_maitredescles,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_DECHIFFRAGE_BACKUP,
            'abcd-1234',
            self.queue_name
        )

    def requete_cle_backup_application(self):
        requete_cert_maitredescles = {
            'certificat': self.certificat_courant_pem,
            'identificateurs_document': {
                'archive_nomfichier': 'application_mariadb_redmine_client_archive_202010101721.tar.xz.mgs1'
            },
        }

        print(requete_cert_maitredescles)

        self.generateur.transmettre_requete(
            requete_cert_maitredescles,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_DECHIFFRAGE_BACKUP,
            'abcd-1234',
            self.queue_name
        )

    def commande_sauvegarder_cle(self):
        commande = {
            'domaine': 'Topologie',
            'identificateurs_document': {
                'transactions_nomfichier': 'Topologie_transactions_2020100325_3.protege.jsonl.xz.mgs1',
            },
            "cles": {
                # "cGrSTYhEB19QGjiipURder6/IRc=Z": "aVA+CkgvSqP496IBrDbFa2SVP11f+BKq8oc3vJ2+8g4Ypo4u2c5ZnYvNPTFEnoAGcggGRDDQY2wkCNUGOjh2gTMnItUOdWJNq5vmjs0XNTOpiEkJpq7U5ZzPTssn2m6V1JbG0TmTu5/f24K1HAhae2lz95mlVdwufm+kQolwL5rzULOzGGV+mX8PGuaQkCHPdcletVj9IUwgkwrwYAgjYHt9qPjGUHO7Bcyiw1t7dWTUTbvt59uh41J53IB79hRqwx8BMeY7rMsWoY5ffVIWBorV//XxcsnEqiXgEOUJoC/LmQfI21FxPNV6mBIzs4hakvOgET5D2yGoAlYX4wJnxg==",
                "OaUo6vkTDQ26S9hbdFqeKYS3NyI=": "jYYDIgn4ShniCGkBgfJ1tIzOARRl1wBAps/SQwKBDMZnL+uH3MAhsieg6XW5vtdZyC/hh+hZ2q++2GGsgSUHAKbJlTn8YWS4WuRpUQssg4agpfCVPndkRoN1qf7QaQiN27HZJhMawqif0KDx7ZU0MsJoHF1l0X0E+frNuVg+WY+8DpHRxxc15CeHcLToSYn1V15WDiCTbrfvZ0zONEF2btie7eQ/B81prcTnUNrJe5xoHraEaQOcD4NOW1gCV0D8YfGcKZ2/by9zad3aJL5iUvGW4AeftewOaaKu4tM5bjdqSeICoeaI0fXwk7L/q2bBR2FOMM/P4so3JbabOaShHA=="
            },
            "iv": "16ldjBWXospiToJEKEIWGw==",
            'domaine_action_transaction': ConstantesMaitreDesCles.TRANSACTION_NOUVELLE_CLE_BACKUPTRANSACTIONS,
        }

        self.generateur.transmettre_commande(
            commande,
            'commande.MaitreDesCles.%s' % ConstantesMaitreDesCles.COMMANDE_SAUVEGARDER_CLE,
            exchange=Constantes.SECURITE_SECURE,
            correlation_id='abcd-1234',
            reply_to=self.queue_name
        )

    def commande_signer_cle_backup(self):
        with open ('/home/mathieu/mgdev/certs/pki.connecteur.key', 'rb') as fichier:
            key_bytes = fichier.read()

        enveloppe = EnveloppeCleCert()
        enveloppe.key_from_pem_bytes(key_bytes, None)
        public_bytes = enveloppe.public_bytes

        requete_cle_racine = {
            'cle_publique': public_bytes.decode('utf-8'),
        }
        enveloppe_requete = self.generateur.transmettre_commande(
            requete_cle_racine,
            'commande.millegrilles.domaines.MaitreDesCles.%s' % ConstantesMaitreDesCles.COMMANDE_SIGNER_CLE_BACKUP,
            correlation_id='abcd-1234',
            reply_to=self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def commande_restaurer_backup_cle(self):
        with open ('/home/mathieu/mgdev/certs/pki.connecteur.key', 'rb') as fichier:
            key_bytes = fichier.read()

        clecert = EnveloppeCleCert()
        clecert.key_from_pem_bytes(key_bytes, None)
        clecert.password = self.mot_de_passe.encode('utf-8')
        key_chiffree_bytes = clecert.private_key_bytes

        self.cert_maitredescles_recu.wait(5)
        mot_de_passe_chiffre, fingerprint = self.certificat_maitredescles.chiffrage_asymmetrique(self.mot_de_passe.encode('utf-8'))

        enveloppe = EnveloppeCleCert()
        enveloppe.key_from_pem_bytes(key_bytes, None)

        requete_cle_racine = {
            'cle_privee': key_chiffree_bytes.decode('utf-8'),
            'mot_de_passe_chiffre': str(b64encode(mot_de_passe_chiffre), 'utf-8'),
            # 'fingerprint_base64': 'Ut/UQ5aKomoGzXB7mpUduPk4Xzg=',
        }
        enveloppe_requete = self.generateur.transmettre_commande(
            requete_cle_racine,
            'commande.millegrilles.domaines.MaitreDesCles.%s' % ConstantesMaitreDesCles.COMMANDE_RESTAURER_BACKUP_CLES,
            correlation_id='abcd-1234',
            reply_to=self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def commande_creer_cles_millegrille_hebergee(self):
        enveloppe_requete = self.generateur.transmettre_commande(
            dict(),
            'commande.millegrilles.domaines.MaitreDesCles.%s' % ConstantesMaitreDesCles.COMMANDE_CREER_CLES_MILLEGRILLE_HEBERGEE,
            correlation_id='abcd-1234',
            reply_to=self.queue_name,
            exchange=Constantes.DEFAUT_MQ_EXCHANGE_MIDDLEWARE
        )

        print("Envoi commande: %s" % enveloppe_requete)
        return enveloppe_requete

    def nouvelle_cle_grosfichiers(self):

        cle_secrete = 'Mon mot de passe secret'
        clecert_chiffrage = self.clecert_millegrille
        # cert_chiffrage = self.certificat_courant
        cert_chiffrage = clecert_chiffrage.cert
        fingerprint_b64 = clecert_chiffrage.fingerprint_b64
        cle_secrete_encryptee = cert_chiffrage.public_key().encrypt(
            cle_secrete.encode('utf8'),
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA256()),
                algorithm=hashes.SHA256(),
                label=None
            )
        )
        cle_secrete_encryptee_base64 = b64encode(cle_secrete_encryptee).decode('utf8')

        nouvelle_cle = {
            "domaine": "GrosFichiers",
            ConstantesMaitreDesCles.TRANSACTION_CHAMP_IDENTIFICATEURS_DOCUMENTS: {
                "fuuid": str(uuid4()),
            },
            "cles": {fingerprint_b64: cle_secrete_encryptee_base64},
            "iv": "gA8cRaiJE+8aN2c6/N1vTg==",
            "sujet": ConstantesMaitreDesCles.DOCUMENT_LIBVAL_CLES_GROSFICHIERS,
        }

        enveloppe_val = self.generateur.soumettre_transaction(
            nouvelle_cle,
            ConstantesMaitreDesCles.TRANSACTION_NOUVELLE_CLE_GROSFICHIER,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def nouvelle_cle_document(self):

        fingerprint_b64 = self.clecert.fingerprint_b64
        cle_secrete = 'Mon mot de passe secret'
        cle_secrete_encryptee = self.certificat_courant.public_key().encrypt(
            cle_secrete.encode('utf8'),
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA256()),
                algorithm=hashes.SHA256(),
                label=None
            )
        )
        cle_secrete_encryptee_mime64 = b64encode(cle_secrete_encryptee).decode('utf8')

        nouvelle_cle = {
            "domaine": "MaitreDesComptes",
            ConstantesMaitreDesCles.TRANSACTION_CHAMP_IDENTIFICATEURS_DOCUMENTS: {
                "_mg-libelle": "proprietaire",
                "champ": 'dummy' + str(uuid4()),
            },
            "cles": {fingerprint_b64: cle_secrete_encryptee_mime64},
            "iv": "gA8cRaiJE+8aN2c6/N1vTg==",
        }

        enveloppe_val = self.generateur.soumettre_transaction(
            nouvelle_cle,
            ConstantesMaitreDesCles.TRANSACTION_NOUVELLE_CLE_DOCUMENT,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def nouvelle_cle_backup(self):
        cle_secrete = 'Mon mot de passe secret'
        clecert_chiffrage = self.clecert_millegrille
        # cert_chiffrage = self.certificat_courant
        cert_chiffrage = clecert_chiffrage.cert
        fingerprint_b64 = clecert_chiffrage.fingerprint_b64
        cle_secrete_encryptee = cert_chiffrage.public_key().encrypt(
            cle_secrete.encode('utf8'),
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA256()),
                algorithm=hashes.SHA256(),
                label=None
            )
        )
        cle_secrete_encryptee_base64 = b64encode(cle_secrete_encryptee).decode('utf8')

        date_str = datetime.datetime.utcnow().strftime('%y%m%d%h%m')

        nouvelle_cle = {
            "domaine": "Topologie",
            ConstantesMaitreDesCles.TRANSACTION_CHAMP_IDENTIFICATEURS_DOCUMENTS: {
                "transactions_nomfichier": "Topologie_transactions_%s_3.protege.jsonl.xz.mgs1" % date_str,
            },
            "cles": {fingerprint_b64: cle_secrete_encryptee_base64},
            "iv": "gA8cRaiJE+8aN2c6/N1vTg==",
            "sujet": ConstantesMaitreDesCles.DOCUMENT_LIBVAL_CLES_BACKUPTRANSACTIONS,
        }

        enveloppe_val = self.generateur.soumettre_transaction(
            nouvelle_cle,
            ConstantesMaitreDesCles.TRANSACTION_NOUVELLE_CLE_BACKUPTRANSACTIONS,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def transaction_declasser_grosfichier(self):

        transaction = {
            'fuuid': '3830311b-145f-4ab2-850e-f4defdb70767'
        }

        enveloppe_val = self.generateur.soumettre_transaction(
            transaction,
            ConstantesMaitreDesCles.TRANSACTION_DECLASSER_CLE_GROSFICHIER,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def transaction_signer_certificat_navigateur(self):

        public_key_str = """
-----BEGIN CERTIFICATE REQUEST-----
MIICfTCCAWUCAQAwODESMBAGA1UEAxMJbm9tVXNhZ2VyMRMwEQYDVQQLEwpOYXZp
Z2F0ZXVyMQ0wCwYDVQQKEwRpZG1nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAwDlWi2KJsccrDJKHq8xLYjCqndu+Oh4GNsbRypPctuu+oU6PNkwwjSIN
xNuJret+ZVr2mw2MNbt9JYANriltYwvFWkF63NTIGXstaegNCkj6vqa4KdtXK7uu
NREtMLEhEu+ZWYcR2hWzVEN9GyIPwEgPNYQwUjjjLADUnaZ73t9Bk+fivgll0JbJ
reSw8DHqvdcmB28AnXltch6Wh34EGiYPbJqDm+NnCHHZ2EumbPRkN5/bqZTmpUDw
qqt+6cTcgAtdIuzYm3sPQt/Zf3EJwDT9dBxVrdbBnNFG4js3lauy49hog78zwwNP
/i3DZU3VDDCDeT4POKfEHXtwxTLF4QIDAQABoAAwDQYJKoZIhvcNAQENBQADggEB
AKBdiHJamlXfevloSBhehrf5g7lRbISGEsyY5HOXvVMLbip75QcGMcz8jnEJxYFk
8mDPuxlR3VOkyDiPGpLloN9hOgk50igwtRmFXcGCENbaJX2FZdho0yyx/yS03WXR
HXkje/v1Z6x1gitAxACbvvywo4qtIQoBSwP08D0JIGtD2GWPvzd1+PSgsdqQsmxz
EMkpLW0RZ2y1fCZyXbXPfAI4rnCL5Lb3CW7e4sbdH2XkcV4fBPEDGo03TE8648XV
6PCY9G7vw3iPiAhicMp1nI9bx+N/IapZvWmqR8vOURfFHYB1ilnli7S3MNXpDC9Q
BMz4ginADdtNs9ARr3DcwG4=
-----END CERTIFICATE REQUEST-----
        """

        commande = {
            'est_proprietaire': True,
            'csr': public_key_str,
        }

        enveloppe_val = self.generateur.transmettre_commande(
            commande,
            'commande.MaitreDesCles.' + ConstantesMaitreDesCles.COMMANDE_SIGNER_NAVIGATEUR_CSR,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def transaction_demande_inscription_tierce(self):
        transaction = {
            'idmg': '33KRMhqcWCKvMHyY5xymMCUEbT53Kg1NqUb9AU6'
        }
        domaine = ConstantesMaitreDesCles.TRANSACTION_GENERER_DEMANDE_INSCRIPTION

        enveloppe_val = self.generateur.soumettre_transaction(
            transaction,
            domaine,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def transaction_signature_inscription_tierce(self):
        with open('/home/mathieu/PycharmProjects/MilleGrilles.consignation.python/test/messages/demande_connexion.json') as fichier:
            transaction = json.load(fichier)
        domaine = ConstantesMaitreDesCles.TRANSACTION_GENERER_CERTIFICAT_POUR_TIERS

        enveloppe_val = self.generateur.soumettre_transaction(
            transaction,
            domaine,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def transaction_supprimer_trousseau_hebergement(self):
        domaine = ConstantesMaitreDesCles.TRANSACTION_HEBERGEMENT_SUPPRIMER

        enveloppe_val = self.generateur.soumettre_transaction(
            {'idmg': '3M87pZxVVWbT1dVLeRarQnge1mvADTs4trG7Caa'},
            domaine,
            reply_to=self.queue_name,
            correlation_id='efgh'
        )

        print("Sent: %s" % enveloppe_val)
        return enveloppe_val

    def commande_signer_csr(self):
        clecert = EnveloppeCleCert()
        clecert.generer_private_key(generer_password=True, keysize=4096)

        public_key = clecert.private_key.public_key()
        builder = x509.CertificateSigningRequestBuilder()
        name = x509.Name([
            x509.NameAttribute(x509.name.NameOID.ORGANIZATION_NAME, '3aeGLdmMbA1BrmRYwpPgNAZKH2WGWmSedBjKSxw'),
            x509.NameAttribute(x509.name.NameOID.ORGANIZATIONAL_UNIT_NAME, 'domaines'),
            x509.NameAttribute(x509.name.NameOID.COMMON_NAME, 'test')
        ])
        builder = builder.subject_name(name)
        request = builder.sign(
            clecert.private_key, hashes.SHA256(), default_backend()
        )
        request_pem = request.public_bytes(primitives.serialization.Encoding.PEM)

        commande = {
            'liste_csr': [request_pem.decode('utf-8')],
        }
        enveloppe_requete = self.generateur.transmettre_commande(
            commande,
            'commande.millegrilles.domaines.MaitreDesCles.%s' % ConstantesMaitreDesCles.COMMANDE_SIGNER_CSR,
            correlation_id='abcd-1234',
            reply_to=self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def commande_signer_csr_noeud_prive(self):
        clecert = EnveloppeCleCert()
        clecert.generer_private_key(keysize=2048)

        public_key = clecert.private_key.public_key()
        builder = x509.CertificateSigningRequestBuilder()
        name = x509.Name([
            # x509.NameAttribute(x509.name.NameOID.ORGANIZATION_NAME, '3aeGLdmMbA1BrmRYwpPgNAZKH2WGWmSedBjKSxw'),
            x509.NameAttribute(x509.name.NameOID.ORGANIZATIONAL_UNIT_NAME, 'intermediaire'),
            x509.NameAttribute(x509.name.NameOID.COMMON_NAME, str(uuid4()))
        ])
        builder = builder.subject_name(name)
        request = builder.sign(
            clecert.private_key, hashes.SHA256(), default_backend()
        )
        request_pem = request.public_bytes(primitives.serialization.Encoding.PEM)

        commande = {
            'liste_csr': [request_pem.decode('utf-8')],
            'role': 'prive'
        }
        enveloppe_requete = self.generateur.transmettre_commande(
            commande,
            'commande.MaitreDesCles.%s' % ConstantesMaitreDesCles.COMMANDE_SIGNER_CSR,
            correlation_id='abcd-1234',
            reply_to=self.queue_name
        )

        print("Envoi requete: %s" % enveloppe_requete)
        return enveloppe_requete

    def requete_cles_non_dechiffrables(self):
        requete_cle_racine = {
            'taille': 2
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cle_racine,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_CLES_NON_DECHIFFRABLES,
            'abcd-1234',
            self.queue_name
        )
        return enveloppe_requete

    def requete_cles_non_dechiffrables_verifmaitrecles(self):
        self.cert_maitredescles_recu.wait(5)  # Attendre reception cert maitredescles

        # Prendre le fingerprint du cert maitre des cles - devrait retourner 0 cles non chiffrees
        fingerprint_maitrecles = self.certificat_maitredescles.fingerprint_b64

        requete_cle_racine = {
            'taille': 2,
            'fingerprints_actifs': [fingerprint_maitrecles],
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cle_racine,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_CLES_NON_DECHIFFRABLES,
            'abcd-1234',
            self.queue_name
        )
        return enveloppe_requete

    def requete_cles_non_dechiffrables_verifcledummy(self):
        self.cert_maitredescles_recu.wait(5)  # Attendre reception cert maitredescles

        # Prendre le fingerprint du cert maitre des cles - devrait retourner 0 cles non chiffrees
        fingerprint_maitrecles = self.certificat_maitredescles.fingerprint_b64

        requete_cle_racine = {
            'taille': 2,
            'fingerprints_actifs': ['DUMMY'],
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cle_racine,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_CLES_NON_DECHIFFRABLES,
            'abcd-1234',
            self.queue_name
        )
        return enveloppe_requete

    def requete_compter_cles_non_dechiffrables_verifcledummy(self):
        self.cert_maitredescles_recu.wait(5)  # Attendre reception cert maitredescles

        # Prendre le fingerprint du cert maitre des cles - devrait retourner 0 cles non chiffrees
        fingerprint_maitrecles = self.certificat_maitredescles.fingerprint_b64

        requete_cle_racine = {
            # 'fingerprints_actifs': ['DUMMY'],
        }
        enveloppe_requete = self.generateur.transmettre_requete(
            requete_cle_racine,
            'MaitreDesCles.%s' % ConstantesMaitreDesCles.REQUETE_COMPTER_CLES_NON_DECHIFFRABLES,
            'abcd-1234',
            self.queue_name
        )
        return enveloppe_requete

    def executer(self):
        # self.event_recu.wait(5)
        # self.event_recu.clear()

        # enveloppe = self.requete_cert_maitredescles()
        # self.requete_trousseau_hebergement()

        # for i in range(0, 2):
        #     self.nouvelle_cle_grosfichiers()
        #     self.nouvelle_cle_document()
        #     self.nouvelle_cle_backup()

        # enveloppe = self.transaction_declasser_grosfichier()
        # enveloppe = self.transaction_signer_certificat_navigateur()
        # enveloppe = self.requete_decryptage_cle_fuuid()
        # enveloppe = self.requete_decryptage_cle_fuuid_avecfingerprint()
        # self.transaction_demande_inscription_tierce()
        # self.transaction_signature_inscription_tierce()
        # self.transaction_supprimer_trousseau_hebergement()
        # self.requete_cle_document()

        # self.requete_cle_racine()
        # self.commande_signer_cle_backup()
        # self.commande_restaurer_backup_cle()
        # self.commande_creer_cles_millegrille_hebergee()
        # self.commande_signer_csr()
        # self.commande_signer_csr_noeud_prive()

        # self.requete_cles_non_dechiffrables()
        # self.requete_cles_non_dechiffrables_verifmaitrecles()
        # self.requete_cles_non_dechiffrables_verifcledummy()
        self.requete_compter_cles_non_dechiffrables_verifcledummy()
    def __init__(self):
        self.idmg = 'JPtGcNcFSkfSdw49YsDpQHKxqTHMitpbPZW17a2JC54T'

        self.chaine_pem = [
            """
-----BEGIN CERTIFICATE-----
MIIDfTCCAmWgAwIBAgIJYGYjdUZ4mWUAMA0GCSqGSIb3DQEBDQUAMCcxDzANBgNV
BAMTBlJhY2luZTEUMBIGA1UEChMLTWlsbGVHcmlsbGUwHhcNMjAwODE0MTMzNTAw
WhcNMjMwODE3MTMzNTAwWjB9MS0wKwYDVQQDEyRmMDNhYTQyNi04Mjc5LTQyMDYt
YWYyYy0wNjA5N2IyMmY2MTYxFTATBgNVBAsTDE5vZXVkUHJvdGVnZTE1MDMGA1UE
ChMsSlB0R2NOY0ZTa2ZTZHc0OVlzRHBRSEt4cVRITWl0cGJQWlcxN2EySkM1NFQw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDbi6hszfap+SF2vPoJx/1t
1k4AZNUWpxpD7zTVw9gjl8re2hHjDne99w4r3bPOyDUjh6A4hWC77bQ/yTa/UQPO
LVHdU3DcbjshxCYv/TebwikEct4EoYjxQZgt6ov4rhhyyEqPK1UFvHsNkjZWH1qM
ocoHA2IeeDZqhi9mRGeKsZ7vPOYI/9RN3lQMEYUqIQI0Tx+rVEXIGT7g6WSuKwN2
O9Q1Ktqb7z6w491UkPTxukM2DkZCglSRXEnfw8Psc2c6yN1TKHgsGzf299d3zkF2
c0ZtI8rqQ9tebX1zZCyYOLZrZXWP73kr89Qnp0b3d78vB2uEHW1ioPhNstRcIQPf
AgMBAAGjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQQwHQYDVR0OBBYEFAAvK7SYudlb
e3wdxyjBcEQz/6uFMB8GA1UdIwQYMBaAFLBXLIVvPd0v2/PRpsXEhxv3SitkMA0G
CSqGSIb3DQEBDQUAA4IBAQBNR6bWpOLfEL/ERZsuCzX04YchFy7gNuCSphzhFpGx
V3gApShKPKja94V2FmcvbHqmiCnU2SK5/q7YB9X7RElYJRktl50DIUw3puKfaYS0
965K4ZIyuhA452G+OdgrvJzE29E6op19z1SAKvzqhk3e/SFrEmrsKisGAA2HGL8Q
E+cGvtDYc/b4YE0YmK4b6+PyGSF+2HDr9D9lEsavn5tJaWLjBiGp2BTKagShOpNX
VPk6OgYoAWz9RULV/jMSVrC/fm8cogmWT0TJ2NFR305iI9bv7zHKtQ7p/MjxNQN2
wh0FLaiqSb+Dd+LZiMlWm7tF2Z5vuqC1EMdbjTYVBU23
-----END CERTIFICATE-----
            """, """
-----BEGIN CERTIFICATE-----
MIIDKDCCAhCgAwIBAgIKAol2BgZkgwIwADANBgkqhkiG9w0BAQ0FADAnMQ8wDQYD
VQQDEwZSYWNpbmUxFDASBgNVBAoTC01pbGxlR3JpbGxlMB4XDTIwMDgwNTE3MTky
NVoXDTIxMDgwNTE3MTkyNVowJzEPMA0GA1UEAxMGUmFjaW5lMRQwEgYDVQQKEwtN
aWxsZUdyaWxsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKHD5H6t
svTC1rkQ0jDq51/5ht72LroSubFIM6SGd4PeofKGk2LCLce8IGC9zz08lXa8WMkr
I9yAxf3P0WK2UEZFXsvGJ0EvBXyewZDEX+Lfp12zyBuKGRK5rjUYFCdbEiO+qVCq
Pvqb4VU4ffbAFvuWRulSfvD5udC2PY1xRxNQytAnbs3jRJSzcFiGDk50bwG5JD/i
TZwtnm6OQYcxnckNZgzz8G34wZEAwz1f5a941nV+Tnnod+7t6kdkLFenMUtVPrd8
hVwHzitBUkBP8OsTvS/AGvyMrz/1XT1+MxwShq8o8S2fp7YGdR8eeb1uUfJLzLu8
rGB5vMOoiiGOkNkCAwEAAaNWMFQwEgYDVR0TAQH/BAgwBgEB/wIBBTAdBgNVHQ4E
FgQUsFcshW893S/b89GmxcSHG/dKK2QwHwYDVR0jBBgwFoAUsFcshW893S/b89Gm
xcSHG/dKK2QwDQYJKoZIhvcNAQENBQADggEBAKD7W6UKrnPpIXzrFVXs0EOYZi1u
IUEOBA0yoJyUQuLcyb+nNCUf9FPjyh1xGrtHLgMwNuIj3EqB3AvzZs+t9kyJ+aun
RaGxOSd6ytQzRW4LcpUNeBs0oCkTftlXGZRBU/ZgaMNQvk7b1R5MaBOtBnUkDsRA
/+bdPl2gpOCUFdNK53805Z8cgV0QXQKNPgM06EVT1URWsy9Z3O6BA57Xq3kEZOtJ
oJMuyy7g7/iRiAfXsys7ZoDgPET8SL3R0UbvUTXXI5jM2+jchBqucI6YSEjJmgBQ
TNQc8kgLqRI+hI8Ri62/ZsEeUmyn5VOrq+oPOsFc1wBS8ErdxXLln77cEEk=
-----END CERTIFICATE-----
            """
        ]
        self.cle_pem = """
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA24uobM32qfkhdrz6Ccf9bdZOAGTVFqcaQ+801cPYI5fK3toR
4w53vfcOK92zzsg1I4egOIVgu+20P8k2v1EDzi1R3VNw3G47IcQmL/03m8IpBHLe
BKGI8UGYLeqL+K4YcshKjytVBbx7DZI2Vh9ajKHKBwNiHng2aoYvZkRnirGe7zzm
CP/UTd5UDBGFKiECNE8fq1RFyBk+4OlkrisDdjvUNSram+8+sOPdVJD08bpDNg5G
QoJUkVxJ38PD7HNnOsjdUyh4LBs39vfXd85BdnNGbSPK6kPbXm19c2QsmDi2a2V1
j+95K/PUJ6dG93e/LwdrhB1tYqD4TbLUXCED3wIDAQABAoIBAQCPCvN10MxB+rw+
7OnMra0Ff3fa8deUptOKJ7S5Ap00s5XOlS7KTYbfErT9B7o7pF5bA+b0bJKWX03t
sWAmTta34vdPySnjtT55xZ9L7SPqLBslduIJCmZ7Kk3IvOTt5iCvyKgrmAQRdLiI
IxecDVml/1PuNdocGB78UOlZLIB58AM9m3zHE0I4UDBL1Uo7q+GagklisDKkYjzU
Blxr8lkvisJniPHkOJj4DRGpXG9bJAoTTwya6tISpMNQRtOPu4lN7CzkK9CXvM/a
l8Eu9rYVzg7m3Q0jdvwiNZWEIFMLuDEi0ijWcEPurH/wV0LMIVQFe1LA7swg8BjC
PjiRExDhAoGBAPrXchrGJUAt1mx2nb9a4OJ2YRlpBkN0pPB0rsBg1AUf4raTTcwb
5S2sDqkn0zwVA3aWhWFkzTJgBlC6Ykn1xsa2VSGP1JchxAl6EgKiWxSHNkaiiBM2
Fo8jjRscMb8T0sjgDEjlmvrERDGSrJtmEPQjGTcDlsOZDlFphls3eQZ1AoGBAOAP
dE2hxX3G8zSD+/90a7bbhfhqfOJta7a6Sv6NwshR9bnI1kLqjJbg32jY15HSvdGL
Em1U5duI/oy+lZCQBBSaGSnPmhFRPqa1o8nPYh5Zz2aLroTWIjiIweGx4hJQ8F3a
wSjG3HQNLZ3y0ppH+FvH2gLuZh1CPsd95lXMjR6DAoGAKh8VhRNy2+UWlZ4RfTmI
e96/DWJKb/ddXxdo5Nsdn0KsclYoATdJ87Jpv9P1L6ijrT03ZpRjtKrVRKcXrC2+
VE3326voWfyMi77Y2WJkAv11isTuLrOtdBnXLw8790cf5SViSrdrn+JnRR/JJkss
W6KtMETFA1FnSxp6OkUFaKUCf37oQfe2qSWUiiw0lYcbaecob7lEl3eogln9Kn0D
zk+oHIYeOz2rm/XZaLD6IR93PgxxuP40F/1Amu0dBZnb+HOy1I3aCGnGmrXSK/Mi
g3CtbcunUjHrF3bt/uLW3jWBoqOGQ+HUwQj6bdwIrUC1gvZ5PAJtBWmNHAHiTZRL
R6MCgYEA6Tr6PMVlKw60m05y1S5zv6FGuUjZrepdKc1gw1U+LG3YztoykF6g+cK4
a3CFRrd9Rbz08P9l2kXM8YWaZVxH38MbOcoVhP7Al3N4ntV+y+dKW3y8IdGYcFRv
PZgCLivK4AyUNpjfeOyrmio+GqiRKt6aVCA4Ht5Az8c5j1atiZM=
-----END RSA PRIVATE KEY-----
        """

        clecert_millegrille = EnveloppeCleCert()
        clecert_millegrille.cert_from_pem_bytes(
            self.chaine_pem[1].encode('utf-8'))

        clecert_inter = EnveloppeCleCert()
        clecert_inter.from_pem_bytes(self.cle_pem.encode('utf-8'),
                                     self.chaine_pem[0].encode('utf-8'))

        dict_ca = {
            clecert_millegrille.fingerprint: clecert_millegrille,
            clecert_inter.fingerprint: clecert_inter
        }

        self.renouvelleur = RenouvelleurCertificat(self.idmg, dict_ca,
                                                   clecert_inter,
                                                   clecert_millegrille)
class GestionnaireCertificats:

    MONITOR_CERT_PATH = 'monitor_cert_path'
    MONITOR_KEY_FILE = 'monitor_key_file'

    def __init__(self, docker_client: docker.DockerClient, service_monitor,
                 **kwargs):
        self._docker = docker_client
        self._service_monitor = service_monitor
        self._date: str = cast(str, None)
        self.__logger = logging.getLogger(__name__ + '.' +
                                          self.__class__.__name__)

        self.certificats = dict()
        self._clecert_millegrille: EnveloppeCleCert = cast(
            EnveloppeCleCert, None)
        self._clecert_intermediaire: EnveloppeCleCert = cast(
            EnveloppeCleCert, None)
        self.clecert_monitor: EnveloppeCleCert = cast(EnveloppeCleCert, None)

        self.secret_path = kwargs.get('secrets')
        self._mode_insecure = kwargs.get('insecure') or False

        self.maj_date()

        self._nodename = self._docker.info()['Name']
        self.idmg: str = cast(str, None)

        self.__cles_memorisees = dict()

        cert_pem = kwargs.get('millegrille_cert_pem')
        if cert_pem:
            self._clecert_millegrille = EnveloppeCleCert()
            self._clecert_millegrille.cert_from_pem_bytes(
                cert_pem.encode('utf-8'))
        else:
            # Tenter de charger le certificat a partir de millegrille.configuration
            try:
                millegrille_pem_config = self._docker.configs.get(
                    'pki.millegrille.cert')
                json_millegrille = b64decode(
                    millegrille_pem_config.attrs['Spec']['Data'])
                self._clecert_millegrille = EnveloppeCleCert()
                self._clecert_millegrille.cert_from_pem_bytes(json_millegrille)

            except docker.errors.NotFound:
                self.__logger.info(
                    "millegrille.configuration abstente : Nouvelle MilleGrille, noeud principal."
                )

        # Calculer le IDMG a partir du certificat de MilleGrille
        if self._clecert_millegrille:
            self.idmg = self._clecert_millegrille.idmg
            self.__logger.info("Gestionnaire certificat, idmg : %s" %
                               self.idmg)

    def maj_date(self):
        self._date = str(datetime.datetime.utcnow().strftime(
            MonitorConstantes.DOCKER_LABEL_TIME))

    def __preparer_label(self, name, date: str = None):
        if date is None:
            date = self._date
        params = {
            'name': name,
            'date': date,
        }
        name_docker = '%(name)s.%(date)s' % params
        return name_docker[0:64]  # Max 64 chars pour name docker

    def ajouter_config(self, name: str, data: bytes, date: str = None):
        name_tronque = self.__preparer_label(name, date)
        self._docker.configs.create(name=name_tronque,
                                    data=data,
                                    labels={'idmg': self.idmg})

    def ajouter_secret(self, name: str, data: bytes):
        name_tronque = self.__preparer_label(name)
        self._docker.secrets.create(name=name_tronque,
                                    data=data,
                                    labels={'idmg': self.idmg})
        return name_tronque

    def __generer_private_key(self,
                              generer_password=False,
                              keysize=2048,
                              public_exponent=65537):
        info_cle = dict()
        clecert = EnveloppeCleCert()
        clecert.generer_private_key(generer_password=generer_password)
        if generer_password:
            # info_cle['password'] = b64encode(secrets.token_bytes(16))
            info_cle['password'] = clecert.password

        # info_cle['cle'] = asymmetric.rsa.generate_private_key(
        #     public_exponent=public_exponent,
        #     key_size=keysize,
        #     backend=default_backend()
        # )

        info_cle['pem'] = clecert.private_key_bytes
        info_cle['clecert'] = clecert
        info_cle['cle'] = clecert.private_key

        return info_cle

    def generer_csr(self,
                    type_cle: str = None,
                    insecure=False,
                    inserer_cle=True,
                    generer_password=False):
        # Generer cle privee
        info_cle = self.__generer_private_key(
            generer_password=generer_password)

        # Generer CSR
        # node_name = self._docker.info()['Name']
        noeud_id = self._service_monitor.noeud_id
        builder = x509.CertificateSigningRequestBuilder()

        name_list = list()
        if type_cle:
            name_list.append(
                x509.NameAttribute(x509.name.NameOID.ORGANIZATIONAL_UNIT_NAME,
                                   type_cle))
        name_list.append(
            x509.NameAttribute(x509.name.NameOID.COMMON_NAME, noeud_id))

        if self.idmg:
            name_list.append(
                x509.NameAttribute(x509.name.NameOID.ORGANIZATION_NAME,
                                   self.idmg))
        name = x509.Name(name_list)
        builder = builder.subject_name(name)

        request = builder.sign(info_cle['cle'], hashes.SHA256(),
                               default_backend())
        request_pem = request.public_bytes(
            primitives.serialization.Encoding.PEM)
        info_cle['request'] = request_pem
        info_cle['cle_pem'] = info_cle['pem']

        self.__logger.debug("Request CSR : %s" % request_pem)

        cle_pem = info_cle['cle_pem']
        cle_passwd = info_cle.get('password')

        if inserer_cle:
            label_key_inter = 'pki.%s.key' % type_cle
            self.ajouter_secret(label_key_inter, data=cle_pem)
            if cle_passwd:
                label_passwd_inter = 'pki.%s.passwd' % type_cle
                self.ajouter_secret(label_passwd_inter, data=cle_passwd)
            label_csr_inter = 'pki.%s.csr' % type_cle
            self.ajouter_config(label_csr_inter, data=request_pem)

        if insecure:  # Mode insecure
            try:
                os.mkdir(self.secret_path, 0o755)
            except FileExistsError:
                pass

            key_path = path.join(self.secret_path, 'pki.%s.key.pem' % type_cle)
            try:
                with open(key_path, 'xb') as fichier:
                    fichier.write(cle_pem)
            except FileExistsError:
                pass

            if cle_passwd:
                passwd_path = path.join(self.secret_path,
                                        'pki.%s.passwd.txt' % type_cle)
                try:
                    with open(passwd_path, 'xb') as fichier:
                        fichier.write(cle_passwd)
                except FileExistsError:
                    pass

        return info_cle

    def _charger_certificat_docker(self, nom_certificat) -> bytes:
        """
        Extrait un certificat de la config docker vers un fichier temporaire.
        Conserve le nom du fichier dans self.__certificats.
        :param nom_certificat:
        :return: Contenu du certificat en PEM
        """
        cert = MonitorConstantes.trouver_config(nom_certificat,
                                                self._docker)['config']
        cert_pem = b64decode(cert.attrs['Spec']['Data'])
        fp, fichier_cert = tempfile.mkstemp(dir='/tmp')
        try:
            os.write(fp, cert_pem)
            self.certificats[nom_certificat] = fichier_cert
        finally:
            os.close(fp)

        return cert_pem

    def recevoir_certificat(self, message: dict):
        self.__logger.info("Certificat recu :\n%s" %
                           json.dumps(message, indent=2))
        chaines = message.get('chaines') or message['resultats']['chaines']

        for info_chaine in chaines['chaines']:
            pems = info_chaine['pems']

            # Identifier le role du certificat (OU)
            self.traiter_reception_certificat(pems)

        self._service_monitor.trigger_event_attente()

    def traiter_reception_certificat(self, pems):
        cert = pems[0]
        clecert = EnveloppeCleCert()
        clecert.cert_from_pem_bytes(cert.encode('utf-8'))
        subject_dict = clecert.formatter_subject()
        role = subject_dict['organizationalUnitName']

        # Trouver cle correspondante (date)
        label_role_cert = 'pki.%s.cert' % role
        label_role_key = 'pki.%s.key' % role
        info_role_key = self._service_monitor.gestionnaire_docker.trouver_secret(
            label_role_key)
        date_key = info_role_key['date']

        # Inserer la chaine de certificat
        chaine = '\n'.join(pems)
        self._service_monitor.gestionnaire_certificats.ajouter_config(
            label_role_cert, chaine, date_key)

    @property
    def idmg_tronque(self):
        return self.idmg[0:12]

    def memoriser_cle(self, role, cle_pem):
        self.__cles_memorisees[role] = cle_pem

    def _recuperer_cle_memorisee(self, role):
        cle = self.__cles_memorisees[role]
        del self.__cles_memorisees[role]
        return cle

    def set_clecert_millegrille(self, clecert_millegrille):
        self._clecert_millegrille = clecert_millegrille

    def set_clecert_intermediaire(self, clecert_intermediaire):
        self._clecert_intermediaire = clecert_intermediaire

    def charger_certificats(self):
        raise NotImplementedError()

    def generer_nouveau_idmg(self):
        raise NotImplementedError()

    def generer_clecert_module(self,
                               role: str,
                               node_name: str,
                               nomcle: str = None,
                               liste_dns: list = None) -> EnveloppeCleCert:
        raise GenerationCertificatNonSupporteeException()