Password creator nor correctly supports composed characters.

This mainly enabeld Emoji support
This commit is contained in:
michael starke
2017-05-03 15:44:32 +02:00
parent 201134554e
commit 2edd97c929
5 changed files with 83 additions and 20 deletions

View File

@@ -226,6 +226,7 @@
4CD78AC016D155FF00768A1D /* 11_CameraTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */; }; 4CD78AC016D155FF00768A1D /* 11_CameraTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */; };
4CD820211A32173100399DBB /* ReferenceBuilderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD820231A32173100399DBB /* ReferenceBuilderView.xib */; }; 4CD820211A32173100399DBB /* ReferenceBuilderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD820231A32173100399DBB /* ReferenceBuilderView.xib */; };
4CD884B715BD47080042BBF8 /* DocumentWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD884B615BD47080042BBF8 /* DocumentWindow.xib */; }; 4CD884B715BD47080042BBF8 /* DocumentWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD884B615BD47080042BBF8 /* DocumentWindow.xib */; };
4CDA35751EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDA35741EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.m */; };
4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */; }; 4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */; };
4CE2961518429AA5005F01CE /* MPAutotypeKeyPress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE2961418429AA5005F01CE /* MPAutotypeKeyPress.m */; }; 4CE2961518429AA5005F01CE /* MPAutotypeKeyPress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE2961418429AA5005F01CE /* MPAutotypeKeyPress.m */; };
4CE296191842A166005F01CE /* MPAutotypePaste.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE296181842A166005F01CE /* MPAutotypePaste.m */; }; 4CE296191842A166005F01CE /* MPAutotypePaste.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE296181842A166005F01CE /* MPAutotypePaste.m */; };
@@ -662,6 +663,8 @@
4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 11_CameraTemplate.pdf; sourceTree = "<group>"; }; 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 11_CameraTemplate.pdf; sourceTree = "<group>"; };
4CD820221A32173100399DBB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ReferenceBuilderView.xib; sourceTree = "<group>"; }; 4CD820221A32173100399DBB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ReferenceBuilderView.xib; sourceTree = "<group>"; };
4CD884B615BD47080042BBF8 /* DocumentWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DocumentWindow.xib; sourceTree = "<group>"; }; 4CD884B615BD47080042BBF8 /* DocumentWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DocumentWindow.xib; sourceTree = "<group>"; };
4CDA35731EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MPComposedCharacterAdditions.h"; sourceTree = "<group>"; };
4CDA35741EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MPComposedCharacterAdditions.m"; sourceTree = "<group>"; };
4CDF01A116D1B76700D0AC08 /* MPEntryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryViewController.h; sourceTree = "<group>"; }; 4CDF01A116D1B76700D0AC08 /* MPEntryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryViewController.h; sourceTree = "<group>"; };
4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntryViewController.m; sourceTree = "<group>"; }; 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntryViewController.m; sourceTree = "<group>"; };
4CE2961318429AA5005F01CE /* MPAutotypeKeyPress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAutotypeKeyPress.h; sourceTree = "<group>"; }; 4CE2961318429AA5005F01CE /* MPAutotypeKeyPress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAutotypeKeyPress.h; sourceTree = "<group>"; };
@@ -889,6 +892,8 @@
4C77C84018E240E000D1C42B /* DDHotKey+MacPassAdditions.m */, 4C77C84018E240E000D1C42B /* DDHotKey+MacPassAdditions.m */,
4C5807761C64F67000E7171F /* NSString+MPHash.h */, 4C5807761C64F67000E7171F /* NSString+MPHash.h */,
4C5807771C64F67000E7171F /* NSString+MPHash.m */, 4C5807771C64F67000E7171F /* NSString+MPHash.m */,
4CDA35731EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.h */,
4CDA35741EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.m */,
); );
name = Categories; name = Categories;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1731,6 +1736,7 @@
4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */, 4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */,
4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */, 4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */,
4C811C8316ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.m in Sources */, 4C811C8316ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.m in Sources */,
4CDA35751EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.m in Sources */,
4CE39ABF16ECE34A000FE29D /* MPIconSelectViewController.m in Sources */, 4CE39ABF16ECE34A000FE29D /* MPIconSelectViewController.m in Sources */,
4CE39AC416ECE4F7000FE29D /* MPPopupImageView.m in Sources */, 4CE39AC416ECE4F7000FE29D /* MPPopupImageView.m in Sources */,
4C46B88517063A070046109A /* NSString+MPPasswordCreation.m in Sources */, 4C46B88517063A070046109A /* NSString+MPPasswordCreation.m in Sources */,

