#3125: check s/mime certificate gebfore storing it

This commit is contained in:
Hivert Quentin committed 2026-11-10 17:09:46 +01:00
1 parent 76d75de17b
commit 109c998391
4 files changed
+57 -5

No files matched your search

@@ -2503,6 +2503,18 @@ Defaults to `NO` when unset.
|Parameter used to enable S/MIME certificate management from the account editor of the
preferences window.
When a S/MIME signed message is displayed, the sender's certificate is
saved in the matching contact of the user's address books (and replaces any
existing one) only if the signature is valid and every signer certificate
is issued for the sender's email address. A signature is valid only if the
signer certificate chains to a certificate authority trusted by the system
(OpenSSL default CA store, for example `/etc/ssl/certs`). Certificates that
are self-signed or issued by a private CA are therefore not imported unless
that CA is added to the system trust store (for example in
`/usr/local/share/ca-certificates` followed by `update-ca-certificates` on
Debian/Ubuntu). Note that some distributions only ship the CAs trusted for
TLS servers, so the root CAs dedicated to S/MIME may also need to be added.
Defaults to `YES` when unset.
|U |SOGoSelectedAddressBook
@@ -30,11 +30,13 @@
{
BOOL processed;
BOOL validSignature;
BOOL signersMatchSender;
NSMutableArray *certificates;
NSString *validationMessage;
}
- (BOOL) validSignature;
- (BOOL) signersMatchSender;
- (NSString *) validationMessage;
- (NSArray *) smimeCertificates;
- (NSDictionary *) certificateForSubject: (NSString *) subject
+35 -3
View File
@@ -94,8 +94,8 @@
- (void) _processMessage
{
NSData *signedData;
NSMutableArray *emails;
NSMutableArray *emails, *signersEmails;
STACK_OF(X509) *certs;
X509_STORE *x509Store;
BIO *msgBio, *inData;
@@ -117,6 +117,8 @@
certs = NULL;
certificates = [NSMutableArray array];
emails = [NSMutableArray array];
signersEmails = [NSMutableArray array];
signersMatchSender = NO;
validationMessage = nil;
if (cms)
@@ -138,13 +140,21 @@
char p[1024];
int j;
STACK_OF(OPENSSL_STRING) *emlst;
NSMutableArray *signerEmails;
NSString *email;
x = sk_X509_value(certs, i);
signerEmails = [NSMutableArray array];
emlst = X509_get1_email(x);
for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
[emails addObject: [[NSString stringWithUTF8String: sk_OPENSSL_STRING_value(emlst, j)] lowercaseString]];
{
email = [[NSString stringWithUTF8String: sk_OPENSSL_STRING_value(emlst, j)] lowercaseString];
[emails addObject: email];
[signerEmails addObject: email];
}
X509_email_free(emlst);
[signersEmails addObject: signerEmails];
memset(p, 0, 1024);
buf = BIO_new(BIO_s_mem());
@@ -227,6 +237,15 @@
{
validationMessage = [self labelForKey: @"Message is signed but the certificate doesn't match the sender email address"];
}
// Every signer certificate must be issued for the sender address
if ([senderAddress length] && [signersEmails count])
{
signersMatchSender = YES;
for (i = 0; i < [signersEmails count]; i++)
if (![[signersEmails objectAtIndex: i] containsObject: senderAddress])
signersMatchSender = NO;
}
}
else if (!validationMessage)
{
@@ -244,6 +263,14 @@
return validSignature;
}
- (BOOL) signersMatchSender
{
if (!processed)
[self _processMessage];
return signersMatchSender;
}
- (NSDictionary *) certificateForSubject: (NSString *) subject
andIssuer: (NSString *) issuer
withEmails: (NSArray *) emails
@@ -283,6 +310,11 @@
return NO;
}
- (BOOL) signersMatchSender
{
return NO;
}
- (NSString *) validationMessage
{
return nil;
+8 -2
View File
@@ -54,6 +54,7 @@
#import <MailPartViewers/UIxMailRenderingContext.h> // cyclic
#import <MailPartViewers/UIxMailSizeFormatter.h>
#import <MailPartViewers/UIxMailPartViewer.h>
#import <MailPartViewers/UIxMailPartSignedViewer.h>
#import "WOContext+UIxMailer.h"
#import "UIxMailFormatter.h"
@@ -244,11 +245,16 @@ static NSString *mailETag = nil;
// If we are looking at a S/MIME signed mail which wasn't sent
// by our actual active user, we update the certificate of that
// sender in the user's address book
// sender in the user's address book. Only do so if the signature
// is valid (trusted chain) and every signer certificate is issued
// for the sender address.
from = [[[[self clientObject] fromEnvelopeAddresses] lastObject] baseEMail];
if (![[context activeUser] hasEmail: from] &&
[[self clientObject] isSigned])
[[self clientObject] isSigned] &&
[viewer isKindOfClass: NSClassFromString(@"UIxMailPartSignedViewer")] &&
[viewer validSignature] &&
[viewer signersMatchSender])
{
SOGoContactFolders *contactFolders;
NSData *p7s;