MYPublicKey-iPhone.m
author snej@snej.local
Sat Apr 04 20:42:03 2009 -0700 (2009-04-04)
changeset 0 0a6527af039b
child 1 60e4cbbb5128
permissions -rw-r--r--
Initial checkin. Passes tests on Mac and in iPhone simulator.
snej@0
     1
//
snej@0
     2
//  MYPublicKey-iPhone.m
snej@0
     3
//  MYCrypto-iPhone
snej@0
     4
//
snej@0
     5
//  Created by Jens Alfke on 3/30/09.
snej@0
     6
//  Copyright 2009 Jens Alfke. All rights reserved.
snej@0
     7
//
snej@0
     8
snej@0
     9
#import "MYPublicKey.h"
snej@0
    10
#import "MYCrypto_Private.h"
snej@0
    11
snej@0
    12
#if 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
@implementation MYPublicKey
snej@0
    19
snej@0
    20
snej@0
    21
- (void) dealloc
snej@0
    22
{
snej@0
    23
    [_digest release];
snej@0
    24
    [super dealloc];
snej@0
    25
}
snej@0
    26
snej@0
    27
snej@0
    28
- (SecExternalItemType) keyType {
snej@0
    29
    return kSecAttrKeyClassPublic;
snej@0
    30
}
snej@0
    31
snej@0
    32
snej@0
    33
- (MYPublicKey*) asPublicKey {
snej@0
    34
    return self;
snej@0
    35
}
snej@0
    36
snej@0
    37
snej@0
    38
snej@0
    39
- (MYSHA1Digest*) publicKeyDigest {
snej@0
    40
    NSData *digestData = [self _attribute: kSecAttrApplicationLabel];
snej@0
    41
    if (digestData)
snej@0
    42
        return (MYSHA1Digest*) [MYSHA1Digest digestFromDigestData: digestData];
snej@0
    43
    else {
snej@0
    44
        Warn(@"MYKeyPair: public key didn't have digest attribute");
snej@0
    45
        return nil;
snej@0
    46
    }
snej@0
    47
}
snej@0
    48
snej@0
    49
snej@0
    50
- (NSData*) encryptData: (NSData*)data {
snej@0
    51
    return _crypt(self.keyRef,data,kCCEncrypt);
snej@0
    52
}
snej@0
    53
snej@0
    54
snej@0
    55
- (BOOL) verifySignature: (NSData*)signature ofData: (NSData*)data {
snej@0
    56
    Assert(data);
snej@0
    57
    Assert(signature);
snej@0
    58
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
snej@0
    59
    CC_SHA1(data.bytes,data.length, digest);
snej@0
    60
    OSStatus err = SecKeyRawVerify(self.keyRef, kSecPaddingPKCS1SHA1,
snej@0
    61
                                   digest,sizeof(digest), //data.bytes, data.length,
snej@0
    62
                                   signature.bytes, signature.length);
snej@0
    63
    return err==noErr;
snej@0
    64
}
snej@0
    65
snej@0
    66
snej@0
    67
@end
snej@0
    68
snej@0
    69
snej@0
    70
snej@0
    71
snej@0
    72
NSData* _crypt(SecKeyRef key, NSData *data, CCOperation op) {
snej@0
    73
    CAssert(data);
snej@0
    74
    size_t dataLength = data.length;
snej@0
    75
    size_t outputLength = MAX(dataLength, SecKeyGetBlockSize(key));
snej@0
    76
    void *outputBuf = malloc(outputLength);
snej@0
    77
    if (!outputBuf) return nil;
snej@0
    78
    OSStatus err;
snej@0
    79
    if (op==kCCEncrypt)
snej@0
    80
        err = SecKeyEncrypt(key, kSecPaddingNone,//PKCS1, 
snej@0
    81
                            data.bytes, dataLength,
snej@0
    82
                            outputBuf, &outputLength);
snej@0
    83
    else
snej@0
    84
        err = SecKeyDecrypt(key, kSecPaddingNone,//PKCS1, 
snej@0
    85
                            data.bytes, dataLength,
snej@0
    86
                            outputBuf, &outputLength);
snej@0
    87
    if (err) {
snej@0
    88
        free(outputBuf);
snej@0
    89
        Warn(@"%scrypting failed (%i)", (op==kCCEncrypt ?"En" :"De"), err);
snej@0
    90
        // Note: One of the errors I've seen is -9809, which is errSSLCrypto (SecureTransport.h)
snej@0
    91
        return nil;
snej@0
    92
    } else
snej@0
    93
        return [NSData dataWithBytesNoCopy: outputBuf length: outputLength freeWhenDone: YES];
snej@0
    94
}
snej@0
    95
snej@0
    96
#endif USE_IPHONE_API