def from_header_and_body(security_policy, header, buf): assert len(buf) >= header.body_size, 'Full body expected here' data = buf.copy(header.body_size) buf.skip(header.body_size) if header.MessageType in (ua.MessageType.SecureMessage, ua.MessageType.SecureClose): security_header = struct_from_binary(ua.SymmetricAlgorithmHeader, data) crypto = security_policy.symmetric_cryptography elif header.MessageType == ua.MessageType.SecureOpen: security_header = struct_from_binary(ua.AsymmetricAlgorithmHeader, data) crypto = security_policy.asymmetric_cryptography else: raise ua.UaError("Unsupported message type: {0}".format(header.MessageType)) obj = MessageChunk(crypto) obj.MessageHeader = header obj.SecurityHeader = security_header decrypted = crypto.decrypt(data.read(len(data))) signature_size = crypto.vsignature_size() if signature_size > 0: signature = decrypted[-signature_size:] decrypted = decrypted[:-signature_size] crypto.verify(header_to_binary(obj.MessageHeader) + struct_to_binary(obj.SecurityHeader) + decrypted, signature) data = ua.utils.Buffer(crypto.remove_padding(decrypted)) obj.SequenceHeader = struct_from_binary(ua.SequenceHeader, data) obj.Body = data.read(len(data)) return obj
def from_header_and_body(security_policy, header, buf): assert len(buf) >= header.body_size, 'Full body expected here' data = buf.copy(header.body_size) buf.skip(header.body_size) if header.MessageType in (ua.MessageType.SecureMessage, ua.MessageType.SecureClose): security_header = struct_from_binary(ua.SymmetricAlgorithmHeader, data) crypto = security_policy.symmetric_cryptography elif header.MessageType == ua.MessageType.SecureOpen: security_header = struct_from_binary(ua.AsymmetricAlgorithmHeader, data) crypto = security_policy.asymmetric_cryptography else: raise ua.UaError("Unsupported message type: {0}".format( header.MessageType)) obj = MessageChunk(crypto) obj.MessageHeader = header obj.SecurityHeader = security_header decrypted = crypto.decrypt(data.read(len(data))) signature_size = crypto.vsignature_size() if signature_size > 0: signature = decrypted[-signature_size:] decrypted = decrypted[:-signature_size] crypto.verify( header_to_binary(obj.MessageHeader) + struct_to_binary(obj.SecurityHeader) + decrypted, signature) data = ua.utils.Buffer(crypto.remove_padding(decrypted)) obj.SequenceHeader = struct_from_binary(ua.SequenceHeader, data) obj.Body = data.read(len(data)) return obj
def to_binary(self): security = struct_to_binary(self.SecurityHeader) encrypted_part = struct_to_binary(self.SequenceHeader) + self.Body encrypted_part += self.security_policy.padding(len(encrypted_part)) self.MessageHeader.body_size = len(security) + self.encrypted_size(len(encrypted_part)) header = header_to_binary(self.MessageHeader) encrypted_part += self.security_policy.signature(header + security + encrypted_part) return header + security + self.security_policy.encrypt(encrypted_part)
def to_binary(self): security = struct_to_binary(self.SecurityHeader) encrypted_part = struct_to_binary(self.SequenceHeader) + self.Body encrypted_part += self.security_policy.padding(len(encrypted_part)) self.MessageHeader.body_size = len(security) + self.encrypted_size(len(encrypted_part)) header = header_to_binary(self.MessageHeader) encrypted_part += self.security_policy.signature(header + security + encrypted_part) return header + security + self.security_policy.encrypt(encrypted_part)
def to_binary(chunk, cert, padding=None, ciphertext_manipulator=None): """ Convert chunk to binary :param chunk: chunk to convert :param cert: server certificate to use for ciphertext manipulation :param padding: padding function :param ciphertext_manipulator: manipulation function for the ciphertext :return: bytes to send to the server """ security = struct_to_binary(chunk.SecurityHeader) encrypted_part = struct_to_binary(chunk.SequenceHeader) + chunk.Body encrypted_part += chunk.security_policy.padding(len(encrypted_part)) chunk.MessageHeader.body_size = len(security) + chunk.encrypted_size( len(encrypted_part)) header = header_to_binary(chunk.MessageHeader) signature = chunk.security_policy.signature(header + security + encrypted_part) encrypted_part += signature # if no padding is given, use the default PKCS #1 v1.5 padding if not padding: plaintext = paddings.pad_pkcs1v15(encrypted_part) else: plaintext = padding(encrypted_part) # extract modulus and exponent from the server certificate N = cert.public_key().public_numbers().n e = cert.public_key().public_numbers().e modulus_bits = int(math.ceil(math.log(N, 2))) modulus_bytes = (modulus_bits + 7) // 8 plaintext_bytes = int.from_bytes(plaintext, byteorder='big') ciphertext = int(gmpy2.powmod(plaintext_bytes, e, N)).to_bytes(modulus_bytes, byteorder="big") if ciphertext_manipulator: ciphertext = ciphertext_manipulator(ciphertext) return header + security + ciphertext
def error_message_to_binary(message): header = ua.Header(ua.MessageType.Error, ua.ChunkType.Single) body = struct_to_binary(message) header.body_size = len(body) return header_to_binary(header) + body