From 80626fde3bb2a6b013d4a3dd75eab55c6913f64e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 21 Feb 2024 12:38:49 +0200 Subject: Review: JWT --- mod/jwt.cxx | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'mod/jwt.cxx') diff --git a/mod/jwt.cxx b/mod/jwt.cxx index e70752e..0c9c1f6 100644 --- a/mod/jwt.cxx +++ b/mod/jwt.cxx @@ -122,15 +122,19 @@ gen_jwt (const options::openssl_options& o, process_env (o.openssl (), o.openssl_envvar ()), "dgst", o.openssl_option (), "-sha256", "-sign", pk); + ifdstream err (move (errp.in)); + vector bs; // Binary signature (openssl output). string et; // Openssl stderr text. try { // In case of exception, skip and close input after output. // + // Note: re-open in/out so that they get automaitcally closed on + // exception. + // ifdstream in (os.in.release (), fdstream_mode::skip); ofdstream out (os.out.release ()); - ifdstream err (move (errp.in)); // Write the concatenated header and payload to openssl's input. // @@ -141,40 +145,45 @@ gen_jwt (const options::openssl_options& o, // bs = in.read_binary (); in.close (); - - if (!os.wait ()) - et = err.read_text (); - - err.close (); } catch (const io_error& e) { - // IO failure, child exit status doesn't matter. Just wait for the - // process completion and throw. + // If the process exits with non-zero status, assume the IO error is due + // to that and fall through. // - os.wait (); - - throw_generic_error (e.code ().value (), - ("unable to communicate with " + - o.openssl ().string () + ": " + e.what ()) - .c_str ()); + if (os.wait ()) + { + throw_generic_error ( + e.code ().value (), + ("unable to read/write openssl stdout/stdin: " + e.what ()).c_str ()); + } } if (!os.wait ()) { + et = err.read_text (); throw_generic_error ( - EINVAL, - (o.openssl ().string () + " failed: " + et).c_str ()); + EINVAL, + ("non-zero openssl exit status: " + et).c_str ()); } + err.close (); + s = base64url_encode (bs); } catch (const process_error& e) { throw_generic_error ( - e.code ().value (), - ("unable to execute " + o.openssl ().string () + ": " + e.what ()) - .c_str ()); + e.code ().value (), + ("unable to execute openssl: " + e.what ()).c_str ()); + } + catch (const io_error& e) + { + // Unable to read diagnostics from stderr. + // + throw_generic_error ( + e.code ().value (), + ("unable to read openssl stderr : " + e.what ()).c_str ()); } return h + '.' + p + '.' + s; // Return the token. -- cgit v1.1