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[1:-1]) bytes_pem = base64.b64decode(content) if (bytes_pem == bytes_der): print("Certificate correctly converted to DER (bytes) - Well done!") else: print("Conversion is not correct") ######################################################################################################## ########################################## TASK 4 ###################################################### ######################################################################################################## # Implement length(data_bytes, offset) which takes: # data_bytes: bytes of the der file # offset: 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): '''returns length + offset''' l = data_bytes[offset] offset += 1 assert(l != 0x80), 'indefinite length' if l < 128: return l, offset else: l -= 128 return int.from_bytes(data_bytes[offset: offset + l], byteorder='big', signed=False), offset + l 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)