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)
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))
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)
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)
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()