11// deno-lint-ignore-file no-slow-types
22// @ts -self-types="../type/signaturescheme.d.ts"
33
4- import { Constrained , Struct , Uint16 } from "./dep.ts" ;
4+ import { Uint16 } from "./dep.ts" ;
55import { Enum } from "./enum.js" ;
6- import { sha256 , sha384 , sha512 } from "@noble/hashes/sha2"
7- import { HandshakeType } from "./handshaketype.js" ;
86
97/**
108 * Enumeration of signature schemes as defined in RFC 8446.
@@ -113,150 +111,7 @@ export class SignatureScheme extends Enum {
113111 }
114112 }
115113
116- async certificateVerify ( clientHelloMsg , serverHelloMsg , encryptedExtensionsMsg , certificateMsg , RSAprivateKey ) {
117- const signature = await signatureFrom ( clientHelloMsg , serverHelloMsg , encryptedExtensionsMsg , certificateMsg , RSAprivateKey , this . algo )
118- return new CertificateVerify ( this , signature )
119- }
120- }
121-
122- export class CertificateVerify extends Uint8Array {
123- static fromMsg ( array ) {
124- const copy = Uint8Array . from ( array )
125- const algorithm = SignatureScheme . from ( copy . subarray ( 4 ) ) ;
126- const signature = Signature . from ( copy . subarray ( 6 ) )
127- return new CertificateVerify ( algorithm , signature . opaque )
128- }
129- static from = CertificateVerify . fromMsg
130- constructor ( signatureScheme , signature ) {
131- const signatureConstrained = new Signature ( signature ) ;
132- const struct = new Struct (
133- signatureScheme . Uint16 ,
134- signatureConstrained
135- )
136- super ( struct ) ;
137- this . algorithm = signatureScheme ;
138- this . signature = signature
139- return HandshakeType . CERTIFICATE_VERIFY . handshake ( this ) ;
140- }
141- }
142-
143- export class Signature extends Constrained {
144- static from ( array ) {
145- const copy = Uint8Array . from ( array ) ;
146- const lengthOf = Uint16 . from ( copy ) . value ;
147- return new Signature ( copy . subarray ( 2 , 2 + lengthOf ) )
148- }
149- constructor ( opaque ) {
150- super ( 0 , 2 ** 16 - 1 , opaque )
151- this . opaque = opaque
152- }
153- }
154-
155- async function signatureFrom ( clientHelloMsg , serverHelloMsg , encryptedExtensionsMsg , certificateMsg , RSAprivateKey , algo ) {
156- const leading = Uint8Array . of (
157- //NOTE 64 space characters
158- 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 ,
159- //NOTE 'TLS 1.3, server CertificateVerify'
160- 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 ,
161- //NOTE single null char
162- 0
163- )
164-
165- const hash = hashFromAlgo ( algo )
166-
167- const transcriptHash = hash
168- . update ( clientHelloMsg )
169- . update ( serverHelloMsg )
170- . update ( encryptedExtensionsMsg )
171- . update ( certificateMsg )
172- . digest ( ) ;
173-
174- const data = Struct . createFrom (
175- leading ,
176- transcriptHash
177- )
178-
179- const signBuffer = await crypto . subtle . sign (
180- algo ,
181- RSAprivateKey ,
182- data
183- )
184-
185- /* const verify = await crypto.subtle.verify(
186- {
187- name: "RSA-PSS",//'RSASSA-PKCS1-v1_5',
188- saltLength: 256 / 8
189- },
190- RSAPublicKey, //rsapublickey in Certificate
191- sign,
192- data
193- ) */
194- return new Uint8Array ( signBuffer )
195- }
196-
197- function hashFromAlgo ( algo ) {
198- let sha
199- const { hash, saltLength } = algo ;
200- if ( hash ) { sha = parseInt ( hash . split ( "-" ) [ 1 ] ) ; }
201- else if ( saltLength ) { sha = saltLength * 8 }
202- else { sha = 256 } ;
203- switch ( sha ) {
204- case 384 : return sha384 . create ( ) ;
205- case 512 : return sha512 . create ( ) ;
206- case 256 :
207- default :
208- return sha256 . create ( ) ;
209- }
210114}
211115
212- export async function finished ( finishedKey , sha = 256 , ...messages ) {
213- //const finishedKey = hkdfExpandLabel(serverHS_secret, 'finished', new Uint8Array, 32);
214- const finishedKeyCrypto = await crypto . subtle . importKey (
215- "raw" ,
216- finishedKey ,
217- {
218- name : "HMAC" ,
219- hash : { name : `SHA-${ sha } ` } ,
220- } ,
221- true ,
222- [ "sign" , "verify" ]
223- ) ;
224-
225- const hash = sha == 256 ? sha256 . create ( ) :
226- sha == 384 ? sha384 . create ( ) : sha256 . create ( ) ;
227-
228- const messagesStruct = Struct . createFrom ( ...messages ) ;
229-
230- const transcriptHash = hash
231- . update ( Uint8Array . from ( messagesStruct ) )
232- . digest ( ) ;
233-
234- const verify_data = await crypto . subtle . sign (
235- { name : "HMAC" } ,
236- finishedKeyCrypto ,
237- transcriptHash
238- )
239-
240- /* const _test_verify_data = await crypto.subtle.verify(
241- { name: "HMAC" },
242- finishedKeyCrypto,
243- verify_data,
244- transcriptHash
245- ) */
246- //verify_data.transcriptHash = transcriptHash;
247- return new Finished ( verify_data ) ;
248- }
249-
250- export class Finished extends Uint8Array {
251- static fromMsg ( message ) {
252- const copy = Uint8Array . from ( message )
253- return new Finished ( copy . subarray ( 4 ) )
254- }
255- constructor ( verify_data ) {
256- super ( verify_data ) ;
257- this . verify_data = verify_data
258- return HandshakeType . FINISHED . handshake ( this )
259- }
260- }
261116
262117// npx -p typescript tsc ./src/signaturescheme.js --declaration --allowJs --emitDeclarationOnly --lib ESNext --outDir ./dist
0 commit comments