// // PwdCryptController.m // // Created by Simon Urbanek on 9/20/12. // Copyright 2012 Simon Urbanek. All rights reserved. // #import "PwdCryptController.h" #import #import "pwdcrypt.h" @implementation PwdCryptController static salt_t salt; - (void)controlTextDidChange:(NSNotification *)aNotification { NSString *hashString; char hash[40], upstart[40]; unsigned int pins[2]; generate([[pwdText stringValue] UTF8String], salt, hash, upstart, pins); [hashText setStringValue: hashString = [NSString stringWithUTF8String:(char*)hash]]; [pinText setStringValue: [NSString stringWithFormat:@"%04u", pins[0]]]; [pin2Text setStringValue: [NSString stringWithFormat:@"%06u", pins[1]]]; [winText setStringValue: [hashString substringToIndex:14]]; [upstartText setStringValue: [[NSString stringWithUTF8String:(char*)upstart] substringToIndex:12]]; // UPSTART require 10-30, so let's use 12 NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; [pasteboard clearContents]; [pasteboard writeObjects:[NSArray arrayWithObject:hashString]]; } static const char *serviceName = "info.urbanek.PwdCrypt", *accountName = "@salt"; static int store_salt() { return (int) SecKeychainAddGenericPassword(NULL, strlen(serviceName), serviceName, strlen(accountName), accountName, sizeof(salt), salt, NULL); } - (NSString *)input: (NSString *)prompt defaultValue: (NSString *)defaultValue { NSAlert *alert = [NSAlert alertWithMessageText: prompt defaultButton:@"OK" alternateButton:@"Cancel" otherButton:nil informativeTextWithFormat:@""]; NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)]; [input setStringValue:defaultValue]; [alert setAccessoryView:input]; NSInteger button = [alert runModal]; if (button == NSAlertDefaultReturn) { [input validateEditing]; return [input stringValue]; } else if (button == NSAlertAlternateReturn) { return nil; } else { NSAssert1(NO, @"Invalid input dialog button %d", button); return nil; } } - (void) awakeFromNib { UInt32 saltLen; void *data; OSStatus res = SecKeychainFindGenericPassword(NULL, strlen(serviceName), serviceName, strlen(accountName), accountName, &saltLen, &data, NULL); if (res || saltLen != sizeof(salt)) { NSLog(@"Note: unable to retrieve salt"); NSString *saltText = [self input:@"Please specify the salt for your hashes" defaultValue:@""]; if (saltText) { sha1hash([saltText UTF8String], strlen([saltText UTF8String]), salt); store_salt(); } } else { memcpy(salt, data, sizeof(salt)); } } @end