1# Copyright 2016-2024 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::ServerKeyExchange; 11 12use vars '@ISA'; 13push @ISA, 'TLSProxy::Message'; 14 15sub new 16{ 17 my $class = shift; 18 my ($isdtls, 19 $server, 20 $msgseq, 21 $msgfrag, 22 $msgfragoffs, 23 $data, 24 $records, 25 $startoffset, 26 $message_frag_lens) = @_; 27 28 my $self = $class->SUPER::new( 29 $isdtls, 30 $server, 31 TLSProxy::Message::MT_SERVER_KEY_EXCHANGE, 32 $msgseq, 33 $msgfrag, 34 $msgfragoffs, 35 $data, 36 $records, 37 $startoffset, 38 $message_frag_lens); 39 40 #DHE 41 $self->{p} = ""; 42 $self->{g} = ""; 43 $self->{pub_key} = ""; 44 $self->{sigalg} = -1; 45 $self->{sig} = ""; 46 47 return $self; 48} 49 50sub parse 51{ 52 my $self = shift; 53 my $sigalg = -1; 54 55 #Minimal SKE parsing. Only supports one known DHE ciphersuite at the moment 56 return if TLSProxy::Proxy->ciphersuite() 57 != TLSProxy::Message::CIPHER_ADH_AES_128_SHA 58 && TLSProxy::Proxy->ciphersuite() 59 != TLSProxy::Message::CIPHER_DHE_RSA_AES_128_SHA; 60 61 my $p_len = unpack('n', $self->data); 62 my $ptr = 2; 63 my $p = substr($self->data, $ptr, $p_len); 64 $ptr += $p_len; 65 66 my $g_len = unpack('n', substr($self->data, $ptr)); 67 $ptr += 2; 68 my $g = substr($self->data, $ptr, $g_len); 69 $ptr += $g_len; 70 71 my $pub_key_len = unpack('n', substr($self->data, $ptr)); 72 $ptr += 2; 73 my $pub_key = substr($self->data, $ptr, $pub_key_len); 74 $ptr += $pub_key_len; 75 76 #We assume its signed 77 my $record = ${$self->records}[0]; 78 79 if (TLSProxy::Proxy->is_tls13() 80 || $record->version() == TLSProxy::Record::VERS_TLS_1_2) { 81 $sigalg = unpack('n', substr($self->data, $ptr)); 82 $ptr += 2; 83 } 84 my $sig = ""; 85 if (defined $sigalg) { 86 my $sig_len = unpack('n', substr($self->data, $ptr)); 87 if (defined $sig_len) { 88 $ptr += 2; 89 $sig = substr($self->data, $ptr, $sig_len); 90 $ptr += $sig_len; 91 } 92 } 93 94 $self->p($p); 95 $self->g($g); 96 $self->pub_key($pub_key); 97 $self->sigalg($sigalg) if defined $sigalg; 98 $self->signature($sig); 99} 100 101 102#Reconstruct the on-the-wire message data following changes 103sub set_message_contents 104{ 105 my $self = shift; 106 my $data; 107 108 $data = pack('n', length($self->p)); 109 $data .= $self->p; 110 $data .= pack('n', length($self->g)); 111 $data .= $self->g; 112 $data .= pack('n', length($self->pub_key)); 113 $data .= $self->pub_key; 114 $data .= pack('n', $self->sigalg) if ($self->sigalg != -1); 115 if (length($self->signature) > 0) { 116 $data .= pack('n', length($self->signature)); 117 $data .= $self->signature; 118 } 119 120 $self->data($data); 121} 122 123#Read/write accessors 124#DHE 125sub p 126{ 127 my $self = shift; 128 if (@_) { 129 $self->{p} = shift; 130 } 131 return $self->{p}; 132} 133sub g 134{ 135 my $self = shift; 136 if (@_) { 137 $self->{g} = shift; 138 } 139 return $self->{g}; 140} 141sub pub_key 142{ 143 my $self = shift; 144 if (@_) { 145 $self->{pub_key} = shift; 146 } 147 return $self->{pub_key}; 148} 149sub sigalg 150{ 151 my $self = shift; 152 if (@_) { 153 $self->{sigalg} = shift; 154 } 155 return $self->{sigalg}; 156} 157sub signature 158{ 159 my $self = shift; 160 if (@_) { 161 $self->{sig} = shift; 162 } 163 return $self->{sig}; 164} 1651; 166