From 97579a4e122ad42592b5d7da9475e128da63a948 Mon Sep 17 00:00:00 2001 From: glaznev Date: Tue, 1 Sep 2015 11:31:27 -0700 Subject: [PATCH] Add option to enable ECDSA key for Java API. Review URL: https://codereview.webrtc.org/1312293003 Cr-Commit-Position: refs/heads/master@{#9835} --- talk/app/webrtc/dtlsidentitystore.cc | 2 +- talk/app/webrtc/dtlsidentitystore.h | 4 ++ .../webrtc/java/jni/classreferenceholder.cc | 1 + .../app/webrtc/java/jni/peerconnection_jni.cc | 37 ++++++++++++++++++- .../java/src/org/webrtc/PeerConnection.java | 8 ++++ webrtc/base/sslidentity.h | 3 ++ .../appspot/apprtc/PeerConnectionClient.java | 2 + 7 files changed, 54 insertions(+), 3 deletions(-) diff --git a/talk/app/webrtc/dtlsidentitystore.cc b/talk/app/webrtc/dtlsidentitystore.cc index 1428f49358..fa330af765 100644 --- a/talk/app/webrtc/dtlsidentitystore.cc +++ b/talk/app/webrtc/dtlsidentitystore.cc @@ -36,7 +36,7 @@ namespace webrtc { // Passed to SSLIdentity::Generate, "WebRTC". Used for the certificates' // subject and issuer name. -static const char kIdentityName[] = "WebRTC"; +const char kIdentityName[] = "WebRTC"; namespace { diff --git a/talk/app/webrtc/dtlsidentitystore.h b/talk/app/webrtc/dtlsidentitystore.h index 1e15afb5f0..3d4a078f0c 100644 --- a/talk/app/webrtc/dtlsidentitystore.h +++ b/talk/app/webrtc/dtlsidentitystore.h @@ -40,6 +40,10 @@ #include "webrtc/base/thread.h" namespace webrtc { + +// Passed to SSLIdentity::Generate. +extern const char kIdentityName[]; + class SSLIdentity; class Thread; diff --git a/talk/app/webrtc/java/jni/classreferenceholder.cc b/talk/app/webrtc/java/jni/classreferenceholder.cc index 520b5a7a19..180bb1d45c 100644 --- a/talk/app/webrtc/java/jni/classreferenceholder.cc +++ b/talk/app/webrtc/java/jni/classreferenceholder.cc @@ -101,6 +101,7 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) { LoadClass(jni, "org/webrtc/PeerConnection$IceGatheringState"); LoadClass(jni, "org/webrtc/PeerConnection$IceTransportsType"); LoadClass(jni, "org/webrtc/PeerConnection$TcpCandidatePolicy"); + LoadClass(jni, "org/webrtc/PeerConnection$KeyType"); LoadClass(jni, "org/webrtc/PeerConnection$SignalingState"); LoadClass(jni, "org/webrtc/SessionDescription"); LoadClass(jni, "org/webrtc/SessionDescription$Type"); diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc index fa52eead8f..1329000aab 100644 --- a/talk/app/webrtc/java/jni/peerconnection_jni.cc +++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc @@ -61,6 +61,7 @@ #include "talk/app/webrtc/java/jni/classreferenceholder.h" #include "talk/app/webrtc/java/jni/jni_helpers.h" #include "talk/app/webrtc/java/jni/native_handle_impl.h" +#include "talk/app/webrtc/dtlsidentitystore.h" #include "talk/app/webrtc/mediaconstraintsinterface.h" #include "talk/app/webrtc/peerconnectioninterface.h" #include "talk/app/webrtc/videosourceinterface.h" @@ -1273,6 +1274,19 @@ JavaTcpCandidatePolicyToNativeType( return PeerConnectionInterface::kTcpCandidatePolicyEnabled; } +static rtc::KeyType JavaKeyTypeToNativeType(JNIEnv* jni, jobject j_key_type) { + std::string enum_name = GetJavaEnumName( + jni, "org/webrtc/PeerConnection$KeyType", j_key_type); + + if (enum_name == "RSA") + return rtc::KT_RSA; + if (enum_name == "ECDSA") + return rtc::KT_ECDSA; + + CHECK(false) << "Unexpected KeyType enum_name " << enum_name; + return rtc::KT_ECDSA; +} + static void JavaIceServersToJsepIceServers( JNIEnv* jni, jobject j_ice_servers, PeerConnectionInterface::IceServers* ice_servers) { @@ -1345,8 +1359,7 @@ JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnection)( jni, j_rtc_config, j_tcp_candidate_policy_id); jfieldID j_ice_servers_id = GetFieldID( - jni, j_rtc_config_class, "iceServers", - "Ljava/util/List;"); + jni, j_rtc_config_class, "iceServers", "Ljava/util/List;"); jobject j_ice_servers = GetObjectField(jni, j_rtc_config, j_ice_servers_id); jfieldID j_audio_jitter_buffer_max_packets_id = @@ -1357,6 +1370,10 @@ JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnection)( jfieldID j_ice_connection_receiving_timeout_id = GetFieldID(jni, j_rtc_config_class, "iceConnectionReceivingTimeout", "I"); + jfieldID j_key_type_id = GetFieldID(jni, j_rtc_config_class, "keyType", + "Lorg/webrtc/PeerConnection$KeyType;"); + jobject j_key_type = GetObjectField(jni, j_rtc_config, j_key_type_id); + PeerConnectionInterface::RTCConfiguration rtc_config; rtc_config.type = JavaIceTransportsTypeToNativeType(jni, j_ice_transports_type); @@ -1373,6 +1390,22 @@ JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnection)( rtc_config.ice_connection_receiving_timeout = GetIntField(jni, j_rtc_config, j_ice_connection_receiving_timeout_id); + // Create ECDSA certificate. + if (JavaKeyTypeToNativeType(jni, j_key_type) == rtc::KT_ECDSA) { + scoped_ptr ssl_identity( + rtc::SSLIdentity::Generate(webrtc::kIdentityName, rtc::KT_ECDSA)); + if (ssl_identity.get()) { + rtc_config.certificates.push_back( + rtc::RTCCertificate::Create(ssl_identity.Pass())); + LOG(LS_INFO) << "ECDSA certificate created."; + } else { + // Failing to create certificate should not abort peer connection + // creation. Instead default encryption (currently RSA) will be used. + LOG(LS_WARNING) << + "Failed to generate SSLIdentity. Default encryption will be used."; + } + } + PCOJava* observer = reinterpret_cast(observer_p); observer->SetConstraints(new ConstraintsWrapper(jni, j_constraints)); rtc::scoped_refptr pc(f->CreatePeerConnection( diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java index a7b79c7b25..8730af96c9 100644 --- a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java +++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java @@ -124,11 +124,17 @@ public class PeerConnection { public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }; + /** Java version of PeerConnectionInterface.TcpCandidatePolicy */ public enum TcpCandidatePolicy { ENABLED, DISABLED }; + /** Java version of rtc::KeyType */ + public enum KeyType { + RSA, ECDSA + } + /** Java version of PeerConnectionInterface.RTCConfiguration */ public static class RTCConfiguration { public IceTransportsType iceTransportsType; @@ -139,6 +145,7 @@ public class PeerConnection { public int audioJitterBufferMaxPackets; public boolean audioJitterBufferFastAccelerate; public int iceConnectionReceivingTimeout; + public KeyType keyType; public RTCConfiguration(List iceServers) { iceTransportsType = IceTransportsType.ALL; @@ -149,6 +156,7 @@ public class PeerConnection { audioJitterBufferMaxPackets = 50; audioJitterBufferFastAccelerate = false; iceConnectionReceivingTimeout = -1; + keyType = KeyType.ECDSA; } }; diff --git a/webrtc/base/sslidentity.h b/webrtc/base/sslidentity.h index 1112def098..47694bb629 100644 --- a/webrtc/base/sslidentity.h +++ b/webrtc/base/sslidentity.h @@ -107,6 +107,9 @@ class SSLCertChain { DISALLOW_COPY_AND_ASSIGN(SSLCertChain); }; +// TODO(hbos, torbjorng): Don't change KT_DEFAULT without first +// updating PeerConnectionFactory_nativeCreatePeerConnection's certificate +// generation code. enum KeyType { KT_RSA, KT_ECDSA, KT_LAST, KT_DEFAULT = KT_RSA }; // Parameters for generating an identity for testing. If common_name is diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java index 6e54ae2262..e9275ea21f 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java @@ -421,6 +421,8 @@ public class PeerConnectionClient { rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED; rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE; rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE; + // Use ECDSA encryption. + rtcConfig.keyType = PeerConnection.KeyType.ECDSA; peerConnection = factory.createPeerConnection( rtcConfig, pcConstraints, pcObserver);