Loading media/libstagefright/chromium_http/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ LOCAL_SHARED_LIBRARIES += \ libstlport \ libchromium_net \ libutils \ libbinder \ libcutils \ liblog \ libstagefright_foundation \ Loading media/libstagefright/chromium_http/support.cpp +100 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -226,7 +308,24 @@ SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain( const std::vector<std::string>& cert_chain, const std::string& hostname, const std::string& auth_type) { 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; } //////////////////////////////////////////////////////////////////////////////// Loading Loading
media/libstagefright/chromium_http/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ LOCAL_SHARED_LIBRARIES += \ libstlport \ libchromium_net \ libutils \ libbinder \ libcutils \ liblog \ libstagefright_foundation \ Loading
media/libstagefright/chromium_http/support.cpp +100 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -226,7 +308,24 @@ SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain( const std::vector<std::string>& cert_chain, const std::string& hostname, const std::string& auth_type) { 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; } //////////////////////////////////////////////////////////////////////////////// Loading