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