MYKey-iPhone.m
author snej@snej-mbp.mtv.corp.google.com
Wed Apr 08 16:30:52 2009 -0700 (2009-04-08)
changeset 3 1dfe820d7ebe
parent 2 8982b8fada63
child 16 c409dbc4f068
permissions -rw-r--r--
* Replaced MYKeyPair with MYPrivateKey.
* Changed config files.
snej@0
     1
//
snej@0
     2
//  MYKey-iPhone.m
snej@0
     3
//  MYCrypto-iPhone
snej@0
     4
//
snej@0
     5
//  Created by Jens Alfke on 4/4/09.
snej@0
     6
//  Copyright 2009 Jens Alfke. All rights reserved.
snej@0
     7
//
snej@0
     8
snej@0
     9
snej@0
    10
#import "MYCrypto_Private.h"
snej@0
    11
snej@2
    12
#if MYCRYPTO_USE_IPHONE_API
snej@0
    13
snej@0
    14
#import "MYDigest.h"
snej@0
    15
#import "MYErrorUtils.h"
snej@0
    16
snej@0
    17
snej@0
    18
#pragma mark -
snej@0
    19
@implementation MYKey
snej@0
    20
snej@0
    21
snej@0
    22
- (id) initWithKeyRef: (SecKeyRef)key {
snej@1
    23
    return [super initWithKeychainItemRef: (SecKeychainItemRef)key];
snej@0
    24
}
snej@0
    25
snej@0
    26
snej@0
    27
- (id) _initWithKeyData: (NSData*)data
snej@0
    28
            forKeychain: (SecKeychainRef)keychain
snej@0
    29
{
snej@0
    30
    NSDictionary *info = $dict( {(id)kSecClass, (id)kSecClassKey},
snej@1
    31
                                {(id)kSecAttrKeyClass, (id)self.keyType},
snej@0
    32
                                {(id)kSecValueData, data},
snej@0
    33
                                {(id)kSecAttrIsPermanent, $object(keychain!=nil)},
snej@0
    34
                                {(id)kSecReturnRef, $true} );
snej@0
    35
    SecKeyRef key;
snej@0
    36
    if (!check(SecItemAdd((CFDictionaryRef)info, (CFTypeRef*)&key), @"SecItemAdd"))
snej@0
    37
        return nil;
snej@0
    38
    else
snej@0
    39
        return [self initWithKeyRef: (SecKeyRef)key];
snej@0
    40
}
snej@0
    41
snej@0
    42
- (id) initWithKeyData: (NSData*)data {
snej@0
    43
    return [self _initWithKeyData: data forKeychain: nil];
snej@0
    44
}
snej@0
    45
snej@0
    46
snej@0
    47
- (SecExternalItemType) keyType {
snej@0
    48
    AssertAbstractMethod();
snej@0
    49
}
snej@0
    50
snej@0
    51
snej@0
    52
- (NSData*) keyData {
snej@0
    53
    NSDictionary *info = $dict( {(id)kSecClass, (id)kSecClassKey},
snej@1
    54
                                {(id)kSecAttrKeyClass, (id)self.keyType},
snej@1
    55
                                {(id)kSecMatchItemList, $array((id)self.keyRef)},
snej@0
    56
                                {(id)kSecReturnData, $true} );
snej@0
    57
    CFDataRef data;
snej@0
    58
    if (!check(SecItemCopyMatching((CFDictionaryRef)info, (CFTypeRef*)&data), @"SecItemCopyMatching"))
snej@0
    59
        return nil;
snej@0
    60
    else
snej@0
    61
        return [(id)CFMakeCollectable(data) autorelease];
snej@0
    62
}
snej@0
    63
snej@0
    64
snej@1
    65
- (SecKeyRef) keyRef {
snej@1
    66
    return (SecKeyRef) self.keychainItemRef;
snej@0
    67
}
snej@0
    68
snej@0
    69
snej@0
    70
- (id) _attribute: (CFTypeRef)attribute {
snej@0
    71
    NSDictionary *info = $dict( {(id)kSecClass, (id)kSecClassKey},
snej@1
    72
                                {(id)kSecAttrKeyClass, (id)self.keyType},
snej@1
    73
                                {(id)kSecMatchItemList, $array((id)self.keyRef)},
snej@0
    74
                                {(id)kSecReturnAttributes, $true} );
snej@2
    75
    CFDictionaryRef attrs = NULL;
snej@0
    76
    if (!check(SecItemCopyMatching((CFDictionaryRef)info, (CFTypeRef*)&attrs), @"SecItemCopyMatching"))
snej@0
    77
        return nil;
snej@0
    78
    CFTypeRef rawValue = CFDictionaryGetValue(attrs,attribute);
snej@0
    79
    id value = rawValue ?[[(id)CFMakeCollectable(rawValue) retain] autorelease] :nil;
snej@0
    80
    CFRelease(attrs);
snej@0
    81
    return value;
snej@0
    82
}
snej@0
    83
