The problem you are describing is not solved yet completely. It largely condenses to Software auditability its distribution method, and protocol design.
You've already mentioned that the encryption needs to be done client-side. This is offered by lots of today's software already. Companies selling a client-side encryption protocol can't easily build their revenue model of selling the customer's data without this becoming public.
Even with a well designed protocol, it's possible the client doesn't follow it. In order to verify that the client does what the protocol says, the software needs to be audited by the public. This works most easily when the software is accessible in a format humans can undestand best: in source code. A verifiable software doesn't have to be open source, or at have its source code publicly available like truecrypt, but its a very strong point.
When the source code has been audited, the trusting trust problem arises: somebody needs to verify that the binary matches the source code. This can be solved by Deterministic builds, which is a new and currently very unstable method.
It has been used to ensure integrity for software considered important like the Tor Browser Bundle, or various Bitcoin clients. Debian has started an effort to make its whole application repository built deterministically (last link).
The amount of software that needs to be verified can be reduced by following a model similar to DRM: one part of the software is closed-source and not trusted, and another part doing the encryption is open source, and audited. End-to-End (repository, blog article) in combination with the gmail js client, or the addon published by Mega are a good examples for this.
Those approaches make it hard to hide that everybody's encryption is bypassed, but its still easy to hide that one's encryption is bypassed.
The worst method is HTTP/js: every time you visit the page, you basically download the software a new time. The server can give you a malicious content, and the next time you visit the page all traces are deleted. The best way to secure a web page is the DRM-like method I've described above.
HTTP downloads also have lots of problems. You are trusting every download provider that they don't serve you malicious software. Android has an "untrusted sources" checkbox which is disabled by default to save you from installing such software. I'm also including PPAs into this, however I don't know of any malicious content served over PPAs. Better is you only trust one entity, through package repositories.
Even package repositories give you an entity you have to trust: the repo maintainer, be it google, debian, or someone else. The software may be auditable, and use a good protocol, but the particular version your maintainer gave you has a backdoor.
The problem is similar to the certificate distribution problem — ensuring that all people see the same — so similar solutions apply. I could think of a gossip protocol like the one outlined in the End-to-End wiki, or even more decentralized ones like Namecoin, however you can argue how decentralized Namecoin is, when hashing gets centralized.
To protect you from the usual bad guy, trusting a trustworthy repo maintainer is currently enough today, as most people still fall for the HTTP download trap, and they can make business there.