CryptoPassphrase  Check-in [d5ba7b8a87]

Overview
Comment:Use non-swappable memory
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: d5ba7b8a87c38520b2c0ca103b585c38b1f8d84ac98b295f1029b3359fdd3388
User & Date: js on 2020-01-03 00:03:58
Other Links: manifest | tags
Context
2020-01-03
00:19
iOS: Update to recent changes check-in: 496f11bd4b user: js tags: trunk
00:03
Use non-swappable memory check-in: d5ba7b8a87 user: js tags: trunk
2019-12-28
22:46
Adjust to ObjFW changes check-in: 31d77b5098 user: js tags: trunk
Changes

Modified CryptoPassphrase.h from [4c913f774e] to [3050e24daf].

1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2019 Jonathan Schleifer <js@heap.zone>
 *
 * https://heap.zone/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

|

|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2020 Jonathan Schleifer <js@nil.im>
 *
 * https://nil.im/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

Modified CryptoPassphrase.m from [af2775fb50] to [d60a88125c].

1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2019 Jonathan Schleifer <js@heap.zone>
 *
 * https://heap.zone/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

|

|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2020 Jonathan Schleifer <js@nil.im>
 *
 * https://nil.im/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60
61
62
63
64
65
66
67


68
69
70
71
72
73
74
	};
	OFOptionsParser *optionsParser =
	    [OFOptionsParser parserWithOptions: options];
	of_unichar_t option;
	OFMutableData *keyFile = nil;
	OFString *prompt;
	const char *promptCString;
	char *passphrase;



	while ((option = [optionsParser nextOption]) != '\0') {
		switch (option) {
		case 'h':
			showHelp(of_stdout, true);

			[OFApplication terminate];







|
>
>







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
	};
	OFOptionsParser *optionsParser =
	    [OFOptionsParser parserWithOptions: options];
	of_unichar_t option;
	OFMutableData *keyFile = nil;
	OFString *prompt;
	const char *promptCString;
	char *passphraseCString;
	size_t passphraseLength;
	OFSecureData *passphrase;

	while ((option = [optionsParser nextOption]) != '\0') {
		switch (option) {
		case 'h':
			showHelp(of_stdout, true);

			[OFApplication terminate];
139
140
141
142
143
144
145
146

147
148



149


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
	prompt = [OFString stringWithFormat: @"Passphrase for site \"%@\": ",
					     generator.site];
	promptCString = [prompt cStringWithEncoding: [OFLocale encoding]];

	if (keyFilePath != nil)
		keyFile = [OFMutableData dataWithContentsOfFile: keyFilePath];

	passphrase = getpass(promptCString);

	@try {
		if (_repeat) {



			char *passphraseCopy = of_strdup(passphrase);



			if (passphraseCopy == NULL)
				@throw [OFOutOfMemoryException exception];

			@try {
				of_string_encoding_t encoding =
				    [OFLocale encoding];

				prompt = [OFString stringWithFormat:
				    @"Repeat passphrase for site \"%@\": ",
				    generator.site];
				passphrase = getpass(
				    [prompt cStringWithEncoding: encoding]);

				if (strcmp(passphrase, passphraseCopy) != 0) {
					[of_stderr writeString:
					    @"Passphrases do not match!\n"];
					[OFApplication terminateWithStatus: 1];
				}
			} @finally {
				of_explicit_memset(passphraseCopy, 0,
				    strlen(passphraseCopy));
				free(passphraseCopy);
			}
		}

		generator.keyFile = keyFile;
		generator.passphrase = passphrase;

		[generator derivePassword];
		@try {
			[of_stdout writeBuffer: generator.output
					length: generator.length];
			[of_stdout writeBuffer: "\n"
					length: 1];
		} @finally {
			of_explicit_memset(generator.output, 0,
			    generator.length);
		}
	} @finally {
		of_explicit_memset(passphrase, 0, strlen(passphrase));

		if (keyFile != nil)
			of_explicit_memset(keyFile.mutableItems, 0,
			    keyFile.count);
	}

	[OFApplication terminate];
}
@end







|
>

<
>
>
>
|
>
>
|
<
<

|
|
<

|
|
<
|
|

|
|
<
|
|
|
|
|
<
<
|

|
|

|
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<




141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157


158
159
160

161
162
163

164
165
166
167
168

169
170
171
172
173


174
175
176
177
178
179

180
181
182
183











184
185
186
187
	prompt = [OFString stringWithFormat: @"Passphrase for site \"%@\": ",
					     generator.site];
	promptCString = [prompt cStringWithEncoding: [OFLocale encoding]];

	if (keyFilePath != nil)
		keyFile = [OFMutableData dataWithContentsOfFile: keyFilePath];

	passphraseCString = getpass(promptCString);
	passphraseLength = strlen(passphraseCString);
	@try {

		passphrase = [OFSecureData dataWithCount: passphraseLength + 1
				   allowsSwappableMemory: false];
		memcpy(passphrase.mutableItems, passphraseCString,
		    passphraseLength + 1);
	} @finally {
		of_explicit_memset(passphraseCString, '\0', passphraseLength);
	}



	if (_repeat) {
		of_string_encoding_t encoding = [OFLocale encoding];


		prompt = [OFString stringWithFormat:
		    @"Repeat passphrase for site \"%@\": ", generator.site];

		passphraseCString =
		    getpass([prompt cStringWithEncoding: encoding]);

		if (strcmp(passphraseCString, passphrase.items) != 0) {
			[of_stderr writeString: @"Passphrases do not match!\n"];

			[OFApplication terminateWithStatus: 1];
		}

		of_explicit_memset(passphraseCString, '\0',
		    strlen(passphraseCString));


	}

	generator.keyFile = keyFile;
	generator.passphrase = passphrase;

	[generator derivePassword];

	[of_stdout writeBuffer: generator.output.items
			length: generator.length];
	[of_stdout writeBuffer: "\n"
			length: 1];












	[OFApplication terminate];
}
@end

Modified LegacyPasswordGenerator.h from [8b2f2b2c68] to [ecf25f2249].

1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2019 Jonathan Schleifer <js@heap.zone>
 *
 * https://heap.zone/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

|

|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2020 Jonathan Schleifer <js@nil.im>
 *
 * https://nil.im/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
24
25
26
27
28
29
30
31
32
33
#import "PasswordGenerator.h"

@interface LegacyPasswordGenerator: OFObject <PasswordGenerator>
{
	size_t _length;
	OFString *_site;
	OFData *_keyFile;
	const char *_passphrase;
	unsigned char *_output;
}
@end







|
<


23
24
25
26
27
28
29
30

31
32
#import "PasswordGenerator.h"

@interface LegacyPasswordGenerator: OFObject <PasswordGenerator>
{
	size_t _length;
	OFString *_site;
	OFData *_keyFile;
	OFSecureData *_passphrase, *_output;

}
@end

Modified LegacyPasswordGenerator.m from [c0c1315d5a] to [d5c5dfec12].

1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2019 Jonathan Schleifer <js@heap.zone>
 *
 * https://heap.zone/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

|

|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2020 Jonathan Schleifer <js@nil.im>
 *
 * https://nil.im/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54
55
56
57
58
59
60

61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
}

