44import { Constrained , Struct , Uint16 } from "./dep.ts" ;
55import { Enum } from "./enum.js" ;
66import { sha256 } from "@noble/hashes/sha256"
7+ import { hkdfExpandLabel } from "./dep.ts"
8+ import { HandshakeType } from "./handshaketype.js" ;
79
810/**
911 * Enumeration of signature schemes as defined in RFC 8446.
@@ -79,6 +81,10 @@ export class SignatureScheme extends Enum {
7981 const signature = await signatureFrom ( clientHelloMsg , serverHelloMsg , certificateMsg , RSAprivateKey )
8082 return new CertificateVerify ( this , signature )
8183 }
84+ async certificateVerifyMsg ( clientHelloMsg , serverHelloMsg , certificateMsg , RSAprivateKey ) {
85+ const certificateVerify = await this . certificateVerify ( clientHelloMsg , serverHelloMsg , certificateMsg , RSAprivateKey ) ;
86+ return HandshakeType . CERTIFICATE_VERIFY . handshake ( certificateVerify ) ;
87+ }
8288}
8389
8490export class CertificateVerify extends Uint8Array {
@@ -101,44 +107,44 @@ export class CertificateVerify extends Uint8Array {
101107}
102108
103109export class Signature extends Constrained {
104- static from ( array ) {
110+ static from ( array ) {
105111 const copy = Uint8Array . from ( array ) ;
106112 const lengthOf = Uint16 . from ( copy ) . value ;
107113 return new Signature ( copy . subarray ( 2 , 2 + lengthOf ) )
108114 }
109- constructor ( opaque ) {
110- super ( 0 , 2 ** 16 - 1 , opaque )
115+ constructor ( opaque ) {
116+ super ( 0 , 2 ** 16 - 1 , opaque )
111117 this . opaque = opaque
112118 }
113119}
114120
115121async function signatureFrom ( clientHelloMsg , serverHelloMsg , certificateMsg , RSAprivateKey ) {
116122 const leading = Uint8Array . of (
117- //NOTE 64 space characters
118- 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 ,
119- //NOTE 'TLS 1.3, server CertificateVerify'
120- 84 , 76 , 83 , 32 , 49 , 46 , 51 , 44 , 32 , 115 , 101 , 114 , 118 , 101 , 114 , 32 , 67 , 101 , 114 , 116 , 105 , 102 , 105 , 99 , 97 , 116 , 101 , 86 , 101 , 114 , 105 , 102 , 121 ,
121- //NOTE single null char
122- 0
123+ //NOTE 64 space characters
124+ 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32 ,
125+ //NOTE 'TLS 1.3, server CertificateVerify'
126+ 84 , 76 , 83 , 32 , 49 , 46 , 51 , 44 , 32 , 115 , 101 , 114 , 118 , 101 , 114 , 32 , 67 , 101 , 114 , 116 , 105 , 102 , 105 , 99 , 97 , 116 , 101 , 86 , 101 , 114 , 105 , 102 , 121 ,
127+ //NOTE single null char
128+ 0
123129 )
124130 const transcriptHash = sha256 . create ( )
125- . update ( clientHelloMsg )
126- . update ( serverHelloMsg )
127- . update ( certificateMsg )
128- . digest ( ) ;
131+ . update ( clientHelloMsg )
132+ . update ( serverHelloMsg )
133+ . update ( certificateMsg )
134+ . digest ( ) ;
129135
130136 const data = Struct . createFrom (
131- leading ,
132- transcriptHash
137+ leading ,
138+ transcriptHash
133139 )
134140
135141 const signBuffer = await crypto . subtle . sign (
136- {
137- name : "RSA-PSS" , // RSAprivateKey.algorithm.name,
138- saltLength : 256 / 8
139- } ,
140- RSAprivateKey ,
141- data
142+ {
143+ name : "RSA-PSS" , // RSAprivateKey.algorithm.name,
144+ saltLength : 256 / 8
145+ } ,
146+ RSAprivateKey ,
147+ data
142148 )
143149
144150 /* const verify = await crypto.subtle.verify(
@@ -150,8 +156,49 @@ async function signatureFrom(clientHelloMsg, serverHelloMsg, certificateMsg, RSA
150156 sign,
151157 data
152158 ) */
159+ const signature = new Uint8Array ( signBuffer )
160+ signature . transcriptHash = transcriptHash ;
161+ return signature
162+ }
153163
154- return new Uint8Array ( signBuffer )
164+ export async function finished ( serverHS_secret , certificateVerifyMsg ) {
165+ const finishedKey = hkdfExpandLabel ( serverHS_secret , 'finished' , new Uint8Array , 32 ) ;
166+ const finishedKeyCrypto = await crypto . subtle . importKey (
167+ "raw" ,
168+ finishedKey ,
169+ {
170+ name : "HMAC" ,
171+ hash : { name : "SHA-256" } ,
172+ } ,
173+ true ,
174+ [ "sign" , "verify" ]
175+ ) ;
176+ const transcriptHash = sha256 . create ( )
177+ . update ( certificateVerifyMsg . message . signature . transcriptHash )
178+ . update ( certificateVerifyMsg . byte )
179+ . digest ( ) ;
180+
181+ const verify_data = await crypto . subtle . sign (
182+ { name : "HMAC" } ,
183+ finishedKeyCrypto ,
184+ transcriptHash
185+ )
186+
187+ /* const _test_verify_data = await crypto.subtle.verify(
188+ { name: "HMAC" },
189+ finishedKeyCrypto,
190+ verify_data,
191+ transcriptHash
192+ ) */
193+ verify_data . transcriptHash = transcriptHash ;
194+ return new Finished ( verify_data ) ;
195+ }
196+
197+ export class Finished extends Uint8Array {
198+ constructor ( verify_data ) {
199+ super ( verify_data ) ;
200+ this . verify_data = verify_data
201+ }
155202}
156203
157204// npx -p typescript tsc ./src/signaturescheme.js --declaration --allowJs --emitDeclarationOnly --lib ESNext --outDir ./dist
0 commit comments