Example #1
0
/*
 * 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;
}
Example #2
0
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;
}