1.1 --- a/MYSymmetricKey-iPhone.m Sun Jun 07 21:53:56 2009 -0700
1.2 +++ b/MYSymmetricKey-iPhone.m Tue Jul 21 10:13:08 2009 -0700
1.3 @@ -13,6 +13,9 @@
1.4 #if MYCRYPTO_USE_IPHONE_API
1.5
1.6
1.7 +#define kAlgorithmNone 0xFFFFFFFF
1.8 +
1.9 +
1.10 typedef uint32_t CSSM_ALGORITHMS;
1.11 enum {
1.12 // Taken from cssmtype.h in OS X 10.5 SDK:
1.13 @@ -36,20 +39,27 @@
1.14 @implementation MYSymmetricKey
1.15
1.16
1.17 +- (id) initWithKeyRef: (SecKeyRef)key {
1.18 + self = [super initWithKeyRef: key];
1.19 + if (self) {
1.20 + _algorithm = kAlgorithmNone;
1.21 + }
1.22 + return self;
1.23 +}
1.24 +
1.25 - (id) _initWithKeyData: (NSData*)keyData
1.26 algorithm: (CCAlgorithm)algorithm
1.27 inKeychain: (MYKeychain*)keychain
1.28 {
1.29 Assert(algorithm <= kCCAlgorithmRC4);
1.30 Assert(keyData);
1.31 - NSNumber *keySizeInBits = [NSNumber numberWithUnsignedInt: keyData.length * 8];
1.32 - NSNumber *keyType = [NSNumber numberWithUnsignedInt: kCSSMAlgorithms[algorithm]];
1.33 + unsigned keySizeInBits = keyData.length * 8;
1.34 NSMutableDictionary *keyAttrs = $mdict( {(id)kSecClass, (id)kSecClassKey},
1.35 {(id)kSecAttrKeyClass, (id)kSecAttrKeyClassSymmetric},
1.36 - {(id)kSecAttrKeyType, keyType},
1.37 + {(id)kSecAttrKeyType, $object(kCSSMAlgorithms[algorithm])},
1.38 {(id)kSecValueData, keyData},
1.39 - {(id)kSecAttrKeySizeInBits, keySizeInBits},
1.40 - {(id)kSecAttrEffectiveKeySize, keySizeInBits},
1.41 + {(id)kSecAttrKeySizeInBits, $object(keySizeInBits)},
1.42 + {(id)kSecAttrEffectiveKeySize, $object(keySizeInBits)},
1.43 {(id)kSecAttrIsPermanent, keychain ?$true :$false},
1.44 {(id)kSecAttrCanEncrypt, $true},
1.45 {(id)kSecAttrCanDecrypt, $true},
1.46 @@ -57,14 +67,17 @@
1.47 {(id)kSecAttrCanUnwrap, $false},
1.48 {(id)kSecAttrCanDerive, $false},
1.49 {(id)kSecAttrCanSign, $false},
1.50 - {(id)kSecAttrCanVerify, $false},
1.51 - {(id)kSecReturnPersistentRef, $true});
1.52 - SecKeyRef keyRef = [[self class] _addKeyWithInfo: keyAttrs];
1.53 + {(id)kSecAttrCanVerify, $false});
1.54 + SecKeyRef keyRef = (SecKeyRef) [MYKeychain _addItemWithInfo: keyAttrs];
1.55 if (!keyRef) {
1.56 [self release];
1.57 return nil;
1.58 }
1.59 self = [self initWithKeyRef: keyRef];
1.60 + if (self) {
1.61 + _algorithm = algorithm;
1.62 + _keySizeInBits = keySizeInBits;
1.63 + }
1.64 CFRelease(keyRef);
1.65 return self;
1.66 }
1.67 @@ -98,25 +111,33 @@
1.68 }
1.69
1.70 - (CCAlgorithm) algorithm {
1.71 - CSSM_ALGORITHMS cssmAlg;
1.72 - id keyType = [self _attribute: kSecAttrKeyType];
1.73 - Assert(keyType!=nil, @"Key has no kSecAttrKeyType");
1.74 - cssmAlg = [keyType unsignedIntValue];
1.75 - switch(cssmAlg) {
1.76 - case CSSM_ALGID_AES:
1.77 - return kCCAlgorithmAES128;
1.78 - case CSSM_ALGID_DES:
1.79 - return kCCAlgorithmDES;
1.80 - case CSSM_ALGID_3DES_3KEY:
1.81 - return kCCAlgorithm3DES;
1.82 - case CSSM_ALGID_CAST:
1.83 - return kCCAlgorithmCAST;
1.84 - case CSSM_ALGID_RC4:
1.85 - return kCCAlgorithmRC4;
1.86 - default:
1.87 - Warn(@"CSSM_ALGORITHMS #%u doesn't map to any CCAlgorithm", cssmAlg);
1.88 - return (CCAlgorithm)-1;
1.89 + if (_algorithm == kAlgorithmNone) {
1.90 + CSSM_ALGORITHMS cssmAlg;
1.91 + id keyType = [self _attribute: kSecAttrKeyType];
1.92 + Assert(keyType!=nil, @"Key has no kSecAttrKeyType");
1.93 + cssmAlg = [keyType unsignedIntValue];
1.94 + switch(cssmAlg) {
1.95 + case CSSM_ALGID_AES:
1.96 + _algorithm = kCCAlgorithmAES128;
1.97 + break;
1.98 + case CSSM_ALGID_DES:
1.99 + _algorithm = kCCAlgorithmDES;
1.100 + break;
1.101 + case CSSM_ALGID_3DES_3KEY:
1.102 + _algorithm = kCCAlgorithm3DES;
1.103 + break;
1.104 + case CSSM_ALGID_CAST:
1.105 + _algorithm = kCCAlgorithmCAST;
1.106 + break;
1.107 + case CSSM_ALGID_RC4:
1.108 + _algorithm = kCCAlgorithmRC4;
1.109 + break;
1.110 + default:
1.111 + Warn(@"CSSM_ALGORITHMS #%u doesn't map to any CCAlgorithm", cssmAlg);
1.112 + break;
1.113 + }
1.114 }
1.115 + return _algorithm;
1.116 }
1.117
1.118 - (const char*) algorithmName {
1.119 @@ -128,9 +149,12 @@
1.120 }
1.121
1.122 - (unsigned) keySizeInBits {
1.123 - id keySize = [self _attribute: kSecAttrKeySizeInBits];
1.124 - Assert(keySize!=nil, @"Key has no kSecAttrKeySizeInBits");
1.125 - return [keySize unsignedIntValue];
1.126 + if (_keySizeInBits == 0) {
1.127 + id keySize = [self _attribute: kSecAttrKeySizeInBits];
1.128 + Assert(keySize!=nil, @"Key has no kSecAttrKeySizeInBits");
1.129 + _keySizeInBits = [keySize unsignedIntValue];
1.130 + }
1.131 + return _keySizeInBits;
1.132 }
1.133
1.134