Bonjour,
Je commence à écrire un petit bout de code où je souhaiterai identifier les clients grâce à leur certificat (cette partie là j'y arrive correctement).
Quand le serveur ne connait pas le certificat du client (le certificat n'est pas présent dans le fichier ca du serveur), j'aimerai qu'il le stocke. Et avec un autre script je pourrais lister les certificats en attente de validation pour l'ajouter ensuite comme valide.
J'ai grandement épuré mon programme ci-dessous en y mettant le minimum :
Code du serveur :
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #!/usr/bin/env python import sys, os, socket, ssl, OpenSSL, shutil port = 10023 ssl_dir = os.path.join(os.path.dirname(sys.argv[0]), 'ssl') ssl_ca = os.path.join(ssl_dir, 'ca.crt') ssl_crt = os.path.join(ssl_dir, 'server.crt') ssl_key = os.path.join(ssl_dir, 'server.key') bindsocket = socket.socket() bindsocket.bind(('', port)) bindsocket.listen(5) while True: newsocket, fromaddr = bindsocket.accept() ssl_stream = ssl.wrap_socket(newsocket, server_side=True, cert_reqs=ssl.CERT_REQUIRED, ca_certs=ssl_ca, certfile=ssl_crt, keyfile=ssl_key) crt_der = ssl_stream.getpeercert(binary_form=True) crt_pem = ssl.DER_cert_to_PEM_cert(crt_der) client_crt = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, crt_pem) print(dict(client_crt.get_subject().get_components())['CN']) print(crt_pem) ssl_stream.shutdown(socket.SHUT_RDWR) ssl_stream.close()
Le client et le serveur possède un fichier ca, un fichier key et un fichier crt.
Le fichier ca du serveur contient le crt du serveur et celui du client.
Le fichier ca du client contient le crt du serveur.
J'ai un script python pour le client mais on peut également utiliser le client openssl :
Dans ce cas tout fonctionne nickel la connexion est acceptée par le serveur. Par contre si dans le fichier ca du serveur j'enlève le certificat du client alors la connexion ne s'effectue pas (ce qui est le comportement désiré).
Code : Sélectionner tout - Visualiser dans une fenêtre à part openssl s_client -port 10023 -host 127.0.0.1 -CAfile ssl/ca.crt -cert ssl/client.crt -key ssl/client.key
Mais je voudrais quand même pouvoir récupérer le certificat du client avec de rejeter la connexion... Et ça je n'y arrive pas car ssl.wrap_socket génère une erreur et je ne peux donc pas appeler ensuite ssl_stream.getpeercer qui permet de récupérer le certificat du client
J'ai l'erreur suivante de mon client écrit en python (l'erreur est claire mais ça ne me dit pas comment récupérer le certificat du client) :
Erreur en utilisant la commande openssl :
Code : Sélectionner tout - Visualiser dans une fenêtre à part ('Error : %s', SSLError(1, '_ssl.c:504: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca'))
erreur sur le serveur (script écrit au dssus) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 ... verify return:1 140568475055784:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1256:SSL alert number 48 140568475055784:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177: ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part ssl.SSLError: [Errno 1] _ssl.c:504: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
Quelqu'un peut-il me venir en aide ? (je ne suis pas développeur donc un peut d'aide serait la bienvenue)
Partager