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::CertificateRequest; 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_CERTIFICATE_REQUEST, 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 $self->{extension_data} = ""; 41e0c4386eSCy Schubert 42e0c4386eSCy Schubert return $self; 43e0c4386eSCy Schubert} 44e0c4386eSCy Schubert 45e0c4386eSCy Schubertsub parse 46e0c4386eSCy Schubert{ 47e0c4386eSCy Schubert my $self = shift; 48e0c4386eSCy Schubert my $ptr = 1; 49e0c4386eSCy Schubert 50e0c4386eSCy Schubert if (TLSProxy::Proxy->is_tls13()) { 51e0c4386eSCy Schubert my $request_ctx_len = unpack('C', $self->data); 52e0c4386eSCy Schubert my $request_ctx = substr($self->data, $ptr, $request_ctx_len); 53e0c4386eSCy Schubert $ptr += $request_ctx_len; 54e0c4386eSCy Schubert 55e0c4386eSCy Schubert my $extensions_len = unpack('n', substr($self->data, $ptr)); 56e0c4386eSCy Schubert $ptr += 2; 57e0c4386eSCy Schubert my $extension_data = substr($self->data, $ptr); 58e0c4386eSCy Schubert if (length($extension_data) != $extensions_len) { 59e0c4386eSCy Schubert die "Invalid extension length\n"; 60e0c4386eSCy Schubert } 61e0c4386eSCy Schubert my %extensions = (); 62e0c4386eSCy Schubert while (length($extension_data) >= 4) { 63e0c4386eSCy Schubert my ($type, $size) = unpack("nn", $extension_data); 64e0c4386eSCy Schubert my $extdata = substr($extension_data, 4, $size); 65e0c4386eSCy Schubert $extension_data = substr($extension_data, 4 + $size); 66e0c4386eSCy Schubert $extensions{$type} = $extdata; 67e0c4386eSCy Schubert } 68e0c4386eSCy Schubert $self->extension_data(\%extensions); 69e0c4386eSCy Schubert 70e0c4386eSCy Schubert print " Extensions Len:".$extensions_len."\n"; 71e0c4386eSCy Schubert } 72e0c4386eSCy Schubert # else parse TLSv1.2 version - we don't support that at the moment 73e0c4386eSCy Schubert} 74e0c4386eSCy Schubert 75e0c4386eSCy Schubert#Reconstruct the on-the-wire message data following changes 76e0c4386eSCy Schubertsub set_message_contents 77e0c4386eSCy Schubert{ 78e0c4386eSCy Schubert my $self = shift; 79e0c4386eSCy Schubert my $data; 80e0c4386eSCy Schubert my $extensions = ""; 81e0c4386eSCy Schubert 82e0c4386eSCy Schubert foreach my $key (keys %{$self->extension_data}) { 83e0c4386eSCy Schubert my $extdata = ${$self->extension_data}{$key}; 84e0c4386eSCy Schubert $extensions .= pack("n", $key); 85e0c4386eSCy Schubert $extensions .= pack("n", length($extdata)); 86e0c4386eSCy Schubert $extensions .= $extdata; 87e0c4386eSCy Schubert } 88e0c4386eSCy Schubert 89e0c4386eSCy Schubert $data = pack('n', length($extensions)); 90e0c4386eSCy Schubert $data .= $extensions; 91e0c4386eSCy Schubert $self->data($data); 92e0c4386eSCy Schubert} 93e0c4386eSCy Schubert 94e0c4386eSCy Schubert#Read/write accessors 95e0c4386eSCy Schubertsub extension_data 96e0c4386eSCy Schubert{ 97e0c4386eSCy Schubert my $self = shift; 98e0c4386eSCy Schubert if (@_) { 99e0c4386eSCy Schubert $self->{extension_data} = shift; 100e0c4386eSCy Schubert } 101e0c4386eSCy Schubert return $self->{extension_data}; 102e0c4386eSCy Schubert} 103e0c4386eSCy Schubertsub set_extension 104e0c4386eSCy Schubert{ 105e0c4386eSCy Schubert my ($self, $ext_type, $ext_data) = @_; 106e0c4386eSCy Schubert $self->{extension_data}{$ext_type} = $ext_data; 107e0c4386eSCy Schubert} 108e0c4386eSCy Schubertsub delete_extension 109e0c4386eSCy Schubert{ 110e0c4386eSCy Schubert my ($self, $ext_type) = @_; 111e0c4386eSCy Schubert delete $self->{extension_data}{$ext_type}; 112e0c4386eSCy Schubert} 113e0c4386eSCy Schubert1; 114