package com.ibm.mobilefirstplatform.appid_clientsdk_android;

import android.content.Context;
import android.os.Build;
import android.security.KeyPairGeneratorSpec;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableEntryException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;

/**
 * Created by rotembr on 04/01/2017.
 */

public class AppIdKeyStore {

    private static final String alias = "registration";
    private static final String ANDROID_KEY_STORE = "AndroidKeyStore";
    private KeyStore keyStore;

    public KeyPair generateKeypair(Context context) throws CertificateException, KeyStoreException, IOException, UnrecoverableEntryException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
        loadKeyStore();
        KeyPair keyPair = null;
        if (!keyStore.containsAlias(alias)) {
            KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_KEY_STORE);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                KeyGenParameterSpec spec  = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_SIGN)
                        .setDigests(KeyProperties.DIGEST_SHA256)
                        .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                        .build();
                generator.initialize(spec);

            }else {
                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
                        .setAlias(alias)
                        .setKeyType(KeyProperties.KEY_ALGORITHM_RSA)
                        .build();
                generator.initialize(spec);

            }
            keyPair = generator.generateKeyPair();
        }else {
            keyPair = getStoredKeyPair();
        }
        return keyPair;
    }

    private void loadKeyStore() throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
        if (keyStore == null) {
            keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
            keyStore.load(null);
        }
    }

    public KeyPair getStoredKeyPair() throws CertificateException, KeyStoreException, IOException, UnrecoverableEntryException, NoSuchAlgorithmException {
        loadKeyStore();
        KeyPair keyPair = null;
        if (keyStore.containsAlias(alias)) {
            KeyStore.PrivateKeyEntry pke = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, null);
            Certificate cert = pke.getCertificate();
            keyPair = new KeyPair(cert.getPublicKey(), pke.getPrivateKey());
        }else{
            throw new IOException("No keyPair found");
        }
        return keyPair;
    }
}

@@ -281,32 +281,61 @@
 io.IOException;%0A
+import java.math.BigInteger;%0A
 import java.secu
@@ -744,16 +744,91 @@
 ception;
+%0Aimport java.util.Calendar;%0A%0Aimport javax.security.auth.x500.X500Principal;
 %0A%0A/**%0A *
@@ -1054,16 +1054,75 @@
 eyStore;
+%0A    private static final String KEY_ALGORITHM_RSA = %22RSA%22;
 %0A%0A    pu
@@ -1517,30 +1517,16 @@
 nstance(
-KeyProperties.
 KEY_ALGO
@@ -1618,17 +1618,17 @@
 N_CODES.
-N
+M
 ) %7B%0A    
@@ -1958,33 +1958,32 @@
 itialize(spec);%0A
-%0A
             %7Dels
@@ -2006,169 +2006,539 @@
     
-KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)%0A                        .setAlias(alias)%0A                        .setKeyType(KeyProperties.
+Calendar start = Calendar.getInstance();%0A                Calendar end = Calendar.getInstance();%0A                end.add(Calendar.YEAR, 1);%0A                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)%0A                        .setAlias(alias)%0A                        .setSubject(new X500Principal(%22CN=fake%22))%0A                        .setSerialNumber(BigInteger.ONE)%0A                        .setStartDate(start.getTime())%0A                        .setEndDate(end.getTime())%0A                        .setKeyType(
 KEY_
@@ -2630,17 +2630,16 @@
 (spec);%0A
-%0A
         

fix bug