xref: /freebsd/crypto/openssl/util/perl/TLSProxy/ServerKeyExchange.pm (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
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