Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lemur/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,26 @@
"""
Parses a PEM-format private key (RSA, DSA, ECDSA or any other supported algorithm).

Strips any EC PARAMETERS block that may precede EC private keys (e.g. from
``openssl ecparam -genkey``), since some cryptography versions cannot parse
a PEM bundle containing both sections.

Raises ValueError for an invalid string. Raises AssertionError when passed value is not str-type.

:param private_key: String containing PEM private key
"""
assert isinstance(private_key, str)

# Strip EC PARAMETERS block if present (produced by openssl ecparam -genkey)
if "-----BEGIN EC PARAMETERS-----" in private_key:
import re
private_key = re.sub(
r"-----BEGIN EC PARAMETERS-----.*?-----END EC PARAMETERS-----\s*",
"",
private_key,

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on a
user-provided value
may run slow on strings starting with '-----BEGIN EC PARAMETERS-----' and with many repetitions of '-----BEGIN EC PARAMETERS-----'.
This
regular expression
that depends on a
user-provided value
may run slow on strings starting with '-----BEGIN EC PARAMETERS-----' and with many repetitions of '-----BEGIN EC PARAMETERS-----'.
This
regular expression
that depends on a
user-provided value
may run slow on strings starting with '-----BEGIN EC PARAMETERS-----' and with many repetitions of '-----BEGIN EC PARAMETERS-----'.
flags=re.DOTALL,
)

return load_pem_private_key(
private_key.encode("utf8"), password=None, backend=default_backend()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ <h3 class="modal-title">Import a certificate <span class="text-muted"><small>enc
<div class="col-sm-10">
<textarea name="privateKey" ng-model="certificate.privateKey" placeholder="PEM encoded string..."
class="form-control"
ng-pattern="/(^-----BEGIN PRIVATE KEY-----[\S\s]*-----END PRIVATE KEY-----)|(^-----BEGIN RSA PRIVATE KEY-----[\S\s]*-----END RSA PRIVATE KEY-----)/"></textarea>
ng-pattern="/(^(-----BEGIN EC PARAMETERS-----[\S\s]*-----END EC PARAMETERS-----\s*)?-----BEGIN (RSA |EC )?PRIVATE KEY-----[\S\s]*-----END (RSA |EC )?PRIVATE KEY-----)/"></textarea>

<p ng-show="uploadForm.privateKey.$invalid && !uploadForm.privateKey.$pristine" class="help-block">Enter
a valid certificate.</p>
Expand Down
13 changes: 13 additions & 0 deletions lemur/tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ def test_private_key(session):
parse_private_key("invalid_private_key")


def test_parse_ec_private_key_with_parameters(session):
"""Verify that EC keys with an EC PARAMETERS prefix can be parsed (issue #5058)."""
import subprocess
result = subprocess.run(
["openssl", "ecparam", "-genkey", "-name", "secp384r1"],
capture_output=True, text=True,
)
ec_key_with_params = result.stdout
assert "BEGIN EC PARAMETERS" in ec_key_with_params
key = parse_private_key(ec_key_with_params)
assert key is not None


def test_validate_private_key(session):
key = parse_private_key(SAN_CERT_KEY)

Expand Down
Loading