forked from JumpingYang001/webrtc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Reviewed-by: Kári Helgason <[email protected]> Reviewed-by: Steve Anton <[email protected]> Cr-Commit-Position: refs/heads/master@{#24276}
- Loading branch information
Showing
8 changed files
with
236 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ Manish Jethani <[email protected]> | |
Martin Storsjo <[email protected]> | ||
Matthias Liebig <[email protected]> | ||
Maxim Potapov <[email protected]> | ||
Michael Iedema <[email protected]> | ||
Mike Gilbert <[email protected]> | ||
Mo Zanaty <[email protected]> | ||
Pali Rohar | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
sdk/objc/Framework/Classes/PeerConnection/RTCCertificate.mm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* 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 <Foundation/Foundation.h> | ||
|
||
#import <WebRTC/RTCMacros.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
RTC_EXPORT | ||
@interface RTCCertificate : NSObject <NSCopying> | ||
|
||
/** Private key in PEM. */ | ||
@property(nonatomic, readonly, copy) NSString *private_key; | ||
|
||
/** Public key in an x509 cert encoded in PEM. */ | ||
@property(nonatomic, readonly, copy) NSString *certificate; | ||
|
||
/** | ||
* Initialize an RTCCertificate with PEM strings for private_key and certificate. | ||
*/ | ||
- (instancetype)initWithPrivateKey:(NSString *)private_key | ||
certificate:(NSString *)certificate NS_DESIGNATED_INITIALIZER; | ||
|
||
- (instancetype)init NS_UNAVAILABLE; | ||
|
||
/** Generate a new certificate for 're' use. | ||
* | ||
* Optional dictionary of parameters. Defaults to KeyType ECDSA if none are | ||
* provided. | ||
* - name: "ECDSA" or "RSASSA-PKCS1-v1_5" | ||
*/ | ||
+ (nullable RTCCertificate *)generateCertificateWithParams:(NSDictionary *)params; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* 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 <Foundation/Foundation.h> | ||
|
||
#include <vector> | ||
|
||
#include "rtc_base/gunit.h" | ||
|
||
#import "NSString+StdString.h" | ||
#import "RTCConfiguration+Private.h" | ||
#import "WebRTC/RTCConfiguration.h" | ||
#import "WebRTC/RTCIceServer.h" | ||
#import "WebRTC/RTCMediaConstraints.h" | ||
#import "WebRTC/RTCPeerConnection.h" | ||
#import "WebRTC/RTCPeerConnectionFactory.h" | ||
|
||
@interface RTCCertificateTest : NSObject | ||
- (void)testCertificateIsUsedInConfig; | ||
@end | ||
|
||
@implementation RTCCertificateTest | ||
|
||
- (void)testCertificateIsUsedInConfig { | ||
RTCConfiguration *originalConfig = [[RTCConfiguration alloc] init]; | ||
|
||
NSArray *urlStrings = @[ @"stun:stun1.example.net" ]; | ||
RTCIceServer *server = [[RTCIceServer alloc] initWithURLStrings:urlStrings]; | ||
originalConfig.iceServers = @[ server ]; | ||
|
||
// Generate a new certificate. | ||
RTCCertificate *originalCertificate = [RTCCertificate generateCertificateWithParams:@{ | ||
@"expires" : @100000, | ||
@"name" : @"RSASSA-PKCS1-v1_5" | ||
}]; | ||
|
||
// Store certificate in configuration. | ||
originalConfig.certificate = originalCertificate; | ||
|
||
RTCMediaConstraints *contraints = | ||
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:@{} optionalConstraints:nil]; | ||
RTCPeerConnectionFactory *factory = [[RTCPeerConnectionFactory alloc] init]; | ||
|
||
// Create PeerConnection with this certificate. | ||
RTCPeerConnection *peerConnection = | ||
[factory peerConnectionWithConfiguration:originalConfig constraints:contraints delegate:nil]; | ||
|
||
// Retrieve certificate from the configuration. | ||
RTCConfiguration *retrievedConfig = peerConnection.configuration; | ||
|
||
// Extract PEM strings from original certificate. | ||
std::string originalPrivateKeyField = [[originalCertificate private_key] UTF8String]; | ||
std::string originalCertificateField = [[originalCertificate certificate] UTF8String]; | ||
|
||
// Extract PEM strings from certificate retrieved from configuration. | ||
RTCCertificate *retrievedCertificate = retrievedConfig.certificate; | ||
std::string retrievedPrivateKeyField = [[retrievedCertificate private_key] UTF8String]; | ||
std::string retrievedCertificateField = [[retrievedCertificate certificate] UTF8String]; | ||
|
||
// Check that the original certificate and retrieved certificate match. | ||
EXPECT_EQ(originalPrivateKeyField, retrievedPrivateKeyField); | ||
EXPECT_EQ(retrievedCertificateField, retrievedCertificateField); | ||
} | ||
|
||
@end | ||
|
||
TEST(CertificateTest, CertificateIsUsedInConfig) { | ||
RTCCertificateTest *test = [[RTCCertificateTest alloc] init]; | ||
[test testCertificateIsUsedInConfig]; | ||
} |