ServerHello.pm 6.1 KB

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