package com.l7tech.gateway.common.security;

import com.l7tech.common.io.AliasNotFoundException;
import com.l7tech.common.io.CertGenParams;
import com.l7tech.gateway.common.AsyncAdminMethods;
import com.l7tech.gateway.common.admin.Administrative;
import com.l7tech.gateway.common.security.keystore.KeystoreFileEntityHeader;
import com.l7tech.gateway.common.security.keystore.SsgKeyEntry;
import com.l7tech.gateway.common.security.keystore.SsgKeyMetadata;
import com.l7tech.gateway.common.security.password.SecurePassword;
import com.l7tech.gateway.common.security.rbac.MethodStereotype;
import com.l7tech.gateway.common.security.rbac.OperationType;
import com.l7tech.gateway.common.security.rbac.Secured;
import com.l7tech.objectmodel.ConstraintViolationException;
import com.l7tech.objectmodel.DeleteException;
import com.l7tech.objectmodel.EntityType;
import com.l7tech.objectmodel.FindException;
import com.l7tech.objectmodel.Goid;
import com.l7tech.objectmodel.ObjectNotFoundException;
import com.l7tech.objectmodel.SaveException;
import com.l7tech.objectmodel.UpdateException;
import com.l7tech.objectmodel.VersionException;
import com.l7tech.security.cert.TrustedCert;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.EventObject;
import java.util.List;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
@Administrative
@Secured(types = EntityType.TRUSTED_CERT)
public interface TrustedCertAdmin extends AsyncAdminMethods {
   String CSR_PROP_SUBJECT_DN = "subject.dn";
   String CSR_PROP_KEY_TYPE = "public.key.type";
   String CSR_PROP_KEY_SIZE = "rsa.public.key.size";
   String CSR_PROP_MODULUS = "rsa.public.key.modulus";
   String CSR_PROP_EXPONENT = "rsa.public.key.public.exponent";
   String CSR_PROP_CURVE_NAME = "ec.public.key.curve.name";
   String CSR_PROP_CURVE_SIZE = "ec.public.key.curve.size";
   String CSR_PROP_CURVE_POINT_W_X = "ec.public.key.curve.point.w.x.coord";
   String CSR_PROP_CURVE_POINT_W_Y = "ec.public.key.curve.point.w.y.coord";
   String CSR_PROP_SUBJECT_ALTERNATIVE_NAMES = "subject.alternative.names";

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   List<TrustedCert> findAllCerts() throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_ENTITY)
   TrustedCert findCertByPrimaryKey(Goid var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   Collection<TrustedCert> findCertsBySubjectDn(String var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.TEST_CONFIGURATION)
   boolean validateCertChainForCc(@NotNull X509Certificate[] var1) throws CertificateException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveCert(TrustedCert var1) throws SaveException, UpdateException, VersionException, CertificateException;

   @Secured(stereotype = MethodStereotype.DELETE_BY_ID)
   void deleteCert(Goid var1) throws FindException, DeleteException, ConstraintViolationException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.REVOCATION_CHECK_POLICY, stereotype = MethodStereotype.FIND_ENTITIES)
   List<RevocationCheckPolicy> findAllRevocationCheckPolicies() throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.REVOCATION_CHECK_POLICY, stereotype = MethodStereotype.FIND_ENTITY)
   RevocationCheckPolicy findRevocationCheckPolicyByPrimaryKey(Goid var1) throws FindException;

   @Secured(types = EntityType.REVOCATION_CHECK_POLICY, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveRevocationCheckPolicy(RevocationCheckPolicy var1) throws SaveException, UpdateException, VersionException;

   @Secured(types = EntityType.REVOCATION_CHECK_POLICY, stereotype = MethodStereotype.DELETE_BY_ID)
   void deleteRevocationCheckPolicy(Goid var1) throws FindException, DeleteException, ConstraintViolationException;

   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   boolean getKeyStoreAllowDuplicatesBySubjectDN();

   @Transactional(readOnly = true)
   @Secured(types = EntityType.TRUSTED_CERT, stereotype = MethodStereotype.TEST_CONFIGURATION)
   X509Certificate[] getCertficatesFromKeystoreBytes(@Nullable byte[] var1, String var2, @Nullable char[] var3, char[] var4, @Nullable String var5) throws UnrecoverableKeyException, MultipleAliasesException, CertificateException, KeyStoreException, NoSuchAlgorithmException, IOException, NoSuchProviderException, AliasNotFoundException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(types = EntityType.TRUSTED_CERT, stereotype = MethodStereotype.TEST_CONFIGURATION)
   X509Certificate[] retrieveCertFromUrl(String var1) throws IOException, TrustedCertAdmin.HostnameMismatchException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(types = EntityType.TRUSTED_CERT, stereotype = MethodStereotype.TEST_CONFIGURATION)
   X509Certificate[] retrieveCertFromUrl(String var1, boolean var2) throws IOException, TrustedCertAdmin.HostnameMismatchException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(types = EntityType.TRUSTED_CERT, stereotype = MethodStereotype.TEST_CONFIGURATION)
   AsyncAdminMethods.JobId<X509Certificate[]> retrieveCertFromUrlAsync(String var1, boolean var2);

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   X509Certificate getSSGRootCert() throws IOException, CertificateException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   X509Certificate getSSGSslCert() throws IOException, CertificateException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   X509Certificate getSSGServerSslCert() throws IOException, CertificateException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   X509Certificate getSSGClientSslCert() throws IOException, CertificateException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   X509Certificate getSSGAuditSigningCert() throws IOException, CertificateException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.FIND_HEADERS, types = EntityType.SSG_KEYSTORE)
   List<KeystoreFileEntityHeader> findAllKeystores(boolean var1) throws IOException, FindException, KeyStoreException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.NO_PRE_CHECK, returnCheck = PrivateKeySecured.ReturnCheck.FILTER_RETURN)
   List<SsgKeyEntry> findAllKeys(Goid var1, boolean var2) throws IOException, CertificateException, FindException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.NO_PRE_CHECK, returnCheck = PrivateKeySecured.ReturnCheck.CHECK_RETURN)
   SsgKeyEntry findKeyEntry(String var1, Goid var2) throws FindException, KeyStoreException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION, argOp = OperationType.DELETE)
   void deleteKey(Goid var1, String var2) throws IOException, CertificateException, DeleteException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(
      preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION,
      argOp = OperationType.CREATE,
      metadataArg = 2,
      returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK
   )
   AsyncAdminMethods.JobId<X509Certificate> generateKeyPair(
      Goid var1, String var2, @Nullable SsgKeyMetadata var3, X500Principal var4, int var5, int var6, boolean var7, String var8
   ) throws FindException, GeneralSecurityException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(
      preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION,
      argOp = OperationType.CREATE,
      metadataArg = 2,
      returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK
   )
   AsyncAdminMethods.JobId<X509Certificate> generateEcKeyPair(
      Goid var1, String var2, @Nullable SsgKeyMetadata var3, X500Principal var4, String var5, int var6, boolean var7, String var8
   ) throws FindException, GeneralSecurityException;

   @Transactional
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION, argOp = OperationType.READ)
   byte[] generateCSR(Goid var1, String var2, CertGenParams var3) throws FindException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(
      preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION,
      argOp = OperationType.READ,
      returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK
   )
   String[] signCSR(Goid var1, String var2, byte[] var3, X500Principal var4, int var5, String var6, String var7) throws FindException, GeneralSecurityException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.NO_PRE_CHECK, returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK)
   List<String> findImpactedKeysByUpdateKeyEntry(@NotNull SsgKeyEntry var1) throws UpdateException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION, argOp = OperationType.UPDATE, keyEntryArg = 0)
   void updateKeyEntry(SsgKeyEntry var1) throws UpdateException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION, argOp = OperationType.UPDATE, keyEntryArg = 0)
   void updateKeyEntry(SsgKeyEntry var1, boolean var2) throws UpdateException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.NO_PRE_CHECK, returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK)
   String getSubjectDNBeforeImport(Goid var1, String var2, @Nullable byte[] var3, String var4, @Nullable char[] var5, char[] var6, @Nullable String var7) throws SaveException, KeyStoreException, MultipleAliasesException, AliasNotFoundException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.NO_PRE_CHECK, returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK)
   List<String> findImpactedKeysByImportKey(
      Goid var1, String var2, @Nullable byte[] var3, String var4, @Nullable char[] var5, char[] var6, @Nullable String var7
   ) throws GeneralSecurityException, SaveException, AliasNotFoundException, MultipleAliasesException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(
      preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION,
      argOp = OperationType.CREATE,
      metadataArg = 2,
      returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK
   )
   SsgKeyEntry importKeyFromKeyStoreFile(
      Goid var1, String var2, @Nullable SsgKeyMetadata var3, byte[] var4, String var5, @Nullable char[] var6, @Nullable char[] var7, String var8
   ) throws FindException, SaveException, KeyStoreException, MultipleAliasesException, AliasNotFoundException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(
      preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION,
      argOp = OperationType.CREATE,
      metadataArg = 2,
      returnCheck = PrivateKeySecured.ReturnCheck.NO_RETURN_CHECK
   )
   SsgKeyEntry importKeyFromKeyStoreFile(
      Goid var1, String var2, @Nullable SsgKeyMetadata var3, byte[] var4, String var5, @Nullable char[] var6, @Nullable char[] var7, String var8, boolean var9
   ) throws FindException, SaveException, KeyStoreException, MultipleAliasesException, AliasNotFoundException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(
      preChecks = {PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION, PrivateKeySecured.PreCheck.CHECK_ARG_EXPORT_KEY},
      argOp = OperationType.READ
   )
   byte[] exportKey(Goid var1, String var2, String var3, char[] var4) throws ObjectNotFoundException, FindException, KeyStoreException, UnrecoverableKeyException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.NO_PRE_CHECK, returnCheck = PrivateKeySecured.ReturnCheck.FILTER_RETURN)
   SsgKeyEntry findDefaultKey(SpecialKeyType var1) throws KeyStoreException;

   @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.CHECK_UPDATE_ALL_KEYSTORES_NONFATAL, allowNonFatalPreChecks = true)
   boolean isDefaultKeyMutable(SpecialKeyType var1);

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(
      preChecks = {PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION, PrivateKeySecured.PreCheck.CHECK_UPDATE_ALL_KEYSTORES_NONFATAL},
      argOp = OperationType.READ,
      keystoreGoidArg = 1,
      keyAliasArg = 2,
      allowNonFatalPreChecks = false
   )
   void setDefaultKey(SpecialKeyType var1, Goid var2, String var3) throws UpdateException;

   @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.FIND_ENTITIES)
   List<SecurePassword> findAllSecurePasswords() throws FindException;

   @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.FIND_ENTITY)
   SecurePassword findSecurePasswordById(Goid var1) throws FindException;

   @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.FIND_ENTITY)
   SecurePassword findSecurePasswordByName(String var1) throws FindException;

   @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   String getSecurePasswordPublicKey(Goid var1) throws FindException;

   @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveSecurePassword(SecurePassword var1) throws UpdateException, SaveException, FindException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.SET_PROPERTY_BY_ID, relevantArg = 0)
   void setSecurePassword(Goid var1, char[] var2) throws FindException, UpdateException;

   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.SET_PROPERTY_BY_ID, relevantArg = 0)
   AsyncAdminMethods.JobId<Boolean> setGeneratedSecurePassword(Goid var1, int var2) throws FindException, UpdateException;

   @Transactional(propagation = Propagation.REQUIRED)
   @Secured(types = EntityType.SECURE_PASSWORD, stereotype = MethodStereotype.DELETE_BY_ID, relevantArg = 0)
   void deleteSecurePassword(Goid var1) throws ConstraintViolationException, DeleteException, FindException;

   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   Map<String, Object> getCsrProperties(byte[] var1);

   @Secured(customInterceptor = "com.l7tech.server.admin.PrivateKeyRbacInterceptor")
   @PrivateKeySecured(preChecks = PrivateKeySecured.PreCheck.CHECK_ARG_OPERATION, argOp = OperationType.READ)
   boolean isShortSigningKey(Goid var1, String var2) throws FindException, KeyStoreException;

   @Secured(types = EntityType.SSG_KEY_METADATA, stereotype = MethodStereotype.FIND_ENTITY)
   SsgKeyMetadata findKeyMetadata(Goid var1) throws FindException;

   @Secured(types = EntityType.SSG_KEY_METADATA, stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 0)
   Goid saveOrUpdateMetadata(@NotNull SsgKeyMetadata var1) throws SaveException;

   @Transactional
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   void addAuditEntry(EventObject var1, String var2);

   class HostnameMismatchException extends Exception {
      static final long serialVersionUID = 8663281158236774450L;
      private static final String[] a;

      public HostnameMismatchException(String var1, String var2) {
         String[] var3 = a;
         super(var3[1] + var1 + var3[0] + var2 + "'");
      }

      static {
         String[] var5 = new String[2];
         int var3 = 0;
         String var2 = "\r{\u0006\u0005Z:\u000eD4\u0016JR(ZI3B\u001eW,\u000eO#\u0012\u000f\\=KN{\n\u0005L=@K6\u0007J\u0018\u0019y\b.J|,\\^2\u0004\u0003\\(ZO{\u0015\u0003K!\u000en\u0015BM";
         int var4 = "\r{\u0006\u0005Z:\u000eD4\u0016JR(ZI3B\u001eW,\u000eO#\u0012\u000f\\=KN{\n\u0005L=@K6\u0007J\u0018\u0019y\b.J|,\\^2\u0004\u0003\\(ZO{\u0015\u0003K!\u000en\u0015BM"
            .length();
         char var1 = '(';
         int var0 = -1;

         while (true) {
            String var10002 = a(72, a(var2.substring(++var0, var0 + var1)));
            byte var10001 = -1;
            var5[var3++] = var10002;
            if ((var0 += var1) >= var4) {
               a = var5;
               return;
            }

            var1 = var2.charAt(var0);
         }
      }

      private static char[] a(String var0) {
         char[] var10000 = var0.toCharArray();
         if (var10000.length < 2) {
            var10000[0] = (char)(var10000[0] ^ 102);
         }

         return var10000;
      }

      private static String a(int var0, char[] var1) {
         int var10003 = var1.length;
         int var10002 = var0;
         char[] var10001 = var1;
         int var10000 = var10003;

         for (int var2 = 0; var10000 > var2; var2++) {
            var10001[var2] = (char)(var10001[var2] ^ var10002 ^ switch (var2 % 7) {
               case 0 -> 98;
               case 1 -> 19;
               case 2 -> 42;
               case 3 -> 34;
               case 4 -> 119;
               case 5 -> 1;
               default -> 102;
            });
         }

         return new String(var10001).intern();
      }
   }
}
