1# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
2#
3# Licensed under the Apache License 2.0 (the "License").  You may not use
4# this file except in compliance with the License.  You can obtain a copy
5# in the file LICENSE in the source distribution or at
6# https://www.openssl.org/source/license.html
7
8use strict;
9
10package TLSProxy::EncryptedExtensions;
11
12use vars '@ISA';
13push @ISA, 'TLSProxy::Message';
14
15sub new
16{
17    my $class = shift;
18    my ($server,
19        $data,
20        $records,
21        $startoffset,
22        $message_frag_lens) = @_;
23
24    my $self = $class->SUPER::new(
25        $server,
26        TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
27        $data,
28        $records,
29        $startoffset,
30        $message_frag_lens);
31
32    $self->{extension_data} = "";
33
34    return $self;
35}
36
37sub parse
38{
39    my $self = shift;
40
41    my $extensions_len = unpack('n', $self->data);
42    if (!defined $extensions_len) {
43        $extensions_len = 0;
44    }
45
46    my $extension_data;
47    if ($extensions_len != 0) {
48        $extension_data = substr($self->data, 2);
49
50        if (length($extension_data) != $extensions_len) {
51            die "Invalid extension length\n";
52        }
53    } else {
54        if (length($self->data) != 2) {
55            die "Invalid extension length\n";
56        }
57        $extension_data = "";
58    }
59    my %extensions = ();
60    while (length($extension_data) >= 4) {
61        my ($type, $size) = unpack("nn", $extension_data);
62        my $extdata = substr($extension_data, 4, $size);
63        $extension_data = substr($extension_data, 4 + $size);
64        $extensions{$type} = $extdata;
65    }
66
67    $self->extension_data(\%extensions);
68
69    print "    Extensions Len:".$extensions_len."\n";
70}
71
72#Reconstruct the on-the-wire message data following changes
73sub set_message_contents
74{
75    my $self = shift;
76    my $data;
77    my $extensions = "";
78
79    foreach my $key (keys %{$self->extension_data}) {
80        my $extdata = ${$self->extension_data}{$key};
81        $extensions .= pack("n", $key);
82        $extensions .= pack("n", length($extdata));
83        $extensions .= $extdata;
84    }
85
86    $data = pack('n', length($extensions));
87    $data .= $extensions;
88    $self->data($data);
89}
90
91#Read/write accessors
92sub extension_data
93{
94    my $self = shift;
95    if (@_) {
96        $self->{extension_data} = shift;
97    }
98    return $self->{extension_data};
99}
100sub set_extension
101{
102    my ($self, $ext_type, $ext_data) = @_;
103    $self->{extension_data}{$ext_type} = $ext_data;
104}
105sub delete_extension
106{
107    my ($self, $ext_type) = @_;
108    delete $self->{extension_data}{$ext_type};
109}
1101;
111