crypto: improve support for non-rsa private keys (discovery)
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
c77f804b77
commit
c1f0833c09
|
@ -72,7 +72,7 @@ class CertificateKeyPairSerializer(ModelSerializer):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def validate_key_data(self, value: str) -> str:
|
def validate_key_data(self, value: str) -> str:
|
||||||
"""Verify that input is a valid PEM RSA Key"""
|
"""Verify that input is a valid PEM Key"""
|
||||||
# Since this field is optional, data can be empty.
|
# Since this field is optional, data can be empty.
|
||||||
if value != "":
|
if value != "":
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -6,6 +6,11 @@ from uuid import uuid4
|
||||||
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.ec import (
|
||||||
|
EllipticCurvePrivateKey,
|
||||||
|
EllipticCurvePublicKey,
|
||||||
|
)
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey, Ed25519PublicKey
|
||||||
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey
|
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
from cryptography.x509 import Certificate, load_pem_x509_certificate
|
from cryptography.x509 import Certificate, load_pem_x509_certificate
|
||||||
|
@ -36,8 +41,8 @@ class CertificateKeyPair(ManagedModel, CreatedUpdatedModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
_cert: Optional[Certificate] = None
|
_cert: Optional[Certificate] = None
|
||||||
_private_key: Optional[RSAPrivateKey] = None
|
_private_key: Optional[RSAPrivateKey | EllipticCurvePrivateKey | Ed25519PrivateKey] = None
|
||||||
_public_key: Optional[RSAPublicKey] = None
|
_public_key: Optional[RSAPublicKey | EllipticCurvePublicKey | Ed25519PublicKey] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def certificate(self) -> Certificate:
|
def certificate(self) -> Certificate:
|
||||||
|
@ -49,14 +54,14 @@ class CertificateKeyPair(ManagedModel, CreatedUpdatedModel):
|
||||||
return self._cert
|
return self._cert
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def public_key(self) -> Optional[RSAPublicKey]:
|
def public_key(self) -> Optional[RSAPublicKey | EllipticCurvePublicKey]:
|
||||||
"""Get public key of the private key"""
|
"""Get public key of the private key"""
|
||||||
if not self._public_key:
|
if not self._public_key:
|
||||||
self._public_key = self.private_key.public_key()
|
self._public_key = self.private_key.public_key()
|
||||||
return self._public_key
|
return self._public_key
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def private_key(self) -> Optional[RSAPrivateKey]:
|
def private_key(self) -> Optional[RSAPrivateKey | EllipticCurvePrivateKey]:
|
||||||
"""Get python cryptography PrivateKey instance"""
|
"""Get python cryptography PrivateKey instance"""
|
||||||
if not self._private_key and self.key_data != "":
|
if not self._private_key and self.key_data != "":
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -24,7 +24,7 @@ MANAGED_DISCOVERED = "goauthentik.io/crypto/discovered/%s"
|
||||||
|
|
||||||
|
|
||||||
def ensure_private_key_valid(body: str):
|
def ensure_private_key_valid(body: str):
|
||||||
"""Attempt loading of an RSA Private key without password"""
|
"""Attempt loading of a PEM Private key without password"""
|
||||||
load_pem_private_key(
|
load_pem_private_key(
|
||||||
str.encode("\n".join([x.strip() for x in body.split("\n")])),
|
str.encode("\n".join([x.strip() for x in body.split("\n")])),
|
||||||
password=None,
|
password=None,
|
||||||
|
@ -60,7 +60,7 @@ def certificate_discovery(self: MonitoredTask):
|
||||||
try:
|
try:
|
||||||
with open(path, "r+", encoding="utf-8") as _file:
|
with open(path, "r+", encoding="utf-8") as _file:
|
||||||
body = _file.read()
|
body = _file.read()
|
||||||
if "BEGIN RSA PRIVATE KEY" in body:
|
if "PRIVATE KEY" in body:
|
||||||
private_keys[cert_name] = ensure_private_key_valid(body)
|
private_keys[cert_name] = ensure_private_key_valid(body)
|
||||||
else:
|
else:
|
||||||
certs[cert_name] = ensure_certificate_valid(body)
|
certs[cert_name] = ensure_certificate_valid(body)
|
||||||
|
|
|
@ -34,7 +34,7 @@ You can also bind mount single files into the folder, as long as they fall under
|
||||||
|
|
||||||
`/foo.pem` Will be imported as the keypair `foo`. Based on its content its either imported as certificate or private key.
|
`/foo.pem` Will be imported as the keypair `foo`. Based on its content its either imported as certificate or private key.
|
||||||
|
|
||||||
Currently, only RSA Keys are supported, so if the file contains `BEGIN RSA PRIVATE KEY` it will imported as private key.
|
Files containing `PRIVATE KEY` it will imported as private key.
|
||||||
|
|
||||||
Otherwise it will be imported as certificate.
|
Otherwise it will be imported as certificate.
|
||||||
|
|
||||||
|
|
Reference in New Issue