snej@0: // snej@0: // MYPublicKey-iPhone.m snej@0: // MYCrypto-iPhone snej@0: // snej@0: // Created by Jens Alfke on 3/30/09. snej@0: // Copyright 2009 Jens Alfke. All rights reserved. snej@0: // snej@0: snej@0: #import "MYPublicKey.h" snej@0: #import "MYCrypto_Private.h" snej@0: snej@0: #if USE_IPHONE_API snej@0: snej@0: #import "MYDigest.h" snej@0: #import "MYErrorUtils.h" snej@0: snej@0: snej@0: @implementation MYPublicKey snej@0: snej@0: snej@0: - (void) dealloc snej@0: { snej@0: [_digest release]; snej@0: [super dealloc]; snej@0: } snej@0: snej@0: snej@0: - (SecExternalItemType) keyType { snej@0: return kSecAttrKeyClassPublic; snej@0: } snej@0: snej@0: snej@0: - (MYPublicKey*) asPublicKey { snej@0: return self; snej@0: } snej@0: snej@0: snej@0: snej@0: - (MYSHA1Digest*) publicKeyDigest { snej@0: NSData *digestData = [self _attribute: kSecAttrApplicationLabel]; snej@0: if (digestData) snej@0: return (MYSHA1Digest*) [MYSHA1Digest digestFromDigestData: digestData]; snej@0: else { snej@0: Warn(@"MYKeyPair: public key didn't have digest attribute"); snej@0: return nil; snej@0: } snej@0: } snej@0: snej@0: snej@0: - (NSData*) encryptData: (NSData*)data { snej@0: return _crypt(self.keyRef,data,kCCEncrypt); snej@0: } snej@0: snej@0: snej@0: - (BOOL) verifySignature: (NSData*)signature ofData: (NSData*)data { snej@0: Assert(data); snej@0: Assert(signature); snej@0: uint8_t digest[CC_SHA1_DIGEST_LENGTH]; snej@0: CC_SHA1(data.bytes,data.length, digest); snej@0: OSStatus err = SecKeyRawVerify(self.keyRef, kSecPaddingPKCS1SHA1, snej@0: digest,sizeof(digest), //data.bytes, data.length, snej@0: signature.bytes, signature.length); snej@0: return err==noErr; snej@0: } snej@0: snej@0: snej@0: @end snej@0: snej@0: snej@0: snej@0: snej@0: NSData* _crypt(SecKeyRef key, NSData *data, CCOperation op) { snej@0: CAssert(data); snej@0: size_t dataLength = data.length; snej@0: size_t outputLength = MAX(dataLength, SecKeyGetBlockSize(key)); snej@0: void *outputBuf = malloc(outputLength); snej@0: if (!outputBuf) return nil; snej@0: OSStatus err; snej@0: if (op==kCCEncrypt) snej@0: err = SecKeyEncrypt(key, kSecPaddingNone,//PKCS1, snej@0: data.bytes, dataLength, snej@0: outputBuf, &outputLength); snej@0: else snej@0: err = SecKeyDecrypt(key, kSecPaddingNone,//PKCS1, snej@0: data.bytes, dataLength, snej@0: outputBuf, &outputLength); snej@0: if (err) { snej@0: free(outputBuf); snej@0: Warn(@"%scrypting failed (%i)", (op==kCCEncrypt ?"En" :"De"), err); snej@0: // Note: One of the errors I've seen is -9809, which is errSSLCrypto (SecureTransport.h) snej@0: return nil; snej@0: } else snej@0: return [NSData dataWithBytesNoCopy: outputBuf length: outputLength freeWhenDone: YES]; snej@0: } snej@0: snej@0: #endif USE_IPHONE_API