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