diff --git a/CHANGELOG.md b/CHANGELOG.md index e1c7c2d7..d8c9be71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- OpenVPN: HMAC breaking due to dangling OSSL_PARAM. [#405](https://github.com/passepartoutvpn/tunnelkit/pull/405) - OpenVPN: Bad error mapping. [#404](https://github.com/passepartoutvpn/tunnelkit/pull/404) ## 6.3.1 (2024-01-05) diff --git a/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m b/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m index 65386a1a..b88b60f2 100644 --- a/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m +++ b/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m @@ -50,6 +50,8 @@ @interface CryptoCBC () @property (nonatomic, unsafe_unretained) const EVP_CIPHER *cipher; @property (nonatomic, unsafe_unretained) const EVP_MD *digest; +@property (nonatomic, unsafe_unretained) const char *utfCipherName; +@property (nonatomic, unsafe_unretained) const char *utfDigestName; @property (nonatomic, assign) int cipherKeyLength; @property (nonatomic, assign) int cipherIVLength; @property (nonatomic, assign) int hmacKeyLength; @@ -75,10 +77,14 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString * self = [super init]; if (self) { if (cipherName) { - self.cipher = EVP_get_cipherbyname([cipherName cStringUsingEncoding:NSASCIIStringEncoding]); + self.utfCipherName = calloc([cipherName length] + 1, sizeof(char)); + strncpy(self.utfCipherName, [cipherName UTF8String], [cipherName length]); + self.cipher = EVP_get_cipherbyname(self.utfCipherName); NSAssert(self.cipher, @"Unknown cipher '%@'", cipherName); } - self.digest = EVP_get_digestbyname([digestName cStringUsingEncoding:NSASCIIStringEncoding]); + self.utfDigestName = calloc([digestName length] + 1, sizeof(char)); + strncpy(self.utfDigestName, [digestName UTF8String], [digestName length]); + self.digest = EVP_get_digestbyname(self.utfDigestName); NSAssert(self.digest, @"Unknown digest '%@'", digestName); if (cipherName) { @@ -96,7 +102,7 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString * self.mac = EVP_MAC_fetch(NULL, "HMAC", NULL); OSSL_PARAM *macParams = calloc(2, sizeof(OSSL_PARAM)); - macParams[0] = OSSL_PARAM_construct_utf8_string("digest", (char *)[digestName cStringUsingEncoding:NSASCIIStringEncoding], 0); + macParams[0] = OSSL_PARAM_construct_utf8_string("digest", self.utfDigestName, 0); macParams[1] = OSSL_PARAM_construct_end(); self.macParams = macParams; @@ -115,7 +121,12 @@ - (void)dealloc free(self.macParams); bzero(self.bufferDecHMAC, CryptoCBCMaxHMACLength); free(self.bufferDecHMAC); - + + if (self.utfCipherName) { + free(self.utfCipherName); + } + free(self.utfDigestName); + self.cipher = NULL; self.digest = NULL; } @@ -175,7 +186,6 @@ - (BOOL)encryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8 memcpy(outEncrypted, bytes, length); l1 = (int)length; } - EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(self.mac); TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_init(ctx, self.hmacKeyEnc.bytes, self.hmacKeyEnc.count, self.macParams); TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, outIV, l1 + l2 + self.cipherIVLength); @@ -215,7 +225,7 @@ - (BOOL)decryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8 const uint8_t *encrypted = bytes + self.digestLength + self.cipherIVLength; size_t l1 = 0, l2 = 0; int code = 1; - + EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(self.mac); TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_init(ctx, self.hmacKeyDec.bytes, self.hmacKeyDec.count, self.macParams); TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, bytes + self.digestLength, length - self.digestLength); @@ -249,7 +259,7 @@ - (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length flags:(const { size_t l1 = 0; int code = 1; - + EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(self.mac); TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_init(ctx, self.hmacKeyDec.bytes, self.hmacKeyDec.count, self.macParams); TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, bytes + self.digestLength, length - self.digestLength); diff --git a/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m b/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m index 6a8d0936..d37624e3 100644 --- a/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m +++ b/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m @@ -38,6 +38,8 @@ @interface CryptoCTR () @property (nonatomic, unsafe_unretained) const EVP_CIPHER *cipher; @property (nonatomic, unsafe_unretained) const EVP_MD *digest; +@property (nonatomic, unsafe_unretained) const char *utfCipherName; +@property (nonatomic, unsafe_unretained) const char *utfDigestName; @property (nonatomic, assign) int cipherKeyLength; @property (nonatomic, assign) int cipherIVLength; @property (nonatomic, assign) int hmacKeyLength; @@ -61,9 +63,14 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString * self = [super init]; if (self) { - self.cipher = EVP_get_cipherbyname([cipherName cStringUsingEncoding:NSASCIIStringEncoding]); + self.utfCipherName = calloc([cipherName length] + 1, sizeof(char)); + strncpy(self.utfCipherName, [cipherName UTF8String], [cipherName length]); + self.cipher = EVP_get_cipherbyname(self.utfCipherName); NSAssert(self.cipher, @"Unknown cipher '%@'", cipherName); - self.digest = EVP_get_digestbyname([digestName cStringUsingEncoding:NSASCIIStringEncoding]); + + self.utfDigestName = calloc([digestName length] + 1, sizeof(char)); + strncpy(self.utfDigestName, [digestName UTF8String], [digestName length]); + self.digest = EVP_get_digestbyname(self.utfDigestName); NSAssert(self.digest, @"Unknown digest '%@'", digestName); self.cipherKeyLength = EVP_CIPHER_key_length(self.cipher); @@ -77,7 +84,7 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString * self.mac = EVP_MAC_fetch(NULL, "HMAC", NULL); OSSL_PARAM *macParams = calloc(2, sizeof(OSSL_PARAM)); - macParams[0] = OSSL_PARAM_construct_utf8_string("digest", (char *)[digestName cStringUsingEncoding:NSASCIIStringEncoding], 0); + macParams[0] = OSSL_PARAM_construct_utf8_string("digest", self.utfDigestName, 0); macParams[1] = OSSL_PARAM_construct_end(); self.macParams = macParams; @@ -94,7 +101,10 @@ - (void)dealloc free(self.macParams); bzero(self.bufferDecHMAC, CryptoCTRTagLength); free(self.bufferDecHMAC); - + + free(self.utfCipherName); + free(self.utfDigestName); + self.cipher = NULL; self.digest = NULL; }