diff --git a/SoObjects/SOGo/NSData+Crypto.h b/SoObjects/SOGo/NSData+Crypto.h index 6361484b1..117fa9241 100644 --- a/SoObjects/SOGo/NSData+Crypto.h +++ b/SoObjects/SOGo/NSData+Crypto.h @@ -35,6 +35,10 @@ withSalt: (NSData *) theSalt keyPath: (NSString *) theKeyPath; +- (BOOL) verifyUsingScheme: (NSString *) passwordScheme + withPassword: (NSData *) thePassword + keyPath: (NSString *) theKeyPath; + - (NSData *) asLM; - (NSData *) asMD4; - (NSData *) asMD5; diff --git a/SoObjects/SOGo/NSData+Crypto.m b/SoObjects/SOGo/NSData+Crypto.m index 81f5fcd08..b74f1c487 100644 --- a/SoObjects/SOGo/NSData+Crypto.m +++ b/SoObjects/SOGo/NSData+Crypto.m @@ -299,6 +299,35 @@ static const char salt_chars[] = return nil; } +/** + * Verify the given password data is equivalent with the + * clear text password using the passed encryption scheme + * + * @param passwordScheme The password scheme to use for comparison + * @param thePassword + */ +- (BOOL) verifyUsingScheme: (NSString *) passwordScheme + withPassword: (NSData *) thePassword + keyPath: (NSString *) theKeyPath +{ + NSData *passwordCrypted; + NSData *salt; + + salt = [self extractSalt: passwordScheme]; + if (salt == nil) + return NO; + // encrypt self with the salt an compare the results + passwordCrypted = [thePassword asCryptedPassUsingScheme: passwordScheme + withSalt: salt + keyPath: theKeyPath]; + + // return always false when there was a problem + if (passwordCrypted == nil) + return NO; + + return [self isEqual: passwordCrypted]; +} + - (NSData *) asLM { NSData *out; diff --git a/SoObjects/SOGo/NSString+Crypto.m b/SoObjects/SOGo/NSString+Crypto.m index 355a58dcc..2b0a7927e 100644 --- a/SoObjects/SOGo/NSString+Crypto.m +++ b/SoObjects/SOGo/NSString+Crypto.m @@ -41,17 +41,17 @@ { NSRange r; int len; - + len = [self length]; if (len == 0) return @""; if ([self characterAtIndex:0] != '{') return @""; - + r = [self rangeOfString:@"}" options:(NSLiteralSearch)]; if (r.length == 0) return @""; - + r.length = (r.location - 1); r.location = 1; return [[self substringWithRange:r] lowercaseString]; @@ -73,7 +73,7 @@ NSString *scheme; NSString *pass; NSArray *encodingAndScheme; - + NSRange range; int selflen, len; @@ -91,7 +91,7 @@ encodingAndScheme = [NSString getDefaultEncodingForScheme: scheme]; pass = [self substringWithRange: range]; - + // Returns an array with [scheme, password, encoding] return [NSArray arrayWithObjects: [encodingAndScheme objectAtIndex: 1], pass, [encodingAndScheme objectAtIndex: 0], nil]; } @@ -109,11 +109,10 @@ keyPath: (NSString *) theKeyPath { NSArray *passInfo; - NSString *selfCrypted; NSString *pass; NSString *scheme; - NSData *salt; NSData *decodedData; + NSData *passwordData; keyEncoding encoding; // split scheme and pass @@ -152,29 +151,17 @@ decodedData = [pass dataUsingEncoding: NSUTF8StringEncoding]; } - salt = [decodedData extractSalt: scheme]; - - // encrypt self with the salt an compare the results - selfCrypted = [self asCryptedPassUsingScheme: scheme - withSalt: salt - andEncoding: encoding - keyPath: theKeyPath]; - - // return always false when there was a problem - if (selfCrypted == nil) - return NO; - - if ([selfCrypted isEqualToString: pass] == YES) - return YES; - - return NO; + passwordData = [self dataUsingEncoding: NSUTF8StringEncoding]; + return [decodedData verifyUsingScheme: scheme + withPassword: passwordData + keyPath: theKeyPath]; } /** * Calls asCryptedPassUsingScheme:withSalt:andEncoding: with an empty salt and uses * the default encoding. * - * @param passwordScheme + * @param passwordScheme: The password scheme to hash the cleartext password. * @return If successful, the encrypted and encoded NSString of the format {scheme}pass, or nil if the scheme did not exists or an error occured */ - (NSString *) asCryptedPassUsingScheme: (NSString *) passwordScheme @@ -358,7 +345,7 @@ // See http://en.wikipedia.org/wiki/LM_hash#Algorithm d = [[self uppercaseString] dataUsingEncoding: NSWindowsCP1252StringEncoding]; - + return [[NSData encodeDataAsHexString: [d asLM]] uppercaseString]; }