Support client certificate in TLSBox

This commit is contained in:
Davide De Rosa 2018-08-23 17:24:39 +02:00
parent 6a71ada1c8
commit b7a48d4f4f
4 changed files with 45 additions and 13 deletions

View File

@ -39,15 +39,17 @@
extern NSString *const TunnelKitErrorDomain;
typedef NS_ENUM(NSInteger, TunnelKitErrorCode) {
TunnelKitErrorCodeCryptoBoxRandomGenerator = 101,
TunnelKitErrorCodeCryptoBoxHMAC,
TunnelKitErrorCodeCryptoBoxEncryption,
TunnelKitErrorCodeCryptoBoxAlgorithm,
TunnelKitErrorCodeTLSBoxCA = 201,
TunnelKitErrorCodeTLSBoxHandshake,
TunnelKitErrorCodeTLSBoxGeneric,
TunnelKitErrorCodeDataPathOverflow = 301,
TunnelKitErrorCodeDataPathPeerIdMismatch
TunnelKitErrorCodeCryptoBoxRandomGenerator = 101,
TunnelKitErrorCodeCryptoBoxHMAC = 102,
TunnelKitErrorCodeCryptoBoxEncryption = 103,
TunnelKitErrorCodeCryptoBoxAlgorithm = 104,
TunnelKitErrorCodeTLSBoxCA = 201,
TunnelKitErrorCodeTLSBoxHandshake = 202,
TunnelKitErrorCodeTLSBoxGeneric = 203,
TunnelKitErrorCodeTLSBoxClientCertificate = 204,
TunnelKitErrorCodeTLSBoxClientKey = 205,
TunnelKitErrorCodeDataPathOverflow = 301,
TunnelKitErrorCodeDataPathPeerIdMismatch = 302
};
static inline NSError *TunnelKitErrorWithCode(TunnelKitErrorCode code) {

View File

@ -767,7 +767,11 @@ public class SessionProxy {
log.debug("Remote sessionId is \(remoteSessionId.toHex())")
log.debug("Start TLS handshake")
negotiationKey.tlsOptional = TLSBox(caPath: configuration.caPath)
negotiationKey.tlsOptional = TLSBox(
caPath: configuration.caPath,
clientCertificatePath: nil,
clientKeyPath: nil
)
do {
try negotiationKey.tls.start()
} catch let e {

View File

@ -49,7 +49,9 @@ extern NSString *const TLSBoxPeerVerificationErrorNotification;
//
@interface TLSBox : NSObject
- (nonnull instancetype)initWithCAPath:(nullable NSString *)caPath;
- (nonnull instancetype)initWithCAPath:(NSString *)caPath
clientCertificatePath:(NSString *)clientCertificatePath
clientKeyPath:(NSString *)clientKeyPath;
- (BOOL)startWithError:(NSError **)error;

View File

@ -59,6 +59,8 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
@interface TLSBox ()
@property (nonatomic, strong) NSString *caPath;
@property (nonatomic, strong) NSString *clientCertificatePath;
@property (nonatomic, strong) NSString *clientKeyPath;
@property (nonatomic, assign) BOOL isConnected;
@property (nonatomic, unsafe_unretained) SSL_CTX *ctx;
@ -75,13 +77,15 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
- (instancetype)init
{
return [self initWithCAPath:nil];
return [self initWithCAPath:nil clientCertificatePath:nil clientKeyPath:nil];
}
- (instancetype)initWithCAPath:(NSString *)caPath
- (instancetype)initWithCAPath:(NSString *)caPath clientCertificatePath:(NSString *)clientCertificatePath clientKeyPath:(NSString *)clientKeyPath
{
if ((self = [super init])) {
self.caPath = caPath;
self.clientCertificatePath = clientCertificatePath;
self.clientKeyPath = clientKeyPath;
self.bufferCipherText = allocate_safely(TLSBoxMaxBufferLength);
}
return self;
@ -124,6 +128,26 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
else {
SSL_CTX_set_verify(self.ctx, SSL_VERIFY_NONE, NULL);
}
if (self.clientCertificatePath) {
if (!SSL_CTX_use_certificate_file(self.ctx, [self.clientCertificatePath cStringUsingEncoding:NSASCIIStringEncoding], SSL_FILETYPE_PEM)) {
ERR_print_errors_fp(stdout);
if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSBoxClientCertificate);
}
return NO;
}
if (self.clientKeyPath) {
if (!SSL_CTX_use_PrivateKey_file(self.ctx, [self.clientKeyPath cStringUsingEncoding:NSASCIIStringEncoding], SSL_FILETYPE_PEM)) {
ERR_print_errors_fp(stdout);
if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSBoxClientKey);
}
return NO;
}
}
}
self.ssl = SSL_new(self.ctx);