Merge pull request #98 from keeshux/customize-security-level

Customize security level
This commit is contained in:
Davide De Rosa 2019-05-09 10:18:04 +02:00 committed by GitHub
commit 977ff7e573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 2 deletions

View File

@ -147,6 +147,7 @@ extension TunnelKitProvider {
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.tlsWrap)]") throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.tlsWrap)]")
} }
} }
sessionConfigurationBuilder.tlsSecurityLevel = providerConfiguration[S.tlsSecurityLevel] as? Int ?? ConfigurationBuilder.defaults.sessionConfiguration.tlsSecurityLevel
sessionConfigurationBuilder.keepAliveInterval = providerConfiguration[S.keepAlive] as? TimeInterval ?? ConfigurationBuilder.defaults.sessionConfiguration.keepAliveInterval sessionConfigurationBuilder.keepAliveInterval = providerConfiguration[S.keepAlive] as? TimeInterval ?? ConfigurationBuilder.defaults.sessionConfiguration.keepAliveInterval
sessionConfigurationBuilder.renegotiatesAfter = providerConfiguration[S.renegotiatesAfter] as? TimeInterval ?? ConfigurationBuilder.defaults.sessionConfiguration.renegotiatesAfter sessionConfigurationBuilder.renegotiatesAfter = providerConfiguration[S.renegotiatesAfter] as? TimeInterval ?? ConfigurationBuilder.defaults.sessionConfiguration.renegotiatesAfter
guard let endpointProtocolsStrings = providerConfiguration[S.endpointProtocols] as? [String], !endpointProtocolsStrings.isEmpty else { guard let endpointProtocolsStrings = providerConfiguration[S.endpointProtocols] as? [String], !endpointProtocolsStrings.isEmpty else {
@ -245,6 +246,8 @@ extension TunnelKitProvider {
static let tlsWrap = "TLSWrap" static let tlsWrap = "TLSWrap"
static let tlsSecurityLevel = "TLSSecurityLevel"
static let keepAlive = "KeepAlive" static let keepAlive = "KeepAlive"
static let endpointProtocols = "EndpointProtocols" static let endpointProtocols = "EndpointProtocols"
@ -451,6 +454,9 @@ extension TunnelKitProvider {
if let tlsWrapData = sessionConfiguration.tlsWrap?.serialized() { if let tlsWrapData = sessionConfiguration.tlsWrap?.serialized() {
dict[S.tlsWrap] = tlsWrapData dict[S.tlsWrap] = tlsWrapData
} }
if let tlsSecurityLevel = sessionConfiguration.tlsSecurityLevel {
dict[S.tlsSecurityLevel] = tlsSecurityLevel
}
if let keepAliveSeconds = sessionConfiguration.keepAliveInterval { if let keepAliveSeconds = sessionConfiguration.keepAliveInterval {
dict[S.keepAlive] = keepAliveSeconds dict[S.keepAlive] = keepAliveSeconds
} }
@ -554,6 +560,11 @@ extension TunnelKitProvider {
} else { } else {
log.info("\tTLS wrapping: disabled") log.info("\tTLS wrapping: disabled")
} }
if let tlsSecurityLevel = sessionConfiguration.tlsSecurityLevel {
log.info("\tTLS security level: \(tlsSecurityLevel)")
} else {
log.info("\tTLS security level: default")
}
if let keepAliveSeconds = sessionConfiguration.keepAliveInterval, keepAliveSeconds > 0 { if let keepAliveSeconds = sessionConfiguration.keepAliveInterval, keepAliveSeconds > 0 {
log.info("\tKeep-alive: \(keepAliveSeconds) seconds") log.info("\tKeep-alive: \(keepAliveSeconds) seconds")
} else { } else {

View File

@ -197,6 +197,9 @@ extension SessionProxy {
/// The optional TLS wrapping. /// The optional TLS wrapping.
public var tlsWrap: SessionProxy.TLSWrap? public var tlsWrap: SessionProxy.TLSWrap?
/// If set, overrides TLS security level (0 = lowest).
public var tlsSecurityLevel: Int?
/// Sends periodical keep-alive packets if set. /// Sends periodical keep-alive packets if set.
public var keepAliveInterval: TimeInterval? public var keepAliveInterval: TimeInterval?
@ -273,6 +276,7 @@ extension SessionProxy {
clientCertificate: clientCertificate, clientCertificate: clientCertificate,
clientKey: clientKey, clientKey: clientKey,
tlsWrap: tlsWrap, tlsWrap: tlsWrap,
tlsSecurityLevel: tlsSecurityLevel,
keepAliveInterval: keepAliveInterval, keepAliveInterval: keepAliveInterval,
renegotiatesAfter: renegotiatesAfter, renegotiatesAfter: renegotiatesAfter,
hostname: hostname, hostname: hostname,
@ -338,6 +342,9 @@ extension SessionProxy {
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap` /// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap`
public let tlsWrap: TLSWrap? public let tlsWrap: TLSWrap?
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsSecurityLevel`
public let tlsSecurityLevel: Int?
/// - Seealso: `SessionProxy.ConfigurationBuilder.keepAliveInterval` /// - Seealso: `SessionProxy.ConfigurationBuilder.keepAliveInterval`
public let keepAliveInterval: TimeInterval? public let keepAliveInterval: TimeInterval?
@ -427,6 +434,7 @@ extension SessionProxy.Configuration {
builder.clientCertificate = clientCertificate builder.clientCertificate = clientCertificate
builder.clientKey = clientKey builder.clientKey = clientKey
builder.tlsWrap = tlsWrap builder.tlsWrap = tlsWrap
builder.tlsSecurityLevel = tlsSecurityLevel
builder.keepAliveInterval = keepAliveInterval builder.keepAliveInterval = keepAliveInterval
builder.renegotiatesAfter = renegotiatesAfter builder.renegotiatesAfter = renegotiatesAfter
builder.hostname = hostname builder.hostname = hostname

View File

@ -792,12 +792,16 @@ public class SessionProxy {
log.debug("Start TLS handshake") log.debug("Start TLS handshake")
negotiationKey.tlsOptional = TLSBox( let tls = TLSBox(
caPath: caURL.path, caPath: caURL.path,
clientCertificatePath: (configuration.clientCertificate != nil) ? clientCertificateURL.path : nil, clientCertificatePath: (configuration.clientCertificate != nil) ? clientCertificateURL.path : nil,
clientKeyPath: (configuration.clientKey != nil) ? clientKeyURL.path : nil, clientKeyPath: (configuration.clientKey != nil) ? clientKeyURL.path : nil,
checksEKU: configuration.checksEKU ?? false checksEKU: configuration.checksEKU ?? false
) )
if let tlsSecurityLevel = configuration.tlsSecurityLevel {
tls.securityLevel = tlsSecurityLevel
}
negotiationKey.tlsOptional = tls
do { do {
try negotiationKey.tls.start() try negotiationKey.tls.start()
} catch let e { } catch let e {

View File

@ -43,6 +43,8 @@ extern const NSInteger TLSBoxMaxBufferLength;
extern NSString *const TLSBoxPeerVerificationErrorNotification; extern NSString *const TLSBoxPeerVerificationErrorNotification;
extern const NSInteger TLSBoxDefaultSecurityLevel;
// //
// cipher text is safe within NSData // cipher text is safe within NSData
// plain text might be sensitive and must avoid NSData // plain text might be sensitive and must avoid NSData
@ -51,6 +53,8 @@ extern NSString *const TLSBoxPeerVerificationErrorNotification;
// //
@interface TLSBox : NSObject @interface TLSBox : NSObject
@property (nonatomic, assign) NSInteger securityLevel; // TLSBoxDefaultSecurityLevel for default
+ (nullable NSString *)md5ForCertificatePath:(NSString *)path error:(NSError **)error; + (nullable NSString *)md5ForCertificatePath:(NSString *)path error:(NSError **)error;
+ (nullable NSString *)decryptedPrivateKeyFromPath:(NSString *)path passphrase:(NSString *)passphrase error:(NSError **)error; + (nullable NSString *)decryptedPrivateKeyFromPath:(NSString *)path passphrase:(NSString *)passphrase error:(NSError **)error;
+ (nullable NSString *)decryptedPrivateKeyFromPEM:(NSString *)pem passphrase:(NSString *)passphrase error:(NSError **)error; + (nullable NSString *)decryptedPrivateKeyFromPEM:(NSString *)pem passphrase:(NSString *)passphrase error:(NSError **)error;

View File

@ -62,6 +62,8 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
return ok; return ok;
} }
const NSInteger TLSBoxDefaultSecurityLevel = -1;
@interface TLSBox () @interface TLSBox ()
@property (nonatomic, strong) NSString *caPath; @property (nonatomic, strong) NSString *caPath;
@ -180,6 +182,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
self.clientKeyPath = clientKeyPath; self.clientKeyPath = clientKeyPath;
self.checksEKU = checksEKU; self.checksEKU = checksEKU;
self.bufferCipherText = allocate_safely(TLSBoxMaxBufferLength); self.bufferCipherText = allocate_safely(TLSBoxMaxBufferLength);
self.securityLevel = TLSBoxDefaultSecurityLevel;
} }
return self; return self;
} }
@ -205,7 +208,9 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
self.ctx = SSL_CTX_new(TLS_client_method()); self.ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_options(self.ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); SSL_CTX_set_options(self.ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION);
SSL_CTX_set_verify(self.ctx, SSL_VERIFY_PEER, TLSBoxVerifyPeer); SSL_CTX_set_verify(self.ctx, SSL_VERIFY_PEER, TLSBoxVerifyPeer);
SSL_CTX_set_security_level(self.ctx, 0); if (self.securityLevel != TLSBoxDefaultSecurityLevel) {
SSL_CTX_set_security_level(self.ctx, (int)self.securityLevel);
}
if (!SSL_CTX_load_verify_locations(self.ctx, [self.caPath cStringUsingEncoding:NSASCIIStringEncoding], NULL)) { if (!SSL_CTX_load_verify_locations(self.ctx, [self.caPath cStringUsingEncoding:NSASCIIStringEncoding], NULL)) {
ERR_print_errors_fp(stdout); ERR_print_errors_fp(stdout);
if (error) { if (error) {