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