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