bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainenstatic HASH_TABLE(struct ssl_iostream_context_cache *,
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen struct ssl_iostream_context *) ssl_iostream_contexts;
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainenstatic unsigned int
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainenssl_iostream_context_cache_hash(const struct ssl_iostream_context_cache *cache)
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen unsigned int n, i, g, h = 0;
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen const char *const cert[] = { cache->set.cert.cert, cache->set.alt_cert.cert };
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen /* checking for different certs is typically good enough,
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen and it should be enough to check only the first few bytes (after the
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen "BEGIN CERTIFICATE" line). */
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen for (i = 0; i < 64 && cert[n][i] != '\0'; i++) {
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen if ((g = h & 0xf0000000UL) != 0) {
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen h = h ^ (g >> 24);
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainenssl_iostream_context_cache_cmp(const struct ssl_iostream_context_cache *c1,
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen return ssl_iostream_settings_equals(&c1->set, &c2->set) ? 0 : -1;
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainenssl_iostream_context_cache_get(const struct ssl_iostream_settings *set,
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen const char **error_r)
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen pool_alloconly_create(MEMPOOL_GROWING"ssl iostream context cache", 1024);
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen ssl_iostream_settings_drop_stream_only(&lookup.set);
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen ctx = hash_table_lookup(ssl_iostream_contexts, &lookup);
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen /* add to cache */
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen if (ssl_iostream_context_init_server(&lookup.set, &ctx, error_r) < 0)
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen if (ssl_iostream_context_init_client(&lookup.set, &ctx, error_r) < 0)
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen ssl_iostream_settings_init_from(ssl_iostream_contexts_pool,
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen hash_table_insert(ssl_iostream_contexts, cache, ctx);
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainenint ssl_iostream_client_context_cache_get(const struct ssl_iostream_settings *set,
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen const char **error_r)
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen return ssl_iostream_context_cache_get(set, FALSE, ctx_r, error_r);
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainenint ssl_iostream_server_context_cache_get(const struct ssl_iostream_settings *set,
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen const char **error_r)
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen return ssl_iostream_context_cache_get(set, TRUE, ctx_r, error_r);
86cc86047bee861a6f7fc3a9cfdb8600b984732eTimo Sirainen iter = hash_table_iterate_init(ssl_iostream_contexts);