@fails-components/webtransport-transport-http3-quiche 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CMakeLists.txt CHANGED
@@ -743,8 +743,12 @@ third_party/quiche/quiche/quic/core/quic_stream_id_manager.cc
743
743
  third_party/quiche/quiche/quic/core/quic_stream_id_manager.h
744
744
  third_party/quiche/quiche/quic/core/quic_stream_priority.cc
745
745
  third_party/quiche/quiche/quic/core/quic_stream_priority.h
746
+ third_party/quiche/quiche/quic/core/quic_stream_send_buffer_base.cc
747
+ third_party/quiche/quiche/quic/core/quic_stream_send_buffer_base.h
746
748
  third_party/quiche/quiche/quic/core/quic_stream_send_buffer.cc
747
749
  third_party/quiche/quiche/quic/core/quic_stream_send_buffer.h
750
+ third_party/quiche/quiche/quic/core/quic_stream_send_buffer_inlining.cc
751
+ third_party/quiche/quiche/quic/core/quic_stream_send_buffer_inlining.h
748
752
  third_party/quiche/quiche/quic/core/quic_stream_sequencer.cc
749
753
  third_party/quiche/quiche/quic/core/quic_stream_sequencer.h
750
754
  third_party/quiche/quiche/quic/core/quic_stream_sequencer_buffer.cc
