Add support for SCRAM-SHA-1-PLUS

This commit is contained in:
Florian Zeitz 2011-09-10 16:08:25 +02:00
parent b24c7500fd
commit 62d2bd2ba5
4 changed files with 88 additions and 18 deletions

View file

@ -73,6 +73,7 @@
id <XMPPConnectionDelegate, OFObject> delegate;
XMPPAuthenticator *authModule;
BOOL needsSession;
BOOL encrypted;
unsigned int lastID;
OFString *bindID, *sessionID;
XMPPRoster *roster;
@ -85,6 +86,7 @@
@property (retain) id <XMPPConnectionDelegate> delegate;
@property (readonly, retain) XMPPRoster *roster;
@property (readonly, retain, getter=socket) OFTCPSocket *sock;
@property (readonly) BOOL encrypted;
#endif
/**
@ -119,6 +121,11 @@
*/
- (OFTCPSocket*)socket;
/**
* \return Whether the connection is encrypted
*/
- (BOOL)encrypted;
/**
* Sends an OFXMLElement, usually an XMPPStanza.
*

View file

@ -61,6 +61,7 @@
@try {
sock = [[OFTCPSocket alloc] init];
port = 5222;
encrypted = NO;
} @catch (id e) {
[self release];
@throw e;
@ -328,6 +329,11 @@
return [[sock retain] autorelease];
}
- (BOOL)encrypted
{
return encrypted;
}
- (void)sendStanza: (OFXMLElement*)element
{
of_log(@"Out: %@", element);
@ -577,6 +583,8 @@
[sock release];
sock = newSock;
encrypted = YES;
if ([delegate respondsToSelector:
@selector(connectionDidUpgradeToTLS:)])
[delegate connectionDidUpgradeToTLS: self];
@ -711,16 +719,29 @@
while ((mech = [enumerator nextObject]) != nil)
[mechanisms addObject: [mech stringValue]];
if ([mechanisms containsObject: @"SCRAM-SHA-1-PLUS"]) {
authModule = [[XMPPSCRAMAuth alloc]
initWithAuthcid: username
password: password
connection: self
hash: [OFSHA1Hash class]
plusAvailable: YES];
[self XMPP_sendAuth: @"SCRAM-SHA-1-PLUS"];
return;
}
if ([mechanisms containsObject: @"SCRAM-SHA-1"]) {
authModule = [[XMPPSCRAMAuth alloc]
initWithAuthcid: username
password: password
hash: [OFSHA1Hash class]];
connection: self
hash: [OFSHA1Hash class]
plusAvailable: NO];
[self XMPP_sendAuth: @"SCRAM-SHA-1"];
return;
}
if ([mechanisms containsObject: @"PLAIN"]) {
if ([mechanisms containsObject: @"PLAIN"] && encrypted) {
authModule = [[XMPPPLAINAuth alloc]
initWithAuthcid: username
password: password];

View file

@ -22,6 +22,7 @@
#import <ObjFW/ObjFW.h>
#import "XMPPAuthenticator.h"
#import "XMPPConnection.h"
/**
* \brief A class to authenticate using SCRAM
@ -33,6 +34,8 @@
OFString *GS2Header;
OFString *clientFirstMessageBare;
OFDataArray *serverSignature;
XMPPConnection *connection;
BOOL plusAvailable;
}
/**
@ -40,12 +43,16 @@
*
* \param authcid The authcid to authenticate with
* \param password The password to authenticate with
* \param connection The connection over which authentication is done
* \param hash The class to use for calulating hashes
* \param plusAvailable Whether the PLUS variant was offered
* \return A new autoreleased XMPPSCRAMAuth
*/
+ SCRAMAuthWithAuthcid: (OFString*)authcid
password: (OFString*)password
hash: (Class)hash;
connection: (XMPPConnection*)connection
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable;
/**
* Creates a new autoreleased XMPPSCRAMAuth with an authzid,
@ -54,25 +61,33 @@
* \param authzid The authzid to get authorization for
* \param authcid The authcid to authenticate with
* \param password The password to authenticate with
* \param connection The connection over which authentication is done
* \param hash The class to use for calulating hashes
* \param plusAvailable Whether the PLUS variant was offered
* \return A new autoreleased XMPPSCRAMAuth
*/
+ SCRAMAuthWithAuthzid: (OFString*)authzid
authcid: (OFString*)authcid
password: (OFString*)password
hash: (Class)hash;
connection: (XMPPConnection*)connection
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable;
/**
* Initializes an already allocated XMPPSCRAMAuth with an authcid and password.
*
* \param authcid The authcid to authenticate with
* \param password The password to authenticate with
* \param connection The connection over which authentication is done
* \param hash The class to use for calulating hashes
* \param plusAvailable Whether the PLUS variant was offered
* \return A initialized XMPPSCRAMAuth
*/
- initWithAuthcid: (OFString*)authcid
password: (OFString*)password
hash: (Class)hash;
connection: (XMPPConnection*)connection
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable;
/**
* Initializes an already allocated XMPPSCRAMAuth with a authzid,
@ -81,13 +96,17 @@
* \param authzid The authzid to get authorization for
* \param authcid The authcid to authenticate with
* \param password The password to authenticate with
* \param connection The connection over which authentication is done
* \param hash The class to use for calulating hashes
* \param plusAvailable Whether the PLUS variant was offered
* \return A initialized XMPPSCRAMAuth
*/
- initWithAuthzid: (OFString*)authzid
authcid: (OFString*)authcid
password: (OFString*)password
hash: (Class)hash;
connection: (XMPPConnection*)connection
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable;
- (OFString*)XMPP_genNonce;
- (uint8_t*)XMPP_HMACWithKey: (OFDataArray*)key

