Cryptographic Message Syntax is the IETF’s standard for public key encryption and digital signatures for S/MIME messages. Apple’s Cryptographic Message Syntax Services in the Security framework provide APIs that implement these industry standard algorithms.
Messages can either be signed, encrypted, or both, by any number of signers or recipients. To sign a message is to allow the recipient to verify its sender. To encrypt a message is to ensure that it kept secret from everyone but the recipients, who alone are able to decrypt the message’s content. These two operations are orthogonal, but cryptographically related.
Encoding a Message
NSData *data;
SecCertificateRef certificateRef;
CMSEncoderRef encoder;
CMSEncoderCreate(&encoder);
// Encrypt
CMSEncoderUpdateContent(encoder, [data bytes], [data length]);
CMSEncoderAddRecipients(encoder, certificateRef);
// Sign
SecIdentityRef identityRef = nil;
SecIdentityCreateWithCertificate(nil, certificateRef, &identityRef);
CMSEncoderUpdateContent(encoder, [data bytes], [data length]);
CMSEncoderAddSigners(encoder, identityRef);
CFRelease(identityRef);
CMSEncoderUpdateContent(encoder, [data bytes], [data length]);
MSEncoderAddSignedAttributes(encoder, kCMSAttrSmimeCapabilities);
CFDataRef encryptedDataRef;
CMSEncoderCopyEncodedContent(encoder, &encryptedDataRef);
NSData *encryptedData = [NSData dataWithData:(__bridge NSData *)encryptedDataRef];
CFRelease(encoder);
Decoding a Message
CMSDecoderRef decoder;
CMSDecoderCreate(&decoder);
CMSDecoderUpdateMessage(decoder, [encryptedData bytes], [encryptedData length]);� ;
CMSDecoderFinalizeMessage(decoder);
CFDataRef decryptedDataRef;
CMSDecoderCopyContent(decoder, &decryptedDataRef);
NSData *decryptedData = [NSData dataWithData:(__bridge NSData *)decryptedDataRef];
CFRelease(decryptedDataRef);
CFRelease(decoder);