- (void)derivePassword
{
	OFSHA256Hash *siteHash = [OFSHA256Hash
	    cryptoHashWithAllowsSwappableMemory: true];
	size_t passphraseLength, combinedPassphraseLength;

	char *combinedPassphrase;


	[siteHash updateWithBuffer: _site.UTF8String
			    length: _site.UTF8StringLength];

	if (_output != NULL) {
		of_explicit_memset(_output, 0, _length);
		[self freeMemory: _output];
	}

	_output = [self allocMemoryWithSize: _length + 1];

	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, true);
	} @finally {
		of_explicit_memset(combinedPassphrase, 0,
		    combinedPassphraseLength);
		free(combinedPassphrase);
	}

	/*
	 * This has a bias, however, this is what scrypt-genpass does and the
	 * legacy mode wants to be compatible to scrypt-genpass.
	 */
	_output[0] = "abcdefghijklmnopqrstuvwxyz"[_output[0] % 26];
	_output[1] = "0123456789"[_output[1] % 10];
	_output[2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[_output[2] % 26];

	for (size_t i = 3; i < _length; i++)
		_output[i] = "abcdefghijklmnopqrstuvwxyz"
		    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		    "0123456789"[_output[i] % (26 + 26 + 10)];
}
@end







>
|
>




|
<
|
<
|
|

