2010-07-21 5 views
3

Je suis en train de réécrire certaines technologies existantes qui utilisaient jadis les bibliothèques de RSA Security dans OpenSSL, mais je commence à rencontrer quelques problèmes. Actuellement, tout le code de vérification de certificat semble fonctionner sans accroc, jusqu'à ce que j'appelle SSL_connect().SSL_connect() produit un échec de vérification de certificat

Avant, l'appel à SSL_connect() produisait SSL_ERROR_WANT_READ.

Une réponse à ce problème sur un autre forum m'a suggéré que SSL_connect() devrait être appelé jusqu'à ce qu'il cesse de produire des erreurs SSL_ERROR_WANT_READ. Unforunately, cela ne produit quelque chose de plus déroutant:

error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed 

même si SSL_CTX_load_verify_locations() réussit. Quelqu'un a-t-il une idée de la raison pour laquelle une erreur de vérification ne serait pas enregistrée avec les méthodes de certificat et attende que SSL_connect() soit déclenché?

Répondre

4

Habituellement, cette erreur signifie que le certificat de serveur que votre client a reçu en réponse à SSL_connect() n'a pas pu être vérifié.

Cela peut se produire pour différentes raisons:

  • Si le certificat de serveur est auto-signé, vous devrez autoriser que sur votre SSL_CONTEXT.
  • Si le certificat du serveur a été signé par une autorité de certification ne figurant pas dans la liste des certificats de confiance
  • Si le certificat du serveur est pas encore valide ou non valide plus

En fait, vous devez définir un rappel pour la vérification du certificat et le faire accepter tout certificat, de sorte que vous pouvez vous concentrer sur la partie connexion. Une fois que cela fonctionne, modifiez simplement votre rappel ou vérifiez que vos certificats sont valides.

À tout moment vous obtenez un échec, vous pouvez appeler une fonction SSL_get_error() qui vous indiquera pourquoi le certificat a été rejeté.

(Malheureusement, je ne peux pas accéder à ma base de code en ce moment, donc je ne peux pas donner des exemples concrets)


Voici quelques exemples de code de ma classe wrapper SSL Socket, adapté pour vous :

// ctx is a SSL_CONTEXT 
// internalCertificateVerificationCallback is a callback static method (or function) 
ctx->setVerify(SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, internalCertificateVerificationCallback); 

Voici la définition de internalCertificateVerificationCallback:

int SecureSocket::internalCertificateVerificationCallback(int preverify_ok, X509_STORE_CTX* x509_ctx) 
{ 
    //preverify_ok contains 1 if the pre-verification succeeded, 0 otherwise. 

    return 1; // This accepts every certificate 
} 
+0

Merci pour la réponse, mais je pense que je suis encore un peu confus. Comment puis-je "accepter un certificat"? J'ai essayé d'utiliser SSL_VERIFY_NONE dans mon appel de méthode SSL_CTX_set_verify(), mais je ne pense pas que ce soit la route que je veux prendre. De plus, comment attacher un rappel à l'appel SSL_CTX_load_verify_locations()? Je pensais qu'il n'acceptait pas une fonction de rappel. er, au moins en C++ ~ –

+0

@ kelly.dunn: J'ai ajouté quelques exemples de code qui peuvent probablement aider. Je ne comprends pas votre remarque sur les fonctions de rappel et 'C++': Vous pouvez écrire et utiliser les callbacks 'C' dans' C++ 'sans aucun problème. Veillez juste à spécifier une fonction, ou une méthode ** static **, pas une méthode (leurs signatures diffèrent, en raison du paramètre caché 'this'). – ereOn

+0

Oh j'étais juste confus quant à l'endroit où vous disiez d'attacher la fonction de rappel ~ J'ai oublié que SSL_set_verify() accepte un paramètre final. Merci beaucoup! Je l'implémenterai sous peu et je verrai si cela aide: D –

Questions connexes