diff --git a/enccnf b/enccnf index 4e5c257..f6337aa 100755 --- a/enccnf +++ b/enccnf @@ -236,10 +236,10 @@ def parse_enc_file(enc_file, tftp_certificate_file): try: public_key.verify(signature, tlv_data, padding.PKCS1v15(), hashes.SHA512() if hash_algorithm == HASH_SHA512 else hashes.SHA1()) + + print('Valid signature') except InvalidSignature: print('Invalid signature') - else: - print('Valid signature') def remove_enc_file(enc_file, private_key_file): @@ -459,34 +459,17 @@ def build_enc_file(cnf_file, tftp_certificate_file, certificate_file, hash_algor header_length_index = len(tlv_data) tlv_data += struct.pack('> B H H', HEADER_LENGTH, 2, 0) - signer_name = '' - - for attribute in certificate.subject: - signer_name += (';' if len(signer_name) else '') + attribute.rfc4514_string() - - signer_name = signer_name.encode('utf-8') + b'\x00' - issuer_name = '' - - for attribute in certificate.issuer: - issuer_name += (';' if len(issuer_name) else '') + attribute.rfc4514_string() - - issuer_name = issuer_name.encode('utf-8') + b'\x00' + signer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.subject]).encode('utf-8') + b'\x00' + issuer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.issuer]).encode('utf-8') + b'\x00' serial_number = certificate.serial_number serial_number = serial_number.to_bytes((serial_number.bit_length() + 7) // 8, byteorder = 'big') - signer_info = struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) - signer_info += signer_name - - signer_info += struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) - signer_info += serial_number - - signer_info += struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) - signer_info += issuer_name - - tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) - tlv_data += signer_info + signer_info = (struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) + signer_name + + struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) + issuer_name + + struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) + serial_number) + tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) + signer_info tlv_data += struct.pack('> B H', HEADER_SIGNATURE_INFO, 15) tlv_data += struct.pack('> B H B', HEADER_HASH_ALGORITHM, 1, HASH_SHA512 if hash_algorithm == 'sha512' else HASH_SHA1) @@ -499,9 +482,7 @@ def build_enc_file(cnf_file, tftp_certificate_file, certificate_file, hash_algor filename = os.path.basename(enc_file).encode('utf-8') + b'\x00' - tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) - tlv_data += filename - + tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) + filename tlv_data += struct.pack('> B H I', HEADER_TIMESTAMP, 4, int(time.time())) hash = hashes.Hash(hashes.SHA512() if hash_algorithm == 'sha512' else hashes.SHA1(), backends.default_backend()) @@ -522,33 +503,21 @@ def build_enc_file(cnf_file, tftp_certificate_file, certificate_file, hash_algor xml = encryptor.update(xml) + encryptor.finalize() encryption_key = device_public_key.encrypt(encryption_key, padding.PKCS1v15()) - encryption_iv_info = struct.pack('> B H B', HEADER_ENCRYPTION_UNKNOWN1, 1, 0) - - encryption_iv_info += struct.pack('> B H', HEADER_ENCRYPTION_IV, len(encryption_iv)) - encryption_iv_info += encryption_iv - - encryption_iv_info += struct.pack('> B H H', HEADER_ENCRYPTION_PADDING, 2, encryption_padding) + encryption_iv_info = (struct.pack('> B H B', HEADER_ENCRYPTION_UNKNOWN1, 1, 0) + + struct.pack('> B H', HEADER_ENCRYPTION_IV, len(encryption_iv)) + encryption_iv + + struct.pack('> B H H', HEADER_ENCRYPTION_PADDING, 2, encryption_padding)) - encryption_key_info = struct.pack('> B H B', HEADER_ENCRYPTION_UNKNOWN2, 1, 0) - encryption_key_info += struct.pack('> B H H', HEADER_ENCRYPTION_KEY_SIZE, 2, len(encryption_key) * 8) - encryption_key_info += struct.pack('> B H B', HEADER_ENCRYPTION_KEY_ALGORITHM, 1, 1) # AES? + encryption_key_info = (struct.pack('> B H B', HEADER_ENCRYPTION_UNKNOWN2, 1, 0) + + struct.pack('> B H H', HEADER_ENCRYPTION_KEY_SIZE, 2, len(encryption_key) * 8) + + struct.pack('> B H B', HEADER_ENCRYPTION_KEY_ALGORITHM, 1, 1) + # AES? + struct.pack('> B H', HEADER_ENCRYPTION_KEY, len(encryption_key)) + encryption_key) - encryption_key_info += struct.pack('> B H', HEADER_ENCRYPTION_KEY, len(encryption_key)) - encryption_key_info += encryption_key - - encryption_info = struct.pack('> B H', HEADER_ENCRYPTION_IV_INFO, len(encryption_iv_info)) - encryption_info += encryption_iv_info - - encryption_info += struct.pack('> B H', HEADER_ENCRYPTION_KEY_INFO, len(encryption_key_info)) - encryption_info += encryption_key_info - - tlv_data += struct.pack('> B H', HEADER_ENCRYPTION_INFO, len(encryption_info)) - tlv_data += encryption_info + encryption_info = (struct.pack('> B H', HEADER_ENCRYPTION_IV_INFO, len(encryption_iv_info)) + encryption_iv_info + + struct.pack('> B H', HEADER_ENCRYPTION_KEY_INFO, len(encryption_key_info)) + encryption_key_info) + tlv_data += struct.pack('> B H', HEADER_ENCRYPTION_INFO, len(encryption_info)) + encryption_info tlv_data += struct.pack('> B H B', HEADER_ENCRYPTION_HASH_ALGORITHM, 1, HASH_SHA512 if hash_algorithm == 'sha512' else HASH_SHA1) - - tlv_data += struct.pack('> B H', HEADER_ENCRYPTION_HASH, len(encryption_hash)) - tlv_data += encryption_hash + tlv_data += struct.pack('> B H', HEADER_ENCRYPTION_HASH, len(encryption_hash)) + encryption_hash # Pad to 4 byte boundary while (len(tlv_data) + 3 + signature_length) % 4: @@ -565,8 +534,7 @@ def build_enc_file(cnf_file, tftp_certificate_file, certificate_file, hash_algor try: with open(enc_file, 'wb') as file: file.write(tlv_data[:signature_index]) - file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature))) - file.write(signature) + file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature)) + signature) file.write(tlv_data[signature_index:]) except (PermissionError, IsADirectoryError) as error: @@ -601,34 +569,17 @@ def build_enc_file(cnf_file, tftp_certificate_file, certificate_file, hash_algor header_length_index = len(tlv_data) tlv_data += struct.pack('> B H H', HEADER_LENGTH, 2, 0) - signer_name = '' - - for attribute in certificate.subject: - signer_name += (';' if len(signer_name) else '') + attribute.rfc4514_string() - - signer_name = signer_name.encode('utf-8') + b'\x00' - issuer_name = '' - - for attribute in certificate.issuer: - issuer_name += (';' if len(issuer_name) else '') + attribute.rfc4514_string() - - issuer_name = issuer_name.encode('utf-8') + b'\x00' + signer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.subject]).encode('utf-8') + b'\x00' + issuer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.issuer]).encode('utf-8') + b'\x00' serial_number = certificate.serial_number serial_number = serial_number.to_bytes((serial_number.bit_length() + 7) // 8, byteorder = 'big') - signer_info = struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) - signer_info += signer_name - - signer_info += struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) - signer_info += serial_number - - signer_info += struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) - signer_info += issuer_name - - tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) - tlv_data += signer_info + signer_info = (struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) + signer_name + + struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) + issuer_name + + struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) + serial_number) + tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) + signer_info tlv_data += struct.pack('> B H', HEADER_SIGNATURE_INFO, 15) tlv_data += struct.pack('> B H B', HEADER_HASH_ALGORITHM, 1, HASH_SHA512 if hash_algorithm == 'sha512' else HASH_SHA1) @@ -641,9 +592,7 @@ def build_enc_file(cnf_file, tftp_certificate_file, certificate_file, hash_algor filename = os.path.basename(sgn_file).encode('utf-8') + b'\x00' - tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) - tlv_data += filename - + tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) + filename tlv_data += struct.pack('> B H I', HEADER_TIMESTAMP, 4, int(time.time())) # Pad to 4 byte boundary @@ -661,8 +610,7 @@ def build_enc_file(cnf_file, tftp_certificate_file, certificate_file, hash_algor try: with open(sgn_file, 'wb') as file: file.write(tlv_data[:signature_index]) - file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature))) - file.write(signature) + file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature)) + signature) file.write(tlv_data[signature_index:]) except (PermissionError, IsADirectoryError) as error: diff --git a/mkcert b/mkcert index be928ed..c40c54a 100755 --- a/mkcert +++ b/mkcert @@ -106,7 +106,7 @@ while [[ -n $1 ]]; do shift 1 ;; -H|--help) - echo "Usage: ${0##*/} [OPTIONS] [PEM-FILE]" + echo "Usage: ${0##*/} [OPTIONS] [FILE]" echo "Create a self-signed X509 certificate." echo "" echo " -c, --common COMMON-NAME common name, required" @@ -117,9 +117,9 @@ while [[ -n $1 ]]; do echo " -C, --country COUNTRY country code" echo " -y, --years NUMBER number of years to sign the certificate (default 10)" echo " -b, --bits, --key-size BITS RSA key-size (default 2048)" - echo " -E, --curve CURVE EC algorithm" + echo " -E, --curve CURVE EC name (secp256r1, secpr384r1 or secp512r1)" echo " -d, --digest DIGEST message digest to use: sha1, sha256 or sha512 (default sha256)" - echo " -f, --file PEM-FILE output file (default COMMON-NAME.pem)" + echo " -f, --file FILE output file (default COMMON-NAME.pem)" echo " -h, --help print this help and exit" echo "" diff --git a/sgnfile b/sgnfile index b37d8ce..6d0d8b9 100755 --- a/sgnfile +++ b/sgnfile @@ -188,10 +188,10 @@ def parse_sgn_file(sgn_file, tftp_certificate_file): try: public_key.verify(signature, tlv_data, padding.PKCS1v15(), hashes.SHA512() if hash_algorithm == HASH_SHA512 else hashes.SHA1()) + + print('Valid signature') except InvalidSignature: print('Invalid signature') - else: - print('Valid signature') def remove_sgn_file(sgn_file): @@ -210,7 +210,6 @@ def remove_sgn_file(sgn_file): if tlv_tag != HEADER_VERSION: raise ProgramError(f'Tag is not header version: {tlv_tag}') - # Skip version tlv_index += tlv_length (tlv_tag, tlv_length) = struct.unpack_from('> B H', tlv_data, tlv_index) @@ -278,34 +277,17 @@ def build_sgn_file(input_file, tftp_certificate_file, hash_algorithm, filename): header_length_index = len(tlv_data) tlv_data += struct.pack('> B H H', HEADER_LENGTH, 2, 0) - signer_name = '' - - for attribute in certificate.subject: - signer_name += (';' if len(signer_name) else '') + attribute.rfc4514_string() - - signer_name = signer_name.encode('utf-8') + b'\x00' - issuer_name = '' - - for attribute in certificate.issuer: - issuer_name += (';' if len(issuer_name) else '') + attribute.rfc4514_string() - - issuer_name = issuer_name.encode('utf-8') + b'\x00' + signer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.subject]).encode('utf-8') + b'\x00' + issuer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.issuer]).encode('utf-8') + b'\x00' serial_number = certificate.serial_number serial_number = serial_number.to_bytes((serial_number.bit_length() + 7) // 8, byteorder = 'big') - signer_info = struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) - signer_info += signer_name - - signer_info += struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) - signer_info += serial_number - - signer_info += struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) - signer_info += issuer_name - - tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) - tlv_data += signer_info + signer_info = (struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) + signer_name + + struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) + issuer_name + + struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) + serial_number) + tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) + signer_info tlv_data += struct.pack('> B H', HEADER_SIGNATURE_INFO, 15) tlv_data += struct.pack('> B H B', HEADER_HASH_ALGORITHM, 1, HASH_SHA512 if hash_algorithm == 'sha512' else HASH_SHA1) @@ -315,12 +297,9 @@ def build_sgn_file(input_file, tftp_certificate_file, hash_algorithm, filename): # Index where the signature will be inserted signature_index = len(tlv_data) - filename = filename.encode('utf-8') + b'\x00' - tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) - tlv_data += filename - + tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) + filename tlv_data += struct.pack('> B H I', HEADER_TIMESTAMP, 4, int(time.time())) # Pad to 4 byte boundary @@ -338,8 +317,7 @@ def build_sgn_file(input_file, tftp_certificate_file, hash_algorithm, filename): try: with open(sgn_file, 'wb') as file: file.write(tlv_data[:signature_index]) - file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature))) - file.write(signature) + file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature)) + signature) file.write(tlv_data[signature_index:]) except (PermissionError, IsADirectoryError) as error: diff --git a/tlvfile b/tlvfile index 32c41db..a290c5d 100755 --- a/tlvfile +++ b/tlvfile @@ -330,10 +330,10 @@ def parse_tlv_file(tlv_file): try: public_key.verify(signature, tlv_data, padding.PKCS1v15(), hashes.SHA512() if hash_algorithm == HASH_SHA512 else hashes.SHA1()) + + print('Valid signature') except InvalidSignature: print('Invalid signature') - else: - print('Valid signature') def build_tlv_file(tlv_file, sast_certificate_file, version, hash_algorithm, filename, certificate_records): @@ -373,34 +373,17 @@ def build_tlv_file(tlv_file, sast_certificate_file, version, hash_algorithm, fil (major, minor) = version.split('.') tlv_data += struct.pack('> B H B B', HEADER_SIGNER_VERSION, 2, int(major), int(minor)) - signer_name = '' - - for attribute in certificate.subject: - signer_name += (';' if len(signer_name) else '') + attribute.rfc4514_string() - - signer_name = signer_name.encode('utf-8') + b'\x00' - issuer_name = '' - - for attribute in certificate.issuer: - issuer_name += (';' if len(issuer_name) else '') + attribute.rfc4514_string() - - issuer_name = issuer_name.encode('utf-8') + b'\x00' + signer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.subject]).encode('utf-8') + b'\x00' + issuer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.issuer]).encode('utf-8') + b'\x00' serial_number = certificate.serial_number serial_number = serial_number.to_bytes((serial_number.bit_length() + 7) // 8, byteorder = 'big') - signer_info = struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) - signer_info += signer_name - - signer_info += struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) - signer_info += serial_number - - signer_info += struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) - signer_info += issuer_name - - tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) - tlv_data += signer_info + signer_info = (struct.pack('> B H', HEADER_SIGNER_NAME, len(signer_name)) + signer_name + + struct.pack('> B H', HEADER_ISSUER_NAME, len(issuer_name)) + issuer_name + + struct.pack('> B H', HEADER_SERIAL_NUMBER, len(serial_number)) + serial_number) + tlv_data += struct.pack('> B H', HEADER_SIGNER_INFO, len(signer_info)) + signer_info tlv_data += struct.pack('> B H', HEADER_SIGNATURE_INFO, 15) tlv_data += struct.pack('> B H B', HEADER_HASH_ALGORITHM, 1, HASH_SHA512 if hash_algorithm == 'sha512' else HASH_SHA1) @@ -410,12 +393,9 @@ def build_tlv_file(tlv_file, sast_certificate_file, version, hash_algorithm, fil # Index where the signature will be inserted signature_index = len(tlv_data) - filename = filename.encode('utf-8') + b'\x00' - tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) - tlv_data += filename - + tlv_data += struct.pack('> B H', HEADER_FILENAME, len(filename)) + filename tlv_data += struct.pack('> B H I', HEADER_TIMESTAMP, 4, int(time.time())) # Pad to 4 byte boundary @@ -446,15 +426,15 @@ def build_tlv_file(tlv_file, sast_certificate_file, version, hash_algorithm, fil record_length_index = len(tlv_data) tlv_data += struct.pack('> B H H', RECORD_LENGTH, 2, 0) - subject_name = '' - - for attribute in certificate.subject: - subject_name += (';' if len(subject_name) else '') + attribute.rfc4514_string() + subject_name = ','.join([attribute.rfc4514_string() for attribute in certificate.subject]).encode('utf-8') + b'\x00' + issuer_name = ','.join([attribute.rfc4514_string() for attribute in certificate.issuer]).encode('utf-8') + b'\x00' - subject_name = subject_name.encode('utf-8') + b'\x00' + serial_number = certificate.serial_number + serial_number = serial_number.to_bytes((serial_number.bit_length() + 7) // 8, byteorder = 'big') - tlv_data += struct.pack('> B H', RECORD_SUBJECT_NAME, len(subject_name)) - tlv_data += subject_name + tlv_data += struct.pack('> B H', RECORD_SUBJECT_NAME, len(subject_name)) + subject_name + tlv_data += struct.pack('> B H', RECORD_ISSUER_NAME, len(issuer_name)) + issuer_name + tlv_data += struct.pack('> B H', RECORD_SERIAL_NUMBER, len(serial_number)) + serial_number tlv_data += struct.pack('> B H', RECORD_ROLE, 2) @@ -475,20 +455,6 @@ def build_tlv_file(tlv_file, sast_certificate_file, version, hash_algorithm, fil else: raise ProgramError(f'Unsupported record role: {role}') - issuer_name = '' - - for attribute in certificate.issuer: - issuer_name += (';' if len(issuer_name) else '') + attribute.rfc4514_string() - - issuer_name = issuer_name.encode('utf-8') + b'\x00' - tlv_data += struct.pack('> B H', RECORD_ISSUER_NAME, len(issuer_name)) + issuer_name - - serial_number = certificate.serial_number - serial_number = serial_number.to_bytes((serial_number.bit_length() + 7) // 8, byteorder = 'big') - - tlv_data += struct.pack('> B H', RECORD_SERIAL_NUMBER, len(serial_number)) - tlv_data += serial_number - if isinstance(public_key, rsa.RSAPublicKey): public_key = public_key.public_bytes(serialization.Encoding.DER, serialization.PublicFormat.PKCS1) elif isinstance(public_key, ec.EllipticCurvePublicKey): @@ -496,18 +462,13 @@ def build_tlv_file(tlv_file, sast_certificate_file, version, hash_algorithm, fil else: raise ProgramError('Unsupported certificate public-key type') - tlv_data += struct.pack('> B H', RECORD_PUBLIC_KEY, len(public_key)) - tlv_data += public_key + tlv_data += struct.pack('> B H', RECORD_PUBLIC_KEY, len(public_key)) + public_key signature = certificate.signature - - tlv_data += struct.pack('> B H', RECORD_SIGNATURE, len(signature)) - tlv_data += signature - certificate = certificate.public_bytes(serialization.Encoding.DER) - tlv_data += struct.pack('> B H', RECORD_CERTIFICATE, len(certificate)) - tlv_data += certificate + tlv_data += struct.pack('> B H', RECORD_SIGNATURE, len(signature)) + signature + tlv_data += struct.pack('> B H', RECORD_CERTIFICATE, len(certificate)) + certificate record_length = len(tlv_data) - record_length_index struct.pack_into('> H', tlv_data, record_length_index + 3, record_length) @@ -518,8 +479,7 @@ def build_tlv_file(tlv_file, sast_certificate_file, version, hash_algorithm, fil try: with open(tlv_file, 'wb') as file: file.write(tlv_data[:signature_index]) - file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature))) - file.write(signature) + file.write(struct.pack('> B H', HEADER_SIGNATURE, len(signature)) + signature) file.write(tlv_data[signature_index:]) except (PermissionError, IsADirectoryError) as error: