@@ -21,12 +21,12 @@ */ #import "NewPasswordGenerator.h" @implementation NewPasswordGenerator -@synthesize length = _length, site = _site, passphrase = _passphrase; -@synthesize output = _output; +@synthesize length = _length, site = _site, keyfile = _keyfile; +@synthesize passphrase = _passphrase, output = _output; + (instancetype)generator { return [[[self alloc] init] autorelease]; } @@ -41,10 +41,13 @@ } - (void)derivePassword { OFSHA384Hash *siteHash = [OFSHA384Hash cryptoHash]; + size_t passphraseLength, combinedPassphraseLength; + char *combinedPassphrase; + [siteHash updateWithBuffer: [_site UTF8String] length: [_site UTF8StringLength]]; if (_output != NULL) { of_explicit_memset(_output, 0, _length); @@ -51,17 +54,40 @@ [self freeMemory: _output]; } _output = [self allocMemoryWithSize: _length + 1]; - of_scrypt(8, 524288, 2, [siteHash digest], - [[siteHash class] digestSize], _passphrase, strlen(_passphrase), - _output, _length); + passphraseLength = combinedPassphraseLength = strlen(_passphrase); + if (_keyfile != nil) { + if (SIZE_MAX - combinedPassphraseLength < [_keyfile count]) + @throw [OFOutOfRangeException exception]; + + combinedPassphraseLength += [_keyfile count]; + } + + if ((combinedPassphrase = malloc(combinedPassphraseLength)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: combinedPassphraseLength]; + @try { + memcpy(combinedPassphrase, _passphrase, passphraseLength); + + if (_keyfile != nil) + memcpy(combinedPassphrase + passphraseLength, + [_keyfile items], [_keyfile count]); + + of_scrypt(8, 524288, 2, [siteHash digest], + [[siteHash class] digestSize], combinedPassphrase, + combinedPassphraseLength, _output, _length); + } @finally { + of_explicit_memset(combinedPassphrase, 0, + combinedPassphraseLength); + free(combinedPassphrase); + } for (size_t i = 0; i < _length; i++) _output[i] = "123456789" "abcdefghijkmnopqrstuvwxyz" "ABCDEFGHJKLMNPQRSTUVWXYZ" "#$%-=?"[_output[i] & 0x3F]; } @end