snej@0
    84
- (BOOL) setValue: (NSString*)value ofAttribute: (SecKeychainAttrType)attribute {
snej@0
    85
    if (!value)
snej@0
    86
        value = (id)[NSNull null];
snej@0
    87
    NSDictionary *query = $dict( {(id)kSecClass, (id)kSecClassKey},
snej@1
    88
                                {(id)kSecAttrKeyClass, (id)self.keyType},
snej@0
    89
                                {(id)kSecMatchItemList, self._itemList} );
snej@0
    90
    NSDictionary *attrs = $dict( {(id)attribute, value} );
snej@0
    91
    return check(SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)attrs), @"SecItemUpdate");
snej@0
    92
}
snej@0
    93
snej@0
    94
snej@0
    95
- (NSString*) name {
snej@0
    96
    return [self _attribute: kSecAttrLabel];
snej@0
    97
}
snej@0
    98
snej@0
    99
- (void) setName: (NSString*)name {
snej@0
   100
    [self setValue: name ofAttribute: kSecAttrLabel];
snej@0
   101
}
snej@0
   102
snej@0
   103
- (NSString*) alias {
snej@0
   104
    return [self _attribute: kSecAttrApplicationTag];
snej@0
   105
}
snej@0
   106
snej@0
   107
- (void) setAlias: (NSString*)alias {
snej@0
   108
    [self setValue: alias ofAttribute: kSecAttrApplicationTag];
snej@0
   109
}
snej@0
   110
snej@0
   111
snej@3
   112
snej@3
   113
snej@3
   114
/** Asymmetric encryption/decryption; used by MYPublicKey and MYPrivateKey. */
snej@3
   115
- (NSData*) _crypt: (NSData*)data operation: (BOOL)operation {
snej@3
   116
    CAssert(data);
snej@3
   117
    size_t dataLength = data.length;
snej@3
   118
    SecKeyRef key = self.keyRef;
snej@3
   119
    size_t outputLength = MAX(dataLength, SecKeyGetBlockSize(key));
snej@3
   120
    void *outputBuf = malloc(outputLength);
snej@3
   121
    if (!outputBuf) return nil;
snej@3
   122
    OSStatus err;
snej@3
   123
    if (operation)
snej@3
   124
        err = SecKeyEncrypt(key, kSecPaddingNone,//PKCS1, 
snej@3
   125
                            data.bytes, dataLength,
snej@3
   126
                            outputBuf, &outputLength);
snej@3
   127
    else
snej@3
   128
        err = SecKeyDecrypt(key, kSecPaddingNone,//PKCS1, 
snej@3
   129
                            data.bytes, dataLength,
snej@3
   130
                            outputBuf, &outputLength);
snej@3
   131
    if (err) {
snej@3
   132
        free(outputBuf);
snej@3
   133
        Warn(@"%scrypting failed (%i)", (operation ?"En" :"De"), err);
snej@3
   134
        // Note: One of the errors I've seen is -9809, which is errSSLCrypto (SecureTransport.h)
snej@3
   135
        return nil;
snej@3
   136
    } else
snej@3
   137
        return [NSData dataWithBytesNoCopy: outputBuf length: outputLength freeWhenDone: YES];
snej@3
   138
}
snej@3
   139
snej@3
   140
snej@0
   141
@end
snej@0
   142
snej@0
   143
snej@2
   144
#endif MYCRYPTO_USE_IPHONE_API
snej@0
   145
snej@0
   146
snej@0
   147
snej@0
   148
/*
snej@0
   149
 Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
snej@0
   150
 
snej@0
   151
 Redistribution and use in source and binary forms, with or without modification, are permitted
snej@0
   152
 provided that the following conditions are met:
snej@0
   153
 
snej@0
   154
 * Redistributions of source code must retain the above copyright notice, this list of conditions
snej@0
   155
 and the following disclaimer.
snej@0
   156
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
snej@0
   157
 and the following disclaimer in the documentation and/or other materials provided with the
snej@0
   158
 distribution.
snej@0
   159
 
snej@0
   160
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
snej@0
   161
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
snej@0
   162
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
snej@0
   163
 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
snej@0
   164
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
snej@0
   165
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
snej@0
   166
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
snej@0
   167
 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
snej@0
   168
 */