From 5f0e1a524b9faf6871584ed20ccb18ba610a286d Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Tue, 23 May 2023 11:30:14 -0300 Subject: [PATCH] chore: Display errors if nomcom private key encoding fails --- ietf/nomcom/templatetags/nomcom_tags.py | 6 ++++-- ietf/nomcom/utils.py | 14 ++++++++++++++ ietf/nomcom/views.py | 12 ++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ietf/nomcom/templatetags/nomcom_tags.py b/ietf/nomcom/templatetags/nomcom_tags.py index c751383fb..38dfc61b9 100644 --- a/ietf/nomcom/templatetags/nomcom_tags.py +++ b/ietf/nomcom/templatetags/nomcom_tags.py @@ -55,8 +55,10 @@ def formatted_email(address): @register.simple_tag def decrypt(string, request, year, plain=False): - key = retrieve_nomcom_private_key(request, year) - + try: + key = retrieve_nomcom_private_key(request, year) + except UnicodeError: + return f"-*- Encrypted text [Error retrieving private key, contact the secretariat ({settings.SECRETARIAT_SUPPORT_EMAIL})]" if not key: return '-*- Encrypted text [No private key provided] -*-' diff --git a/ietf/nomcom/utils.py b/ietf/nomcom/utils.py index 5cc41f820..f00baa934 100644 --- a/ietf/nomcom/utils.py +++ b/ietf/nomcom/utils.py @@ -172,6 +172,12 @@ def command_line_safe_secret(secret): return base64.encodebytes(secret).decode('utf-8').rstrip() def retrieve_nomcom_private_key(request, year): + """Retrieve decrypted nomcom private key from the session store + + Retrieves encrypted, ascii-armored private key from the session store, encodes + as utf8 bytes, then decrypts. Raises UnicodeError if the value in the session + store cannot be encoded as utf8. + """ private_key = request.session.get('NOMCOM_PRIVATE_KEY_%s' % year, None) if not private_key: @@ -183,6 +189,7 @@ def retrieve_nomcom_private_key(request, year): settings.OPENSSL_COMMAND, command_line_safe_secret(settings.NOMCOM_APP_SECRET) ), + # The openssl command expects ascii-armored input, so utf8 encoding should be valid private_key.encode("utf8") ) if code != 0: @@ -191,6 +198,12 @@ def retrieve_nomcom_private_key(request, year): def store_nomcom_private_key(request, year, private_key): + """Put encrypted nomcom private key in the session store + + Encrypts the private key using openssl, then decodes the ascii-armored output + as utf8 and adds to the session store. Raises UnicodeError if the openssl's + output cannot be decoded as utf8. + """ if not private_key: request.session['NOMCOM_PRIVATE_KEY_%s' % year] = '' else: @@ -206,6 +219,7 @@ def store_nomcom_private_key(request, year, private_key): log("openssl error: %s:\n Error %s: %s" %(command, code, error)) if error and error!=b"*** WARNING : deprecated key derivation used.\nUsing -iter or -pbkdf2 would be better.\n": out = b'' + # The openssl command output in 'out' is an ascii-armored value, so should be utf8-decodable request.session['NOMCOM_PRIVATE_KEY_%s' % year] = out.decode("utf8") diff --git a/ietf/nomcom/views.py b/ietf/nomcom/views.py index 51c165bce..77a3c3b76 100644 --- a/ietf/nomcom/views.py +++ b/ietf/nomcom/views.py @@ -158,8 +158,16 @@ def private_key(request, year): if request.method == 'POST': form = PrivateKeyForm(data=request.POST) if form.is_valid(): - store_nomcom_private_key(request, year, force_bytes(form.cleaned_data.get('key', ''))) - return HttpResponseRedirect(back_url) + try: + store_nomcom_private_key(request, year, force_bytes(form.cleaned_data.get('key', ''))) + except UnicodeError: + form.add_error( + None, + "An internal error occurred while adding your private key to your session." + f"Please contact the secretariat for assistance ({settings.SECRETARIAT_SUPPORT_EMAIL})" + ) + else: + return HttpResponseRedirect(back_url) else: form = PrivateKeyForm()