ObjXMPP  Check-in [73157b0bcd]

Overview
Comment:Fix SCRAM auth
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 73157b0bcd9881dc2180303062c3a9acc800712db9f66caac445290380e1859e
User & Date: js on 2018-11-04 23:01:40
Other Links: manifest | tags
Context
2018-11-05
00:14
Remove dependency on libresolv check-in: d6978b56f0 user: js tags: trunk
2018-11-04
23:01
Fix SCRAM auth check-in: 73157b0bcd user: js tags: trunk
22:07
Adjust to ObjFW changes check-in: 960467b47f user: js tags: trunk
Changes

Modified src/XMPPSCRAMAuth.m from [b84765f635] to [64601fbc72].

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#define HMAC_OPAD 0x5c

OF_ASSUME_NONNULL_BEGIN

@interface XMPPSCRAMAuth ()
- (OFString *)XMPP_genNonce;
- (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








|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#define HMAC_OPAD 0x5c

OF_ASSUME_NONNULL_BEGIN

@interface XMPPSCRAMAuth ()
- (OFString *)XMPP_genNonce;
- (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

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
		}
	}

	if (got != (GOT_SNONCE | GOT_SALT | GOT_ITERCOUNT))
		@throw [OFInvalidServerReplyException exception];

	// Add c=<base64(GS2Header+channelBindingData)>
	tmpArray = [OFMutableData data];
	[tmpArray addItems: [_GS2Header UTF8String]
		     count: [_GS2Header UTF8StringLength]];
	if (_plusAvailable && [_connection encrypted]) {
		OFData *channelBinding = [((SSLSocket *)[_connection socket])
		    channelBindingDataWithType: @"tls-unique"];
		[tmpArray addItems: [channelBinding items]
			     count: [channelBinding count]];
	}
	tmpString = [tmpArray stringByBase64Encoding];







|
<
|







262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
		}
	}

	if (got != (GOT_SNONCE | GOT_SALT | GOT_ITERCOUNT))
		@throw [OFInvalidServerReplyException exception];

	// Add c=<base64(GS2Header+channelBindingData)>
	tmpArray = [OFMutableData dataWithItems: [_GS2Header UTF8String]

					  count: [_GS2Header UTF8StringLength]];
	if (_plusAvailable && [_connection encrypted]) {
		OFData *channelBinding = [((SSLSocket *)[_connection socket])
		    channelBindingDataWithType: @"tls-unique"];
		[tmpArray addItems: [channelBinding items]
			     count: [channelBinding count]];
	}
	tmpString = [tmpArray stringByBase64Encoding];
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337


338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
			count: [ret count]];

	/*
	 * IETF RFC 5802:
	 * ClientKey := HMAC(SaltedPassword, "Client Key")
	 */
	clientKey = [self XMPP_HMACWithKey: saltedPassword
				      data: [OFData dataWithItems: @"Client key"
							    count: 10]];

	/*
	 * IETF RFC 5802:
	 * StoredKey := H(ClientKey)
	 */
	[hash updateWithBuffer: (void *)clientKey
			length: [_hashType digestSize]];
	tmpArray = [OFMutableData dataWithItems: [hash digest]
					  count: [_hashType digestSize]];

	/*
	 * IETF RFC 5802:
	 * ClientSignature := HMAC(StoredKey, AuthMessage)
	 */
	clientSignature = [self XMPP_HMACWithKey: tmpArray


					    data: authMessage];

	/*
	 * IETF RFC 5802:
	 * ServerKey := HMAC(SaltedPassword, "Server Key")
	 */

	tmpArray = [OFMutableData dataWithItems: "Server Key"
					  count: 10];
	serverKey = [self XMPP_HMACWithKey: saltedPassword
				      data: tmpArray];

	/*
	 * IETF RFC 5802:
	 * ServerSignature := HMAC(ServerKey, AuthMessage)
	 */
	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 = [OFMutableData data];
	for (i = 0; i < [_hashType digestSize]; i++) {
		uint8_t c = clientKey[i] ^ clientSignature[i];
		[tmpArray addItem: &c];
	}

	// Add p=<base64(ClientProof)>
	[ret addItem: ","];







