mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-03-19 13:25:57 +00:00
@@ -28,13 +28,15 @@
|
||||
@interface NSData (SOGoMailSMIME)
|
||||
|
||||
- (NSData *) signUsingCertificateAndKey: (NSData *) theData;
|
||||
- (NSData *) encryptUsingCertificate: (NSData *) theData;
|
||||
- (NSData *) encryptUsingCertificate: (NSData *) theData
|
||||
andAlgos: (NSArray *) theAlgos;
|
||||
- (NSData *) decryptUsingCertificate: (NSData *) theData;
|
||||
- (NGMimeMessage *) messageFromEncryptedDataAndCertificate: (NSData *) theCertificate;
|
||||
- (NSData *) embeddedContent;
|
||||
- (NGMimeMessage *) messageFromOpaqueSignedData;
|
||||
- (NSData *) convertPKCS12ToPEMUsingPassword: (NSString *) thePassword;
|
||||
- (NSData *) signersFromPKCS7;
|
||||
- (NSData *) signersFromCMS;
|
||||
- (NSArray *) algosFromCMS;
|
||||
- (NSDictionary *) certificateDescription;
|
||||
|
||||
@end
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
@@ -27,12 +28,13 @@
|
||||
#import <NGExtensions/NSString+Encoding.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <NGMime/NGMimeType.h>
|
||||
#import <NGMail/NGMimeMessageParser.h>
|
||||
|
||||
#if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS)
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/pem.h>
|
||||
#endif
|
||||
@@ -54,18 +56,18 @@
|
||||
X509 *link = NULL;
|
||||
STACK_OF(X509) *chain = NULL;
|
||||
EVP_PKEY *skey = NULL;
|
||||
PKCS7 *p7 = NULL;
|
||||
CMS_ContentInfo *cms = NULL;
|
||||
BUF_MEM *bptr;
|
||||
|
||||
|
||||
unsigned int len, slen;
|
||||
const char* bytes;
|
||||
const char* sbytes;
|
||||
|
||||
int flags = PKCS7_STREAM | PKCS7_DETACHED | PKCS7_CRLFEOL;
|
||||
|
||||
int flags = CMS_STREAM | CMS_DETACHED | CMS_CRLFEOL;
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
|
||||
bytes = [theData bytes];
|
||||
len = [theData length];
|
||||
tbio = BIO_new_mem_buf((void *)bytes, len);
|
||||
@@ -77,13 +79,13 @@
|
||||
NSLog(@"FATAL: failed to read certificate for signing.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
chain = sk_X509_new_null();
|
||||
while (link = PEM_read_bio_X509_AUX(tbio, NULL, 0, NULL))
|
||||
sk_X509_unshift(chain, link);
|
||||
|
||||
BIO_reset(tbio);
|
||||
|
||||
|
||||
skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
|
||||
|
||||
if (!skey)
|
||||
@@ -91,34 +93,34 @@
|
||||
NSLog(@"FATAL: failed to read private key for signing.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
// We sign
|
||||
sbytes = [self bytes];
|
||||
slen = [self length];
|
||||
sbio = BIO_new_mem_buf((void *)sbytes, slen);
|
||||
p7 = PKCS7_sign(scert, skey, (sk_X509_num(chain) > 0) ? chain : NULL, sbio, flags);
|
||||
cms = CMS_sign(scert, skey, (sk_X509_num(chain) > 0) ? chain : NULL, sbio, flags);
|
||||
|
||||
if (!p7)
|
||||
if (!cms)
|
||||
{
|
||||
NSLog(@"FATAL: failed to sign message.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
// We output
|
||||
obio = BIO_new(BIO_s_mem());
|
||||
SMIME_write_PKCS7(obio, p7, sbio, flags);
|
||||
SMIME_write_CMS(obio, cms, sbio, flags);
|
||||
BIO_get_mem_ptr(obio, &bptr);
|
||||
|
||||
output = [NSData dataWithBytes: bptr->data length: bptr->length];
|
||||
|
||||
cleanup:
|
||||
PKCS7_free(p7);
|
||||
CMS_ContentInfo_free(cms);
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
X509_free(scert);
|
||||
X509_free(scert);
|
||||
BIO_free(tbio);
|
||||
BIO_free(sbio);
|
||||
BIO_free(obio);
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -126,21 +128,25 @@
|
||||
//
|
||||
//
|
||||
- (NSData *) encryptUsingCertificate: (NSData *) theData
|
||||
andAlgos: (NSArray *) theAlgos
|
||||
{
|
||||
NSData *output = NULL;
|
||||
|
||||
BUF_MEM *bptr = NULL;
|
||||
BIO *tbio = NULL, *sbio = NULL, *obio = NULL;
|
||||
X509 *rcert = NULL;
|
||||
PKCS7 *p7 = NULL;
|
||||
CMS_ContentInfo *cms = NULL;
|
||||
STACK_OF(X509) *recips = NULL;
|
||||
|
||||
|
||||
int i;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
|
||||
unsigned int len, slen;
|
||||
const char* bytes;
|
||||
const char* sbytes;
|
||||
|
||||
int flags = PKCS7_STREAM;
|
||||
|
||||
int flags = CMS_STREAM;
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
@@ -162,9 +168,9 @@
|
||||
NSLog(@"FATAL: unable to read certificate for encryption");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
recips = sk_X509_new_null();
|
||||
|
||||
|
||||
if (!recips || !sk_X509_push(recips, rcert))
|
||||
{
|
||||
NSLog(@"FATAL: unable to push certificate into stack");
|
||||
@@ -173,15 +179,70 @@
|
||||
|
||||
rcert = NULL;
|
||||
|
||||
if (theAlgos)
|
||||
{
|
||||
// pick first supported cipher suggested by peer
|
||||
for (i = 0; cipher == NULL && i < [theAlgos count]; i++)
|
||||
{
|
||||
int nid = [[theAlgos objectAtIndex: i] intValue];
|
||||
switch (nid)
|
||||
{
|
||||
// ciphers from RFC8551
|
||||
//No support for AuthEnvelopedData in OpenSSL yet
|
||||
//case NID_chacha20_poly1305:
|
||||
//case NID_aes_256_gcm:
|
||||
//case NID_aes_128_gcm:
|
||||
#ifdef NID_aes_128_cbc
|
||||
case NID_aes_128_cbc:
|
||||
#endif
|
||||
// plus ciphers from RFC5751
|
||||
#ifdef NID_aes_192_cbc
|
||||
case NID_aes_192_cbc:
|
||||
#endif
|
||||
#ifdef NID_aes_256_cbc
|
||||
case NID_aes_256_cbc:
|
||||
#endif
|
||||
#ifdef NID_des_ede3_cbc
|
||||
case NID_des_ede3_cbc:
|
||||
#endif
|
||||
cipher = EVP_get_cipherbynid(nid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// no matching cipher - use default cipher
|
||||
if (cipher == NULL)
|
||||
#ifndef OPENSSL_NO_AES
|
||||
cipher = EVP_aes_128_cbc();
|
||||
#elif !defined(OPENSSL_NO_DES)
|
||||
cipher = EVP_des_ede3_cbc();
|
||||
#else
|
||||
#error "Neither AES nor 3DES available"
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// ATM theAlgos == NULL means we're storing a draft with the writer's own key
|
||||
#ifndef OPENSSL_NO_AES
|
||||
cipher = EVP_aes_128_cbc();
|
||||
#elif !defined(OPENSSL_NO_DES)
|
||||
cipher = EVP_des_ede3_cbc();
|
||||
#else
|
||||
#error "Neither AES nor 3DES available"
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get the bytes to encrypt
|
||||
sbytes = [self bytes];
|
||||
slen = [self length];
|
||||
sbio = BIO_new_mem_buf((void *)sbytes, slen);
|
||||
|
||||
// Encrypt
|
||||
p7 = PKCS7_encrypt(recips, sbio, EVP_des_ede3_cbc(), flags);
|
||||
cms = CMS_encrypt(recips, sbio, cipher, flags);
|
||||
|
||||
if (!p7)
|
||||
if (!cms)
|
||||
{
|
||||
NSLog(@"FATAL: unable to encrypt message");
|
||||
goto cleanup;
|
||||
@@ -189,19 +250,19 @@
|
||||
|
||||
// We output the S/MIME encrypted message
|
||||
obio = BIO_new(BIO_s_mem());
|
||||
if (!SMIME_write_PKCS7(obio, p7, sbio, flags))
|
||||
if (!SMIME_write_CMS(obio, cms, sbio, flags))
|
||||
{
|
||||
NSLog(@"FATAL: unable to write PKCS7 output");
|
||||
NSLog(@"FATAL: unable to write CMS output");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
BIO_get_mem_ptr(obio, &bptr);
|
||||
|
||||
|
||||
output = [NSData dataWithBytes: bptr->data length: bptr->length];
|
||||
|
||||
cleanup:
|
||||
PKCS7_free(p7);
|
||||
X509_free(rcert);
|
||||
CMS_ContentInfo_free(cms);
|
||||
X509_free(rcert);
|
||||
BIO_free(tbio);
|
||||
BIO_free(sbio);
|
||||
BIO_free(obio);
|
||||
@@ -216,16 +277,16 @@
|
||||
{
|
||||
NSData *output = NULL;
|
||||
|
||||
BIO *tbio, *sbio, *obio;
|
||||
BIO *tbio, *sbio = NULL, *obio = NULL;
|
||||
BUF_MEM *bptr;
|
||||
X509 *scert = NULL;
|
||||
EVP_PKEY *skey = NULL;
|
||||
PKCS7 *p7 = NULL;
|
||||
|
||||
CMS_ContentInfo *cms = NULL;
|
||||
|
||||
unsigned int len, slen;
|
||||
const char* bytes;
|
||||
const char* sbytes;
|
||||
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
@@ -241,8 +302,8 @@
|
||||
{
|
||||
NSLog(@"FATAL: could not read certificate for decryption");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BIO_reset(tbio);
|
||||
|
||||
skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
|
||||
@@ -251,15 +312,15 @@
|
||||
{
|
||||
NSLog(@"FATAL: could not read private key for decryption");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sbytes = [self bytes];
|
||||
slen = [self length];
|
||||
sbio = BIO_new_mem_buf((void *)sbytes, slen);
|
||||
|
||||
p7 = SMIME_read_PKCS7(sbio, NULL);
|
||||
cms = SMIME_read_CMS(sbio, NULL);
|
||||
|
||||
if (!p7)
|
||||
if (!cms)
|
||||
{
|
||||
NSLog(@"FATAL: could not read the content to be decrypted");
|
||||
goto cleanup;
|
||||
@@ -267,24 +328,24 @@
|
||||
|
||||
// We output the S/MIME encrypted message
|
||||
obio = BIO_new(BIO_s_mem());
|
||||
|
||||
if (!PKCS7_decrypt(p7, skey, scert, obio, 0))
|
||||
|
||||
if (!CMS_decrypt(cms, skey, scert, NULL, obio, 0))
|
||||
{
|
||||
NSLog(@"FATAL: could not decrypt content");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
BIO_get_mem_ptr(obio, &bptr);
|
||||
|
||||
|
||||
output = [NSData dataWithBytes: bptr->data length: bptr->length];
|
||||
|
||||
cleanup:
|
||||
PKCS7_free(p7);
|
||||
X509_free(scert);
|
||||
CMS_ContentInfo_free(cms);
|
||||
X509_free(scert);
|
||||
BIO_free(sbio);
|
||||
BIO_free(tbio);
|
||||
BIO_free(obio);
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -295,10 +356,10 @@
|
||||
{
|
||||
NGMimeMessageParser *parser;
|
||||
NGMimeMessage *message;
|
||||
NSData *decryptedData;
|
||||
NSData *decryptedData;
|
||||
NGMimeType *contentType;
|
||||
NSString *type, *subtype, *smimetype;
|
||||
|
||||
|
||||
decryptedData = [self decryptUsingCertificate: theCertificate];
|
||||
parser = [[NGMimeMessageParser alloc] init];
|
||||
message = [parser parsePartFromData: decryptedData];
|
||||
@@ -329,15 +390,15 @@
|
||||
{
|
||||
NSData *output = NULL;
|
||||
|
||||
BIO *sbio, *obio;
|
||||
BIO *sbio, *obio = NULL;
|
||||
BUF_MEM *bptr;
|
||||
PKCS7 *p7 = NULL;
|
||||
CMS_ContentInfo *cms = NULL;
|
||||
|
||||
sbio = BIO_new_mem_buf((void *)[self bytes], [self length]);
|
||||
|
||||
p7 = SMIME_read_PKCS7(sbio, NULL);
|
||||
cms = SMIME_read_CMS(sbio, NULL);
|
||||
|
||||
if (!p7)
|
||||
if (!cms)
|
||||
{
|
||||
NSLog(@"FATAL: could not read the signature");
|
||||
goto cleanup;
|
||||
@@ -346,7 +407,7 @@
|
||||
// We output the S/MIME encrypted message
|
||||
obio = BIO_new(BIO_s_mem());
|
||||
|
||||
if (!PKCS7_verify(p7, NULL, NULL, NULL, obio, PKCS7_NOVERIFY|PKCS7_NOSIGS))
|
||||
if (!CMS_verify(cms, NULL, NULL, NULL, obio, CMS_NOVERIFY|CMS_NOSIGS))
|
||||
{
|
||||
NSLog(@"FATAL: could not extract content");
|
||||
goto cleanup;
|
||||
@@ -357,7 +418,7 @@
|
||||
output = [NSData dataWithBytes: bptr->data length: bptr->length];
|
||||
|
||||
cleanup:
|
||||
PKCS7_free(p7);
|
||||
CMS_ContentInfo_free(cms);
|
||||
BIO_free(sbio);
|
||||
BIO_free(obio);
|
||||
|
||||
@@ -388,7 +449,7 @@
|
||||
{
|
||||
NSData *output = NULL;
|
||||
|
||||
BIO *ibio, *obio;
|
||||
BIO *ibio, *obio = NULL;
|
||||
EVP_PKEY *pkey;
|
||||
BUF_MEM *bptr;
|
||||
PKCS12 *p12;
|
||||
@@ -396,7 +457,7 @@
|
||||
|
||||
const char* bytes;
|
||||
int i, len;
|
||||
|
||||
|
||||
STACK_OF(X509) *ca = NULL;
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
@@ -405,7 +466,7 @@
|
||||
bytes = [self bytes];
|
||||
len = [self length];
|
||||
ibio = BIO_new_mem_buf((void *)bytes, len);
|
||||
|
||||
|
||||
p12 = d2i_PKCS12_bio(ibio, NULL);
|
||||
|
||||
if (!p12)
|
||||
@@ -419,7 +480,7 @@
|
||||
NSLog(@"FATAL: could not parse PKCS12 certificate with provided password");
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
// We output everything in PEM
|
||||
obio = BIO_new(BIO_s_mem());
|
||||
|
||||
@@ -433,7 +494,7 @@
|
||||
{
|
||||
PEM_write_bio_X509(obio, cert);
|
||||
}
|
||||
|
||||
|
||||
if (ca && sk_X509_num(ca))
|
||||
{
|
||||
for (i = 0; i < sk_X509_num(ca); i++)
|
||||
@@ -446,46 +507,50 @@
|
||||
|
||||
cleanup:
|
||||
PKCS12_free(p12);
|
||||
BIO_free(ibio);
|
||||
BIO_free(obio);
|
||||
|
||||
BIO_free(ibio);
|
||||
BIO_free(obio);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (NSData *) signersFromPKCS7
|
||||
- (NSData *) signersFromCMS
|
||||
{
|
||||
NSData *output = NULL;
|
||||
|
||||
STACK_OF(X509) *certs = NULL;
|
||||
BIO *ibio, *obio;
|
||||
BIO *ibio, *obio = NULL, *dummybio = NULL;
|
||||
BUF_MEM *bptr;
|
||||
PKCS7 *p7;
|
||||
CMS_ContentInfo *cms;
|
||||
|
||||
const char* bytes;
|
||||
int i, len;
|
||||
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
bytes = [self bytes];
|
||||
len = [self length];
|
||||
ibio = BIO_new_mem_buf((void *)bytes, len);
|
||||
|
||||
p7 = d2i_PKCS7_bio(ibio, NULL);
|
||||
|
||||
if (!p7)
|
||||
cms = d2i_CMS_bio(ibio, NULL);
|
||||
|
||||
if (!cms)
|
||||
{
|
||||
NSLog(@"FATAL: could not read PKCS7 content");
|
||||
NSLog(@"FATAL: could not read CMS content");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
// before calling CMS_get0_signers(), CMS_verify() must be called
|
||||
dummybio = BIO_new(BIO_s_mem());
|
||||
CMS_verify(cms, NULL, NULL, dummybio, NULL, CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY | CMS_NO_CONTENT_VERIFY);
|
||||
ERR_clear_error();
|
||||
|
||||
// We output everything in PEM
|
||||
obio = BIO_new(BIO_s_mem());
|
||||
|
||||
certs = PKCS7_get0_signers(p7, NULL, 0);
|
||||
certs = CMS_get0_signers(cms);
|
||||
if (certs != NULL)
|
||||
{
|
||||
X509 *x;
|
||||
@@ -503,13 +568,93 @@
|
||||
output = [NSData dataWithBytes: bptr->data length: bptr->length];
|
||||
|
||||
cleanup:
|
||||
PKCS7_free(p7);
|
||||
BIO_free(ibio);
|
||||
BIO_free(obio);
|
||||
|
||||
CMS_ContentInfo_free(cms);
|
||||
BIO_free(dummybio);
|
||||
BIO_free(ibio);
|
||||
BIO_free(obio);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Implementation based on "STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)"
|
||||
STACK_OF(X509_ALGOR) *CMS_get_smimecap(CMS_SignerInfo *si)
|
||||
{
|
||||
X509_ATTRIBUTE *attr;
|
||||
ASN1_TYPE *cap;
|
||||
const unsigned char *p;
|
||||
|
||||
attr = CMS_signed_get_attr(si, CMS_signed_get_attr_by_NID(si, NID_SMIMECapabilities, -1));
|
||||
if (!attr)
|
||||
return NULL;
|
||||
cap = X509_ATTRIBUTE_get0_type(attr, 0);
|
||||
if (!cap || (cap->type != V_ASN1_SEQUENCE))
|
||||
return NULL;
|
||||
p = cap->value.sequence->data;
|
||||
return (STACK_OF(X509_ALGOR) *)
|
||||
ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
|
||||
ASN1_ITEM_rptr(X509_ALGORS));
|
||||
}
|
||||
|
||||
- (NSArray *) algosFromCMS
|
||||
{
|
||||
NSMutableArray *algos = [[NSMutableArray alloc] initWithCapacity: 10];
|
||||
|
||||
STACK_OF(CMS_SignerInfo) *signerinfos;
|
||||
BIO *ibio;
|
||||
CMS_ContentInfo *cms;
|
||||
|
||||
const ASN1_OBJECT *paobj;
|
||||
int pptype;
|
||||
int nid;
|
||||
|
||||
const char* bytes;
|
||||
int i, j, len;
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
bytes = [self bytes];
|
||||
len = [self length];
|
||||
ibio = BIO_new_mem_buf((void *)bytes, len);
|
||||
|
||||
cms = d2i_CMS_bio(ibio, NULL);
|
||||
|
||||
if (!cms)
|
||||
{
|
||||
NSLog(@"FATAL: could not read CMS content");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
signerinfos = CMS_get0_SignerInfos(cms);
|
||||
if (signerinfos != NULL)
|
||||
{
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(signerinfos); i++)
|
||||
{
|
||||
CMS_SignerInfo *si = sk_CMS_SignerInfo_value(signerinfos, i);
|
||||
STACK_OF(X509_ALGOR) *smimecap = CMS_get_smimecap(si);
|
||||
|
||||
if (smimecap != NULL)
|
||||
{
|
||||
for (j = 0; j < sk_X509_ALGOR_num(smimecap); j++)
|
||||
{
|
||||
X509_ALGOR_get0(&paobj, &pptype, NULL, sk_X509_ALGOR_value(smimecap, j));
|
||||
nid = OBJ_obj2nid(paobj);
|
||||
// Of all ciphers commonly used for S/MIME only RC2 has a keylength parameter
|
||||
// As RC2 is outdated it's ok to ignore all ciphers with parameter
|
||||
if (nid != NID_undef && pptype == V_ASN1_UNDEF)
|
||||
[algos addObject: [NSNumber numberWithInt: nid]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
CMS_ContentInfo_free(cms);
|
||||
BIO_free(ibio);
|
||||
|
||||
return algos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract usefull information from PEM certificate
|
||||
*/
|
||||
|
||||
@@ -1866,7 +1866,8 @@ static NSString *userAgent = nil;
|
||||
{
|
||||
NGMimeMessageGenerator *generator, *partGenerator;
|
||||
NGMimeMessage *mimeMessage;
|
||||
NSData *certificate, *content;
|
||||
NSData *certificate, *content, *p7s;
|
||||
NSArray *algos;
|
||||
NGMutableHashMap *hashMap;
|
||||
NGMimeMessage *message;
|
||||
NSMutableData *d;
|
||||
@@ -1910,17 +1911,22 @@ static NSString *userAgent = nil;
|
||||
lookupName: @"Contacts"
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
certificate = [[contactFolders certificateForEmail: theRecipient] signersFromPKCS7];
|
||||
p7s = [contactFolders certificateForEmail: theRecipient];
|
||||
certificate = [p7s signersFromCMS];
|
||||
algos = [p7s algosFromCMS];
|
||||
}
|
||||
else
|
||||
certificate = [[self mailAccountFolder] certificate];
|
||||
{
|
||||
certificate = [[self mailAccountFolder] certificate];
|
||||
algos = nil;
|
||||
}
|
||||
|
||||
// We check if we have a valid certificate. We can have nil here coming from [[self mailAccountFolder] certificate].
|
||||
// This can happen if one sends an encrypted mail, but actually never uploaded
|
||||
// a PKCS#12 file to SOGo for his/her own usage and we're trying to save an encrypted
|
||||
// version of the message in the current user's Sent folder
|
||||
if (certificate)
|
||||
content = [content encryptUsingCertificate: certificate];
|
||||
content = [content encryptUsingCertificate: certificate andAlgos: algos];
|
||||
}
|
||||
|
||||
finish_smime:
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
|
||||
if (pkcs7)
|
||||
{
|
||||
data = [[pkcs7 signersFromPKCS7] certificateDescription];
|
||||
data = [[pkcs7 signersFromCMS] certificateDescription];
|
||||
if (data)
|
||||
{
|
||||
response = [self responseWithStatus: 200 andJSONRepresentation: data];
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#endif
|
||||
@@ -101,8 +101,8 @@
|
||||
|
||||
STACK_OF(X509) *certs;
|
||||
X509_STORE *x509Store;
|
||||
BIO *msgBio, *obio;
|
||||
PKCS7 *p7;
|
||||
BIO *msgBio, *obio = NULL;
|
||||
CMS_ContentInfo *cms;
|
||||
int err, i;
|
||||
|
||||
ERR_clear_error();
|
||||
@@ -110,21 +110,25 @@
|
||||
msgBio = BIO_new_mem_buf ((void *) [signedData bytes], [signedData length]);
|
||||
output = NULL;
|
||||
|
||||
p7 = SMIME_read_PKCS7(msgBio, NULL);
|
||||
cms = SMIME_read_CMS(msgBio, NULL);
|
||||
|
||||
certs = NULL;
|
||||
certificates = [NSMutableArray array];
|
||||
emails = [NSMutableArray array];
|
||||
validationMessage = nil;
|
||||
|
||||
if (p7)
|
||||
if (cms)
|
||||
{
|
||||
if (OBJ_obj2nid(p7->type) == NID_pkcs7_signed)
|
||||
if (OBJ_obj2nid(CMS_get0_type(cms)) == NID_pkcs7_signed)
|
||||
{
|
||||
NSString *subject, *issuer;
|
||||
X509 *x;
|
||||
|
||||
certs = p7->d.sign->cert;
|
||||
BIO *dummybio = BIO_new(BIO_s_mem());
|
||||
CMS_verify(cms, NULL, NULL, dummybio, NULL, CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY | CMS_NO_CONTENT_VERIFY);
|
||||
ERR_clear_error();
|
||||
BIO_free(dummybio);
|
||||
certs = CMS_get0_signers(cms);
|
||||
|
||||
for (i = 0; i < sk_X509_num(certs); i++)
|
||||
{
|
||||
@@ -171,7 +175,7 @@
|
||||
x509Store = [self _setupVerify];
|
||||
obio = BIO_new(BIO_s_mem());
|
||||
|
||||
validSignature = (PKCS7_verify(p7, NULL, x509Store, NULL,
|
||||
validSignature = (CMS_verify(cms, NULL, x509Store, NULL,
|
||||
obio, 0) == 1);
|
||||
|
||||
err = ERR_get_error();
|
||||
@@ -214,7 +218,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
PKCS7_free(p7);
|
||||
CMS_ContentInfo_free(cms);
|
||||
BIO_free (msgBio);
|
||||
BIO_free (obio);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS)
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#endif
|
||||
@@ -99,7 +99,7 @@
|
||||
STACK_OF(X509) *certs;
|
||||
X509_STORE *x509Store;
|
||||
BIO *msgBio, *inData;
|
||||
PKCS7 *p7;
|
||||
CMS_ContentInfo *cms;
|
||||
int err, i;
|
||||
|
||||
ERR_clear_error();
|
||||
@@ -112,21 +112,25 @@
|
||||
msgBio = BIO_new_mem_buf ((void *) [signedData bytes], [signedData length]);
|
||||
|
||||
inData = NULL;
|
||||
p7 = SMIME_read_PKCS7(msgBio, &inData);
|
||||
cms = SMIME_read_CMS(msgBio, &inData);
|
||||
|
||||
certs = NULL;
|
||||
certificates = [NSMutableArray array];
|
||||
emails = [NSMutableArray array];
|
||||
validationMessage = nil;
|
||||
|
||||
if (p7)
|
||||
if (cms)
|
||||
{
|
||||
if (OBJ_obj2nid(p7->type) == NID_pkcs7_signed)
|
||||
if (OBJ_obj2nid(CMS_get0_type(cms)) == NID_pkcs7_signed)
|
||||
{
|
||||
NSString *subject, *issuer;
|
||||
X509 *x;
|
||||
|
||||
certs = PKCS7_get0_signers(p7, NULL, 0);
|
||||
BIO *dummybio = BIO_new(BIO_s_mem());
|
||||
CMS_verify(cms, NULL, NULL, dummybio, NULL, CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY | CMS_NO_CONTENT_VERIFY);
|
||||
ERR_clear_error();
|
||||
BIO_free(dummybio);
|
||||
certs = CMS_get0_signers(cms);
|
||||
|
||||
for (i = 0; i < sk_X509_num(certs); i++)
|
||||
{
|
||||
@@ -172,7 +176,7 @@
|
||||
else
|
||||
{
|
||||
x509Store = [self _setupVerify];
|
||||
validSignature = (PKCS7_verify(p7, NULL, x509Store, inData,
|
||||
validSignature = (CMS_verify(cms, NULL, x509Store, inData,
|
||||
NULL, PKCS7_DETACHED) == 1);
|
||||
|
||||
err = ERR_get_error();
|
||||
@@ -205,6 +209,7 @@
|
||||
}
|
||||
|
||||
|
||||
CMS_ContentInfo_free(cms);
|
||||
BIO_free (msgBio);
|
||||
if (inData)
|
||||
BIO_free (inData);
|
||||
|
||||
Reference in New Issue
Block a user