1
1
import type { Config as QuicheConfig } from './native/types' ;
2
2
import { quiche } from './native' ;
3
-
3
+ import * as errors from './errors' ;
4
4
5
5
type QUICConfig = {
6
6
/**
@@ -133,11 +133,18 @@ const textDecoder = new TextDecoder('utf-8');
133
133
const textEncoder = new TextEncoder ( ) ;
134
134
135
135
function buildQuicheConfig ( config : QUICConfig ) : QuicheConfig {
136
-
137
- // This will be passed in as a Optional<Uint8Array>
138
-
139
- // This is a concatenated certificate authority certificates in
140
- // PEM format, separated by `\n`
136
+ if ( config . key != null && config . cert == null ) {
137
+ throw new errors . ErrorQUICConfig ( 'The cert option must be set when key is set' ) ;
138
+ } else if ( config . key == null && config . cert != null ) {
139
+ throw new errors . ErrorQUICConfig ( 'The key option must be set when cert is set' ) ;
140
+ } else if ( config . key != null && config . cert != null ) {
141
+ if ( Array . isArray ( config . key ) && Array . isArray ( config . cert ) ) {
142
+ if ( config . key . length !== config . cert . length ) {
143
+ throw new errors . ErrorQUICConfig ( 'The number of keys must match the number of certs' ) ;
144
+ }
145
+ }
146
+ }
147
+ // This is a concatenated CA certificates in PEM format
141
148
let caPEMBuffer : Uint8Array | undefined ;
142
149
if ( config . ca != null ) {
143
150
let caPEMString = '' ;
@@ -156,48 +163,51 @@ function buildQuicheConfig(config: QUICConfig): QuicheConfig {
156
163
}
157
164
caPEMBuffer = textEncoder . encode ( caPEMString ) ;
158
165
}
159
-
160
- // Setup: [keyPEM, keyPEM, keyPEM]
161
- // AND [certChainPem, certChainPEM, certChainPEM]
162
- // Then we pass it in
163
- // atm, i don't think this actually works
164
- // due to lack of this `SSL_CTX_add1_chain_cert` function
165
-
166
-
167
-
168
-
169
- // let certChainPem: Buffer | null = null;
170
- // let privKeyPem: Buffer | null = null;
171
- // if (config.tlsConfig != null && 'certChainPem' in config.tlsConfig) {
172
- // if (config.tlsConfig.certChainPem != null) {
173
- // certChainPem = Buffer.from(config.tlsConfig.certChainPem);
174
- // }
175
- // if (config.tlsConfig.privKeyPem != null) {
176
- // privKeyPem = Buffer.from(config.tlsConfig.privKeyPem);
177
- // }
178
- // }
179
-
180
-
181
- const quicheConfig : QuicheConfig = quiche . Config . withBoringSslCtx (
182
- certChainPem ,
183
- privKeyPem ,
184
- config . supportedPrivateKeyAlgos ?? null ,
185
- caBuffer ,
186
- config . verifyPeer ,
187
- ) ;
188
- if ( config . tlsConfig != null && 'certChainFromPemFile' in config . tlsConfig ) {
189
- if ( config . tlsConfig ?. certChainFromPemFile != null ) {
190
- quicheConfig . loadCertChainFromPemFile (
191
- config . tlsConfig . certChainFromPemFile ,
192
- ) ;
166
+ // This is an array of private keys in PEM format
167
+ let keyPEMBuffers : Array < Uint8Array > | undefined ;
168
+ if ( config . key != null ) {
169
+ let keyPEMs : Array < string > = [ ] ;
170
+ if ( typeof config . key === 'string' ) {
171
+ keyPEMs . push ( config . key . trim ( ) + '\n' ) ;
172
+ } else if ( config . key instanceof Uint8Array ) {
173
+ keyPEMs . push ( textDecoder . decode ( config . key ) . trim ( ) + '\n' ) ;
174
+ } else if ( Array . isArray ( config . key ) ) {
175
+ for ( const k of config . key ) {
176
+ if ( typeof k === 'string' ) {
177
+ keyPEMs . push ( k . trim ( ) + '\n' ) ;
178
+ } else {
179
+ keyPEMs . push ( textDecoder . decode ( k ) . trim ( ) + '\n' ) ;
180
+ }
181
+ }
193
182
}
194
- if ( config . tlsConfig ?. privKeyFromPemFile != null ) {
195
- quicheConfig . loadPrivKeyFromPemFile ( config . tlsConfig . privKeyFromPemFile ) ;
183
+ keyPEMBuffers = keyPEMs . map ( ( k ) => textEncoder . encode ( k ) ) ;
184
+ }
185
+ // This is an array of certificate chains in PEM format
186
+ let certChainPEMBuffers : Array < Uint8Array > | undefined ;
187
+ if ( config . cert != null ) {
188
+ let certChainPEMs : Array < string > = [ ] ;
189
+ if ( typeof config . cert === 'string' ) {
190
+ certChainPEMs . push ( config . cert . trim ( ) + '\n' ) ;
191
+ } else if ( config . cert instanceof Uint8Array ) {
192
+ certChainPEMs . push ( textDecoder . decode ( config . cert ) . trim ( ) + '\n' ) ;
193
+ } else if ( Array . isArray ( config . cert ) ) {
194
+ for ( const c of config . cert ) {
195
+ if ( typeof c === 'string' ) {
196
+ certChainPEMs . push ( c . trim ( ) + '\n' ) ;
197
+ } else {
198
+ certChainPEMs . push ( textDecoder . decode ( c ) . trim ( ) + '\n' ) ;
199
+ }
200
+ }
196
201
}
202
+ certChainPEMBuffers = certChainPEMs . map ( ( c ) => textEncoder . encode ( c ) ) ;
197
203
}
198
- // if (config.verifyFromPemFile != null) {
199
- // quicheConfig.loadVerifyLocationsFromFile(config.verifyFromPemFile);
200
- // }
204
+ const quicheConfig : QuicheConfig = quiche . Config . withBoringSslCtx (
205
+ config . verifyPeer ,
206
+ caPEMBuffer ,
207
+ keyPEMBuffers ,
208
+ certChainPEMBuffers ,
209
+ config . sigalgs ,
210
+ ) ;
201
211
if ( config . logKeys != null ) {
202
212
quicheConfig . logKeys ( ) ;
203
213
}
0 commit comments