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 :
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
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é).
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) :
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 en utilisant la commande openssl :
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:
...
erreur sur le serveur (script écrit au dssus) :
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 )