quic 0.0.3 → 0.0.4

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.
@@ -10,14 +10,13 @@
10
10
  share across verifications; creation runs under the GVL. Never freed. */
11
11
  static X509_STORE *quic_default_store;
12
12
 
13
- static X509_STORE *
14
- quic_get_default_store(void)
15
- {
13
+ static X509_STORE *quic_get_default_store(void) {
16
14
  if (quic_default_store == NULL) {
17
15
  X509_STORE *store = X509_STORE_new();
18
16
  if (store == NULL || X509_STORE_set_default_paths(store) != 1) {
19
17
  X509_STORE_free(store);
20
- rb_raise(rb_eRuntimeError, "failed to load the default certificate store");
18
+ rb_raise(rb_eRuntimeError,
19
+ "failed to load the default certificate store");
21
20
  }
22
21
  quic_default_store = store;
23
22
  }
@@ -31,8 +30,7 @@ quic_get_default_store(void)
31
30
  static int
32
31
  quic_override_verify_cb(ptls_openssl_override_verify_certificate_t *self,
33
32
  ptls_t *tls, int ret, int ossl_ret, X509 *cert,
34
- STACK_OF(X509) *chain)
35
- {
33
+ STACK_OF(X509) * chain) {
36
34
  (void)self;
37
35
  (void)cert;
38
36
  (void)chain;
@@ -46,35 +44,40 @@ quic_override_verify_cb(ptls_openssl_override_verify_certificate_t *self,
46
44
  }
47
45
 
48
46
  static ptls_openssl_override_verify_certificate_t quic_override_verify = {
49
- quic_override_verify_cb,
47
+ quic_override_verify_cb,
50
48
  };
51
49
 
52
50
  /* Install picotls's certificate verifier on c->tls_ctx according to the
53
51
  verify_mode / ca_file / ca_path settings. Leaves verify_certificate NULL
54
52
  for verify_mode :none, which skips verification altogether. */
55
- static void
56
- quic_client_setup_verify(quic_conn_t *c, VALUE settings_v, VALUE server_name)
57
- {
53
+ static void quic_client_setup_verify(quic_conn_t *c, VALUE settings_v,
54
+ VALUE server_name) {
58
55
  VALUE mode = rb_funcall(settings_v, rb_intern("verify_mode"), 0);
59
56
  /* ca_file and ca_path are not even type-checked under :none. */
60
- if (mode == ID2SYM(rb_intern("none"))) return;
57
+ if (mode == ID2SYM(rb_intern("none")))
58
+ return;
61
59
  if (mode != ID2SYM(rb_intern("peer"))) {
62
- rb_raise(rb_eArgError, "verify_mode must be :peer or :none (got %+"PRIsVALUE")", mode);
60
+ rb_raise(rb_eArgError,
61
+ "verify_mode must be :peer or :none (got %+" PRIsVALUE ")", mode);
63
62
  }
64
63
 
65
- VALUE ca_file = quic_path_value(rb_funcall(settings_v, rb_intern("ca_file"), 0), "ca_file");
66
- VALUE ca_path = quic_path_value(rb_funcall(settings_v, rb_intern("ca_path"), 0), "ca_path");
64
+ VALUE ca_file = quic_path_value(
65
+ rb_funcall(settings_v, rb_intern("ca_file"), 0), "ca_file");
66
+ VALUE ca_path = quic_path_value(
67
+ rb_funcall(settings_v, rb_intern("ca_path"), 0), "ca_path");
67
68
 
68
69
  /* An empty name makes OpenSSL clear its host list and skip the name check,
69
70
  and both SNI and the check would silently stop at an embedded NUL. */
70
71
  if (RSTRING_LEN(server_name) == 0 ||
71
- memchr(RSTRING_PTR(server_name), '\0', (size_t)RSTRING_LEN(server_name)) != NULL) {
72
- rb_raise(rb_eArgError,
73
- "server_name must be a non-empty string without NUL bytes when verify_mode is :peer");
72
+ memchr(RSTRING_PTR(server_name), '\0',
73
+ (size_t)RSTRING_LEN(server_name)) != NULL) {
74
+ rb_raise(rb_eArgError, "server_name must be a non-empty string without NUL "
75
+ "bytes when verify_mode is :peer");
74
76
  }
75
77
  /* X509_LOOKUP_hash_dir does not check that the directory exists. */
76
- if (!NIL_P(ca_path) && !RTEST(rb_funcall(rb_cFile, rb_intern("directory?"), 1, ca_path))) {
77
- rb_raise(rb_eArgError, "ca_path is not a directory: %"PRIsVALUE, ca_path);
78
+ if (!NIL_P(ca_path) &&
79
+ !RTEST(rb_funcall(rb_cFile, rb_intern("directory?"), 1, ca_path))) {
80
+ rb_raise(rb_eArgError, "ca_path is not a directory: %" PRIsVALUE, ca_path);
78
81
  }
79
82
 
80
83
  X509_STORE *store;
@@ -85,17 +88,17 @@ quic_client_setup_verify(quic_conn_t *c, VALUE settings_v, VALUE server_name)
85
88
  if (store == NULL) {
86
89
  rb_raise(rb_eRuntimeError, "X509_STORE_new failed");
87
90
  }
88
- if (X509_STORE_load_locations(store,
89
- NIL_P(ca_file) ? NULL : RSTRING_PTR(ca_file),
90
- NIL_P(ca_path) ? NULL : RSTRING_PTR(ca_path)) != 1) {
91
+ if (X509_STORE_load_locations(
92
+ store, NIL_P(ca_file) ? NULL : RSTRING_PTR(ca_file),
93
+ NIL_P(ca_path) ? NULL : RSTRING_PTR(ca_path)) != 1) {
91
94
  X509_STORE_free(store);
92
95
  /* libcrypto is shared with Ruby's openssl extension; do not leave our
93
96
  failure on its error queue. */
94
97
  ERR_clear_error();
95
98
  if (NIL_P(ca_file)) {
96
- rb_raise(rb_eArgError, "failed to load ca_path: %"PRIsVALUE, ca_path);
99
+ rb_raise(rb_eArgError, "failed to load ca_path: %" PRIsVALUE, ca_path);
97
100
  }
98
- rb_raise(rb_eArgError, "failed to load ca_file: %"PRIsVALUE, ca_file);
101
+ rb_raise(rb_eArgError, "failed to load ca_file: %" PRIsVALUE, ca_file);
99
102
  }
100
103
  } else {
101
104
  store = quic_get_default_store();
@@ -103,7 +106,8 @@ quic_client_setup_verify(quic_conn_t *c, VALUE settings_v, VALUE server_name)
103
106
 
104
107
  /* init takes its own reference on the store, so ours can go right away. */
105
108
  int rv = ptls_openssl_init_verify_certificate(&c->verify_cert, store);
106
- if (own_store) X509_STORE_free(store);
109
+ if (own_store)
110
+ X509_STORE_free(store);
107
111
  if (rv != 0) {
108
112
  rb_raise(rb_eRuntimeError, "ptls_openssl_init_verify_certificate failed");
109
113
  }
@@ -112,29 +116,31 @@ quic_client_setup_verify(quic_conn_t *c, VALUE settings_v, VALUE server_name)
112
116
  c->tls_ctx.verify_certificate = &c->verify_cert.super;
113
117
  }
114
118
 
115
- static VALUE
116
- quic_client_open(int argc, VALUE *argv, VALUE klass)
117
- {
119
+ static VALUE quic_client_open(int argc, VALUE *argv, VALUE klass) {
118
120
  VALUE opts = Qnil;
119
121
  rb_scan_args(argc, argv, "0:", &opts);
120
122
  if (NIL_P(opts)) {
121
- rb_raise(rb_eArgError,
122
- "missing keywords: local_sockaddr, remote_sockaddr, server_name, transport_params, settings");
123
+ rb_raise(rb_eArgError, "missing keywords: local_sockaddr, remote_sockaddr, "
124
+ "server_name, transport_params, settings");
123
125
  }
124
126
 
125
- VALUE local_sockaddr = rb_hash_aref(opts, ID2SYM(rb_intern("local_sockaddr")));
126
- VALUE remote_sockaddr = rb_hash_aref(opts, ID2SYM(rb_intern("remote_sockaddr")));
127
- VALUE server_name = rb_hash_aref(opts, ID2SYM(rb_intern("server_name")));
128
- VALUE transport_params = rb_hash_aref(opts, ID2SYM(rb_intern("transport_params")));
129
- VALUE settings_v = rb_hash_aref(opts, ID2SYM(rb_intern("settings")));
127
+ VALUE local_sockaddr =
128
+ rb_hash_aref(opts, ID2SYM(rb_intern("local_sockaddr")));
129
+ VALUE remote_sockaddr =
130
+ rb_hash_aref(opts, ID2SYM(rb_intern("remote_sockaddr")));
131
+ VALUE server_name = rb_hash_aref(opts, ID2SYM(rb_intern("server_name")));
132
+ VALUE transport_params =
133
+ rb_hash_aref(opts, ID2SYM(rb_intern("transport_params")));
134
+ VALUE settings_v = rb_hash_aref(opts, ID2SYM(rb_intern("settings")));
130
135
 
131
136
  if (NIL_P(local_sockaddr) || NIL_P(remote_sockaddr) || NIL_P(server_name) ||
132
137
  NIL_P(transport_params) || NIL_P(settings_v)) {
133
138
  rb_raise(rb_eArgError,
134
- "all keywords required: local_sockaddr, remote_sockaddr, server_name, transport_params, settings");
139
+ "all keywords required: local_sockaddr, remote_sockaddr, "
140
+ "server_name, transport_params, settings");
135
141
  }
136
142
 
137
- quic_require_sockaddr(local_sockaddr, "local_sockaddr");
143
+ quic_require_sockaddr(local_sockaddr, "local_sockaddr");
138
144
  quic_require_sockaddr(remote_sockaddr, "remote_sockaddr");
139
145
  Check_Type(server_name, T_STRING);
140
146
 
@@ -153,17 +159,18 @@ quic_client_open(int argc, VALUE *argv, VALUE klass)
153
159
  the ngtcp2-side initialization explicit and the TLS setup in one place. */
154
160
  ngtcp2_crypto_picotls_ctx_init(&c->cptls);
155
161
  c->tls_ctx = (ptls_context_t){
156
- .random_bytes = ptls_openssl_random_bytes,
157
- .get_time = &ptls_get_time,
158
- .key_exchanges = quic_key_exchanges,
159
- .cipher_suites = quic_cipher_suites,
160
- /* No session resumption yet, so this has no effect today. Keep it so that
161
- when resumption is added, PSK-only (non-forward-secret) resumption is
162
- refused rather than silently accepted. */
163
- .require_dhe_on_psk = 1,
162
+ .random_bytes = ptls_openssl_random_bytes,
163
+ .get_time = &ptls_get_time,
164
+ .key_exchanges = quic_key_exchanges,
165
+ .cipher_suites = quic_cipher_suites,
166
+ /* No session resumption yet, so this has no effect today. Keep it so that
167
+ when resumption is added, PSK-only (non-forward-secret) resumption is
168
+ refused rather than silently accepted. */
169
+ .require_dhe_on_psk = 1,
164
170
  };
165
171
  if (ngtcp2_crypto_picotls_configure_client_context(&c->tls_ctx) != 0) {
166
- rb_raise(rb_eRuntimeError, "ngtcp2_crypto_picotls_configure_client_context failed");
172
+ rb_raise(rb_eRuntimeError,
173
+ "ngtcp2_crypto_picotls_configure_client_context failed");
167
174
  }
168
175
 
169
176
  /* ptls_client_new keeps a pointer to tls_ctx, so the verifier has to be in
@@ -189,21 +196,27 @@ quic_client_open(int argc, VALUE *argv, VALUE klass)
189
196
 
190
197
  ngtcp2_settings settings;
191
198
  quic_fill_settings(&settings, settings_v);
192
- quic_conn_open_qlog(c, settings_v, &settings);
193
199
 
194
200
  ngtcp2_transport_params params;
195
201
  quic_fill_transport_params(&params, transport_params);
196
202
 
203
+ /* Opened once the caller's values have all been read, so that a bad one
204
+ leaves no file behind. Every raise below closes it first. */
205
+ quic_conn_open_qlog(c, settings_v, &settings);
206
+
197
207
  ngtcp2_path path = {
198
- {(struct sockaddr *)RSTRING_PTR(local_sockaddr), (ngtcp2_socklen)RSTRING_LEN(local_sockaddr)},
199
- {(struct sockaddr *)RSTRING_PTR(remote_sockaddr), (ngtcp2_socklen)RSTRING_LEN(remote_sockaddr)},
200
- NULL,
208
+ {(struct sockaddr *)RSTRING_PTR(local_sockaddr),
209
+ (ngtcp2_socklen)RSTRING_LEN(local_sockaddr)},
210
+ {(struct sockaddr *)RSTRING_PTR(remote_sockaddr),
211
+ (ngtcp2_socklen)RSTRING_LEN(remote_sockaddr)},
212
+ NULL,
201
213
  };
202
214
 
203
215
  int rv = ngtcp2_conn_client_new(&c->conn, &c->dcid, &c->scid, &path,
204
- NGTCP2_PROTO_VER_V1, &callbacks,
205
- &settings, &params, NULL, c);
216
+ NGTCP2_PROTO_VER_V1, &callbacks, &settings,
217
+ &params, NULL, c);
206
218
  if (rv != 0) {
219
+ quic_conn_close_qlog(c);
207
220
  quic_raise_ngtcp2_error(rv);
208
221
  }
209
222
 
@@ -211,6 +224,7 @@ quic_client_open(int argc, VALUE *argv, VALUE klass)
211
224
  transport parameters from the conn, so it needs the conn to exist. */
212
225
  c->cptls.ptls = ptls_client_new(&c->tls_ctx);
213
226
  if (c->cptls.ptls == NULL) {
227
+ quic_conn_close_qlog(c);
214
228
  rb_raise(rb_eRuntimeError, "ptls_client_new failed");
215
229
  }
216
230
  /* Let ngtcp2's crypto callbacks (add_handshake_data,
@@ -222,13 +236,17 @@ quic_client_open(int argc, VALUE *argv, VALUE klass)
222
236
  c->tls_exts[1].type = UINT16_MAX;
223
237
  c->cptls.handshake_properties.additional_extensions = c->tls_exts;
224
238
  if (ngtcp2_crypto_picotls_configure_client_session(&c->cptls, c->conn) != 0) {
225
- rb_raise(rb_eRuntimeError, "ngtcp2_crypto_picotls_configure_client_session failed");
239
+ quic_conn_close_qlog(c);
240
+ rb_raise(rb_eRuntimeError,
241
+ "ngtcp2_crypto_picotls_configure_client_session failed");
226
242
  }
227
243
  c->cptls.handshake_properties.client.negotiated_protocols.list = c->alpn;
228
- c->cptls.handshake_properties.client.negotiated_protocols.count = c->alpn_count;
244
+ c->cptls.handshake_properties.client.negotiated_protocols.count =
245
+ c->alpn_count;
229
246
  /* ptls_set_server_name copies the name. */
230
247
  if (ptls_set_server_name(c->cptls.ptls, RSTRING_PTR(server_name),
231
248
  (size_t)RSTRING_LEN(server_name)) != 0) {
249
+ quic_conn_close_qlog(c);
232
250
  rb_raise(rb_eRuntimeError, "ptls_set_server_name failed");
233
251
  }
234
252
 
@@ -246,11 +264,11 @@ quic_client_open(int argc, VALUE *argv, VALUE klass)
246
264
  return self;
247
265
  }
248
266
 
249
- void
250
- Init_quic_connection_client(VALUE rb_mQUICConnectionArg)
251
- {
252
- rb_cQUICConnectionClient = rb_define_class_under(rb_mQUICConnectionArg, "Client", rb_cObject);
267
+ void Init_quic_connection_client(VALUE rb_mQUICConnectionArg) {
268
+ rb_cQUICConnectionClient =
269
+ rb_define_class_under(rb_mQUICConnectionArg, "Client", rb_cObject);
253
270
  rb_define_alloc_func(rb_cQUICConnectionClient, quic_conn_alloc);
254
- rb_define_singleton_method(rb_cQUICConnectionClient, "_open", quic_client_open, -1);
271
+ rb_define_singleton_method(rb_cQUICConnectionClient, "_open",
272
+ quic_client_open, -1);
255
273
  quic_conn_define_shared_methods(rb_cQUICConnectionClient);
256
274
  }