OpenSSL s client-cert: prouver qu'un certificat client a été envoyé au serveur

Background

je suis bloqué dans une correspondance de pointage avec un fournisseur de services avec une API protégée par le serveur SSL et le client certificats.

  • j'ai généré un CSR, j'ai obtenu un certificat d'une autorité de certification publique (GoDaddy dans ce cas) et j'ai fourni le certificat et la chaîne de L'autorité de certification au fournisseur de services.
  • ils auraient chargé le certificat de L'AC et de mon client dans leur passerelle.
  • je suis travailler avec les tests de niveau les plus basiques en utilisant openssl s_client -connect ... -cert ... -key ...
  • le fournisseur me dit que leurs journaux suggèrent que mes requêtes ne comprennent pas du tout de certificat client SSL.
  • étrangement, l'émetteur D'AC approprié pour mon certificat apparaît dans la liste des "noms D'AC acceptables pour le certificat du client" fournie pendant la poignée de main SSL.
  • Pour référence, un certificat auto-signé, j'ai créé et fourni pour le test fonctionne pour correctement.

Un échantillon (échec) demande

[shell ~]$ openssl s_client -connect host:443 -cert cert_and_key.pem -key cert_and_key.pem -state -quiet
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 **SNIP**
verify return:1
depth=1 **SNIP**
verify return:1
depth=0 **SNIP**
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:unknown CA
SSL_connect:failed in SSLv3 read finished A
140011313276744:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1197:SSL alert number 48
140011313276744:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:

ma lecture du SSL3 alert read:fatal:unknown CA erreur est que le serveur ne reconnaît pas l'émetteur du certificat, je suis (en fait) de fournir. Cependant, le fournisseur "m'assure" que les certificats de L'AC sont chargés correctement et je n'ai pas été en mesure de les convaincre du contraire.

Question

donc, en mettant les autres étapes de dépannage (extensive) de côté, ce que j'aimerais vraiment savoir c'est:

Est-il une sortie disponible à partir de openssl s_client cela montre de façon concluante qu'un certificat client n'était pas seulement demandé par le serveur, mais en fait était transmises au serveur pendant la poignée de main SSL?

j'ai expérimenté le -state,-msg,-debug et -trace options, mais n'ont pas le fond nécessaire pour interpréter la sortie.

la réponse D'EJP suggère que le résultat de l'échantillon que j'ai fourni est la preuve avec l' write client certificate A, mais cette sortie apparaît indépendamment du fait que le -cert options a été utilisé sur la ligne de commande ou pas, donc il n'est pas indicative d'un certificat a été envoi.

27
demandé sur beporter 2013-06-20 04:35:55

2 réponses

pour vérifier qu'un certificat client est envoyé au serveur, vous devez analyser la sortie de la combinaison de -state et -debug drapeaux.

tout d'abord comme ligne de base, essayez de lancer

$ openssl s_client -connect host:443 -state -debug

Vous aurez une tonne de sortie, mais les lignes qui nous intéresse ressembler à ceci:

SSL_connect:SSLv3 read server done A
write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
0000 - 16 03 01 00 07 0b 00 00-03                        .........
000c - <SPACES/NULS>
SSL_connect:SSLv3 write client certificate A

What is happening here:

  • -state pavillon est responsable de l'affichage de la fin de la précédente section:

    SSL_connect:SSLv3 read server done A  
    

    Ceci est seulement important pour vous aider à trouver votre place dans la sortie.

  • Puis -debug flag affiche les octets bruts envoyés à l'étape suivante:

    write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
    0000 - 16 03 01 00 07 0b 00 00-03                        .........
    000c - <SPACES/NULS>
    
  • Enfin, le -state flag rapporte une fois de plus le résultat de l'étape que -debug simplement fait l'écho:

    SSL_connect:SSLv3 write client certificate A
    

Donc, en d'autres mots: s_client fin de la lecture des données envoyées par le serveur, et envoyées 12 octets sur le serveur (ce que je suppose)"aucun certificat du client" message.


si vous répétez le test, mais cette fois inclure le -cert et -key indicateurs comme ceci:

$ openssl s_client -connect host:443 \
   -cert cert_and_key.pem \
   -key cert_and_key.pem  \
   -state -debug

votre sortie entre les "serveur de lecture fait" et "écrire certificat du client" la ligne sera beaucoup plus longue, représentant la forme binaire de votre certificat client:

SSL_connect:SSLv3 read server done A
write to 0x7bd970 [0x86d890] (1576 bytes => 1576 (0x628))
0000 - 16 03 01 06 23 0b 00 06-1f 00 06 1c 00 06 19 31   ....#..........1
(*SNIP*)
0620 - 95 ca 5e f4 2f 6c 43 11-                          ..^%/lC.
SSL_connect:SSLv3 write client certificate A

le 1576 bytes est une excellente indication à elle seule que le cert a été transmis, mais en plus de cela, la colonne de droite montrera des parties du certificat qui sont lisibles par l'homme: vous devriez être en mesure de reconnaître les chaînes CN et émetteur de votre cert là-dedans.

57
répondu beporter 2018-05-17 13:57:09

je sais que c'est une vieille question, mais elle ne semble pas encore avoir une réponse. J'ai dupliqué cette situation, mais j'écris l'application du serveur, donc j'ai pu établir ce qui se passe du côté du serveur aussi bien. Le client envoie le certificat lorsque le serveur le demande et s'il a une référence à un vrai certificat dans la ligne de commande s_client. Mon application serveur est configurée pour demander un certificat client et échouer si un n'est pas présenté. Voici la ligne de commande je question:

Yourhostname here -vvvvvvvvvv s_client -connect <hostname>:443 -cert client.pem -key cckey.pem -CAfile rootcert.pem -cipher ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH -tls1 -state

quand j'oublie le client " - cert.pem" fait partie de la commande la poignée de main échoue du côté du serveur et la commande s_client échoue avec une erreur signalée. Je reçois toujours le rapport "No client certificate CA names sent" mais je pense que cela a été répondu ici ci-dessus.

la réponse courte est alors que le serveur détermine si un certificat sera envoyé par le client dans des conditions normales d'exploitation (s_client n'est pas normal) et l'échec est dû au fait que le serveur ne reconnaît pas L'AC dans le certificat présenté. Je ne suis pas familier avec de nombreuses situations dans lesquelles l'authentification bidirectionnelle est faite bien qu'elle soit requise pour mon projet.

vous envoyez clairement un certificat. Le serveur le rejette clairement.

l'information manquante ici est la façon exacte dont les certs ont été créés et la façon dont le fournisseur a chargé le cert, mais tout est probablement terminé maintenant.

6
répondu JSAnderson 2014-11-04 14:26:31