tlspuffin/tls/
differential_rfc_violations.rs

1#![allow(dead_code)]
2/// This modules contains reproducer for RFC violations found with differential fuzzing
3use puffin::agent::{AgentDescriptor, AgentName};
4use puffin::put_registry::Factory;
5use puffin::trace::{Action, InputAction, OutputAction, Step, Trace};
6use puffin::{input_action, term};
7
8use crate::protocol::{
9    AgentType, MessageFlight, TLSDescriptorConfig, TLSProtocolBehavior, TLSProtocolTypes,
10    TLSVersion,
11};
12use crate::query::TlsQueryMatcher;
13use crate::tls::fn_impl::*;
14use crate::tls::rustls::msgs::enums::HandshakeType;
15
16/// The `differential_rfc` corpus: reproducers for RFC violations found via differential
17/// fuzzing.
18pub fn create_corpus(
19    put: &dyn Factory<TLSProtocolBehavior>,
20) -> Vec<(Trace<TLSProtocolTypes>, &'static str)> {
21    puffin::corpus!(
22        rfc_violation_alert_unsupported_cipher_suite: put.supports("tls13"),
23        rfc_violation_alert_bad_key_share: put.supports("tls13"),
24        rfc_violation_missing_alert_out_of_order_encrypted: put.supports("tls13"),
25        rfc_violation_bad_alert_non_requested_psk: put.supports("tls13"),
26        rfc_violation_incorrect_keyshare_after_hrr: put.supports("tls13"),
27        rfc_violation_no_alert_duplicate_extension: put.supports("tls13"),
28        rfc_violation_missing_supported_group: put.supports("tls13"),
29        rfc_violation_changing_cipher_after_hrr: put.supports("tls13"),
30        rfc_violation_no_change_after_hrr: put.supports("tls13"),
31        rfc_violation_incorrect_extension_in_sh: put.supports("tls13"),
32        rfc_violation_client_changing_cipher_hrr: put.supports("tls13"),
33    )
34}
35
36/// RFC violation triggering bad wolfSSL alert when SH contains unsupported cipher (HandshakeFailure
37/// instead of IllegalParameter)
38/// <https://github.com/wolfSSL/wolfssl/issues/9639>
39pub fn rfc_violation_alert_unsupported_cipher_suite(
40    client: AgentName,
41    _server: AgentName,
42) -> Trace<TLSProtocolTypes> {
43    let curve = term! {
44        fn_get_any_client_curve(
45            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))])
46        )
47    };
48
49    let server_hello = term! {
50          fn_server_hello(
51            fn_protocol_version12,
52            fn_new_random,
53            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
54            fn_cipher_suite13_aes_128_ccm_sha256,
55            fn_compression,
56            (fn_server_extensions_make(
57              (fn_server_extensions_append(
58                  (fn_server_extensions_append(
59                      fn_server_extensions_new,
60                      (fn_key_share_server_extension(
61                          (fn_key_share_deterministic((@curve)))
62                      ))
63                  )),
64                  fn_supported_versions13_server_extension
65            ))))
66        )
67    };
68
69    let server_hello_transcript = term! {
70        fn_append_transcript(
71            (fn_append_transcript(
72                fn_new_transcript,
73                ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]) // ClientHello
74            )),
75            (@server_hello) // plaintext ServerHello
76        )
77    };
78
79    let encrypted_extensions = term! {
80        fn_encrypted_extensions(
81            fn_server_extensions_new
82        )
83    };
84
85    let certificate = term! {
86        fn_certificate13(
87            (fn_payload_u8((fn_empty_bytes_vec))),
88            (fn_certificate_entries_make(
89                (fn_chain_append_certificate_entry(
90                  fn_empty_certificate_chain,
91                  (fn_certificate_entry_extensions(
92                    fn_alice_cert,
93                    (fn_cert_extensions_make(
94                        fn_cert_extensions_new
95                    ))
96            ))))
97            ))
98        )
99    };
100
101    let encrypted_extensions_transcript = term! {
102        fn_append_transcript(
103            (@server_hello_transcript),
104            (@encrypted_extensions) // plaintext EncryptedExtensions
105        )
106    };
107
108    let certificate_transcript = term! {
109        fn_append_transcript(
110            (@encrypted_extensions_transcript),
111            (@certificate) // plaintext Certificate
112        )
113    };
114
115    let certificate_verify = term! {
116        fn_certificate_verify(
117            fn_rsa_pss_signature_algorithm,
118            (fn_payload_u16(
119                (fn_rsa_sign_server(
120                    (@certificate_transcript),
121                    fn_alice_key,
122                    fn_rsa_pss_signature_algorithm
123                ))
124            ))
125        )
126    };
127
128    let certificate_verify_transcript = term! {
129        fn_append_transcript(
130            (@certificate_transcript),
131            (@certificate_verify) // plaintext CertificateVerify
132        )
133    };
134
135    let server_finished = term! {
136        fn_finished(
137            (fn_verify_data_server(
138                (@certificate_verify_transcript),
139                //(fn_server_finished_transcript(((client, 0)))),
140                (@server_hello_transcript),
141                (fn_get_client_key_share(((client, 0)), (@curve))),
142                (@curve),
143                fn_no_psk,
144                fn_new_random,
145                fn_cipher_suite13_aes_128_gcm_sha256
146            ))
147        )
148    };
149
150    let mut descriptor_config = TLSDescriptorConfig {
151        tls_version: TLSVersion::V1_3,
152        typ: AgentType::Client,
153        ..TLSDescriptorConfig::default()
154    };
155
156    descriptor_config.set_cipher_string(String::from(
157        "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
158    ));
159
160    Trace {
161        prior_traces: vec![],
162        descriptors: vec![AgentDescriptor::from_config(client, descriptor_config)],
163        steps: vec![
164            OutputAction::new_step(client),
165            Step {
166                agent: client,
167                action: Action::Input(input_action! { server_hello
168                }),
169            },
170            Step {
171                agent: client,
172                action: Action::Input(input_action! { term! {
173                        fn_encrypt_handshake(
174                            (@encrypted_extensions),
175                            (@server_hello_transcript),
176                            (fn_get_client_key_share(((client, 0)), (@curve))),
177                            fn_no_psk,
178                            (@curve),
179                            fn_false,
180                            fn_seq_0,  // sequence 0
181                            fn_new_random,
182                            fn_cipher_suite13_aes_128_gcm_sha256
183                        )
184                    }
185                }),
186            },
187            Step {
188                agent: client,
189                action: Action::Input(input_action! { term! {
190                        fn_encrypt_handshake(
191                            (@certificate),
192                            (@server_hello_transcript),
193                            (fn_get_client_key_share(((client, 0)), (@curve))),
194                            fn_no_psk,
195                            (@curve),
196                            fn_false,
197                            fn_seq_1,  // sequence 1
198                            fn_new_random,
199                            fn_cipher_suite13_aes_128_gcm_sha256
200                        )
201                    }
202                }),
203            },
204            Step {
205                agent: client,
206                action: Action::Input(input_action! { term! {
207                        fn_encrypt_handshake(
208                            (@certificate_verify),
209                            (@server_hello_transcript),
210                            (fn_get_client_key_share(((client, 0)), (@curve))),
211                            fn_no_psk,
212                            (@curve),
213                            fn_false,
214                            fn_seq_2,  // sequence 2
215                            fn_new_random,
216                            fn_cipher_suite13_aes_128_gcm_sha256
217                        )
218                    }
219                }),
220            },
221            Step {
222                agent: client,
223                action: Action::Input(input_action! { term! {
224                        fn_encrypt_handshake(
225                            (@server_finished),
226                            (@server_hello_transcript),
227                            (fn_get_client_key_share(((client, 0)), (@curve))),
228                            fn_no_psk,
229                            (@curve),
230                            fn_false,
231                            fn_seq_3,  // sequence 3
232                            fn_new_random,
233                            fn_cipher_suite13_aes_128_gcm_sha256
234                        )
235                    }
236                }),
237            },
238        ],
239        ..Default::default()
240    }
241}
242
243/// A wolfSSL TLS 1.3 Server receiving a ClientHello with a malformed KeyShare extension (e.g. with
244/// no key inside) returns a IllegalParameter alert instead of a DecodeError alert.
245/// <https://github.com/wolfSSL/wolfssl/issues/9640>
246pub fn rfc_violation_alert_bad_key_share(
247    _client: AgentName,
248    server: AgentName,
249) -> Trace<TLSProtocolTypes> {
250    let client_hello = term! {
251          fn_client_hello(
252            fn_protocol_version12,
253            fn_new_random,
254            fn_new_session_id,
255            (fn_cipher_suites_make(
256                 (fn_append_cipher_suite(
257                (fn_new_cipher_suites()),
258                fn_cipher_suite13_aes_128_gcm_sha256
259            )))),
260            fn_compressions,
261            (fn_client_extensions_make(
262                (fn_client_extensions_append(
263                (fn_client_extensions_append(
264                    (fn_client_extensions_append(
265                        (fn_client_extensions_append(
266                            fn_client_extensions_new,
267                            (fn_support_group_extension_make(
268                                (fn_support_group_extension_append(
269                                    fn_support_group_extension_new,
270                                    fn_named_group_secp384r1
271                                ))
272                            ))
273                        )),
274                        (fn_signature_algorithm_extension(
275                            (fn_supported_signature_schemes_extension_append(
276                                (fn_supported_signature_schemes_extension_append(
277                                    fn_supported_signature_schemes_extension_new,
278                                    fn_sig_scheme_rsa_pkcs1_sha256
279                                )),
280                                fn_sig_scheme_rsa_pss_sha256
281                            ))
282                        ))
283                    )),
284                    (fn_key_share_extension(
285                        fn_named_group_secp384r1,
286                        (fn_payload_u16(fn_empty_bytes_vec))
287                    ))
288                )),
289                fn_supported_versions13_extension
290            ))
291        )))
292    };
293
294    let server_hello_transcript = term! {
295        fn_append_transcript(
296            (fn_append_transcript(
297                fn_new_transcript,
298                (@client_hello) // ClientHello
299            )),
300            ((server, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ServerHello)))]) // plaintext ServerHello
301        )
302    };
303
304    // ((0, 1)) could be a CCS the server sends one
305
306    let extensions = term! {
307        fn_decrypt_handshake_flight(
308            ((server, 0)/MessageFlight), // The first flight of messages sent by the server
309            (@server_hello_transcript),
310            (fn_get_server_key_share(((server, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ServerHello)))]))),
311            fn_no_psk,
312            fn_named_group_secp384r1,
313            fn_true,
314            fn_seq_0,  // sequence 0
315            fn_new_random,
316            fn_cipher_suite13_aes_128_gcm_sha256
317        )
318    };
319
320    let encrypted_extensions = term! {
321        fn_find_encrypted_extensions((@extensions))
322    };
323
324    let encrypted_extension_transcript = term! {
325        fn_append_transcript(
326            (@server_hello_transcript),
327            (@encrypted_extensions) // plaintext Encrypted Extensions
328        )
329    };
330
331    let server_certificate = term! {
332        fn_find_server_certificate((@extensions))
333    };
334
335    let server_certificate_transcript = term! {
336        fn_append_transcript(
337            (@encrypted_extension_transcript),
338            (@server_certificate) // plaintext Server Certificate
339        )
340    };
341
342    let server_certificate_verify = term! {
343        fn_find_server_certificate_verify((@extensions))
344    };
345
346    let server_certificate_verify_transcript = term! {
347        fn_append_transcript(
348            (@server_certificate_transcript),
349            (@server_certificate_verify) // plaintext Server Certificate Verify
350        )
351    };
352
353    let server_finished = term! {
354        fn_find_server_finished((@extensions))
355    };
356
357    let server_finished_transcript = term! {
358        fn_append_transcript(
359            (@server_certificate_verify_transcript),
360            (@server_finished) // plaintext Server Handshake Finished
361        )
362    };
363
364    let client_finished = term! {
365        fn_finished(
366            (fn_verify_data(
367                (@server_finished_transcript),
368                (@server_hello_transcript),
369                (fn_get_server_key_share(((server, 0)))),
370                fn_no_psk,
371                fn_named_group_secp384r1,
372                fn_new_random,
373                fn_cipher_suite13_aes_128_gcm_sha256
374             ))
375        )
376    };
377
378    Trace {
379        prior_traces: vec![],
380        descriptors: vec![TLSDescriptorConfig::new_server(server, TLSVersion::V1_3)],
381        steps: vec![
382            Step {
383                agent: server,
384                action: Action::Input(input_action! { term! {
385                        @client_hello
386                    }
387                }),
388            },
389            OutputAction::new_step(server),
390            Step {
391                agent: server,
392                action: Action::Input(input_action! { term! {
393                        fn_encrypt_handshake(
394                            (@client_finished),
395                            (@server_hello_transcript),
396                            (fn_get_server_key_share(((server, 0)))),
397                            fn_no_psk,
398                            fn_named_group_secp384r1,
399                            fn_true,
400                            fn_seq_0,  // sequence 0
401                            fn_new_random,
402                            fn_cipher_suite13_aes_128_gcm_sha256
403                        )
404                    }
405                }),
406            },
407            OutputAction::new_step(server),
408        ],
409        ..Default::default()
410    }
411}
412
413/// A WolfSSL TLS 1.3 client receiving encrypted out of order messages will detect the error and log
414/// "Out of order message, fatal" without sending an alert.
415/// <https://github.com/wolfSSL/wolfssl/issues/9531>
416pub fn rfc_violation_missing_alert_out_of_order_encrypted(
417    client: AgentName,
418    _server: AgentName,
419) -> Trace<TLSProtocolTypes> {
420    let curve = term! {
421        fn_get_any_client_curve(
422            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))])
423        )
424    };
425
426    let server_hello = term! {
427          fn_server_hello(
428            fn_protocol_version12,
429            fn_new_random,
430            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
431            fn_cipher_suite13_aes_128_gcm_sha256,
432            fn_compression,
433            (fn_server_extensions_make(
434              (fn_server_extensions_append(
435                  (fn_server_extensions_append(
436                      fn_server_extensions_new,
437                      (fn_key_share_server_extension(
438                          (fn_key_share_deterministic((@curve)))
439                      ))
440                  )),
441                  fn_supported_versions13_server_extension
442            ))))
443        )
444    };
445
446    let server_hello_transcript = term! {
447        fn_append_transcript(
448            (fn_append_transcript(
449                fn_new_transcript,
450                ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]) // ClientHello
451            )),
452            (@server_hello) // plaintext ServerHello
453        )
454    };
455
456    let encrypted_extensions = term! {
457        fn_encrypted_extensions(
458            fn_server_extensions_new
459        )
460    };
461
462    let certificate = term! {
463        fn_certificate13(
464            (fn_payload_u8((fn_empty_bytes_vec))),
465            (fn_certificate_entries_make(
466                (fn_chain_append_certificate_entry(
467                  fn_empty_certificate_chain,
468                  (fn_certificate_entry_extensions(
469                    fn_alice_cert,
470                    (fn_cert_extensions_make(
471                        fn_cert_extensions_new
472                    ))
473            ))))
474            ))
475        )
476    };
477
478    let encrypted_extensions_transcript = term! {
479        fn_append_transcript(
480            (@server_hello_transcript),
481            (@encrypted_extensions) // plaintext EncryptedExtensions
482        )
483    };
484
485    let certificate_transcript = term! {
486        fn_append_transcript(
487            (@encrypted_extensions_transcript),
488            (@certificate) // plaintext Certificate
489        )
490    };
491
492    let certificate_verify = term! {
493        fn_certificate_verify(
494            fn_rsa_pss_signature_algorithm,
495            (fn_payload_u16(
496                (fn_rsa_sign_server(
497                    (@certificate_transcript),
498                    fn_alice_key,
499                    fn_rsa_pss_signature_algorithm
500                ))
501            ))
502        )
503    };
504
505    let certificate_verify_transcript = term! {
506        fn_append_transcript(
507            (@certificate_transcript),
508            (@certificate_verify) // plaintext CertificateVerify
509        )
510    };
511
512    let server_finished = term! {
513        fn_finished(
514            (fn_verify_data_server(
515                (@certificate_verify_transcript),
516                //(fn_server_finished_transcript(((client, 0)))),
517                (@server_hello_transcript),
518                (fn_get_client_key_share(((client, 0)), (@curve))),
519                (@curve),
520                fn_no_psk,
521                fn_new_random,
522                fn_cipher_suite13_aes_128_gcm_sha256
523            ))
524        )
525    };
526
527    Trace {
528        prior_traces: vec![],
529        descriptors: vec![AgentDescriptor::from_config(
530            client,
531            TLSDescriptorConfig {
532                tls_version: TLSVersion::V1_3,
533                typ: AgentType::Client,
534                ..TLSDescriptorConfig::default()
535            },
536        )],
537        steps: vec![
538            OutputAction::new_step(client),
539            Step {
540                agent: client,
541                action: Action::Input(input_action! { term! { @server_hello }
542                }),
543            },
544            Step {
545                agent: client,
546                action: Action::Input(input_action! { term! {
547                        fn_encrypt_handshake(
548                            (@server_hello),
549                            (@server_hello_transcript),
550                            (fn_get_client_key_share(((client, 0)), (@curve))),
551                            fn_no_psk,
552                            (@curve),
553                            fn_false,
554                            fn_seq_0,  // sequence 0
555                            fn_new_random,
556                            fn_cipher_suite13_aes_128_gcm_sha256
557                        )
558                    }
559                }),
560            },
561            Step {
562                agent: client,
563                action: Action::Input(input_action! { term! {
564                        fn_encrypt_handshake(
565                            (@certificate),
566                            (@server_hello_transcript),
567                            (fn_get_client_key_share(((client, 0)), (@curve))),
568                            fn_no_psk,
569                            (@curve),
570                            fn_false,
571                            fn_seq_1,  // sequence 1
572                            fn_new_random,
573                            fn_cipher_suite13_aes_128_gcm_sha256
574                        )
575                    }
576                }),
577            },
578            Step {
579                agent: client,
580                action: Action::Input(input_action! { term! {
581                        fn_encrypt_handshake(
582                            (@certificate_verify),
583                            (@server_hello_transcript),
584                            (fn_get_client_key_share(((client, 0)), (@curve))),
585                            fn_no_psk,
586                            (@curve),
587                            fn_false,
588                            fn_seq_2,  // sequence 2
589                            fn_new_random,
590                            fn_cipher_suite13_aes_128_gcm_sha256
591                        )
592                    }
593                }),
594            },
595            Step {
596                agent: client,
597                action: Action::Input(input_action! { term! {
598                        fn_encrypt_handshake(
599                            (@server_finished),
600                            (@server_hello_transcript),
601                            (fn_get_client_key_share(((client, 0)), (@curve))),
602                            fn_no_psk,
603                            (@curve),
604                            fn_false,
605                            fn_seq_3,  // sequence 3
606                            fn_new_random,
607                            fn_cipher_suite13_aes_128_gcm_sha256
608                        )
609                    }
610                }),
611            },
612        ],
613        ..Default::default()
614    }
615}
616
617/// A WolfSSL TLS 1.3 client receiving a ServerHello with a PresharedKey extension when the client
618/// hasn't requested the use of a preshared key, returns an IllegalParameter Alert instead of
619/// UnsupportedExtension
620/// <https://github.com/wolfSSL/wolfssl/issues/9503>
621pub fn rfc_violation_bad_alert_non_requested_psk(
622    client: AgentName,
623    _server: AgentName,
624) -> Trace<TLSProtocolTypes> {
625    let curve = term! {
626        fn_get_any_client_curve(
627            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))])
628        )
629    };
630
631    let server_hello = term! {
632          fn_server_hello(
633            fn_protocol_version12,
634            fn_new_random,
635            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
636            fn_cipher_suite13_aes_128_gcm_sha256,
637            fn_compression,
638            (fn_server_extensions_make(
639              (fn_server_extensions_append(
640                  (fn_server_extensions_append(
641                      (fn_server_extensions_append(
642                          fn_server_extensions_new,
643                          (fn_key_share_server_extension(
644                              (fn_key_share_deterministic((@curve)))
645                          ))
646                      )),
647                      (fn_preshared_keys_server_extension((fn_u32_to_u16((fn_u64_to_u32(fn_seq_5))))))
648                  )),
649                  fn_supported_versions13_server_extension
650            ))))
651        )
652    };
653
654    Trace {
655        prior_traces: vec![],
656        descriptors: vec![AgentDescriptor::from_config(
657            client,
658            TLSDescriptorConfig {
659                tls_version: TLSVersion::V1_3,
660                typ: AgentType::Client,
661                ..TLSDescriptorConfig::default()
662            },
663        )],
664        steps: vec![
665            OutputAction::new_step(client),
666            Step {
667                agent: client,
668                action: Action::Input(input_action! { server_hello
669                }),
670            },
671        ],
672        ..Default::default()
673    }
674}
675
676/// A WolfSSL TLS 1.3 server sending a HelloRetryRequest requesting a specific KeyShare can accept a
677/// second ClientHello with a KeyShare not present in the HelloRetryRequest.
678/// <https://github.com/wolfSSL/wolfssl/issues/9362>
679pub fn rfc_violation_incorrect_keyshare_after_hrr(server: AgentName) -> Trace<TLSProtocolTypes> {
680    let client_hello_1 = term! {
681          fn_client_hello(
682            fn_protocol_version12,
683            fn_new_random,
684            fn_new_session_id,
685            (fn_cipher_suites_make(
686                 (fn_append_cipher_suite(
687                (fn_new_cipher_suites()),
688                fn_cipher_suite13_aes_128_gcm_sha256
689            )))),
690            fn_compressions,
691            (fn_client_extensions_make(
692                (fn_client_extensions_append(
693                (fn_client_extensions_append(
694                    (fn_client_extensions_append(
695                        (fn_client_extensions_append(
696                            fn_client_extensions_new,
697                            (fn_support_group_extension_make(
698                                (fn_support_group_extension_append(
699                                    (fn_support_group_extension_append(
700                                        fn_support_group_extension_new,
701                                        fn_named_group_x25519
702                                    )),
703                                    fn_named_group_secp256r1
704                                ))
705                            ))
706                        )),
707                        (fn_signature_algorithm_extension(
708                            (fn_supported_signature_schemes_extension_append(
709                                (fn_supported_signature_schemes_extension_append(
710                                    fn_supported_signature_schemes_extension_new,
711                                    fn_sig_scheme_rsa_pkcs1_sha256
712                                )),
713                                fn_sig_scheme_rsa_pss_sha256
714                            ))
715                        ))
716                    )),
717                    (fn_key_share_extension_make(
718                        (fn_key_share_extension_append(
719                            fn_key_share_extension_new,
720                            (fn_key_share_deterministic(fn_named_group_x25519))
721                        ))
722                    ))
723                )),
724                fn_supported_versions13_extension
725            ))
726        )))
727    };
728
729    let client_hello_2 = term! {
730          fn_client_hello(
731            fn_protocol_version12,
732            fn_new_random,
733            fn_new_session_id,
734            (fn_cipher_suites_make(
735                 (fn_append_cipher_suite(
736                (fn_new_cipher_suites()),
737                fn_cipher_suite13_aes_128_gcm_sha256
738            )))),
739            fn_compressions,
740            (fn_client_extensions_make(
741                (fn_client_extensions_append(
742                (fn_client_extensions_append(
743                    (fn_client_extensions_append(
744                        (fn_client_extensions_append(
745                            fn_client_extensions_new,
746                            (fn_support_group_extension_make(
747                                (fn_support_group_extension_append(
748                                    fn_support_group_extension_new,
749                                    fn_named_group_secp384r1
750                                ))
751                            ))
752                        )),
753                        (fn_signature_algorithm_extension(
754                            (fn_supported_signature_schemes_extension_append(
755                                (fn_supported_signature_schemes_extension_append(
756                                    fn_supported_signature_schemes_extension_new,
757                                    fn_sig_scheme_rsa_pkcs1_sha256
758                                )),
759                                fn_sig_scheme_rsa_pss_sha256
760                            ))
761                        ))
762                    )),
763                    (fn_key_share_extension_make(
764                        (fn_key_share_extension_append(
765                            fn_key_share_extension_new,
766                            (fn_key_share_deterministic(fn_named_group_secp384r1))
767                        ))
768                    ))
769                )),
770                fn_supported_versions13_extension
771            ))
772        )))
773    };
774
775    Trace {
776        prior_traces: vec![],
777        descriptors: vec![AgentDescriptor::from_config(
778            server,
779            TLSDescriptorConfig {
780                tls_version: TLSVersion::V1_3,
781                typ: AgentType::Server,
782                groups: Some(String::from("P-256:P-384")),
783                ..TLSDescriptorConfig::default()
784            },
785        )],
786        steps: vec![
787            Step {
788                agent: server,
789                action: Action::Input(input_action! { term! {
790                        @client_hello_1
791                    }
792                }),
793            },
794            OutputAction::new_step(server),
795            Step {
796                agent: server,
797                action: Action::Input(input_action! { term! {
798                        @client_hello_2
799                    }
800                }),
801            },
802            OutputAction::new_step(server),
803        ],
804        ..Default::default()
805    }
806}
807
808/// A WolfSSL TLS 1.3 client receiving a ServerHello containing a duplicated extension (e.g. two
809/// SupportedVersions) abort the connection but doesn't send an Alert.
810/// <https://github.com/wolfSSL/wolfssl/issues/9520>
811pub fn rfc_violation_no_alert_duplicate_extension(
812    client: AgentName,
813    _server: AgentName,
814) -> Trace<TLSProtocolTypes> {
815    let curve = term! {
816        fn_get_any_client_curve(
817            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))])
818        )
819    };
820
821    let server_hello = term! {
822          fn_server_hello(
823            fn_protocol_version12,
824            fn_new_random,
825            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
826            fn_cipher_suite13_aes_128_gcm_sha256,
827            fn_compression,
828            (fn_server_extensions_make(
829              (fn_server_extensions_append(
830                  (fn_server_extensions_append(
831                      (fn_server_extensions_append(
832                          fn_server_extensions_new,
833                          (fn_key_share_server_extension(
834                              (fn_key_share_deterministic((@curve)))
835                          ))
836                      )),
837                      fn_supported_versions13_server_extension
838                  )),
839                  fn_supported_versions13_server_extension
840            ))))
841        )
842    };
843
844    Trace {
845        prior_traces: vec![],
846        descriptors: vec![AgentDescriptor::from_config(
847            client,
848            TLSDescriptorConfig {
849                tls_version: TLSVersion::V1_3,
850                typ: AgentType::Client,
851                ..TLSDescriptorConfig::default()
852            },
853        )],
854        steps: vec![
855            OutputAction::new_step(client),
856            Step {
857                agent: client,
858                action: Action::Input(input_action! { server_hello
859                }),
860            },
861        ],
862        ..Default::default()
863    }
864}
865
866/// WolfSSL can respond to a ClientHello without a SupportedGroup extension if the CH contains a
867/// keyshare. This behavior happens only when setting the list of supported groups on the server
868/// using wolfSSL_set_groups or wolfSSL_CTX_set1_groups_list or using --force-curve in the example
869/// CLI. <https://github.com/wolfSSL/wolfssl/issues/9521>
870/// <https://github.com/wolfSSL/wolfssl/issues/9247>
871pub fn rfc_violation_missing_supported_group(server: AgentName) -> Trace<TLSProtocolTypes> {
872    let client_hello = term! {
873          fn_client_hello(
874            fn_protocol_version12,
875            fn_new_random,
876            fn_new_session_id,
877            (fn_cipher_suites_make(
878                 (fn_append_cipher_suite(
879                (fn_new_cipher_suites()),
880                fn_cipher_suite13_aes_128_gcm_sha256
881            )))),
882            fn_compressions,
883            (fn_client_extensions_make(
884                (fn_client_extensions_append(
885                    (fn_client_extensions_append(
886                        (fn_client_extensions_append(
887                            fn_client_extensions_new,
888                            (fn_signature_algorithm_extension(
889                                (fn_supported_signature_schemes_extension_append(
890                                    (fn_supported_signature_schemes_extension_append(
891                                        fn_supported_signature_schemes_extension_new,
892                                        fn_sig_scheme_rsa_pkcs1_sha256
893                                    )),
894                                    fn_sig_scheme_rsa_pss_sha256
895                                ))
896                            ))
897                        )),
898                    (fn_key_share_extension_make(
899                        (fn_key_share_extension_append(
900                            fn_key_share_extension_new,
901                            (fn_key_share_deterministic(fn_named_group_secp384r1))
902                        ))
903                    ))
904                )),
905                fn_supported_versions13_extension
906            ))
907        )))
908    };
909
910    Trace {
911        prior_traces: vec![],
912        descriptors: vec![AgentDescriptor::from_config(
913            server,
914            TLSDescriptorConfig {
915                tls_version: TLSVersion::V1_3,
916                typ: AgentType::Server,
917                groups: Some(String::from("P-256:P-384")),
918                ..TLSDescriptorConfig::default()
919            },
920        )],
921        steps: vec![Step {
922            agent: server,
923            action: Action::Input(input_action! { term! {
924                    @client_hello
925                }
926            }),
927        }],
928        ..Default::default()
929    }
930}
931
932/// A WolfSSL TLS 1.3 client receiving a HelloRetryRequest followed by a ServerHello with another
933/// cipher (eg. using TLS_AES_256_GCM_SHA384 in HRR and TLS_AES_128_GCM_SHA256 in ServerHello), will
934/// continue the handshake while it should reject the ServerHello with an appropriate error.
935/// <https://github.com/wolfSSL/wolfssl/issues/9331>
936pub fn rfc_violation_changing_cipher_after_hrr(client: AgentName) -> Trace<TLSProtocolTypes> {
937    let curve = term! {
938        fn_get_any_client_curve(
939            ((client, 1)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))])
940        )
941    };
942
943    let server_hrr = term! {
944        fn_hello_retry_request(
945            fn_protocol_version12,
946            fn_hello_retry_request_random,
947            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
948            fn_cipher_suite13_aes_128_gcm_sha256,
949            fn_compressions,
950            (fn_hello_retry_extensions_make(
951                (fn_hello_retry_extensions_append(
952                    (fn_hello_retry_extensions_append(
953                        fn_hello_retry_extensions_new,
954                    fn_supported_versions13_hello_retry_extension
955                    )),
956                    // ask the client to use P384 curve for the second client hello
957                    (fn_key_share_hello_retry_extension(fn_named_group_secp384r1))
958                ))
959            ))
960        )
961    };
962
963    let server_hello = term! {
964          fn_server_hello(
965            fn_protocol_version12,
966            fn_new_random,
967            ((client, 1)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
968            fn_cipher_suite13_aes_256_gcm_sha384,
969            fn_compression,
970            (fn_server_extensions_make(
971              (fn_server_extensions_append(
972                  (fn_server_extensions_append(
973                      fn_server_extensions_new,
974                      (fn_key_share_server_extension(
975                          (fn_key_share_deterministic((@curve)))
976                      ))
977                  )),
978                  fn_supported_versions13_server_extension
979            ))))
980        )
981    };
982
983    Trace {
984        prior_traces: vec![],
985        descriptors: vec![AgentDescriptor::from_config(
986            client,
987            TLSDescriptorConfig {
988                tls_version: TLSVersion::V1_3,
989                typ: AgentType::Client,
990                ..TLSDescriptorConfig::default()
991            },
992        )],
993        steps: vec![
994            OutputAction::new_step(client),
995            Step {
996                agent: client,
997                action: Action::Input(input_action! { server_hrr }),
998            },
999            Step {
1000                agent: client,
1001                action: Action::Input(input_action! { server_hello }),
1002            },
1003        ],
1004        ..Default::default()
1005    }
1006}
1007
1008/// When receiving a HelloRetryRequest (ServerHello with magic random value) which should trigger no
1009/// change in the ClientHello (the HRR only contains a SupportedVersion extension), WolfSSL TLS 1.3
1010/// client sends a ClientHello that is identical to its first ClientHello.
1011/// <https://github.com/wolfSSL/wolfssl/issues/9247>
1012pub fn rfc_violation_no_change_after_hrr(client: AgentName) -> Trace<TLSProtocolTypes> {
1013    let server_hrr = term! {
1014        fn_hello_retry_request(
1015            fn_protocol_version12,
1016            fn_hello_retry_request_random,
1017            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
1018            fn_cipher_suite13_aes_128_gcm_sha256,
1019            fn_compressions,
1020            (fn_hello_retry_extensions_make(
1021                    (fn_hello_retry_extensions_append(
1022                        fn_hello_retry_extensions_new,
1023                    fn_supported_versions13_hello_retry_extension
1024                    ))
1025                ))
1026        )
1027    };
1028
1029    Trace {
1030        prior_traces: vec![],
1031        descriptors: vec![AgentDescriptor::from_config(
1032            client,
1033            TLSDescriptorConfig {
1034                tls_version: TLSVersion::V1_3,
1035                typ: AgentType::Client,
1036                ..TLSDescriptorConfig::default()
1037            },
1038        )],
1039        steps: vec![
1040            OutputAction::new_step(client),
1041            Step {
1042                agent: client,
1043                action: Action::Input(input_action! { server_hrr }),
1044            },
1045        ],
1046        ..Default::default()
1047    }
1048}
1049
1050/// An OpenSSL TLS 1.3 client receiving a ServerHello with a StatusRequest extension returns an
1051/// UnsupportedExtension Alert instead of an IllegalParameter alert
1052/// <https://github.com/openssl/openssl/issues/29353>
1053pub fn rfc_violation_incorrect_extension_in_sh(
1054    client: AgentName,
1055    _server: AgentName,
1056) -> Trace<TLSProtocolTypes> {
1057    let curve = term! {
1058        fn_get_any_client_curve(
1059            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))])
1060        )
1061    };
1062
1063    let server_hello = term! {
1064          fn_server_hello(
1065            fn_protocol_version12,
1066            fn_new_random,
1067            ((client, 0)[Some(TlsQueryMatcher::Handshake(Some(HandshakeType::ClientHello)))]),
1068            fn_cipher_suite13_aes_128_gcm_sha256,
1069            fn_compression,
1070            (fn_server_extensions_make(
1071              (fn_server_extensions_append(
1072                  (fn_server_extensions_append(
1073                      (fn_server_extensions_append(
1074                          fn_server_extensions_new,
1075                          (fn_key_share_server_extension(
1076                              (fn_key_share_deterministic((@curve)))
1077                          ))
1078                      )),
1079                    fn_status_request_server_extension
1080                  )),
1081                  fn_supported_versions13_server_extension
1082            ))))
1083        )
1084    };
1085
1086    Trace {
1087        prior_traces: vec![],
1088        descriptors: vec![AgentDescriptor::from_config(
1089            client,
1090            TLSDescriptorConfig {
1091                tls_version: TLSVersion::V1_3,
1092                typ: AgentType::Client,
1093                ..TLSDescriptorConfig::default()
1094            },
1095        )],
1096        steps: vec![
1097            OutputAction::new_step(client),
1098            Step {
1099                agent: client,
1100                action: Action::Input(input_action! { server_hello
1101                }),
1102            },
1103        ],
1104        ..Default::default()
1105    }
1106}
1107
1108/// A WolfSSL TLS 1.3 server receiving a second ClientHello after a HelloRetryRequest with another
1109/// cipher, after the Server has selected a cipher (eg. using `TLS_AES_256_GCM_SHA384` in first CH
1110/// and `TLS_AES_128_GCM_SHA256` in the second), will continue the handshake while it should
1111/// reject the second ClientHello with an appropriate error.
1112pub fn rfc_violation_client_changing_cipher_hrr(server: AgentName) -> Trace<TLSProtocolTypes> {
1113    let client_hello_1 = term! {
1114          fn_client_hello(
1115            fn_protocol_version12,
1116            fn_new_random,
1117            fn_new_session_id,
1118            (fn_cipher_suites_make(
1119                 (fn_append_cipher_suite(
1120                (fn_new_cipher_suites()),
1121                fn_cipher_suite13_aes_128_gcm_sha256
1122            )))),
1123            fn_compressions,
1124            (fn_client_extensions_make(
1125                (fn_client_extensions_append(
1126                (fn_client_extensions_append(
1127                    (fn_client_extensions_append(
1128                        (fn_client_extensions_append(
1129                            fn_client_extensions_new,
1130                            (fn_support_group_extension_make(
1131                                (fn_support_group_extension_append(
1132                                    (fn_support_group_extension_append(
1133                                        fn_support_group_extension_new,
1134                                        fn_named_group_x25519
1135                                    )),
1136                                    fn_named_group_secp384r1
1137                                ))
1138                            ))
1139                        )),
1140                        (fn_signature_algorithm_extension(
1141                            (fn_supported_signature_schemes_extension_append(
1142                                (fn_supported_signature_schemes_extension_append(
1143                                    fn_supported_signature_schemes_extension_new,
1144                                    fn_sig_scheme_rsa_pkcs1_sha256
1145                                )),
1146                                fn_sig_scheme_rsa_pss_sha256
1147                            ))
1148                        ))
1149                    )),
1150                    (fn_key_share_extension_make(
1151                        (fn_key_share_extension_append(
1152                            fn_key_share_extension_new,
1153                            (fn_key_share_deterministic(fn_named_group_x25519))
1154                        ))
1155                    ))
1156                )),
1157                fn_supported_versions13_extension
1158            ))
1159        )))
1160    };
1161
1162    let client_hello_2 = term! {
1163          fn_client_hello(
1164            fn_protocol_version12,
1165            fn_new_random,
1166            fn_new_session_id,
1167            (fn_cipher_suites_make(
1168                 (fn_append_cipher_suite(
1169                (fn_new_cipher_suites()),
1170                fn_cipher_suite13_aes_256_gcm_sha384
1171            )))),
1172            fn_compressions,
1173            (fn_client_extensions_make(
1174                (fn_client_extensions_append(
1175                (fn_client_extensions_append(
1176                    (fn_client_extensions_append(
1177                        (fn_client_extensions_append(
1178                            fn_client_extensions_new,
1179                            (fn_support_group_extension_make(
1180                                (fn_support_group_extension_append(
1181                                    fn_support_group_extension_new,
1182                                    fn_named_group_secp384r1
1183                                ))
1184                            ))
1185                        )),
1186                        (fn_signature_algorithm_extension(
1187                            (fn_supported_signature_schemes_extension_append(
1188                                (fn_supported_signature_schemes_extension_append(
1189                                    fn_supported_signature_schemes_extension_new,
1190                                    fn_sig_scheme_rsa_pkcs1_sha256
1191                                )),
1192                                fn_sig_scheme_rsa_pss_sha256
1193                            ))
1194                        ))
1195                    )),
1196                    (fn_key_share_extension_make(
1197                        (fn_key_share_extension_append(
1198                            fn_key_share_extension_new,
1199                            (fn_key_share_deterministic(fn_named_group_secp384r1))
1200                        ))
1201                    ))
1202                )),
1203                fn_supported_versions13_extension
1204            ))
1205        )))
1206    };
1207
1208    Trace {
1209        prior_traces: vec![],
1210        descriptors: vec![AgentDescriptor::from_config(
1211            server,
1212            TLSDescriptorConfig {
1213                tls_version: TLSVersion::V1_3,
1214                typ: AgentType::Server,
1215                groups: Some(String::from("P-256:P-384")),
1216                ..TLSDescriptorConfig::default()
1217            },
1218        )],
1219        steps: vec![
1220            Step {
1221                agent: server,
1222                action: Action::Input(input_action! { term! {
1223                        @client_hello_1
1224                    }
1225                }),
1226            },
1227            OutputAction::new_step(server),
1228            Step {
1229                agent: server,
1230                action: Action::Input(input_action! { term! {
1231                        @client_hello_2
1232                    }
1233                }),
1234            },
1235            OutputAction::new_step(server),
1236        ],
1237        ..Default::default()
1238    }
1239}