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