JNI+mm: Generate certificate if non-default key type is specified.

By comparing key type with KT_DEFAULT we remove the implicit assumption that
the default is RSA.

Removing the assumptions about what the default is is necessary for a
follow-up CL that will change the default.

BUG=webrtc:5795, webrtc:5707
R=hta@webrtc.org, magjed@webrtc.org, tommi@webrtc.org
TBR=tkchin@webrtc.org

Review URL: https://codereview.webrtc.org/1965313002 .

Cr-Commit-Position: refs/heads/master@{#12722}
This commit is contained in:
Henrik Boström
2016-05-13 13:50:38 +02:00
parent d0dc66e0ea
commit e06c2ddbde
6 changed files with 69 additions and 53 deletions

View File

@ -64,6 +64,7 @@
#include "webrtc/base/logsinks.h" #include "webrtc/base/logsinks.h"
#include "webrtc/base/messagequeue.h" #include "webrtc/base/messagequeue.h"
#include "webrtc/base/networkmonitor.h" #include "webrtc/base/networkmonitor.h"
#include "webrtc/base/rtccertificategenerator.h"
#include "webrtc/base/ssladapter.h" #include "webrtc/base/ssladapter.h"
#include "webrtc/base/stringutils.h" #include "webrtc/base/stringutils.h"
#include "webrtc/media/base/videocapturer.h" #include "webrtc/media/base/videocapturer.h"
@ -1565,20 +1566,17 @@ JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnection)(
"Lorg/webrtc/PeerConnection$KeyType;"); "Lorg/webrtc/PeerConnection$KeyType;");
jobject j_key_type = GetObjectField(jni, j_rtc_config, j_key_type_id); jobject j_key_type = GetObjectField(jni, j_rtc_config, j_key_type_id);
// Create ECDSA certificate. // Generate non-default certificate.
if (JavaKeyTypeToNativeType(jni, j_key_type) == rtc::KT_ECDSA) { rtc::KeyType key_type = JavaKeyTypeToNativeType(jni, j_key_type);
std::unique_ptr<rtc::SSLIdentity> ssl_identity( if (key_type != rtc::KT_DEFAULT) {
rtc::SSLIdentity::Generate(webrtc::kIdentityName, rtc::KT_ECDSA)); rtc::scoped_refptr<rtc::RTCCertificate> certificate =
if (ssl_identity.get()) { rtc::RTCCertificateGenerator::GenerateCertificate(
rtc_config.certificates.push_back( rtc::KeyParams(key_type), rtc::Optional<uint64_t>());
rtc::RTCCertificate::Create(std::move(ssl_identity))); if (!certificate) {
LOG(LS_INFO) << "ECDSA certificate created."; LOG(LS_ERROR) << "Failed to generate certificate. KeyType: " << key_type;
} else { return 0;
// 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.";
} }
rtc_config.certificates.push_back(certificate);
} }
PCOJava* observer = reinterpret_cast<PCOJava*>(observer_p); PCOJava* observer = reinterpret_cast<PCOJava*>(observer_p);

View File

