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