1*b0d17251Schristos# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. 253060421Schristos# 3*b0d17251Schristos# Licensed under the Apache License 2.0 (the "License"). You may not use 453060421Schristos# this file except in compliance with the License. You can obtain a copy 553060421Schristos# in the file LICENSE in the source distribution or at 653060421Schristos# https://www.openssl.org/source/license.html 753060421Schristos 853060421Schristosuse strict; 953060421Schristos 1053060421Schristospackage TLSProxy::ServerKeyExchange; 1153060421Schristos 1253060421Schristosuse vars '@ISA'; 1353060421Schristospush @ISA, 'TLSProxy::Message'; 1453060421Schristos 1553060421Schristossub new 1653060421Schristos{ 1753060421Schristos my $class = shift; 1853060421Schristos my ($server, 1953060421Schristos $data, 2053060421Schristos $records, 2153060421Schristos $startoffset, 2253060421Schristos $message_frag_lens) = @_; 2353060421Schristos 2453060421Schristos my $self = $class->SUPER::new( 2553060421Schristos $server, 2653060421Schristos TLSProxy::Message::MT_SERVER_KEY_EXCHANGE, 2753060421Schristos $data, 2853060421Schristos $records, 2953060421Schristos $startoffset, 3053060421Schristos $message_frag_lens); 3153060421Schristos 3253060421Schristos #DHE 3353060421Schristos $self->{p} = ""; 3453060421Schristos $self->{g} = ""; 3553060421Schristos $self->{pub_key} = ""; 3613d40330Schristos $self->{sigalg} = -1; 3753060421Schristos $self->{sig} = ""; 3853060421Schristos 3953060421Schristos return $self; 4053060421Schristos} 4153060421Schristos 4253060421Schristossub parse 4353060421Schristos{ 4453060421Schristos my $self = shift; 4513d40330Schristos my $sigalg = -1; 4653060421Schristos 4713d40330Schristos #Minimal SKE parsing. Only supports one known DHE ciphersuite at the moment 4813d40330Schristos return if TLSProxy::Proxy->ciphersuite() 4913d40330Schristos != TLSProxy::Message::CIPHER_ADH_AES_128_SHA 5013d40330Schristos && TLSProxy::Proxy->ciphersuite() 5113d40330Schristos != TLSProxy::Message::CIPHER_DHE_RSA_AES_128_SHA; 5253060421Schristos 5353060421Schristos my $p_len = unpack('n', $self->data); 5453060421Schristos my $ptr = 2; 5553060421Schristos my $p = substr($self->data, $ptr, $p_len); 5653060421Schristos $ptr += $p_len; 5753060421Schristos 5853060421Schristos my $g_len = unpack('n', substr($self->data, $ptr)); 5953060421Schristos $ptr += 2; 6053060421Schristos my $g = substr($self->data, $ptr, $g_len); 6153060421Schristos $ptr += $g_len; 6253060421Schristos 6353060421Schristos my $pub_key_len = unpack('n', substr($self->data, $ptr)); 6453060421Schristos $ptr += 2; 6553060421Schristos my $pub_key = substr($self->data, $ptr, $pub_key_len); 6653060421Schristos $ptr += $pub_key_len; 6753060421Schristos 6853060421Schristos #We assume its signed 6913d40330Schristos my $record = ${$self->records}[0]; 7013d40330Schristos 7113d40330Schristos if (TLSProxy::Proxy->is_tls13() 7213d40330Schristos || $record->version() == TLSProxy::Record::VERS_TLS_1_2) { 7313d40330Schristos $sigalg = unpack('n', substr($self->data, $ptr)); 7413d40330Schristos $ptr += 2; 7513d40330Schristos } 7653060421Schristos my $sig = ""; 7713d40330Schristos if (defined $sigalg) { 7813d40330Schristos my $sig_len = unpack('n', substr($self->data, $ptr)); 7953060421Schristos if (defined $sig_len) { 8053060421Schristos $ptr += 2; 8153060421Schristos $sig = substr($self->data, $ptr, $sig_len); 8253060421Schristos $ptr += $sig_len; 8353060421Schristos } 8413d40330Schristos } 8553060421Schristos 8653060421Schristos $self->p($p); 8753060421Schristos $self->g($g); 8853060421Schristos $self->pub_key($pub_key); 8913d40330Schristos $self->sigalg($sigalg) if defined $sigalg; 9013d40330Schristos $self->signature($sig); 9153060421Schristos} 9253060421Schristos 9353060421Schristos 9453060421Schristos#Reconstruct the on-the-wire message data following changes 9553060421Schristossub set_message_contents 9653060421Schristos{ 9753060421Schristos my $self = shift; 9853060421Schristos my $data; 9953060421Schristos 10053060421Schristos $data = pack('n', length($self->p)); 10153060421Schristos $data .= $self->p; 10253060421Schristos $data .= pack('n', length($self->g)); 10353060421Schristos $data .= $self->g; 10453060421Schristos $data .= pack('n', length($self->pub_key)); 10553060421Schristos $data .= $self->pub_key; 10613d40330Schristos $data .= pack('n', $self->sigalg) if ($self->sigalg != -1); 10713d40330Schristos if (length($self->signature) > 0) { 10813d40330Schristos $data .= pack('n', length($self->signature)); 10913d40330Schristos $data .= $self->signature; 11053060421Schristos } 11153060421Schristos 11253060421Schristos $self->data($data); 11353060421Schristos} 11453060421Schristos 11553060421Schristos#Read/write accessors 11653060421Schristos#DHE 11753060421Schristossub p 11853060421Schristos{ 11953060421Schristos my $self = shift; 12053060421Schristos if (@_) { 12153060421Schristos $self->{p} = shift; 12253060421Schristos } 12353060421Schristos return $self->{p}; 12453060421Schristos} 12553060421Schristossub g 12653060421Schristos{ 12753060421Schristos my $self = shift; 12853060421Schristos if (@_) { 12953060421Schristos $self->{g} = shift; 13053060421Schristos } 13153060421Schristos return $self->{g}; 13253060421Schristos} 13353060421Schristossub pub_key 13453060421Schristos{ 13553060421Schristos my $self = shift; 13653060421Schristos if (@_) { 13753060421Schristos $self->{pub_key} = shift; 13853060421Schristos } 13953060421Schristos return $self->{pub_key}; 14053060421Schristos} 14113d40330Schristossub sigalg 14213d40330Schristos{ 14313d40330Schristos my $self = shift; 14413d40330Schristos if (@_) { 14513d40330Schristos $self->{sigalg} = shift; 14613d40330Schristos } 14713d40330Schristos return $self->{sigalg}; 14813d40330Schristos} 14913d40330Schristossub signature 15053060421Schristos{ 15153060421Schristos my $self = shift; 15253060421Schristos if (@_) { 15353060421Schristos $self->{sig} = shift; 15453060421Schristos } 15553060421Schristos return $self->{sig}; 15653060421Schristos} 15753060421Schristos1; 158