|








<
<





|
>
>
|





>
|
|
<
<









|








|







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328


329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345


346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
			count: [ret count]];

	/*
	 * IETF RFC 5802:
	 * ClientKey := HMAC(SaltedPassword, "Client Key")
	 */
	clientKey = [self XMPP_HMACWithKey: saltedPassword
				      data: [OFData dataWithItems: "Client Key"
							    count: 10]];

	/*
	 * IETF RFC 5802:
	 * StoredKey := H(ClientKey)
	 */
	[hash updateWithBuffer: (void *)clientKey
			length: [_hashType digestSize]];



	/*
	 * IETF RFC 5802:
	 * ClientSignature := HMAC(StoredKey, AuthMessage)
	 */
	clientSignature = [self
	    XMPP_HMACWithKey: [OFData dataWithItems: [hash digest]
					      count: [_hashType digestSize]]
			data: authMessage];

	/*
	 * IETF RFC 5802:
	 * ServerKey := HMAC(SaltedPassword, "Server Key")
	 */
	serverKey = [self XMPP_HMACWithKey: saltedPassword
				      data: [OFData dataWithItems: "Server Key"
							    count: 10]];



	/*
	 * IETF RFC 5802:
	 * ServerSignature := HMAC(ServerKey, AuthMessage)
	 */
	tmpArray = [OFMutableData dataWithItems: serverKey
					  count: [_hashType digestSize]];

	[_serverSignature release];
	_serverSignature = [[OFData alloc]
	    initWithItems: [self XMPP_HMACWithKey: tmpArray
					     data: authMessage]
		    count: [_hashType digestSize]];

	/*
	 * IETF RFC 5802:
	 * ClientProof := ClientKey XOR ClientSignature
	 */
	tmpArray = [OFMutableData dataWithCapacity: [_hashType digestSize]];
	for (i = 0; i < [_hashType digestSize]; i++) {
		uint8_t c = clientKey[i] ^ clientSignature[i];
		[tmpArray addItem: &c];
	}

	// Add p=<base64(ClientProof)>
	[ret addItem: ","];
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508
509
510
511
512
	     iterationCount: (intmax_t)i
{
	void *pool = objc_autoreleasePoolPush();
	size_t digestSize = [_hashType digestSize];
	uint8_t *result = NULL;
	const uint8_t *u, *uOld;
	intmax_t j, k;
	OFMutableData *salty, *tmp, *ret;


	result = [self allocMemoryWithSize: digestSize];

	@try {
		memset(result, 0, digestSize);

		salty = [[salt copy] autorelease];
		[salty addItems: "\0\0\0\1"
			  count: 4];

		uOld = [self XMPP_HMACWithKey: str
					 data: salty];

		for (j = 0; j < digestSize; j++)







|
>






|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
	     iterationCount: (intmax_t)i
{
	void *pool = objc_autoreleasePoolPush();
	size_t digestSize = [_hashType digestSize];
	uint8_t *result = NULL;
	const uint8_t *u, *uOld;
	intmax_t j, k;
	OFMutableData *salty, *tmp;
	OFData *ret;

	result = [self allocMemoryWithSize: digestSize];

	@try {
		memset(result, 0, digestSize);

		salty = [[salt mutableCopy] autorelease];
		[salty addItems: "\0\0\0\1"
			  count: 4];

		uOld = [self XMPP_HMACWithKey: str
					 data: salty];

		for (j = 0; j < digestSize; j++)
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

			for (k = 0; k < digestSize; k++)
				result[k] ^= u[k];

			uOld = u;
		}

		ret = [OFMutableData dataWithItems: result
					     count: digestSize];
	} @finally {
		[self freeMemory: result];
	}

	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
@end







|
|











526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545

			for (k = 0; k < digestSize; k++)
				result[k] ^= u[k];

			uOld = u;
		}

		ret = [OFData dataWithItems: result
				      count: digestSize];
	} @finally {
		[self freeMemory: result];
	}

	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
@end