def test_framed_iv_invalid_sequence_numbers(sequence_number):
    with pytest.raises(ActionNotAllowedError) as excinfo:
        frame_iv(ALGORITHM, sequence_number)

    excinfo.match(r'Invalid frame sequence number: *')
Ejemplo n.º 2
0
def serialize_frame(algorithm,
                    plaintext,
                    message_id,
                    data_encryption_key,
                    frame_length,
                    sequence_number,
                    is_final_frame,
                    signer=None):
    """Receives a message plaintext, breaks off a frame, encrypts and serializes
    the frame, and returns the encrypted frame and the remaining plaintext.

    :param algorithm: Algorithm to use for encryption
    :type algorithm: aws_encryption_sdk.identifiers.Algorithm
    :param bytes plaintext: Source plaintext to encrypt and serialize
    :param bytes message_id: Message ID
    :param bytes data_encryption_key: Data key with which to encrypt message
    :param int frame_length: Length of the framed data
    :param int sequence_number: Sequence number for frame to be generated
    :param bool is_final_frame: Boolean stating whether or not this frame is a final frame
    :param signer: Cryptographic signer object (optional)
    :type signer: aws_encryption_sdk.Signer
    :returns: Serialized frame and remaining plaintext
    :rtype: tuple of bytes
    :raises SerializationError: if number of frames is too large
    """
    if sequence_number < 1:
        raise SerializationError(
            'Frame sequence number must be greater than 0')
    if sequence_number > aws_encryption_sdk.internal.defaults.MAX_FRAME_COUNT:
        raise SerializationError('Max frame count exceeded')
    if is_final_frame:
        content_string = ContentAADString.FINAL_FRAME_STRING_ID
    else:
        content_string = ContentAADString.FRAME_STRING_ID
    frame_plaintext = plaintext[:frame_length]
    frame_ciphertext = aws_encryption_sdk.internal.crypto.encrypt(
        algorithm=algorithm,
        key=data_encryption_key,
        plaintext=frame_plaintext,
        associated_data=aws_encryption_sdk.internal.formatting.
        encryption_context.assemble_content_aad(
            message_id=message_id,
            aad_content_string=content_string,
            seq_num=sequence_number,
            length=len(frame_plaintext)),
        iv=frame_iv(algorithm, sequence_number))
    plaintext = plaintext[frame_length:]
    if is_final_frame:
        _LOGGER.debug('Serializing final frame')
        packed_frame = struct.pack(
            '>II{iv_len}sI{content_len}s{auth_len}s'.format(
                iv_len=algorithm.iv_len,
                content_len=len(frame_ciphertext.ciphertext),
                auth_len=algorithm.auth_len),
            SequenceIdentifier.SEQUENCE_NUMBER_END.value,
            sequence_number, frame_ciphertext.iv,
            len(frame_ciphertext.ciphertext), frame_ciphertext.ciphertext,
            frame_ciphertext.tag)
    else:
        _LOGGER.debug('Serializing frame')
        packed_frame = struct.pack(
            '>I{iv_len}s{content_len}s{auth_len}s'.format(
                iv_len=algorithm.iv_len,
                content_len=frame_length,
                auth_len=algorithm.auth_len), sequence_number,
            frame_ciphertext.iv, frame_ciphertext.ciphertext,
            frame_ciphertext.tag)
    if signer is not None:
        signer.update(packed_frame)
    return packed_frame, plaintext
def test_framed_iv(sequence_number, iv):
    assert frame_iv(ALGORITHM, sequence_number) == iv