Merge pull request #98 from keeshux/customize-security-level
Customize security level
This commit is contained in:
commit
977ff7e573
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue