Whew! MYParsedCertificate can now generate certs from scratch. Also added improvements and fixes to the BER/DER codecs.
5 // Created by Jens Alfke on 4/4/09.
6 // Copyright 2009 Jens Alfke. All rights reserved.
10 #import "MYCrypto_Private.h"
12 #if MYCRYPTO_USE_IPHONE_API
15 #import "MYErrorUtils.h"
22 - (id) initWithKeyRef: (SecKeyRef)key {
23 return [super initWithKeychainItemRef: (SecKeychainItemRef)key];
27 - (id) _initWithKeyData: (NSData*)data
28 forKeychain: (SecKeychainRef)keychain
30 NSDictionary *info = $dict( {(id)kSecClass, (id)kSecClassKey},
31 {(id)kSecAttrKeyClass, (id)self.keyType},
32 {(id)kSecValueData, data},
33 {(id)kSecAttrIsPermanent, $object(keychain!=nil)},
34 {(id)kSecReturnRef, $true} );
36 if (!check(SecItemAdd((CFDictionaryRef)info, (CFTypeRef*)&key), @"SecItemAdd"))
39 return [self initWithKeyRef: (SecKeyRef)key];
42 - (id) initWithKeyData: (NSData*)data {
43 return [self _initWithKeyData: data forKeychain: nil];
47 - (SecExternalItemType) keyType {
48 AssertAbstractMethod();
53 NSDictionary *info = $dict( {(id)kSecClass, (id)kSecClassKey},
54 {(id)kSecAttrKeyClass, (id)self.keyType},
55 {(id)kSecMatchItemList, $array((id)self.keyRef)},
56 {(id)kSecReturnData, $true} );
58 if (!check(SecItemCopyMatching((CFDictionaryRef)info, (CFTypeRef*)&data), @"SecItemCopyMatching"))
61 return [(id)CFMakeCollectable(data) autorelease];
63 // The format of this data is not documented. There's been some reverse-engineering:
64 // https://devforums.apple.com/message/32089#32089
65 // Apparently it is a DER-formatted sequence of a modulus followed by an exponent.
66 // This can be converted to OpenSSL format by wrapping it in some additional DER goop.
70 - (SecKeyRef) keyRef {
71 return (SecKeyRef) self.keychainItemRef;
75 - (id) _attribute: (CFTypeRef)attribute {
76 NSDictionary *info = $dict( {(id)kSecClass, (id)kSecClassKey},
77 {(id)kSecAttrKeyClass, (id)self.keyType},
78 {(id)kSecMatchItemList, $array((id)self.keyRef)},
79 {(id)kSecReturnAttributes, $true} );
80 CFDictionaryRef attrs = NULL;
81 if (!check(SecItemCopyMatching((CFDictionaryRef)info, (CFTypeRef*)&attrs), @"SecItemCopyMatching"))
83 CFTypeRef rawValue = CFDictionaryGetValue(attrs,attribute);
84 id value = rawValue ?[[(id)CFMakeCollectable(rawValue) retain] autorelease] :nil;
89 - (BOOL) setValue: (NSString*)value ofAttribute: (SecKeychainAttrType)attribute {
91 value = (id)[NSNull null];
92 NSDictionary *query = $dict( {(id)kSecClass, (id)kSecClassKey},
93 {(id)kSecAttrKeyClass, (id)self.keyType},
94 {(id)kSecMatchItemList, self._itemList} );
95 NSDictionary *attrs = $dict( {(id)attribute, value} );
96 return check(SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)attrs), @"SecItemUpdate");
101 return [self _attribute: kSecAttrLabel];
104 - (void) setName: (NSString*)name {
105 [self setValue: name ofAttribute: kSecAttrLabel];
108 - (NSString*) alias {
109 return [self _attribute: kSecAttrApplicationTag];
112 - (void) setAlias: (NSString*)alias {
113 [self setValue: alias ofAttribute: kSecAttrApplicationTag];
119 /** Asymmetric encryption/decryption; used by MYPublicKey and MYPrivateKey. */
120 - (NSData*) _crypt: (NSData*)data operation: (BOOL)operation {
122 size_t dataLength = data.length;
123 SecKeyRef key = self.keyRef;
124 size_t outputLength = MAX(dataLength, SecKeyGetBlockSize(key));
125 void *outputBuf = malloc(outputLength);
126 if (!outputBuf) return nil;
129 err = SecKeyEncrypt(key, kSecPaddingNone,//PKCS1,
130 data.bytes, dataLength,
131 outputBuf, &outputLength);
133 err = SecKeyDecrypt(key, kSecPaddingNone,//PKCS1,
134 data.bytes, dataLength,
135 outputBuf, &outputLength);
138 Warn(@"%scrypting failed (%i)", (operation ?"En" :"De"), err);
139 // Note: One of the errors I've seen is -9809, which is errSSLCrypto (SecureTransport.h)
142 return [NSData dataWithBytesNoCopy: outputBuf length: outputLength freeWhenDone: YES];
149 #endif MYCRYPTO_USE_IPHONE_API
154 Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
156 Redistribution and use in source and binary forms, with or without modification, are permitted
157 provided that the following conditions are met:
159 * Redistributions of source code must retain the above copyright notice, this list of conditions
160 and the following disclaimer.
161 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
162 and the following disclaimer in the documentation and/or other materials provided with the
165 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
166 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
167 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
168 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
169 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
170 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
171 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
172 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.