diff options
author | Marco Nelissen <marcone@google.com> | 2014-03-14 23:33:07 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-03-14 23:33:07 +0000 |
commit | 0dc3583043bb578b149e50a9928894eff2819508 (patch) | |
tree | 07332bb776cfd3e5c1cbea52d6d2c66e737c9063 /media | |
parent | 3c7801882bbb6d5f3cc641525a54cb8a6c4aca34 (diff) | |
parent | 8788c40c7b5bdcaef1dcaa7f36598ae767880047 (diff) | |
download | frameworks_av-0dc3583043bb578b149e50a9928894eff2819508.zip frameworks_av-0dc3583043bb578b149e50a9928894eff2819508.tar.gz frameworks_av-0dc3583043bb578b149e50a9928894eff2819508.tar.bz2 |
am 8788c40c: am 75dcf510: Merge "Verify certificates" into klp-dev
* commit '8788c40c7b5bdcaef1dcaa7f36598ae767880047':
Verify certificates
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/chromium_http/Android.mk | 1 | ||||
-rw-r--r-- | media/libstagefright/chromium_http/support.cpp | 101 |
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; } //////////////////////////////////////////////////////////////////////////////// |