Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented TDMACAUthorizer, for use with OAuth.

Not tested yet!!
  • Loading branch information...
commit c716ebaa1a49788a446c93d92d314d87d100478c 1 parent ed92b46
@snej snej authored
View
6 Source/TDMisc.h
@@ -13,8 +13,14 @@ extern NSString* const TDHTTPErrorDomain;
NSString* TDCreateUUID( void );
+NSData* TDSHA1Digest( NSData* input );
+NSData* TDSHA256Digest( NSData* input );
+
NSString* TDHexSHA1Digest( NSData* input );
+NSData* TDHMACSHA1(NSData* key, NSData* data);
+NSData* TDHMACSHA256(NSData* key, NSData* data);
+
/** Generates a hex dump of a sequence of bytes.
The result is lowercase. This is important for CouchDB compatibility. */
NSString* TDHexFromBytes( const void* bytes, size_t length);
View
33 Source/TDMisc.m
@@ -24,6 +24,7 @@
#else
#define COMMON_DIGEST_FOR_OPENSSL
#import <CommonCrypto/CommonDigest.h>
+#import <CommonCrypto/CommonHMAC.h>
#endif
@@ -43,6 +44,25 @@
}
+NSData* TDSHA1Digest( NSData* input ) {
+ unsigned char digest[SHA_DIGEST_LENGTH];
+ SHA_CTX ctx;
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, input.bytes, input.length);
+ SHA1_Final(digest, &ctx);
+ return [NSData dataWithBytes: &digest length: sizeof(digest)];
+}
+
+NSData* TDSHA256Digest( NSData* input ) {
+ unsigned char digest[SHA256_DIGEST_LENGTH];
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, input.bytes, input.length);
+ SHA256_Final(digest, &ctx);
+ return [NSData dataWithBytes: &digest length: sizeof(digest)];
+}
+
+
NSString* TDHexSHA1Digest( NSData* input ) {
unsigned char digest[SHA_DIGEST_LENGTH];
SHA_CTX ctx;
@@ -63,6 +83,19 @@
}
+NSData* TDHMACSHA1(NSData* key, NSData* data) {
+ UInt8 hmac[SHA_DIGEST_LENGTH];
+ CCHmac(kCCHmacAlgSHA1, key.bytes, key.length, data.bytes, data.length, &hmac);
+ return [NSData dataWithBytes: hmac length: sizeof(hmac)];
+}
+
+NSData* TDHMACSHA256(NSData* key, NSData* data) {
+ UInt8 hmac[SHA256_DIGEST_LENGTH];
+ CCHmac(kCCHmacAlgSHA256, key.bytes, key.length, data.bytes, data.length, &hmac);
+ return [NSData dataWithBytes: hmac length: sizeof(hmac)];
+}
+
+
NSComparisonResult TDSequenceCompare( SequenceNumber a, SequenceNumber b) {
SInt64 diff = a - b;
return diff > 0 ? 1 : (diff < 0 ? -1 : 0);
View
22 Source/TDReplicator.h
@@ -122,4 +122,24 @@ extern NSString* TDReplicatorStoppedNotification;
/** Initialize given a credential object that contains a username and password. */
- (id) initWithCredential: (NSURLCredential*)credential;
-@end
+@end
+
+
+
+/** Implementation of TDAuthorizer that supports MAC authorization as used in OAuth 2. */
+@interface TDMACAuthorizer : NSObject <TDAuthorizer>
+{
+@private
+ NSString *_key, *_identifier;
+ NSDate* _issueTime;
+ NSData* (*_hmacFunction)(NSData*, NSData*);
+
+}
+
+/** Initialize given MAC credentials */
+- (id) initWithKey: (NSString*)key
+ identifier: (NSString*)identifier
+ algorithm: (NSString*)algorithm
+ issueTime: (NSDate*)issueTime;
+
+@end
View
67 Source/TDReplicator.m
@@ -23,6 +23,7 @@
#import "TDInternal.h"
#import "TDMisc.h"
#import "TDBase64.h"
+#import "MYURLUtils.h"
#define kProcessDelay 0.5
@@ -451,3 +452,69 @@ - (NSString*) authorizeURLRequest: (NSMutableURLRequest*)request {
}
@end
+
+
+@implementation TDMACAuthorizer
+
+- (id) initWithKey: (NSString*)key
+ identifier: (NSString*)identifier
+ algorithm: (NSString*)algorithm
+ issueTime: (NSDate*)issueTime
+{
+ self = [super init];
+ if (self) {
+ _key = [key copy];
+ _identifier = [identifier copy];
+ _issueTime = [issueTime copy];
+ if ([algorithm isEqualToString: @"hmac-sha-1"])
+ _hmacFunction = &TDHMACSHA1;
+ else if ([algorithm isEqualToString: @"hmac-sha-256"])
+ _hmacFunction = &TDHMACSHA256;
+ else {
+ [self release];
+ return nil;
+ }
+ }
+ return self;
+}
+
+
+- (void)dealloc
+{
+ [_key release];
+ [_identifier release];
+ [_issueTime release];
+ [super dealloc];
+}
+
+
+- (NSString*) authorizeURLRequest: (NSMutableURLRequest*)request {
+ // <http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-00>
+ NSString* nonce = $sprintf(@"%.0f:%@", -[_issueTime timeIntervalSinceNow], TDCreateUUID());
+ NSURL* url = request.URL;
+ NSString* ext = @""; // not implemented yet
+
+ NSString* bodyHash = @"";
+ NSData* body = request.HTTPBody;
+ if (body.length > 0) {
+ NSData* digest = (_hmacFunction == &TDHMACSHA1) ? TDSHA1Digest(body) : TDSHA256Digest(body);
+ bodyHash = [TDBase64 encode: digest];
+ }
+
+ NSString* normalized = $sprintf(@"%@\n%@%@\n%@\n%d\n%@\n%@\n",
+ nonce,
+ request.HTTPMethod,
+ url.my_pathAndQuery,
+ [url.host lowercaseString],
+ url.my_effectivePort,
+ bodyHash,
+ ext);
+ NSString* mac;
+ mac = [TDBase64 encode: _hmacFunction([_key dataUsingEncoding: NSUTF8StringEncoding],
+ [normalized dataUsingEncoding: NSUTF8StringEncoding])];
+ return $sprintf(@"MAC id=\"%@\", nonce=\"%@\", bodyhash=\"%@\", mac=\"%@\"",
+ _identifier, nonce, bodyHash, mac);
+}
+
+
+@end
2  vendor/MYUtilities
@@ -1 +1 @@
-Subproject commit ee15426817dc4ec8b54f4e021ea346497eea3e78
+Subproject commit 071cfd2f015a48ac2da8bbdc5443b568de5e82dc
Please sign in to comment.
Something went wrong with that request. Please try again.