ServerHello.pm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. # Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License 2.0 (the "License"). You may not use
  4. # this file except in compliance with the License. You can obtain a copy
  5. # in the file LICENSE in the source distribution or at
  6. # https://www.openssl.org/source/license.html
  7. use strict;
  8. package TLSProxy::ServerHello;
  9. use vars '@ISA';
  10. push @ISA, 'TLSProxy::Message';
  11. my $hrrrandom = pack("C*", 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE,
  12. 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2,
  13. 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09,
  14. 0xE2, 0xC8, 0xA8, 0x33, 0x9C);
  15. sub new
  16. {
  17. my $class = shift;
  18. my ($server,
  19. $data,
  20. $records,
  21. $startoffset,
  22. $message_frag_lens) = @_;
  23. my $self = $class->SUPER::new(
  24. $server,
  25. TLSProxy::Message::MT_SERVER_HELLO,
  26. $data,
  27. $records,
  28. $startoffset,
  29. $message_frag_lens);
  30. $self->{server_version} = 0;
  31. $self->{random} = [];
  32. $self->{session_id_len} = 0;
  33. $self->{session} = "";
  34. $self->{ciphersuite} = 0;
  35. $self->{comp_meth} = 0;
  36. $self->{extension_data} = "";
  37. return $self;
  38. }
  39. sub parse
  40. {
  41. my $self = shift;
  42. my $ptr = 2;
  43. my ($server_version) = unpack('n', $self->data);
  44. my $neg_version = $server_version;
  45. my $random = substr($self->data, $ptr, 32);
  46. $ptr += 32;
  47. my $session_id_len = 0;
  48. my $session = "";
  49. $session_id_len = unpack('C', substr($self->data, $ptr));
  50. $ptr++;
  51. $session = substr($self->data, $ptr, $session_id_len);
  52. $ptr += $session_id_len;
  53. my $ciphersuite = unpack('n', substr($self->data, $ptr));
  54. $ptr += 2;
  55. my $comp_meth = 0;
  56. $comp_meth = unpack('C', substr($self->data, $ptr));
  57. $ptr++;
  58. my $extensions_len = unpack('n', substr($self->data, $ptr));
  59. if (!defined $extensions_len) {
  60. $extensions_len = 0;
  61. } else {
  62. $ptr += 2;
  63. }
  64. #For now we just deal with this as a block of data. In the future we will
  65. #want to parse this
  66. my $extension_data;
  67. if ($extensions_len != 0) {
  68. $extension_data = substr($self->data, $ptr);
  69. if (length($extension_data) != $extensions_len) {
  70. die "Invalid extension length\n";
  71. }
  72. } else {
  73. if (length($self->data) != $ptr) {
  74. die "Invalid extension length\n";
  75. }
  76. $extension_data = "";
  77. }
  78. my %extensions = ();
  79. while (length($extension_data) >= 4) {
  80. my ($type, $size) = unpack("nn", $extension_data);
  81. my $extdata = substr($extension_data, 4, $size);
  82. $extension_data = substr($extension_data, 4 + $size);
  83. $extensions{$type} = $extdata;
  84. if ($type == TLSProxy::Message::EXT_SUPPORTED_VERSIONS) {
  85. $neg_version = unpack('n', $extdata);
  86. }
  87. }
  88. if ($random eq $hrrrandom) {
  89. TLSProxy::Proxy->is_tls13(1);
  90. } elsif ($neg_version == TLSProxy::Record::VERS_TLS_1_3) {
  91. TLSProxy::Proxy->is_tls13(1);
  92. TLSProxy::Record->server_encrypting(1);
  93. TLSProxy::Record->client_encrypting(1);
  94. }
  95. $self->server_version($server_version);
  96. $self->random($random);
  97. $self->session_id_len($session_id_len);
  98. $self->session($session);
  99. $self->ciphersuite($ciphersuite);
  100. TLSProxy::Proxy->ciphersuite($ciphersuite);
  101. $self->comp_meth($comp_meth);
  102. $self->extension_data(\%extensions);
  103. $self->process_data();
  104. print " Server Version:".$server_version."\n";
  105. print " Session ID Len:".$session_id_len."\n";
  106. print " Ciphersuite:".$ciphersuite."\n";
  107. print " Compression Method:".$comp_meth."\n";
  108. print " Extensions Len:".$extensions_len."\n";
  109. }
  110. #Perform any actions necessary based on the data we've seen
  111. sub process_data
  112. {
  113. my $self = shift;
  114. TLSProxy::Message->ciphersuite($self->ciphersuite);
  115. }
  116. #Reconstruct the on-the-wire message data following changes
  117. sub set_message_contents
  118. {
  119. my $self = shift;
  120. my $data;
  121. my $extensions = "";
  122. $data = pack('n', $self->server_version);
  123. $data .= $self->random;
  124. $data .= pack('C', $self->session_id_len);
  125. $data .= $self->session;
  126. $data .= pack('n', $self->ciphersuite);
  127. $data .= pack('C', $self->comp_meth);
  128. foreach my $key (keys %{$self->extension_data}) {
  129. my $extdata = ${$self->extension_data}{$key};
  130. $extensions .= pack("n", $key);
  131. $extensions .= pack("n", length($extdata));
  132. $extensions .= $extdata;
  133. if ($key == $self->dupext) {
  134. $extensions .= pack("n", $key);
  135. $extensions .= pack("n", length($extdata));
  136. $extensions .= $extdata;
  137. }
  138. }
  139. $data .= pack('n', length($extensions));
  140. $data .= $extensions;
  141. $self->data($data);
  142. }
  143. #Read/write accessors
  144. sub server_version
  145. {
  146. my $self = shift;
  147. if (@_) {
  148. $self->{server_version} = shift;
  149. }
  150. return $self->{server_version};
  151. }
  152. sub random
  153. {
  154. my $self = shift;
  155. if (@_) {
  156. $self->{random} = shift;
  157. }
  158. return $self->{random};
  159. }
  160. sub session_id_len
  161. {
  162. my $self = shift;
  163. if (@_) {
  164. $self->{session_id_len} = shift;
  165. }
  166. return $self->{session_id_len};
  167. }
  168. sub session
  169. {
  170. my $self = shift;
  171. if (@_) {
  172. $self->{session} = shift;
  173. }
  174. return $self->{session};
  175. }
  176. sub ciphersuite
  177. {
  178. my $self = shift;
  179. if (@_) {
  180. $self->{ciphersuite} = shift;
  181. }
  182. return $self->{ciphersuite};
  183. }
  184. sub comp_meth
  185. {
  186. my $self = shift;
  187. if (@_) {
  188. $self->{comp_meth} = shift;
  189. }
  190. return $self->{comp_meth};
  191. }
  192. sub extension_data
  193. {
  194. my $self = shift;
  195. if (@_) {
  196. $self->{extension_data} = shift;
  197. }
  198. return $self->{extension_data};
  199. }
  200. sub set_extension
  201. {
  202. my ($self, $ext_type, $ext_data) = @_;
  203. $self->{extension_data}{$ext_type} = $ext_data;
  204. }
  205. sub delete_extension
  206. {
  207. my ($self, $ext_type) = @_;
  208. delete $self->{extension_data}{$ext_type};
  209. }
  210. 1;