1e1051a39Sopenharmony_ci#! /usr/bin/env perl 2e1051a39Sopenharmony_ci# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci# 4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci# this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci 9e1051a39Sopenharmony_ciuse strict; 10e1051a39Sopenharmony_ciuse OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; 11e1051a39Sopenharmony_ciuse OpenSSL::Test::Utils; 12e1051a39Sopenharmony_ciuse TLSProxy::Proxy; 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_cimy $test_name = "test_sslsignature"; 15e1051a39Sopenharmony_cisetup($test_name); 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ciplan skip_all => "TLSProxy isn't usable on $^O" 18e1051a39Sopenharmony_ci if $^O =~ /^(VMS)$/; 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ciplan skip_all => "$test_name needs the dynamic engine feature enabled" 21e1051a39Sopenharmony_ci if disabled("engine") || disabled("dynamic-engine"); 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ciplan skip_all => "$test_name needs the sock feature enabled" 24e1051a39Sopenharmony_ci if disabled("sock"); 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ciplan skip_all => "$test_name needs TLS enabled" 27e1051a39Sopenharmony_ci if alldisabled(available_protocols("tls")); 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci$ENV{OPENSSL_ia32cap} = '~0x200000200000000'; 30e1051a39Sopenharmony_cimy $proxy = TLSProxy::Proxy->new( 31e1051a39Sopenharmony_ci undef, 32e1051a39Sopenharmony_ci cmdstr(app(["openssl"]), display => 1), 33e1051a39Sopenharmony_ci srctop_file("apps", "server.pem"), 34e1051a39Sopenharmony_ci (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) 35e1051a39Sopenharmony_ci); 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ciuse constant { 38e1051a39Sopenharmony_ci NO_CORRUPTION => 0, 39e1051a39Sopenharmony_ci CORRUPT_SERVER_CERT_VERIFY => 1, 40e1051a39Sopenharmony_ci CORRUPT_CLIENT_CERT_VERIFY => 2, 41e1051a39Sopenharmony_ci CORRUPT_TLS1_2_SERVER_KEY_EXCHANGE => 3, 42e1051a39Sopenharmony_ci}; 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci$proxy->filter(\&signature_filter); 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_ci#Test 1: No corruption should succeed 47e1051a39Sopenharmony_cimy $testtype = NO_CORRUPTION; 48e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3") if disabled("ec") && disabled("dh"); 49e1051a39Sopenharmony_ci$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; 50e1051a39Sopenharmony_ciplan tests => 4; 51e1051a39Sopenharmony_ciok(TLSProxy::Message->success, "No corruption"); 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ciSKIP: { 54e1051a39Sopenharmony_ci skip "TLSv1.3 disabled", 1 55e1051a39Sopenharmony_ci if disabled("tls1_3") || (disabled("ec") && disabled("dh")); 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_ci #Test 2: Corrupting a server CertVerify signature in TLSv1.3 should fail 58e1051a39Sopenharmony_ci $proxy->clear(); 59e1051a39Sopenharmony_ci $testtype = CORRUPT_SERVER_CERT_VERIFY; 60e1051a39Sopenharmony_ci $proxy->start(); 61e1051a39Sopenharmony_ci ok(TLSProxy::Message->fail, "Corrupt server TLSv1.3 CertVerify"); 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ci #Test x: Corrupting a client CertVerify signature in TLSv1.3 should fail 64e1051a39Sopenharmony_ci #$proxy->clear(); 65e1051a39Sopenharmony_ci #$testtype = CORRUPT_CLIENT_CERT_VERIFY; 66e1051a39Sopenharmony_ci #$proxy->serverflags("-Verify 5"); 67e1051a39Sopenharmony_ci #$proxy->clientflags("-cert ".srctop_file("apps", "server.pem")); 68e1051a39Sopenharmony_ci #$proxy->start(); 69e1051a39Sopenharmony_ci #ok(TLSProxy::Message->fail, "Corrupt client TLSv1.3 CertVerify"); 70e1051a39Sopenharmony_ci #TODO(TLS1.3): This test fails due to a problem in s_server/TLSProxy. 71e1051a39Sopenharmony_ci #Currently a connection is counted as "successful" if the client ends it 72e1051a39Sopenharmony_ci #with a close_notify. In TLSProxy the client initiates the closure of the 73e1051a39Sopenharmony_ci #connection so really we should not count it as successful until s_server 74e1051a39Sopenharmony_ci #has also responded with a close_notify. However s_server never sends a 75e1051a39Sopenharmony_ci #close_notify - it just closes the connection. Fixing this would be a 76e1051a39Sopenharmony_ci #significant change to the long established behaviour of s_server. 77e1051a39Sopenharmony_ci #Unfortunately in this test, it is the server that notices the incorrect 78e1051a39Sopenharmony_ci #signature and responds with an appropriate alert. However s_client never 79e1051a39Sopenharmony_ci #sees that because it occurs after the server Finished has been sent. 80e1051a39Sopenharmony_ci #Therefore s_client just continues to send its application data and sends 81e1051a39Sopenharmony_ci #its close_notify regardless. TLSProxy sees this and thinks that the 82e1051a39Sopenharmony_ci #connection was successful when in fact it was not. There isn't an easy fix 83e1051a39Sopenharmony_ci #for this, so leaving this test commented out for now. 84e1051a39Sopenharmony_ci} 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ciSKIP: { 87e1051a39Sopenharmony_ci skip "TLS <= 1.2 disabled", 2 88e1051a39Sopenharmony_ci if alldisabled(("ssl3", "tls1", "tls1_1", "tls1_2")); 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci #Test 3: Corrupting a CertVerify signature in <=TLSv1.2 should fail 91e1051a39Sopenharmony_ci $proxy->clear(); 92e1051a39Sopenharmony_ci $testtype = CORRUPT_CLIENT_CERT_VERIFY; 93e1051a39Sopenharmony_ci $proxy->serverflags("-Verify 5"); 94e1051a39Sopenharmony_ci $proxy->clientflags("-no_tls1_3 -cert ".srctop_file("apps", "server.pem")); 95e1051a39Sopenharmony_ci $proxy->start(); 96e1051a39Sopenharmony_ci ok(TLSProxy::Message->fail, "Corrupt <=TLSv1.2 CertVerify"); 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci SKIP: { 99e1051a39Sopenharmony_ci skip "DH disabled", 1 if disabled("dh"); 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci #Test 4: Corrupting a ServerKeyExchange signature in <=TLSv1.2 should 102e1051a39Sopenharmony_ci #fail 103e1051a39Sopenharmony_ci $proxy->clear(); 104e1051a39Sopenharmony_ci $testtype = CORRUPT_TLS1_2_SERVER_KEY_EXCHANGE; 105e1051a39Sopenharmony_ci $proxy->clientflags("-no_tls1_3"); 106e1051a39Sopenharmony_ci $proxy->cipherc('DHE-RSA-AES128-SHA'); 107e1051a39Sopenharmony_ci $proxy->ciphers('DHE-RSA-AES128-SHA'); 108e1051a39Sopenharmony_ci $proxy->start(); 109e1051a39Sopenharmony_ci ok(TLSProxy::Message->fail, "Corrupt <=TLSv1.2 ServerKeyExchange"); 110e1051a39Sopenharmony_ci } 111e1051a39Sopenharmony_ci} 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_cisub signature_filter 114e1051a39Sopenharmony_ci{ 115e1051a39Sopenharmony_ci my $proxy = shift; 116e1051a39Sopenharmony_ci my $flight; 117e1051a39Sopenharmony_ci my $mt = TLSProxy::Message::MT_CERTIFICATE_VERIFY; 118e1051a39Sopenharmony_ci 119e1051a39Sopenharmony_ci if ($testtype == CORRUPT_SERVER_CERT_VERIFY 120e1051a39Sopenharmony_ci || $testtype == CORRUPT_TLS1_2_SERVER_KEY_EXCHANGE 121e1051a39Sopenharmony_ci || (!disabled("tls1_3") && $testtype == NO_CORRUPTION)) { 122e1051a39Sopenharmony_ci $flight = 1; 123e1051a39Sopenharmony_ci } else { 124e1051a39Sopenharmony_ci $flight = 2; 125e1051a39Sopenharmony_ci } 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci # We're only interested in the initial server flight 128e1051a39Sopenharmony_ci return if ($proxy->flight != $flight); 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ci $mt = TLSProxy::Message::MT_SERVER_KEY_EXCHANGE 131e1051a39Sopenharmony_ci if ($testtype == CORRUPT_TLS1_2_SERVER_KEY_EXCHANGE); 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ci foreach my $message (@{$proxy->message_list}) { 134e1051a39Sopenharmony_ci if ($message->mt == $mt) { 135e1051a39Sopenharmony_ci my $sig = $message->signature(); 136e1051a39Sopenharmony_ci my $sigbase = substr($sig, 0, -1); 137e1051a39Sopenharmony_ci my $sigend = unpack("C", substr($sig, -1)); 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci #Flip bits in final byte of signature to corrupt the sig 140e1051a39Sopenharmony_ci $sigend ^= 0xff unless $testtype == NO_CORRUPTION; 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci $message->signature($sigbase.pack("C", $sigend)); 143e1051a39Sopenharmony_ci $message->repack(); 144e1051a39Sopenharmony_ci } 145e1051a39Sopenharmony_ci } 146e1051a39Sopenharmony_ci} 147