2016-02-29 2 views
0

J'ai développé une application client IOCP qui envoie un message au serveur. Maintenant, je souhaite ajouter le support SSL pour connecter l'application serveur SSL avec OpenSSL.Ajout du support OpenSSL dans l'application client IOCP

J'ai initialiser SSL à l'aide

/* Load encryption & hashing algorithms for the SSL program */ 
SSL_library_init(); 

/* Load the error strings for SSL & CRYPTO APIs */ 
SSL_load_error_strings(); 

/* Create an SSL_METHOD structure (choose an SSL/TLS protocol version) */ 
meth = TLSv1_2_method(); 

/* Create an SSL_CTX structure */ 
ctx = SSL_CTX_new(meth); 

if(ctx == NULL) 
    return false; 

SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr); 

SSL_CTX_set_verify_depth(ctx,1); 

Après l'initialisation, nous créons de threads de travail normales IOCP, prises IOCP puis connectez à la prise SSL Server en tant que

  /* An SSL structure is created */ 
      ssl = SSL_new (ctx); 

      RETURN_NULL(ssl); 

      /* Assign the socket into the SSL structure (SSL and socket without BIO) */ 
      SSL_set_fd(ssl, Socket); 

      /* Perform SSL Handshake on the SSL client */ 
      int  err; 
      err = SSL_connect(ssl); 
      if (err<1) 
      { 
       err=SSL_get_error(ssl,err); 
       printf("SSL error #%d in accept,program terminated\n",err); 
      } 

      RETURN_SSL(err); 

      /* Informational output (optional) */ 
      printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); 

      /* Get the server's certificate (optional) */ 
      X509   *server_cert; 
      server_cert = SSL_get_peer_certificate (ssl);  

      if (server_cert != NULL) 
      { 
       printf ("Server certificate:\n"); 

       char *str; 
       str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0); 
       //RETURN_NULL(str); 
       printf ("\t subject: %s\n", str); 
       free (str); 

       str = X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0); 
       //RETURN_NULL(str); 
       printf ("\t issuer: %s\n", str); 
       free(str); 

       X509_free (server_cert); 

      } 
      else 
       printf("The SSL server does not have certificate.\n"); 

SSL Connexion au serveur jusqu'à ce fonctionne correctement et Je suis en mesure de récupérer les détails du certificat du serveur correctement. Maintenant, je veux envoyer un message au serveur SSL via SSL Socket et recevoir une réponse du serveur. Mais dans notre application client IOCP, nous utilisons WSASend et WSARecv pour l'échange de données. Comment puis-je faire cela sur un serveur SSL en utilisant la fonction SSL_write/SSL_read?

Veuillez me guider pour ce faire.


Modifier le 01 Mars 2016

J'ai essayé d'utiliser des paires BIO pour socket SSL après "err = SSL_CONNECT (ssl);" comme

bioIn = BIO_new_socket(this->Socket, BIO_NOCLOSE); 
bioOut = BIO_new_socket(this->Socket, BIO_NOCLOSE); 
SSL_set_bio(ssl, bioIn, bioIn); 

Ensuite, essayez d'envoyer la longueur du message au serveur comme

int err = SSL_write(ssl, PerIOHandle->Buffer, PerIOHandle->BufferLength); 

Une fois ci-dessus exécution d'une instruction, serveur lit la longueur du message approprié et attend un message réel du client. Mais lorsque j'essaie d'envoyer un message en utilisant la même instruction ci-dessus, la fonction SSL_read du serveur échoue avec -1 code retour.

S'il vous plaît, aidez-moi à ajouter un support SSL complet.

Répondre

0

Comme vous l'avez découvert, vous devez utiliser l'abstraction OpenSSL IO, le BIO. Cela vous permet de séparer le code OpenSSL du socket. Vous venez de pousser les données à travers les BIO et ensuite prendre les données qu'ils vous donnent et émettre vos propres écritures sur les sockets async/IOCP.

J'ai écrit à ce sujet pour le Dr. Dobbs Journal en 2002, voir here. L'article se concentre sur l'utilisation d'OpenSSL avec les sockets async de MFC mais les idées sont les mêmes si vous souhaitez l'utiliser avec le code IOCP.

L'article est livré avec un code complet et fonctionnel que vous pouvez probablement utiliser comme base pour votre code IOCP. Vous branchez la paire BIO dès le début et n'utilisez pas du tout SSL_connect().

+0

Merci pour la réponse, Je passe en revue votre exemple de code, mais à partir de là, je ne comprends pas exactement comment l'initialisation SSL et les paires BIO sont utilisées. Pourriez-vous s'il vous plaît me guider comment je peux creuser votre code pour mieux le comprendre? Comme vous l'avez dit, n'utilisez pas "SSL_connect()", quelle en est la raison? J'ai essayé de ne pas l'utiliser, mais la connexion SSL au serveur n'est pas terminée. –

+0

Je viens de tester le code d'exemple. Vous devriez pouvoir mettre à jour le projet VC6 vers n'importe quel nouveau compilateur en l'ouvrant simplement avec le nouvel IDE. Ensuite, suivez les instructions de l'article pour ajuster le projet pour votre chemin SSL Open. Le code se construit ensuite. Exécutez-le et remplacez le serveur de destination par www.google.com car le serveur d'exemple Microsoft n'existe plus.Cliquez sur connecter, le code se connectera à google et fera la négociation SSL. Cliquez sur SendRequest et vous enverrez une requête HTTP. Vous devriez pouvoir tracer en définissant des points d'arrêt autour du code SSL ouvert qui vous intéresse. –