Question:
With smime message we have 8 type:
1/ Detached signature message without signing cert inside
2/ Detached signature message with signing cert inside
3/ Opaque signature message without signing cert inside
4/ Opaque signature message with signing cert inside
5/ Encrypt Detached signature message without signing cert inside
6/ Encrypt Detached signature message with signing cert inside
7/ Encrypt Opaque signature message without signing cert inside
8/ Encrypt Opaque signature message with signing cert inside
I try to parse all of them using chilkasoft, this is my code (IOS):
(MimeInfo )decryptMime:(NSString )mimeText ownerAccount:(MailAccount )account signatureCertificate:(PublicCertificate ) signatureCertificate error : (NSError * __autoreleasing *) error {
BOOL isEncrypted = NO;
BOOL isSigned = NO;
BOOL isPassVerify = NO;
NSMutableArray *signingCerts = [NSMutableArray array];
CkoMime *mime = [[CkoMime alloc] init];
if (![mime UnlockComponent: UNLOCK_STRING]) {
if (error) {
*error = [[NSError alloc] initWithDomain:SMIME code:0 userInfo:@{NSLocalizedDescriptionKey : @"Unlock Fail"}];
}
return [[MimeInfo alloc] initWithPlainText:nil html:nil archieveAt:nil attachments:nil isSigned:isSigned isEncrypted:isEncrypted isPassVerify:NO signingCertificate:nil];
}
if (![mime LoadMime:mimeText]) {
if (error) {
*error = [[NSError alloc] initWithDomain:SMIME_DECRYPT_DOMAIN code:0 userInfo:@{NSLocalizedDescriptionKey : @"Wrong Mime"}];
}
return [[MimeInfo alloc] initWithPlainText:nil html:nil archieveAt:nil attachments:nil isSigned:isSigned isEncrypted:isEncrypted isPassVerify:NO signingCertificate:nil];
}
NSString *archiveAt = [mime GetHeaderField:ARCHIEVED_AT];
if (mime.IsSigned) {
isSigned = YES;
}
if (mime.IsEncrypted) {
isEncrypted = YES;
}
if (isEncrypted) {
if (!account.certificate) {
if (error) {
*error = [[NSError alloc] initWithDomain:SMIME_DECRYPT_DOMAIN code:1 userInfo:@{NSLocalizedDescriptionKey : @"No decrypted certificate found"}];
}
return [[MimeInfo alloc] initWithPlainText:nil html:nil archieveAt:nil attachments:nil isSigned:isSigned isEncrypted:isEncrypted isPassVerify:NO signingCertificate:nil];
}
CkoCert *encryptedCert = [[CkoCert alloc] init];
if (![encryptedCert LoadPfxData:account.certificate.pfx password:account.certificate.password]) {
if (error) {
*error = [[NSError alloc] initWithDomain:SMIME_DECRYPT_DOMAIN code:2 userInfo:@{NSLocalizedDescriptionKey : @"Wrong decrypted certificate"}];
}
return [[MimeInfo alloc] initWithPlainText:nil html:nil archieveAt:nil attachments:nil isSigned:isSigned isEncrypted:isEncrypted isPassVerify:NO signingCertificate:nil];
}
if (![mime DecryptUsingCert:encryptedCert]) {
if (error) {
*error = [[NSError alloc] initWithDomain:SMIME_DECRYPT_DOMAIN code:3 userInfo:@{NSLocalizedDescriptionKey : @"Decrypt fail"}];
}
return [[MimeInfo alloc] initWithPlainText:nil html:nil archieveAt:nil attachments:nil isSigned:isSigned isEncrypted:isEncrypted isPassVerify:NO signingCertificate:nil];
}
for (int i = 0; i < [mime NumSignerCerts].intValue; i ++) {
CkoCert *cert = [mime GetSignerCert:[NSNumber numberWithInt:i]];
NSData *data = [cert ExportCertDer];
if (signatureCertificate && !isPassVerify) {
if ([data isEqualToData:signatureCertificate.cert]) {
isPassVerify = YES;
}
}
[signingCerts addObject:data];
}
isSigned = signingCerts.count > 0;
}
if (mime.IsSigned) {
isSigned = YES;
CkoCert *cert = nil;
if (signatureCertificate) {
cert =[[CkoCert alloc] init];
if ([cert LoadFromBinary:signatureCertificate.cert]) {
[mime SetVerifyCert:cert];
}
}
if (![mime Verify]) {
if (error) {
*error = [[NSError alloc] initWithDomain:SMIME_DECRYPT_DOMAIN code:4 userInfo:@{NSLocalizedDescriptionKey : @"No signing certificate found"}];
}
}
isPassVerify = NO;
for (int i = 0; i < [mime NumSignerCerts].intValue; i ++) {
CkoCert *cert = [mime GetSignerCert:[NSNumber numberWithInt:i]];
NSData *data = [cert ExportCertDer];
if (signatureCertificate && !isPassVerify) {
if ([data isEqualToData:signatureCertificate.cert]) {
isPassVerify = YES;
}
}
[signingCerts addObject:data];
}
}
NSLog(@"%@", [mime GetMime]);
NSArray *certs = nil;
if (signingCerts.count > 0) {
certs = [NSArray arrayWithArray:signingCerts];
}
MimeInfo *result = [self parseFromDecryptMessageCkoMine:mime];
[result setIsSigned:isSigned isEncrypted:isEncrypted isPassVerify:isPassVerify signingCerts:certs archivedAt:archiveAt];
return result;
}
Result
1/ If I have the private encrypted certificate and public signing certificate. I can get the content and verify and trusted of all the messages
2/ If I have the private encrypted certificate only. I can't either get the content nor verify the trusted of message 3,5,7
3/ If I don't have any certificate. I can get the content of message 1,2,4 (We need to get the content of message 3 also). With the message 5,6,7,8 we don't know it is signed or not ???
Please refer link for the smime messages that i woking on
https://drive.google.com/open?id=0B6GCW3Gz34lFLXFPb2FEWDh4Mk0&authuser=0