1fefa4b6cb
Accepts keys like nz-admin.pem (BEGIN RSA PRIVATE KEY); rejects invalid PEM before encrypting. Public key field optional on create/update. Co-authored-by: Cursor <cursoragent@cursor.com>
39 lines
1.3 KiB
Python
39 lines
1.3 KiB
Python
"""Validate SSH private key PEM and optionally derive OpenSSH public key."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncssh
|
|
|
|
|
|
def normalize_ssh_private_key_pem(private_key: str) -> str:
|
|
"""Strip outer whitespace; PEM body newlines preserved."""
|
|
return (private_key or "").strip()
|
|
|
|
|
|
def prepare_ssh_key_preset_fields(
|
|
private_key: str,
|
|
public_key: str | None = None,
|
|
) -> tuple[str, str | None]:
|
|
"""
|
|
Validate PEM private key (RSA / OPENSSH / PKCS#8) and return (private, public).
|
|
|
|
If public_key is empty, derive OpenSSH public key from private (asyncssh).
|
|
"""
|
|
pem = normalize_ssh_private_key_pem(private_key)
|
|
if not pem:
|
|
raise ValueError("私钥不能为空")
|
|
if "BEGIN" not in pem or "PRIVATE KEY" not in pem:
|
|
raise ValueError(
|
|
"私钥须为 PEM 格式(整文件粘贴,含 -----BEGIN … PRIVATE KEY----- 首尾行)"
|
|
)
|
|
try:
|
|
key = asyncssh.import_private_key(pem)
|
|
except Exception as exc:
|
|
raise ValueError("私钥格式无效,无法解析;请确认是未加密的 PEM 私钥") from exc
|
|
|
|
pub = (public_key or "").strip() or None
|
|
if not pub:
|
|
exported = key.export_public_key("openssh")
|
|
pub = exported.decode() if isinstance(exported, bytes) else exported
|
|
return pem, pub
|