/* * Create a new SSL_SESSION and duplicate the contents of |src| into it. If * ticket == 0 then no ticket information is duplicated, otherwise it is. */ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) { SSL_SESSION *dest; dest = OPENSSL_malloc(sizeof(*src)); if (dest == NULL) { goto err; } memcpy(dest, src, sizeof(*dest)); /* * Set the various pointers to NULL so that we can call SSL_SESSION_free in * the case of an error whilst halfway through constructing dest */ #ifndef OPENSSL_NO_PSK dest->psk_identity_hint = NULL; dest->psk_identity = NULL; #endif dest->ciphers = NULL; dest->ext.hostname = NULL; #ifndef OPENSSL_NO_EC dest->ext.ecpointformats = NULL; dest->ext.supportedgroups = NULL; #endif dest->ext.tick = NULL; #ifndef OPENSSL_NO_SRP dest->srp_username = NULL; #endif memset(&dest->ex_data, 0, sizeof(dest->ex_data)); /* We deliberately don't copy the prev and next pointers */ dest->prev = NULL; dest->next = NULL; dest->references = 1; dest->lock = CRYPTO_THREAD_lock_new(); if (dest->lock == NULL) goto err; if (src->peer != NULL) X509_up_ref(src->peer); if (src->peer_chain != NULL) { dest->peer_chain = X509_chain_up_ref(src->peer_chain); if (dest->peer_chain == NULL) goto err; } #ifndef OPENSSL_NO_PSK if (src->psk_identity_hint) { dest->psk_identity_hint = OPENSSL_strdup(src->psk_identity_hint); if (dest->psk_identity_hint == NULL) { goto err; } } if (src->psk_identity) { dest->psk_identity = OPENSSL_strdup(src->psk_identity); if (dest->psk_identity == NULL) { goto err; } } #endif if (src->ciphers != NULL) { dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); if (dest->ciphers == NULL) goto err; } if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, &dest->ex_data, &src->ex_data)) { goto err; } if (src->ext.hostname) { dest->ext.hostname = OPENSSL_strdup(src->ext.hostname); if (dest->ext.hostname == NULL) { goto err; } } #ifndef OPENSSL_NO_EC if (src->ext.ecpointformats) { dest->ext.ecpointformats = OPENSSL_memdup(src->ext.ecpointformats, src->ext.ecpointformats_len); if (dest->ext.ecpointformats == NULL) goto err; } if (src->ext.supportedgroups) { dest->ext.supportedgroups = OPENSSL_memdup(src->ext.supportedgroups, src->ext.supportedgroups_len); if (dest->ext.supportedgroups == NULL) goto err; } #endif if (ticket != 0) { dest->ext.tick = OPENSSL_memdup(src->ext.tick, src->ext.ticklen); if (dest->ext.tick == NULL) goto err; } else { dest->ext.tick_lifetime_hint = 0; dest->ext.ticklen = 0; } #ifndef OPENSSL_NO_SRP if (src->srp_username) { dest->srp_username = OPENSSL_strdup(src->srp_username); if (dest->srp_username == NULL) { goto err; } } #endif return dest; err: SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); SSL_SESSION_free(dest); return NULL; }
MONO_API int mono_btls_ssl_ctx_set_ciphers (MonoBtlsSslCtx *ctx, int count, const uint16_t *data, int allow_unsupported) { STACK_OF(SSL_CIPHER) *ciphers = NULL; struct ssl_cipher_preference_list_st *pref_list = NULL; uint8_t *in_group_flags = NULL; int i; ciphers = sk_SSL_CIPHER_new_null (); if (!ciphers) goto err; for (i = 0; i < count; i++) { const SSL_CIPHER *cipher = SSL_get_cipher_by_value (data [i]); if (!cipher) { debug_printf (ctx, "mono_btls_ssl_ctx_set_ciphers(): unknown cipher %02x", data [i]); if (!allow_unsupported) goto err; continue; } if (!sk_SSL_CIPHER_push (ciphers, cipher)) goto err; } pref_list = OPENSSL_malloc (sizeof (struct ssl_cipher_preference_list_st)); if (!pref_list) goto err; memset (pref_list, 0, sizeof (struct ssl_cipher_preference_list_st)); pref_list->ciphers = sk_SSL_CIPHER_dup (ciphers); if (!pref_list->ciphers) goto err; pref_list->in_group_flags = OPENSSL_malloc (sk_SSL_CIPHER_num (ciphers)); if (!pref_list->in_group_flags) goto err; if (ctx->ctx->cipher_list) ssl_cipher_preference_list_free (ctx->ctx->cipher_list); if (ctx->ctx->cipher_list_by_id) sk_SSL_CIPHER_free (ctx->ctx->cipher_list_by_id); if (ctx->ctx->cipher_list_tls10) { ssl_cipher_preference_list_free (ctx->ctx->cipher_list_tls10); ctx->ctx->cipher_list_tls10 = NULL; } if (ctx->ctx->cipher_list_tls11) { ssl_cipher_preference_list_free (ctx->ctx->cipher_list_tls11); ctx->ctx->cipher_list_tls11 = NULL; } ctx->ctx->cipher_list = pref_list; ctx->ctx->cipher_list_by_id = ciphers; return (int)sk_SSL_CIPHER_num (ciphers); err: sk_SSL_CIPHER_free (ciphers); OPENSSL_free (pref_list); OPENSSL_free (in_group_flags); return 0; }