77 dtlsconfig "github.com/pion/dtls/v3/internal/config"
88 dtlserrors "github.com/pion/dtls/v3/internal/errors"
99 dtlsflight "github.com/pion/dtls/v3/internal/flight"
10+ dtlscrypto "github.com/pion/dtls/v3/internal/handshakecrypto"
1011 dtlsstate "github.com/pion/dtls/v3/internal/state"
1112 "github.com/pion/dtls/v3/pkg/protocol/handshake"
1213)
@@ -16,7 +17,7 @@ import (
1617func VerifyAndAppendProtectedHandshakeCacheItems13 (
1718 transcript * Transcript ,
1819 state * dtlsstate.State13 ,
19- _ * dtlsconfig.HandshakeConfig ,
20+ cfg * dtlsconfig.HandshakeConfig ,
2021 cipherSuite dtlsconfig.CipherSuite ,
2122 items []* dtlsflight.HandshakeCacheItem ,
2223) error {
@@ -32,6 +33,7 @@ func VerifyAndAppendProtectedHandshakeCacheItems13(
3233 flight := protectedHandshakeFlight13 {
3334 transcript : working ,
3435 state : state ,
36+ cfg : cfg ,
3537 cipherSuite : cipherSuite ,
3638 }
3739 for _ , item := range items {
@@ -43,15 +45,26 @@ func VerifyAndAppendProtectedHandshakeCacheItems13(
4345 return dtlserrors .ErrVerifyDataMismatch
4446 }
4547
46- return transcript .replaceWith (working )
48+ if err := transcript .replaceWith (working ); err != nil {
49+ return err
50+ }
51+ if flight .hasCertificate {
52+ state .PeerCertificates = flight .peerCertificates
53+ }
54+
55+ return nil
4756}
4857
4958type protectedHandshakeFlight13 struct {
5059 transcript * Transcript
5160 state * dtlsstate.State13
61+ cfg * dtlsconfig.HandshakeConfig
5262 cipherSuite dtlsconfig.CipherSuite
5363
54- hasFinished bool
64+ peerCertificates [][]byte
65+ hasCertificate bool
66+ hasCertificateVerify bool
67+ hasFinished bool
5568}
5669
5770func (f * protectedHandshakeFlight13 ) process (item * dtlsflight.HandshakeCacheItem ) error {
@@ -60,19 +73,56 @@ func (f *protectedHandshakeFlight13) process(item *dtlsflight.HandshakeCacheItem
6073 return err
6174 }
6275
63- finished , ok := hs .Message .(* handshake.MessageFinished )
64- if ok {
65- return f .processFinished (item , hs , finished )
76+ switch msg := hs .Message .(type ) {
77+ case * handshake.MessageCertificate13 :
78+ return f .processCertificate (item , hs , msg )
79+ case * handshake.MessageCertificateVerify :
80+ return f .processCertificateVerify (item , hs , msg )
81+ case * handshake.MessageFinished :
82+ return f .processFinished (item , hs , msg )
83+ default :
84+ return f .append (item , hs )
85+ }
86+ }
87+
88+ func (f * protectedHandshakeFlight13 ) processCertificate (
89+ item * dtlsflight.HandshakeCacheItem ,
90+ h * handshake.Handshake ,
91+ certificate * handshake.MessageCertificate13 ,
92+ ) error {
93+ f .hasCertificate = true
94+ f .peerCertificates = rawCertificatesFromCertificate13 (certificate )
95+ if len (f .peerCertificates ) == 0 {
96+ return dtlserrors .ErrInvalidCertificate
97+ }
98+
99+ return f .append (item , h )
100+ }
101+
102+ func (f * protectedHandshakeFlight13 ) processCertificateVerify (
103+ item * dtlsflight.HandshakeCacheItem ,
104+ h * handshake.Handshake ,
105+ verify * handshake.MessageCertificateVerify ,
106+ ) error {
107+ if ! f .hasCertificate {
108+ return dtlserrors .ErrCertificateVerifyNoCertificate
109+ }
110+ if err := verifyServerCertificateVerify13 (f .transcript , f .cfg , verify , f .peerCertificates ); err != nil {
111+ return err
66112 }
113+ f .hasCertificateVerify = true
67114
68- return f .append (item , hs )
115+ return f .append (item , h )
69116}
70117
71118func (f * protectedHandshakeFlight13 ) processFinished (
72119 item * dtlsflight.HandshakeCacheItem ,
73120 h * handshake.Handshake ,
74121 finished * handshake.MessageFinished ,
75122) error {
123+ if f .hasCertificate && ! f .hasCertificateVerify {
124+ return dtlserrors .ErrClientCertificateNotVerified
125+ }
76126 if err := verifyServerFinished13 (f .transcript , f .state , f .cipherSuite , finished ); err != nil {
77127 return err
78128 }
@@ -127,6 +177,12 @@ func protectedHandshakeMessage13(typ handshake.Type, body []byte) (handshake.Mes
127177 switch typ {
128178 case handshake .TypeEncryptedExtensions :
129179 msg = & handshake.MessageEncryptedExtensions {}
180+ case handshake .TypeCertificateRequest :
181+ msg = & handshake.MessageCertificateRequest13 {}
182+ case handshake .TypeCertificate :
183+ msg = & handshake.MessageCertificate13 {}
184+ case handshake .TypeCertificateVerify :
185+ msg = & handshake.MessageCertificateVerify {}
130186 case handshake .TypeFinished :
131187 msg = & handshake.MessageFinished {}
132188 default :
@@ -139,6 +195,50 @@ func protectedHandshakeMessage13(typ handshake.Type, body []byte) (handshake.Mes
139195 return msg , nil
140196}
141197
198+ func rawCertificatesFromCertificate13 (certificate * handshake.MessageCertificate13 ) [][]byte {
199+ out := make ([][]byte , 0 , len (certificate .CertificateList ))
200+ for _ , entry := range certificate .CertificateList {
201+ out = append (out , append ([]byte (nil ), entry .CertificateData ... ))
202+ }
203+
204+ return out
205+ }
206+
207+ func verifyServerCertificateVerify13 (
208+ transcript * Transcript ,
209+ cfg * dtlsconfig.HandshakeConfig ,
210+ verify * handshake.MessageCertificateVerify ,
211+ peerCertificates [][]byte ,
212+ ) error {
213+ if cfg == nil {
214+ return dtlserrors .ErrNoAvailableSignatureSchemes
215+ }
216+ var validSignatureScheme bool
217+ for _ , alg := range cfg .LocalSignatureSchemes {
218+ if alg .Hash == verify .HashAlgorithm && alg .Signature == verify .SignatureAlgorithm {
219+ validSignatureScheme = true
220+
221+ break
222+ }
223+ }
224+ if ! validSignatureScheme {
225+ return dtlserrors .ErrNoAvailableSignatureSchemes
226+ }
227+
228+ input , err := CertificateVerifyInputFromTranscript (false , transcript )
229+ if err != nil {
230+ return err
231+ }
232+
233+ return dtlscrypto .VerifyCertificateVerify (
234+ input ,
235+ verify .HashAlgorithm ,
236+ verify .SignatureAlgorithm ,
237+ verify .Signature ,
238+ peerCertificates ,
239+ )
240+ }
241+
142242func verifyServerFinished13 (
143243 transcript * Transcript ,
144244 state * dtlsstate.State13 ,
0 commit comments