summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorMarco Nelissen <marcone@google.com>2014-03-14 22:34:55 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-03-14 22:34:55 +0000
commita58ed6d8378108e4309ee0077dc4529b76634791 (patch)
tree771dbffdcc074c06ec06e9d3a223c9982265c435 /media/libstagefright
parent236104afb2300b7d969b1dc786f14b5f912df1cf (diff)
parent75dcf5101c90e31bbac95694d835b0e8f57ba720 (diff)
downloadframeworks_av-a58ed6d8378108e4309ee0077dc4529b76634791.zip
frameworks_av-a58ed6d8378108e4309ee0077dc4529b76634791.tar.gz
frameworks_av-a58ed6d8378108e4309ee0077dc4529b76634791.tar.bz2
am 75dcf510: Merge "Verify certificates" into klp-dev
* commit '75dcf5101c90e31bbac95694d835b0e8f57ba720': Verify certificates
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/chromium_http/Android.mk1
-rw-r--r--media/libstagefright/chromium_http/support.cpp101
2 files changed, 101 insertions, 1 deletions
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
index 25a25ab..f191a4b 100644
--- a/media/libstagefright/chromium_http/Android.mk
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -21,6 +21,7 @@ LOCAL_SHARED_LIBRARIES += \
libstlport \
libchromium_net \
libutils \
+ libbinder \
libcutils \
liblog \
libstagefright_foundation \
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index 3b33212..d4e82ee 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -40,8 +40,90 @@
#include <media/stagefright/Utils.h>
#include <string>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+
namespace android {
+// must be kept in sync with interface defined in IAudioService.aidl
+class IAudioService : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioService);
+
+ virtual int verifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type) = 0;
+};
+
+class BpAudioService : public BpInterface<IAudioService>
+{
+public:
+ BpAudioService(const sp<IBinder>& impl)
+ : BpInterface<IAudioService>(impl)
+ {
+ }
+
+ virtual int verifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioService::getInterfaceDescriptor());
+
+ // The vector of std::string we get isn't really a vector of strings,
+ // but rather a vector of binary certificate data. If we try to pass
+ // it to Java language code as a string, it ends up mangled on the other
+ // side, so send them as bytes instead.
+ // Since we can't send an array of byte arrays, send a single array,
+ // which will be split out by the recipient.
+
+ int numcerts = cert_chain.size();
+ data.writeInt32(numcerts);
+ size_t total = 0;
+ for (int i = 0; i < numcerts; i++) {
+ total += cert_chain[i].size();
+ }
+ size_t bytesize = total + numcerts * 4;
+ uint8_t *bytes = (uint8_t*) malloc(bytesize);
+ if (!bytes) {
+ return 5; // SSL_INVALID
+ }
+ ALOGV("%d certs: %d -> %d", numcerts, total, bytesize);
+
+ int offset = 0;
+ for (int i = 0; i < numcerts; i++) {
+ int32_t certsize = cert_chain[i].size();
+ // store this in a known order, which just happens to match the default
+ // byte order of a java ByteBuffer
+ int32_t bigsize = htonl(certsize);
+ ALOGV("cert %d, size %d", i, certsize);
+ memcpy(bytes + offset, &bigsize, sizeof(bigsize));
+ offset += sizeof(bigsize);
+ memcpy(bytes + offset, cert_chain[i].data(), certsize);
+ offset += certsize;
+ }
+ data.writeByteArray(bytesize, bytes);
+ free(bytes);
+ data.writeString16(String16(hostname.c_str()));
+ data.writeString16(String16(auth_type.c_str()));
+
+ int32_t result;
+ if (remote()->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply) != NO_ERROR
+ || reply.readExceptionCode() < 0 || reply.readInt32(&result) != NO_ERROR) {
+ return 5; // SSL_INVALID;
+ }
+ return result;
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(AudioService, "android.media.IAudioService");
+
+
static Mutex gNetworkThreadLock;
static base::Thread *gNetworkThread = NULL;
static scoped_refptr<SfRequestContext> gReqContext;
@@ -226,7 +308,24 @@ SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
const std::vector<std::string>& cert_chain,
const std::string& hostname,
const std::string& auth_type) {
- return VERIFY_OK;
+
+ sp<IBinder> binder =
+ defaultServiceManager()->checkService(String16("audio"));
+ if (binder == 0) {
+ ALOGW("Thread cannot connect to the audio service");
+ } else {
+ sp<IAudioService> service = interface_cast<IAudioService>(binder);
+ int code = service->verifyX509CertChain(cert_chain, hostname, auth_type);
+ ALOGV("verified: %d", code);
+ if (code == -1) {
+ return VERIFY_OK;
+ } else if (code == 2) { // SSL_IDMISMATCH
+ return VERIFY_BAD_HOSTNAME;
+ } else if (code == 3) { // SSL_UNTRUSTED
+ return VERIFY_NO_TRUSTED_ROOT;
+ }
+ }
+ return VERIFY_INVOCATION_ERROR;
}
////////////////////////////////////////////////////////////////////////////////