1*4724848cSchristos# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. 2*4724848cSchristos# 3*4724848cSchristos# Licensed under the OpenSSL license (the "License"). You may not use 4*4724848cSchristos# this file except in compliance with the License. You can obtain a copy 5*4724848cSchristos# in the file LICENSE in the source distribution or at 6*4724848cSchristos# https://www.openssl.org/source/license.html 7*4724848cSchristos 8*4724848cSchristosuse strict; 9*4724848cSchristos 10*4724848cSchristospackage TLSProxy::ServerKeyExchange; 11*4724848cSchristos 12*4724848cSchristosuse vars '@ISA'; 13*4724848cSchristospush @ISA, 'TLSProxy::Message'; 14*4724848cSchristos 15*4724848cSchristossub new 16*4724848cSchristos{ 17*4724848cSchristos my $class = shift; 18*4724848cSchristos my ($server, 19*4724848cSchristos $data, 20*4724848cSchristos $records, 21*4724848cSchristos $startoffset, 22*4724848cSchristos $message_frag_lens) = @_; 23*4724848cSchristos 24*4724848cSchristos my $self = $class->SUPER::new( 25*4724848cSchristos $server, 26*4724848cSchristos TLSProxy::Message::MT_SERVER_KEY_EXCHANGE, 27*4724848cSchristos $data, 28*4724848cSchristos $records, 29*4724848cSchristos $startoffset, 30*4724848cSchristos $message_frag_lens); 31*4724848cSchristos 32*4724848cSchristos #DHE 33*4724848cSchristos $self->{p} = ""; 34*4724848cSchristos $self->{g} = ""; 35*4724848cSchristos $self->{pub_key} = ""; 36*4724848cSchristos $self->{sigalg} = -1; 37*4724848cSchristos $self->{sig} = ""; 38*4724848cSchristos 39*4724848cSchristos return $self; 40*4724848cSchristos} 41*4724848cSchristos 42*4724848cSchristossub parse 43*4724848cSchristos{ 44*4724848cSchristos my $self = shift; 45*4724848cSchristos my $sigalg = -1; 46*4724848cSchristos 47*4724848cSchristos #Minimal SKE parsing. Only supports one known DHE ciphersuite at the moment 48*4724848cSchristos return if TLSProxy::Proxy->ciphersuite() 49*4724848cSchristos != TLSProxy::Message::CIPHER_ADH_AES_128_SHA 50*4724848cSchristos && TLSProxy::Proxy->ciphersuite() 51*4724848cSchristos != TLSProxy::Message::CIPHER_DHE_RSA_AES_128_SHA; 52*4724848cSchristos 53*4724848cSchristos my $p_len = unpack('n', $self->data); 54*4724848cSchristos my $ptr = 2; 55*4724848cSchristos my $p = substr($self->data, $ptr, $p_len); 56*4724848cSchristos $ptr += $p_len; 57*4724848cSchristos 58*4724848cSchristos my $g_len = unpack('n', substr($self->data, $ptr)); 59*4724848cSchristos $ptr += 2; 60*4724848cSchristos my $g = substr($self->data, $ptr, $g_len); 61*4724848cSchristos $ptr += $g_len; 62*4724848cSchristos 63*4724848cSchristos my $pub_key_len = unpack('n', substr($self->data, $ptr)); 64*4724848cSchristos $ptr += 2; 65*4724848cSchristos my $pub_key = substr($self->data, $ptr, $pub_key_len); 66*4724848cSchristos $ptr += $pub_key_len; 67*4724848cSchristos 68*4724848cSchristos #We assume its signed 69*4724848cSchristos my $record = ${$self->records}[0]; 70*4724848cSchristos 71*4724848cSchristos if (TLSProxy::Proxy->is_tls13() 72*4724848cSchristos || $record->version() == TLSProxy::Record::VERS_TLS_1_2) { 73*4724848cSchristos $sigalg = unpack('n', substr($self->data, $ptr)); 74*4724848cSchristos $ptr += 2; 75*4724848cSchristos } 76*4724848cSchristos my $sig = ""; 77*4724848cSchristos if (defined $sigalg) { 78*4724848cSchristos my $sig_len = unpack('n', substr($self->data, $ptr)); 79*4724848cSchristos if (defined $sig_len) { 80*4724848cSchristos $ptr += 2; 81*4724848cSchristos $sig = substr($self->data, $ptr, $sig_len); 82*4724848cSchristos $ptr += $sig_len; 83*4724848cSchristos } 84*4724848cSchristos } 85*4724848cSchristos 86*4724848cSchristos $self->p($p); 87*4724848cSchristos $self->g($g); 88*4724848cSchristos $self->pub_key($pub_key); 89*4724848cSchristos $self->sigalg($sigalg) if defined $sigalg; 90*4724848cSchristos $self->signature($sig); 91*4724848cSchristos} 92*4724848cSchristos 93*4724848cSchristos 94*4724848cSchristos#Reconstruct the on-the-wire message data following changes 95*4724848cSchristossub set_message_contents 96*4724848cSchristos{ 97*4724848cSchristos my $self = shift; 98*4724848cSchristos my $data; 99*4724848cSchristos 100*4724848cSchristos $data = pack('n', length($self->p)); 101*4724848cSchristos $data .= $self->p; 102*4724848cSchristos $data .= pack('n', length($self->g)); 103*4724848cSchristos $data .= $self->g; 104*4724848cSchristos $data .= pack('n', length($self->pub_key)); 105*4724848cSchristos $data .= $self->pub_key; 106*4724848cSchristos $data .= pack('n', $self->sigalg) if ($self->sigalg != -1); 107*4724848cSchristos if (length($self->signature) > 0) { 108*4724848cSchristos $data .= pack('n', length($self->signature)); 109*4724848cSchristos $data .= $self->signature; 110*4724848cSchristos } 111*4724848cSchristos 112*4724848cSchristos $self->data($data); 113*4724848cSchristos} 114*4724848cSchristos 115*4724848cSchristos#Read/write accessors 116*4724848cSchristos#DHE 117*4724848cSchristossub p 118*4724848cSchristos{ 119*4724848cSchristos my $self = shift; 120*4724848cSchristos if (@_) { 121*4724848cSchristos $self->{p} = shift; 122*4724848cSchristos } 123*4724848cSchristos return $self->{p}; 124*4724848cSchristos} 125*4724848cSchristossub g 126*4724848cSchristos{ 127*4724848cSchristos my $self = shift; 128*4724848cSchristos if (@_) { 129*4724848cSchristos $self->{g} = shift; 130*4724848cSchristos } 131*4724848cSchristos return $self->{g}; 132*4724848cSchristos} 133*4724848cSchristossub pub_key 134*4724848cSchristos{ 135*4724848cSchristos my $self = shift; 136*4724848cSchristos if (@_) { 137*4724848cSchristos $self->{pub_key} = shift; 138*4724848cSchristos } 139*4724848cSchristos return $self->{pub_key}; 140*4724848cSchristos} 141*4724848cSchristossub sigalg 142*4724848cSchristos{ 143*4724848cSchristos my $self = shift; 144*4724848cSchristos if (@_) { 145*4724848cSchristos $self->{sigalg} = shift; 146*4724848cSchristos } 147*4724848cSchristos return $self->{sigalg}; 148*4724848cSchristos} 149*4724848cSchristossub signature 150*4724848cSchristos{ 151*4724848cSchristos my $self = shift; 152*4724848cSchristos if (@_) { 153*4724848cSchristos $self->{sig} = shift; 154*4724848cSchristos } 155*4724848cSchristos return $self->{sig}; 156*4724848cSchristos} 157*4724848cSchristos1; 158