11"""Init mTLS client cert for RASENMAEHER itself"""
22
3+ from typing import Optional
34import asyncio
45from pathlib import Path
56import logging
1011import aiohttp
1112import filelock
1213
13-
14- from .rmsettings import switchme_to_singleton_call , RMSettings , CertBackend
14+ from . cert . errors import CertError
15+ from .rmsettings import RMSettings , CertBackend
1516
1617LOGGER = logging .getLogger (__name__ )
1718
@@ -39,26 +40,24 @@ async def _anon_sign_csr(csr: str) -> str:
3940def check_settings_clientpaths () -> bool :
4041 """Make sure the paths are defined, to defaults if needed, return True if setting was changed"""
4142 changed = False
42- if not switchme_to_singleton_call .mtls_client_cert_path :
43- switchme_to_singleton_call .mtls_client_cert_path = str (
44- Path (switchme_to_singleton_call .persistent_data_dir ) / "public" / f"{ CERT_NAME_PREFIX } .pem"
45- )
43+ config = RMSettings .singleton ()
44+ if not config .mtls_client_cert_path :
45+ config .mtls_client_cert_path = str (Path (config .persistent_data_dir ) / "public" / f"{ CERT_NAME_PREFIX } .pem" )
4646 changed = True
47- if not switchme_to_singleton_call .mtls_client_key_path :
48- switchme_to_singleton_call .mtls_client_key_path = str (
49- Path (switchme_to_singleton_call .persistent_data_dir ) / "private" / f"{ CERT_NAME_PREFIX } .key"
50- )
47+ if not config .mtls_client_key_path :
48+ config .mtls_client_key_path = str (Path (config .persistent_data_dir ) / "private" / f"{ CERT_NAME_PREFIX } .key" )
5149 changed = True
5250 return changed
5351
5452
5553def check_mtls_init () -> bool :
5654 """Check if we have the cert and key"""
5755 check_settings_clientpaths ()
58- assert switchme_to_singleton_call .mtls_client_cert_path is not None
59- assert switchme_to_singleton_call .mtls_client_key_path is not None
60- cert_path = Path (switchme_to_singleton_call .mtls_client_cert_path )
61- key_path = Path (switchme_to_singleton_call .mtls_client_key_path )
56+ config = RMSettings .singleton ()
57+ assert config .mtls_client_cert_path is not None
58+ assert config .mtls_client_key_path is not None
59+ cert_path = Path (config .mtls_client_cert_path )
60+ key_path = Path (config .mtls_client_key_path )
6261 LOGGER .debug ("cert_path={} exits={}" .format (cert_path , cert_path .exists ()))
6362 LOGGER .debug ("key_path={} exits={}" .format (key_path , key_path .exists ()))
6463 if cert_path .exists () and key_path .exists ():
@@ -71,45 +70,57 @@ async def mtls_init() -> None:
7170 if check_mtls_init ():
7271 return
7372 privkeypath , pubkeypath , csrpath = resolve_filepaths (
74- Path (switchme_to_singleton_call .persistent_data_dir ), CERT_NAME_PREFIX
73+ Path (RMSettings . singleton () .persistent_data_dir ), CERT_NAME_PREFIX
7574 )
7675 check_settings_clientpaths ()
77- assert switchme_to_singleton_call .mtls_client_key_path is not None
78- assert switchme_to_singleton_call .mtls_client_cert_path is not None
79- if (pth := Path (switchme_to_singleton_call .mtls_client_key_path )) != privkeypath :
76+ config = RMSettings .singleton ()
77+ assert config .mtls_client_key_path is not None
78+ assert config .mtls_client_cert_path is not None
79+ if (pth := Path (config .mtls_client_key_path )) != privkeypath :
8080 privkeypath = pth
8181 certpath = pubkeypath .parent / f"{ CERT_NAME_PREFIX } .pem"
82- if (pth := Path (switchme_to_singleton_call .mtls_client_cert_path )) != certpath :
82+ if (pth := Path (config .mtls_client_cert_path )) != certpath :
8383 certpath = pth
8484 lockpath = privkeypath .with_suffix (".lock" )
8585 # Random sleep to avoid race conditions on these file accesses
8686 await asyncio .sleep (random .random () * 3.0 ) # nosec
8787 lock = filelock .FileLock (lockpath )
88+ csrpem : Optional [str ] = None
8889 try :
8990 lock .acquire (timeout = 0.0 )
9091 # Check the privkey again to avoid overwriting.
91- if privkeypath .exists ():
92- return None
93- LOGGER .info ("No mTLS client cert yet, creating it, this will take a moment" )
94- keypair = await async_create_keypair (privkeypath , pubkeypath )
95- csrpem = await async_create_client_csr (keypair , csrpath , {"CN" : switchme_to_singleton_call .mtls_client_cert_cn })
96- certpem = (await _anon_sign_csr (csrpem )).replace ("\\ n" , "\n " )
92+ if not privkeypath .exists ():
93+ LOGGER .info ("No mTLS client cert yet, creating it, this will take a moment" )
94+ keypair = await async_create_keypair (privkeypath , pubkeypath )
95+ LOGGER .debug ("Creating mTLS client CSR" )
96+ csrpem = await async_create_client_csr (keypair , csrpath , {"CN" : config .mtls_client_cert_cn })
97+ if not certpath .exists ():
98+ if not csrpem :
99+ LOGGER .debug ("Loading mTLS client CSR from {}" .format (csrpath ))
100+ csrpem = csrpath .read_text ()
101+ try :
102+ LOGGER .debug ("Getting CSR signed" )
103+ certpem = (await _anon_sign_csr (csrpem )).replace ("\\ n" , "\n " )
104+ LOGGER .debug ("Saving mTLS cert to {}" .format (certpath ))
105+ certpath .write_text (certpem , encoding = "ascii" )
106+ except CertError as exc :
107+ LOGGER .exception ("Signing failed: {}" .format (exc ))
97108 except filelock .Timeout :
98109 LOGGER .warning ("Someone has already locked {}" .format (lockpath ))
99110 LOGGER .debug ("Sleeping for ~5s and then recursing" )
100111 await asyncio .sleep (5.0 + random .random ()) # nosec
101112 return await mtls_init ()
102113 finally :
103114 lock .release ()
104- certpath .write_text (certpem , encoding = "ascii" )
105115
106116
107117async def get_session_winit () -> aiohttp .ClientSession :
108118 """wrap libpvarki get_session to init checks"""
109119 await mtls_init ()
110120 check_settings_clientpaths ()
111- assert switchme_to_singleton_call .mtls_client_cert_path is not None
112- assert switchme_to_singleton_call .mtls_client_key_path is not None
113- cert_path = Path (switchme_to_singleton_call .mtls_client_cert_path )
114- key_path = Path (switchme_to_singleton_call .mtls_client_key_path )
121+ config = RMSettings .singleton ()
122+ assert config .mtls_client_cert_path is not None
123+ assert config .mtls_client_key_path is not None
124+ cert_path = Path (config .mtls_client_cert_path )
125+ key_path = Path (config .mtls_client_key_path )
115126 return libsession ((cert_path , key_path ))
0 commit comments