|







|
<
|
|
>
|

|
|
|

>
|
|
|
<
<
<
<
<





|
|
|


|

|


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69

70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94





95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
}

- (void)derivePassword
{
	OFSHA256Hash *siteHash = [OFSHA256Hash
	    cryptoHashWithAllowsSwappableMemory: true];
	size_t passphraseLength, combinedPassphraseLength;
	OFSecureData *combinedPassphrase;
	char *combinedPassphraseItems;
	unsigned char *outputItems;

	[siteHash updateWithBuffer: _site.UTF8String
			    length: _site.UTF8StringLength];

	[_output release];

	_output = nil;

	_output = [[OFSecureData alloc] initWithCount: _length + 1
				allowsSwappableMemory: false];

	passphraseLength = combinedPassphraseLength = _passphrase.count - 1;
	if (_keyFile != nil) {
		if (SIZE_MAX - combinedPassphraseLength < _keyFile.count)
			@throw [OFOutOfRangeException exception];

		combinedPassphraseLength += _keyFile.count;
	}

	combinedPassphrase = [OFSecureData

		    dataWithCount: combinedPassphraseLength
	    allowsSwappableMemory: false];
	combinedPassphraseItems = combinedPassphrase.mutableItems;
	memcpy(combinedPassphraseItems, _passphrase.items, passphraseLength);

	if (_keyFile != nil)
		memcpy(combinedPassphraseItems + passphraseLength,
		    _keyFile.items, _keyFile.count);

	outputItems = _output.mutableItems;
	of_scrypt(8, 524288, 2, siteHash.digest, [siteHash.class digestSize],
	    combinedPassphraseItems, combinedPassphraseLength, outputItems,
	    _length, true);






	/*
	 * This has a bias, however, this is what scrypt-genpass does and the
	 * legacy mode wants to be compatible to scrypt-genpass.
	 */
	outputItems[0] = "abcdefghijklmnopqrstuvwxyz"[outputItems[0] % 26];
	outputItems[1] = "0123456789"[outputItems[1] % 10];
	outputItems[2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[outputItems[2] % 26];

	for (size_t i = 3; i < _length; i++)
		outputItems[i] = "abcdefghijklmnopqrstuvwxyz"
		    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		    "0123456789"[outputItems[i] % (26 + 26 + 10)];
}
@end

Modified NewPasswordGenerator.h from [9f48bbafee] to [9d87dde63d].

1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2019 Jonathan Schleifer <js@heap.zone>
 *
 * https://heap.zone/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

|

|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2020 Jonathan Schleifer <js@nil.im>
 *
 * https://nil.im/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
24
25
26
27
28
29
30
31
32
33
#import "PasswordGenerator.h"

@interface NewPasswordGenerator: OFObject <PasswordGenerator>
{
	size_t _length;
	OFString *_site;
	OFData *_keyFile;
	const char *_passphrase;
	unsigned char *_output;
}
@end







|
<


23
24
25
26
27
28
29
30

31
32
#import "PasswordGenerator.h"

@interface NewPasswordGenerator: OFObject <PasswordGenerator>
{
	size_t _length;
	OFString *_site;
	OFData *_keyFile;
	OFSecureData *_passphrase, *_output;

}
@end

Modified NewPasswordGenerator.m from [37a8c168df] to [17ced95bbb].

1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2019 Jonathan Schleifer <js@heap.zone>
 *
 * https://heap.zone/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

|

|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2020 Jonathan Schleifer <js@nil.im>
 *
 * https://nil.im/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
42
43
44
45
46
47

48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
}

