summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorFrederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk>2024-01-11 14:18:07 +0100
committerMatt Caswell <matt@openssl.org>2024-02-09 08:11:23 +0000
commita1c72cc20dd4620a69142cfc65fd17daef8d28ee (patch)
tree0ac3c746f4b0e57162a6d493787189cc130f5e2f /util
parent01690a7ff36c4d18c48b301cdf375c954105a1d9 (diff)
Support DTLS in TLS::Proxy.
Fixes #23199 Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23319)
Diffstat (limited to 'util')
-rw-r--r--util/perl/TLSProxy/Certificate.pm10
-rw-r--r--util/perl/TLSProxy/CertificateRequest.pm10
-rw-r--r--util/perl/TLSProxy/CertificateVerify.pm10
-rw-r--r--util/perl/TLSProxy/ClientHello.pm54
-rw-r--r--util/perl/TLSProxy/EncryptedExtensions.pm10
-rw-r--r--util/perl/TLSProxy/HelloVerifyRequest.pm115
-rw-r--r--util/perl/TLSProxy/Message.pm187
-rw-r--r--util/perl/TLSProxy/NewSessionTicket.pm56
-rw-r--r--util/perl/TLSProxy/Proxy.pm132
-rw-r--r--util/perl/TLSProxy/Record.pm184
-rw-r--r--util/perl/TLSProxy/ServerHello.pm14
-rw-r--r--util/perl/TLSProxy/ServerKeyExchange.pm10
12 files changed, 694 insertions, 98 deletions
diff --git a/util/perl/TLSProxy/Certificate.pm b/util/perl/TLSProxy/Certificate.pm
index 03f6619954..a32bc2c97b 100644
--- a/util/perl/TLSProxy/Certificate.pm
+++ b/util/perl/TLSProxy/Certificate.pm
@@ -15,15 +15,23 @@ push @ISA, 'TLSProxy::Message';
sub new
{
my $class = shift;
- my ($server,
+ my ($isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
my $self = $class->SUPER::new(
+ $isdtls,
$server,
TLSProxy::Message::MT_CERTIFICATE,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
diff --git a/util/perl/TLSProxy/CertificateRequest.pm b/util/perl/TLSProxy/CertificateRequest.pm
index 193bea168a..0191df68f9 100644
--- a/util/perl/TLSProxy/CertificateRequest.pm
+++ b/util/perl/TLSProxy/CertificateRequest.pm
@@ -15,15 +15,23 @@ push @ISA, 'TLSProxy::Message';
sub new
{
my $class = shift;
- my ($server,
+ my ($isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
my $self = $class->SUPER::new(
+ $isdtls,
$server,
TLSProxy::Message::MT_CERTIFICATE_REQUEST,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
diff --git a/util/perl/TLSProxy/CertificateVerify.pm b/util/perl/TLSProxy/CertificateVerify.pm
index fe45001405..9592272991 100644
--- a/util/perl/TLSProxy/CertificateVerify.pm
+++ b/util/perl/TLSProxy/CertificateVerify.pm
@@ -15,15 +15,23 @@ push @ISA, 'TLSProxy::Message';
sub new
{
my $class = shift;
- my ($server,
+ my ($isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
my $self = $class->SUPER::new(
+ $isdtls,
$server,
TLSProxy::Message::MT_CERTIFICATE_VERIFY,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
diff --git a/util/perl/TLSProxy/ClientHello.pm b/util/perl/TLSProxy/ClientHello.pm
index c49bc23671..5a5f5fd34d 100644
--- a/util/perl/TLSProxy/ClientHello.pm
+++ b/util/perl/TLSProxy/ClientHello.pm
@@ -9,30 +9,43 @@ use strict;
package TLSProxy::ClientHello;
+use TLSProxy::Record;
+
use vars '@ISA';
push @ISA, 'TLSProxy::Message';
sub new
{
my $class = shift;
- my ($server,
+ my ($isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
my $self = $class->SUPER::new(
+ $isdtls,
$server,
- 1,
+ TLSProxy::Message::MT_CLIENT_HELLO,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
$message_frag_lens);
+ $self->{isdtls} = $isdtls;
$self->{client_version} = 0;
$self->{random} = [];
$self->{session_id_len} = 0;
$self->{session} = "";
+ $self->{legacy_cookie_len} = 0; #DTLS only
+ $self->{legacy_cookie} = ""; #DTLS only
$self->{ciphersuite_len} = 0;
$self->{ciphersuites} = [];
$self->{comp_meth_len} = 0;
@@ -54,6 +67,14 @@ sub parse
$ptr++;
my $session = substr($self->data, $ptr, $session_id_len);
$ptr += $session_id_len;
+ my $legacy_cookie_len = 0;
+ my $legacy_cookie = "";
+ if($self->{isdtls}) {
+ $legacy_cookie_len = unpack('C', substr($self->data, $ptr));
+ $ptr++;
+ $legacy_cookie = substr($self->data, $ptr, $legacy_cookie_len);
+ $ptr += $legacy_cookie_len;
+ }
my $ciphersuite_len = unpack('n', substr($self->data, $ptr));
$ptr += 2;
my @ciphersuites = unpack('n*', substr($self->data, $ptr,
@@ -84,6 +105,8 @@ sub parse
$self->random($random);
$self->session_id_len($session_id_len);
$self->session($session);
+ $self->legacy_cookie_len($legacy_cookie_len);
+ $self->legacy_cookie($legacy_cookie);
$self->ciphersuite_len($ciphersuite_len);
$self->ciphersuites(\@ciphersuites);
$self->comp_meth_len($comp_meth_len);
@@ -93,8 +116,11 @@ sub parse
$self->process_extensions();
- print " Client Version:".$client_version."\n";
+ print " Client Version:".$TLSProxy::Record::tls_version{$client_version}."\n";
print " Session ID Len:".$session_id_len."\n";
+ if($self->{isdtls}) {
+ print " Legacy Cookie Len:".$legacy_cookie_len."\n";
+ }
print " Ciphersuite len:".$ciphersuite_len."\n";
print " Compression Method Len:".$comp_meth_len."\n";
print " Extensions Len:".$extensions_len."\n";
@@ -138,6 +164,12 @@ sub set_message_contents
$data .= $self->random;
$data .= pack('C', $self->session_id_len);
$data .= $self->session;
+ if($self->{isdtls}){
+ $data .= pack('C', $self->legacy_cookie_len);
+ if($self->legacy_cookie_len > 0) {
+ $data .= $self->legacy_cookie;
+ }
+ }
$data .= pack('n', $self->ciphersuite_len);
$data .= pack("n*", @{$self->ciphersuites});
$data .= pack('C', $self->comp_meth_len);
@@ -197,6 +229,22 @@ sub session
}
return $self->{session};
}
+sub legacy_cookie_len
+{
+ my $self = shift;
+ if (@_) {
+ $self->{legacy_cookie_len} = shift;
+ }
+ return $self->{legacy_cookie_len};
+}
+sub legacy_cookie
+{
+ my $self = shift;
+ if (@_) {
+ $self->{legacy_cookie} = shift;
+ }
+ return $self->{legacy_cookie};
+}
sub ciphersuite_len
{
my $self = shift;
diff --git a/util/perl/TLSProxy/EncryptedExtensions.pm b/util/perl/TLSProxy/EncryptedExtensions.pm
index 4fd445b41e..5f867101d9 100644
--- a/util/perl/TLSProxy/EncryptedExtensions.pm
+++ b/util/perl/TLSProxy/EncryptedExtensions.pm
@@ -15,15 +15,23 @@ push @ISA, 'TLSProxy::Message';
sub new
{
my $class = shift;
- my ($server,
+ my ($isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
my $self = $class->SUPER::new(
+ $isdtls,
$server,
TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
diff --git a/util/perl/TLSProxy/HelloVerifyRequest.pm b/util/perl/TLSProxy/HelloVerifyRequest.pm
new file mode 100644
index 0000000000..40162d08ef
--- /dev/null
+++ b/util/perl/TLSProxy/HelloVerifyRequest.pm
@@ -0,0 +1,115 @@
+# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+
+package TLSProxy::HelloVerifyRequest;
+
+use TLSProxy::Record;
+
+use vars '@ISA';
+push @ISA, 'TLSProxy::Message';
+
+
+sub new
+{
+ my $class = shift;
+ my ($isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens) = @_;
+
+ my $self = $class->SUPER::new(
+ $isdtls,
+ $server,
+ TLSProxy::Message::MT_HELLO_VERIFY_REQUEST,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens);
+
+ $self->{server_version} = 0;
+ $self->{cookie_len} = 0;
+ $self->{cookie} = "";
+
+ return $self;
+}
+
+sub parse
+{
+ my $self = shift;
+
+ my ($server_version) = unpack('n', $self->data);
+ my $ptr = 2;
+ my $cookie_len = unpack('C', substr($self->data, $ptr));
+ $ptr++;
+ my $cookie = substr($self->data, $ptr, $cookie_len);
+
+ $self->server_version($server_version);
+ $self->cookie_len($cookie_len);
+ $self->cookie($cookie);
+
+ $self->process_data();
+
+ print " Server Version:".$TLSProxy::Record::tls_version{$server_version}."\n";
+ print " Cookie Len:".$cookie_len."\n";
+}
+
+#Perform any actions necessary based on the data we've seen
+sub process_data
+{
+ my $self = shift;
+ #Intentional no-op
+}
+
+#Reconstruct the on-the-wire message data following changes
+sub set_message_contents
+{
+ my $self = shift;
+ my $data;
+
+ $data = pack('n', $self->server_version);
+ $data .= pack('C', $self->cookie_len);
+ $data .= $self->cookie;
+
+ $self->data($data);
+}
+
+#Read/write accessors
+sub server_version
+{
+ my $self = shift;
+ if (@_) {
+ $self->{server_version} = shift;
+ }
+ return $self->{server_version};
+}
+sub cookie_len
+{
+ my $self = shift;
+ if (@_) {
+ $self->{cookie_len} = shift;
+ }
+ return $self->{cookie_len};
+}
+sub cookie
+{
+ my $self = shift;
+ if (@_) {
+ $self->{cookie} = shift;
+ }
+ return $self->{cookie};
+}
+1;
diff --git a/util/perl/TLSProxy/Message.pm b/util/perl/TLSProxy/Message.pm
index ce22187569..c5e822e90d 100644
--- a/util/perl/TLSProxy/Message.pm
+++ b/util/perl/TLSProxy/Message.pm
@@ -11,6 +11,7 @@ package TLSProxy::Message;
use TLSProxy::Alert;
+use constant DTLS_MESSAGE_HEADER_LENGTH => 12;
use constant TLS_MESSAGE_HEADER_LENGTH => 4;
#Message types
@@ -18,6 +19,7 @@ use constant {
MT_HELLO_REQUEST => 0,
MT_CLIENT_HELLO => 1,
MT_SERVER_HELLO => 2,
+ MT_HELLO_VERIFY_REQUEST => 3,
MT_NEW_SESSION_TICKET => 4,
MT_ENCRYPTED_EXTENSIONS => 8,
MT_CERTIFICATE => 11,
@@ -42,7 +44,9 @@ use constant {
use constant {
AL_DESC_CLOSE_NOTIFY => 0,
AL_DESC_UNEXPECTED_MESSAGE => 10,
+ AL_DESC_BAD_RECORD_MAC => 20,
AL_DESC_ILLEGAL_PARAMETER => 47,
+ AL_DESC_PROTOCOL_VERSION => 70,
AL_DESC_NO_RENEGOTIATION => 100
};
@@ -50,6 +54,7 @@ my %message_type = (
MT_HELLO_REQUEST, "HelloRequest",
MT_CLIENT_HELLO, "ClientHello",
MT_SERVER_HELLO, "ServerHello",
+ MT_HELLO_VERIFY_REQUEST, "HelloVerifyRequest",
MT_NEW_SESSION_TICKET, "NewSessionTicket",
MT_ENCRYPTED_EXTENSIONS, "EncryptedExtensions",
MT_CERTIFICATE, "Certificate",
@@ -172,6 +177,7 @@ sub get_messages
my $class = shift;
my $serverin = shift;
my $record = shift;
+ my $isdtls = shift;
my @messages = ();
my $message;
@@ -216,8 +222,14 @@ sub get_messages
$recoffset = $messlen - length($payload);
$payload .= substr($record->decrypt_data, 0, $recoffset);
push @message_frag_lens, $recoffset;
- $message = create_message($server, $mt, $payload,
- $startoffset);
+ if ($isdtls) {
+ # We must set $msgseq, $msgfrag, $msgfragoffs
+ die "Internal error: cannot handle partial dtls messages\n"
+ }
+ $message = create_message($server, $mt,
+ #$msgseq, $msgfrag, $msgfragoffs,
+ 0, 0, 0,
+ $payload, $startoffset, $isdtls);
push @messages, $message;
$payload = "";
@@ -232,21 +244,36 @@ sub get_messages
while ($record->decrypt_len > $recoffset) {
#We are at the start of a new message
- if ($record->decrypt_len - $recoffset < 4) {
+ my $msgheaderlen = $isdtls ? DTLS_MESSAGE_HEADER_LENGTH
+ : TLS_MESSAGE_HEADER_LENGTH;
+ if ($record->decrypt_len - $recoffset < $msgheaderlen) {
#Whilst technically probably valid we can't cope with this
die "End of record in the middle of a message header\n";
}
@message_rec_list = ($record);
my $lenhi;
my $lenlo;
- ($mt, $lenhi, $lenlo) = unpack('CnC',
- substr($record->decrypt_data,
- $recoffset));
+ my $msgseq;
+ my $msgfrag;
+ my $msgfragoffs;
+ if ($isdtls) {
+ my $msgfraghi;
+ my $msgfraglo;
+ my $msgfragoffshi;
+ my $msgfragoffslo;
+ ($mt, $lenhi, $lenlo, $msgseq, $msgfraghi, $msgfraglo, $msgfragoffshi, $msgfragoffslo) =
+ unpack('CnCnnCnC', substr($record->decrypt_data, $recoffset));
+ $msgfrag = ($msgfraghi << 8) | $msgfraglo;
+ $msgfragoffs = ($msgfragoffshi << 8) | $msgfragoffslo;
+ } else {
+ ($mt, $lenhi, $lenlo) =
+ unpack('CnC', substr($record->decrypt_data, $recoffset));
+ }
$messlen = ($lenhi << 8) | $lenlo;
- print " Message type: $message_type{$mt}\n";
+ print " Message type: $message_type{$mt}($mt)\n";
print " Message Length: $messlen\n";
$startoffset = $recoffset;
- $recoffset += 4;
+ $recoffset += $msgheaderlen;
$payload = "";
if ($recoffset <= $record->decrypt_len) {
@@ -257,8 +284,9 @@ sub get_messages
$messlen);
$recoffset += $messlen;
push @message_frag_lens, $messlen;
- $message = create_message($server, $mt, $payload,
- $startoffset);
+ $message = create_message($server, $mt, $msgseq,
+ $msgfrag, $msgfragoffs,
+ $payload, $startoffset, $isdtls);
push @messages, $message;
$payload = "";
@@ -307,14 +335,18 @@ sub get_messages
#construct it
sub create_message
{
- my ($server, $mt, $data, $startoffset) = @_;
+ my ($server, $mt, $msgseq, $msgfrag, $msgfragoffs, $data, $startoffset, $isdtls) = @_;
my $message;
#We only support ClientHello in this version...needs to be extended for
#others
if ($mt == MT_CLIENT_HELLO) {
$message = TLSProxy::ClientHello->new(
+ $isdtls,
$server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -323,7 +355,24 @@ sub create_message
$message->parse();
} elsif ($mt == MT_SERVER_HELLO) {
$message = TLSProxy::ServerHello->new(
+ $isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
+ $data,
+ [@message_rec_list],
+ $startoffset,
+ [@message_frag_lens]
+ );
+ $message->parse();
+ } elsif ($mt == MT_HELLO_VERIFY_REQUEST) {
+ $message = TLSProxy::HelloVerifyRequest->new(
+ $isdtls,
$server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -332,7 +381,11 @@ sub create_message
$message->parse();
} elsif ($mt == MT_ENCRYPTED_EXTENSIONS) {
$message = TLSProxy::EncryptedExtensions->new(
+ $isdtls,
$server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -341,7 +394,11 @@ sub create_message
$message->parse();
} elsif ($mt == MT_CERTIFICATE) {
$message = TLSProxy::Certificate->new(
+ $isdtls,
$server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -350,7 +407,11 @@ sub create_message
$message->parse();
} elsif ($mt == MT_CERTIFICATE_REQUEST) {
$message = TLSProxy::CertificateRequest->new(
+ $isdtls,
$server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -359,7 +420,11 @@ sub create_message
$message->parse();
} elsif ($mt == MT_CERTIFICATE_VERIFY) {
$message = TLSProxy::CertificateVerify->new(
+ $isdtls,
$server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -368,7 +433,11 @@ sub create_message
$message->parse();
} elsif ($mt == MT_SERVER_KEY_EXCHANGE) {
$message = TLSProxy::ServerKeyExchange->new(
+ $isdtls,
$server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -376,19 +445,36 @@ sub create_message
);
$message->parse();
} elsif ($mt == MT_NEW_SESSION_TICKET) {
- $message = TLSProxy::NewSessionTicket->new(
- $server,
- $data,
- [@message_rec_list],
- $startoffset,
- [@message_frag_lens]
- );
+ if ($isdtls) {
+ $message = TLSProxy::NewSessionTicket->new_dtls(
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
+ $data,
+ [@message_rec_list],
+ $startoffset,
+ [@message_frag_lens]
+ );
+ } else {
+ $message = TLSProxy::NewSessionTicket->new(
+ $server,
+ $data,
+ [@message_rec_list],
+ $startoffset,
+ [@message_frag_lens]
+ );
+ }
$message->parse();
} else {
#Unknown message type
$message = TLSProxy::Message->new(
+ $isdtls,
$server,
$mt,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
[@message_rec_list],
$startoffset,
@@ -423,18 +509,26 @@ sub alert
sub new
{
my $class = shift;
- my ($server,
+ my ($isdtls,
+ $server,
$mt,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
my $self = {
+ isdtls => $isdtls,
server => $server,
data => $data,
records => $records,
mt => $mt,
+ msgseq => $msgseq,
+ msgfrag => $msgfrag,
+ msgfragoffs => $msgfragoffs,
startoffset => $startoffset,
message_frag_lens => $message_frag_lens,
dupext => -1
@@ -463,12 +557,21 @@ sub repack
$self->set_message_contents();
- my $lenhi;
- my $lenlo;
+ my $lenlo = length($self->data) & 0xff;
+ my $lenhi = length($self->data) >> 8;
- $lenlo = length($self->data) & 0xff;
- $lenhi = length($self->data) >> 8;
- $msgdata = pack('CnC', $self->mt, $lenhi, $lenlo).$self->data;
+ if ($self->{isdtls}) {
+ my $msgfraghi = $self->msgfrag >> 8;
+ my $msgfraglo = $self->msgfrag & 0xff;
+ my $msgfragoffshi = $self->msgfragoffs >> 8;
+ my $msgfragoffslo = $self->msgfragoffs & 0xff;
+
+ $msgdata = pack('CnCnnCnC', $self->mt, $lenhi, $lenlo, $self->msgseq,
+ $msgfraghi, $msgfraglo,
+ $msgfragoffshi, $msgfragoffslo).$self->data;
+ } else {
+ $msgdata = pack('CnC', $self->mt, $lenhi, $lenlo).$self->data;
+ }
if ($numrecs == 0) {
#The message is fully contained within one record
@@ -476,13 +579,14 @@ sub repack
my $recdata = $rec->decrypt_data;
my $old_length;
+ my $msg_header_len = $self->{isdtls} ? DTLS_MESSAGE_HEADER_LENGTH
+ : TLS_MESSAGE_HEADER_LENGTH;
# We use empty message_frag_lens to indicates that pre-repacking,
# the message wasn't present. The first fragment length doesn't include
# the TLS header, so we need to check and compute the right length.
if (@{$self->message_frag_lens}) {
- $old_length = ${$self->message_frag_lens}[0] +
- TLS_MESSAGE_HEADER_LENGTH;
+ $old_length = ${$self->message_frag_lens}[0] + $msg_header_len;
} else {
$old_length = 0;
}
@@ -529,8 +633,7 @@ sub repack
$rec->len(length($rec->data));
#Update the fragment len in case we changed it above
- ${$self->message_frag_lens}[0] = length($msgdata)
- - TLS_MESSAGE_HEADER_LENGTH;
+ ${$self->message_frag_lens}[0] = length($msgdata) - $msg_header_len;
return;
}
@@ -578,6 +681,30 @@ sub mt
}
return $self->{mt};
}
+sub msgseq
+{
+ my $self = shift;
+ if (@_) {
+ $self->{msgseq} = shift;
+ }
+ return $self->{msgseq};
+}
+sub msgfrag
+{
+ my $self = shift;
+ if (@_) {
+ $self->{msgfrag} = shift;
+ }
+ return $self->{msgfrag};
+}
+sub msgfragoffs
+{
+ my $self = shift;
+ if (@_) {
+ $self->{msgfragoffs} = shift;
+ }
+ return $self->{msgfragoffs};
+}
sub data
{
my $self = shift;
@@ -613,7 +740,9 @@ sub message_frag_lens
sub encoded_length
{
my $self = shift;
- return TLS_MESSAGE_HEADER_LENGTH + length($self->data);
+ my $msg_header_len = $self->{isdtls} ? DTLS_MESSAGE_HEADER_LENGTH
+ : TLS_MESSAGE_HEADER_LENGTH;
+ return $msg_header_len + length($self->data);
}
sub dupext
{
diff --git a/util/perl/TLSProxy/NewSessionTicket.pm b/util/perl/TLSProxy/NewSessionTicket.pm
index 1c532ff7be..748efb8aa8 100644
--- a/util/perl/TLSProxy/NewSessionTicket.pm
+++ b/util/perl/TLSProxy/NewSessionTicket.pm
@@ -12,18 +12,74 @@ package TLSProxy::NewSessionTicket;
use vars '@ISA';
push @ISA, 'TLSProxy::Message';
+sub new_dtls
+{
+ my $class = shift;
+
+ my ($server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens) = @_;
+
+ return $class->init(
+ 1,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens
+ )
+}
+
sub new
{
my $class = shift;
+
my ($server,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
+ return $class->init(
+ 0,
+ $server,
+ 0, # msgseq
+ 0, # msgfrag
+ 0, # $msgfragoffs
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens
+ )
+}
+
+sub init{
+ my $class = shift;
+ my ($isdtls,
+ $server,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens) = @_;
+
my $self = $class->SUPER::new(
+ $isdtls,
$server,
TLSProxy::Message::MT_NEW_SESSION_TICKET,
+ $msgseq,
+ $msgfrag,
+ $msgfragoffs,
$data,
$records,
$startoffset,
diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm
index 3de10eccb9..0084328a5f 100644
--- a/util/perl/TLSProxy/Proxy.pm
+++ b/util/perl/TLSProxy/Proxy.pm
@@ -17,6 +17,7 @@ use TLSProxy::Record;
use TLSProxy::Message;
use TLSProxy::ClientHello;
use TLSProxy::ServerHello;
+use TLSProxy::HelloVerifyRequest;
use TLSProxy::EncryptedExtensions;
use TLSProxy::Certificate;
use TLSProxy::CertificateRequest;
@@ -71,17 +72,37 @@ BEGIN
my $is_tls13 = 0;
my $ciphersuite = undef;
-sub new
-{
+sub new {
+ my $class = shift;
+ my ($filter,
+ $execute,
+ $cert,
+ $debug) = @_;
+ return init($class, $filter, $execute, $cert, $debug, 0);
+}
+
+sub new_dtls {
my $class = shift;
my ($filter,
$execute,
$cert,
$debug) = @_;
+ return init($class, $filter, $execute, $cert, $debug, 1);
+}
+
+sub init
+{
+ my $class = shift;
+ my ($filter,
+ $execute,
+ $cert,
+ $debug,
+ $isdtls) = @_;
my $self = {
#Public read/write
proxy_addr => $have_IPv6 ? "[::1]" : "127.0.0.1",
+ client_addr => $have_IPv6 ? "[::1]" : "127.0.0.1",
filter => $filter,
serverflags => "",
clientflags => "",
@@ -90,7 +111,9 @@ sub new
sessionfile => undef,
#Public read
+ isdtls => $isdtls,
proxy_port => 0,
+ client_port => 49152 + int(rand(65535 - 49152)),
server_port => 0,
serverpid => 0,
clientpid => 0,
@@ -108,29 +131,6 @@ sub new
message_list => [],
};
- # Create the Proxy socket
- my $proxaddr = $self->{proxy_addr};
- $proxaddr =~ s/[\[\]]//g; # Remove [ and ]
- my @proxyargs = (
- LocalHost => $proxaddr,
- LocalPort => 0,
- Proto => "tcp",
- Listen => SOMAXCONN,
- );
-
- if (my $sock = $IP_factory->(@proxyargs)) {
- $self->{proxy_sock} = $sock;
- $self->{proxy_port} = $sock->sockport();
- $self->{proxy_addr} = $sock->sockhost();
- $self->{proxy_addr} =~ s/(.*:.*)/[$1]/;
- print "Proxy started on port ",
- "$self->{proxy_addr}:$self->{proxy_port}\n";
- # use same address for s_server
- $self->{server_addr} = $self->{proxy_addr};
- } else {
- warn "Failed creating proxy socket (".$proxaddr.",0): $!\n";
- }
-
return bless $self, $class;
}
@@ -200,7 +200,7 @@ sub connect_to_server
my $sock = $IP_factory->(PeerAddr => $servaddr,
PeerPort => $self->{server_port},
- Proto => 'tcp');
+ Proto => $self->{isdtls} ? 'udp' : 'tcp');
if (!defined($sock)) {
my $err = $!;
kill(3, $self->{real_serverpid});
@@ -215,12 +215,51 @@ sub start
my ($self) = shift;
my $pid;
+
+ # Create the Proxy socket
+ my $proxaddr = $self->{proxy_addr};
+ $proxaddr =~ s/[\[\]]//g; # Remove [ and ]
+ my $clientaddr = $self->{client_addr};
+ $clientaddr =~ s/[\[\]]//g; # Remove [ and ]
+
+ my @proxyargs;
+
+ if ($self->{isdtls}) {
+ @proxyargs = (
+ LocalHost => $proxaddr,
+ LocalPort => 0,
+ PeerHost => $clientaddr,
+ PeerPort => $self->{client_port},
+ Proto => "udp",
+ );
+ } else {
+ @proxyargs = (
+ LocalHost => $proxaddr,
+ LocalPort => 0,
+ Proto => "tcp",
+ Listen => SOMAXCONN,
+ );
+ }
+
+ if (my $sock = $IP_factory->(@proxyargs)) {
+ $self->{proxy_sock} = $sock;
+ $self->{proxy_port} = $sock->sockport();
+ $self->{proxy_addr} = $sock->sockhost();
+ $self->{proxy_addr} =~ s/(.*:.*)/[$1]/;
+ print "Proxy started on port ",
+ "$self->{proxy_addr}:$self->{proxy_port}\n";
+ # use same address for s_server
+ $self->{server_addr} = $self->{proxy_addr};
+ } else {
+ warn "Failed creating proxy socket (".$proxaddr.",0): $!\n";
+ }
+
if ($self->{proxy_sock} == 0) {
return 0;
}
my $execcmd = $self->execute
- ." s_server -max_protocol TLSv1.3 -no_comp -rev -engine ossltest"
+ ." s_server -no_comp -engine ossltest -state"
#In TLSv1.3 we issue two session tickets. The default session id
#callback gets confused because the ossltest engine causes the same
#session id to be created twice due to the changed random number
@@ -230,6 +269,14 @@ sub start
." -accept $self->{server_addr}:0"
." -cert ".$self->cert." -cert2 ".$self->cert
." -naccept ".$self->serverconnects;
+ if ($self->{isdtls}) {
+ $execcmd .= " -dtls -max_protocol DTLSv1.2"
+