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