From cade15365b7f63ab304213d3d1744573e32f6bfd Mon Sep 17 00:00:00 2001 From: Khushali Date: Thu, 21 May 2026 11:40:05 -0400 Subject: [PATCH 1/3] support generic pem format --- mauth_client/utils.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/mauth_client/utils.py b/mauth_client/utils.py index 80e19f8..d3bfc2f 100644 --- a/mauth_client/utils.py +++ b/mauth_client/utils.py @@ -3,8 +3,7 @@ import re from hashlib import sha512 -HEADER = '-----BEGIN RSA PRIVATE KEY-----' -FOOTER = '-----END RSA PRIVATE KEY-----' +PEM_BOUNDARY_RE = re.compile(r"^-----(?:BEGIN|END) ([A-Za-z0-9 -]+)-----$", re.MULTILINE) def make_bytes(val): @@ -39,19 +38,30 @@ def decode(byte_string: bytes) -> str: def to_rsa_format(key: str) -> str: - """Convert a private key to RSA format with proper newlines.""" - - if "\n" in key and HEADER in key and FOOTER in key: - return key + """Convert a private key to PEM format with proper newlines (RFC 7468).""" + stripped = key.strip() + labels = PEM_BOUNDARY_RE.findall(stripped) + + # Already well-formed if we have at least a BEGIN and END boundary with newlines + if len(labels) >= 2 and "\n" in stripped: + return stripped + + if labels: + label = labels[0] + header = f"-----BEGIN {label}-----" + footer = f"-----END {label}-----" + else: + # Fallback: treat as a bare RSA private key body + header = "-----BEGIN RSA PRIVATE KEY-----" + footer = "-----END RSA PRIVATE KEY-----" - body = key.strip() - body = body.replace(HEADER, "").replace(FOOTER, "").strip() + body = PEM_BOUNDARY_RE.sub("", stripped).strip() # Replace whitespace with newlines or chunk into 64-char lines if " " in body or "\t" in body: - body = re.sub(r'\s+', '\n', body) + body = re.sub(r"\s+", "\n", body) else: # PEM-encoded keys are typically split into lines of 64 characters as per RFC 7468 (section 2) - body = '\n'.join(body[i:i + 64] for i in range(0, len(body), 64)) + body = "\n".join(body[i : i + 64] for i in range(0, len(body), 64)) - return f"{HEADER}\n{body}\n{FOOTER}" + return f"{header}\n{body}\n{footer}" From 1397f63085a7cba085453a5f0fef5d826930ee99 Mon Sep 17 00:00:00 2001 From: Khushali Date: Thu, 21 May 2026 17:29:19 -0400 Subject: [PATCH 2/3] update regex --- mauth_client/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mauth_client/utils.py b/mauth_client/utils.py index d3bfc2f..6570b96 100644 --- a/mauth_client/utils.py +++ b/mauth_client/utils.py @@ -3,7 +3,7 @@ import re from hashlib import sha512 -PEM_BOUNDARY_RE = re.compile(r"^-----(?:BEGIN|END) ([A-Za-z0-9 -]+)-----$", re.MULTILINE) +PEM_BOUNDARY_RE = re.compile(r"-----(?:BEGIN|END) ([A-Za-z0-9 -]+?)-----") def make_bytes(val): From b9f23d696f111272f2a91a05a9dc2250d123a4be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 21 May 2026 21:40:57 +0000 Subject: [PATCH 3/3] Add tests for non-RSA PEM label and boundary-less body with embedded newlines Agent-Logs-Url: https://github.com/mdsol/mauth-client-python/sessions/ab575d3d-0d12-451b-847e-81a6c2b696e2 Co-authored-by: Khushalijp <105746972+Khushalijp@users.noreply.github.com> --- tests/utils_test.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/utils_test.py b/tests/utils_test.py index 81673d9..6fbb6f6 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -20,3 +20,21 @@ def test_newlines_removed(self): key_no_newlines = PRIVATE_KEY.replace("\n", "") key = to_rsa_format(key_no_newlines) self.assertEqual(key, PRIVATE_KEY) + + def test_non_rsa_label_well_formed(self): + """A well-formed PRIVATE KEY (non-RSA label) PEM should be returned unchanged.""" + non_rsa_key = PRIVATE_KEY.replace("RSA PRIVATE KEY", "PRIVATE KEY") + self.assertEqual(to_rsa_format(non_rsa_key), non_rsa_key) + + def test_boundary_less_body_with_embedded_newlines(self): + """A bare body with embedded newlines is wrapped in RSA PRIVATE KEY boundaries.""" + lines = PRIVATE_KEY.splitlines() + body_with_newlines = "\n".join(lines[1:-1]) + header = "-----BEGIN RSA PRIVATE KEY-----" + footer = "-----END RSA PRIVATE KEY-----" + result = to_rsa_format(body_with_newlines) + self.assertTrue(result.startswith(header + "\n")) + self.assertTrue(result.endswith("\n" + footer)) + # Verify the base64 content is preserved + result_body = result[len(header) + 1 : -(len(footer) + 1)] + self.assertEqual(result_body.replace("\n", ""), body_with_newlines.replace("\n", ""))