Skip to content

Commit 6b89b30

Browse files
tniessendanielleadams
authored andcommitted
src: fix typo in comment in quic/sessionticket.cc
PR-URL: #47754 Reviewed-By: Matthew Aitken <[email protected]> Reviewed-By: Deokjin Kim <[email protected]>
1 parent e155c10 commit 6b89b30

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed

src/quic/sessionticket.cc

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
2+
3+
#include "sessionticket.h"
4+
#include <env-inl.h>
5+
#include <memory_tracker-inl.h>
6+
#include <ngtcp2/ngtcp2_crypto.h>
7+
#include <node_buffer.h>
8+
#include <node_errors.h>
9+
10+
namespace node {
11+
12+
using v8::ArrayBufferView;
13+
using v8::Just;
14+
using v8::Local;
15+
using v8::Maybe;
16+
using v8::MaybeLocal;
17+
using v8::Nothing;
18+
using v8::Object;
19+
using v8::Value;
20+
using v8::ValueDeserializer;
21+
using v8::ValueSerializer;
22+
23+
namespace quic {
24+
25+
namespace {
26+
SessionTicket::AppData::Source* GetAppDataSource(SSL* ssl) {
27+
ngtcp2_crypto_conn_ref* ref =
28+
static_cast<ngtcp2_crypto_conn_ref*>(SSL_get_app_data(ssl));
29+
if (ref != nullptr && ref->user_data != nullptr) {
30+
return static_cast<SessionTicket::AppData::Source*>(ref->user_data);
31+
}
32+
return nullptr;
33+
}
34+
} // namespace
35+
36+
SessionTicket::SessionTicket(Store&& ticket, Store&& transport_params)
37+
: ticket_(std::move(ticket)),
38+
transport_params_(std::move(transport_params)) {}
39+
40+
Maybe<SessionTicket> SessionTicket::FromV8Value(Environment* env,
41+
v8::Local<v8::Value> value) {
42+
if (!value->IsArrayBufferView()) {
43+
THROW_ERR_INVALID_ARG_TYPE(env, "The ticket must be an ArrayBufferView.");
44+
return Nothing<SessionTicket>();
45+
}
46+
47+
Store content(value.As<ArrayBufferView>());
48+
ngtcp2_vec vec = content;
49+
50+
ValueDeserializer des(env->isolate(), vec.base, vec.len);
51+
52+
if (des.ReadHeader(env->context()).IsNothing()) {
53+
THROW_ERR_INVALID_ARG_VALUE(env, "The ticket format is invalid.");
54+
return Nothing<SessionTicket>();
55+
}
56+
57+
Local<Value> ticket;
58+
Local<Value> transport_params;
59+
60+
errors::TryCatchScope tryCatch(env);
61+
62+
if (!des.ReadValue(env->context()).ToLocal(&ticket) ||
63+
!des.ReadValue(env->context()).ToLocal(&transport_params) ||
64+
!ticket->IsArrayBufferView() || !transport_params->IsArrayBufferView()) {
65+
if (tryCatch.HasCaught()) {
66+
// Any errors thrown we want to catch and suppress. The only
67+
// error we want to expose to the user is that the ticket format
68+
// is invalid.
69+
if (!tryCatch.HasTerminated()) {
70+
THROW_ERR_INVALID_ARG_VALUE(env, "The ticket format is invalid.");
71+
tryCatch.ReThrow();
72+
}
73+
return Nothing<SessionTicket>();
74+
}
75+
THROW_ERR_INVALID_ARG_VALUE(env, "The ticket format is invalid.");
76+
return Nothing<SessionTicket>();
77+
}
78+
79+
return Just(SessionTicket(Store(ticket.As<ArrayBufferView>()),
80+
Store(transport_params.As<ArrayBufferView>())));
81+
}
82+
83+
MaybeLocal<Object> SessionTicket::encode(Environment* env) const {
84+
auto context = env->context();
85+
ValueSerializer ser(env->isolate());
86+
ser.WriteHeader();
87+
88+
if (ser.WriteValue(context, ticket_.ToUint8Array(env)).IsNothing() ||
89+
ser.WriteValue(context, transport_params_.ToUint8Array(env))
90+
.IsNothing()) {
91+
return MaybeLocal<Object>();
92+
}
93+
94+
auto result = ser.Release();
95+
96+
return Buffer::New(env, reinterpret_cast<char*>(result.first), result.second);
97+
}
98+
99+
const uv_buf_t SessionTicket::ticket() const {
100+
return ticket_;
101+
}
102+
103+
const ngtcp2_vec SessionTicket::transport_params() const {
104+
return transport_params_;
105+
}
106+
107+
void SessionTicket::MemoryInfo(MemoryTracker* tracker) const {
108+
tracker->TrackField("ticket", ticket_);
109+
tracker->TrackField("transport_params", transport_params_);
110+
}
111+
112+
int SessionTicket::GenerateCallback(SSL* ssl, void* arg) {
113+
SessionTicket::AppData::Collect(ssl);
114+
return 1;
115+
}
116+
117+
SSL_TICKET_RETURN SessionTicket::DecryptedCallback(SSL* ssl,
118+
SSL_SESSION* session,
119+
const unsigned char* keyname,
120+
size_t keyname_len,
121+
SSL_TICKET_STATUS status,
122+
void* arg) {
123+
switch (status) {
124+
default:
125+
return SSL_TICKET_RETURN_IGNORE;
126+
case SSL_TICKET_EMPTY:
127+
[[fallthrough]];
128+
case SSL_TICKET_NO_DECRYPT:
129+
return SSL_TICKET_RETURN_IGNORE_RENEW;
130+
case SSL_TICKET_SUCCESS_RENEW:
131+
[[fallthrough]];
132+
case SSL_TICKET_SUCCESS:
133+
return static_cast<SSL_TICKET_RETURN>(
134+
SessionTicket::AppData::Extract(ssl));
135+
}
136+
}
137+
138+
SessionTicket::AppData::AppData(SSL* ssl) : ssl_(ssl) {}
139+
140+
bool SessionTicket::AppData::Set(const uv_buf_t& data) {
141+
if (set_ || data.base == nullptr || data.len == 0) return false;
142+
set_ = true;
143+
SSL_SESSION_set1_ticket_appdata(SSL_get0_session(ssl_), data.base, data.len);
144+
return set_;
145+
}
146+
147+
std::optional<const uv_buf_t> SessionTicket::AppData::Get() const {
148+
uv_buf_t buf;
149+
int ret =
150+
SSL_SESSION_get0_ticket_appdata(SSL_get0_session(ssl_),
151+
reinterpret_cast<void**>(&buf.base),
152+
reinterpret_cast<size_t*>(&buf.len));
153+
if (ret != 1) return std::nullopt;
154+
return buf;
155+
}
156+
157+
void SessionTicket::AppData::Collect(SSL* ssl) {
158+
auto source = GetAppDataSource(ssl);
159+
if (source != nullptr) {
160+
SessionTicket::AppData app_data(ssl);
161+
source->CollectSessionTicketAppData(&app_data);
162+
}
163+
}
164+
165+
SessionTicket::AppData::Status SessionTicket::AppData::Extract(SSL* ssl) {
166+
auto source = GetAppDataSource(ssl);
167+
if (source != nullptr) {
168+
SessionTicket::AppData app_data(ssl);
169+
return source->ExtractSessionTicketAppData(app_data);
170+
}
171+
return Status::TICKET_IGNORE;
172+
}
173+
174+
} // namespace quic
175+
} // namespace node
176+
177+
#endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC

0 commit comments

Comments
 (0)