@@ -234,41 +234,23 @@ def generate_localhost_cert(key_dir: Path) -> tuple[Path, Path]:
234234
235235
236236def generate_ca_jks (key_dir : Path , password : str = "password" ) -> Path :
237- """Convert the keycloak CA into the JKS truststore Keycloak mounts.
237+ """Convert the keycloak CA certificate into a JKS truststore Keycloak mounts.
238238
239239 Uses keytool inside the keycloak/keycloak:25.0 image so we don't need a
240240 local JDK — docker is already a hard dependency for the test env.
241241 Requires generate_localhost_cert() to have run first.
242+
243+ Only the CA certificate (public) is imported — not the private key — so the
244+ JKS is a proper truststore, not a keystore.
242245 """
243- ca_key = key_dir / "keycloak-ca-private.pem"
244246 ca_cert = key_dir / "keycloak-ca.pem"
245- if not ca_key . exists () or not ca_cert .exists ():
247+ if not ca_cert .exists ():
246248 raise FileNotFoundError (
247- f"CA files missing in { key_dir } ; call generate_localhost_cert() first"
249+ f"CA certificate missing in { key_dir } ; call generate_localhost_cert() first"
248250 )
249- p12 = key_dir / "ca.p12"
250251 jks = key_dir / "ca.jks"
251252
252- subprocess .run (
253- [
254- "openssl" ,
255- "pkcs12" ,
256- "-export" ,
257- "-in" ,
258- str (ca_cert ),
259- "-inkey" ,
260- str (ca_key ),
261- "-out" ,
262- str (p12 ),
263- "-nodes" ,
264- "-passout" ,
265- f"pass:{ password } " ,
266- ],
267- check = True ,
268- capture_output = True ,
269- )
270-
271- # keytool -importkeystore via the keycloak image (matches init-temp-keys.sh)
253+ # keytool -importcert via the keycloak image: cert-only truststore entry
272254 result = subprocess .run (
273255 [
274256 "docker" ,
@@ -281,18 +263,16 @@ def generate_ca_jks(key_dir: Path, password: str = "password") -> Path:
281263 "--user" ,
282264 f"{ os .getuid ()} :{ os .getgid ()} " ,
283265 "keycloak/keycloak:25.0" ,
284- "-importkeystore " ,
285- "-srckeystore " ,
286- "/keys/ca.p12 " ,
287- "-srcstoretype " ,
288- "PKCS12 " ,
289- "-destkeystore " ,
266+ "-importcert " ,
267+ "-file " ,
268+ "/keys/keycloak- ca.pem " ,
269+ "-alias " ,
270+ "ca " ,
271+ "-keystore " ,
290272 "/keys/ca.jks" ,
291- "-deststoretype " ,
273+ "-storetype " ,
292274 "JKS" ,
293- "-srcstorepass" ,
294- password ,
295- "-deststorepass" ,
275+ "-storepass" ,
296276 password ,
297277 "-noprompt" ,
298278 ],
@@ -301,7 +281,7 @@ def generate_ca_jks(key_dir: Path, password: str = "password") -> Path:
301281 )
302282 if result .returncode != 0 :
303283 raise RuntimeError (
304- f"keytool failed converting PKCS12 → JKS:\n { result .stderr } \n "
284+ f"keytool failed importing CA cert into JKS truststore :\n { result .stderr } \n "
305285 "Ensure Docker is running and `keycloak/keycloak:25.0` is pullable."
306286 )
307287 return jks
@@ -323,24 +303,30 @@ def ensure_keys_exist(key_dir: Path, force: bool = False) -> bool:
323303 True if any keys were generated, False if everything already existed
324304 """
325305 rsa_private = key_dir / "kas-private.pem"
306+ rsa_cert = key_dir / "kas-cert.pem"
326307 ec_private = key_dir / "kas-ec-private.pem"
308+ ec_cert = key_dir / "kas-ec-cert.pem"
327309 localhost_key = key_dir / "localhost.key"
310+ localhost_cert = key_dir / "localhost.crt"
328311 ca_jks = key_dir / "ca.jks"
329312
330313 if (
331314 not force
332315 and rsa_private .exists ()
316+ and rsa_cert .exists ()
333317 and ec_private .exists ()
318+ and ec_cert .exists ()
334319 and localhost_key .exists ()
320+ and localhost_cert .exists ()
335321 and ca_jks .exists ()
336322 ):
337323 return False
338324
339- if force or not rsa_private .exists ():
325+ if force or not rsa_private .exists () or not rsa_cert . exists () :
340326 generate_rsa_keypair (key_dir , "kas" )
341- if force or not ec_private .exists ():
327+ if force or not ec_private .exists () or not ec_cert . exists () :
342328 generate_ec_keypair (key_dir , "kas-ec" )
343- if force or not localhost_key .exists ():
329+ if force or not localhost_key .exists () or not localhost_cert . exists () :
344330 generate_localhost_cert (key_dir )
345331 if force or not ca_jks .exists ():
346332 generate_ca_jks (key_dir )
0 commit comments