Frage

Ich habe eine funktionierende Anwendung, die eine SSL-Verbindung zu einem Server. Der Server verwendet ein selbst signiertes Zertifikat und den Client lädt ihm eine Zertifizierungsstelle Kette zu sagen, dass der Server an Vertrauen in Ordnung ist. Ich habe das mit Code wie folgt auf dem Client:

SSL_METHOD* method = TLSv1_client_method();
_ctx = SSL_CTX_new(method);
if ( SSL_CTX_load_verify_locations(_ctx, "ca-all.crt", NULL) != 1 )
{
    return false;
}
_ssl = SSL_new(_ctx);
int val = SSL_set_fd(_ssl, _socket->GetFD());
if ( val != SSL_SUCCESS )
{
    int err = SSL_get_error(_ssl, val);
    return false;
}
val = SSL_connect(_ssl);

Und auf dem Server:

  if ( SSL_CTX_use_certificate_chain_file( g_ctx, "ca-chain1.crt" ) <= 0 ) {
    return 1;
  }
  ppem_file = getenv( "PEM_FILE" );
  if ( ppem_file == NULL ) {
    ppem_file = pem_file;
  }
  if ( SSL_CTX_use_certificate_file( g_ctx, ppem_file,
                                     SSL_FILETYPE_PEM ) <= 0 ) {
    return 1;
  }
  if ( SSL_CTX_use_PrivateKey_file( g_ctx, ppem_file,
                                    SSL_FILETYPE_PEM ) <= 0 ) {
    return 2;
  }

Ich versuche, diesen Code zu ändern, so dass der Server auch das Peer-Zertifikat des Clients überprüft (selbstsignierten, elben Emittenten wie der Server) und ein wenig Mühe hat. Ich habe nicht gut „konzeptionellen Überblick“ Dokumentation überall zu finden, und das scheint eine typische Hürde mit den OpenSSL-Bibliotheken zu sein.

Auf dem Client hat ich dies nach dem SSL_CTX_load_verify_locations () Aufruf:

if ( SSL_CTX_use_certificate_file(_ctx, "generic_client.pem", SSL_FILETYPE_PEM ) != 1 )
{
    return false;
}

Auf dem Server habe ich diese nach dem SSL_CTX_use_PrivateKey_file () Aufruf:

  STACK_OF(X509_NAME) *list;
  list = SSL_load_client_CA_file( "ca_chain2.crt" );
  if( list == NULL ) {
    return 4;
  }
  SSL_CTX_set_client_CA_list( g_ctx, list );
  SSL_CTX_set_verify( g_ctx, SSL_VERIFY_PEER, NULL );

Die Verbindung schlägt fehl, da das Zertifikat nicht validiert. Der Kunde scheint das Zertifikat in Ordnung zu laden und wenn ich die SSL_CTX_set_verify Zeile aus kommentieren, der Client eine Verbindung ohne Probleme (weil ihr Zertifikat wird nie überprüft).

Es scheint, dass der Server glaubt nicht, dass die Zertifizierungsstelle Kette des Kunden ist gut. Was soll ich hier fehlt?

Von der Kommandozeile ich laufen kann: OpenSSL überprüfen -CAfile ca-chain2.crt generic_client.pem Und es geht, so dass ich die richtigen Zertifikatsdaten zur Verfügung haben, muss ich es nur irgendwie falsch verwendet werden.

War es hilfreich?

Lösung

Auf dem Server müssen Sie auch SSL_CTX_load_verify_locations() nennen. Diese Funktion teilt dem Server, was die Verwendung von Zertifikaten für Zertifikatsüberprüfung; die SSL_CTX_set_client_CA_list() Funktion setzt die Liste der erlaubten CAs, die an den Client in dem Handshake gesendet werden. Beide sind erforderlich.

(Sie müssen auch einen SSL_CTX_use_PrivateKey_file() Anruf auf dem Client nach dem use_certificate_file Anruf, aber ich denke, dir tut, dass es nur weggelassen).

Andere Tipps

SSL_CTX_set_client_CA_list setzt die CA Liste. Ein CA-Zertifikat per Definition verschieden ist von einem Benutzerzertifikat (zum Beispiel hat sie die CA-Bit gesetzt). Daher empfehle ich erstellen Sie eine richtige CA (deren CA-Zertifikat ist selbstsigniert) und die Verwendung, dass sowohl der Client als auch den Server-Zertifikat zu unterzeichnen. Ich gehe davon aus, dass OpenSSL wird nicht erwartet, dass der Kunde tatsächlich das CA-Zertifikat für die Kommunikation auch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top