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