Home | History | Annotate | Line # | Download | only in recipes
      1 #! /usr/bin/env perl
      2 # Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
      3 #
      4 # Licensed under the Apache License 2.0 (the "License").  You may not use
      5 # this file except in compliance with the License.  You can obtain a copy
      6 # in the file LICENSE in the source distribution or at
      7 # https://www.openssl.org/source/license.html
      8 
      9 use strict;
     10 use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
     11 use OpenSSL::Test::Utils;
     12 use TLSProxy::Proxy;
     13 
     14 my $test_name = "test_sslsigalgs";
     15 setup($test_name);
     16 
     17 plan skip_all => "TLSProxy isn't usable on $^O"
     18     if $^O =~ /^(VMS)$/;
     19 
     20 plan skip_all => "$test_name needs the dynamic engine feature enabled"
     21     if disabled("engine") || disabled("dynamic-engine");
     22 
     23 plan skip_all => "$test_name needs the sock feature enabled"
     24     if disabled("sock");
     25 
     26 plan skip_all => "$test_name needs TLS1.2 or TLS1.3 enabled"
     27     if disabled("tls1_2") && disabled("tls1_3");
     28 
     29 my $proxy = TLSProxy::Proxy->new(
     30     undef,
     31     cmdstr(app(["openssl"]), display => 1),
     32     srctop_file("apps", "server.pem"),
     33     (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
     34 );
     35 
     36 use constant {
     37     NO_SIG_ALGS_EXT => 0,
     38     EMPTY_SIG_ALGS_EXT => 1,
     39     NO_KNOWN_SIG_ALGS => 2,
     40     NO_PSS_SIG_ALGS => 3,
     41     PSS_ONLY_SIG_ALGS => 4,
     42     PURE_SIGALGS => 5,
     43     COMPAT_SIGALGS => 6,
     44     SIGALGS_CERT_ALL => 7,
     45     SIGALGS_CERT_PKCS => 8,
     46     SIGALGS_CERT_INVALID => 9,
     47     UNRECOGNIZED_SIGALGS_CERT => 10,
     48     UNRECOGNIZED_SIGALG => 11,
     49     RSAPSSPSS_SIG_ALG => 12,
     50     MLDSA65_SIG_ALG => 13
     51 };
     52 
     53 srand(70);
     54 sub randcase {
     55     my ($names) = @_;
     56     my @ret;
     57     foreach my $name (split(/:/, $names)) {
     58         my ($alg, $rest) = split(/(?=[+])/, $name, 2);
     59         $alg =~ s{([a-zA-Z])}{chr(ord($1)^(int(rand(2.0)) * 32))}eg;
     60         push @ret, $alg . ($rest // "");
     61     }
     62     return join(":", @ret);
     63 }
     64 
     65 #Note: Throughout this test we override the default ciphersuites where TLSv1.2
     66 #      is expected to ensure that a ServerKeyExchange message is sent that uses
     67 #      the sigalgs
     68 
     69 #Test 1: Default sig algs should succeed
     70 $proxy->clientflags("-no_tls1_3") if disabled("ec") && disabled("dh");
     71 $proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
     72 plan tests => 27;
     73 ok(TLSProxy::Message->success, "Default sigalgs");
     74 my $testtype;
     75 
     76 SKIP: {
     77     skip "TLSv1.3 disabled", 7
     78         if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
     79 
     80     $proxy->filter(\&sigalgs_filter);
     81 
     82     #Test 2: Sending no sig algs extension in TLSv1.3 should fail
     83     $proxy->clear();
     84     $testtype = NO_SIG_ALGS_EXT;
     85     $proxy->start();
     86     ok(TLSProxy::Message->fail, "No TLSv1.3 sigalgs");
     87 
     88     #Test 3: Sending an empty sig algs extension in TLSv1.3 should fail
     89     $proxy->clear();
     90     $testtype = EMPTY_SIG_ALGS_EXT;
     91     $proxy->start();
     92     ok(TLSProxy::Message->fail, "Empty TLSv1.3 sigalgs");
     93 
     94     #Test 4: Sending a list with no recognised sig algs in TLSv1.3 should fail
     95     $proxy->clear();
     96     $testtype = NO_KNOWN_SIG_ALGS;
     97     $proxy->start();
     98     ok(TLSProxy::Message->fail, "No known TLSv1.3 sigalgs");
     99 
    100     #Test 5: Sending a sig algs list without pss for an RSA cert in TLSv1.3
    101     #        should fail
    102     $proxy->clear();
    103     $testtype = NO_PSS_SIG_ALGS;
    104     $proxy->start();
    105     ok(TLSProxy::Message->fail, "No PSS TLSv1.3 sigalgs");
    106 
    107     #Test 6: Sending only TLSv1.3 PSS sig algs in TLSv1.3 should succeed
    108     #TODO(TLS1.3): Do we need to verify the cert to make sure its a PSS only
    109     #cert in this case?
    110     $proxy->clear();
    111     $testtype = PSS_ONLY_SIG_ALGS;
    112     $proxy->start();
    113     ok(TLSProxy::Message->success, "PSS only sigalgs in TLSv1.3");
    114 
    115     #Test 7: Modify the CertificateVerify sigalg from rsa_pss_rsae_sha256 to
    116     #        rsa_pss_pss_sha256. This should fail because the public key OID
    117     #        in the certificate is rsaEncryption and not rsassaPss
    118     $proxy->filter(\&modify_cert_verify_sigalg);
    119     $proxy->clear();
    120     $testtype = RSAPSSPSS_SIG_ALG;
    121     $proxy->start();
    122     ok(TLSProxy::Message->fail,
    123        "Mismatch between CertVerify sigalg and public key OID");
    124 
    125     SKIP: {
    126         skip "ML-DSA disabled", 1
    127             if disabled("ml-dsa");
    128 
    129         #Test 8: Modify the CertificateVerify sigalg from mldsa44 to mldsa65.
    130         #        This should fail because the public key in the certificate is
    131         #        for the wrong type of ML-DSA
    132         $proxy->filter(\&modify_cert_verify_sigalg);
    133         $proxy->clear();
    134         $testtype = MLDSA65_SIG_ALG;
    135         $proxy->serverflags("-cert " . srctop_file("test", "certs",
    136                                                    "server-ml-dsa-44-cert.pem") .
    137                             " -key " . srctop_file("test", "certs",
    138                                                    "server-ml-dsa-44-key.pem")),
    139         $proxy->start();
    140         ok(TLSProxy::Message->fail,
    141             "Mismatch between CertVerify sigalg and public key OID (ML-DSA)");
    142     }
    143 }
    144 
    145 SKIP: {
    146     skip "EC or TLSv1.3 disabled", 1
    147         if disabled("tls1_3") || disabled("ec");
    148     #Test 9: Sending a valid sig algs list but not including a sig type that
    149     #        matches the certificate should fail in TLSv1.3.
    150     $proxy->clear();
    151     $proxy->clientflags("-sigalgs ".randcase("ECDSA+SHA256"));
    152     $proxy->filter(undef);
    153     $proxy->start();
    154     ok(TLSProxy::Message->fail, "No matching TLSv1.3 sigalgs");
    155 }
    156 
    157 SKIP: {
    158     skip "EC, TLSv1.3 or TLSv1.2 disabled", 1
    159         if disabled("tls1_2") || disabled("tls1_3") || disabled("ec");
    160 
    161     #Test 10: Sending a full list of TLSv1.3 sig algs but negotiating TLSv1.2
    162     #         should succeed
    163     $proxy->clear();
    164     $proxy->serverflags("-no_tls1_3");
    165     $proxy->ciphers("ECDHE-RSA-AES128-SHA");
    166     $proxy->filter(undef);
    167     $proxy->start();
    168     ok(TLSProxy::Message->success, "TLSv1.3 client TLSv1.2 server");
    169 }
    170 
    171 SKIP: {
    172     skip "EC or TLSv1.2 disabled", 10 if disabled("tls1_2") || disabled("ec");
    173 
    174     $proxy->filter(\&sigalgs_filter);
    175 
    176     #Test 11: Sending no sig algs extension in TLSv1.2 will make it use
    177     #         SHA1, which is only supported at security level 0.
    178     $proxy->clear();
    179     $testtype = NO_SIG_ALGS_EXT;
    180     $proxy->clientflags("-no_tls1_3 -cipher DEFAULT:\@SECLEVEL=0");
    181     $proxy->ciphers("ECDHE-RSA-AES128-SHA:\@SECLEVEL=0");
    182     $proxy->start();
    183     ok(TLSProxy::Message->success, "No TLSv1.2 sigalgs seclevel 0");
    184 
    185     #Test 12: Sending no sig algs extension in TLSv1.2 should fail at security
    186     #         level 1 since it will try to use SHA1. Testing client at level 0,
    187     #         server level 1.
    188     $proxy->clear();
    189     $testtype = NO_SIG_ALGS_EXT;
    190     $proxy->clientflags("-tls1_2 -cipher DEFAULT:\@SECLEVEL=0");
    191     $proxy->ciphers("DEFAULT:\@SECLEVEL=1");
    192     $proxy->start();
    193     ok(TLSProxy::Message->fail, "No TLSv1.2 sigalgs server seclevel 1");
    194 
    195     #Test 13: Sending no sig algs extension in TLSv1.2 should fail at security
    196     #         level 1 since it will try to use SHA1. Testing client at level 1,
    197     #         server level 0.
    198     $proxy->clear();
    199     $testtype = NO_SIG_ALGS_EXT;
    200     $proxy->clientflags("-tls1_2 -cipher DEFAULT:\@SECLEVEL=1");
    201     $proxy->ciphers("DEFAULT:\@SECLEVEL=0");
    202     $proxy->start();
    203     ok(TLSProxy::Message->fail, "No TLSv1.2 sigalgs client seclevel 2");
    204 
    205     #Test 14: Sending an empty sig algs extension in TLSv1.2 should fail
    206     $proxy->clear();
    207     $testtype = EMPTY_SIG_ALGS_EXT;
    208     $proxy->clientflags("-no_tls1_3");
    209     $proxy->ciphers("ECDHE-RSA-AES128-SHA");
    210     $proxy->start();
    211     ok(TLSProxy::Message->fail, "Empty TLSv1.2 sigalgs");
    212 
    213     #Test 15: Sending a list with no recognised sig algs in TLSv1.2 should fail
    214     $proxy->clear();
    215     $testtype = NO_KNOWN_SIG_ALGS;
    216     $proxy->clientflags("-no_tls1_3");
    217     $proxy->ciphers("ECDHE-RSA-AES128-SHA");
    218     $proxy->start();
    219     ok(TLSProxy::Message->fail, "No known TLSv1.3 sigalgs");
    220 
    221     #Test 16: Sending a sig algs list without pss for an RSA cert in TLSv1.2
    222     #         should succeed
    223     $proxy->clear();
    224     $testtype = NO_PSS_SIG_ALGS;
    225     $proxy->clientflags("-no_tls1_3");
    226     $proxy->ciphers("ECDHE-RSA-AES128-SHA");
    227     $proxy->start();
    228     ok(TLSProxy::Message->success, "No PSS TLSv1.2 sigalgs");
    229 
    230     #Test 17: Sending only TLSv1.3 PSS sig algs in TLSv1.2 should succeed
    231     $proxy->clear();
    232     $testtype = PSS_ONLY_SIG_ALGS;
    233     $proxy->serverflags("-no_tls1_3");
    234     $proxy->ciphers("ECDHE-RSA-AES128-SHA");
    235     $proxy->start();
    236     ok(TLSProxy::Message->success, "PSS only sigalgs in TLSv1.2");
    237 
    238     #Test 18: Responding with a sig alg we did not send in TLSv1.2 should fail
    239     #         We send rsa_pkcs1_sha256 and respond with rsa_pss_rsae_sha256
    240     #         TODO(TLS1.3): Add a similar test to the TLSv1.3 section above
    241     #         when we have an API capable of configuring the TLSv1.3 sig algs
    242     $proxy->clear();
    243     $testtype = PSS_ONLY_SIG_ALGS;
    244     $proxy->clientflags("-no_tls1_3 -sigalgs ".randcase("RSA+SHA256"));
    245     $proxy->ciphers("ECDHE-RSA-AES128-SHA");
    246     $proxy->start();
    247     ok(TLSProxy::Message->fail, "Sigalg we did not send in TLSv1.2");
    248 
    249     #Test 19: Sending a valid sig algs list but not including a sig type that
    250     #         matches the certificate should fail in TLSv1.2
    251     $proxy->clear();
    252     $proxy->clientflags("-no_tls1_3 -sigalgs ".randcase("ECDSA+SHA256"));
    253     $proxy->ciphers("ECDHE-RSA-AES128-SHA");
    254     $proxy->filter(undef);
    255     $proxy->start();
    256     ok(TLSProxy::Message->fail, "No matching TLSv1.2 sigalgs");
    257     $proxy->filter(\&sigalgs_filter);
    258 
    259     #Test 20: No sig algs extension, ECDSA cert, will use SHA1,
    260     #         TLSv1.2 should succeed at security level 0
    261     $proxy->clear();
    262     $testtype = NO_SIG_ALGS_EXT;
    263     $proxy->clientflags("-no_tls1_3 -cipher DEFAULT:\@SECLEVEL=0");
    264     $proxy->serverflags("-cert " . srctop_file("test", "certs",
    265                                                "server-ecdsa-cert.pem") .
    266                         " -key " . srctop_file("test", "certs",
    267                                                "server-ecdsa-key.pem")),
    268     $proxy->ciphers("ECDHE-ECDSA-AES128-SHA:\@SECLEVEL=0");
    269     $proxy->start();
    270     ok(TLSProxy::Message->success, "No TLSv1.2 sigalgs, ECDSA");
    271 }
    272 
    273 my ($dsa_status, $sha1_status, $sha224_status);
    274 SKIP: {
    275     skip "TLSv1.3 disabled", 2
    276         if disabled("tls1_3")
    277            || disabled("dsa")
    278            || (disabled("ec") && disabled("dh"));
    279     #Test 21: signature_algorithms with 1.3-only ClientHello
    280     $testtype = PURE_SIGALGS;
    281     $dsa_status = $sha1_status = $sha224_status = 0;
    282     $proxy->clear();
    283     $proxy->clientflags("-tls1_3");
    284     $proxy->filter(\&modify_sigalgs_filter);
    285     $proxy->start();
    286     ok($dsa_status && $sha1_status && $sha224_status,
    287        "DSA and SHA1 sigalgs not sent for 1.3-only ClientHello");
    288 
    289     #Test 22: signature_algorithms with backwards compatible ClientHello
    290     SKIP: {
    291         skip "TLSv1.2 disabled", 1 if disabled("tls1_2");
    292         $testtype = COMPAT_SIGALGS;
    293         $dsa_status = $sha1_status = $sha224_status = 0;
    294         $proxy->clear();
    295         $proxy->clientflags("-cipher AES128-SHA\@SECLEVEL=0");
    296         $proxy->filter(\&modify_sigalgs_filter);
    297         $proxy->start();
    298         ok($dsa_status && $sha1_status && $sha224_status,
    299            "backwards compatible sigalg sent for compat ClientHello");
    300    }
    301 }
    302 
    303 SKIP: {
    304     skip "TLSv1.3 disabled", 5
    305         if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
    306     #Test 23: Insert signature_algorithms_cert that match normal sigalgs
    307     $testtype = SIGALGS_CERT_ALL;
    308     $proxy->clear();
    309     $proxy->filter(\&modify_sigalgs_cert_filter);
    310     $proxy->start();
    311     ok(TLSProxy::Message->success, "sigalgs_cert in TLSv1.3");
    312 
    313     #Test 24: Insert signature_algorithms_cert that forces PKCS#1 cert
    314     $testtype = SIGALGS_CERT_PKCS;
    315     $proxy->clear();
    316     $proxy->filter(\&modify_sigalgs_cert_filter);
    317     $proxy->start();
    318     ok(TLSProxy::Message->success, "sigalgs_cert in TLSv1.3 with PKCS#1 cert");
    319 
    320     #Test 25: Insert signature_algorithms_cert that fails
    321     $testtype = SIGALGS_CERT_INVALID;
    322     $proxy->clear();
    323     $proxy->filter(\&modify_sigalgs_cert_filter);
    324     $proxy->start();
    325     ok(TLSProxy::Message->fail, "No matching certificate for sigalgs_cert");
    326 
    327     #Test 26: Send an unrecognized signature_algorithms_cert
    328     #        We should be able to skip over the unrecognized value and use a
    329     #        valid one that appears later in the list.
    330     $proxy->clear();
    331     $proxy->filter(\&inject_unrecognized_sigalg);
    332     $proxy->clientflags("-tls1_3");
    333     # Use -xcert to get SSL_check_chain() to run in the cert_cb.  This is
    334     # needed to trigger (e.g.) CVE-2020-1967
    335     $proxy->serverflags("" .
    336             " -xcert " . srctop_file("test", "certs", "servercert.pem") .
    337             " -xkey " . srctop_file("test", "certs", "serverkey.pem") .
    338             " -xchain " . srctop_file("test", "certs", "rootcert.pem"));
    339     $testtype = UNRECOGNIZED_SIGALGS_CERT;
    340     $proxy->start();
    341     ok(TLSProxy::Message->success(), "Unrecognized sigalg_cert in ClientHello");
    342 
    343     #Test 27: Send an unrecognized signature_algorithms
    344     #        We should be able to skip over the unrecognized value and use a
    345     #        valid one that appears later in the list.
    346     $proxy->clear();
    347     $proxy->filter(\&inject_unrecognized_sigalg);
    348     $proxy->clientflags("-tls1_3");
    349     $proxy->serverflags("" .
    350             " -xcert " . srctop_file("test", "certs", "servercert.pem") .
    351             " -xkey " . srctop_file("test", "certs", "serverkey.pem") .
    352             " -xchain " . srctop_file("test", "certs", "rootcert.pem"));
    353     $testtype = UNRECOGNIZED_SIGALG;
    354     $proxy->start();
    355     ok(TLSProxy::Message->success(), "Unrecognized sigalg in ClientHello");
    356 }
    357 
    358 sub sigalgs_filter
    359 {
    360     my $proxy = shift;
    361 
    362     # We're only interested in the initial ClientHello
    363     if ($proxy->flight != 0) {
    364         return;
    365     }
    366 
    367     foreach my $message (@{$proxy->message_list}) {
    368         if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
    369             if ($testtype == NO_SIG_ALGS_EXT) {
    370                 $message->delete_extension(TLSProxy::Message::EXT_SIG_ALGS);
    371             } else {
    372                 my $sigalg;
    373                 if ($testtype == EMPTY_SIG_ALGS_EXT) {
    374                     $sigalg = pack "C2", 0x00, 0x00;
    375                 } elsif ($testtype == NO_KNOWN_SIG_ALGS) {
    376                     $sigalg = pack "C4", 0x00, 0x02, 0xff, 0xff;
    377                 } elsif ($testtype == NO_PSS_SIG_ALGS) {
    378                     #No PSS sig algs - just send rsa_pkcs1_sha256
    379                     $sigalg = pack "C4", 0x00, 0x02, 0x04, 0x01;
    380                 } else {
    381                     #PSS sig algs only - just send rsa_pss_rsae_sha256
    382                     $sigalg = pack "C4", 0x00, 0x02, 0x08, 0x04;
    383                 }
    384                 $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS, $sigalg);
    385             }
    386 
    387             $message->repack();
    388         }
    389     }
    390 }
    391 
    392 sub modify_sigalgs_filter
    393 {
    394     my $proxy = shift;
    395 
    396     # We're only interested in the initial ClientHello
    397     return if ($proxy->flight != 0);
    398 
    399     foreach my $message (@{$proxy->message_list}) {
    400         my $ext;
    401         my @algs;
    402 
    403         if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
    404             if ($testtype == PURE_SIGALGS) {
    405                 my $ok = 1;
    406                 $ext = $message->extension_data->{TLSProxy::Message::EXT_SIG_ALGS};
    407                 @algs = unpack('S>*', $ext);
    408                 # unpack will unpack the length as well
    409                 shift @algs;
    410                 foreach (@algs) {
    411                     if ($_ == TLSProxy::Message::SIG_ALG_DSA_SHA256
    412                         || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA384
    413                         || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA512
    414                         || $_ == TLSProxy::Message::OSSL_SIG_ALG_DSA_SHA224
    415                         || $_ == TLSProxy::Message::SIG_ALG_RSA_PKCS1_SHA1
    416                         || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA1
    417                         || $_ == TLSProxy::Message::SIG_ALG_ECDSA_SHA1) {
    418                         $ok = 0;
    419                     }
    420                 }
    421                 $sha1_status = $dsa_status = $sha224_status = 1 if ($ok);
    422             } elsif ($testtype == COMPAT_SIGALGS) {
    423                 $ext = $message->extension_data->{TLSProxy::Message::EXT_SIG_ALGS};
    424                 @algs = unpack('S>*', $ext);
    425                 # unpack will unpack the length as well
    426                 shift @algs;
    427                 foreach (@algs) {
    428                     if ($_ == TLSProxy::Message::SIG_ALG_DSA_SHA256
    429                         || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA384
    430                         || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA512) {
    431                         $dsa_status = 1;
    432                     }
    433                     if ($_ == TLSProxy::Message::SIG_ALG_RSA_PKCS1_SHA1
    434                         || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA1
    435                         || $_ == TLSProxy::Message::SIG_ALG_ECDSA_SHA1) {
    436                         $sha1_status = 1;
    437                     }
    438                     if ($_ == TLSProxy::Message::OSSL_SIG_ALG_RSA_PKCS1_SHA224
    439                         || $_ == TLSProxy::Message::OSSL_SIG_ALG_DSA_SHA224
    440                         || $_ == TLSProxy::Message::OSSL_SIG_ALG_ECDSA_SHA224) {
    441                         $sha224_status = 1;
    442                     }
    443                 }
    444             }
    445         }
    446     }
    447 }
    448 
    449 sub modify_sigalgs_cert_filter
    450 {
    451     my $proxy = shift;
    452 
    453     # We're only interested in the initial ClientHello
    454     if ($proxy->flight != 0) {
    455         return;
    456     }
    457 
    458     foreach my $message (@{$proxy->message_list}) {
    459         if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
    460             my $sigs;
    461             # two byte length at front of sigs, then two-byte sigschemes
    462             if ($testtype == SIGALGS_CERT_ALL) {
    463                 $sigs = pack "C26", 0x00, 0x18,
    464                              # rsa_pkcs_sha{256,512}  rsa_pss_rsae_sha{256,512}
    465                              0x04, 0x01,  0x06, 0x01,  0x08, 0x04,  0x08, 0x06,
    466                              # ed25518    ed448        rsa_pss_pss_sha{256,512}
    467                              0x08, 0x07,  0x08, 0x08,  0x08, 0x09,  0x08, 0x0b,
    468                              # ecdsa_secp{256,512}     rsa+sha1     ecdsa+sha1
    469                              0x04, 0x03,  0x06, 0x03,  0x02, 0x01,  0x02, 0x03;
    470             } elsif ($testtype == SIGALGS_CERT_PKCS) {
    471                 $sigs = pack "C10", 0x00, 0x08,
    472                              # rsa_pkcs_sha{256,384,512,1}
    473                              0x04, 0x01,  0x05, 0x01,  0x06, 0x01,  0x02, 0x01;
    474             } elsif ($testtype == SIGALGS_CERT_INVALID) {
    475                 $sigs = pack "C4", 0x00, 0x02,
    476                              # unregistered codepoint
    477                              0xb2, 0x6f;
    478             }
    479             $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS_CERT, $sigs);
    480             $message->repack();
    481         }
    482     }
    483 }
    484 
    485 sub modify_cert_verify_sigalg
    486 {
    487     my $proxy = shift;
    488 
    489     # We're only interested in the CertificateVerify
    490     if ($proxy->flight != 1) {
    491         return;
    492     }
    493 
    494     foreach my $message (@{$proxy->message_list}) {
    495         if ($message->mt == TLSProxy::Message::MT_CERTIFICATE_VERIFY) {
    496             if ($testtype == RSAPSSPSS_SIG_ALG) {
    497                 $message->sigalg(TLSProxy::Message::SIG_ALG_RSA_PSS_PSS_SHA256);
    498             } elsif ($testtype == MLDSA65_SIG_ALG) {
    499                 $message->sigalg(TLSProxy::Message::SIG_ALG_MLDSA65);
    500             }
    501             $message->repack();
    502         }
    503     }
    504 }
    505 
    506 sub inject_unrecognized_sigalg
    507 {
    508     my $proxy = shift;
    509     my $type;
    510 
    511     # We're only interested in the initial ClientHello
    512     if ($proxy->flight != 0) {
    513         return;
    514     }
    515     if ($testtype == UNRECOGNIZED_SIGALGS_CERT) {
    516         $type = TLSProxy::Message::EXT_SIG_ALGS_CERT;
    517     } elsif ($testtype == UNRECOGNIZED_SIGALG) {
    518         $type = TLSProxy::Message::EXT_SIG_ALGS;
    519     } else {
    520         return;
    521     }
    522 
    523     my $ext = pack "C8",
    524         0x00, 0x06, #Extension length
    525         0xfe, 0x18, #private use
    526         0x04, 0x01, #rsa_pkcs1_sha256
    527         0x08, 0x04; #rsa_pss_rsae_sha256;
    528     my $message = ${$proxy->message_list}[0];
    529     $message->set_extension($type, $ext);
    530     $message->repack;
    531 }
    532