@@ -567,6 +567,7 @@ pub enum ClientExtension {
567567 ServerCertificateType ( Vec < CertificateType > ) ,
568568 ClientCertificateType ( Vec < CertificateType > ) ,
569569
570+ // https://datatracker.ietf.org/doc/html/draft-beck-tls-trust-anchor-ids-01
570571 TrustAnchors ( Vec < TrustAnchorIdentifier > ) ,
571572
572573 Unknown ( UnknownExtension ) ,
@@ -754,6 +755,9 @@ pub enum ServerExtension {
754755 ServerCertificateType ( CertificateType ) ,
755756 ClientCertificateType ( CertificateType ) ,
756757
758+ // https://datatracker.ietf.org/doc/html/draft-beck-tls-trust-anchor-ids-01
759+ TrustAnchors ( Vec < TrustAnchorIdentifier > ) ,
760+
757761 Unknown ( UnknownExtension ) ,
758762}
759763
@@ -776,6 +780,7 @@ impl ServerExtension {
776780 Self :: EncryptedClientHello ( _) => ExtensionType :: EncryptedClientHello ,
777781 Self :: ServerCertificateType ( _) => ExtensionType :: ServerCertificateType ,
778782 Self :: ClientCertificateType ( _) => ExtensionType :: ClientCertificateType ,
783+ Self :: TrustAnchors ( _) => ExtensionType :: TrustAnchors ,
779784 Self :: Unknown ( ref r) => r. typ ,
780785 }
781786 }
@@ -805,6 +810,7 @@ impl Codec<'_> for ServerExtension {
805810 Self :: ClientCertificateType ( ref r) | Self :: ServerCertificateType ( ref r) => {
806811 r. encode ( nested. buf )
807812 }
813+ Self :: TrustAnchors ( ref r) => r. encode ( nested. buf ) ,
808814 Self :: Unknown ( ref r) => r. encode ( nested. buf ) ,
809815 }
810816 }
@@ -841,6 +847,7 @@ impl Codec<'_> for ServerExtension {
841847 ExtensionType :: ClientCertificateType => {
842848 Self :: ClientCertificateType ( CertificateType :: read ( & mut sub) ?)
843849 }
850+ ExtensionType :: TrustAnchors => Self :: TrustAnchors ( Vec :: read ( & mut sub) ?) ,
844851 _ => Self :: Unknown ( UnknownExtension :: read ( typ, & mut sub) ) ,
845852 } ;
846853
@@ -1544,16 +1551,18 @@ pub(crate) const CERTIFICATE_MAX_SIZE_LIMIT: usize = 0x1_0000;
15441551#[ derive( Debug ) ]
15451552pub ( crate ) enum CertificateExtension < ' a > {
15461553 CertificateStatus ( CertificateStatus < ' a > ) ,
1547- // TODO @max add support for client certificate type
1548- ServerCertificateType ( CertificateType ) ,
1554+ // TODO @max this is based on https://datatracker.ietf.org/doc/html/draft-davidben-tls-merkle-tree-certs-03#appendix-B.1
1555+ ClientCertificateType ( CertificateType ) ,
1556+ TrustAnchors ( Vec < TrustAnchorIdentifier > ) ,
15491557 Unknown ( UnknownExtension ) ,
15501558}
15511559
15521560impl < ' a > CertificateExtension < ' a > {
15531561 pub ( crate ) fn ext_type ( & self ) -> ExtensionType {
15541562 match * self {
15551563 Self :: CertificateStatus ( _) => ExtensionType :: StatusRequest ,
1556- Self :: ServerCertificateType ( _) => ExtensionType :: ServerCertificateType ,
1564+ Self :: ClientCertificateType ( _) => ExtensionType :: ServerCertificateType ,
1565+ Self :: TrustAnchors ( _) => ExtensionType :: TrustAnchors ,
15571566 Self :: Unknown ( ref r) => r. typ ,
15581567 }
15591568 }
@@ -1568,7 +1577,8 @@ impl<'a> CertificateExtension<'a> {
15681577 pub ( crate ) fn into_owned ( self ) -> CertificateExtension < ' static > {
15691578 match self {
15701579 Self :: CertificateStatus ( st) => CertificateExtension :: CertificateStatus ( st. into_owned ( ) ) ,
1571- Self :: ServerCertificateType ( sct) => CertificateExtension :: ServerCertificateType ( sct) ,
1580+ Self :: ClientCertificateType ( sct) => CertificateExtension :: ClientCertificateType ( sct) ,
1581+ Self :: TrustAnchors ( tai) => CertificateExtension :: TrustAnchors ( tai) ,
15721582 Self :: Unknown ( unk) => CertificateExtension :: Unknown ( unk) ,
15731583 }
15741584 }
@@ -1581,7 +1591,8 @@ impl<'a> Codec<'a> for CertificateExtension<'a> {
15811591 let nested = LengthPrefixedBuffer :: new ( ListLength :: U16 , bytes) ;
15821592 match * self {
15831593 Self :: CertificateStatus ( ref r) => r. encode ( nested. buf ) ,
1584- Self :: ServerCertificateType ( r) => r. encode ( nested. buf ) ,
1594+ Self :: ClientCertificateType ( r) => r. encode ( nested. buf ) ,
1595+ Self :: TrustAnchors ( ref r) => r. encode ( nested. buf ) ,
15851596 Self :: Unknown ( ref r) => r. encode ( nested. buf ) ,
15861597 }
15871598 }
@@ -1598,7 +1609,11 @@ impl<'a> Codec<'a> for CertificateExtension<'a> {
15981609 }
15991610 ExtensionType :: ServerCertificateType => {
16001611 let sct = CertificateType :: read ( & mut sub) ?;
1601- Self :: ServerCertificateType ( sct)
1612+ Self :: ClientCertificateType ( sct)
1613+ }
1614+ ExtensionType :: TrustAnchors => {
1615+ let tai = Vec :: < TrustAnchorIdentifier > :: read ( & mut sub) ?;
1616+ Self :: TrustAnchors ( tai)
16021617 }
16031618 _ => Self :: Unknown ( UnknownExtension :: read ( typ, & mut sub) ) ,
16041619 } ;
@@ -1660,9 +1675,7 @@ impl<'a> CertificateEntry<'a> {
16601675 }
16611676
16621677 pub ( crate ) fn has_unknown_extension ( & self ) -> bool {
1663- self . exts
1664- . iter ( )
1665- . any ( |ext| ext. ext_type ( ) != ExtensionType :: StatusRequest )
1678+ self . exts . iter ( ) . any ( |ext| matches ! ( ext, CertificateExtension :: Unknown ( _) ) )
16661679 }
16671680
16681681 pub ( crate ) fn ocsp_response ( & self ) -> Option < & [ u8 ] > {
@@ -1671,6 +1684,15 @@ impl<'a> CertificateEntry<'a> {
16711684 . find ( |ext| ext. ext_type ( ) == ExtensionType :: StatusRequest )
16721685 . and_then ( CertificateExtension :: cert_status)
16731686 }
1687+
1688+ pub ( crate ) fn trust_anchor_ext ( & self ) -> Option < & [ TrustAnchorIdentifier ] > {
1689+ self . exts
1690+ . first ( )
1691+ . and_then ( |ext| match ext {
1692+ CertificateExtension :: TrustAnchors ( tai) => Some ( tai. as_slice ( ) ) ,
1693+ _ => None ,
1694+ } )
1695+ }
16741696}
16751697
16761698impl < ' a > TlsListElement for CertificateEntry < ' a > {
@@ -1704,36 +1726,60 @@ impl<'a> CertificatePayloadTls13<'a> {
17041726 pub ( crate ) fn from_x509_certificates (
17051727 certs : impl Iterator < Item = & ' a CertificateDer < ' a > > ,
17061728 ocsp_response : Option < & ' a [ u8 ] > ,
1729+ matches_requested_trust_anchors : bool ,
17071730 ) -> Self {
1731+ let mut entries: Vec < _ > = certs
1732+ // zip certificate iterator with `ocsp_response` followed by
1733+ // an infinite-length iterator of `None`.
1734+ . zip (
1735+ ocsp_response
1736+ . into_iter ( )
1737+ . map ( Some )
1738+ . chain ( iter:: repeat ( None ) ) ,
1739+ )
1740+ . map ( |( cert, ocsp) | {
1741+ let mut e = CertificateEntry :: new ( cert. to_vec ( ) ) ;
1742+ if let Some ( ocsp) = ocsp {
1743+ e. exts
1744+ . push ( CertificateExtension :: CertificateStatus (
1745+ CertificateStatus :: new ( ocsp) ,
1746+ ) ) ;
1747+ }
1748+ e
1749+ } )
1750+ . collect ( ) ;
1751+
1752+ if matches_requested_trust_anchors {
1753+ entries
1754+ . first_mut ( )
1755+ . iter_mut ( )
1756+ . for_each ( |entry| {
1757+ entry
1758+ . exts
1759+ . push ( CertificateExtension :: TrustAnchors ( Vec :: new ( ) ) )
1760+ } ) ;
1761+ } ;
1762+
17081763 Self {
17091764 context : PayloadU8 :: empty ( ) ,
1710- entries : certs
1711- // zip certificate iterator with `ocsp_response` followed by
1712- // an infinite-length iterator of `None`.
1713- . zip (
1714- ocsp_response
1715- . into_iter ( )
1716- . map ( Some )
1717- . chain ( iter:: repeat ( None ) ) ,
1718- )
1719- . map ( |( cert, ocsp) | {
1720- let mut e = CertificateEntry :: new ( cert. to_vec ( ) ) ;
1721- if let Some ( ocsp) = ocsp {
1722- e. exts
1723- . push ( CertificateExtension :: CertificateStatus (
1724- CertificateStatus :: new ( ocsp) ,
1725- ) ) ;
1726- }
1727- e
1728- } )
1729- . collect ( ) ,
1765+ entries,
17301766 }
17311767 }
17321768
1733- pub ( crate ) fn from_bikeshed_certificate ( cert : & BikeshedCertificate < ' _ > ) -> Self {
1769+ pub ( crate ) fn from_bikeshed_certificate (
1770+ cert : & BikeshedCertificate < ' _ > ,
1771+ matches_requested_trust_anchors : bool ,
1772+ ) -> Self {
1773+ let mut entry = CertificateEntry :: new ( cert. encode ( ) ) ;
1774+ if matches_requested_trust_anchors {
1775+ entry
1776+ . exts
1777+ . push ( CertificateExtension :: TrustAnchors ( Vec :: new ( ) ) ) ;
1778+ }
1779+
17341780 Self {
17351781 context : PayloadU8 :: empty ( ) ,
1736- entries : vec ! [ CertificateEntry :: new ( cert . encode ( ) ) ] ,
1782+ entries : vec ! [ entry ] ,
17371783 }
17381784 }
17391785
0 commit comments