1.1 --- a/MYKeyPair.m Tue Apr 07 10:56:58 2009 -0700
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,246 +0,0 @@
1.4 -//
1.5 -// KeyPair.m
1.6 -// MYCrypto
1.7 -//
1.8 -// Created by Jens Alfke on 3/21/09.
1.9 -// Copyright 2009 Jens Alfke. All rights reserved.
1.10 -//
1.11 -
1.12 -#import "MYKeyPair.h"
1.13 -#import "MYCrypto_Private.h"
1.14 -#import <CommonCrypto/CommonDigest.h>
1.15 -
1.16 -#if !MYCRYPTO_USE_IPHONE_API
1.17 -
1.18 -
1.19 -#pragma mark -
1.20 -
1.21 -@implementation MYKeyPair
1.22 -
1.23 -
1.24 -+ (MYKeyPair*) _generateRSAKeyPairOfSize: (unsigned)keySize
1.25 - inKeychain: (MYKeychain*)keychain {
1.26 - Assert( keySize == 512 || keySize == 1024 || keySize == 2048, @"Unsupported key size %u", keySize );
1.27 - SecKeyRef pubKey=NULL, privKey=NULL;
1.28 - OSStatus err;
1.29 - err = SecKeyCreatePair(keychain.keychainRefOrDefault,
1.30 - CSSM_ALGID_RSA,
1.31 - keySize,
1.32 - 0LL,
1.33 - CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY, // public key
1.34 - CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT,
1.35 - CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN, // private key
1.36 - CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_PERMANENT,
1.37 - NULL, // SecAccessRef
1.38 - &pubKey, &privKey);
1.39 - if (!check(err, @"SecKeyCreatePair")) {
1.40 - return nil;
1.41 - } else
1.42 - return [[[self alloc] initWithPublicKeyRef: pubKey privateKeyRef: privKey] autorelease];
1.43 -}
1.44 -
1.45 -
1.46 -- (id) initWithPublicKeyRef: (SecKeyRef)publicKey privateKeyRef: (SecKeyRef)privateKey {
1.47 - self = [super initWithKeyRef: publicKey];
1.48 - if (self) {
1.49 - NSParameterAssert(privateKey);
1.50 - _privateKey = (SecKeyRef) CFRetain(privateKey);
1.51 - }
1.52 - return self;
1.53 -}
1.54 -
1.55 -- (id) _initWithPublicKeyData: (NSData*)pubKeyData
1.56 - privateKey: (SecKeyRef)privateKey
1.57 - forKeychain: (SecKeychainRef)keychain {
1.58 - if (!privateKey) {
1.59 - [self release];
1.60 - return nil;
1.61 - }
1.62 - self = [self _initWithKeyData: pubKeyData forKeychain: keychain];
1.63 - if (self) {
1.64 - _privateKey = privateKey;
1.65 - } else {
1.66 - SecKeychainItemDelete((SecKeychainItemRef)privateKey);
1.67 - CFRelease(privateKey);
1.68 - }
1.69 - return self;
1.70 -}
1.71 -
1.72 -
1.73 -// The public API for this is in MYKeychain.
1.74 -- (id) _initWithPublicKeyData: (NSData*)pubKeyData
1.75 - privateKeyData: (NSData*)privKeyData
1.76 - forKeychain: (SecKeychainRef)keychain
1.77 - alertTitle: (NSString*)title
1.78 - alertPrompt: (NSString*)prompt
1.79 -{
1.80 - // Try to import the private key first, since the user might cancel the passphrase alert.
1.81 - SecKeyImportExportParameters params = {
1.82 - .flags = kSecKeySecurePassphrase,
1.83 - .alertTitle = (CFStringRef) title,
1.84 - .alertPrompt = (CFStringRef) prompt
1.85 - };
1.86 - SecKeyRef privateKey = importKey(privKeyData,kSecItemTypePrivateKey,keychain,¶ms);
1.87 - return [self _initWithPublicKeyData: pubKeyData privateKey: privateKey forKeychain: keychain];
1.88 -}
1.89 -
1.90 -// This method is for testing, so unit-tests don't require user intervention.
1.91 -// It's deliberately not made public, to discourage clients from trying to manage the passphrases
1.92 -// themselves (this is less secure than letting the Security agent do it.)
1.93 -- (id) _initWithPublicKeyData: (NSData*)pubKeyData
1.94 - privateKeyData: (NSData*)privKeyData
1.95 - forKeychain: (SecKeychainRef)keychain
1.96 - passphrase: (NSString*)passphrase
1.97 -{
1.98 - SecKeyImportExportParameters params = {
1.99 - .passphrase = (CFStringRef) passphrase,
1.100 - };
1.101 - SecKeyRef privateKey = importKey(privKeyData,kSecItemTypePrivateKey,keychain,¶ms);
1.102 - return [self _initWithPublicKeyData: pubKeyData privateKey: privateKey forKeychain: keychain];
1.103 -}
1.104 -
1.105 -
1.106 -- (void) dealloc
1.107 -{
1.108 - if (_privateKey) CFRelease(_privateKey);
1.109 - [super dealloc];
1.110 -}
1.111 -
1.112 -- (void) finalize
1.113 -{
1.114 - if (_privateKey) CFRelease(_privateKey);
1.115 - [super finalize];
1.116 -}
1.117 -
1.118 -
1.119 -- (NSUInteger)hash {
1.120 - // Ensure that a KeyPair doesn't hash the same as its corresponding PublicKey:
1.121 - return super.hash ^ 0xFFFFFFFF;
1.122 -}
1.123 -
1.124 -
1.125 -- (MYPublicKey*) asPublicKey {
1.126 - return [[[MYPublicKey alloc] initWithKeyRef: self.keyRef] autorelease];
1.127 -}
1.128 -
1.129 -
1.130 -- (NSData*) exportPrivateKeyInFormat: (SecExternalFormat)format
1.131 - withPEM: (BOOL)withPEM
1.132 - alertTitle: (NSString*)title
1.133 - alertPrompt: (NSString*)prompt
1.134 -{
1.135 - SecKeyImportExportParameters params = {
1.136 - .version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,
1.137 - .flags = kSecKeySecurePassphrase,
1.138 - .alertTitle = (CFStringRef)title,
1.139 - .alertPrompt = (CFStringRef)prompt
1.140 - };
1.141 - CFDataRef data = NULL;
1.142 - if (check(SecKeychainItemExport(_privateKey, //$array((id)_publicKey,(id)_privateKey),
1.143 - format, (withPEM ?kSecItemPemArmour :0),
1.144 - ¶ms, &data),
1.145 - @"SecKeychainItemExport"))
1.146 - return [(id)CFMakeCollectable(data) autorelease];
1.147 - else
1.148 - return nil;
1.149 -}
1.150 -
1.151 -- (NSData*) exportPrivateKey {
1.152 - return [self exportPrivateKeyInFormat: kSecFormatWrappedOpenSSL withPEM: YES
1.153 - alertTitle: @"Export Private Key"
1.154 - alertPrompt: @"Enter a passphrase to protect the private-key file.\n"
1.155 - "You will need to re-enter the passphrase later when importing the key from this file, "
1.156 - "so keep it in a safe place."];
1.157 - //FIX: Should make these messages localizable.
1.158 -}
1.159 -
1.160 -
1.161 -- (NSData*) _exportPrivateKeyInFormat: (SecExternalFormat)format
1.162 - withPEM: (BOOL)withPEM
1.163 - passphrase: (NSString*)passphrase
1.164 -{
1.165 - SecKeyImportExportParameters params = {
1.166 - .version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,
1.167 - .passphrase = (CFStringRef)passphrase
1.168 - };
1.169 - CFDataRef data = NULL;
1.170 - if (check(SecKeychainItemExport(_privateKey,
1.171 - format, (withPEM ?kSecItemPemArmour :0),
1.172 - ¶ms, &data),
1.173 - @"SecKeychainItemExport"))
1.174 - return [(id)CFMakeCollectable(data) autorelease];
1.175 - else
1.176 - return nil;
1.177 -}
1.178 -
1.179 -- (BOOL) removeFromKeychain {
1.180 - return check(SecKeychainItemDelete((SecKeychainItemRef)_privateKey), @"delete private key")
1.181 - && [super removeFromKeychain];
1.182 -}
1.183 -
1.184 -
1.185 -- (SecKeyRef) privateKeyRef {
1.186 - return _privateKey;
1.187 -}
1.188 -
1.189 -
1.190 -- (NSData*) decryptData: (NSData*)data {
1.191 - return _crypt(_privateKey,data,kCCDecrypt);
1.192 -}
1.193 -
1.194 -
1.195 -- (NSData*) signData: (NSData*)data {
1.196 - Assert(data);
1.197 - uint8_t digest[CC_SHA256_DIGEST_LENGTH];
1.198 - CC_SHA256(data.bytes,data.length, digest);
1.199 -
1.200 - NSData *signature = nil;
1.201 - CSSM_CC_HANDLE ccHandle = cssmCreateSignatureContext(_privateKey);
1.202 - if (!ccHandle) return nil;
1.203 - CSSM_DATA original = {data.length, (void*)data.bytes};
1.204 - CSSM_DATA result = {0,NULL};
1.205 - if (checkcssm(CSSM_SignData(ccHandle, &original, 1, CSSM_ALGID_NONE, &result), @"CSSM_SignData"))
1.206 - signature = [NSData dataWithBytesNoCopy: result.Data length: result.Length
1.207 - freeWhenDone: YES];
1.208 - CSSM_DeleteContext(ccHandle);
1.209 - return signature;
1.210 -}
1.211 -
1.212 -
1.213 -- (BOOL) setValue: (NSString*)valueStr ofAttribute: (SecKeychainAttrType)attr {
1.214 - return [super setValue: valueStr ofAttribute: attr]
1.215 - && [[self class] _setAttribute: attr
1.216 - ofItem: (SecKeychainItemRef)_privateKey
1.217 - stringValue: valueStr];
1.218 -}
1.219 -
1.220 -
1.221 -@end
1.222 -
1.223 -
1.224 -#endif !MYCRYPTO_USE_IPHONE_API
1.225 -
1.226 -
1.227 -
1.228 -
1.229 -/*
1.230 - Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
1.231 -
1.232 - Redistribution and use in source and binary forms, with or without modification, are permitted
1.233 - provided that the following conditions are met:
1.234 -
1.235 - * Redistributions of source code must retain the above copyright notice, this list of conditions
1.236 - and the following disclaimer.
1.237 - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
1.238 - and the following disclaimer in the documentation and/or other materials provided with the
1.239 - distribution.
1.240 -
1.241 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
1.242 - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1.243 - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
1.244 - BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1.245 - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1.246 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1.247 - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
1.248 - THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.249 - */