Skip to content

Commit 0fb21e4

Browse files
added X509_verify(cert, serverPubKey) (#3861)
* added X509_verify(cert, serverPubKey) Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com> * cleaning Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com> --------- Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
1 parent f38a79e commit 0fb21e4

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

iOSClient/Networking/E2EE/NCEndToEndEncryption.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
- (NSString *)encryptPrivateKey:(NSString *)userId directory: (NSString *)directory passphrase:(NSString *)passphrase privateKey:(NSString **)privateKey;
2121
- (NSData *)decryptPrivateKey:(NSString *)privateKey passphrase:(NSString *)passphrase;
2222

23+
// Verify X.509 certificate
24+
- (BOOL)verifyCertificate:(NSString *)certificate PublicKey:(NSString *)publicKey;
25+
2326
// Encrypt / Decrypt file material
2427

2528
- (NSString *)encryptPayloadFile:(NSData *)encrypted key:(NSString *)key;

iOSClient/Networking/E2EE/NCEndToEndEncryption.m

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,59 @@ - (BOOL)saveP12WithCert:(X509 *)x509 key:(EVP_PKEY *)pkey directory:(NSString *)
314314
return YES;
315315
}
316316

317+
#
318+
#pragma mark - Verify X.509 certificate
319+
#
320+
321+
// This method verifies that the provided X.509 certificate (issued by the server)
322+
// was actually signed using the server's own public key.
323+
- (BOOL)verifyCertificate:(NSString *)certificate PublicKey:(NSString *)publicKey
324+
{
325+
BOOL success = NO;
326+
BIO *certBio = NULL;
327+
BIO *pubBio = NULL;
328+
X509 *cert = NULL;
329+
EVP_PKEY *serverPubKey = NULL;
330+
331+
// Convert NSStrings to UTF-8 data buffers
332+
NSData *certData = [certificate dataUsingEncoding:NSUTF8StringEncoding];
333+
NSData *pubData = [publicKey dataUsingEncoding:NSUTF8StringEncoding];
334+
if (certData.length == 0 || pubData.length == 0) {
335+
return NO;
336+
}
337+
338+
// Create BIOs from memory buffers
339+
certBio = BIO_new_mem_buf((void *)certData.bytes, (int)certData.length);
340+
pubBio = BIO_new_mem_buf((void *)pubData.bytes, (int)pubData.length);
341+
if (!certBio || !pubBio) {
342+
goto cleanup;
343+
}
344+
345+
// Read X.509 certificate from PEM text
346+
cert = PEM_read_bio_X509(certBio, NULL, NULL, NULL);
347+
if (!cert) {
348+
goto cleanup;
349+
}
350+
351+
// Read public key from PEM text
352+
serverPubKey = PEM_read_bio_PUBKEY(pubBio, NULL, NULL, NULL);
353+
if (!serverPubKey) {
354+
goto cleanup;
355+
}
356+
357+
// Verify that the certificate was signed using this public key
358+
int verifyResult = X509_verify(cert, serverPubKey);
359+
success = (verifyResult == 1);
360+
361+
cleanup:
362+
if (serverPubKey) EVP_PKEY_free(serverPubKey);
363+
if (cert) X509_free(cert);
364+
if (certBio) BIO_free(certBio);
365+
if (pubBio) BIO_free(pubBio);
366+
367+
return success;
368+
}
369+
317370
#
318371
#pragma mark - Create CSR & Encrypt/Decrypt Private Key
319372
#

iOSClient/Settings/E2EE/NCEndToEndInitialize.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,23 @@ class NCEndToEndInitialize: NSObject {
165165
}
166166
} completion: { account, publicKey, _, error in
167167
if error == .success, let publicKey {
168+
169+
// Verify Certificate
170+
var verifyCertificate: Bool = false
171+
if let certificate = NCPreferences().getEndToEndCertificate(account: account) {
172+
verifyCertificate = NCEndToEndEncryption.shared().verifyCertificate(certificate, publicKey: publicKey)
173+
}
174+
if verifyCertificate == false {
175+
let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "Serious internal error to verify certificate")
176+
NCContentPresenter().messageNotification("E2E verify certificate server", error: error, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, priority: .max)
177+
return
178+
}
179+
168180
NCPreferences().setEndToEndPublicKey(account: account, publicKey: publicKey)
169181
NCManageDatabase.shared.clearTablesE2EE(account: account)
182+
170183
self.delegate?.endToEndInitializeSuccess(metadata: self.metadata)
184+
171185
} else if error != .success {
172186
switch error.errorCode {
173187
case NCGlobal.shared.errorBadRequest:
@@ -259,6 +273,16 @@ class NCEndToEndInitialize: NSObject {
259273
} completion: { account, publicKey, _, error in
260274
if error == .success, let publicKey {
261275

276+
var verifyCertificate: Bool = false
277+
if let certificate = NCPreferences().getEndToEndCertificate(account: account) {
278+
verifyCertificate = NCEndToEndEncryption.shared().verifyCertificate(certificate, publicKey: publicKey)
279+
}
280+
if verifyCertificate == false {
281+
let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "Serious internal error to verify certificate")
282+
NCContentPresenter().messageNotification("E2E verify certificate server", error: error, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, priority: .max)
283+
return
284+
}
285+
262286
NCPreferences().setEndToEndPublicKey(account: account, publicKey: publicKey)
263287
NCManageDatabase.shared.clearTablesE2EE(account: account)
264288

0 commit comments

Comments
 (0)