summaryrefslogtreecommitdiffstats
path: root/crypto.py
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.net>2026-01-16 17:09:18 +0000
committerLeonardo Bishop <me@leonardobishop.net>2026-01-16 17:09:18 +0000
commit3c92a2e5fc0e1d04c8ec8199db319d3a575fcfe5 (patch)
tree150474ac1f2a60c18420527e9580e1bf3aff7f62 /crypto.py
Initial commitHEADmaster
Diffstat (limited to 'crypto.py')
-rw-r--r--crypto.py45
1 files changed, 45 insertions, 0 deletions
diff --git a/crypto.py b/crypto.py
new file mode 100644
index 0000000..a278c25
--- /dev/null
+++ b/crypto.py
@@ -0,0 +1,45 @@
+from cryptography.hazmat.primitives.asymmetric import rsa
+from cryptography.hazmat.primitives import serialization
+from .models import db, OIDCKey, OIDCClient
+import jwt
+import datetime
+
+
+def generate_rsa_key():
+ key = rsa.generate_private_key(
+ public_exponent=65537,
+ key_size=2048,
+ )
+
+ private_pem = key.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.PKCS8,
+ encryption_algorithm=serialization.NoEncryption(),
+ )
+
+ public_pem = key.public_key().public_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PublicFormat.SubjectPublicKeyInfo,
+ )
+
+ return private_pem, public_pem
+
+
+def sign_jwt(payload, issuer, client_id):
+ key = OIDCKey.query.filter_by(client_id=client_id).order_by(OIDCKey.created.desc()).first()
+ if not key:
+ raise ValueError("No RSA key is active for this client")
+
+ claims = {
+ "sub": payload["sub"],
+ "iss": issuer,
+ "aud": [client_id],
+ "iat": datetime.datetime.utcnow(),
+ "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1),
+ "email": payload.get("email", ""),
+ "name": payload.get("name", ""),
+ }
+
+ token = jwt.encode(claims, key.private_pem.encode("utf-8"), algorithm="RS256")
+
+ return token