Skip to content

Commit 11e2f4c

Browse files
author
lukpueh
authored
Merge pull request #1191 from lukpueh/adopt-sslib-interface-changes
Adopt sslib keygen interface encryption changes
2 parents 201e07d + dc20fdb commit 11e2f4c

10 files changed

Lines changed: 106 additions & 93 deletions

File tree

docs/TUTORIAL.md

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,15 @@ text without prepended symbols is the output of a command.
9696
# following function creates an RSA key pair, where the private key is saved to
9797
# "root_key" and the public key to "root_key.pub" (both saved to the current
9898
# working directory).
99-
>>> generate_and_write_rsa_keypair("root_key", bits=2048, password="password")
99+
>>> generate_and_write_rsa_keypair(password="password", filepath="root_key", bits=2048)
100100

101101
# If the key length is unspecified, it defaults to 3072 bits. A length of less
102-
# than 2048 bits raises an exception. A password may be supplied as an
103-
# argument, otherwise a user prompt is presented. If an empty password
104-
# is entered, the private key is saved unencrypted.
105-
>>> generate_and_write_rsa_keypair("root_key2")
106-
Enter a password for the RSA key (/path/to/root_key2):
102+
# than 2048 bits raises an exception. A similar function is available to supply
103+
# a password on the prompt. If an empty password is entered, the private key
104+
# is saved unencrypted.
105+
>>> generate_and_write_rsa_keypair_with_prompt(filepath="root_key2")
106+
enter password to encrypt private key file '/path/to/root_key2'
107+
(leave empty if key should not be encrypted):
107108
Confirm:
108109
```
109110
The following four key files should now exist:
@@ -117,8 +118,9 @@ If a filepath is not given, the KEYID of the generated key is used as the
117118
filename. The key files are written to the current working directory.
118119
```python
119120
# Continuing from the previous section . . .
120-
>>> generate_and_write_rsa_keypair()
121-
Enter a password for the encrypted RSA key (/path/to/b5b8de8aeda674bce948fbe82cab07e309d6775fc0ec299199d16746dc2bd54c):
121+
>>> generate_and_write_rsa_keypair_with_prompt()
122+
enter password to encrypt private key file '/path/to/KEYID'
123+
(leave empty if key should not be encrypted):
122124
Confirm:
123125
```
124126

@@ -132,36 +134,27 @@ Confirm:
132134
# Import an existing private key. Importing a private key requires a password,
133135
# whereas importing a public key does not.
134136
>>> private_root_key = import_rsa_privatekey_from_file("root_key")
135-
Enter a password for the encrypted RSA key (/path/to/root_key):
136-
```
137-
138-
`import_rsa_privatekey_from_file()` raises a
139-
`securesystemslib.exceptions.CryptoError` exception if the key / password is
140-
invalid:
141-
142-
```
143-
securesystemslib.exceptions.CryptoError: RSA (public, private) tuple cannot be
144-
generated from the encrypted PEM string: Bad decrypt. Incorrect password?
137+
enter password to decrypt private key file '/path/to/root_key'
138+
(leave empty if key not encrypted):
145139
```
146140

147141
### Create and Import Ed25519 Keys ###
148142
```Python
149143
# Continuing from the previous section . . .
150144

151-
# Generate and write an Ed25519 key pair. A 'password' argument may be
152-
# supplied, otherwise a prompt is presented. The private key is saved
153-
# encrypted if a non-empty password is given, and unencrypted if the password
154-
# is empty.
155-
>>> generate_and_write_ed25519_keypair('ed25519_key')
156-
Enter a password for the Ed25519 key (/path/to/ed25519_key):
145+
# The same generation and import functions as for rsa keys exist for ed25519
146+
>>> generate_and_write_ed25519_keypair_with_prompt(filepath='ed25519_key')
147+
enter password to encrypt private key file '/path/to/ed25519_key'
148+
(leave empty if key should not be encrypted):
157149
Confirm:
158150

159151
# Import the ed25519 public key just created . . .
160152
>>> public_ed25519_key = import_ed25519_publickey_from_file('ed25519_key.pub')
161153

162154
# and its corresponding private key.
163155
>>> private_ed25519_key = import_ed25519_privatekey_from_file('ed25519_key')
164-
Enter a password for the encrypted Ed25519 key (/path/to/ed25519_key):
156+
enter password to decrypt private key file '/path/to/ed25519_key'
157+
(leave empty if key should not be encrypted):
165158
```
166159

167160
Note: Methods are also available to generate and write keys from memory.
@@ -259,26 +252,20 @@ secure manner.
259252
>>> import datetime
260253

