@@ -39,17 +39,17 @@ OF_ASSUME_NONNULL_BEGIN @interface XMPPSCRAMAuth () - (OFString *)XMPP_genNonce; -- (const uint8_t *)XMPP_HMACWithKey: (OFDataArray *)key - data: (OFDataArray *)data; -- (OFDataArray *)XMPP_hiWithData: (OFDataArray *)str - salt: (OFDataArray *)salt - iterationCount: (intmax_t)i; -- (OFDataArray *)XMPP_parseServerFirstMessage: (OFDataArray *)data; -- (OFDataArray *)XMPP_parseServerFinalMessage: (OFDataArray *)data; +- (const uint8_t *)XMPP_HMACWithKey: (OFData *)key + data: (OFData *)data; +- (OFData *)XMPP_hiWithData: (OFData *)str + salt: (OFData *)salt + iterationCount: (intmax_t)i; +- (OFData *)XMPP_parseServerFirstMessage: (OFData *)data; +- (OFData *)XMPP_parseServerFinalMessage: (OFData *)data; @end OF_ASSUME_NONNULL_END @implementation XMPPSCRAMAuth @@ -156,13 +156,13 @@ _authcid = nil; [old release]; } -- (OFDataArray *)initialMessage +- (OFData *)initialMessage { - OFDataArray *ret = [OFDataArray dataArray]; + OFMutableData *ret = [OFMutableData data]; /* New authentication attempt, reset status */ [_cNonce release]; _cNonce = nil; [_GS2Header release]; @@ -169,11 +169,11 @@ _GS2Header = nil; [_serverSignature release]; _serverSignature = nil; _authenticated = false; - if (_authzid) + if (_authzid != nil) _GS2Header = [[OFString alloc] initWithFormat: @"%@,a=%@,", (_plusAvailable ? @"p=tls-unique" : @"y"), _authzid]; else @@ -190,17 +190,19 @@ count: [_GS2Header UTF8StringLength]]; [ret addItems: [_clientFirstMessageBare UTF8String] count: [_clientFirstMessageBare UTF8StringLength]]; + [ret makeImmutable]; + return ret; } -- (OFDataArray *)continueWithData: (OFDataArray *)data +- (OFData *)continueWithData: (OFData *)data { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFDataArray *ret; + OFData *ret; if (!_serverSignature) ret = [self XMPP_parseServerFirstMessage: data]; else ret = [self XMPP_parseServerFinalMessage: data]; @@ -209,17 +211,18 @@ [pool release]; return [ret autorelease]; } -- (OFDataArray *)XMPP_parseServerFirstMessage: (OFDataArray *)data +- (OFData *)XMPP_parseServerFirstMessage: (OFData *)data { size_t i; const uint8_t *clientKey, *serverKey, *clientSignature; intmax_t iterCount = 0; id hash; - OFDataArray *ret, *authMessage, *tmpArray, *salt = nil, *saltedPassword; + OFMutableData *ret, *authMessage, *tmpArray; + OFData *salt = nil, *saltedPassword; OFString *tmpString, *sNonce = nil; OFEnumerator *enumerator; OFString *comp; enum { GOT_SNONCE = 0x01, @@ -226,12 +229,12 @@ GOT_SALT = 0x02, GOT_ITERCOUNT = 0x04 } got = 0; hash = [[[_hashType alloc] init] autorelease]; - ret = [OFDataArray dataArray]; - authMessage = [OFDataArray dataArray]; + ret = [OFMutableData data]; + authMessage = [OFMutableData data]; OFString *chal = [OFString stringWithUTF8String: [data items] length: [data count] * [data itemSize]]; @@ -249,12 +252,11 @@ @"nonce"]; sNonce = entry; got |= GOT_SNONCE; } else if ([comp hasPrefix: @"s="]) { - salt = [OFDataArray - dataArrayWithBase64EncodedString: entry]; + salt = [OFData dataWithBase64EncodedString: entry]; got |= GOT_SALT; } else if ([comp hasPrefix: @"i="]) { iterCount = [entry decimalValue]; got |= GOT_ITERCOUNT; } @@ -262,16 +264,15 @@ if (got != (GOT_SNONCE | GOT_SALT | GOT_ITERCOUNT)) @throw [OFInvalidServerReplyException exception]; // Add c= - tmpArray = [OFDataArray dataArray]; + tmpArray = [OFMutableData data]; [tmpArray addItems: [_GS2Header UTF8String] count: [_GS2Header UTF8StringLength]]; if (_plusAvailable && [_connection encrypted]) { - OFDataArray *channelBinding = - [((SSLSocket *)[_connection socket]) + OFData *channelBinding = [((SSLSocket *)[_connection socket]) channelBindingDataWithType: @"tls-unique"]; [tmpArray addItems: [channelBinding items] count: [channelBinding count]]; } tmpString = [tmpArray stringByBase64Encoding]; @@ -289,14 +290,12 @@ /* * IETF RFC 5802: * SaltedPassword := Hi(Normalize(password), salt, i) */ - tmpArray = [OFDataArray dataArray]; - [tmpArray addItems: [_password UTF8String] - count: [_password UTF8StringLength]]; - + tmpArray = [OFMutableData dataWithItems: [_password UTF8String] + count: [_password UTF8StringLength]]; saltedPassword = [self XMPP_hiWithData: tmpArray salt: salt iterationCount: iterCount]; /* @@ -316,25 +315,22 @@ /* * IETF RFC 5802: * ClientKey := HMAC(SaltedPassword, "Client Key") */ - tmpArray = [OFDataArray dataArray]; - [tmpArray addItems: "Client Key" - count: 10]; clientKey = [self XMPP_HMACWithKey: saltedPassword - data: tmpArray]; + data: [OFData dataWithItems: @"Client key" + count: 10]]; /* * IETF RFC 5802: * StoredKey := H(ClientKey) */ [hash updateWithBuffer: (void *)clientKey length: [_hashType digestSize]]; - tmpArray = [OFDataArray dataArray]; - [tmpArray addItems: [hash digest] - count: [_hashType digestSize]]; + tmpArray = [OFMutableData dataWithItems: [hash digest] + count: [_hashType digestSize]]; /* * IETF RFC 5802: * ClientSignature := HMAC(StoredKey, AuthMessage) */ @@ -343,33 +339,33 @@ /* * IETF RFC 5802: * ServerKey := HMAC(SaltedPassword, "Server Key") */ - tmpArray = [OFDataArray dataArray]; - [tmpArray addItems: "Server Key" - count: 10]; + tmpArray = [OFMutableData dataWithItems: "Server Key" + count: 10]; serverKey = [self XMPP_HMACWithKey: saltedPassword data: tmpArray]; /* * IETF RFC 5802: * ServerSignature := HMAC(ServerKey, AuthMessage) */ - tmpArray = [OFDataArray dataArray]; - [tmpArray addItems: serverKey - count: [_hashType digestSize]]; - _serverSignature = [[OFDataArray alloc] init]; - [_serverSignature addItems: [self XMPP_HMACWithKey: tmpArray - data: authMessage] - count: [_hashType digestSize]]; + tmpArray = [OFMutableData dataWithItems: serverKey + count: [_hashType digestSize]]; + + [_serverSignature release]; + _serverSignature = [[OFMutableData alloc] + initWithItems: [self XMPP_HMACWithKey: tmpArray + data: authMessage] + count: [_hashType digestSize]]; /* * IETF RFC 5802: * ClientProof := ClientKey XOR ClientSignature */ - tmpArray = [OFDataArray dataArray]; + tmpArray = [OFMutableData data]; for (i = 0; i < [_hashType digestSize]; i++) { uint8_t c = clientKey[i] ^ clientSignature[i]; [tmpArray addItem: &c]; } @@ -382,11 +378,11 @@ count: [tmpString UTF8StringLength]]; return ret; } -- (OFDataArray *)XMPP_parseServerFinalMessage: (OFDataArray *)data +- (OFData *)XMPP_parseServerFinalMessage: (OFData *)data { OFString *mess, *value; /* * server-final-message already received, @@ -394,12 +390,11 @@ */ if (_authenticated) return nil; mess = [OFString stringWithUTF8String: [data items] - length: [data count] * - [data itemSize]]; + length: [data count] * [data itemSize]]; value = [mess substringWithRange: of_range(2, [mess length] - 2)]; if ([mess hasPrefix: @"v="]) { if (![value isEqual: [_serverSignature stringByBase64Encoding]]) @throw [XMPPAuthFailedException @@ -433,15 +428,15 @@ return [OFString stringWithCString: (char *)buf encoding: OF_STRING_ENCODING_ASCII length: 64]; } -- (const uint8_t *)XMPP_HMACWithKey: (OFDataArray *)key - data: (OFDataArray *)data +- (const uint8_t *)XMPP_HMACWithKey: (OFData *)key + data: (OFData *)data { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFDataArray *k = [OFDataArray dataArray]; + OFMutableData *k = [OFMutableData data]; size_t i, kSize, blockSize = [_hashType blockSize]; uint8_t *kI = NULL, *kO = NULL; id hashI, hashO; if ([key itemSize] * [key count] > blockSize) { @@ -488,20 +483,20 @@ [pool release]; return [[hashO autorelease] digest]; } -- (OFDataArray *)XMPP_hiWithData: (OFDataArray *)str - salt: (OFDataArray *)salt - iterationCount: (intmax_t)i +- (OFData *)XMPP_hiWithData: (OFData *)str + salt: (OFData *)salt + iterationCount: (intmax_t)i { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; size_t digestSize = [_hashType digestSize]; uint8_t *result = NULL; const uint8_t *u, *uOld; intmax_t j, k; - OFDataArray *salty, *tmp, *ret; + OFMutableData *salty, *tmp, *ret; result = [self allocMemoryWithSize: digestSize]; @try { memset(result, 0, digestSize); @@ -515,11 +510,11 @@ for (j = 0; j < digestSize; j++) result[j] ^= uOld[j]; for (j = 0; j < i - 1; j++) { - tmp = [[OFDataArray alloc] init]; + tmp = [[OFMutableData alloc] init]; [tmp addItems: uOld count: digestSize]; [pool releaseObjects]; // releases uOld and previous tmp [tmp autorelease]; @@ -531,13 +526,12 @@ result[k] ^= u[k]; uOld = u; } - ret = [OFDataArray dataArray]; - [ret addItems: result - count: digestSize]; + ret = [OFMutableData dataWithItems: result + count: digestSize]; } @finally { [self freeMemory: result]; } [ret retain];