@@ -35,25 +35,21 @@ #import "XMPPExceptions.h" #define HMAC_IPAD 0x36 #define HMAC_OPAD 0x5c -OF_ASSUME_NONNULL_BEGIN - @interface XMPPSCRAMAuth () -- (OFString *)XMPP_genNonce; -- (const uint8_t *)XMPP_HMACWithKey: (OFData *)key +- (OFString *)xmpp_genNonce; +- (const uint8_t *)xmpp_HMACWithKey: (OFData *)key data: (OFData *)data; -- (OFData *)XMPP_hiWithData: (OFData *)str +- (OFData *)xmpp_hiWithData: (OFData *)str salt: (OFData *)salt iterationCount: (intmax_t)i; -- (OFData *)XMPP_parseServerFirstMessage: (OFData *)data; -- (OFData *)XMPP_parseServerFinalMessage: (OFData *)data; +- (OFData *)xmpp_parseServerFirstMessage: (OFData *)data; +- (OFData *)xmpp_parseServerFinalMessage: (OFData *)data; @end -OF_ASSUME_NONNULL_END - @implementation XMPPSCRAMAuth + (instancetype)SCRAMAuthWithAuthcid: (OFString *)authcid password: (OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash @@ -79,30 +75,30 @@ connection: connection hash: hash plusAvailable: plusAvailable] autorelease]; } -- initWithAuthcid: (OFString *)authcid - password: (OFString *)password - connection: (XMPPConnection *)connection - hash: (Class)hash - plusAvailable: (bool)plusAvailable +- (instancetype)initWithAuthcid: (OFString *)authcid + password: (OFString *)password + connection: (XMPPConnection *)connection + hash: (Class)hash + plusAvailable: (bool)plusAvailable { return [self initWithAuthzid: nil authcid: authcid password: password connection: connection hash: hash plusAvailable: plusAvailable]; } -- initWithAuthzid: (OFString *)authzid - authcid: (OFString *)authcid - password: (OFString *)password - connection: (XMPPConnection *)connection - hash: (Class)hash - plusAvailable: (bool)plusAvailable +- (instancetype)initWithAuthzid: (OFString *)authzid + authcid: (OFString *)authcid + password: (OFString *)password + connection: (XMPPConnection *)connection + hash: (Class)hash + plusAvailable: (bool)plusAvailable { self = [super initWithAuthzid: authzid authcid: authcid password: password]; @@ -177,11 +173,11 @@ (_plusAvailable ? @"p=tls-unique" : @"y"), _authzid]; else _GS2Header = (_plusAvailable ? @"p=tls-unique,," : @"y,,"); - _cNonce = [[self XMPP_genNonce] retain]; + _cNonce = [[self xmpp_genNonce] retain]; [_clientFirstMessageBare release]; _clientFirstMessageBare = nil; _clientFirstMessageBare = [[OFString alloc] initWithFormat: @"n=%@,r=%@", _authcid, _cNonce]; @@ -201,31 +197,29 @@ { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFData *ret; if (!_serverSignature) - ret = [self XMPP_parseServerFirstMessage: data]; + ret = [self xmpp_parseServerFirstMessage: data]; else - ret = [self XMPP_parseServerFinalMessage: data]; + ret = [self xmpp_parseServerFinalMessage: data]; [ret retain]; [pool release]; return [ret autorelease]; } -- (OFData *)XMPP_parseServerFirstMessage: (OFData *)data +- (OFData *)xmpp_parseServerFirstMessage: (OFData *)data { size_t i; const uint8_t *clientKey, *serverKey, *clientSignature; intmax_t iterCount = 0; id hash; OFMutableData *ret, *authMessage, *tmpArray; OFData *salt = nil, *saltedPassword; OFString *tmpString, *sNonce = nil; - OFEnumerator *enumerator; - OFString *comp; enum { GOT_SNONCE = 0x01, GOT_SALT = 0x02, GOT_ITERCOUNT = 0x04 } got = 0; @@ -232,33 +226,32 @@ hash = [[[_hashType alloc] init] autorelease]; ret = [OFMutableData data]; authMessage = [OFMutableData data]; - OFString *chal = [OFString stringWithUTF8String: [data items] - length: [data count] * - [data itemSize]]; - - enumerator = - [[chal componentsSeparatedByString: @","] objectEnumerator]; - while ((comp = [enumerator nextObject]) != nil) { - OFString *entry = [comp substringWithRange: - of_range(2, [comp length] - 2)]; - - if ([comp hasPrefix: @"r="]) { + OFString *challenge = [OFString stringWithUTF8String: [data items] + length: [data count] * + [data itemSize]]; + + for (OFString *component in + [challenge componentsSeparatedByString: @","]) { + OFString *entry = [component substringWithRange: + of_range(2, [component length] - 2)]; + + if ([component hasPrefix: @"r="]) { if (![entry hasPrefix: _cNonce]) @throw [XMPPAuthFailedException exceptionWithConnection: nil reason: @"Received wrong " @"nonce"]; sNonce = entry; got |= GOT_SNONCE; - } else if ([comp hasPrefix: @"s="]) { + } else if ([component hasPrefix: @"s="]) { salt = [OFData dataWithBase64EncodedString: entry]; got |= GOT_SALT; - } else if ([comp hasPrefix: @"i="]) { + } else if ([component hasPrefix: @"i="]) { iterCount = [entry decimalValue]; got |= GOT_ITERCOUNT; } } @@ -291,11 +284,11 @@ * IETF RFC 5802: * SaltedPassword := Hi(Normalize(password), salt, i) */ tmpArray = [OFMutableData dataWithItems: [_password UTF8String] count: [_password UTF8StringLength]]; - saltedPassword = [self XMPP_hiWithData: tmpArray + saltedPassword = [self xmpp_hiWithData: tmpArray salt: salt iterationCount: iterCount]; /* * IETF RFC 5802: @@ -314,11 +307,11 @@ /* * IETF RFC 5802: * ClientKey := HMAC(SaltedPassword, "Client Key") */ - clientKey = [self XMPP_HMACWithKey: saltedPassword + clientKey = [self xmpp_HMACWithKey: saltedPassword data: [OFData dataWithItems: "Client Key" count: 10]]; /* * IETF RFC 5802: @@ -330,19 +323,19 @@ /* * IETF RFC 5802: * ClientSignature := HMAC(StoredKey, AuthMessage) */ clientSignature = [self - XMPP_HMACWithKey: [OFData dataWithItems: [hash digest] + xmpp_HMACWithKey: [OFData dataWithItems: [hash digest] count: [_hashType digestSize]] data: authMessage]; /* * IETF RFC 5802: * ServerKey := HMAC(SaltedPassword, "Server Key") */ - serverKey = [self XMPP_HMACWithKey: saltedPassword + serverKey = [self xmpp_HMACWithKey: saltedPassword data: [OFData dataWithItems: "Server Key" count: 10]]; /* * IETF RFC 5802: @@ -351,11 +344,11 @@ tmpArray = [OFMutableData dataWithItems: serverKey count: [_hashType digestSize]]; [_serverSignature release]; _serverSignature = [[OFData alloc] - initWithItems: [self XMPP_HMACWithKey: tmpArray + initWithItems: [self xmpp_HMACWithKey: tmpArray data: authMessage] count: [_hashType digestSize]]; /* * IETF RFC 5802: @@ -376,11 +369,11 @@ count: [tmpString UTF8StringLength]]; return ret; } -- (OFData *)XMPP_parseServerFinalMessage: (OFData *)data +- (OFData *)xmpp_parseServerFinalMessage: (OFData *)data { OFString *mess, *value; /* * server-final-message already received, @@ -405,11 +398,11 @@ reason: value]; return nil; } -- (OFString *)XMPP_genNonce +- (OFString *)xmpp_genNonce { uint8_t buf[64]; size_t i; assert(RAND_pseudo_bytes(buf, 64) >= 0); @@ -426,11 +419,11 @@ return [OFString stringWithCString: (char *)buf encoding: OF_STRING_ENCODING_ASCII length: 64]; } -- (const uint8_t *)XMPP_HMACWithKey: (OFData *)key +- (const uint8_t *)xmpp_HMACWithKey: (OFData *)key data: (OFData *)data { void *pool = objc_autoreleasePoolPush(); OFMutableData *k = [OFMutableData data]; size_t i, kSize, blockSize = [_hashType blockSize]; @@ -482,11 +475,11 @@ objc_autoreleasePoolPop(pool); return [[hashO autorelease] digest]; } -- (OFData *)XMPP_hiWithData: (OFData *)str +- (OFData *)xmpp_hiWithData: (OFData *)str salt: (OFData *)salt iterationCount: (intmax_t)i { void *pool = objc_autoreleasePoolPush(); size_t digestSize = [_hashType digestSize]; @@ -503,11 +496,11 @@ salty = [[salt mutableCopy] autorelease]; [salty addItems: "\0\0\0\1" count: 4]; - uOld = [self XMPP_HMACWithKey: str + uOld = [self xmpp_HMACWithKey: str data: salty]; for (j = 0; j < digestSize; j++) result[j] ^= uOld[j]; @@ -519,11 +512,11 @@ /* releases uOld and previous tmp */ objc_autoreleasePoolPop(pool); pool = objc_autoreleasePoolPush(); [tmp autorelease]; - u = [self XMPP_HMACWithKey: str + u = [self xmpp_HMACWithKey: str data: tmp]; for (k = 0; k < digestSize; k++) result[k] ^= u[k];