261254
# Generate keys for the remaining top-level roles. The root keys have been set above.
262-
# The password argument may be omitted if a password prompt is needed.
263-
>>> generate_and_write_rsa_keypair('targets_key', password='password')
264-
>>> generate_and_write_rsa_keypair('snapshot_key', password='password')
265-
>>> generate_and_write_rsa_keypair('timestamp_key', password='password')
255+
>>> generate_and_write_rsa_keypair(password='password', filepath='targets_key')
256+
>>> generate_and_write_rsa_keypair(password='password', filepath='snapshot_key')
257+
>>> generate_and_write_rsa_keypair(password='password', filepath='timestamp_key')
266258

267259
# Add the verification keys of the remaining top-level roles.
268260

269261
>>> repository.targets.add_verification_key(import_rsa_publickey_from_file('targets_key.pub'))
270262
>>> repository.snapshot.add_verification_key(import_rsa_publickey_from_file('snapshot_key.pub'))
271263
>>> repository.timestamp.add_verification_key(import_rsa_publickey_from_file('timestamp_key.pub'))
272264

273-
# Import the signing keys of the remaining top-level roles. Prompt for passwords.
274-
>>> private_targets_key = import_rsa_privatekey_from_file('targets_key')
275-
Enter a password for the encrypted RSA key (/path/to/targets_key):
276-
277-
>>> private_snapshot_key = import_rsa_privatekey_from_file('snapshot_key')
278-
Enter a password for the encrypted RSA key (/path/to/snapshot_key):
279-
280-
>>> private_timestamp_key = import_rsa_privatekey_from_file('timestamp_key')
281-
Enter a password for the encrypted RSA key (/path/to/timestamp_key):
265+
# Import the signing keys of the remaining top-level roles.
266+
>>> private_targets_key = import_rsa_privatekey_from_file('targets_key', password='password')
267+
>>> private_snapshot_key = import_rsa_privatekey_from_file('snapshot_key', password='password')
268+
>>> private_timestamp_key = import_rsa_privatekey_from_file('timestamp_key', password='password')
282269

283270
# Load the signing keys of the remaining roles so that valid signatures are
284271
# generated when repository.writeall() is called.
@@ -390,18 +377,21 @@ metadata. `snapshot.json` keys must be loaded and its metadata signed because
390377
# The private key of the updated targets metadata must be re-loaded before it
391378
# can be signed and written (Note the load_repository() call above).
392379
>>> private_targets_key = import_rsa_privatekey_from_file('targets_key')
393-
Enter a password for the encrypted RSA key (/path/to/targets_key):
380+
enter password to decrypt private key file '/path/to/targets_key'
381+
(leave empty if key not encrypted):
394382

395383
>>> repository.targets.load_signing_key(private_targets_key)
396384

397385
# Due to the load_repository() and new versions of metadata, we must also load
398386
# the private keys of Snapshot and Timestamp to generate a valid set of metadata.
399387
>>> private_snapshot_key = import_rsa_privatekey_from_file('snapshot_key')
400-
Enter a password for the encrypted RSA key (/path/to/snapshot_key):
388+
enter password to decrypt private key file '/path/to/snapshot_key'
389+
(leave empty if key not encrypted):
401390
>>> repository.snapshot.load_signing_key(private_snapshot_key)
402391

403392
>>> private_timestamp_key = import_rsa_privatekey_from_file('timestamp_key')
404-
Enter a password for the encrypted RSA key (/path/to/timestamp_key):
393+
enter password to decrypt private key file '/path/to/timestamp_key'
394+
(leave empty if key not encrypted):
405395
>>> repository.timestamp.load_signing_key(private_timestamp_key)
406396

407397
# Mark roles for metadata update (see #964, #958)
@@ -451,7 +441,7 @@ threshold, it needs to be added to `root.json`, e.g. via
451441
>>> from securesystemslib.formats import encode_canonical
452442
>>> from securesystemslib.keys import create_signature
453443
>>> private_ed25519_key = import_ed25519_privatekey_from_file('ed25519_key')
454-
Enter a password for the encrypted Ed25519 key (/path/to/ed25519_key):
444+
enter password to decrypt private key file '/path/to/ed25519_key'
455445
>>> signature = create_signature(
456446
... private_ed25519_key, encode_canonical(signable_content).encode())
457447
```
@@ -489,7 +479,7 @@ targets and generate signed metadata.
489479
# Continuing from the previous section . . .
490480

491481
# Generate a key for a new delegated role named "unclaimed".
492-
>>> generate_and_write_rsa_keypair('unclaimed_key', bits=2048, password='password')
482+
>>> generate_and_write_rsa_keypair(password='password', filepath='unclaimed_key', bits=2048)
493483
>>> public_unclaimed_key = import_rsa_publickey_from_file('unclaimed_key.pub')
494484

495485
# Make a delegation (delegate trust of 'myproject/*.txt' files) from "targets"
@@ -502,8 +492,7 @@ targets and generate signed metadata.
502492

503493
# Load the private key of "unclaimed" so that unclaimed's metadata can be
504494
# signed, and valid metadata created.
505-
>>> private_unclaimed_key = import_rsa_privatekey_from_file('unclaimed_key')
506-
Enter a password for the encrypted RSA key (/path/to/unclaimed_key):
495+
>>> private_unclaimed_key = import_rsa_privatekey_from_file('unclaimed_key', password='password')
507496

508497
>>> repository.targets("unclaimed").load_signing_key(private_unclaimed_key)
509498

requirements-pinned.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ipaddress==1.0.23 ; python_version < '3' # via cryptography
88
pycparser==2.20 # via cffi
99
pynacl==1.4.0 # via securesystemslib
1010
requests==2.24.0
11-
securesystemslib[crypto,pynacl]==0.17.0
11+
securesystemslib[crypto,pynacl]==0.18.0
1212
six==1.15.0
1313
subprocess32==3.5.4 ; python_version < '3' # via securesystemslib
1414
urllib3==1.25.11 # via requests

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
install_requires = [
118118
'requests>=2.19.1',
119119
'six>=1.11.0',
120-
'securesystemslib>=0.16.0'
120+
'securesystemslib>=0.18.0'
121121
],
122122
tests_require = [
123123
'mock; python_version < "3.3"'

tests/repository_data/generate.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@
5959
# Generate public and private key files for the top-level roles, and two
6060
# delegated roles (these number of keys should be sufficient for most of the
6161
# unit tests). Unit tests may generate additional keys, if needed.
62-
generate_and_write_rsa_keypair(root_key_file, password='password')
63-
generate_and_write_ed25519_keypair(targets_key_file, password='password')
64-
generate_and_write_ed25519_keypair(snapshot_key_file, password='password')
65-
generate_and_write_ed25519_keypair(timestamp_key_file, password='password')
66-
generate_and_write_ed25519_keypair(delegation_key_file, password='password')
62+
generate_and_write_rsa_keypair(password='password', filepath=root_key_file)
63+
generate_and_write_ed25519_keypair(password='password', filepath=targets_key_file)
64+
generate_and_write_ed25519_keypair(password='password', filepath=snapshot_key_file)
65+
generate_and_write_ed25519_keypair(password='password', filepath=timestamp_key_file)
66+
generate_and_write_ed25519_keypair(password='password', filepath=delegation_key_file)
6767

6868
# Import the public keys. These keys are needed so that metadata roles are
6969
# assigned verification keys, which clients use to verify the signatures created

tests/test_repository_lib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ def test_import_ed25519_privatekey_from_file(self):
143143
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
144144
ed25519_keypath = os.path.join(temporary_directory, 'ed25519_key')
145145
securesystemslib.interface.generate_and_write_ed25519_keypair(
146-
ed25519_keypath, password='pw')
146+
password='pw', filepath=ed25519_keypath)
147147

148148
imported_ed25519_key = \
149149
repo_lib.import_ed25519_privatekey_from_file(ed25519_keypath, 'pw')

tests/test_tutorial.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ def test_tutorial(self):
7575

7676
# ----- Tutorial Section: Keys
7777

78-
generate_and_write_rsa_keypair('root_key', bits=2048, password='password')
78+
generate_and_write_rsa_keypair(password='password', filepath='root_key', bits=2048)
7979

8080
# Skipping user entry of password
81-
## generate_and_write_rsa_keypair('root_key2')
82-
generate_and_write_rsa_keypair('root_key2', password='password')
81+
## generate_and_write_rsa_keypair_with_prompt('root_key2')
82+
generate_and_write_rsa_keypair(password='password', filepath='root_key2')
8383

8484
# Tutorial tells users to expect these files to exist:
8585
# ['root_key', 'root_key.pub', 'root_key2', 'root_key2.pub']
@@ -109,8 +109,8 @@ def test_tutorial(self):
109109
# ----- Tutorial Section: Create and Import Ed25519 Keys
110110

111111
# Skipping user entry of password
112-
## generate_and_write_ed25519_keypair('ed25519_key')
113-
generate_and_write_ed25519_keypair('ed25519_key', password='password')
112+
## generate_and_write_ed25519_keypair_with_prompt('ed25519_key')
113+
generate_and_write_ed25519_keypair(password='password', filepath='ed25519_key')
114114

115115
public_ed25519_key = import_ed25519_publickey_from_file('ed25519_key.pub')
116116

@@ -157,9 +157,9 @@ def test_tutorial(self):
157157
repr('targets') + " role contains 0 / 1 signatures."
158158
], [args[0] for args, _ in mock_logger.info.call_args_list])
159159

160-
generate_and_write_rsa_keypair('targets_key', password='password')
161-
generate_and_write_rsa_keypair('snapshot_key', password='password')
162-
generate_and_write_rsa_keypair('timestamp_key', password='password')
160+
generate_and_write_rsa_keypair(password='password', filepath='targets_key')
161+
generate_and_write_rsa_keypair(password='password', filepath='snapshot_key')
162+
generate_and_write_rsa_keypair(password='password', filepath='timestamp_key')
163163

164164
repository.targets.add_verification_key(import_rsa_publickey_from_file(
165165
'targets_key.pub'))
@@ -309,7 +309,7 @@ def test_tutorial(self):
309309

310310
# ----- Tutorial Section: Delegations
311311
generate_and_write_rsa_keypair(
312-
'unclaimed_key', bits=2048, password='password')
312+
password='password', filepath='unclaimed_key', bits=2048)
313313
public_unclaimed_key = import_rsa_publickey_from_file('unclaimed_key.pub')
314314
repository.targets.delegate(
315315
'unclaimed', [public_unclaimed_key], ['myproject/*.txt'])

tuf/README-developer-tools.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,16 @@ is the private key.
5353

5454
```
5555
>>> from tuf.developer_tool import *
56-
>>> generate_and_write_rsa_keypair("path/to/key")
57-
Enter a password for the RSA key:
56+
>>> generate_and_write_rsa_keypair_with_prompt(filepath="path/to/key")
57+
enter password to encrypt private key file 'path/to/key'
58+
(leave empty if key should not be encrypted):
5859
Confirm:
5960
>>>
6061
```
6162

6263
We can also use the bits parameter to set a different key length (the default
63-
is 3072). We can also provide the password parameter in order to suppress the
64-
password prompt.
64+
is 3072). We can also `generate_and_write_rsa_keypair` with a `password`
65+
parameter if a prompt is not desired.
6566

6667
In this example we will be using rsa keys, but ed25519 keys are also supported.
6768

@@ -257,7 +258,7 @@ When generating keys, it is possible to specify the length of the key in bits
257258
and its password as parameters:
258259

259260
```
260-
>>> generate_and_write_rsa_keypair("path/to/key", bits=2048, password="pw")
261+
>>> generate_and_write_rsa_keypair(password="pw", filepath="path/to/key", bits=2048)
261262
```
262263
The bits parameter defaults to 3072, and values below 2048 will raise an error.
263264
The password parameter is only intended to be used in scripts.

tuf/developer_tool.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,14 @@
7676

7777
from securesystemslib.interface import (
7878
generate_and_write_rsa_keypair,
79+
generate_and_write_rsa_keypair_with_prompt,
80+
generate_and_write_unencrypted_rsa_keypair,
81+
generate_and_write_ecdsa_keypair,
82+
generate_and_write_ecdsa_keypair_with_prompt,
83+
generate_and_write_unencrypted_ecdsa_keypair,
7984
generate_and_write_ed25519_keypair,
85+
generate_and_write_ed25519_keypair_with_prompt,
86+
generate_and_write_unencrypted_ed25519_keypair,
8087
import_rsa_publickey_from_file,
8188
import_ed25519_publickey_from_file,
8289
import_ed25519_privatekey_from_file)

tuf/repository_tool.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,14 @@
7474

7575
from securesystemslib.interface import (
7676
generate_and_write_rsa_keypair,
77+
generate_and_write_rsa_keypair_with_prompt,
78+
generate_and_write_unencrypted_rsa_keypair,
7779
generate_and_write_ecdsa_keypair,
80+
generate_and_write_ecdsa_keypair_with_prompt,
81+
generate_and_write_unencrypted_ecdsa_keypair,
7882
generate_and_write_ed25519_keypair,
83+
generate_and_write_ed25519_keypair_with_prompt,
84+
generate_and_write_unencrypted_ed25519_keypair,
7985
import_rsa_publickey_from_file,
8086
import_ecdsa_publickey_from_file,
8187
import_ed25519_publickey_from_file,

0 commit comments

Comments
 (0)