Skip to content

Commit

Permalink
Adding the repoint function, and some tests. Fixing the list of tests
Browse files Browse the repository at this point in the history
  • Loading branch information
silverdaz committed Jul 11, 2024
1 parent 40099da commit 5f3d2ef
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 5 deletions.
2 changes: 1 addition & 1 deletion crypt4gh/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def main(argv=sys.argv[1:]):
args = cli.parse_args(argv)

# Main Commands
for command in ('encrypt', 'decrypt', 'rearrange', 'reencrypt'):
for command in ('encrypt', 'decrypt', 'rearrange', 'reencrypt', 'repoint'):
if args.get(command):
cmd = getattr(cli,command,None)
if not cmd:
Expand Down
25 changes: 21 additions & 4 deletions crypt4gh/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
Usage:
{PROG} [-hv] [--log <file>] encrypt [--sk <path>] --recipient_pk <path> [--recipient_pk <path>]... [--range <start-end>] [--header <path>] [--expiration <date>] [--uri <path>]
{PROG} [-hv] [--log <file>] decrypt [--sk <path>] [--sender_pk <path>] [--range <start-end>]
{PROG} [-hv] [--log <file>] rearrange [--sk <path>] --range <start-end>
{PROG} [-hv] [--log <file>] reencrypt [--sk <path>] --recipient_pk <path> [--recipient_pk <path>]... [--trim] [--header-only]
{PROG} [-hv] [--log <file>] rearrange [--sk <path>] --range <start-end>
{PROG} [-hv] [--log <file>] repoint [--sk <path>] --uri <path>
Options:
-h, --help Prints this help and exit
Expand Down Expand Up @@ -84,9 +85,6 @@ def parse_args(argv=sys.argv[1:]):
if args['--range'] is not None and args['--uri'] is not None:
raise ValueError('Can not mix --range and --uri')

if args['--uri'] is not None and args['--header'] is None:
raise ValueError('--uri requires --header')

# print(args)
return args

Expand Down Expand Up @@ -140,6 +138,9 @@ def make_timestamp(date):
def encrypt(args):
assert( args['encrypt'] )

if args['--uri'] is not None and args['--header'] is None:
raise ValueError('--uri requires --header')

range_start, range_span = parse_range(args)

seckey = retrieve_private_key(args, generate=True)
Expand Down Expand Up @@ -245,3 +246,19 @@ def build_recipients():
sys.stdout.buffer,
trim=args['--trim'],
header_only=args['--header-only'])

def repoint(args):
assert( args['repoint'] )

# if args['--uri'] is None:
# raise ValueError('--uri is required')

seckey = retrieve_private_key(args)

keys = [(0, seckey, bytes(PrivateKey(seckey).public_key))] # keys = list of (method, privkey, recipient_pubkey=ourselves)

lib.repoint(keys,
sys.stdin.buffer,
sys.stdout.buffer,
args['--uri'])

40 changes: 40 additions & 0 deletions crypt4gh/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,43 @@ def segment_oracle():
return packets, segment_oracle()


# -------------------------------------
# Header Re-Arrange
# -------------------------------------

def repoint(header_packets, keys, uri, sender_pubkey=None):
'''
Re-point the link to the given URI.
:returns: the packet list as-is, replacing with (or adding) a new link packet.
Note: we trim the packets we couldn't decrypt
'''

LOG.info('Repointing the header to URI: %s', uri)

decrypted_packets, _ = decrypt(header_packets, keys, sender_pubkey=sender_pubkey)

if not decrypted_packets:
raise ValueError('No header packet could be decrypted')

data_packets, edits, timestamp, link = extract(decrypted_packets)

if link is None:
LOG.warning('Ignoring existing link poiting to %s', link)


LOG.info('Reencrypting all packets')

packets = [PACKET_TYPE_DATA_ENC + packet for packet in data_packets]
packets.append(make_packet_link(uri)) # Adding a new URI
if timestamp is not None:
packets.append(make_packet_timestamp(timestamp))
if edits is not None:
packets.append(make_packet_data_edit_list(edits))

packets = [encrypted_packet for packet in packets for encrypted_packet in encrypt(packet, keys)]

return packets


25 changes: 25 additions & 0 deletions crypt4gh/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,3 +494,28 @@ def rearrange(keys, infile, outfile, offset=0, span=None):
del segment_oracle # enough to terminate and remove it?
LOG.info('Rearrangement Successful')


##############################################################
##
## Adding or Updating an URI in the header
##
##############################################################

@close_on_broken_pipe
def repoint(keys, infile, outfile, uri):
'''Extract header packets from infile, replacing with (or adding) a new link packet.
The new header is sent to the outfile.
'''

# Decrypt and re-encrypt the header
header_packets = header.parse(infile)

packets = header.repoint(header_packets, keys, uri)
outfile.write(header.serialize(packets))

remainder = infile.read(1)
if not remainder:
LOG.info('Repointing Successful')
else:
LOG.warning('Not at the end of the file: Truncating here')

19 changes: 19 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,23 @@ We use the testfile and Bob encrypts it for himself.
Expected outcome: They both can read the same content as Bob had.


## Payload as URI


- [x] Bob sends the testfile secretly Alice, over an URI<br/>
Expected outcome: Alice reads the same content as testfile.

- [x] Bob sends the testfile secretly Alice, over an URI, and moves its payload.<br/>
Expected outcome: Alice repoints to the new URI and reads the same content as testfile.

## Expiration dates


- [x] Bob sends the testfile secretly Alice, with a past expiration date<br/>
Expected outcome: Alice can't decrypt the file.

- [x] Bob sends the testfile secretly Alice, with a future expiration date<br/>
Expected outcome: Alice reads the same content as testfile.



29 changes: 29 additions & 0 deletions tests/uri.bats
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,32 @@ function teardown() {

unset C4GH_PASSPHRASE
}

@test "Bob sends the testfile secretly to Alice over an URI, and repoints it" {

TESTFILE=${BATS_TEST_DIRNAME}/_common/testfile.abcd

# Bob encrypts the testfile for Alice
export C4GH_PASSPHRASE=${BOB_PASSPHRASE}
crypt4gh encrypt --recipient_pk ${ALICE_PUBKEY} --uri "file://$TESTFILES/message.c4gh.payload" --header "$TESTFILES/message.c4gh.header" < $TESTFILE > $TESTFILES/message.c4gh.payload

# Bob moves the testfile payload
mv $TESTFILES/message.c4gh.payload $TESTFILES/message.c4gh.payload.new

# Alice repoints the testfile to the new URI
export C4GH_PASSPHRASE=${ALICE_PASSPHRASE}
crypt4gh repoint --sk ${ALICE_SECKEY} --uri "file://$TESTFILES/message.c4gh.payload.new" < $TESTFILES/message.c4gh.header > $TESTFILES/message.c4gh.header.new

# Alice decrypts it
# export C4GH_PASSPHRASE=${ALICE_PASSPHRASE}
crypt4gh decrypt --sk ${ALICE_SECKEY} < $TESTFILES/message.c4gh.header.new > $TESTFILES/message.alice.received

run diff $TESTFILE $TESTFILES/message.alice.received
[ "$status" -eq 0 ]

# Alice can't access the old URI
run crypt4gh decrypt --sk ${ALICE_SECKEY} < $TESTFILES/message.c4gh.header
[ "$status" -ne 0 ]

unset C4GH_PASSPHRASE
}

0 comments on commit 5f3d2ef

Please sign in to comment.