Skip to content

Commit 4b7dafd

Browse files
committed
cookie reading that looks like the rest of the code; constants to clean up numbers strewn about
1 parent 311883e commit 4b7dafd

2 files changed

Lines changed: 23 additions & 11 deletions

File tree

src/api-umbrella/web-app/actions/admin/sessions.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,10 @@ function _M.logout_callback(self)
173173
local state = ngx.var.arg_state
174174
if state then
175175
self:init_session_cookie()
176-
self.session_cookie:open()
176+
local ok, open_err = self.session_cookie:open()
177+
if not ok and open_err and open_err ~= "missing session cookie" then
178+
ngx.log(ngx.ERR, "session open error: ", open_err)
179+
end
177180
local session_state = self.session_cookie:get("openid_connect_state")
178181
if state ~= session_state then
179182
ngx.log(ngx.WARN, "state from argument: " .. (state or "nil") .. " does not match state restored from session: " .. (session_state or "nil"))

test/support/api_umbrella_test_helpers/admin_auth.rb

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ module AdminAuth
88
# a hard-coded user agent when we're pre-seeding the session cookie value.
99
STATIC_USER_AGENT = "TestStaticUserAgent".freeze
1010

11+
# lua-resty-session v4 binary header layout constants.
12+
# Header is 82 bytes: [1B type][2B flags][32B sid][5B creation_time]
13+
# [4B rolling_offset][3B data_size][16B tag][3B idling_offset][16B mac]
14+
V4_HEADER_SIZE = 82
15+
V4_HEADER_SID_OFFSET = 3
16+
V4_HEADER_SID_SIZE = 32
17+
V4_HEADER_PRE_TAG_SIZE = 47 # bytes before AES-GCM tag
18+
V4_HEADER_TAG_SIZE = 16
19+
1120
include ApiUmbrellaTestHelpers::Selenium
1221

1322
def admin_login(admin = nil)
@@ -333,7 +342,7 @@ def decrypt_session_cookie(cookie_value)
333342
# In v4, the DB-backed cookie is just the base64url-encoded header.
334343
# Extract the SID from the header to look up the DB record.
335344
header = session_base64_decode(cookie_value)
336-
sid = header[3, 32]
345+
sid = header[V4_HEADER_SID_OFFSET, V4_HEADER_SID_SIZE]
337346
sid_encoded = session_base64_encode(sid)
338347

339348
session = Session.find_by(:sid => sid_encoded)
@@ -348,9 +357,9 @@ def decrypt_session_cookie(cookie_value)
348357
aes_key = sid_key[0, 32]
349358
iv = sid_key[32, 12]
350359

351-
# The AAD is the first 47 bytes of the header (before the tag)
352-
aad = header[0, 47]
353-
tag = header[47, 16]
360+
# The AAD is the bytes before the AES-GCM tag
361+
aad = header[0, V4_HEADER_PRE_TAG_SIZE]
362+
tag = header[V4_HEADER_PRE_TAG_SIZE, V4_HEADER_TAG_SIZE]
354363

355364
decipher = OpenSSL::Cipher.new("aes-256-gcm")
356365
decipher.decrypt
@@ -377,24 +386,24 @@ def encrypt_session_client_cookie(data)
377386

378387
def decrypt_session_client_cookie(cookie_value)
379388
# The cookie value is base64url(header) + base64url(ciphertext).
380-
# The header is always 82 bytes raw = 110 base64url chars (ceil(82*4/3) with no padding).
381-
header_b64_len = ((82 * 4 + 2) / 3.0).ceil
389+
# The header is always V4_HEADER_SIZE bytes raw.
390+
header_b64_len = ((V4_HEADER_SIZE * 4 + 2) / 3.0).ceil
382391
header_b64 = cookie_value[0, header_b64_len]
383392
ciphertext_b64 = cookie_value[header_b64_len..]
384393

385394
header = session_base64_decode(header_b64)
386395
ciphertext = session_base64_decode(ciphertext_b64)
387-
sid = header[3, 32]
396+
sid = header[V4_HEADER_SID_OFFSET, V4_HEADER_SID_SIZE]
388397

389398
# Derive the decryption key from the SID
390399
ikm = Digest::SHA256.digest($config["secret_key"])
391400
sid_key = OpenSSL::KDF.hkdf(ikm, salt: "", info: "encryption:#{sid}", length: 44, hash: "SHA256")
392401
aes_key = sid_key[0, 32]
393402
iv = sid_key[32, 12]
394403

395-
# The AAD is the first 47 bytes of the header (before the tag)
396-
aad = header[0, 47]
397-
tag = header[47, 16]
404+
# The AAD is the bytes before the AES-GCM tag
405+
aad = header[0, V4_HEADER_PRE_TAG_SIZE]
406+
tag = header[V4_HEADER_PRE_TAG_SIZE, V4_HEADER_TAG_SIZE]
398407

399408
decipher = OpenSSL::Cipher.new("aes-256-gcm")
400409
decipher.decrypt

0 commit comments

Comments
 (0)