def verify_update_receipt_signature(self, input_json): """ Function to verify the signature of work order receipt update Parameters: - input_json is dictionary contains payload returned by the WorkOrderReceiptUpdateRetrieve API as define EEA spec 7.2.7 Returns enum type SignatureStatus """ input_json_params = input_json['result'] concat_string = input_json_params["workOrderId"] + \ str(input_json_params["updateType"]) + \ input_json_params["updateData"] concat_hash = bytes(concat_string, 'UTF-8') final_hash = crypto.compute_message_hash(concat_hash) signature = input_json_params["updateSignature"] verification_key = input_json_params["receiptVerificationKey"] try: _verifying_key = crypto.SIG_PublicKey(verification_key) except Exception as error: logger.info("Error in verification key : %s", error) return SignatureStatus.INVALID_VERIFICATION_KEY decoded_signature = crypto.base64_to_byte_array(signature) sig_result = _verifying_key.VerifySignature( final_hash, decoded_signature) if sig_result == 1: return SignatureStatus.PASSED elif sig_result == 0: return SignatureStatus.FAILED else: return SignatureStatus.INVALID_SIGNATURE_FORMAT
def decrypt_data(encryption_key, data, iv=None): """ Function to decrypt the outData in the result Parameters: - encryption_key is the key used to decrypt the encrypted data of the response. - iv is an initialization vector if required by the data encryption algorithm. The default is all zeros. - data is the parameter data in outData part of workorder request as per TCF API 6.1.7 Work Order Data Formats. Returns decrypted data as a string """ if not data: logger.debug("Outdata is empty, nothing to decrypt") return data data_byte = crypto.base64_to_byte_array(data) logger.debug("encryption_key: %s", encryption_key) if iv is not None: decrypt_result = crypto.SKENC_DecryptMessage(encryption_key, iv, data_byte) else: decrypt_result = crypto.SKENC_DecryptMessage(encryption_key, data_byte) result = crypto.byte_array_to_string(decrypt_result) logger.info("Decryption result at client - %s", result) return result
def decrypted_response(input_json_str, encrypted_session_key): """ Function to calculate a hash value of the array concatenating dataHash, data, encryptedDataEncryptionKey, iv for each item in the inData/outData array Parameters: - input_json_params is a collection of parameters as per TCF APi 6.1.2 Work Order Response Payload - encryption_session_key is the key used to decrypt the encrypted data of response. """ input_json = json.loads(input_json_str) input_json_params = input_json['result'] i = 0 do_decrypt = True data_objects = input_json_params['outData'] for item in data_objects: data = item['data'].encode('UTF-8') e_key = item['encryptedDataEncryptionKey'].encode('UTF-8') if not e_key or (e_key == "null".encode('UTF-8')): encryption_key_byte = encrypted_session_key[:NO_OF_BYTES] elif e_key == "-".encode('UTF-8'): do_decrypt = False else: encryption_key_byte = crypto.base64_to_byte_array(e_key) iv = item['iv'].encode('UTF-8') if not do_decrypt: input_json_params['outData'][i]['data'] = data logger.info( "Work order response data not encrypted, data in plain is %s", base64.b64decode(data)) else: # Decrypt output data logger.debug("encrypted_session_key: %s", encryption_key_byte) input_json_params['outData'][i]['data'] = decrypt_data( encryption_key_byte, item['iv'], item['data']) i = i + 1
def verify_signature(self,response_str,worker): """ Function to verify the signature received from the enclave Parameters: - response_str is json payload returned by the Worker Service in response to successful workorder submit request as per TCF API 6.1.2 Work Order Result Payload - worker is a worker object to store all the common details of worker as per TCF API 8.1 Common Data for All Worker Types """ input_json = json.loads(response_str) if ( self.tcs_worker['HashingAlgorithm'] != worker.hashing_algorithm ): logger.error("ERROR: Signing the request failed. Hashing algorithm is not supported for %s", worker.hashing_algorithm ) return SignatureStatus.ERROR_RESPONSE if ( self.tcs_worker['SigningAlgorithm'] != worker.signing_algorithm): logger.error("ERROR: Signing the request failed. Signing algorithm is not supported for %s", worker.signing_algorithm ) return SignatureStatus.ERROR_RESPONSE #Checking for a error response. if 'error' in input_json.keys(): return SignatureStatus.ERROR_RESPONSE input_json_params = input_json['result'] #Checking if error is response if 'code' in input_json_params.keys() and input_json_params['code'] < 0 : return SignatureStatus.ERROR_RESPONSE nonce = (input_json_params['workerNonce']).encode('UTF-8') signature = input_json_params['workerSignature'] hash_string_1 = self.__calculate_hash_on_concatenated_string(input_json_params, nonce) data_objects = input_json_params['outData'] data_objects.sort(key = lambda x:x['index']) hash_string_2 = self.__calculate_datahash(data_objects) concat_string = hash_string_1+ hash_string_2 concat_hash = bytes(concat_string, 'UTF-8') final_hash = crypto.compute_message_hash(concat_hash) verify_key = worker.worker_typedata_verification_key try: _verifying_key = crypto.SIG_PublicKey(verify_key) except Exception as error: logger.info("Error in verification key : %s", error) return SignatureStatus.INVALID_VERIFICATION_KEY decoded_signature = crypto.base64_to_byte_array(signature) sig_result =_verifying_key.VerifySignature(final_hash, decoded_signature) if sig_result == 1 : return SignatureStatus.PASSED elif sig_result == 0 : return SignatureStatus.FAILED else : return SignatureStatus.INVALID_SIGNATURE_FORMAT
def decrypt_data(encryption_key, iv, data): """ Function to decrypt the outData in the result Parameters: - encryption_key is the key used to decrypt the encrypted data of response. - iv is an initialization vector if required by the data encryption algorithm. The default is all zeros. - data is the parameter data in outData part of workorder request as per TCF API 6.1.7 Work Order Data Formats """ if not data: logger.debug("Outdata is empty, nothing to decrypt") return data_byte = crypto.base64_to_byte_array(data) logger.debug("encrypted_session_key: %s", encryption_key) decrypt_result = crypto.SKENC_DecryptMessage(encryption_key, crypto.hex_to_byte_array(iv), data_byte) result = base64.b64decode(crypto.byte_array_to_base64(decrypt_result)) logger.info("Decryption Result at Client - %s ", result)
def verify_signature(self, input_json, verification_key): """ Function to verify the signature received from the enclave Parameters: - input_json is dictionary contains payload returned by the Worker Service in response to successful workorder submit request as per TCF API 6.1.2 Work Order Result Payload - verification_key is ECDSA/SECP256K1 public key used to verify signatures created by the Enclave. Returns enum type SignatureStatus """ input_json_params = input_json['result'] nonce = (input_json_params['workerNonce']).encode('UTF-8') signature = input_json_params['workerSignature'] hash_string_1 = self.__calculate_hash_on_concatenated_string( input_json_params, nonce) data_objects = input_json_params['outData'] data_objects.sort(key=lambda x: x['index']) hash_string_2 = self.calculate_datahash(data_objects) concat_string = hash_string_1 + hash_string_2 concat_hash = bytes(concat_string, 'UTF-8') final_hash = crypto.compute_message_hash(concat_hash) try: _verifying_key = crypto.SIG_PublicKey(verification_key) except Exception as error: logger.info("Error in verification key : %s", error) return SignatureStatus.INVALID_VERIFICATION_KEY decoded_signature = crypto.base64_to_byte_array(signature) sig_result = _verifying_key.VerifySignature(final_hash, decoded_signature) if sig_result == 1: return SignatureStatus.PASSED elif sig_result == 0: return SignatureStatus.FAILED else: return SignatureStatus.INVALID_SIGNATURE_FORMAT
def evaluate(self) : serialized_byte_array = crypto.string_to_byte_array(self.work_order) encrypted_request = crypto.byte_array_to_base64(serialized_byte_array) try : encoded_encrypted_response = self.enclave_service.send_to_sgx_worker(encrypted_request) assert encoded_encrypted_response except : logger.exception('workorder request invocation failed') raise try : decrypted_response = crypto.base64_to_byte_array(encoded_encrypted_response) response_string = crypto.byte_array_to_string(decrypted_response) response_parsed = json.loads(response_string[0:-1]) except : logger.exception('workorder response is invalid') raise return response_parsed
else: logger.error( "ERROR: Symmetric decryption (random IV) " + "invalid key detection test failed: ", exc) sys.exit(-1) try: iv = crypto.SKENC_GenerateIV("A message") except Exception as exc: logger.error( "ERROR: Symmetric encryption deterministic iv generation " + "test failed: ", exc) sys.exit(-1) logger.debug( "Symmetric encryption deterministic iv generation test successful!") try: rand = crypto.random_bit_string(16) except Exception as exc: logger.error("ERROR: Random number generation failed: ", exc) sys.exit(-1) logger.debug("Random number generation successful!") hash = crypto.compute_message_hash(rand) bhash = bytearray(hash) b64hash = crypto.byte_array_to_base64(bhash) logger.debug("Hash computed!") crypto.base64_to_byte_array(b64hash) logger.debug("SWIG CRYPTO_WRAPPER TEST SUCCESSFUL!") sys.exit(0)