View file

@ -26,11 +26,11 @@
#endif
#include <string.h>
#include <assert.h>
#include <openssl/rand.h>
#import <ObjOpenSSL/SSLSocket.h>
#import "XMPPSCRAMAuth.h"
#import "XMPPExceptions.h"
@ -40,44 +40,60 @@
@implementation XMPPSCRAMAuth
+ SCRAMAuthWithAuthcid: (OFString*)authcid
password: (OFString*)password
hash: (Class)hash;
connection: (XMPPConnection*)connection_
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable_
{
return [[[self alloc] initWithAuthcid: authcid
password: password
hash: hash] autorelease];
connection: connection_
hash: hash
plusAvailable: plusAvailable_] autorelease];
}
+ SCRAMAuthWithAuthzid: (OFString*)authzid
authcid: (OFString*)authcid
password: (OFString*)password
hash: (Class)hash;
connection: (XMPPConnection*)connection_
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable_
{
return [[[self alloc] initWithAuthzid: authzid
authcid: authcid
password: password
hash: hash] autorelease];
connection: connection_
hash: hash
plusAvailable: plusAvailable_] autorelease];
}
- initWithAuthcid: (OFString*)authcid_
password: (OFString*)password_
hash: (Class)hash;
connection: (XMPPConnection*)connection_
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable_
{
return [self initWithAuthzid: nil
authcid: authcid_
password: password_
hash: hash];
connection: connection_
hash: hash
plusAvailable: plusAvailable_];
}
- initWithAuthzid: (OFString*)authzid_
authcid: (OFString*)authcid_
password: (OFString*)password_
hash: (Class)hash;
connection: (XMPPConnection*)connection_
hash: (Class)hash
plusAvailable: (BOOL)plusAvailable_
{
self = [super initWithAuthzid: authzid_
authcid: authcid_
password: password_];
hashType = hash;
plusAvailable = plusAvailable_;
connection = [connection_ retain];
return self;
}
@ -88,6 +104,7 @@
[clientFirstMessageBare release];
[serverSignature release];
[cNonce release];
[connection release];
[super dealloc];
}
@ -134,10 +151,10 @@
GS2Header = nil;
if (authzid)
GS2Header = [[OFString alloc] initWithFormat: @"n,a=%@,",
authzid];
GS2Header = [[OFString alloc] initWithFormat: @"%@,a=%@,",
(plusAvailable ? @"p=tls-unique" : @"y"), authzid];
else
GS2Header = @"n,,";
GS2Header = plusAvailable ? @"p=tls-unique,," : @"y,,";
[cNonce release];
cNonce = nil;
@ -216,6 +233,12 @@
tmpArray = [OFDataArray dataArrayWithItemSize: 1];
[tmpArray addNItems: [GS2Header cStringLength]
fromCArray: [GS2Header cString]];
if (plusAvailable && [connection encrypted]) {
OFDataArray *channelBinding = [((SSLSocket*)[connection socket])
channelBindingDataWithType: @"tls-unique"];
[tmpArray addNItems: [channelBinding count]
fromCArray: [channelBinding cArray]];
}
tmpString = [tmpArray stringByBase64Encoding];
[ret addNItems: 2
fromCArray: "c="];