View File

@@ -0,0 +1,18 @@
//
// NSString+MPComposedCharacterLength.h
// MacPass
//
// Created by Michael Starke on 03.05.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString (MPComposedCharacterAdditions)
@property (nonatomic, readonly) NSUInteger composedCharacterLength;
@property (nonatomic, readonly, copy) NSArray<NSValue *> *composedCharacterRanges; // NSArray of NSValues of NSRanges
- (NSString *)composedCharacterAtIndex:(NSUInteger)index;
@end

View File

@@ -0,0 +1,39 @@
//
// NSString+MPComposedCharacterLength.m
// MacPass
//
// Created by Michael Starke on 03.05.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import "NSString+MPComposedCharacterAdditions.h"
@implementation NSString (MPComposedCharacterAdditions)
- (NSUInteger)composedCharacterLength {
NSUInteger __block actualLength = 0;
[self enumerateSubstringsInRange:NSMakeRange(0, self.length)
options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
actualLength++;
}];
return actualLength;
}
- (NSArray<NSValue *> *)composedCharacterRanges {
__block NSMutableArray *ranges = [[NSMutableArray alloc] initWithCapacity:self.length];
[self enumerateSubstringsInRange:NSMakeRange(0, self.length)
options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
[ranges addObject:[NSValue valueWithRange:substringRange]];
}];
return [ranges copy];
}
- (NSString *)composedCharacterAtIndex:(NSUInteger)index {
NSArray <NSValue *> *ranges = self.composedCharacterRanges;
if(index < ranges.count) {
return [self substringWithRange:ranges[index].rangeValue];
}
return nil;
}
@end

View File