@ -117,9 +117,6 @@ class SSLCertChain {
// KT_DEFAULT is currently an alias for KT_RSA. This is likely to change. // KT_DEFAULT is currently an alias for KT_RSA. This is likely to change.
// KT_LAST is intended for vector declarations and loops over all key types; // KT_LAST is intended for vector declarations and loops over all key types;
// it does not represent any key type in itself. // it does not represent any key type in itself.
// 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 }; enum KeyType { KT_RSA, KT_ECDSA, KT_LAST, KT_DEFAULT = KT_RSA };
static const int kRsaDefaultModSize = 1024; static const int kRsaDefaultModSize = 1024;

View File

@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
* needed to pass to the underlying C++ APIs. * needed to pass to the underlying C++ APIs.
*/ */
@property(nonatomic, readonly) @property(nonatomic, readonly)
webrtc::PeerConnectionInterface::RTCConfiguration nativeConfiguration; webrtc::PeerConnectionInterface::RTCConfiguration* nativeConfiguration;
+ (webrtc::PeerConnectionInterface::IceTransportsType) + (webrtc::PeerConnectionInterface::IceTransportsType)
nativeTransportsTypeForTransportPolicy:(RTCIceTransportPolicy)policy; nativeTransportsTypeForTransportPolicy:(RTCIceTransportPolicy)policy;

View File

@ -15,6 +15,7 @@
#import "RTCIceServer+Private.h" #import "RTCIceServer+Private.h"
#import "WebRTC/RTCLogging.h" #import "WebRTC/RTCLogging.h"
#include "webrtc/base/rtccertificategenerator.h"
#include "webrtc/base/sslidentity.h" #include "webrtc/base/sslidentity.h"
@implementation RTCConfiguration @implementation RTCConfiguration
@ -74,39 +75,43 @@
#pragma mark - Private #pragma mark - Private
- (webrtc::PeerConnectionInterface::RTCConfiguration)nativeConfiguration { - (webrtc::PeerConnectionInterface::RTCConfiguration*)nativeConfiguration {
webrtc::PeerConnectionInterface::RTCConfiguration nativeConfig; std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration>
nativeConfig(new webrtc::PeerConnectionInterface::RTCConfiguration());
for (RTCIceServer *iceServer in _iceServers) { for (RTCIceServer *iceServer in _iceServers) {
nativeConfig.servers.push_back(iceServer.nativeServer); nativeConfig->servers.push_back(iceServer.nativeServer);
} }
nativeConfig.type = nativeConfig->type =
[[self class] nativeTransportsTypeForTransportPolicy:_iceTransportPolicy]; [[self class] nativeTransportsTypeForTransportPolicy:_iceTransportPolicy];
nativeConfig.bundle_policy = nativeConfig->bundle_policy =
[[self class] nativeBundlePolicyForPolicy:_bundlePolicy]; [[self class] nativeBundlePolicyForPolicy:_bundlePolicy];
nativeConfig.rtcp_mux_policy = nativeConfig->rtcp_mux_policy =
[[self class] nativeRtcpMuxPolicyForPolicy:_rtcpMuxPolicy]; [[self class] nativeRtcpMuxPolicyForPolicy:_rtcpMuxPolicy];
nativeConfig.tcp_candidate_policy = nativeConfig->tcp_candidate_policy =
[[self class] nativeTcpCandidatePolicyForPolicy:_tcpCandidatePolicy]; [[self class] nativeTcpCandidatePolicyForPolicy:_tcpCandidatePolicy];
nativeConfig.continual_gathering_policy = [[self class] nativeConfig->continual_gathering_policy = [[self class]
nativeContinualGatheringPolicyForPolicy:_continualGatheringPolicy]; nativeContinualGatheringPolicyForPolicy:_continualGatheringPolicy];
nativeConfig.audio_jitter_buffer_max_packets = _audioJitterBufferMaxPackets; nativeConfig->audio_jitter_buffer_max_packets = _audioJitterBufferMaxPackets;
nativeConfig.ice_connection_receiving_timeout = nativeConfig->ice_connection_receiving_timeout =
_iceConnectionReceivingTimeout; _iceConnectionReceivingTimeout;
nativeConfig.ice_backup_candidate_pair_ping_interval = nativeConfig->ice_backup_candidate_pair_ping_interval =
_iceBackupCandidatePairPingInterval; _iceBackupCandidatePairPingInterval;
if (_keyType == RTCEncryptionKeyTypeECDSA) { rtc::KeyType keyType =
std::unique_ptr<rtc::SSLIdentity> identity( [[self class] nativeEncryptionKeyTypeForKeyType:_keyType];
rtc::SSLIdentity::Generate(webrtc::kIdentityName, rtc::KT_ECDSA)); // Generate non-default certificate.
if (identity) { if (keyType != rtc::KT_DEFAULT) {
nativeConfig.certificates.push_back( rtc::scoped_refptr<rtc::RTCCertificate> certificate =
rtc::RTCCertificate::Create(std::move(identity))); rtc::RTCCertificateGenerator::GenerateCertificate(
} else { rtc::KeyParams(keyType), rtc::Optional<uint64_t>());
RTCLogWarning(@"Failed to generate ECDSA identity. RSA will be used."); if (!certificate) {
RTCLogWarning(@"Failed to generate certificate.");
return nullptr;
} }
nativeConfig->certificates.push_back(certificate);
} }
return nativeConfig; return nativeConfig.release();
} }
+ (webrtc::PeerConnectionInterface::IceTransportsType) + (webrtc::PeerConnectionInterface::IceTransportsType)
@ -224,6 +229,16 @@
} }
} }
+ (rtc::KeyType)nativeEncryptionKeyTypeForKeyType:
(RTCEncryptionKeyType)keyType {
switch (keyType) {
case RTCEncryptionKeyTypeRSA:
return rtc::KT_RSA;
case RTCEncryptionKeyTypeECDSA:
return rtc::KT_ECDSA;
}
}
+ (RTCTcpCandidatePolicy)tcpCandidatePolicyForNativePolicy: + (RTCTcpCandidatePolicy)tcpCandidatePolicyForNativePolicy:
(webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativePolicy { (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativePolicy {
switch (nativePolicy) { switch (nativePolicy) {

View File

@ -197,14 +197,16 @@ void PeerConnectionDelegateAdapter::OnIceCandidate(
constraints:(RTCMediaConstraints *)constraints constraints:(RTCMediaConstraints *)constraints
delegate:(id<RTCPeerConnectionDelegate>)delegate { delegate:(id<RTCPeerConnectionDelegate>)delegate {
NSParameterAssert(factory); NSParameterAssert(factory);
std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
configuration.nativeConfiguration);
if (!config)
return nullptr;
if (self = [super init]) { if (self = [super init]) {
_observer.reset(new webrtc::PeerConnectionDelegateAdapter(self)); _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
webrtc::PeerConnectionInterface::RTCConfiguration config =
configuration.nativeConfiguration;
std::unique_ptr<webrtc::MediaConstraints> nativeConstraints = std::unique_ptr<webrtc::MediaConstraints> nativeConstraints =
constraints.nativeConstraints; constraints.nativeConstraints;
_peerConnection = _peerConnection =
factory.nativeFactory->CreatePeerConnection(config, factory.nativeFactory->CreatePeerConnection(*config,
nativeConstraints.get(), nativeConstraints.get(),
nullptr, nullptr,
nullptr, nullptr,
@ -251,7 +253,11 @@ void PeerConnectionDelegateAdapter::OnIceCandidate(
} }
- (BOOL)setConfiguration:(RTCConfiguration *)configuration { - (BOOL)setConfiguration:(RTCConfiguration *)configuration {
return _peerConnection->SetConfiguration(configuration.nativeConfiguration); std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
configuration.nativeConfiguration);
if (!config)
return false;
return _peerConnection->SetConfiguration(*config);
} }
- (void)close { - (void)close {

View File

@ -44,26 +44,26 @@
config.continualGatheringPolicy = config.continualGatheringPolicy =
RTCContinualGatheringPolicyGatherContinually; RTCContinualGatheringPolicyGatherContinually;
webrtc::PeerConnectionInterface::RTCConfiguration nativeConfig = std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration>
config.nativeConfiguration; nativeConfig(config.nativeConfiguration);
EXPECT_EQ(1u, nativeConfig.servers.size()); EXPECT_EQ(1u, nativeConfig->servers.size());
webrtc::PeerConnectionInterface::IceServer nativeServer = webrtc::PeerConnectionInterface::IceServer nativeServer =
nativeConfig.servers.front(); nativeConfig->servers.front();
EXPECT_EQ(1u, nativeServer.urls.size()); EXPECT_EQ(1u, nativeServer.urls.size());
EXPECT_EQ("stun:stun1.example.net", nativeServer.urls.front()); EXPECT_EQ("stun:stun1.example.net", nativeServer.urls.front());
EXPECT_EQ(webrtc::PeerConnectionInterface::kRelay, nativeConfig.type); EXPECT_EQ(webrtc::PeerConnectionInterface::kRelay, nativeConfig->type);
EXPECT_EQ(webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle, EXPECT_EQ(webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle,
nativeConfig.bundle_policy); nativeConfig->bundle_policy);
EXPECT_EQ(webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate, EXPECT_EQ(webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate,
nativeConfig.rtcp_mux_policy); nativeConfig->rtcp_mux_policy);
EXPECT_EQ(webrtc::PeerConnectionInterface::kTcpCandidatePolicyDisabled, EXPECT_EQ(webrtc::PeerConnectionInterface::kTcpCandidatePolicyDisabled,
nativeConfig.tcp_candidate_policy); nativeConfig->tcp_candidate_policy);
EXPECT_EQ(maxPackets, nativeConfig.audio_jitter_buffer_max_packets); EXPECT_EQ(maxPackets, nativeConfig->audio_jitter_buffer_max_packets);
EXPECT_EQ(timeout, nativeConfig.ice_connection_receiving_timeout); EXPECT_EQ(timeout, nativeConfig->ice_connection_receiving_timeout);
EXPECT_EQ(interval, nativeConfig.ice_backup_candidate_pair_ping_interval); EXPECT_EQ(interval, nativeConfig->ice_backup_candidate_pair_ping_interval);
EXPECT_EQ(webrtc::PeerConnectionInterface::GATHER_CONTINUALLY, EXPECT_EQ(webrtc::PeerConnectionInterface::GATHER_CONTINUALLY,
nativeConfig.continual_gathering_policy); nativeConfig->continual_gathering_policy);
} }
@end @end