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
|