// Path: lib/src/main/java/com/google/capillary/NoSuchKeyException.java
// public final class NoSuchKeyException extends CapillaryException {
// 
//   /**
//    * Creates a new {@link NoSuchKeyException} object.
//    *
//    * @param msg the exception message.
//    */
//   public NoSuchKeyException(String msg) {
//     super(msg);
//   }
// }
// 
// Path: lib/src/main/java/com/google/capillary/RsaEcdsaConstants.java
// public enum Padding {
//   OAEP("OAEPPadding"),
//   PKCS1("PKCS1Padding");
// 
//   private static final String PREFIX = "RSA/ECB/";
// 
//   private final String padding;
// 
//   Padding(String val) {
//     padding = val;
//   }
// 
//   /**
//    * Returns the current padding enum's transformation string that should be used when calling
//    * {@code javax.crypto.Cipher.getInstance}.
//    *
//    * @return the transformation string.
//    */
//   public String getTransformation() {
//     return PREFIX + padding;
//   }
// }


import android.content.Context;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.security.KeyPairGeneratorSpec;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import com.google.capillary.NoSuchKeyException;
import com.google.capillary.RsaEcdsaConstants.Padding;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import javax.security.auth.x500.X500Principal;
import org.joda.time.LocalDate;
        specBuilder.setUserAuthenticationRequired(true);
        specBuilder.setUserAuthenticationValidityDurationSeconds(UNLOCK_DURATION_SECONDS);
      }
      spec = specBuilder.build();
    } else { // API levels 22 and below have to use KeyPairGeneratorSpec to build RSA keys.
      LocalDate startDate = LocalDate.now();
      LocalDate endDate = startDate.plusYears(KEY_DURATION_YEARS);
      KeyPairGeneratorSpec.Builder specBuilder = new KeyPairGeneratorSpec.Builder(context)
          .setAlias(keyAlias)
          .setSubject(new X500Principal("CN=" + keyAlias))
          .setSerialNumber(BigInteger.ONE)
          .setStartDate(startDate.toDate())
          .setEndDate(endDate.toDate());
      // Only API levels 19 and above allow specifying RSA key parameters.
      if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
        specBuilder.setAlgorithmParameterSpec(rsaSpec);
        specBuilder.setKeySize(KEY_SIZE);
      }
      if (isAuth) {
        specBuilder.setEncryptionRequired();
      }
      spec = specBuilder.build();
    }

    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", KEYSTORE_ANDROID);
    keyPairGenerator.initialize(spec);
    keyPairGenerator.generateKeyPair();
  }

  static PublicKey getPublicKey(KeyStore keyStore, String keychainId, boolean isAuth)
// Path: lib/src/main/java/com/google/capillary/NoSuchKeyException.java
// public final class NoSuchKeyException extends CapillaryException {
// 
//   /**
//    * Creates a new {@link NoSuchKeyException} object.
//    *
//    * @param msg the exception message.
//    */
//   public NoSuchKeyException(String msg) {
//     super(msg);
//   }
// }
// 
// Path: lib/src/main/java/com/google/capillary/RsaEcdsaConstants.java
// public enum Padding {
//   OAEP("OAEPPadding"),
//   PKCS1("PKCS1Padding");
// 
//   private static final String PREFIX = "RSA/ECB/";
// 
//   private final String padding;
// 
//   Padding(String val) {
//     padding = val;
//   }
// 
//   /**
//    * Returns the current padding enum's transformation string that should be used when calling
//    * {@code javax.crypto.Cipher.getInstance}.
//    *
//    * @return the transformation string.
//    */
//   public String getTransformation() {
//     return PREFIX + padding;
//   }
// }


// Path: lib-android/src/main/java/com/google/capillary/android/AndroidKeyStoreRsaUtils.java
import android.content.Context;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.security.KeyPairGeneratorSpec;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import com.google.capillary.NoSuchKeyException;
import com.google.capillary.RsaEcdsaConstants.Padding;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import javax.security.auth.x500.X500Principal;
import org.joda.time.LocalDate;

        specBuilder.setUserAuthenticationRequired(true);
        specBuilder.setUserAuthenticationValidityDurationSeconds(UNLOCK_DURATION_SECONDS);
      }
      spec = specBuilder.build();
    } else { // API levels 22 and below have to use KeyPairGeneratorSpec to build RSA keys.
      LocalDate startDate = LocalDate.now();
      LocalDate endDate = startDate.plusYears(KEY_DURATION_YEARS);
      KeyPairGeneratorSpec.Builder specBuilder = new KeyPairGeneratorSpec.Builder(context)
          .setAlias(keyAlias)
          .setSubject(new X500Principal("CN=" + keyAlias))
          .setSerialNumber(BigInteger.ONE)
          .setStartDate(startDate.toDate())
          .setEndDate(endDate.toDate());
      // Only API levels 19 and above allow specifying RSA key parameters.
      if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
        specBuilder.setAlgorithmParameterSpec(rsaSpec);
        specBuilder.setKeySize(KEY_SIZE);
      }
      if (isAuth) {
        specBuilder.setEncryptionRequired();
      }
      spec = specBuilder.build();
    }

    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", KEYSTORE_ANDROID);
    keyPairGenerator.initialize(spec);
    keyPairGenerator.generateKeyPair();
  }

  static PublicKey getPublicKey(KeyStore keyStore, String keychainId, boolean isAuth)
      throws NoSuchKeyException, KeyStoreException {