snej@0: //
snej@0: //  MYKeyPair-iPhone.m
snej@0: //  MYNetwork-iPhone
snej@0: //
snej@0: //  Created by Jens Alfke on 3/22/09.
snej@0: //  Copyright 2009 Jens Alfke. All rights reserved.
snej@0: //
snej@0: 
snej@0: 
snej@0: #import "MYKeyPair.h"
snej@0: #import "MYCrypto_Private.h"
snej@1: #import <CommonCrypto/CommonDigest.h>
snej@1: 
snej@0: 
snej@2: #if MYCRYPTO_USE_IPHONE_API
snej@0: 
snej@0: 
snej@0: @implementation MYKeyPair
snej@0: 
snej@0: 
snej@2: + (MYKeyPair*) _generateRSAKeyPairOfSize: (unsigned)keySize inKeychain: (MYKeychain*)keychain {
snej@0:     Assert( keySize == 512 || keySize == 1024 || keySize == 2048, @"Unsupported key size %u", keySize );
snej@0:     SecKeyRef pubKey=NULL, privKey=NULL;
snej@0:     OSStatus err;
snej@0:     NSDictionary *pubKeyAttrs = $dict({(id)kSecAttrIsPermanent, $true});
snej@0:     NSDictionary *privKeyAttrs = $dict({(id)kSecAttrIsPermanent, $true});
snej@0:     NSDictionary *keyAttrs = $dict( {(id)kSecAttrKeyType, (id)kSecAttrKeyTypeRSA},
snej@0:                                     {(id)kSecAttrKeySizeInBits, $object(keySize)},
snej@0:                                     {(id)kSecPublicKeyAttrs, pubKeyAttrs},
snej@0:                                     {(id)kSecPrivateKeyAttrs, privKeyAttrs} );
snej@0:     err = SecKeyGeneratePair((CFDictionaryRef)keyAttrs,&pubKey,&privKey);
snej@0:     if (err) {
snej@0:         Warn(@"Failed to create key-pair: %i", err);
snej@0:         return nil;
snej@0:     } else
snej@0:         return [[[self alloc] initWithPublicKeyRef: pubKey privateKeyRef: privKey] autorelease];
snej@0: }
snej@0: 
snej@0: - (id) initWithPublicKeyRef: (SecKeyRef)publicKey privateKeyRef: (SecKeyRef)privateKey {
snej@0:     self = [super initWithKeyRef: publicKey];
snej@0:     if (self) {
snej@0:         NSParameterAssert(privateKey);
snej@0:         _privateKey = (SecKeyRef) CFRetain(privateKey);
snej@0:     }
snej@0:     return self;
snej@0: }
snej@0: 
snej@0: 
snej@0: - (NSArray*) _itemList {
snej@0:     return $array((id)_privateKey,(id)self.keyRef);
snej@0: }
snej@0: 
snej@0: 
snej@1: - (SecKeyRef) privateKeyRef {
snej@1:     return _privateKey;
snej@1: }
snej@0: 
snej@0: 
snej@0: - (NSData*) decryptData: (NSData*)data {
snej@0:     return _crypt(_privateKey,data,kCCDecrypt);
snej@0: }
snej@0:     
snej@0: 
snej@0: - (NSData*) signData: (NSData*)data {
snej@0:     Assert(data);
snej@0:     uint8_t digest[CC_SHA1_DIGEST_LENGTH];
snej@0:     CC_SHA1(data.bytes,data.length, digest);
snej@0: 
snej@0:     size_t sigLen = 1024;
snej@0:     uint8_t sigBuf[sigLen];
snej@0:     OSStatus err = SecKeyRawSign(_privateKey, kSecPaddingPKCS1SHA1,
snej@0:                                    digest,sizeof(digest), //data.bytes, data.length,
snej@0:                                    sigBuf, &sigLen);
snej@0:     if(err) {
snej@0:         Warn(@"SecKeyRawSign failed: %i",err);
snej@0:         return nil;
snej@0:     } else
snej@0:         return [NSData dataWithBytes: sigBuf length: sigLen];
snej@0: }
snej@0: 
snej@0: 
snej@0: @end
snej@0: 
snej@0: 
snej@2: #endif MYCRYPTO_USE_IPHONE_API