Use OpenSSL 3 (#347)

- Replace deprecated peer cert calls
- Use atomic HMAC
- Upgrade HMAC to EVP_MAC
This commit is contained in:
Davide De Rosa 2023-12-13 21:17:38 +01:00 committed by GitHub
parent 071b6e22ee
commit f56dfa313c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 66 deletions

View File

@ -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

View File

@ -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"
}
}

View File

@ -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"))

View File

@ -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

View File

@ -35,7 +35,6 @@
//
#import <openssl/evp.h>
#import <openssl/hmac.h>
#import <openssl/rand.h>
#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);

View File

@ -24,7 +24,6 @@
//
#import <openssl/evp.h>
#import <openssl/hmac.h>
#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) {

View File

@ -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;
}