- (void)derivePassword
{
	OFSHA384Hash *siteHash = [OFSHA384Hash
	    cryptoHashWithAllowsSwappableMemory: true];
	size_t passphraseLength, combinedPassphraseLength;

	char *combinedPassphrase;


	[siteHash updateWithBuffer: _site.UTF8String
			    length: _site.UTF8StringLength];

	if (_output != NULL) {
		of_explicit_memset(_output, 0, _length);
		[self freeMemory: _output];
	}

	_output = [self allocMemoryWithSize: _length + 1];

	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, true);
	} @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







>
|
>




|
<
|
<
|
|

|







|
<
|
|
>
|

|
|
|

>
|
|
|
<
<
<
<
|
<

|



|


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56

57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81




82

83
84
85
86
87
88
89
90
}

- (void)derivePassword
{
	OFSHA384Hash *siteHash = [OFSHA384Hash
	    cryptoHashWithAllowsSwappableMemory: true];
	size_t passphraseLength, combinedPassphraseLength;
	OFSecureData *combinedPassphrase;
	char *combinedPassphraseItems;
	unsigned char *outputItems;

	[siteHash updateWithBuffer: _site.UTF8String
			    length: _site.UTF8StringLength];

	[_output release];

	_output = nil;

	_output = [[OFSecureData alloc] initWithCount: _length + 1
				allowsSwappableMemory: false];

	passphraseLength = combinedPassphraseLength = _passphrase.count - 1;
	if (_keyFile != nil) {
		if (SIZE_MAX - combinedPassphraseLength < _keyFile.count)
			@throw [OFOutOfRangeException exception];

		combinedPassphraseLength += _keyFile.count;
	}

	combinedPassphrase = [OFSecureData

		    dataWithCount: combinedPassphraseLength
	    allowsSwappableMemory: false];
	combinedPassphraseItems = combinedPassphrase.mutableItems;
	memcpy(combinedPassphraseItems, _passphrase.items, passphraseLength);

	if (_keyFile != nil)
		memcpy(combinedPassphraseItems + passphraseLength,
		    _keyFile.items, _keyFile.count);

	outputItems = _output.mutableItems;
	of_scrypt(8, 524288, 2, siteHash.digest, [siteHash.class digestSize],
	    combinedPassphraseItems, combinedPassphraseLength, outputItems,
	    _length, true);






	for (size_t i = 0; i < _length; i++)
		outputItems[i] =
		    "123456789"
		    "abcdefghijkmnopqrstuvwxyz"
		    "ABCDEFGHJKLMNPQRSTUVWXYZ"
		    "#$%-=?"[outputItems[i] & 0x3F];
}
@end

Modified PasswordGenerator.h from [331c2d1755] to [2fc83e5fa2].

1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2019 Jonathan Schleifer <js@heap.zone>
 *
 * https://heap.zone/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

|

|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2016 - 2020 Jonathan Schleifer <js@nil.im>
 *
 * https://nil.im/git/cryptopassphrase.git
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
23
24
25
26
27
28
29
30
31
32
33
34

#import <ObjFW/ObjFW.h>

@protocol PasswordGenerator
@property (nonatomic) size_t length;
@property (copy, nonatomic) OFString *site;
@property (retain, nonatomic) OFData *keyFile;
@property (nonatomic) const char *passphrase;
@property (readonly, nonatomic) unsigned char *output;

+ (instancetype)generator;
- (void)derivePassword;
@end







|
|




22
23
24
25
26
27
28
29
30
31
32
33
34

#import <ObjFW/ObjFW.h>

@protocol PasswordGenerator
@property (nonatomic) size_t length;
@property (copy, nonatomic) OFString *site;
@property (retain, nonatomic) OFData *keyFile;
@property (retain) OFSecureData *passphrase;
@property (readonly, nonatomic) OFSecureData *output;

+ (instancetype)generator;
- (void)derivePassword;
@end