@@ -1 +1 @@
1
- {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../lib/socket.js"],"names":[],"mappings":"AAqEA;IACE;;OAEG;IAEH,kBAHW,OAAO,4BAA4B,EAAE,oBAAoB,GAAC,SAAS,EAc7E;IAVC,0CAA0C;IAE1C,WAFW,OAAO,YAAY,EAAE,MAAM,CAEZ;IAE1B,UAAqB;IACrB,oBAAuB;IAgCzB,qBASC;IAlCD,+BAGC;IAPC,iBAAoB;IACpB,gBAAmB;IAQrB;;OAEG;IAEH,mDAHW,OAAO,SAAS,EAAE,mBAAmB,WAiB/C;CAYF"}
1
+ {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../lib/socket.js"],"names":[],"mappings":"AAkFA;IACE;;OAEG;IAEH,kBAHW,OAAO,4BAA4B,EAAE,oBAAoB,GAAC,SAAS,EAc7E;IAVC,0CAA0C;IAE1C,WAFW,OAAO,YAAY,EAAE,MAAM,CAEZ;IAE1B,UAAqB;IACrB,oBAAuB;IAgCzB,qBASC;IAlCD,+BAGC;IAPC,iBAAoB;IACpB,gBAAmB;IAQrB;;OAEG;IAEH,mDAHW,OAAO,SAAS,EAAE,mBAAmB,WAiB/C;CAYF"}
package/lib/socket.js CHANGED
@@ -10,12 +10,24 @@ globalThis.FAILSsetTimeoutAlarm = (
10
10
  return setTimeout(alarm.fireJS.bind(alarm), delay)
11
11
  }
12
12
 
13
+ function convertToPem(/** @type {ArrayBuffer} */ cert) {
14
+ return (
15
+ '-----BEGIN CERTIFICATE-----\n' +
16
+ Buffer.from(new Uint8Array(cert)).toString('base64') +
17
+ '\n-----END CERTIFICATE-----\n'
18
+ )
19
+ }
20
+
13
21
  globalThis.FAILSVerifyProof = (
14
- /** @type {{ certs: string[]; hostname: string; server_config?: string; signature?: string; }} */ obj
22
+ /** @type {{ certs: ArrayBuffer[]; hostname: string; server_config?: string; signature?: string; }} */ obj
15
23
  ) => {
16
24
  try {
25
+ console.warn(
26
+ 'Non serverCertificateHashes certificate verification is an experimental feature for webtransport node client and not covered by tests and thus may be broken (DO NOT USE IN PRODUCTION)'
27
+ )
17
28
  if (obj.certs.length < 1) return false
18
- const leafcert = new X509Certificate(obj.certs[0])
29
+ const pem = convertToPem(obj.certs[0])
30
+ const leafcert = new X509Certificate(pem)
19
31
  if (!leafcert.checkHost(obj.hostname)) return false
20
32
 
21
33
  if (obj.server_config) {
@@ -36,7 +48,8 @@ globalThis.FAILSVerifyProof = (
36
48
 
37
49
  let curcert = leafcert
38
50
  for (let certnum = 1; certnum < obj.certs.length; certnum++) {
39
- const nextcert = new X509Certificate(obj.certs[certnum])
51
+ const nextpem = convertToPem(obj.certs[certnum])
52
+ const nextcert = new X509Certificate(nextpem)
40
53
 
41
54
  if (
42
55
  new Date(nextcert.validFrom) > curdate ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fails-components/webtransport-transport-http3-quiche",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "A component to add webtransport support (server and client) to node.js, transport using libquiche",
5
5
  "exports": {
6
6
  ".": {
@@ -38,6 +38,7 @@
38
38
  #include "quiche/quic/core/quic_udp_socket.h"
39
39
  #include "quiche/quic/tools/quic_url.h"
40
40
  #include "quiche/common/quiche_text_utils.h"
41
+ #include "quiche/web_transport/web_transport_headers.h"
41
42
 
42
43
  using quiche::HttpHeaderBlock;
43
44
 
@@ -91,12 +92,14 @@ namespace quic
91
92
  retObj.Set("hostname", hostname);
92
93
  retObj.Set("port", port);
93
94
  retObj.Set("serverconfig", server_config);
94
- // todo certs
95
95
 
96
96
  Napi::Array jscerts = Napi::Array::New(env, certs.size());
97
97
  for (size_t i = 0; i < certs.size(); i++) {
98
- jscerts.Set(i, certs[i]);
98
+ jscerts.Set(i, Napi::Buffer<uint8_t>::Copy(env,
99
+ reinterpret_cast<const uint8_t*>(certs[i].data()),
100
+ certs[i].size()));
99
101
  }
102
+ retObj.Set("certs", jscerts);
100
103
  retObj.Set("signature", signature);
101
104
 
102
105
  Napi::Value verifyres = env.Global().Get("FAILSVerifyProof").As<Napi::Function>().Call({
@@ -125,13 +128,15 @@ namespace quic
125
128
 
126
129
  Napi::Array jscerts = Napi::Array::New(env, certs.size());
127
130
  for (size_t i = 0; i < certs.size(); i++) {
128
- jscerts.Set(i, certs[i]);
131
+ jscerts.Set(i, Napi::Buffer<uint8_t>::Copy(env,
132
+ reinterpret_cast<const uint8_t*>(certs[i].data()),
133
+ certs[i].size()));
129
134
  }
135
+ retObj.Set("certs", jscerts);
130
136
  Napi::Value verifyres = env.Global().Get("FAILSVerifyProof").As<Napi::Function>().Call({
131
137
  retObj });
132
138
  if (verifyres.As<Napi::Boolean>().Value()) {
133
139
  return QUIC_SUCCESS;
134
-
135
140
  } else {
136
141
  return QUIC_FAILURE;
137
142
  }
@@ -616,7 +621,7 @@ namespace quic
616
621
  return finish_stream_open_.size() > 0;
617
622
  }
618
623
 
619
- void Http3Client::openWTSessionInt(absl::string_view path)
624
+ bool Http3Client::openWTSessionInt(absl::string_view path)
620
625
  {
621
626
  quiche::HttpHeaderBlock headers;
622
627
  headers[":scheme"] = "https";
@@ -624,17 +629,15 @@ namespace quic
624
629
  headers[":path"] = path;
625
630
  headers[":method"] = "CONNECT";
626
631
  headers[":protocol"] = "webtransport";
627
- if (protocols_.size() > 0) { // not very efficient
628
- std::string protocols = "";
629
- for (size_t i=0; i < protocols_.size(); i++) {
630
- protocols += protocols_[i];
631
- if (i!= protocols_.size()-1) {
632
- protocols += ',';
633
- }
632
+ if (protocols_.size() > 0) {
633
+ absl::StatusOr<std::string> wtavail = webtransport::SerializeSubprotocolRequestHeader(protocols_);
634
+ if (!wtavail.ok()) {
635
+ return false;
634
636
  }
635
- headers["wt-available-protocols"] = protocols;
637
+ headers["wt-available-protocols"] = *wtavail;
636
638
  }
637
639
  SendMessageAsync(headers, "", /*fin=*/false);
640
+ return true;
638
641
  }
639
642
 
640
643
  void Http3Client::StartConnect()
@@ -1376,7 +1379,9 @@ namespace quic
1376
1379
  {
1377
1380
  std::string lpath(info[0].ToString().Utf8Value());
1378
1381
 
1379
- obj->openWTSessionInt(lpath);
1382
+ if (!obj->openWTSessionInt(lpath)) {
1383
+ Napi::Error::New(info.Env(), "openWTSessionInt failed, invalid protocols?").ThrowAsJavaScriptException();
1384
+ }
1380
1385
  }
1381
1386
  else
1382
1387
  {
package/src/http3client.h CHANGED
@@ -365,7 +365,7 @@ namespace quic
365
365
  // tracking its state.
366
366
  void SetLatestCreatedStream(QuicSpdyClientStream *stream);
367
367
 
368
- void openWTSessionInt(absl::string_view path);
368
+ bool openWTSessionInt(absl::string_view path);
369
369
 
370
370
  bool closeClientInt();
371
371
 
@@ -17,6 +17,7 @@
17
17
  #include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
18
18
  #include "quiche/quic/core/crypto/proof_source_x509.h"
19
19
  #include "quiche/common/platform/api/quiche_reference_counted.h"
20
+ #include "quiche/web_transport/web_transport_headers.h"
20
21
 
21
22
  using namespace Napi;
22
23
 
@@ -448,6 +449,17 @@ namespace quic
448
449
  for (auto pair : reqhead)
449
450
  {
450
451
  // we iterate over all header fields
452
+ if (pair.first.compare("wt-available-protocols") == 0) {
453
+ absl::StatusOr<std::vector<std::string>> prots = webtransport::ParseSubprotocolRequestHeader(pair.second);
454
+ if (prots.ok()) {
455
+ Napi::Array protArray = Napi::Array::New(Env(), (*prots).size());
456
+ for (size_t i = 0; i < (*prots).size(); i++) {
457
+ protArray.Set(i, std::string((*prots)[i]));
458
+ }
459
+ headObj.Set(std::string("wt-available-protocols"), protArray);
460
+ continue;
461
+ } // otherwise fall through to default
462
+ }
451
463
  headObj.Set(std::string(pair.first), std::string(pair.second));
452
464
  }
453
465
  retObj.Set("header", headObj);
@@ -586,7 +598,11 @@ namespace quic
586
598
  std::unique_ptr<Http3ServerBackend::WebTransportResponse> response = std::make_unique<Http3ServerBackend::WebTransportResponse>();
587
599
  response->response_headers[":status"] = std::to_string(status);
588
600
  if (selectedProtocol != "") {
589
- response->response_headers["wt-protocol"] = selectedProtocol;
601
+ absl::StatusOr<std::string> selprot = webtransport::SerializeSubprotocolResponseHeader(selectedProtocol);
602
+ if (!selprot.ok()) {
603
+ return Napi::Error::New(Env(), "Selected protocol is invalid").ThrowAsJavaScriptException();
604
+ }
605
+ response->response_headers["wt-protocol"] = *selprot;
590
606
  }
591
607
  Http3WTSession *wtsession = new Http3WTSession();
592
608
  wtsession->init(session);
@@ -25,7 +25,7 @@
25
25
  #include "quiche/quic/core/web_transport_interface.h"
26
26
  #include "quiche/quic/platform/api/quic_logging.h"
27
27
  #include "quiche/common/quiche_circular_deque.h"
28
- #include "quiche/common/platform/api/quiche_mem_slice.h"
28
+ #include "quiche/common/quiche_mem_slice.h"
29
29
 
30
30
  namespace quic
31
31
  {