diff --git a/CHANGELOG.md b/CHANGELOG.md index 21b6b03..f0b6454 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Upgrade OpenSSL to 3.2.0. [#336](https://github.com/passepartoutvpn/tunnelkit/issues/336) + ## 6.1.1 (2023-07-06) ### Fixed diff --git a/Package.resolved b/Package.resolved index 37083a4..d411d92 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/passepartoutvpn/openssl-apple", "state": { "branch": null, - "revision": "757c074af45e4f2514fe63f649ccdde966183e90", - "version": "1.1.11700" + "revision": "c15562540646602300df94540765fbe27b6d5474", + "version": "3.2.0" } }, { @@ -24,7 +24,7 @@ "repositoryURL": "https://github.com/passepartoutvpn/wireguard-apple", "state": { "branch": null, - "revision": "73d9152fa0cb661db0348a1ac11dbbf998422a50", + "revision": "57f9babde0fb7567f31a75e943538022f8725f8f", "version": "1.0.17" } } diff --git a/Package.swift b/Package.swift index d9beaa2..de80840 100644 --- a/Package.swift +++ b/Package.swift @@ -39,7 +39,7 @@ let package = Package( // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), .package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver", from: "1.9.0"), - .package(url: "https://github.com/passepartoutvpn/openssl-apple", from: "1.1.11700"), + .package(url: "https://github.com/passepartoutvpn/openssl-apple", from: "3.2.0"), // .package(name: "WireGuardKit", url: "https://git.zx2c4.com/wireguard-apple", .exact("1.0.15-26")), .package(name: "WireGuardKit", url: "https://github.com/passepartoutvpn/wireguard-apple", .exact("1.0.17")) // .package(name: "WireGuardKit", url: "https://github.com/passepartoutvpn/wireguard-apple", .revision("73d9152fa0cb661db0348a1ac11dbbf998422a50")) diff --git a/Sources/CTunnelKitOpenVPNProtocol/CryptoBox.m b/Sources/CTunnelKitOpenVPNProtocol/CryptoBox.m index be04694..9b15c91 100644 --- a/Sources/CTunnelKitOpenVPNProtocol/CryptoBox.m +++ b/Sources/CTunnelKitOpenVPNProtocol/CryptoBox.m @@ -167,18 +167,18 @@ NSParameterAssert(data); unsigned int l = 0; - int code = 1; - HMAC_CTX *ctx = HMAC_CTX_new(); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_CTX_reset(ctx); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Init_ex(ctx, secret, (int)secretLength, EVP_get_digestbyname([digestName cStringUsingEncoding:NSASCIIStringEncoding]), NULL); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(ctx, data, dataLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Final(ctx, hmac, &l); - HMAC_CTX_free(ctx); - + const BOOL success = HMAC(EVP_get_digestbyname([digestName cStringUsingEncoding:NSASCIIStringEncoding]), + secret, + (int)secretLength, + data, + dataLength, + hmac, + &l) != NULL; + *hmacLength = l; - TUNNEL_CRYPTO_RETURN_STATUS(code) + return success; } @end diff --git a/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m b/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m index 30af902..65386a1 100644 --- a/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m +++ b/Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m @@ -35,7 +35,6 @@ // #import -#import #import #import "CryptoCBC.h" @@ -56,10 +55,12 @@ const NSInteger CryptoCBCMaxHMACLength = 100; @property (nonatomic, assign) int hmacKeyLength; @property (nonatomic, assign) int digestLength; +@property (nonatomic, unsafe_unretained) EVP_MAC *mac; +@property (nonatomic, unsafe_unretained) OSSL_PARAM *macParams; @property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxEnc; @property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxDec; -@property (nonatomic, unsafe_unretained) HMAC_CTX *hmacCtxEnc; -@property (nonatomic, unsafe_unretained) HMAC_CTX *hmacCtxDec; +@property (nonatomic, strong) ZeroingData *hmacKeyEnc; +@property (nonatomic, strong) ZeroingData *hmacKeyDec; @property (nonatomic, unsafe_unretained) uint8_t *bufferDecHMAC; @end @@ -92,8 +93,13 @@ const NSInteger CryptoCBCMaxHMACLength = 100; self.cipherCtxEnc = EVP_CIPHER_CTX_new(); self.cipherCtxDec = EVP_CIPHER_CTX_new(); } - self.hmacCtxEnc = HMAC_CTX_new(); - self.hmacCtxDec = HMAC_CTX_new(); + + 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[1] = OSSL_PARAM_construct_end(); + self.macParams = macParams; + self.bufferDecHMAC = allocate_safely(CryptoCBCMaxHMACLength); } return self; @@ -105,8 +111,8 @@ const NSInteger CryptoCBCMaxHMACLength = 100; EVP_CIPHER_CTX_free(self.cipherCtxEnc); EVP_CIPHER_CTX_free(self.cipherCtxDec); } - HMAC_CTX_free(self.hmacCtxEnc); - HMAC_CTX_free(self.hmacCtxDec); + EVP_MAC_free(self.mac); + free(self.macParams); bzero(self.bufferDecHMAC, CryptoCBCMaxHMACLength); free(self.bufferDecHMAC); @@ -138,8 +144,7 @@ const NSInteger CryptoCBCMaxHMACLength = 100; EVP_CipherInit(self.cipherCtxEnc, self.cipher, cipherKey.bytes, NULL, 1); } - HMAC_CTX_reset(self.hmacCtxEnc); - HMAC_Init_ex(self.hmacCtxEnc, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); + self.hmacKeyEnc = [[ZeroingData alloc] initWithBytes:hmacKey.bytes count:self.hmacKeyLength]; } - (BOOL)encryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength flags:(const CryptoFlags * _Nullable)flags error:(NSError * _Nullable __autoreleasing * _Nullable)error @@ -147,7 +152,7 @@ const NSInteger CryptoCBCMaxHMACLength = 100; uint8_t *outIV = dest + self.digestLength; uint8_t *outEncrypted = dest + self.digestLength + self.cipherIVLength; int l1 = 0, l2 = 0; - unsigned int l3 = 0; + size_t l3 = 0; int code = 1; if (self.cipher) { @@ -171,10 +176,12 @@ const NSInteger CryptoCBCMaxHMACLength = 100; l1 = (int)length; } - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Init_ex(self.hmacCtxEnc, NULL, 0, NULL, NULL); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(self.hmacCtxEnc, outIV, l1 + l2 + self.cipherIVLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Final(self.hmacCtxEnc, dest, &l3); - + 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); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_final(ctx, dest, &l3, self.digestLength); + EVP_MAC_CTX_free(ctx); + *destLength = l1 + l2 + self.cipherIVLength + self.digestLength; TUNNEL_CRYPTO_RETURN_STATUS(code) @@ -199,21 +206,22 @@ const NSInteger CryptoCBCMaxHMACLength = 100; EVP_CipherInit(self.cipherCtxDec, self.cipher, cipherKey.bytes, NULL, 0); } - HMAC_CTX_reset(self.hmacCtxDec); - HMAC_Init_ex(self.hmacCtxDec, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); + self.hmacKeyDec = [[ZeroingData alloc] initWithBytes:hmacKey.bytes count:self.hmacKeyLength]; } - (BOOL)decryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength flags:(const CryptoFlags * _Nullable)flags error:(NSError * _Nullable __autoreleasing * _Nullable)error { const uint8_t *iv = bytes + self.digestLength; const uint8_t *encrypted = bytes + self.digestLength + self.cipherIVLength; - int l1 = 0, l2 = 0; + size_t l1 = 0, l2 = 0; int code = 1; - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Init_ex(self.hmacCtxDec, NULL, 0, NULL, NULL); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(self.hmacCtxDec, bytes + self.digestLength, length - self.digestLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Final(self.hmacCtxDec, self.bufferDecHMAC, (unsigned *)&l1); - + 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); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_final(ctx, self.bufferDecHMAC, &l1, self.digestLength); + EVP_MAC_CTX_free(ctx); + if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, self.digestLength) != 0) { if (error) { *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoHMAC); @@ -223,8 +231,8 @@ const NSInteger CryptoCBCMaxHMACLength = 100; if (self.cipher) { TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_CipherInit(self.cipherCtxDec, NULL, NULL, iv, -1); - TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_CipherUpdate(self.cipherCtxDec, dest, &l1, encrypted, (int)length - self.digestLength - self.cipherIVLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_CipherFinal_ex(self.cipherCtxDec, dest + l1, &l2); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_CipherUpdate(self.cipherCtxDec, dest, (int *)&l1, encrypted, (int)length - self.digestLength - self.cipherIVLength); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_CipherFinal_ex(self.cipherCtxDec, dest + l1, (int *)&l2); *destLength = l1 + l2; } else { @@ -239,13 +247,15 @@ const NSInteger CryptoCBCMaxHMACLength = 100; - (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length flags:(const CryptoFlags * _Nullable)flags error:(NSError * _Nullable __autoreleasing * _Nullable)error { - int l1 = 0; + size_t l1 = 0; int code = 1; - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Init_ex(self.hmacCtxDec, NULL, 0, NULL, NULL); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(self.hmacCtxDec, bytes + self.digestLength, length - self.digestLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Final(self.hmacCtxDec, self.bufferDecHMAC, (unsigned *)&l1); - + 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); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_final(ctx, self.bufferDecHMAC, &l1, self.digestLength); + EVP_MAC_CTX_free(ctx); + if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, self.digestLength) != 0) { if (error) { *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoHMAC); diff --git a/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m b/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m index ce6de15..6a8d093 100644 --- a/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m +++ b/Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m @@ -24,7 +24,6 @@ // #import -#import #import "CryptoCTR.h" #import "CryptoMacros.h" @@ -43,10 +42,12 @@ static const NSInteger CryptoCTRTagLength = 32; @property (nonatomic, assign) int cipherIVLength; @property (nonatomic, assign) int hmacKeyLength; +@property (nonatomic, unsafe_unretained) EVP_MAC *mac; +@property (nonatomic, unsafe_unretained) OSSL_PARAM *macParams; @property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxEnc; @property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxDec; -@property (nonatomic, unsafe_unretained) HMAC_CTX *hmacCtxEnc; -@property (nonatomic, unsafe_unretained) HMAC_CTX *hmacCtxDec; +@property (nonatomic, strong) ZeroingData *hmacKeyEnc; +@property (nonatomic, strong) ZeroingData *hmacKeyDec; @property (nonatomic, unsafe_unretained) uint8_t *bufferDecHMAC; @end @@ -73,8 +74,13 @@ static const NSInteger CryptoCTRTagLength = 32; self.cipherCtxEnc = EVP_CIPHER_CTX_new(); self.cipherCtxDec = EVP_CIPHER_CTX_new(); - self.hmacCtxEnc = HMAC_CTX_new(); - self.hmacCtxDec = HMAC_CTX_new(); + + 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[1] = OSSL_PARAM_construct_end(); + self.macParams = macParams; + self.bufferDecHMAC = allocate_safely(CryptoCTRTagLength); } return self; @@ -84,8 +90,8 @@ static const NSInteger CryptoCTRTagLength = 32; { EVP_CIPHER_CTX_free(self.cipherCtxEnc); EVP_CIPHER_CTX_free(self.cipherCtxDec); - HMAC_CTX_free(self.hmacCtxEnc); - HMAC_CTX_free(self.hmacCtxDec); + EVP_MAC_free(self.mac); + free(self.macParams); bzero(self.bufferDecHMAC, CryptoCTRTagLength); free(self.bufferDecHMAC); @@ -119,8 +125,7 @@ static const NSInteger CryptoCTRTagLength = 32; EVP_CIPHER_CTX_reset(self.cipherCtxEnc); EVP_CipherInit(self.cipherCtxEnc, self.cipher, cipherKey.bytes, NULL, 1); - HMAC_CTX_reset(self.hmacCtxEnc); - HMAC_Init_ex(self.hmacCtxEnc, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); + self.hmacKeyEnc = [[ZeroingData alloc] initWithBytes:hmacKey.bytes count:self.hmacKeyLength]; } - (BOOL)encryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength flags:(const CryptoFlags * _Nullable)flags error:(NSError * _Nullable __autoreleasing * _Nullable)error @@ -129,14 +134,16 @@ static const NSInteger CryptoCTRTagLength = 32; uint8_t *outEncrypted = dest + CryptoCTRTagLength; int l1 = 0, l2 = 0; - unsigned int l3 = 0; + size_t l3 = 0; int code = 1; - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Init_ex(self.hmacCtxEnc, NULL, 0, NULL, NULL); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(self.hmacCtxEnc, flags->ad, flags->adLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(self.hmacCtxEnc, bytes, length); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Final(self.hmacCtxEnc, dest, &l3); - + 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, flags->ad, flags->adLength); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, bytes, length); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_final(ctx, dest, &l3, self.digestLength); + EVP_MAC_CTX_free(ctx); + NSAssert(l3 == CryptoCTRTagLength, @"Incorrect digest size"); TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_CipherInit(self.cipherCtxEnc, NULL, NULL, dest, -1); @@ -165,8 +172,7 @@ static const NSInteger CryptoCTRTagLength = 32; EVP_CIPHER_CTX_reset(self.cipherCtxDec); EVP_CipherInit(self.cipherCtxDec, self.cipher, cipherKey.bytes, NULL, 0); - HMAC_CTX_reset(self.hmacCtxDec); - HMAC_Init_ex(self.hmacCtxDec, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); + self.hmacKeyDec = [[ZeroingData alloc] initWithBytes:hmacKey.bytes count:self.hmacKeyLength]; } - (BOOL)decryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength flags:(const CryptoFlags * _Nullable)flags error:(NSError * _Nullable __autoreleasing * _Nullable)error @@ -177,7 +183,7 @@ static const NSInteger CryptoCTRTagLength = 32; const uint8_t *iv = bytes; const uint8_t *encrypted = bytes + CryptoCTRTagLength; int l1 = 0, l2 = 0; - unsigned int l3 = 0; + size_t l3 = 0; int code = 1; TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_CipherInit(self.cipherCtxDec, NULL, NULL, iv, -1); @@ -186,11 +192,13 @@ static const NSInteger CryptoCTRTagLength = 32; *destLength = l1 + l2; - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Init_ex(self.hmacCtxDec, NULL, 0, NULL, NULL); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(self.hmacCtxDec, flags->ad, flags->adLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Update(self.hmacCtxDec, dest, *destLength); - TUNNEL_CRYPTO_TRACK_STATUS(code) HMAC_Final(self.hmacCtxDec, self.bufferDecHMAC, &l3); - + 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, flags->ad, flags->adLength); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, dest, *destLength); + TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_final(ctx, self.bufferDecHMAC, &l3, self.digestLength); + EVP_MAC_CTX_free(ctx); + NSAssert(l3 == CryptoCTRTagLength, @"Incorrect digest size"); if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, CryptoCTRTagLength) != 0) { diff --git a/Sources/CTunnelKitOpenVPNProtocol/TLSBox.m b/Sources/CTunnelKitOpenVPNProtocol/TLSBox.m index 91fb3aa..11d372f 100644 --- a/Sources/CTunnelKitOpenVPNProtocol/TLSBox.m +++ b/Sources/CTunnelKitOpenVPNProtocol/TLSBox.m @@ -406,7 +406,7 @@ static BIO *create_BIO_from_PEM(NSString *pem) { - (BOOL)verifyEKUWithSSL:(SSL *)ssl { - X509 *cert = SSL_get_peer_certificate(self.ssl); + X509 *cert = SSL_get1_peer_certificate(self.ssl); if (!cert) { return NO; } @@ -454,7 +454,7 @@ static BIO *create_BIO_from_PEM(NSString *pem) { - (BOOL)verifySANHostWithSSL:(SSL *)ssl { - X509 *cert = SSL_get_peer_certificate(self.ssl); + X509 *cert = SSL_get1_peer_certificate(self.ssl); if (!cert) { return NO; }