Add certificate generate/set functionality to bring iOS closer to JS API
The JS API supports two operations which have never been implemented in the iOS counterpart: - generate a new certificate - use this certificate when creating a new PeerConnection Both functions are illustrated in the generateCertificate example code: - https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/generateCertificate Currently, on iOS, a new certificate is automatically generated for every PeerConnection with no programmatic way to set a specific certificate. Work sponsored by |pipe| Bug: webrtc:9498 Change-Id: Ic1936c3de8b8bd18aef67c784727b72f90e7157c Reviewed-on: https://webrtc-review.googlesource.com/87303 Commit-Queue: Steve Anton <steveanton@webrtc.org> Reviewed-by: Kári Helgason <kthelgason@webrtc.org> Reviewed-by: Steve Anton <steveanton@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24276}
This commit is contained in:

committed by
Commit Bot

parent
b336c2784f
commit
ccee56beee
70
sdk/objc/Framework/Classes/PeerConnection/RTCCertificate.mm
Normal file
70
sdk/objc/Framework/Classes/PeerConnection/RTCCertificate.mm
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#import "WebRTC/RTCCertificate.h"
|
||||
#import "WebRTC/RTCLogging.h"
|
||||
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/rtccertificategenerator.h"
|
||||
#include "rtc_base/sslidentity.h"
|
||||
|
||||
@implementation RTCCertificate
|
||||
|
||||
@synthesize private_key = _private_key;
|
||||
@synthesize certificate = _certificate;
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
id copy = [[[self class] alloc] initWithPrivateKey:[self.private_key copyWithZone:zone]
|
||||
certificate:[self.certificate copyWithZone:zone]];
|
||||
return copy;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPrivateKey:(NSString *)private_key certificate:(NSString *)certificate {
|
||||
if (self = [super init]) {
|
||||
_private_key = [private_key copy];
|
||||
_certificate = [certificate copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (nullable RTCCertificate *)generateCertificateWithParams:(NSDictionary *)params {
|
||||
rtc::KeyType keyType = rtc::KT_ECDSA;
|
||||
NSString *keyTypeString = [params valueForKey:@"name"];
|
||||
if (keyTypeString && [keyTypeString isEqualToString:@"RSASSA-PKCS1-v1_5"]) {
|
||||
keyType = rtc::KT_RSA;
|
||||
}
|
||||
|
||||
NSNumber *expires = [params valueForKey:@"expires"];
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> cc_certificate = nullptr;
|
||||
if (expires != nil) {
|
||||
uint64_t expirationTimestamp = [expires unsignedLongLongValue];
|
||||
cc_certificate = rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType),
|
||||
expirationTimestamp);
|
||||
} else {
|
||||
cc_certificate =
|
||||
rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType), absl::nullopt);
|
||||
}
|
||||
if (!cc_certificate) {
|
||||
RTCLogError(@"Failed to generate certificate.");
|
||||
return nullptr;
|
||||
}
|
||||
// grab PEMs and create an NS RTCCerticicate
|
||||
rtc::RTCCertificatePEM pem = cc_certificate->ToPEM();
|
||||
std::string pem_private_key = pem.private_key();
|
||||
std::string pem_certificate = pem.certificate();
|
||||
RTC_LOG(LS_INFO) << "CERT PEM ";
|
||||
RTC_LOG(LS_INFO) << pem_certificate;
|
||||
|
||||
RTCCertificate *cert = [[RTCCertificate alloc] initWithPrivateKey:@(pem_private_key.c_str())
|
||||
certificate:@(pem_certificate.c_str())];
|
||||
return cert;
|
||||
}
|
||||
|
||||
@end
|
@ -23,6 +23,7 @@
|
||||
@implementation RTCConfiguration
|
||||
|
||||
@synthesize iceServers = _iceServers;
|
||||
@synthesize certificate = _certificate;
|
||||
@synthesize iceTransportPolicy = _iceTransportPolicy;
|
||||
@synthesize bundlePolicy = _bundlePolicy;
|
||||
@synthesize rtcpMuxPolicy = _rtcpMuxPolicy;
|
||||
@ -63,6 +64,14 @@
|
||||
[iceServers addObject:iceServer];
|
||||
}
|
||||
_iceServers = iceServers;
|
||||
if (!config.certificates.empty()) {
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> native_cert;
|
||||
native_cert = config.certificates[0];
|
||||
rtc::RTCCertificatePEM native_pem = native_cert->ToPEM();
|
||||
_certificate =
|
||||
[[RTCCertificate alloc] initWithPrivateKey:@(native_pem.private_key().c_str())
|
||||
certificate:@(native_pem.certificate().c_str())];
|
||||
}
|
||||
_iceTransportPolicy =
|
||||
[[self class] transportPolicyForTransportsType:config.type];
|
||||
_bundlePolicy =
|
||||
@ -168,16 +177,32 @@
|
||||
_iceBackupCandidatePairPingInterval;
|
||||
rtc::KeyType keyType =
|
||||
[[self class] nativeEncryptionKeyTypeForKeyType:_keyType];
|
||||
// Generate non-default certificate.
|
||||
if (keyType != rtc::KT_DEFAULT) {
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate =
|
||||
rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType),
|
||||
absl::optional<uint64_t>());
|
||||
if (_certificate != nullptr) {
|
||||
// if offered a pemcert use it...
|
||||
RTC_LOG(LS_INFO) << "Have configured cert - using it.";
|
||||
std::string pem_private_key = [[_certificate private_key] UTF8String];
|
||||
std::string pem_certificate = [[_certificate certificate] UTF8String];
|
||||
rtc::RTCCertificatePEM pem = rtc::RTCCertificatePEM(pem_private_key, pem_certificate);
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate = rtc::RTCCertificate::FromPEM(pem);
|
||||
RTC_LOG(LS_INFO) << "Created cert from PEM strings.";
|
||||
if (!certificate) {
|
||||
RTCLogError(@"Failed to generate certificate.");
|
||||
RTC_LOG(LS_ERROR) << "Failed to generate certificate from PEM.";
|
||||
return nullptr;
|
||||
}
|
||||
nativeConfig->certificates.push_back(certificate);
|
||||
} else {
|
||||
RTC_LOG(LS_INFO) << "Don't have configured cert.";
|
||||
// Generate non-default certificate.
|
||||
if (keyType != rtc::KT_DEFAULT) {
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate =
|
||||
rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType),
|
||||
absl::optional<uint64_t>());
|
||||
if (!certificate) {
|
||||
RTCLogError(@"Failed to generate certificate.");
|
||||
return nullptr;
|
||||
}
|
||||
nativeConfig->certificates.push_back(certificate);
|
||||
}
|
||||
}
|
||||
nativeConfig->ice_candidate_pool_size = _iceCandidatePoolSize;
|
||||
nativeConfig->prune_turn_ports = _shouldPruneTurnPorts ? true : false;
|
||||
|
Reference in New Issue
Block a user