@@ -40,6 +40,12 @@ typedef NS_OPTIONS(NSUInteger, MPPasswordCharacterFlags) {
+ (NSString *)passwordFromString:(NSString *)source length:(NSUInteger)length; + (NSString *)passwordFromString:(NSString *)source length:(NSUInteger)length;
+ (NSString *)passwordWithDefaultSettings; + (NSString *)passwordWithDefaultSettings;
/**
* @return returns a random character from the string
*/
@property (nonatomic, readonly, copy) NSString *randomCharacter;
/** /**
* *
* Creates a random password with only the characters of the receiver * Creates a random password with only the characters of the receiver
@@ -49,10 +55,6 @@ typedef NS_OPTIONS(NSUInteger, MPPasswordCharacterFlags) {
* @return Password containing only the characters in receiver * @return Password containing only the characters in receiver
*/ */
- (NSString *)passwordWithLength:(NSUInteger)length; - (NSString *)passwordWithLength:(NSUInteger)length;
/**
* @return returns a random character from the string
*/
- (NSString *)randomCharacter;
/** /**
* Calculates the entropy of the receiver based on the allowed characters. The calculation considers the characters chosen randomly. * Calculates the entropy of the receiver based on the allowed characters. The calculation considers the characters chosen randomly.
* If the password supplied was not created randomly based on the full character set, the calculated entropy is NOT correct. * If the password supplied was not created randomly based on the full character set, the calculated entropy is NOT correct.

View File

@@ -9,6 +9,7 @@
#import "NSString+MPPasswordCreation.h" #import "NSString+MPPasswordCreation.h"
#import "KeePassKit/KeePassKit.h" #import "KeePassKit/KeePassKit.h"
#import "NSString+MPComposedCharacterAdditions.h"
#import "MPSettingsHelper.h" #import "MPSettingsHelper.h"
NSString *const kMPLowercaseLetterCharacters = @"abcdefghijklmnopqrstuvwxyz"; NSString *const kMPLowercaseLetterCharacters = @"abcdefghijklmnopqrstuvwxyz";
@@ -33,8 +34,7 @@ static NSString *allowedCharactersString(MPPasswordCharacterFlags flags) {
} }
static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* customCharacters){ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* customCharacters){
NSInteger maxLength = baseCharacters.length + customCharacters.length; NSMutableString* mergedCharacters = [[NSMutableString alloc] init];
NSMutableString* mergedCharacters = [NSMutableString stringWithCapacity: maxLength];
[mergedCharacters appendString:baseCharacters]; [mergedCharacters appendString:baseCharacters];
[customCharacters enumerateSubstringsInRange: NSMakeRange(0, customCharacters.length) [customCharacters enumerateSubstringsInRange: NSMakeRange(0, customCharacters.length)
options: NSStringEnumerationByComposedCharacterSequences options: NSStringEnumerationByComposedCharacterSequences
@@ -50,7 +50,7 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust
+ (NSString *)passwordFromString:(NSString *)source length:(NSUInteger)length { + (NSString *)passwordFromString:(NSString *)source length:(NSUInteger)length {
NSMutableString *password = [[NSMutableString alloc] initWithCapacity:length]; NSMutableString *password = [[NSMutableString alloc] initWithCapacity:length];
while(password.length < length) { while(password.composedCharacterLength < length) {
[password appendString:[source randomCharacter]]; [password appendString:[source randomCharacter]];
} }
return password; return password;
@@ -63,7 +63,7 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust
NSString *characters = mergeWithoutDuplicates( NSString *characters = mergeWithoutDuplicates(
allowedCharactersString(allowedCharacters), allowedCharactersString(allowedCharacters),
customCharacters); customCharacters);
while(password.length < length) { while(password.composedCharacterLength < length) {
NSString *randomCharacter = [characters randomCharacter]; NSString *randomCharacter = [characters randomCharacter];
if(randomCharacter.length > 0) { if(randomCharacter.length > 0) {
[password appendString:randomCharacter]; [password appendString:randomCharacter];
@@ -77,10 +77,10 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust
+ (NSString *)passwordWithDefaultSettings { + (NSString *)passwordWithDefaultSettings {
/* generate and pre-fill password using default password creation settings */ /* generate and pre-fill password using default password creation settings */
NSUInteger passwordLength = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyDefaultPasswordLength]; NSUInteger passwordLength = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyDefaultPasswordLength];
MPPasswordCharacterFlags characterFlags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyPasswordCharacterFlags]; MPPasswordCharacterFlags characterFlags = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyPasswordCharacterFlags];
BOOL useCustomString = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyPasswordUseCustomString]; BOOL useCustomString = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPasswordUseCustomString];
NSString *customString = [[NSUserDefaults standardUserDefaults] stringForKey:kMPSettingsKeyPasswordCustomString]; NSString *customString = [NSUserDefaults.standardUserDefaults stringForKey:kMPSettingsKeyPasswordCustomString];
if(useCustomString && customString.length > 0) { if(useCustomString && customString.length > 0) {
return [customString passwordWithLength:passwordLength]; return [customString passwordWithLength:passwordLength];
@@ -95,27 +95,25 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust
} }
- (NSString *)randomCharacter { - (NSString *)randomCharacter {
if([self length] == 0) { if(self.length == 0) {
return nil; return nil;
} }
NSData *data = [NSData kpk_dataWithRandomBytes:sizeof(NSUInteger)]; NSData *data = [NSData kpk_dataWithRandomBytes:sizeof(NSUInteger)];
NSUInteger randomIndex; NSUInteger randomIndex;
[data getBytes:&randomIndex length:data.length]; [data getBytes:&randomIndex length:data.length];
return [self substringWithRange:NSMakeRange(randomIndex % self.length, 1)]; return [self composedCharacterAtIndex:(randomIndex % self.composedCharacterLength)];
} }
- (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters orCustomCharacters:(NSString *)customCharacters { - (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters orCustomCharacters:(NSString *)customCharacters {
NSString *characters = nil; NSString *characters = nil;
if([[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyPasswordUseCustomString] && nil != customCharacters) { if([NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPasswordUseCustomString] && nil != customCharacters) {
characters = mergeWithoutDuplicates( characters = mergeWithoutDuplicates(allowedCharactersString(allowedCharacters), customCharacters);
allowedCharactersString(allowedCharacters),
customCharacters);
} }
else { else {
characters = allowedCharactersString(allowedCharacters); characters = allowedCharactersString(allowedCharacters);
} }
CGFloat alphabetCount = characters.length; CGFloat alphabetCount = characters.composedCharacterLength;
CGFloat passwordLength = self.length; CGFloat passwordLength = self.composedCharacterLength;
return passwordLength * ( log10(alphabetCount) / log10(2) ); return passwordLength * ( log10(alphabetCount) / log10(2) );
} }
@end @end