* More work on iPhone compatibility.
* Restored the signature-verification code to MYCertInfo, which I'd removed earlier. I now need it to verify self-signed certs, since the Security framework won't do it for me.
* Merged MYCertificate-iPhone.m into MYCertificate.m since there's more shared code now.
5 // Created by Jens Alfke on 1/16/08.
6 // Copyright 2008-2009 Jens Alfke. All rights reserved.
10 #import "MYIdentity.h"
11 #import "MYCrypto_Private.h"
13 #import "MYErrorUtils.h"
16 @implementation MYEncoder
23 if( ! checksave(CMSEncoderCreate(&_encoder)) ) {
33 if(_encoder) CFRelease(_encoder);
39 - (BOOL) addSigner: (MYIdentity*)signer
42 return checksave( CMSEncoderAddSigners(_encoder, signer.identityRef) );
45 - (BOOL) addRecipient: (MYCertificate*)recipient
48 return checksave( CMSEncoderAddRecipients(_encoder, recipient.certificateRef) );
51 - (BOOL) addSupportingCert: (MYCertificate*)supportingCert
53 Assert(supportingCert);
54 return checksave( CMSEncoderAddSupportingCerts(_encoder, supportingCert.certificateRef) );
59 return checksave( CMSEncoderAddSignedAttributes(_encoder, kCMSAttrSigningTime) );
66 return MYError(_error, NSOSStatusErrorDomain,
67 @"%@", MYErrorName(NSOSStatusErrorDomain,_error));
73 - (CMSCertificateChainMode) certificateChainMode
75 CMSCertificateChainMode mode;
76 if( CMSEncoderGetCertificateChainMode(_encoder, &mode) == noErr )
82 - (void) setCertificateChainMode: (CMSCertificateChainMode)mode
84 checksave( CMSEncoderSetCertificateChainMode(_encoder, mode) );
87 - (BOOL) hasDetachedContent
90 return CMSEncoderGetHasDetachedContent(_encoder, &detached)==noErr && detached;
93 - (void) setHasDetachedContent: (BOOL)detached
95 checksave( CMSEncoderSetHasDetachedContent(_encoder, detached) );
98 - (NSData*) _dataFromFunction: (OSStatus (*)(CMSEncoderRef,CFDataRef*))function
101 if( checksave( (*function)(_encoder, &data) ) )
102 return [(NSData*)CFMakeCollectable(data) autorelease];
108 - (CSSM_OID) contentType
110 NSData *data = [self _dataFromFunction: &CMSEncoderCopyEncapsulatedContentType];
111 return (CSSM_OID){data.length,(uint8*)data.bytes};
114 - (void) setContentType: (CSSM_OID)contentType
116 checksave( CMSEncoderSetEncapsulatedContentType(_encoder, &contentType) );
120 - (BOOL) addData: (NSData*)data
123 return ! _error && checksave( CMSEncoderUpdateContent(_encoder, data.bytes, data.length) );
127 - (NSData*) encodedData
130 return [self _dataFromFunction: &CMSEncoderCopyEncodedContent];
136 + (NSData*) encodeData: (NSData*)data
137 signer: (MYIdentity*)signer
138 recipient: (MYCertificate*)recipient
139 error: (NSError**)outError
141 MYEncoder *e = [[self alloc] init];
143 [e addSigner: signer];
145 [e addRecipient: recipient];
148 NSData *result = e.encodedData;
159 #import "MYCrypto+Cocoa.h"
161 TestCase(MYEncoder) {
162 MYIdentity *me = nil;//[MYIdentity preferredIdentityForName: @"MYCryptoTest"];
164 NSArray *idents = [[[MYKeychain allKeychains] enumerateIdentities] allObjects];
165 SFChooseIdentityPanel *panel = [SFChooseIdentityPanel sharedChooseIdentityPanel];
166 [panel setAlternateButtonTitle: @"Cancel"];
167 if ([panel my_runModalForIdentities: idents
168 message: @"Choose an identity for the MYEncoder test case:"]
170 [NSException raise: NSGenericException format: @"User canceled"];
172 me = [panel my_identity];
173 [me makePreferredIdentityForName: @"MYCryptoTest"];
175 CAssert(me,@"No default identity has been set up in the Keychain");
177 NSData *source = [NSData dataWithContentsOfFile: @"/Library/Desktop Pictures/Nature/Zen Garden.jpg"];
183 Log(@"Testing signing...");
184 encoded = [MYEncoder encodeData: source signer: me recipient: nil error: &error];
185 CAssertEq(error,nil);
186 CAssert([encoded length]);
187 Log(@"MYEncoder signed %u bytes into %u bytes", source.length,encoded.length);
189 Log(@"Testing encryption...");
190 encoded = [MYEncoder encodeData: source signer: nil recipient: me error: &error];
191 CAssertEq(error,nil);
192 CAssert([encoded length]);
193 Log(@"MYEncoder encrypted %u bytes into %u bytes", source.length,encoded.length);
195 Log(@"Testing signing+encryption...");
196 encoded = [MYEncoder encodeData: source signer: me recipient: me error: &error];
197 CAssertEq(error,nil);
198 CAssert([encoded length]);
199 Log(@"MYEncoder signed/encrypted %u bytes into %u bytes", source.length,encoded.length);
206 Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
208 Redistribution and use in source and binary forms, with or without modification, are permitted
209 provided that the following conditions are met:
211 * Redistributions of source code must retain the above copyright notice, this list of conditions
212 and the following disclaimer.
213 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
214 and the following disclaimer in the documentation and/or other materials provided with the
217 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
218 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
219 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
220 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
221 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
222 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
223 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
224 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.