diff --git a/ChangeLog b/ChangeLog index 7b26727d2..ab83cbd4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2012-04-16 Wolfgang Sourdeau + * SoObjects/SOGo/NSString+Utilities.m (-encryptWithKey:) + (-decryptWithKey:): new methods providing symmetric encryption of + strings. + * Tests/Unit/SOGoTestRunner.m (-run): do not empty the pool after each test. diff --git a/SoObjects/SOGo/NSString+Utilities.h b/SoObjects/SOGo/NSString+Utilities.h index 53bf190b9..a37f6e627 100644 --- a/SoObjects/SOGo/NSString+Utilities.h +++ b/SoObjects/SOGo/NSString+Utilities.h @@ -74,6 +74,11 @@ - (NSUInteger) countOccurrencesOfString: (NSString *) substring; + +/* Those methods provide symmetric enc-/decryption via a XOR operation */ +- (NSString *) encryptWithKey: (NSString *) theKey; +- (NSString *) decryptWithKey: (NSString *) theKey; + @end #endif /* NSSTRING_URL_H */ diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index 55838a2dc..9cfe2788f 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -35,6 +35,7 @@ #import #import +#import #import #import @@ -610,4 +611,85 @@ static int cssEscapingCount; return count; } +- (NSString *) encryptWithKey: (NSString *) theKey +{ + NSMutableData *encryptedPassword; + NSMutableString *key; + NSString *result; + NSUInteger i, passLength, theKeyLength, keyLength; + unichar p, k, e; + + if ([theKey length] > 0) + { + // The length of the key must be greater (or equal) than + // the length of the password + key = [NSMutableString string]; + keyLength = 0; + + passLength = [self length]; + theKeyLength = [theKey length]; + while (keyLength < passLength) + { + [key appendString: theKey]; + keyLength += theKeyLength; + } + + encryptedPassword = [NSMutableData data]; + for (i = 0; i < passLength; i++) + { + p = [self characterAtIndex: i]; + k = [key characterAtIndex: i]; + e = p ^ k; + [encryptedPassword appendBytes: (void *)&e length: 2]; + } + + result = [encryptedPassword stringByEncodingBase64]; + } + else + result = nil; + + return result; +} + +- (NSString *) decryptWithKey: (NSString *) theKey +{ + NSMutableString *result; + NSMutableString *key; + NSData *decoded; + unichar *decryptedPassword; + NSUInteger i, theKeyLength, keyLength, decodedLength; + unichar p, k; + + if ([theKey length] > 0) + { + decoded = [self dataByDecodingBase64]; + decryptedPassword = (unichar *)[decoded bytes]; + + // The length of the key must be greater (or equal) than + // the length of the password + key = [NSMutableString string]; + keyLength = 0; + decodedLength = ([decoded length] / 2); /* 1 unichar = 2 bytes/char */ + theKeyLength = [theKey length]; + + while (keyLength < decodedLength) + { + [key appendString: theKey]; + keyLength += theKeyLength; + } + + result = [NSMutableString string]; + for (i = 0; i < decodedLength; i++) + { + k = [key characterAtIndex: i]; + p = decryptedPassword[i] ^ k; + [result appendFormat: @"%C", p]; + } + } + else + result = nil; + + return result; +} + @end diff --git a/Tests/Unit/TestNSString+Utilities.m b/Tests/Unit/TestNSString+Utilities.m index 7f9ef5b18..6442c800f 100644 --- a/Tests/Unit/TestNSString+Utilities.m +++ b/Tests/Unit/TestNSString+Utilities.m @@ -47,4 +47,27 @@ failIf(count != 0); } +- (void) test_encryptdecrypt +{ + NSString *secret = @"this is a secret"; + NSString *password = @"qwerty"; + NSString *encresult, *decresult; + + encresult = [secret encryptWithKey: nil]; + failIf(encresult != nil); + encresult = [secret encryptWithKey: @""]; + failIf(encresult != nil); + + encresult = [secret encryptWithKey: password]; + failIf(encresult == nil); + + decresult = [encresult decryptWithKey: nil]; + failIf(decresult != nil); + decresult = [encresult decryptWithKey: @""]; + failIf(decresult != nil); + + decresult = [encresult decryptWithKey: password]; + failIf(![decresult isEqualToString: secret]); +} + @end