def test_responder_finalize(responder, test_vectors): responder.msg_1 = MessageOne.decode(test_vectors['S']['message_1']) responder.msg_2 = MessageTwo.decode( responder.create_message_two(test_vectors['S']['message_1'])) responder.msg_3 = MessageThree.decode(test_vectors['S']['message_3']) decoded = EdhocMessage.decode( responder._decrypt(responder.msg_3.ciphertext)) if KID.identifier in cbor2.loads(test_vectors['I']['cred_id']): assert decoded[0] == EdhocMessage.encode_bstr_id( cbor2.loads(test_vectors['I']['cred_id'])[KID.identifier]) else: assert decoded[0] == cbor2.loads(test_vectors['I']['cred_id']) assert decoded[1] == test_vectors['S']['signature_3'] if getattr(responder, 'remote_authkey', None) is None: warnings.warn(NoRemoteKey()) return c_i, c_r, app_aead, app_hash = responder.finalize( test_vectors['S']['message_3']) assert c_i == test_vectors['I']['conn_id'] assert c_r == test_vectors['R']['conn_id'] assert app_aead == CipherSuite.from_id( test_vectors['I']['selected']).app_aead.identifier assert app_hash == CipherSuite.from_id( test_vectors['I']['selected']).app_hash.identifier
def create_message_three(self, message_two: bytes): self.msg_2 = MessageTwo.decode(message_two) self._internal_state = EdhocState.MSG_2_RCVD decoded = EdhocMessage.decode(self._decrypt(self.msg_2.ciphertext)) self.cred_idr = decoded[0] if not self._verify_signature_or_mac2(signature_or_mac2=decoded[1]): self._internal_state = EdhocState.EDHOC_FAIL return MessageError( err_msg='Signature verification failed').encode() try: ad_2 = decoded[2] if self.aad2_cb is not None: self.aad2_cb(ad_2) except IndexError: pass self.msg_3 = MessageThree(self.ciphertext_3, self.conn_idr) self._internal_state = EdhocState.MSG_3_SENT return self.msg_3.encode(self.corr)
def finalize( self, message_three: bytes ) -> Union[Tuple[bytes, bytes, int, int], bytes]: """ Decodes an incoming EDHOC message 3 and finalizes the key exchange. :param message_three: An EDHOC message 3 :return: An EDHOC error message in case the verification of the EDHOC message 3 fails or a 4-tuple containing the initiator and responder's connection identifiers and the application AEAD and hash algorithms. """ self.msg_3 = MessageThree.decode(message_three) self._internal_state = EdhocState.MSG_3_RCVD decoded = EdhocMessage.decode(self._decrypt(self.msg_3.ciphertext)) self.cred_idi = decoded[0] if not self._verify_signature_or_mac3(signature_or_mac3=decoded[1]): return MessageError(err_msg='').encode() try: ad_3 = decoded[2] if self.aad3_cb is not None: self.aad3_cb(ad_3) except IndexError: pass app_aead = self.cipher_suite.app_aead app_hash = self.cipher_suite.app_hash self._internal_state = EdhocState.EDHOC_SUCC return self.msg_1.conn_idi, self._conn_id, app_aead.identifier, app_hash.identifier
def data_3(self) -> CBOR: """ Create the data_3 message part from EDHOC message 3. """ if self.conn_idr == b'': return self.conn_idr else: return cbor2.dumps(EdhocMessage.encode_bstr_id(self.conn_idr))
def cred_idr(self, value): if isinstance(value, int): value = {4: EdhocMessage.decode_bstr_id(value)} elif isinstance(value, bytes): value = {4: value} self._cred_idr = value self._populate_remote_details(value)
def test_responder_finalize(responder, test_vectors): responder.msg_1 = MessageOne.decode(test_vectors['I']['message_1']) responder.msg_2 = MessageTwo.decode( responder.create_message_two(test_vectors['I']['message_1'])) responder.msg_3 = MessageThree.decode(test_vectors['I']['message_3']) decoded = EdhocMessage.decode( responder._decrypt(responder.msg_3.ciphertext)) if CoseHeaderKeys.KID in test_vectors['I']['id_cred']: assert decoded[0] == EdhocMessage.encode_bstr_id( test_vectors['I']['id_cred'][CoseHeaderKeys.KID]) else: assert decoded[0] == test_vectors['I']['id_cred'] assert decoded[1] == test_vectors['I']['sign_or_mac3'] c_i, c_r, app_aead, app_hash = responder.finalize( test_vectors['I']['message_3']) assert c_i == test_vectors['I']['conn_id'] assert c_r == test_vectors['R']['conn_id'] assert app_aead == CipherSuite(test_vectors['I']['selected']).app_aead.id assert app_hash == CipherSuite(test_vectors['I']['selected']).app_hash.id
def _p_2e(self): # compute MAC_2 # TODO: resolve magic key and IV lengths mac_2 = self._mac(self._hkdf2, 'K_2m', 16, 'IV_2m', 13, self._th2_input, self._prk3e2m, self.aad2_cb) # compute the signature_or_mac2 signature = self.signature_or_mac2(mac_2) if CoseHeaderKeys.KID in self.cred_id: cred_id = EdhocMessage.encode_bstr_id(self.cred_id[CoseHeaderKeys.KID]) else: cred_id = self.cred_id return b"".join([cbor2.dumps(cred_id), cbor2.dumps(signature)])
def _p_2e(self): # compute MAC_2 # TODO: resolve magic key and IV lengths mac_2 = self._mac(self._hkdf2, 'K_2m', 16, 'IV_2m', 13, self._th2_input, self._prk3e2m, self.aad2_cb) # compute the signature_or_mac2 signature = self.signature_or_mac2(mac_2) if KID.identifier in self.cred_id: cred_id = EdhocMessage.encode_bstr_id(self.cred_id[KID.identifier]) else: cred_id = self.cred_id return b"".join([cbor2.dumps(cred_id, default=EdhocRole._custom_cbor_encoder), cbor2.dumps(signature)])
def _p_3ae(self): # TODO: resolve magic key and IV lengths mac_3 = self._mac(self._hkdf3, 'K_3m', 16, 'IV_3m', 13, self._th3_input, self._prk4x3m, self.aad3_cb) signature = self.signature_or_mac3(mac_3) if CoseHeaderKeys.KID in self.cred_id: cred_id = EdhocMessage.encode_bstr_id( self.cred_id[CoseHeaderKeys.KID]) else: cred_id = self.cred_id return b"".join([cbor2.dumps(cred_id), cbor2.dumps(signature)])
def _p_3ae(self): # TODO: resolve magic key and IV lengths mac_3 = self._mac(self._hkdf3, 'K_3m', 16, 'IV_3m', 13, self._th3_input, self._prk4x3m, self.aad3_cb) signature = self.signature_or_mac3(mac_3) if KID.identifier in self.cred_id: cred_id = EdhocMessage.encode_bstr_id(self.cred_id[KID.identifier]) else: cred_id = self.cred_id return b"".join([ cbor2.dumps(cred_id, default=EdhocRole._custom_cbor_encoder), cbor2.dumps(signature) ])