!7 concept PasswordEntry { S publicKey; SecretValue privateKey; S comment; S globalID = aGlobalID(); } cmodule2 WebPushKeyManager > DynCRUD { KeyPair generateKeyPair() ctex { ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec(nl.martijndwars.webpush.Utils.CURVE); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(nl.martijndwars.webpush.Utils.ALGORITHM, org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME); keyPairGenerator.initialize(parameterSpec); ret keyPairGenerator.generateKeyPair(); } // API PKIKeyPair getKeyPair() { lock dbLock(); Entry entry = conceptWhere Entry(); if (entry == null) { KeyPair keyPair = generateKeyPair(); ECPublicKey publicKey = cast keyPair.getPublic(); ECPrivateKey privateKey = cast keyPair.getPrivate(); byte[] encodedPublicKey = nl.martijndwars.webpush.Utils.encode(publicKey); byte[] encodedPrivateKey = nl.martijndwars.webpush.Utils.encode(privateKey); S publicKeyString = base64encode(encodedPublicKey); S privateKeyString = base64encode(encodedPrivateKey); Entry entry = cnew Entry(publicKey := publicKeyString, privateKey := SecretValue(privateKeyString)); } ret entry; } }