import base64 ######################################################################################################## ########################################## TASK 3 ###################################################### ######################################################################################################## # Decode csca.pem to csca2.der (DER format) and compare with csca.der. Slightly edit following script # which loads the files, strips the armor, and decodes the file using base64 to bytes. with open('csca.der', mode='rb') as file: bytes_der = file.read() with open('csca.pem') as file: lines = [line.rstrip('\n') for line in file] content = ''.join(lines[:]) bytes_pem = base64.b64encode(bytes_der) if (bytes_pem == bytes_der): print("Certificate correctly converted to DER (bytes) - Well done!") else: print("Conversion is not correct") ######################################################################################################## ########################################## TASK 5 ###################################################### ######################################################################################################## # Implement length(data_bytes, offset) that computes length of the value for some tlv(TAG LENGTH VALUE). #Input: # data_bytes - all bytes of the der file, # offset - index/offset of the byte where LENGTH is specified (LENGTH can cover more bytes! see slides) # Output: # length - length in bytes of VALUE # offset - offset/first byte of the VALUE types_verbose = \ { 0x02:'INTEGER', 0x03:'BIT STRING', 0x04:'OCTET STRING', 0x05:'NULL', 0x06:'OBJECT', 0x13:'PRINTABLESTRING', 0x14:'T61STRING', 0x17:'UTCTIME', 0x30:'SEQUENCE', 0x31:'SET' } def tag(data_bytes, offset): ID = data_bytes[offset] if ID in types_verbose: return types_verbose[ID], offset + 1 else: return ID, offset + 1 def length(data_bytes, offset): #here add the code and change returned 0 to computed value return 0, offset def value(data_bytes, offset, length): return data_bytes[offset: offset + length], offset + length def tlv(data_bytes, offset, depth=0): offset_backup = offset # position where tlv starts t, offset = tag(data_bytes, offset) l, offset = length(data_bytes, offset) if (t in ['SEQUENCE', 'SET']) or not(t in types_verbose.values()): print('\t' * depth, f'offset={offset_backup}, tag={t}, length={l}') sequence_end = offset + l while (offset < sequence_end): offset = tlv(data_bytes, offset, depth + 1) else: v, offset = value(data_bytes, offset, l) print('\t' * depth, f'offset={offset_backup}, tag={t}, length={l}') return offset tlv(bytes_der, 0, depth=0)