J’ai un processus Linux qui doit agir en tant que serveur SSL (accepter et entretenir des connexions à partir d’autres clients) mais doit également – dans le même processus – lancer des sessions client avec d’autres serveurs SSL.
J’ai l’intention de créer deux descripteurs SSL_CTX distincts en utilisant deux appels de fonction SSL_CTX_new (), l’un appelé avec des méthodes serveur et l’autre avec des méthodes client. Cette double utilisation d’OpenSSL au sein d’un processus unique est-elle prise en charge? J’espère qu’OpenSSL utilise le handle SSL_CTX – et ne s’appuie pas sur des variables locales globales ou statiques – pour toutes les informations de contexte dont il peut avoir besoin pour créer et entretenir de nouvelles sessions. Est-ce une bonne hypothèse?
De mon expérience: vous pouvez créer librement plusieurs contextes à condition d’initialiser correctement la bibliothèque OpenSSL. J’ai utilisé deux contextes différents dans la même application sans aucun problème après avoir configuré les verrous de thread comme décrit dans la page de manuel OpenSSL: http://www.openssl.org/docs/crypto/threads.html . Si votre application n’utilise pas de threads, vous n’aurez pas besoin d’une telle configuration.
OpenSSL autorise-t-il plusieurs SSL_CTX par processus, un SSL_CTX utilisé pour les sessions de serveur …
Oui, et c’est assez courant. C’est commun lors de l’utilisation de l’indication du nom de serveur. Dans le cas de SNI, vous avez un SSL_CTX
par défaut, puis un SSL_CTX
pour chaque serveur. Vous retournez ensuite le SSL_CTX
par défaut ou un SSL_CTX
spécialisé dans le rappel SNI si le client a inclus l’extension de nom de serveur dans son ClientHello
.
SSL_CTX
sont référencés comptés par la bibliothèque, ils ne sont donc pas réellement libérés tant que le compte de référence n’a pas SSL_CTX_free
0 dans l’un des appels SSL_CTX_free
.
Si vous êtes intéressé, voici quelques questions sur SNI:
Le premier vous fournit même le code de rappel. GetServerContext
renvoie un nouveau contexte (ou existant) basé sur le nom du serveur:
/* Need a new certificatee for this domain */ SSL_CTX* ctx = GetServerContext(servername); if(ctx == NULL) handleFailure(); ... /* Set new context */ SSL_CTX* v = SSL_set_SSL_CTX(ssl, ctx);
OpenSSL autorise-t-il plusieurs SSL_CTX par processus, … d’autres SSL_CTX pour les sessions client?
Oui, mais vous ne l’utilisez généralement pas. Le client ne change généralement pas son SSL_CTX
comme le fait le serveur.
Dans le cas où un client se connecte à plusieurs serveurs, vous définissez généralement vos parameters de canal avec SSL_CTX_set_options
et les utilisez pour chaque connexion à chaque serveur (même différents). Les parameters seraient des choses comme les protocoles (TLS 1.1, TLS 1.2), les suites de chiffrement (suppression des suites de chiffrement anonymes) et la compression. Voir la discussion ci-dessous concernant le client SSL / TLS pour plus de détails.
Le client doit définir le nom d’hôte du serveur, mais cela se fait sur SSL*
utilisant SSL_set_tlsext_host_name
, et non sur SSL_CTX*
.
Ou, si vous utilisez BIO
, cela ressemblerait à ceci. Notez que le BIO
enveloppe efficacement un SSL*
, de sorte que vous ne modifiez pas le SSL_CTX*
:
BIO* web = BIO_new_ssl_connect(ctx); if(web == NULL) handleFailure(); res = BIO_set_conn_hostname(web, HOST_NAME ":" HOST_PORT); if(res != 1) handleFailure();
… l’une invoquée avec les méthodes du serveur et l’autre avec les méthodes du client
Pas besoin. La seule différence entre eux (comme SSLv23_client_method
et SSLv23_server_method
), est un couple de pointeurs de fonctions pour des fonctions telles que connect
et accept
dans des structures inédites. Les clients appellent connect
et les serveurs appellent accept
.
Au lieu de cela, utilisez simplement la SSLv23_method
générique et tout ira bien. Vous devez toujours régler le contexte avec SSL_CTX_set_options
car le contexte par défaut fourni par SSL_CTX_new
inclut les protocoles et les chiffrements faibles / blessés / cassés.
La page wiki d’OpenSSL SSL / TLS Client vous montre comment régler un object SSL_CTX
. Il effectue les opérations suivantes et peut être utilisé par les clients et les serveurs:
L’utilisation d’une liste de chiffrement personnalisée telle que "HIGH: ... : !SRP:!PSK"
supprime de nombreux chiffrements faibles / blessés et supprime une série de suites de chiffrement qui ne sont probablement pas sockets en charge sur le serveur (le client n’a donc aucune raison les annoncer). SRP est le mot de passe sécurisé de Thomas Wu et PSK est la clé pré-partagée. IANA réserve 87 suites de chiffrement basées sur celles-ci, ce qui permet d’économiser près de 180 octets dans ClientHello
.
Cette double utilisation d’OpenSSL au sein d’un processus unique est-elle prise en charge?
Oui.
J’espère que OpenSSL utilise le handle SSL_CTX – et ne repose pas sur des variables locales globales ou statiques
Eh bien, vous n’avez pas de chance là-bas. Il y a beaucoup de globaux, certains sont alloués dynamicment et certains ne sont pas libérés.
Et si vous travaillez en Java ou en C #, ils fuient chaque fois que l’object partagé est chargé / déchargé. Ainsi, votre programme Java ou C # accumule de plus en plus de mémoire au fil du temps. Les développeurs OpenSSL ne se sentent pas dignes de leur temps. Voir, par exemple, Petite fuite de mémoire sur un serveur multithread dans la liste de diffusion OpenSSL.