Browse Source

RA Image
增加对网络接口传的账号密码进行加密

Ray Zhang 9 năm trước cách đây
mục cha
commit
641de59936

BIN
RA Image/RA Image.xcodeproj/project.xcworkspace/xcuserdata/ray.xcuserdatad/UserInterfaceState.xcuserstate


+ 6 - 3
RA Image/RA Image/ModelModeViewController.m

@@ -12,6 +12,8 @@
 #import <AssetsLibrary/AssetsLibrary.h>
 #import "ManufacturerListController.h"
 #import "UploadViewController.h"
+#import "AESCrypt.h"
+
 
 @interface ModelModeViewController ()<UITextViewDelegate>
 
@@ -120,11 +122,12 @@
         
         task[@"url"]=Appdelegate.address;
         NSString *md5 = [photo objectForKey:@"md5"];
-        
+        NSString* encryptu=[AESCrypt encrypt:Appdelegate.user password:@"usai"];
+        NSString* encryptp=[AESCrypt encrypt:Appdelegate.password password:@"usai"] ;
         
         NSMutableDictionary* params = [@{
-                                         @"user" : Appdelegate.user,
-                                         @"password" : Appdelegate.password,
+                                         @"user" : encryptu,
+                                         @"password" : encryptp,
                                          @"mode":self.name,
                                          @"barcode":self.barcode,
                                          @"_operate":@"upload",

+ 8 - 2
RA Image/RA Image/PopModeViewController.m

@@ -10,6 +10,8 @@
 
 #import "PopModeViewController.h"
 #import "UploadViewController.h"
+#import "AESCrypt.h"
+
 
 @interface PopModeViewController ()
 @property (strong, nonatomic) IBOutlet UIButton *scanBtn;
@@ -91,9 +93,13 @@
         task[@"url"]=Appdelegate.address;
         NSString *md5 = [photo objectForKey:@"md5"];
         
+        
+        
+        NSString* encryptu=[AESCrypt encrypt:Appdelegate.user password:@"usai"];
+        NSString* encryptp=[AESCrypt encrypt:Appdelegate.password password:@"usai"] ;
         NSDictionary* params = @{
-                                 @"user" : Appdelegate.user,
-                                 @"password" : Appdelegate.password,
+                                 @"user" : encryptu,
+                                 @"password" : encryptp,
                                  @"mode":self.name,
                                  @"barcode":self.barcode,
                                  @"_operate":@"upload",

+ 7 - 2
RA Image/RA Image/RAINetwork.m

@@ -106,8 +106,13 @@
 }
 
 + (NSDictionary *)Login:(NSString *)user password:(NSString *)password {
-    NSMutableDictionary *params = @{@"user":user,
-                                    @"password":password,
+    
+    
+    NSString* encryptu=[AESCrypt encrypt:user password:@"usai"];
+    NSString* encryptp=[AESCrypt encrypt:password password:@"usai"] ;
+    
+    NSMutableDictionary *params = @{@"user":encryptu,
+                                    @"password":encryptp,
                                     @"_operate":@"handset_login"
                                     }.mutableCopy;
     AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

+ 42 - 0
common/AES/AESCrypt.h

@@ -0,0 +1,42 @@
+//
+//  AESCrypt.h
+//  Gurpartap Singh
+//
+//  Created by Gurpartap Singh on 06/05/12.
+//  Copyright (c) 2012 Gurpartap Singh
+// 
+// 	MIT License
+// 
+// 	Permission is hereby granted, free of charge, to any person obtaining
+// 	a copy of this software and associated documentation files (the
+// 	"Software"), to deal in the Software without restriction, including
+// 	without limitation the rights to use, copy, modify, merge, publish,
+// 	distribute, sublicense, and/or sell copies of the Software, and to
+// 	permit persons to whom the Software is furnished to do so, subject to
+// 	the following conditions:
+// 
+// 	The above copyright notice and this permission notice shall be
+// 	included in all copies or substantial portions of the Software.
+// 
+// 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// 	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// 	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// 	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// 	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#import <Foundation/Foundation.h>
+
+
+@interface AESCrypt : NSObject
++(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString*) gkey;
++(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString*) gkey;
++ (NSString *)encrypt:(NSString *)message password:(NSString *)password;
++ (NSString *)decrypt:(NSString *)base64EncodedString password:(NSString *)password;
++ (NSString *)fastdecrypt:(NSString *)base64EncodedString ;
++ (NSString *)fastencrypt:(NSString *)message;
+//+ (NSString *)simple_encrypt:(NSString *)message password:(NSString *)password;
+//+ (NSString *)simple_decrypt:(NSString *)base64EncodedString password:(NSString *)password;
+@end

+ 316 - 0
common/AES/AESCrypt.m

@@ -0,0 +1,316 @@
+//
+//  AESCrypt.m
+//  Gurpartap Singh
+//
+//  Created by Gurpartap Singh on 06/05/12.
+//  Copyright (c) 2012 Gurpartap Singh
+// 
+// 	MIT License
+// 
+// 	Permission is hereby granted, free of charge, to any person obtaining
+// 	a copy of this software and associated documentation files (the
+// 	"Software"), to deal in the Software without restriction, including
+// 	without limitation the rights to use, copy, modify, merge, publish,
+// 	distribute, sublicense, and/or sell copies of the Software, and to
+// 	permit persons to whom the Software is furnished to do so, subject to
+// 	the following conditions:
+// 
+// 	The above copyright notice and this permission notice shall be
+// 	included in all copies or substantial portions of the Software.
+// 
+// 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// 	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// 	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// 	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// 	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#import "AESCrypt.h"
+
+#import "NSData+Base64.h"
+#import "NSString+Base64.h"
+#import "NSData+CommonCrypto.h"
+#import "config.h"
+
+@implementation AESCrypt
+
+
+#pragma simple aes
+
++(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString*) gkey
+{
+    NSString* gIv = nil;
+    char keyPtr[kCCKeySizeAES128+1];
+    memset(keyPtr, 0, sizeof(keyPtr));
+    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
+    
+    char ivPtr[kCCBlockSizeAES128+1];
+    memset(ivPtr, 0, sizeof(ivPtr));
+    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
+    
+    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
+    NSUInteger dataLength = [data length];
+    
+    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
+    size_t newSize = 0;
+    
+    if(diff > 0)
+    {
+        newSize = dataLength + diff;
+    }
+    
+    //    char dataPtr[newSize];
+    //    memcpy(dataPtr, [data bytes], [data length]);
+    //    for(int i = 0; i < diff; i++)
+    //    {
+    //        dataPtr[i + dataLength] = 0x00;
+    //    }
+    
+    size_t bufferSize = newSize + kCCBlockSizeAES128;
+    void *buffer = malloc(bufferSize);
+    memset(buffer, 0, bufferSize);
+    
+    size_t numBytesCrypted = 0;
+    
+    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
+                                          kCCAlgorithmAES128,
+                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,               //No padding
+                                          keyPtr,
+                                          kCCKeySizeAES128,
+                                          ivPtr,
+                                          [data bytes],
+                                          [data length],
+                                          buffer,
+                                          bufferSize,
+                                          &numBytesCrypted);
+    
+    if (cryptStatus == kCCSuccess) {
+        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
+        //        return [GTMBase64 stringByEncodingData:resultData];
+        
+        
+        NSString *base64EncodedString = [resultData base64EncodedStringWithOptions:0];//[NSString base64StringFromData:resultData length:[resultData length]];
+        return base64EncodedString;
+    }
+    free(buffer);
+    return nil;
+}
++(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString*) gkey
+{
+    
+    NSString* gIv = nil;
+    char keyPtr[kCCKeySizeAES128 + 1];
+    memset(keyPtr, 0, sizeof(keyPtr));
+    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
+    
+    char ivPtr[kCCBlockSizeAES128 + 1];
+    memset(ivPtr, 0, sizeof(ivPtr));
+    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
+    
+    // NSData* d1 = [encryptText dataUsingEncoding:NSUTF8StringEncoding];
+    NSData *encryptedData =[[NSData alloc] initWithBase64EncodedString:encryptText options:NSDataBase64DecodingIgnoreUnknownCharacters];
+    
+    //[[NSData alloc] initWithBase64EncodedString:stringBase64 options:NSDataBase64DecodingIgnoreUnknownCharacters];//[NSData base64DataFromString:encryptText];
+    NSData *data = encryptedData;//[GTMBase64 decodeData:];
+    NSUInteger dataLength = [data length];
+    size_t bufferSize = dataLength + kCCBlockSizeAES128;
+    void *buffer = malloc(bufferSize);
+    
+    size_t numBytesCrypted = 0;
+    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
+                                          kCCAlgorithmAES128,
+                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,
+                                          keyPtr,
+                                          kCCBlockSizeAES128,
+                                          ivPtr,
+                                          [data bytes],
+                                          dataLength,
+                                          buffer,
+                                          bufferSize,
+                                          &numBytesCrypted);
+    if (cryptStatus == kCCSuccess) {
+        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
+        return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding] ;
+    }
+    free(buffer);
+    return nil;
+}
+//+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString*) gkey
+//{
+//    NSString* gIv = nil;
+//    char keyPtr[kCCKeySizeAES128+1];
+//    memset(keyPtr, 0, sizeof(keyPtr));
+//    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
+//    
+//    char ivPtr[kCCBlockSizeAES128+1];
+//    memset(ivPtr, 0, sizeof(ivPtr));
+//    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
+//    
+//    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
+//    NSUInteger dataLength = [data length];
+//    
+//    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
+//    int newSize = 0;
+//    
+//    if(diff > 0)
+//    {
+//        newSize = dataLength + diff;
+//    }
+//    
+//    char dataPtr[newSize];
+//    memcpy(dataPtr, [data bytes], [data length]);
+//    for(int i = 0; i < diff; i++)
+//    {
+//        dataPtr[i + dataLength] = 0x00;
+//    }
+//    
+//    size_t bufferSize = newSize + kCCBlockSizeAES128;
+//    void *buffer = malloc(bufferSize);
+//    memset(buffer, 0, bufferSize);
+//    
+//    size_t numBytesCrypted = 0;
+//    
+//    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
+//                                          kCCAlgorithmAES128,
+//                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,               //No padding
+//                                          keyPtr,
+//                                          kCCKeySizeAES128,
+//                                          ivPtr,
+//                                          dataPtr,
+//                                          sizeof(dataPtr),
+//                                          buffer,
+//                                          bufferSize,
+//                                          &numBytesCrypted);
+//    
+//    if (cryptStatus == kCCSuccess) {
+//        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
+////        return [GTMBase64 stringByEncodingData:resultData];
+//        
+//        
+//        NSString *base64EncodedString = [NSString base64StringFromData:resultData length:[resultData length]];
+//        return base64EncodedString;
+//    }
+//    free(buffer);
+//    return nil;
+//}
+//
+//+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString*) gkey
+//{
+//    
+//    NSString* gIv = nil;
+//    char keyPtr[kCCKeySizeAES128 + 1];
+//    memset(keyPtr, 0, sizeof(keyPtr));
+//    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
+//    
+//    char ivPtr[kCCBlockSizeAES128 + 1];
+//    memset(ivPtr, 0, sizeof(ivPtr));
+//    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
+//    
+//    
+//    NSData *encryptedData = [NSData base64DataFromString:encryptText];
+//    NSData *data = encryptedData;//[GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
+//    NSUInteger dataLength = [data length];
+//    size_t bufferSize = dataLength + kCCBlockSizeAES128;
+//    void *buffer = malloc(bufferSize);
+//    
+//    size_t numBytesCrypted = 0;
+//    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
+//                                          kCCAlgorithmAES128,
+//                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,
+//                                          keyPtr,
+//                                          kCCBlockSizeAES128,
+//                                          ivPtr,
+//                                          [data bytes],
+//                                          dataLength,
+//                                          buffer,
+//                                          bufferSize,
+//                                          &numBytesCrypted);
+//    if (cryptStatus == kCCSuccess) {
+//        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
+//        return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding] ;
+//    }
+//    free(buffer);
+//    return nil;
+//}
+
+
+
++ (NSString *)encrypt:(NSString *)message password:(NSString *)password {
+    
+#ifdef ENCRYPT_OFF
+    return message;
+#endif
+    
+//    message=@"NEW PACIFIC DIRECT";
+//    NSData* msgdata=[message dataUsingEncoding:NSUTF8StringEncoding];
+//    NSData* passdata=[password dataUsingEncoding:NSUTF8StringEncoding];
+//    NSData* SHA256Hash = [passdata SHA256Hash];
+//    NSString *SHA256Hashresult = [[NSString alloc] initWithData:SHA256Hash  encoding:NSUTF8StringEncoding];
+  //  message=@"NEW PACIFIC DIRECT";
+  NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash]  error:nil];
+  NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
+  return base64EncodedString;
+}
+
+
+//+ (NSString *)simple_encrypt:(NSString *)message password:(NSString *)password {
+//    
+//
+//    
+//    //    message=@"NEW PACIFIC DIRECT";
+//    //    NSData* msgdata=[message dataUsingEncoding:NSUTF8StringEncoding];
+//    //    NSData* passdata=[password dataUsingEncoding:NSUTF8StringEncoding];
+//    //    NSData* SHA256Hash = [passdata SHA256Hash];
+//    //    NSString *SHA256Hashresult = [[NSString alloc] initWithData:SHA256Hash  encoding:NSUTF8StringEncoding];
+//    //  message=@"NEW PACIFIC DIRECT";
+//  //  NSString* aaa=[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash];;
+//    NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:password  error:nil];
+//    NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
+//    return base64EncodedString;
+//}
+
++ (NSString *)decrypt:(NSString *)base64EncodedString password:(NSString *)password {
+#ifdef ENCRYPT_OFF
+    return base64EncodedString;
+#endif
+    
+    if(base64EncodedString==nil)
+        return nil;
+    if(base64EncodedString.length==0)
+        return @"";
+  NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
+  NSData *decryptedData = [encryptedData decryptedAES256DataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
+  return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
+}
+
+
+//+ (NSString *)simple_decrypt:(NSString *)base64EncodedString password:(NSString *)password
+//{
+//
+//    
+//    if(base64EncodedString==nil)
+//        return nil;
+//    if(base64EncodedString.length==0)
+//        return @"";
+//    NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
+//    NSData *decryptedData = [encryptedData decryptedAES256DataUsingKey:password error:nil];
+//    return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
+//}
+
++ (NSString *)fastdecrypt:(NSString *)base64EncodedString
+{
+    NSString* ret=[self decrypt:base64EncodedString password:@"usai"];
+    if(ret==nil)
+        ret= @"";
+    return ret;
+}
+
++ (NSString *)fastencrypt:(NSString *)message
+{
+    
+    return [self encrypt:message password:@"usai"];
+}
+
+@end

+ 22 - 0
common/AES/LICENSE

@@ -0,0 +1,22 @@
+Copyright (c) 2012 Gurpartap Singh
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 17 - 0
common/AES/NSData+Base64.h

@@ -0,0 +1,17 @@
+//
+//  NSData+Base64.m
+//  Gurpartap Singh
+//
+//  Created by Gurpartap Singh on 06/05/12.
+//  Copyright (c) 2012 Gurpartap Singh. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class NSString;
+
+@interface NSData (Base64Additions)
+
++ (NSData *)base64DataFromString:(NSString *)string;
+
+@end

+ 110 - 0
common/AES/NSData+Base64.m

@@ -0,0 +1,110 @@
+//
+//  NSData+Base64.h
+//  Gurpartap Singh
+//
+//  Created by Gurpartap Singh on 06/05/12.
+//  Copyright (c) 2012 Gurpartap Singh. All rights reserved.
+//
+
+#import "NSData+Base64.h"
+
+@implementation NSData (Base64Additions)
+
++ (NSData *)base64DataFromString:(NSString *)string {
+  unsigned long ixtext, lentext;
+  unsigned char ch, inbuf[4], outbuf[3];
+  short i, ixinbuf;
+  Boolean flignore, flendtext = false;
+  const unsigned char *tempcstring;
+  NSMutableData *theData;
+  
+  if (string == nil) {
+    return [NSData data];
+  }
+  
+  ixtext = 0;
+  
+  tempcstring = (const unsigned char *)[string UTF8String];
+  
+  lentext = [string length];
+  
+  theData = [NSMutableData dataWithCapacity: lentext];
+  
+  ixinbuf = 0;
+  
+  while (true) {
+    if (ixtext >= lentext) {
+      break;
+    }
+    
+    ch = tempcstring [ixtext++];
+    
+    flignore = false;
+    
+    if ((ch >= 'A') && (ch <= 'Z')) {
+      ch = ch - 'A';
+    }
+    else if ((ch >= 'a') && (ch <= 'z')) {
+      ch = ch - 'a' + 26;
+    }
+    else if ((ch >= '0') && (ch <= '9')) {
+      ch = ch - '0' + 52;
+    }
+    else if (ch == '+') {
+      ch = 62;
+    }
+    else if (ch == '=') {
+      flendtext = true;
+    }
+    else if (ch == '/') {
+      ch = 63;
+    }
+    else {
+      flignore = true; 
+    }
+    
+    if (!flignore) {
+      short ctcharsinbuf = 3;
+      Boolean flbreak = false;
+      
+      if (flendtext) {
+        if (ixinbuf == 0) {
+          break;
+        }
+        
+        if ((ixinbuf == 1) || (ixinbuf == 2)) {
+          ctcharsinbuf = 1;
+        }
+        else {
+          ctcharsinbuf = 2;
+        }
+        
+        ixinbuf = 3;
+        
+        flbreak = true;
+      }
+      
+      inbuf [ixinbuf++] = ch;
+      
+      if (ixinbuf == 4) {
+        ixinbuf = 0;
+        
+        outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
+        outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
+        outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
+        
+        for (i = 0; i < ctcharsinbuf; i++) {
+          [theData appendBytes: &outbuf[i] length: 1];
+        }
+      }
+      
+      if (flbreak) {
+        break;
+      }
+    }
+  }
+  
+  return theData;
+}
+
+@end

+ 112 - 0
common/AES/NSData+CommonCrypto.h

@@ -0,0 +1,112 @@
+/*
+ *  NSData+CommonCrypto.h
+ *  AQToolkit
+ *
+ *  Created by Jim Dovey on 31/8/2008.
+ *
+ *  Copyright (c) 2008-2009, Jim Dovey
+ *  All rights reserved.
+ *  
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  
+ *  Neither the name of this project's author nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/NSData.h>
+#import <Foundation/NSError.h>
+#import <CommonCrypto/CommonCryptor.h>
+#import <CommonCrypto/CommonHMAC.h>
+
+extern NSString * const kCommonCryptoErrorDomain;
+
+@interface NSError (CommonCryptoErrorDomain)
++ (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status;
+@end
+
+@interface NSData (CommonDigest)
+
+- (NSData *) MD2Sum;
+- (NSData *) MD4Sum;
+- (NSData *) MD5Sum;
+
+- (NSData *) SHA1Hash;
+- (NSData *) SHA224Hash;
+- (NSData *) SHA256Hash;
+- (NSData *) SHA384Hash;
+- (NSData *) SHA512Hash;
+
+@end
+
+@interface NSData (CommonCryptor)
+
+- (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error;
+- (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error;
+
+- (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error;
+- (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error;
+
+- (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error;
+- (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error;
+
+@end
+
+@interface NSData (LowLevelCommonCryptor)
+
+- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                                   error: (CCCryptorStatus *) error;
+- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error;
+- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                    initializationVector: (id) iv		// data or string
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error;
+
+- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                                   error: (CCCryptorStatus *) error;
+- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error;
+- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                    initializationVector: (id) iv		// data or string
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error;
+
+@end
+
+@interface NSData (CommonHMAC)
+
+- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm;
+- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key;
+
+@end

+ 546 - 0
common/AES/NSData+CommonCrypto.m

@@ -0,0 +1,546 @@
+/*
+ *  NSData+CommonCrypto.m
+ *  AQToolkit
+ *
+ *  Created by Jim Dovey on 31/8/2008.
+ *
+ *  Copyright (c) 2008-2009, Jim Dovey
+ *  All rights reserved.
+ *  
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  
+ *  Neither the name of this project's author nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+#import "NSData+CommonCrypto.h"
+#import <CommonCrypto/CommonDigest.h>
+#import <CommonCrypto/CommonCryptor.h>
+#import <CommonCrypto/CommonHMAC.h>
+
+NSString * const kCommonCryptoErrorDomain = @"CommonCryptoErrorDomain";
+
+@implementation NSError (CommonCryptoErrorDomain)
+
++ (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status
+{
+	NSString * description = nil, * reason = nil;
+	
+	switch ( status )
+	{
+		case kCCSuccess:
+			description = NSLocalizedString(@"Success", @"Error description");
+			break;
+			
+		case kCCParamError:
+			description = NSLocalizedString(@"Parameter Error", @"Error description");
+			reason = NSLocalizedString(@"Illegal parameter supplied to encryption/decryption algorithm", @"Error reason");
+			break;
+			
+		case kCCBufferTooSmall:
+			description = NSLocalizedString(@"Buffer Too Small", @"Error description");
+			reason = NSLocalizedString(@"Insufficient buffer provided for specified operation", @"Error reason");
+			break;
+			
+		case kCCMemoryFailure:
+			description = NSLocalizedString(@"Memory Failure", @"Error description");
+			reason = NSLocalizedString(@"Failed to allocate memory", @"Error reason");
+			break;
+			
+		case kCCAlignmentError:
+			description = NSLocalizedString(@"Alignment Error", @"Error description");
+			reason = NSLocalizedString(@"Input size to encryption algorithm was not aligned correctly", @"Error reason");
+			break;
+			
+		case kCCDecodeError:
+			description = NSLocalizedString(@"Decode Error", @"Error description");
+			reason = NSLocalizedString(@"Input data did not decode or decrypt correctly", @"Error reason");
+			break;
+			
+		case kCCUnimplemented:
+			description = NSLocalizedString(@"Unimplemented Function", @"Error description");
+			reason = NSLocalizedString(@"Function not implemented for the current algorithm", @"Error reason");
+			break;
+			
+		default:
+			description = NSLocalizedString(@"Unknown Error", @"Error description");
+			break;
+	}
+	
+	NSMutableDictionary * userInfo = [[NSMutableDictionary alloc] init];
+	[userInfo setObject: description forKey: NSLocalizedDescriptionKey];
+	
+	if ( reason != nil )
+		[userInfo setObject: reason forKey: NSLocalizedFailureReasonErrorKey];
+	
+	NSError * result = [NSError errorWithDomain: kCommonCryptoErrorDomain code: status userInfo: userInfo];
+    #if !__has_feature(objc_arc)
+        [userInfo release];
+    #endif
+	
+	return ( result );
+}
+
+@end
+
+#pragma mark -
+
+@implementation NSData (CommonDigest)
+
+- (NSData *) MD2Sum
+{
+	unsigned char hash[CC_MD2_DIGEST_LENGTH];
+	(void) CC_MD2( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_MD2_DIGEST_LENGTH] );
+}
+
+- (NSData *) MD4Sum
+{
+	unsigned char hash[CC_MD4_DIGEST_LENGTH];
+	(void) CC_MD4( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_MD4_DIGEST_LENGTH] );
+}
+
+- (NSData *) MD5Sum
+{
+	unsigned char hash[CC_MD5_DIGEST_LENGTH];
+	(void) CC_MD5( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_MD5_DIGEST_LENGTH] );
+}
+
+- (NSData *) SHA1Hash
+{
+	unsigned char hash[CC_SHA1_DIGEST_LENGTH];
+	(void) CC_SHA1( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_SHA1_DIGEST_LENGTH] );
+}
+
+- (NSData *) SHA224Hash
+{
+	unsigned char hash[CC_SHA224_DIGEST_LENGTH];
+	(void) CC_SHA224( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_SHA224_DIGEST_LENGTH] );
+}
+
+- (NSData *) SHA256Hash
+{
+	unsigned char hash[CC_SHA256_DIGEST_LENGTH];
+	(void) CC_SHA256( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_SHA256_DIGEST_LENGTH] );
+}
+
+- (NSData *) SHA384Hash
+{
+	unsigned char hash[CC_SHA384_DIGEST_LENGTH];
+	(void) CC_SHA384( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_SHA384_DIGEST_LENGTH] );
+}
+
+- (NSData *) SHA512Hash
+{
+	unsigned char hash[CC_SHA512_DIGEST_LENGTH];
+	(void) CC_SHA512( [self bytes], (CC_LONG)[self length], hash );
+	return ( [NSData dataWithBytes: hash length: CC_SHA512_DIGEST_LENGTH] );
+}
+
+@end
+
+@implementation NSData (CommonCryptor)
+
+- (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error
+{
+	CCCryptorStatus status = kCCSuccess;
+	NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmAES128
+                                                  key: key
+                                              options: kCCOptionPKCS7Padding
+                                                error: &status];
+	
+	if ( result != nil )
+		return ( result );
+	
+	if ( error != NULL )
+		*error = [NSError errorWithCCCryptorStatus: status];
+	
+	return ( nil );
+}
+
+- (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error
+{
+	CCCryptorStatus status = kCCSuccess;
+	NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmAES128
+                                                  key: key
+                                              options: kCCOptionPKCS7Padding
+                                                error: &status];
+	
+	if ( result != nil )
+		return ( result );
+	
+	if ( error != NULL )
+		*error = [NSError errorWithCCCryptorStatus: status];
+	
+	return ( nil );
+}
+
+- (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error
+{
+	CCCryptorStatus status = kCCSuccess;
+	NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmDES
+                                                  key: key
+                                              options: kCCOptionPKCS7Padding
+                                                error: &status];
+	
+	if ( result != nil )
+		return ( result );
+	
+	if ( error != NULL )
+		*error = [NSError errorWithCCCryptorStatus: status];
+	
+	return ( nil );
+}
+
+- (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error
+{
+	CCCryptorStatus status = kCCSuccess;
+	NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmDES
+                                                  key: key
+                                              options: kCCOptionPKCS7Padding
+                                                error: &status];
+	
+	if ( result != nil )
+		return ( result );
+	
+	if ( error != NULL )
+		*error = [NSError errorWithCCCryptorStatus: status];
+	
+	return ( nil );
+}
+
+- (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error
+{
+	CCCryptorStatus status = kCCSuccess;
+	NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmCAST
+                                                  key: key
+                                              options: kCCOptionPKCS7Padding
+                                                error: &status];
+	
+	if ( result != nil )
+		return ( result );
+	
+	if ( error != NULL )
+		*error = [NSError errorWithCCCryptorStatus: status];
+	
+	return ( nil );
+}
+
+- (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error
+{
+	CCCryptorStatus status = kCCSuccess;
+	NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmCAST
+                                                  key: key
+                                              options: kCCOptionPKCS7Padding
+                                                error: &status];
+	
+	if ( result != nil )
+		return ( result );
+	
+	if ( error != NULL )
+		*error = [NSError errorWithCCCryptorStatus: status];
+	
+	return ( nil );
+}
+
+@end
+
+static void FixKeyLengths( CCAlgorithm algorithm, NSMutableData * keyData, NSMutableData * ivData )
+{
+	NSUInteger keyLength = [keyData length];
+	switch ( algorithm )
+	{
+		case kCCAlgorithmAES128:
+		{
+			if ( keyLength < 16 )
+			{
+				[keyData setLength: 16];
+			}
+			else if ( keyLength < 24 )
+			{
+				[keyData setLength: 24];
+			}
+			else
+			{
+				[keyData setLength: 32];
+			}
+			
+			break;
+		}
+			
+		case kCCAlgorithmDES:
+		{
+			[keyData setLength: 8];
+			break;
+		}
+			
+		case kCCAlgorithm3DES:
+		{
+			[keyData setLength: 24];
+			break;
+		}
+			
+		case kCCAlgorithmCAST:
+		{
+			if ( keyLength < 5 )
+			{
+				[keyData setLength: 5];
+			}
+			else if ( keyLength > 16 )
+			{
+				[keyData setLength: 16];
+			}
+			
+			break;
+		}
+			
+		case kCCAlgorithmRC4:
+		{
+			if ( keyLength > 512 )
+				[keyData setLength: 512];
+			break;
+		}
+			
+		default:
+			break;
+	}
+	
+	[ivData setLength: [keyData length]];
+}
+
+@implementation NSData (LowLevelCommonCryptor)
+
+- (NSData *) _runCryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus *) status
+{
+	size_t bufsize = CCCryptorGetOutputLength( cryptor, (size_t)[self length], true );
+	void * buf = malloc( bufsize );
+	size_t bufused = 0;
+  size_t bytesTotal = 0;
+	*status = CCCryptorUpdate( cryptor, [self bytes], (size_t)[self length], 
+                            buf, bufsize, &bufused );
+	if ( *status != kCCSuccess )
+	{
+		free( buf );
+		return ( nil );
+	}
+  
+  bytesTotal += bufused;
+	
+	// From Brent Royal-Gordon (Twitter: architechies):
+	//  Need to update buf ptr past used bytes when calling CCCryptorFinal()
+	*status = CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused );
+	if ( *status != kCCSuccess )
+	{
+		free( buf );
+		return ( nil );
+	}
+  
+  bytesTotal += bufused;
+	
+	return ( [NSData dataWithBytesNoCopy: buf length: bytesTotal] );
+}
+
+- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key
+                                   error: (CCCryptorStatus *) error
+{
+	return ( [self dataEncryptedUsingAlgorithm: algorithm
+                                         key: key
+                        initializationVector: nil
+                                     options: 0
+                                       error: error] );
+}
+
+- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error
+{
+  return ( [self dataEncryptedUsingAlgorithm: algorithm
+                                         key: key
+                        initializationVector: nil
+                                     options: options
+                                       error: error] );
+}
+
+- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key
+                    initializationVector: (id) iv
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error
+{
+	CCCryptorRef cryptor = NULL;
+	CCCryptorStatus status = kCCSuccess;
+	
+	NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
+	NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
+	
+	NSMutableData * keyData, * ivData;
+	if ( [key isKindOfClass: [NSData class]] )
+		keyData = (NSMutableData *) [key mutableCopy];
+	else
+		keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
+	
+	if ( [iv isKindOfClass: [NSString class]] )
+		ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
+	else
+		ivData = (NSMutableData *) [iv mutableCopy];	// data or nil
+	
+    #if !__has_feature(objc_arc)
+        [keyData autorelease];
+        [ivData autorelease];
+	#endif
+	// ensure correct lengths for key and iv data, based on algorithms
+	FixKeyLengths( algorithm, keyData, ivData );
+	
+	status = CCCryptorCreate( kCCEncrypt, algorithm, options,
+                           [keyData bytes], [keyData length], [ivData bytes],
+                           &cryptor );
+	
+	if ( status != kCCSuccess )
+	{
+		if ( error != NULL )
+			*error = status;
+		return ( nil );
+	}
+	
+	NSData * result = [self _runCryptor: cryptor result: &status];
+	if ( (result == nil) && (error != NULL) )
+		*error = status;
+	
+	CCCryptorRelease( cryptor );
+	
+	return ( result );
+}
+
+- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                                   error: (CCCryptorStatus *) error
+{
+	return ( [self decryptedDataUsingAlgorithm: algorithm
+                                         key: key
+                        initializationVector: nil
+                                     options: 0
+                                       error: error] );
+}
+
+- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error
+{
+  return ( [self decryptedDataUsingAlgorithm: algorithm
+                                         key: key
+                        initializationVector: nil
+                                     options: options
+                                       error: error] );
+}
+
+- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
+                                     key: (id) key		// data or string
+                    initializationVector: (id) iv		// data or string
+                                 options: (CCOptions) options
+                                   error: (CCCryptorStatus *) error
+{
+	CCCryptorRef cryptor = NULL;
+	CCCryptorStatus status = kCCSuccess;
+	
+	NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
+	NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
+	
+	NSMutableData * keyData, * ivData;
+	if ( [key isKindOfClass: [NSData class]] )
+		keyData = (NSMutableData *) [key mutableCopy];
+	else
+		keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
+	
+	if ( [iv isKindOfClass: [NSString class]] )
+		ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
+	else
+		ivData = (NSMutableData *) [iv mutableCopy];	// data or nil
+	
+    #if !__has_feature(objc_arc)
+        [keyData autorelease];
+        [ivData autorelease];
+    #endif
+	
+	// ensure correct lengths for key and iv data, based on algorithms
+	FixKeyLengths( algorithm, keyData, ivData );
+	
+	status = CCCryptorCreate( kCCDecrypt, algorithm, options,
+                           [keyData bytes], [keyData length], [ivData bytes],
+                           &cryptor );
+	
+	if ( status != kCCSuccess )
+	{
+		if ( error != NULL )
+			*error = status;
+		return ( nil );
+	}
+	
+	NSData * result = [self _runCryptor: cryptor result: &status];
+	if ( (result == nil) && (error != NULL) )
+		*error = status;
+	
+	CCCryptorRelease( cryptor );
+	
+	return ( result );
+}
+
+@end
+
+@implementation NSData (CommonHMAC)
+
+- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm
+{
+	return ( [self HMACWithAlgorithm: algorithm key: nil] );
+}
+
+- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key
+{
+	NSParameterAssert(key == nil || [key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
+	
+	NSData * keyData = nil;
+	if ( [key isKindOfClass: [NSString class]] )
+		keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
+	else
+		keyData = (NSData *) key;
+	
+	// this could be either CC_SHA1_DIGEST_LENGTH or CC_MD5_DIGEST_LENGTH. SHA1 is larger.
+	unsigned char buf[CC_SHA1_DIGEST_LENGTH];
+	CCHmac( algorithm, [keyData bytes], [keyData length], [self bytes], [self length], buf );
+	
+	return ( [NSData dataWithBytes: buf length: (algorithm == kCCHmacAlgMD5 ? CC_MD5_DIGEST_LENGTH : CC_SHA1_DIGEST_LENGTH)] );
+}
+
+@end

+ 15 - 0
common/AES/NSString+Base64.h

@@ -0,0 +1,15 @@
+//
+//  NSString+Base64.h
+//  Gurpartap Singh
+//
+//  Created by Gurpartap Singh on 06/05/12.
+//  Copyright (c) 2012 Gurpartap Singh. All rights reserved.
+//
+
+#import <Foundation/NSString.h>
+#import<Foundation/Foundation.h>
+@interface NSString (Base64Additions)
+
++ (NSString *)base64StringFromData:(NSData *)data length:(NSUInteger)length;
+
+@end

+ 82 - 0
common/AES/NSString+Base64.m

@@ -0,0 +1,82 @@
+//
+//  NSStringAdditions.m
+//  Gurpartap Singh
+//
+//  Created by Gurpartap Singh on 06/05/12.
+//  Copyright (c) 2012 Gurpartap Singh. All rights reserved.
+//
+
+#import "NSString+Base64.h"
+
+static char base64EncodingTable[64] = {
+  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+  'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
+
+@implementation NSString (Base64Additions)
+
++ (NSString *)base64StringFromData: (NSData *)data length: (NSUInteger)length {
+  unsigned long ixtext, lentext;
+  long ctremaining;
+  unsigned char input[3], output[4];
+  short i, charsonline = 0, ctcopy;
+  const unsigned char *raw;
+  NSMutableString *result;
+  
+  lentext = [data length]; 
+  if (lentext < 1) {
+    return @"";
+  }
+  result = [NSMutableString stringWithCapacity: lentext];
+  raw = [data bytes];
+  ixtext = 0; 
+  
+  while (true) {
+    ctremaining = lentext - ixtext;
+    if (ctremaining <= 0) {
+      break;
+    }
+    for (i = 0; i < 3; i++) { 
+      unsigned long ix = ixtext + i;
+      if (ix < lentext) {
+        input[i] = raw[ix];
+      }
+      else {
+        input[i] = 0;
+      }
+    }
+    output[0] = (input[0] & 0xFC) >> 2;
+    output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
+    output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
+    output[3] = input[2] & 0x3F;
+    ctcopy = 4;
+    switch (ctremaining) {
+      case 1: 
+        ctcopy = 2; 
+        break;
+      case 2: 
+        ctcopy = 3; 
+        break;
+    }
+    
+    for (i = 0; i < ctcopy; i++) {
+      [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
+    }
+    
+    for (i = ctcopy; i < 4; i++) {
+      [result appendString: @"="];
+    }
+    
+    ixtext += 3;
+    charsonline += 4;
+    
+    if ((length > 0) && (charsonline >= length)) {
+      charsonline = 0;
+    }
+  }     
+  return result;
+}
+
+@end